@iislee/opencodex 2.11.0 → 2.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (733) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +117 -22
  3. package/bin/ocx.mjs +245 -88
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-Be1sDpWw.css +1 -0
  6. package/gui/dist/assets/index-D4OKgUV4.js +114 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +21 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +475 -62
  44. package/src/adapters/base.ts +82 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +637 -0
  48. package/src/adapters/cursor/call-id.ts +44 -0
  49. package/src/adapters/cursor/catalog.ts +541 -0
  50. package/src/adapters/cursor/checkpoint-store.ts +308 -0
  51. package/src/adapters/cursor/cursor-errors.ts +144 -6
  52. package/src/adapters/cursor/discovery.ts +122 -14
  53. package/src/adapters/cursor/effort-map.ts +106 -4
  54. package/src/adapters/cursor/envelope-echo.ts +290 -0
  55. package/src/adapters/cursor/framing.ts +39 -0
  56. package/src/adapters/cursor/h2-pool.ts +123 -0
  57. package/src/adapters/cursor/http1-bidi.ts +361 -0
  58. package/src/adapters/cursor/images.ts +704 -0
  59. package/src/adapters/cursor/live-models.ts +180 -59
  60. package/src/adapters/cursor/live-transport.ts +623 -170
  61. package/src/adapters/cursor/message-mapper.ts +4 -1
  62. package/src/adapters/cursor/native-exec-common.ts +23 -2
  63. package/src/adapters/cursor/native-exec-desktop.ts +23 -0
  64. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  65. package/src/adapters/cursor/native-exec-network.ts +1 -1
  66. package/src/adapters/cursor/native-exec-shell.ts +5 -3
  67. package/src/adapters/cursor/native-exec.ts +121 -14
  68. package/src/adapters/cursor/protobuf-events.ts +829 -11
  69. package/src/adapters/cursor/protobuf-request.ts +447 -75
  70. package/src/adapters/cursor/request-builder.ts +271 -35
  71. package/src/adapters/cursor/tool-definitions.ts +252 -12
  72. package/src/adapters/cursor/tool-result-normalize.ts +115 -0
  73. package/src/adapters/cursor/transport.ts +22 -0
  74. package/src/adapters/cursor/types.ts +48 -1
  75. package/src/adapters/cursor.ts +336 -39
  76. package/src/adapters/exec-tool-result-normalize.ts +99 -0
  77. package/src/adapters/google-antigravity-replay.ts +713 -41
  78. package/src/adapters/google-antigravity-wire.ts +48 -10
  79. package/src/adapters/google-errors.ts +44 -12
  80. package/src/adapters/google-http.ts +38 -10
  81. package/src/adapters/google-tool-schema.ts +80 -15
  82. package/src/adapters/google-truncation.ts +11 -0
  83. package/src/adapters/google.ts +742 -86
  84. package/src/adapters/identity.ts +39 -6
  85. package/src/adapters/image.ts +1 -1
  86. package/src/adapters/kiro-constants.ts +27 -0
  87. package/src/adapters/kiro-errors.ts +11 -0
  88. package/src/adapters/kiro-events.ts +19 -1
  89. package/src/adapters/kiro-thinking.ts +18 -2
  90. package/src/adapters/kiro-tools.ts +65 -17
  91. package/src/adapters/kiro.ts +270 -73
  92. package/src/adapters/mimo-free.ts +17 -0
  93. package/src/adapters/openai-chat-url.ts +11 -0
  94. package/src/adapters/openai-chat.ts +1377 -344
  95. package/src/adapters/openai-responses-url.ts +16 -0
  96. package/src/adapters/openai-responses.ts +1164 -64
  97. package/src/adapters/registry.ts +175 -0
  98. package/src/adapters/responses-tool-schema.ts +67 -0
  99. package/src/adapters/run-turn-queue.ts +36 -1
  100. package/src/adapters/tool-call-id.ts +119 -0
  101. package/src/adapters/tool-catalog-nudge.ts +105 -21
  102. package/src/adapters/xai-tool-schema.ts +436 -0
  103. package/src/adapters/xai-web-search.ts +186 -0
  104. package/src/bridge.ts +512 -92
  105. package/src/chat/inbound.ts +57 -20
  106. package/src/chat/outbound.ts +97 -33
  107. package/src/claude/agents-inject.ts +40 -10
  108. package/src/claude/context-windows.ts +37 -14
  109. package/src/claude/desktop-3p.ts +243 -9
  110. package/src/claude/gateway-cache.ts +41 -4
  111. package/src/claude/inbound.ts +72 -3
  112. package/src/claude/model-info.ts +38 -15
  113. package/src/claude/outbound.ts +88 -21
  114. package/src/cli/access.ts +46 -3
  115. package/src/cli/account-api.ts +150 -19
  116. package/src/cli/account-auth.ts +33 -6
  117. package/src/cli/account-catalog-refresh.ts +14 -0
  118. package/src/cli/account-extended.ts +648 -28
  119. package/src/cli/account-main.ts +317 -0
  120. package/src/cli/account.ts +97 -19
  121. package/src/cli/agent.ts +53 -2
  122. package/src/cli/alias.ts +66 -0
  123. package/src/cli/capabilities-command.ts +94 -0
  124. package/src/cli/capabilities.ts +496 -0
  125. package/src/cli/claude-agent-startup-sync.ts +73 -0
  126. package/src/cli/claude-desktop.ts +60 -15
  127. package/src/cli/claude.ts +129 -35
  128. package/src/cli/codex-log-guard-doctor.ts +103 -0
  129. package/src/cli/codex-shim-autorestore.ts +2 -0
  130. package/src/cli/codex-shim-readiness.ts +76 -0
  131. package/src/cli/combo.ts +8 -0
  132. package/src/cli/config-command.ts +74 -10
  133. package/src/cli/dispatch.ts +821 -0
  134. package/src/cli/doctor.ts +440 -56
  135. package/src/cli/ensure-desired-integrations.ts +152 -0
  136. package/src/cli/export-command.ts +46 -20
  137. package/src/cli/help.ts +34 -274
  138. package/src/cli/index.ts +417 -528
  139. package/src/cli/init.ts +5 -17
  140. package/src/cli/inspect.ts +230 -0
  141. package/src/cli/integrations.ts +120 -2
  142. package/src/cli/lab.ts +607 -0
  143. package/src/cli/launcher-context.ts +77 -0
  144. package/src/cli/minimax.ts +497 -0
  145. package/src/cli/models-runtime.ts +130 -2
  146. package/src/cli/models.ts +118 -16
  147. package/src/cli/observe.ts +123 -11
  148. package/src/cli/opencode.ts +4 -2
  149. package/src/cli/provider-runtime.ts +34 -3
  150. package/src/cli/provider.ts +25 -3
  151. package/src/cli/ready.ts +301 -0
  152. package/src/cli/registry.ts +476 -0
  153. package/src/cli/root.ts +86 -0
  154. package/src/cli/route-policy.ts +92 -0
  155. package/src/cli/runtime-api.ts +57 -10
  156. package/src/cli/star-prompt.ts +71 -15
  157. package/src/cli/status.ts +51 -4
  158. package/src/cli/storage.ts +234 -0
  159. package/src/cli/system-command.ts +16 -0
  160. package/src/cli/system-restart-client.ts +146 -0
  161. package/src/cli/tray-proxy.ts +153 -6
  162. package/src/cli/usage-report.ts +184 -0
  163. package/src/cli/v2.ts +137 -18
  164. package/src/cli/version-skew.ts +46 -0
  165. package/src/cli.ts +1 -1
  166. package/src/clients/config-export.ts +1442 -23
  167. package/src/clients/effective-status.ts +30 -2
  168. package/src/clients/probes/cline.ts +81 -0
  169. package/src/codex/account-label.ts +35 -1
  170. package/src/codex/account-lifecycle.ts +130 -13
  171. package/src/codex/account-namespaces.ts +49 -3
  172. package/src/codex/account-pause.ts +2 -1
  173. package/src/codex/account-priority.ts +84 -0
  174. package/src/codex/account-store.ts +29 -2
  175. package/src/codex/account-usability.ts +25 -2
  176. package/src/codex/admission.ts +256 -0
  177. package/src/codex/affinity-debug.ts +162 -0
  178. package/src/codex/app-server-processes.ts +570 -107
  179. package/src/codex/app-server-restart-service.ts +232 -0
  180. package/src/codex/auth-api.ts +893 -246
  181. package/src/codex/auth-collision.ts +5 -3
  182. package/src/codex/auth-context.ts +348 -32
  183. package/src/codex/autostart-health.ts +24 -1
  184. package/src/codex/catalog/account-models.ts +67 -0
  185. package/src/codex/catalog/aggregation.ts +86 -10
  186. package/src/codex/catalog/bundled.ts +331 -33
  187. package/src/codex/catalog/effort.ts +138 -32
  188. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  189. package/src/codex/catalog/kinds.ts +2 -0
  190. package/src/codex/catalog/metadata.ts +555 -45
  191. package/src/codex/catalog/native-models.ts +75 -0
  192. package/src/codex/catalog/parsing.ts +269 -30
  193. package/src/codex/catalog/provider-fetch.ts +1626 -144
  194. package/src/codex/catalog/sync.ts +1576 -187
  195. package/src/codex/catalog-admission.ts +199 -0
  196. package/src/codex/catalog-refresh-status.ts +105 -0
  197. package/src/codex/catalog-write-serialization.ts +242 -0
  198. package/src/codex/catalog.ts +6 -3
  199. package/src/codex/codex-write-lock.ts +386 -0
  200. package/src/codex/convergence-types.ts +614 -0
  201. package/src/codex/convergence.ts +676 -0
  202. package/src/codex/coordinator-doctor.ts +332 -0
  203. package/src/codex/custom-model-catalog-migration.ts +176 -0
  204. package/src/codex/desired-state.ts +230 -0
  205. package/src/codex/desktop-app-restart.ts +355 -0
  206. package/src/codex/features.ts +636 -39
  207. package/src/codex/generation.ts +202 -0
  208. package/src/codex/history-job.ts +436 -0
  209. package/src/codex/history-lock.ts +242 -0
  210. package/src/codex/history-manifest.ts +112 -0
  211. package/src/codex/history-migration-guardian.ts +30 -24
  212. package/src/codex/history-provider.ts +1016 -235
  213. package/src/codex/history-transition.ts +105 -0
  214. package/src/codex/history-worker.ts +223 -0
  215. package/src/codex/inject-coordination.ts +373 -0
  216. package/src/codex/inject.ts +1114 -152
  217. package/src/codex/injected-marker.ts +37 -3
  218. package/src/codex/integration-record.ts +266 -0
  219. package/src/codex/internal/catalog-writer.ts +203 -0
  220. package/src/codex/internal/history-writer.ts +81 -0
  221. package/src/codex/journal.ts +66 -4
  222. package/src/codex/log-guard/inspect.ts +524 -0
  223. package/src/codex/log-guard/lock.ts +150 -0
  224. package/src/codex/log-guard/maintenance.ts +403 -0
  225. package/src/codex/log-guard/path-safety.ts +88 -0
  226. package/src/codex/log-guard/policy.ts +44 -0
  227. package/src/codex/log-guard/processes.ts +205 -0
  228. package/src/codex/log-guard/protection.ts +489 -0
  229. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  230. package/src/codex/main-account-cache.ts +24 -0
  231. package/src/codex/main-account.ts +29 -1
  232. package/src/codex/management-convergence.ts +167 -0
  233. package/src/codex/model-cache.ts +56 -10
  234. package/src/codex/model-entitlements.ts +360 -0
  235. package/src/codex/native-main-admission.ts +47 -0
  236. package/src/codex/native-main-auth-temp.ts +187 -0
  237. package/src/codex/native-main-claim.ts +178 -0
  238. package/src/codex/native-main-lock-file.ts +162 -0
  239. package/src/codex/native-main-owner.ts +329 -0
  240. package/src/codex/native-profile-api.ts +247 -0
  241. package/src/codex/native-profile-manager.ts +1531 -0
  242. package/src/codex/native-profile-processes.ts +121 -0
  243. package/src/codex/native-profile-recovery.ts +99 -0
  244. package/src/codex/native-profile-stage-store.ts +387 -0
  245. package/src/codex/native-profile-startup.ts +622 -0
  246. package/src/codex/native-profile-store.ts +855 -0
  247. package/src/codex/native-profile-types.ts +120 -0
  248. package/src/codex/native-residue.ts +675 -0
  249. package/src/codex/paths.ts +80 -1
  250. package/src/codex/plan-from-token.ts +140 -0
  251. package/src/codex/plan.ts +40 -0
  252. package/src/codex/plugins-doctor.ts +1 -1
  253. package/src/codex/pool-rotation.ts +74 -4
  254. package/src/codex/project-config-warnings.ts +20 -6
  255. package/src/codex/prompt-journal.ts +352 -0
  256. package/src/codex/prompt-layers.ts +1313 -0
  257. package/src/codex/prompt-lock.ts +143 -0
  258. package/src/codex/prompt-text-probe.ts +238 -0
  259. package/src/codex/quota-rejection.ts +298 -0
  260. package/src/codex/quota.ts +264 -21
  261. package/src/codex/refresh.ts +11 -2
  262. package/src/codex/reset-credit-recovery.ts +1044 -0
  263. package/src/codex/routing.ts +514 -94
  264. package/src/codex/runtime.ts +159 -38
  265. package/src/codex/shim.ts +1065 -31
  266. package/src/codex/subagent-model-fallback.ts +437 -43
  267. package/src/codex/sync.ts +191 -2
  268. package/src/codex/transition-state.ts +720 -0
  269. package/src/codex/upstream-host-health.ts +368 -0
  270. package/src/codex/user-identity.ts +557 -0
  271. package/src/codex/warmup.ts +187 -81
  272. package/src/codex/write-coordination.ts +114 -0
  273. package/src/combos/failover.ts +47 -0
  274. package/src/combos/index.ts +4 -0
  275. package/src/combos/request.ts +32 -0
  276. package/src/combos/types.ts +91 -9
  277. package/src/compatibility/index.ts +26 -0
  278. package/src/compatibility/manifest.ts +253 -0
  279. package/src/compatibility/openai-responses.ts +121 -0
  280. package/src/config/atomic-write.ts +219 -0
  281. package/src/config/paths.ts +40 -0
  282. package/src/config/process-state.ts +309 -0
  283. package/src/config/provider-name.ts +24 -0
  284. package/src/config/provider-validation.ts +177 -0
  285. package/src/config/rebase-provenance.ts +68 -0
  286. package/src/config.ts +1713 -709
  287. package/src/generated/compatibility-version.json +3324 -0
  288. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  289. package/src/grok/inject.ts +16 -5
  290. package/src/grok/inspect.ts +45 -0
  291. package/src/grok/sync.ts +2 -2
  292. package/src/images/loop.ts +157 -33
  293. package/src/images/plan.ts +24 -13
  294. package/src/integrations/config-io.ts +269 -0
  295. package/src/integrations/journal.ts +315 -0
  296. package/src/integrations/merge.ts +135 -0
  297. package/src/integrations/mutation-flight.ts +71 -0
  298. package/src/integrations/native/ownership-preflight.ts +202 -0
  299. package/src/integrations/omp-yaml-source.ts +358 -0
  300. package/src/integrations/owned-refresh.ts +74 -0
  301. package/src/integrations/ownership-policy.ts +160 -0
  302. package/src/integrations/ownership.ts +155 -0
  303. package/src/integrations/registry.ts +166 -0
  304. package/src/integrations/serialize.ts +314 -0
  305. package/src/integrations/state.ts +433 -0
  306. package/src/integrations/store.ts +103 -0
  307. package/src/integrations/writer-lock.ts +98 -0
  308. package/src/integrations/writer.ts +715 -0
  309. package/src/lab/artifacts/sanitize.ts +586 -0
  310. package/src/lab/artifacts/secure-fs.ts +475 -0
  311. package/src/lab/artifacts/store.ts +310 -0
  312. package/src/lab/automation/budgets.ts +78 -0
  313. package/src/lab/automation/config-persistence.ts +256 -0
  314. package/src/lab/automation/constants.ts +39 -0
  315. package/src/lab/automation/cooldown.ts +103 -0
  316. package/src/lab/automation/dispatch.ts +211 -0
  317. package/src/lab/automation/index.ts +13 -0
  318. package/src/lab/automation/orchestrator.ts +499 -0
  319. package/src/lab/automation/persistence.ts +512 -0
  320. package/src/lab/automation/planner.ts +371 -0
  321. package/src/lab/automation/policy.ts +136 -0
  322. package/src/lab/automation/queue.ts +191 -0
  323. package/src/lab/automation/recovery.ts +24 -0
  324. package/src/lab/automation/route-context.ts +21 -0
  325. package/src/lab/automation/run-key.ts +44 -0
  326. package/src/lab/automation/runs-query.ts +34 -0
  327. package/src/lab/automation/types.ts +160 -0
  328. package/src/lab/conformance/assertion.ts +325 -0
  329. package/src/lab/conformance/digest.ts +22 -0
  330. package/src/lab/conformance/executor.ts +741 -0
  331. package/src/lab/conformance/fixture-provider.ts +27 -0
  332. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  333. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  334. package/src/lab/conformance/harness-budget.ts +47 -0
  335. package/src/lab/conformance/index.ts +5 -0
  336. package/src/lab/conformance/jcs.ts +64 -0
  337. package/src/lab/conformance/json-pointer.ts +39 -0
  338. package/src/lab/conformance/manifest.ts +180 -0
  339. package/src/lab/conformance/mcp-stub.ts +179 -0
  340. package/src/lab/conformance/negative-controls.ts +164 -0
  341. package/src/lab/conformance/observation.ts +355 -0
  342. package/src/lab/conformance/runner.ts +68 -0
  343. package/src/lab/conformance/sse-normalize.ts +59 -0
  344. package/src/lab/conformance/suite-manifest.ts +78 -0
  345. package/src/lab/conformance/types.ts +214 -0
  346. package/src/lab/constants.ts +126 -0
  347. package/src/lab/digest.ts +64 -0
  348. package/src/lab/events/errors.ts +9 -0
  349. package/src/lab/events/limits.ts +117 -0
  350. package/src/lab/events/types.ts +229 -0
  351. package/src/lab/events/validate.ts +781 -0
  352. package/src/lab/fabric/constants.ts +40 -0
  353. package/src/lab/fabric/executor.ts +492 -0
  354. package/src/lab/fabric/index.ts +80 -0
  355. package/src/lab/fabric/manifest.ts +222 -0
  356. package/src/lab/fabric/observe.ts +489 -0
  357. package/src/lab/fabric/patch.ts +79 -0
  358. package/src/lab/fabric/producer-child.ts +139 -0
  359. package/src/lab/fabric/producer-isolate.ts +276 -0
  360. package/src/lab/fabric/producer-protocol.ts +61 -0
  361. package/src/lab/fabric/scratch.ts +439 -0
  362. package/src/lab/fabric/subject.ts +106 -0
  363. package/src/lab/fabric/types.ts +134 -0
  364. package/src/lab/fabric/verifier.ts +98 -0
  365. package/src/lab/index.ts +54 -0
  366. package/src/lab/ledger/artifact-refs.ts +127 -0
  367. package/src/lab/ledger/invalidation.ts +136 -0
  368. package/src/lab/ledger/purge.ts +310 -0
  369. package/src/lab/ledger/store.ts +532 -0
  370. package/src/lab/live/credential-lease.ts +53 -0
  371. package/src/lab/live/destination.ts +155 -0
  372. package/src/lab/live/executor.ts +336 -0
  373. package/src/lab/live/inert-tools.ts +56 -0
  374. package/src/lab/live/manifest.ts +85 -0
  375. package/src/lab/live/mcp-loopback.ts +57 -0
  376. package/src/lab/live/runner.ts +19 -0
  377. package/src/lab/live/sandbox.ts +61 -0
  378. package/src/lab/live/suite-manifest.ts +41 -0
  379. package/src/lab/live/transport.ts +118 -0
  380. package/src/lab/live/types.ts +197 -0
  381. package/src/lab/observe/from-conformance.ts +301 -0
  382. package/src/lab/observe/from-live.ts +117 -0
  383. package/src/lab/paths.ts +153 -0
  384. package/src/lab/projection/rebuild.ts +495 -0
  385. package/src/lab/projection/schema.ts +135 -0
  386. package/src/lab/projection/verdicts.ts +474 -0
  387. package/src/lab/projection/verification.ts +412 -0
  388. package/src/lab/public/bundle.ts +217 -0
  389. package/src/lab/public/community-authority.ts +175 -0
  390. package/src/lab/public/community-files.ts +29 -0
  391. package/src/lab/public/community.ts +479 -0
  392. package/src/lab/public/file-safety.ts +155 -0
  393. package/src/lab/public/ids.ts +26 -0
  394. package/src/lab/public/index.ts +16 -0
  395. package/src/lab/public/mutation-lock.ts +424 -0
  396. package/src/lab/public/operator.ts +353 -0
  397. package/src/lab/public/origin-purge.ts +79 -0
  398. package/src/lab/public/origin.ts +203 -0
  399. package/src/lab/public/privacy.ts +143 -0
  400. package/src/lab/public/private-file.ts +261 -0
  401. package/src/lab/public/project.ts +124 -0
  402. package/src/lab/public/purge-test-fault.ts +21 -0
  403. package/src/lab/public/purge.ts +223 -0
  404. package/src/lab/public/registry.ts +44 -0
  405. package/src/lab/public/revocation.ts +252 -0
  406. package/src/lab/public/signature.ts +243 -0
  407. package/src/lab/public/storage.ts +105 -0
  408. package/src/lab/public/strict-json.ts +206 -0
  409. package/src/lab/public/time.ts +26 -0
  410. package/src/lab/public/types.ts +172 -0
  411. package/src/lab/public/validate.ts +391 -0
  412. package/src/lab/query/catalog.ts +101 -0
  413. package/src/lab/query/connection.ts +107 -0
  414. package/src/lab/query/constants.ts +4 -0
  415. package/src/lab/query/cursor.ts +132 -0
  416. package/src/lab/query/dto-map.ts +277 -0
  417. package/src/lab/query/errors.ts +22 -0
  418. package/src/lab/query/freshness.ts +53 -0
  419. package/src/lab/query/index.ts +45 -0
  420. package/src/lab/query/latest-observation.ts +59 -0
  421. package/src/lab/query/passive-production.ts +159 -0
  422. package/src/lab/query/queries.ts +444 -0
  423. package/src/lab/query/types.ts +266 -0
  424. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  425. package/src/lab/subject/installation-salt.ts +112 -0
  426. package/src/lab/subject/protocol-subject.ts +80 -0
  427. package/src/lab/subject/route-subject.ts +74 -0
  428. package/src/lib/admin-secrets.ts +24 -0
  429. package/src/lib/app-owned-memory-stores.ts +22 -0
  430. package/src/lib/bounded-body.ts +167 -11
  431. package/src/lib/bun-runtime.ts +125 -12
  432. package/src/lib/bun-stream-caps.ts +13 -9
  433. package/src/lib/codex-restart-contract.ts +120 -0
  434. package/src/lib/config-ownership.ts +26 -2
  435. package/src/lib/destination-policy.ts +65 -1
  436. package/src/lib/errors.ts +80 -5
  437. package/src/lib/fabric-task-execution-authority.ts +7 -0
  438. package/src/lib/fabric-task-host.ts +29 -0
  439. package/src/lib/lab-activation.ts +223 -0
  440. package/src/lib/lab-live-execution-authority.ts +13 -0
  441. package/src/lib/lab-live-host.ts +30 -0
  442. package/src/lib/lab-live-pinned-sender.ts +56 -0
  443. package/src/lib/lab-live-route-production.ts +130 -0
  444. package/src/lib/lab-passive-linker-registration.ts +26 -0
  445. package/src/lib/local-management-attestation.ts +51 -0
  446. package/src/lib/local-management-capability.ts +100 -0
  447. package/src/lib/local-provider-reload-contract.ts +100 -0
  448. package/src/lib/optional-shutdown-hooks.ts +57 -0
  449. package/src/lib/package-tree-integrity.ts +101 -0
  450. package/src/lib/pinned-http.ts +145 -26
  451. package/src/lib/process-control.ts +6 -2
  452. package/src/lib/provider-outbound.ts +49 -9
  453. package/src/lib/redact.ts +419 -3
  454. package/src/lib/self-launch-argv.ts +15 -0
  455. package/src/lib/server-resource-ownership.ts +71 -0
  456. package/src/lib/service-secrets.ts +15 -0
  457. package/src/lib/shadow-call.ts +35 -4
  458. package/src/lib/sse-decoder.ts +41 -0
  459. package/src/lib/state-store-registrations.ts +10 -2
  460. package/src/lib/system-restart-contract.ts +73 -0
  461. package/src/lib/token-estimate.ts +19 -2
  462. package/src/lib/tool-argument-integers.ts +253 -0
  463. package/src/lib/translator-budget.ts +44 -0
  464. package/src/lib/upstream-http-version.ts +57 -0
  465. package/src/lib/upstream-reachability.ts +95 -0
  466. package/src/lib/upstream-retry.ts +156 -3
  467. package/src/lib/windows-atomic-replace.ts +155 -0
  468. package/src/lib/windows-elevation.ts +70 -2
  469. package/src/lib/windows-secret-acl.ts +409 -69
  470. package/src/lib/windows-service-wrappers.ts +72 -0
  471. package/src/lib/windows-text.ts +106 -0
  472. package/src/lib/windows-user-principal.ts +341 -0
  473. package/src/lib/winsw.ts +33 -5
  474. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  475. package/src/oauth/account-import/index.ts +15 -0
  476. package/src/oauth/account-import/parser.ts +83 -0
  477. package/src/oauth/account-import/registry.ts +18 -0
  478. package/src/oauth/account-import/service.ts +75 -0
  479. package/src/oauth/account-import/types.ts +91 -0
  480. package/src/oauth/anthropic.ts +12 -1
  481. package/src/oauth/callback-server.ts +30 -4
  482. package/src/oauth/chatgpt.ts +12 -1
  483. package/src/oauth/cline.ts +203 -0
  484. package/src/oauth/command-code.ts +239 -0
  485. package/src/oauth/cursor.ts +46 -5
  486. package/src/oauth/generic-account-failover.ts +231 -0
  487. package/src/oauth/google-antigravity.ts +35 -3
  488. package/src/oauth/health.ts +20 -12
  489. package/src/oauth/index.ts +462 -71
  490. package/src/oauth/key-providers.ts +25 -0
  491. package/src/oauth/kimi.ts +25 -3
  492. package/src/oauth/kiro.ts +95 -6
  493. package/src/oauth/local-token-detect.ts +13 -2
  494. package/src/oauth/log.ts +3 -1
  495. package/src/oauth/login-cli.ts +88 -28
  496. package/src/oauth/nous.ts +798 -0
  497. package/src/oauth/open-browser-choice.ts +26 -0
  498. package/src/oauth/store.ts +133 -26
  499. package/src/oauth/token-guardian.ts +9 -3
  500. package/src/oauth/types.ts +15 -0
  501. package/src/pi/models.ts +2 -2
  502. package/src/providers/alibaba-region-migration.ts +1 -1
  503. package/src/providers/antigravity-models.ts +521 -31
  504. package/src/providers/auto-compact-budget.ts +65 -0
  505. package/src/providers/base-url-choices.ts +10 -0
  506. package/src/providers/codex-capacity.ts +292 -0
  507. package/src/providers/command-code-efforts.ts +176 -0
  508. package/src/providers/context-cap.ts +26 -8
  509. package/src/providers/cursor-pool.ts +72 -0
  510. package/src/providers/default-aliases.ts +65 -0
  511. package/src/providers/derive.ts +281 -6
  512. package/src/providers/fastwire.ts +507 -0
  513. package/src/providers/free-directory.ts +10 -7
  514. package/src/providers/google-vertex-location.ts +14 -0
  515. package/src/providers/key-failover.ts +71 -3
  516. package/src/providers/label.ts +35 -2
  517. package/src/providers/model-discovery-limits.ts +16 -0
  518. package/src/providers/model-discovery.ts +115 -22
  519. package/src/providers/model-presets.ts +119 -0
  520. package/src/providers/model-rename-migration.ts +255 -0
  521. package/src/providers/model-rename-startup.ts +28 -0
  522. package/src/providers/new-model-policy.ts +146 -0
  523. package/src/providers/openai-sidecar.ts +72 -4
  524. package/src/providers/openai-tier-startup.ts +31 -2
  525. package/src/providers/openai-tiers.ts +119 -4
  526. package/src/providers/openai-virtual-models.ts +1 -0
  527. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  528. package/src/providers/provider-id-rewrite.ts +30 -0
  529. package/src/providers/quota.ts +1379 -40
  530. package/src/providers/registry.ts +1545 -112
  531. package/src/providers/request-pacing.ts +310 -0
  532. package/src/providers/service-tier.ts +277 -0
  533. package/src/providers/slug-codec.ts +94 -6
  534. package/src/providers/static-model-discovery.ts +86 -0
  535. package/src/providers/xai-responses-opt-in.ts +15 -0
  536. package/src/providers/xai-transport.ts +32 -4
  537. package/src/reasoning-effort.ts +68 -3
  538. package/src/responses/apply-patch-envelope.ts +63 -0
  539. package/src/responses/code-mode-helper-compat.ts +50 -0
  540. package/src/responses/compaction.ts +26 -1
  541. package/src/responses/custom-tool-compat.ts +384 -0
  542. package/src/responses/hosted-tool-policy.ts +9 -0
  543. package/src/responses/namespace-tool-compat.ts +435 -0
  544. package/src/responses/parser.ts +225 -38
  545. package/src/responses/provider-continuation.ts +98 -0
  546. package/src/responses/provider-opaque-metadata.ts +73 -0
  547. package/src/responses/reasoning-envelope.ts +9 -1
  548. package/src/responses/reasoning-replay-cache.ts +504 -0
  549. package/src/responses/schema.ts +12 -2
  550. package/src/responses/spill-store.ts +75 -10
  551. package/src/responses/state.ts +659 -31
  552. package/src/responses/thought-signature-replay.ts +364 -0
  553. package/src/responses/tool-search-compat.ts +301 -0
  554. package/src/responses/truncated-stop-reason.ts +60 -0
  555. package/src/responses/turn-termination.ts +107 -0
  556. package/src/router.ts +405 -31
  557. package/src/routing/analytics.ts +379 -0
  558. package/src/routing/capability.ts +244 -0
  559. package/src/routing/compatibility/assemble.ts +73 -0
  560. package/src/routing/compatibility/behavior.ts +278 -0
  561. package/src/routing/compatibility/catalog.ts +99 -0
  562. package/src/routing/compatibility/endpoint.ts +52 -0
  563. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  564. package/src/routing/compatibility/policy.ts +181 -0
  565. package/src/routing/compatibility/provider-slot.ts +56 -0
  566. package/src/routing/compatibility/reader.ts +110 -0
  567. package/src/routing/compatibility/subject.ts +191 -0
  568. package/src/routing/compatibility/types.ts +64 -0
  569. package/src/routing/compatibility/version.ts +104 -0
  570. package/src/routing/cost.ts +77 -0
  571. package/src/routing/evaluator.ts +495 -0
  572. package/src/routing/health.ts +412 -0
  573. package/src/routing/history/cursor.ts +43 -0
  574. package/src/routing/history/indexer.ts +605 -0
  575. package/src/routing/history/schema.ts +72 -0
  576. package/src/routing/profile-namespace.ts +15 -0
  577. package/src/routing/profile.ts +547 -0
  578. package/src/routing/quota.ts +155 -0
  579. package/src/routing/request-evidence.ts +45 -0
  580. package/src/routing/trace.ts +776 -0
  581. package/src/server/adapter-resolve.ts +2 -29
  582. package/src/server/auth-cors.ts +289 -48
  583. package/src/server/background-lifecycle.ts +182 -0
  584. package/src/server/chat-completions.ts +154 -72
  585. package/src/server/chat-native-sse.ts +331 -0
  586. package/src/server/chat-native.ts +445 -0
  587. package/src/server/claude-messages.ts +160 -44
  588. package/src/server/direct-local-http.ts +347 -0
  589. package/src/server/effort-policy.ts +18 -0
  590. package/src/server/github-copilot-responses-repair.ts +338 -0
  591. package/src/server/gui-static.ts +39 -10
  592. package/src/server/images.ts +94 -12
  593. package/src/server/index.ts +1021 -190
  594. package/src/server/lifecycle.ts +336 -14
  595. package/src/server/live.ts +136 -17
  596. package/src/server/local-management-read-client.ts +90 -0
  597. package/src/server/local-provider-reload-client.ts +137 -0
  598. package/src/server/management/agent-settings-routes.ts +433 -116
  599. package/src/server/management/api-key-usage.ts +31 -5
  600. package/src/server/management/body.ts +6 -0
  601. package/src/server/management/codex-prompt-routes.ts +570 -0
  602. package/src/server/management/combo-routes.ts +64 -25
  603. package/src/server/management/config-routes.ts +511 -51
  604. package/src/server/management/context.ts +89 -2
  605. package/src/server/management/integration-routes.ts +498 -0
  606. package/src/server/management/lab-automation-routes.ts +206 -0
  607. package/src/server/management/lab-routes.ts +563 -0
  608. package/src/server/management/logs-usage-routes.ts +127 -52
  609. package/src/server/management/model-routes.ts +461 -133
  610. package/src/server/management/model-rows.ts +167 -0
  611. package/src/server/management/native-integration-routes.ts +770 -0
  612. package/src/server/management/oauth-account-routes.ts +90 -8
  613. package/src/server/management/provider-capability-config.ts +48 -0
  614. package/src/server/management/provider-routes.ts +836 -159
  615. package/src/server/management/request-history-routes.ts +191 -0
  616. package/src/server/management/route-registry.ts +332 -0
  617. package/src/server/management/routing-analytics-routes.ts +74 -0
  618. package/src/server/management/routing-profile-routes.ts +380 -0
  619. package/src/server/management/shared.ts +27 -11
  620. package/src/server/management/sidebar-routes.ts +47 -31
  621. package/src/server/management/storage-log-guard-routes.ts +186 -0
  622. package/src/server/management/sync-response.ts +69 -0
  623. package/src/server/management/system-restart.ts +289 -33
  624. package/src/server/management/system-routes.ts +77 -0
  625. package/src/server/management/usage-summary-cache.ts +9 -1
  626. package/src/server/management/vision-sidecar-options.ts +167 -0
  627. package/src/server/management/web-search-sidecar-options.ts +120 -0
  628. package/src/server/management-api.ts +126 -23
  629. package/src/server/management-auth.ts +220 -5
  630. package/src/server/passive-route-linker.ts +66 -0
  631. package/src/server/port-reclaim.ts +1 -1
  632. package/src/server/ports.ts +41 -1
  633. package/src/server/proxy-liveness.ts +161 -10
  634. package/src/server/readiness.ts +99 -0
  635. package/src/server/relay-eager.ts +221 -54
  636. package/src/server/relay.ts +479 -87
  637. package/src/server/request-decompress.ts +113 -6
  638. package/src/server/request-log-conversation.ts +51 -0
  639. package/src/server/request-log.ts +298 -31
  640. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  641. package/src/server/responses/agent-task-recovery.ts +465 -0
  642. package/src/server/responses/codex-auth-error.ts +55 -0
  643. package/src/server/responses/collaboration.ts +239 -36
  644. package/src/server/responses/combo-stream-preflight.ts +178 -0
  645. package/src/server/responses/compact.ts +444 -72
  646. package/src/server/responses/core.ts +3579 -436
  647. package/src/server/responses/empty-completion-guard.ts +333 -0
  648. package/src/server/responses/encrypted-payload.ts +62 -39
  649. package/src/server/responses/fetch-helpers.ts +89 -99
  650. package/src/server/responses/input-admission.ts +187 -0
  651. package/src/server/responses/pacing-overload.ts +13 -0
  652. package/src/server/responses/passthrough-error.ts +33 -9
  653. package/src/server/responses/policy-fallback.ts +178 -0
  654. package/src/server/responses/responses-field-backfill.ts +343 -0
  655. package/src/server/responses/terminal-guard.ts +26 -5
  656. package/src/server/responses/upstream-error.ts +5 -0
  657. package/src/server/responses/ws-upstream.ts +381 -0
  658. package/src/server/responses-custom-tool-repair.ts +363 -0
  659. package/src/server/responses-item-id-repair.ts +54 -6
  660. package/src/server/responses-json-events.ts +90 -0
  661. package/src/server/responses-model-rewrite.ts +29 -0
  662. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  663. package/src/server/responses-snapshot-repair.ts +621 -0
  664. package/src/server/responses-terminal-repair.ts +363 -0
  665. package/src/server/responses-tool-search-repair.ts +267 -0
  666. package/src/server/responses-undeclared-tool-guard.ts +376 -0
  667. package/src/server/responses.ts +18 -2
  668. package/src/server/search.ts +78 -13
  669. package/src/server/sse-frame-buffer.ts +319 -0
  670. package/src/server/sse-payload-rewrite.ts +110 -22
  671. package/src/server/startup-action-control.ts +8 -1
  672. package/src/server/startup-health-cache.ts +19 -1
  673. package/src/server/system-env.ts +80 -9
  674. package/src/server/ws-bridge.ts +53 -40
  675. package/src/service-manager-probe.ts +892 -0
  676. package/src/service.ts +1153 -94
  677. package/src/sidecar/auth.ts +92 -0
  678. package/src/sidecar/candidates.ts +83 -0
  679. package/src/storage/cleanup.ts +2 -2
  680. package/src/storage/policy-job.ts +14 -4
  681. package/src/storage/policy.ts +88 -23
  682. package/src/storage/scanner.ts +1 -1
  683. package/src/storage/worker-lifecycle.ts +14 -14
  684. package/src/tray/windows-tray.ps1 +83 -9
  685. package/src/tray/windows.ts +43 -16
  686. package/src/types/accounts.ts +37 -0
  687. package/src/types/config.ts +911 -0
  688. package/src/types/provider.ts +614 -0
  689. package/src/types/request.ts +397 -0
  690. package/src/types/tools.ts +236 -0
  691. package/src/types/wire.ts +80 -0
  692. package/src/types.ts +107 -1237
  693. package/src/update/index.ts +37 -23
  694. package/src/update/job.ts +445 -68
  695. package/src/update/notify.ts +12 -6
  696. package/src/update/npm-cache-preflight.d.mts +47 -0
  697. package/src/update/npm-cache-preflight.mjs +201 -0
  698. package/src/update/transactional-install.d.mts +22 -0
  699. package/src/update/transactional-install.mjs +266 -0
  700. package/src/usage/cost.ts +0 -0
  701. package/src/usage/expected-prices.ts +287 -16
  702. package/src/usage/log.ts +666 -50
  703. package/src/usage/summary.ts +388 -17
  704. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  705. package/src/usage/user-cost-overlays.ts +314 -0
  706. package/src/vision/anthropic-describe.ts +10 -6
  707. package/src/vision/backends.ts +97 -0
  708. package/src/vision/describe.ts +27 -16
  709. package/src/vision/eligibility.ts +250 -0
  710. package/src/vision/index.ts +238 -24
  711. package/src/vision/reasoning.ts +55 -0
  712. package/src/vision/routed-describe.ts +175 -0
  713. package/src/vision/timeout-bounds.ts +9 -0
  714. package/src/web-search/anthropic-executor.ts +13 -7
  715. package/src/web-search/backends.ts +108 -0
  716. package/src/web-search/exa-executor.ts +119 -0
  717. package/src/web-search/executor.ts +21 -6
  718. package/src/web-search/gemini-executor.ts +141 -0
  719. package/src/web-search/index.ts +150 -15
  720. package/src/web-search/loop.ts +284 -54
  721. package/src/web-search/parse.ts +125 -30
  722. package/src/web-search/sources.ts +60 -0
  723. package/src/web-search/xai-executor.ts +219 -0
  724. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  725. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  726. package/gui/dist/provider-icons/antigravity.svg +0 -1
  727. package/gui/dist/provider-icons/claude.svg +0 -1
  728. package/gui/dist/provider-icons/copilot.svg +0 -1
  729. package/gui/dist/provider-icons/cursor.svg +0 -2
  730. package/gui/dist/provider-icons/gemini.svg +0 -1
  731. package/gui/dist/provider-icons/grok-color.svg +0 -1
  732. package/gui/dist/provider-icons/kiro.svg +0 -14
  733. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,622 @@
1
+ import { NativeProfileManager } from "./native-profile-manager";
2
+ import { clearAccountNeedsReauth } from "./account-runtime-state";
3
+ import { MAIN_CODEX_ACCOUNT_ID } from "./main-account";
4
+ import {
5
+ probeNativeProfileRecoveryState,
6
+ resolveNativeProfileContext,
7
+ type NativeProfileRecoveryState,
8
+ } from "./native-profile-store";
9
+ import {
10
+ retainNativeMainOwner,
11
+ withNativeMainOwnerOperation,
12
+ type NativeMainOwnerOptions,
13
+ type NativeMainOwnerReference,
14
+ type NativeMainOwnerSnapshot,
15
+ } from "./native-main-owner";
16
+ import { withNativeMainExclusiveClaim } from "./native-main-claim";
17
+ import { scrubNativeMainAuthTempResidues } from "./native-main-auth-temp";
18
+ import { NATIVE_STAGE_SWEEP_INTERVAL_MS } from "./native-profile-stage-store";
19
+ import type { NativeCodexOwnership } from "../integrations/native/ownership-preflight";
20
+
21
+ export type NativeMainStartupGateSnapshot =
22
+ | { status: "ready"; homeId: string | null }
23
+ | {
24
+ status: "blocked";
25
+ homeId: string | null;
26
+ reason:
27
+ | "foreign-ownership"
28
+ | "ownership-unknown"
29
+ | "recovery-pending"
30
+ | "manual-recovery"
31
+ | "owner-conflict"
32
+ | "owner-unavailable"
33
+ | "stage-cleanup-required";
34
+ };
35
+
36
+ /** The settled reason a blocked gate carries, named so consumers can hold one without the union. */
37
+ export type NativeMainStartupBlockReason =
38
+ Extract<NativeMainStartupGateSnapshot, { status: "blocked" }>["reason"];
39
+
40
+ export interface NativeMainStartupGateDeps {
41
+ manager?: NativeProfileManager;
42
+ /** Test-only barrier used to prove admission stays closed while startup recovery is pending. */
43
+ beforeRecovery?: () => void | Promise<void>;
44
+ probeRecoveryState?: typeof probeNativeProfileRecoveryState;
45
+ owner?: NativeMainOwnerOptions;
46
+ stageSweepIntervalMs?: number;
47
+ /** Test seam / activation-time revalidation for the ambient physical auth home. */
48
+ currentHomeId?: () => string | null;
49
+ }
50
+
51
+ export interface NativeMainStartupLifecycle {
52
+ readonly homeId: string | null;
53
+ readonly settled: Promise<NativeMainStartupGateSnapshot>;
54
+ release(): Promise<void>;
55
+ }
56
+
57
+ export interface PreparedNativeMainStartupLifecycle {
58
+ readonly homeId: string;
59
+ start(): NativeMainStartupLifecycle;
60
+ }
61
+
62
+ let epoch = 0;
63
+ let snapshot: NativeMainStartupGateSnapshot = { status: "ready", homeId: null };
64
+ let settled: Promise<NativeMainStartupGateSnapshot> = Promise.resolve(snapshot);
65
+ export type NativeMainServiceOwnershipBlockReason =
66
+ | "foreign-ownership"
67
+ | "ownership-unknown";
68
+ const serviceOwnershipRefs = new Map<NativeMainServiceOwnershipBlockReason, number>();
69
+ interface StartupEntry {
70
+ homeId: string;
71
+ refs: number;
72
+ epoch: number;
73
+ owner: NativeMainOwnerReference;
74
+ unsubscribe: () => void;
75
+ recoveryStarted: boolean;
76
+ settled: Promise<NativeMainStartupGateSnapshot>;
77
+ resolveAcquisition?: (value: NativeMainStartupGateSnapshot) => void;
78
+ deps: NativeMainStartupGateDeps;
79
+ manager: NativeProfileManager;
80
+ sweepTimer?: ReturnType<typeof setTimeout>;
81
+ sweepInFlight?: Promise<void>;
82
+ sweepStopping: boolean;
83
+ }
84
+ const startupEntries = new Map<string, StartupEntry>();
85
+ const serverLifecycles = new WeakMap<object, NativeMainStartupLifecycle>();
86
+ const serverLifecycleReleases = new WeakMap<object, Promise<void>>();
87
+
88
+ function ready(homeId: string | null): NativeMainStartupGateSnapshot {
89
+ return { status: "ready", homeId };
90
+ }
91
+
92
+ /**
93
+ * Arm the native-main gate synchronously, then converge the encrypted journal in the background.
94
+ * No credential bytes are read here: journal/auth inspection remains inside NativeProfileManager.
95
+ */
96
+ export function initializeNativeMainStartupGate(
97
+ deps: NativeMainStartupGateDeps = {},
98
+ ): Promise<NativeMainStartupGateSnapshot> {
99
+ const currentEpoch = ++epoch;
100
+ let manager: NativeProfileManager;
101
+ try {
102
+ manager = deps.manager ?? new NativeProfileManager();
103
+ } catch {
104
+ // A missing/unresolvable Codex home cannot provide a usable native-main token either.
105
+ // Do not turn an unused opt-in feature into a process-wide startup outage.
106
+ snapshot = ready(null);
107
+ settled = Promise.resolve(snapshot);
108
+ return settled;
109
+ }
110
+
111
+ const homeId = manager.context.homeId;
112
+ const probe = deps.probeRecoveryState ?? probeNativeProfileRecoveryState;
113
+ let recoveryState: NativeProfileRecoveryState;
114
+ try {
115
+ recoveryState = probe(manager.context);
116
+ } catch {
117
+ snapshot = { status: "blocked", homeId, reason: "manual-recovery" };
118
+ settled = Promise.resolve(snapshot);
119
+ return settled;
120
+ }
121
+ if (recoveryState === "none") {
122
+ snapshot = ready(homeId);
123
+ settled = Promise.resolve(snapshot);
124
+ return settled;
125
+ }
126
+
127
+ if (recoveryState !== "journal") {
128
+ snapshot = { status: "blocked", homeId, reason: "manual-recovery" };
129
+ settled = Promise.resolve(snapshot);
130
+ return settled;
131
+ }
132
+
133
+ snapshot = { status: "blocked", homeId, reason: "recovery-pending" };
134
+ settled = (async () => {
135
+ try {
136
+ await deps.beforeRecovery?.();
137
+ await manager.recover(false);
138
+ if (epoch === currentEpoch && probe(manager.context) === "none") {
139
+ clearAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID);
140
+ snapshot = ready(homeId);
141
+ } else if (epoch === currentEpoch) {
142
+ snapshot = { status: "blocked", homeId, reason: "manual-recovery" };
143
+ }
144
+ } catch {
145
+ if (epoch === currentEpoch) snapshot = { status: "blocked", homeId, reason: "manual-recovery" };
146
+ }
147
+ return snapshot;
148
+ })();
149
+ return settled;
150
+ }
151
+
152
+ function ownerBlockedReason(owner: NativeMainOwnerSnapshot): "owner-conflict" | "owner-unavailable" {
153
+ return owner.status === "unavailable" ? "owner-unavailable" : "owner-conflict";
154
+ }
155
+
156
+ async function runOwnedStageSweep(entry: StartupEntry): Promise<boolean> {
157
+ if (typeof (entry.manager as Partial<NativeProfileManager>).sweepStages !== "function") return true;
158
+ // A fresh installation has no stage registry or staging tree. Avoid creating
159
+ // and contending on the profile transaction database for an inert subsystem.
160
+ // Real managers treat every present or uncertain artifact as sweep-required;
161
+ // partial test/library managers without the preflight keep the old behavior.
162
+ if (
163
+ typeof (entry.manager as Partial<NativeProfileManager>).stageSweepRequired === "function"
164
+ && !entry.manager.stageSweepRequired()
165
+ ) return true;
166
+ try {
167
+ const result = await withNativeMainOwnerOperation(entry.manager.context, () => entry.manager.sweepStages());
168
+ return !result.plaintextMayRemain;
169
+ } catch {
170
+ return false;
171
+ }
172
+ }
173
+
174
+ function scheduleStageSweep(entry: StartupEntry): void {
175
+ if (entry.sweepStopping || entry.sweepTimer || startupEntries.get(entry.homeId) !== entry) return;
176
+ const intervalMs = Math.max(10, entry.deps.stageSweepIntervalMs ?? NATIVE_STAGE_SWEEP_INTERVAL_MS);
177
+ entry.sweepTimer = setTimeout(() => {
178
+ entry.sweepTimer = undefined;
179
+ if (entry.sweepStopping || startupEntries.get(entry.homeId) !== entry) return;
180
+ entry.sweepInFlight = (async () => {
181
+ const safe = await runOwnedStageSweep(entry);
182
+ if (entry.sweepStopping || startupEntries.get(entry.homeId) !== entry) return;
183
+ if (!safe) snapshot = { status: "blocked", homeId: entry.homeId, reason: "stage-cleanup-required" };
184
+ else if (snapshot.homeId === entry.homeId && snapshot.status === "blocked" && snapshot.reason === "stage-cleanup-required") {
185
+ snapshot = ready(entry.homeId);
186
+ }
187
+ })().finally(() => {
188
+ entry.sweepInFlight = undefined;
189
+ scheduleStageSweep(entry);
190
+ });
191
+ }, intervalMs);
192
+ entry.sweepTimer.unref?.();
193
+ }
194
+
195
+ function convergeOwnedStartup(entry: StartupEntry): void {
196
+ if (entry.recoveryStarted) return;
197
+ entry.recoveryStarted = true;
198
+ const currentEpoch = entry.epoch;
199
+ snapshot = { status: "blocked", homeId: entry.homeId, reason: "recovery-pending" };
200
+ const acquisitionWaiter = entry.resolveAcquisition;
201
+ entry.resolveAcquisition = undefined;
202
+ entry.settled = settled = (async () => {
203
+ const probe = entry.deps.probeRecoveryState ?? probeNativeProfileRecoveryState;
204
+ try {
205
+ const recoveryState = await withNativeMainOwnerOperation(entry.manager.context, () => withNativeMainExclusiveClaim(
206
+ entry.manager.context,
207
+ async () => {
208
+ scrubNativeMainAuthTempResidues(entry.manager.context);
209
+ let state = probe(entry.manager.context);
210
+ if (state === "journal") {
211
+ await entry.deps.beforeRecovery?.();
212
+ await entry.manager.recover(false);
213
+ state = probe(entry.manager.context);
214
+ }
215
+ return state;
216
+ },
217
+ { waitMs: 10_000 },
218
+ ));
219
+ const stageSweepSafe = recoveryState === "none" ? await runOwnedStageSweep(entry) : false;
220
+ if (startupEntries.get(entry.homeId) === entry && entry.epoch === currentEpoch && recoveryState === "none" && stageSweepSafe) {
221
+ clearAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID);
222
+ snapshot = ready(entry.homeId);
223
+ } else if (startupEntries.get(entry.homeId) === entry && entry.epoch === currentEpoch && recoveryState === "none") {
224
+ snapshot = { status: "blocked", homeId: entry.homeId, reason: "stage-cleanup-required" };
225
+ } else if (startupEntries.get(entry.homeId) === entry && entry.epoch === currentEpoch) {
226
+ snapshot = { status: "blocked", homeId: entry.homeId, reason: "manual-recovery" };
227
+ }
228
+ } catch {
229
+ if (startupEntries.get(entry.homeId) === entry && entry.epoch === currentEpoch) {
230
+ snapshot = { status: "blocked", homeId: entry.homeId, reason: "manual-recovery" };
231
+ }
232
+ }
233
+ if (startupEntries.get(entry.homeId) === entry && entry.epoch === currentEpoch) scheduleStageSweep(entry);
234
+ return snapshot;
235
+ })();
236
+ if (acquisitionWaiter) void entry.settled.then(acquisitionWaiter);
237
+ }
238
+
239
+ function observeOwner(entry: StartupEntry, owner: NativeMainOwnerSnapshot): void {
240
+ if (startupEntries.get(entry.homeId) !== entry) return;
241
+ if (owner.status === "acquiring") {
242
+ snapshot = { status: "blocked", homeId: entry.homeId, reason: "recovery-pending" };
243
+ return;
244
+ }
245
+ if (owner.status === "held") {
246
+ convergeOwnedStartup(entry);
247
+ return;
248
+ }
249
+ if (owner.status === "closing" || owner.status === "released") return;
250
+ snapshot = { status: "blocked", homeId: entry.homeId, reason: ownerBlockedReason(owner) };
251
+ entry.settled = settled = Promise.resolve(snapshot);
252
+ entry.resolveAcquisition?.(snapshot);
253
+ entry.resolveAcquisition = undefined;
254
+ }
255
+
256
+ /**
257
+ * Retain process ownership for one live server. The first reference acquires the
258
+ * canonical-home SQLite lease and owns recovery; later same-process references share it.
259
+ */
260
+ export function startNativeMainStartupLifecycle(
261
+ deps: NativeMainStartupGateDeps = {},
262
+ ): NativeMainStartupLifecycle {
263
+ let manager: NativeProfileManager;
264
+ try {
265
+ manager = deps.manager ?? new NativeProfileManager();
266
+ } catch {
267
+ snapshot = ready(null);
268
+ settled = Promise.resolve(snapshot);
269
+ return { homeId: null, settled, release: async () => {} };
270
+ }
271
+ const homeId = manager.context.homeId;
272
+ let entry = startupEntries.get(homeId);
273
+ if (!entry) {
274
+ const owner = retainNativeMainOwner(manager.context, deps.owner);
275
+ snapshot = { status: "blocked", homeId, reason: "recovery-pending" };
276
+ let resolveAcquisition!: (value: NativeMainStartupGateSnapshot) => void;
277
+ const acquisition = new Promise<NativeMainStartupGateSnapshot>(resolve => { resolveAcquisition = resolve; });
278
+ settled = acquisition;
279
+ entry = {
280
+ homeId,
281
+ refs: 0,
282
+ epoch: ++epoch,
283
+ owner,
284
+ unsubscribe: () => {},
285
+ recoveryStarted: false,
286
+ settled: acquisition,
287
+ resolveAcquisition,
288
+ deps,
289
+ manager,
290
+ sweepStopping: false,
291
+ };
292
+ startupEntries.set(homeId, entry);
293
+ entry.unsubscribe = owner.subscribe(ownerState => observeOwner(entry!, ownerState));
294
+ }
295
+ entry.refs += 1;
296
+ let released = false;
297
+ return {
298
+ homeId,
299
+ get settled() { return entry!.settled; },
300
+ async release() {
301
+ if (released) return;
302
+ released = true;
303
+ entry!.refs = Math.max(0, entry!.refs - 1);
304
+ if (entry!.refs !== 0) return;
305
+ entry!.epoch += 1;
306
+ entry!.sweepStopping = true;
307
+ if (entry!.sweepTimer) clearTimeout(entry!.sweepTimer);
308
+ entry!.sweepTimer = undefined;
309
+ entry!.unsubscribe();
310
+ startupEntries.delete(homeId);
311
+ entry!.resolveAcquisition?.(snapshot);
312
+ entry!.resolveAcquisition = undefined;
313
+ // Startup convergence can transition from the exclusive recovery claim
314
+ // into a stage sweep. Keep the owner registered until that entire chain
315
+ // settles so no cleanup transaction starts untracked after owner detach.
316
+ await Promise.allSettled([entry!.settled]);
317
+ if (entry!.sweepInFlight) await Promise.allSettled([entry!.sweepInFlight]);
318
+ await entry!.owner.release();
319
+ },
320
+ };
321
+ }
322
+
323
+ /** Resolve and pin the owned lifecycle target without acquiring ownership or creating artifacts. */
324
+ export function prepareNativeMainStartupLifecycle(
325
+ deps: NativeMainStartupGateDeps = {},
326
+ homes?: { codexHome: string; configDir: string },
327
+ ): PreparedNativeMainStartupLifecycle | null {
328
+ let manager: NativeProfileManager;
329
+ try {
330
+ manager = deps.manager ?? new NativeProfileManager(homes);
331
+ if (homes) {
332
+ const expected = resolveNativeProfileContext(homes);
333
+ if (
334
+ manager.context.homeId !== expected.homeId
335
+ || manager.context.instanceId !== expected.instanceId
336
+ ) return null;
337
+ }
338
+ } catch {
339
+ return null;
340
+ }
341
+ const currentHomeId = deps.currentHomeId ?? (() => {
342
+ try { return resolveNativeProfileContext().homeId; } catch { return null; }
343
+ });
344
+ const pinnedDeps = { ...deps, manager };
345
+ return {
346
+ homeId: manager.context.homeId,
347
+ start: () => {
348
+ if (currentHomeId() !== manager.context.homeId) {
349
+ throw new Error("The native-main startup home changed after ownership inspection.");
350
+ }
351
+ return startNativeMainStartupLifecycle(pinnedDeps);
352
+ },
353
+ };
354
+ }
355
+
356
+ /**
357
+ * How many times a service-ownership fence will re-ask before it stops asking (#2108).
358
+ *
359
+ * A host that is permanently unaskable must not re-probe on every request forever, and a
360
+ * host that recovers usually does so within the first few. The budget belongs to the
361
+ * live hook owner, not to an individual fence: raising a second fence deliberately does
362
+ * not hand out a fresh allowance, or a caller looping over fences could spin the probe
363
+ * forever. Spending or releasing that hook owner ends its budget generation; a later
364
+ * fence can install a new owner even if an older hookless fence is still draining.
365
+ */
366
+ export const NATIVE_MAIN_OWNERSHIP_RETRY_LIMIT = 5;
367
+
368
+ /** Reprobe hooks for the fences currently held, keyed by the reason they were raised for. */
369
+ const serviceOwnershipReprobes = new Map<NativeMainServiceOwnershipBlockReason, ServiceOwnershipReprobe>();
370
+
371
+ interface ServiceOwnershipReprobe {
372
+ readonly probe: () => NativeCodexOwnership;
373
+ readonly expectedHomeId: () => string | null;
374
+ readonly activate: () => NativeMainStartupLifecycle;
375
+ readonly adopt: (lifecycle: NativeMainStartupLifecycle) => boolean;
376
+ readonly discard: (lifecycle: NativeMainStartupLifecycle) => void;
377
+ activating: boolean;
378
+ attempts: number;
379
+ /** The fence that installed this hook; only its own release may drop the entry. */
380
+ readonly owner: NativeMainStartupLifecycle;
381
+ /** Releases the fence that installed this hook, exactly once. */
382
+ readonly spend: () => void;
383
+ }
384
+
385
+ function releaseUnadoptedLifecycle(lifecycle: NativeMainStartupLifecycle): Promise<void> {
386
+ try { return Promise.resolve(lifecycle.release()).catch(() => {}); } catch { return Promise.resolve(); }
387
+ }
388
+
389
+ /** Test-only: the retry budget is module state and would otherwise leak across tests. */
390
+ export function __resetNativeMainOwnershipRetries(): void {
391
+ for (const entry of serviceOwnershipReprobes.values()) entry.attempts = 0;
392
+ }
393
+
394
+ /**
395
+ * Re-ask whether this host is still unownable, and drop the fence if it is not.
396
+ *
397
+ * `startServer` takes the ownership verdict once, at boot, and holds it for the process
398
+ * lifetime. For `foreign-ownership` that is correct — a foreign owner is a fact, and
399
+ * re-asking would only hand a determined caller a second chance. For `ownership-unknown`
400
+ * it is wrong: that verdict means the probe could not answer, so waiting cannot help,
401
+ * which is precisely why the #2108 reporter had to run `ocx restart` after every reboot.
402
+ *
403
+ * The re-probe is demand-driven rather than timed: it runs when something asks whether
404
+ * native-main is fenced, which is usually a request but is also the background token
405
+ * guardian's warmup. It is capped so a permanently unaskable host cannot spin.
406
+ *
407
+ * The probe is synchronous `spawnSync` with a bounded timeout, and this function is on a
408
+ * request path, so the cap is what keeps a wedged host from paying that cost repeatedly.
409
+ */
410
+ function reprobeServiceOwnership(reason: NativeMainServiceOwnershipBlockReason): boolean {
411
+ if (reason !== "ownership-unknown") return false;
412
+ const entry = serviceOwnershipReprobes.get(reason);
413
+ if (!entry) return false;
414
+ if (entry.activating) return false;
415
+ if (entry.attempts >= NATIVE_MAIN_OWNERSHIP_RETRY_LIMIT) return false;
416
+ entry.attempts += 1;
417
+ let activated: NativeMainStartupLifecycle | undefined;
418
+ let expectedHomeId: string | null = null;
419
+ entry.activating = true;
420
+ try {
421
+ const answer = entry.probe();
422
+ if (answer !== "owned") return false;
423
+ expectedHomeId = entry.expectedHomeId();
424
+ if (expectedHomeId === null) return false;
425
+ // Ownership becoming knowable is not itself startup completion. Install the
426
+ // normal owner/recovery lifecycle while this fence is still held, so native
427
+ // traffic cannot get ahead of owner registration, journal recovery, auth-temp
428
+ // scrubbing, or the initial stage sweep.
429
+ activated = entry.activate();
430
+ } catch {
431
+ // Neither a failed inspection nor a failed activation is evidence that
432
+ // native-main is safe to admit. Keep the fence and retry hook intact.
433
+ return false;
434
+ } finally {
435
+ entry.activating = false;
436
+ }
437
+ if (
438
+ !activated
439
+ || activated.homeId === null
440
+ || activated.homeId !== expectedHomeId
441
+ || typeof activated.release !== "function"
442
+ ) {
443
+ if (activated && typeof activated.release === "function") entry.discard(activated);
444
+ return false;
445
+ }
446
+ if (serviceOwnershipReprobes.get(reason) !== entry || !entry.adopt(activated)) {
447
+ // Shutdown or a re-entrant release can retire this fence while activation
448
+ // runs. A lifecycle that was never attached to the server must not retain
449
+ // another owner reference in the background.
450
+ entry.discard(activated);
451
+ return false;
452
+ }
453
+ // Release through the fence that installed this hook, and only that one.
454
+ //
455
+ // Several servers can hold a fence for the same reason while only one carries a hook, so
456
+ // clearing the shared refcount here would unblock fences this probe never spoke for.
457
+ // Decrementing here directly is just as wrong the other way: that fence's own release()
458
+ // would then pay a second time for one fence, leaving the count short. The
459
+ // fence's idempotent spend hook keeps exactly one payment per fence while the
460
+ // transitioned owned lifecycle remains attached until server shutdown.
461
+ entry.spend();
462
+ return true;
463
+ }
464
+
465
+ function activeServiceOwnershipBlockReason(): NativeMainServiceOwnershipBlockReason | null {
466
+ if ((serviceOwnershipRefs.get("foreign-ownership") ?? 0) > 0) return "foreign-ownership";
467
+ if ((serviceOwnershipRefs.get("ownership-unknown") ?? 0) > 0) return "ownership-unknown";
468
+ return null;
469
+ }
470
+
471
+ function serviceOwnershipSnapshot(
472
+ reason: NativeMainServiceOwnershipBlockReason,
473
+ ): NativeMainStartupGateSnapshot {
474
+ return { status: "blocked", homeId: null, reason };
475
+ }
476
+
477
+ /** Close native-main admission without resolving or creating any CODEX_HOME artifacts. */
478
+ export function blockNativeMainStartupForUnownedServiceHome(
479
+ reason: NativeMainServiceOwnershipBlockReason,
480
+ options?: {
481
+ reprobe: () => NativeCodexOwnership;
482
+ expectedHomeId: string | (() => string | null);
483
+ startOwnedLifecycle: () => NativeMainStartupLifecycle;
484
+ },
485
+ ): NativeMainStartupLifecycle {
486
+ serviceOwnershipRefs.set(reason, (serviceOwnershipRefs.get(reason) ?? 0) + 1);
487
+ let fenceSpent = false;
488
+ let ownedLifecycle: NativeMainStartupLifecycle | undefined;
489
+ let releaseFlight: Promise<void> | undefined;
490
+ const orphanReleaseFlights = new Set<Promise<void>>();
491
+ let lifecycle!: NativeMainStartupLifecycle;
492
+ const blockedSettled = Promise.resolve(serviceOwnershipSnapshot(reason));
493
+ const spendFence = () => {
494
+ if (fenceSpent) return;
495
+ fenceSpent = true;
496
+ const remaining = Math.max(0, (serviceOwnershipRefs.get(reason) ?? 0) - 1);
497
+ if (remaining === 0) serviceOwnershipRefs.delete(reason);
498
+ else serviceOwnershipRefs.set(reason, remaining);
499
+ if (serviceOwnershipReprobes.get(reason)?.owner === lifecycle) {
500
+ serviceOwnershipReprobes.delete(reason);
501
+ }
502
+ };
503
+ lifecycle = {
504
+ get homeId() { return ownedLifecycle?.homeId ?? null; },
505
+ get settled() { return ownedLifecycle?.settled ?? blockedSettled; },
506
+ release() {
507
+ return releaseFlight ??= (async () => {
508
+ spendFence();
509
+ // A synchronous activator can re-enter release before its returned
510
+ // lifecycle is adopted or discarded. Let that call stack finish so the
511
+ // cleanup set is complete before this shared release flight drains it.
512
+ await Promise.resolve();
513
+ await ownedLifecycle?.release();
514
+ if (orphanReleaseFlights.size > 0) {
515
+ await Promise.allSettled([...orphanReleaseFlights]);
516
+ }
517
+ })();
518
+ },
519
+ };
520
+ // Do NOT reset an existing budget: keying the reprobe by reason means a caller raising
521
+ // fences in a loop would otherwise be handed a fresh allowance each time and could spin
522
+ // the probe forever. But once the holder is gone its entry is removed above, so a LATER
523
+ // fence installs its own hook — a server started after an earlier probe must not be left
524
+ // needing `ocx restart`, which is the very symptom this exists to remove.
525
+ if (options && reason === "ownership-unknown" && !serviceOwnershipReprobes.has(reason)) {
526
+ const expectedHomeId = options.expectedHomeId;
527
+ serviceOwnershipReprobes.set(reason, {
528
+ probe: options.reprobe,
529
+ expectedHomeId: typeof expectedHomeId === "function"
530
+ ? expectedHomeId
531
+ : () => expectedHomeId,
532
+ activate: options.startOwnedLifecycle,
533
+ adopt: activated => {
534
+ if (releaseFlight !== undefined || fenceSpent || ownedLifecycle !== undefined) return false;
535
+ ownedLifecycle = activated;
536
+ return true;
537
+ },
538
+ discard: activated => {
539
+ const flight = releaseUnadoptedLifecycle(activated);
540
+ orphanReleaseFlights.add(flight);
541
+ void flight.finally(() => orphanReleaseFlights.delete(flight));
542
+ },
543
+ activating: false,
544
+ attempts: 0,
545
+ owner: lifecycle,
546
+ spend: spendFence,
547
+ });
548
+ }
549
+ return lifecycle;
550
+ }
551
+
552
+ export function bindNativeMainStartupLifecycle(server: object, lifecycle: NativeMainStartupLifecycle): void {
553
+ serverLifecycles.set(server, lifecycle);
554
+ }
555
+
556
+ export async function releaseNativeMainStartupLifecycle(server: object): Promise<void> {
557
+ const existing = serverLifecycleReleases.get(server);
558
+ if (existing) return existing;
559
+ const lifecycle = serverLifecycles.get(server);
560
+ if (!lifecycle) return;
561
+ const flight = Promise.resolve().then(() => lifecycle.release());
562
+ serverLifecycleReleases.set(server, flight);
563
+ try {
564
+ await flight;
565
+ } finally {
566
+ if (serverLifecycleReleases.get(server) === flight) {
567
+ serverLifecycleReleases.delete(server);
568
+ serverLifecycles.delete(server);
569
+ }
570
+ }
571
+ }
572
+
573
+ export function isNativeMainTrafficBlocked(): boolean {
574
+ const reason = activeServiceOwnershipBlockReason();
575
+ if (reason !== null && reprobeServiceOwnership(reason)) {
576
+ // The host became ownable after boot (#2108): the fence lifts here rather than
577
+ // waiting for the restart the reporter had to perform by hand.
578
+ return activeServiceOwnershipBlockReason() !== null || snapshot.status === "blocked";
579
+ }
580
+ return reason !== null || snapshot.status === "blocked";
581
+ }
582
+
583
+ /**
584
+ * Close the process-wide native-main admission gate after a live transaction
585
+ * leaves recovery state behind. A known different home owns a different
586
+ * native credential file, so it must not be fenced by this transition.
587
+ */
588
+ export function blockNativeMainRecovery(
589
+ homeId: string,
590
+ recoveryState?: Exclude<NativeProfileRecoveryState, "none">,
591
+ ): boolean {
592
+ if (snapshot.homeId !== null && snapshot.homeId !== homeId) return false;
593
+ epoch += 1;
594
+ snapshot = {
595
+ status: "blocked",
596
+ homeId,
597
+ reason: recoveryState === "journal" ? "recovery-pending" : "manual-recovery",
598
+ };
599
+ settled = Promise.resolve(snapshot);
600
+ return true;
601
+ }
602
+
603
+ export function completeNativeMainRecovery(homeId: string): boolean {
604
+ if (snapshot.status !== "blocked" || snapshot.homeId !== homeId) return false;
605
+ epoch += 1;
606
+ clearAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID);
607
+ snapshot = ready(homeId);
608
+ settled = Promise.resolve(snapshot);
609
+ return true;
610
+ }
611
+
612
+ export function nativeMainStartupGateSnapshot(): NativeMainStartupGateSnapshot {
613
+ const reason = activeServiceOwnershipBlockReason();
614
+ if (reason) return serviceOwnershipSnapshot(reason);
615
+ return { ...snapshot };
616
+ }
617
+
618
+ export function waitForNativeMainStartupGate(): Promise<NativeMainStartupGateSnapshot> {
619
+ const reason = activeServiceOwnershipBlockReason();
620
+ if (reason) return Promise.resolve(serviceOwnershipSnapshot(reason));
621
+ return settled;
622
+ }