@bitkyc08/opencodex 2.86.0 → 2.87.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 (378) hide show
  1. package/gui/dist/assets/App-ZfYbLHkB.js +58 -0
  2. package/gui/dist/assets/App-wT3mXqFz.css +1 -0
  3. package/gui/dist/assets/{Tray-DyR9yBee.js → Tray-DCd-A1az.js} +1 -1
  4. package/gui/dist/assets/index-CfYDMj34.js +94 -0
  5. package/gui/dist/assets/index-DPeB9HpV.css +1 -0
  6. package/gui/dist/assets/quota-summary-ChvmKGOk.js +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/package.json +1 -1
  9. package/src/adapters/anthropic/beta-allowlist.ts +9 -8
  10. package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
  11. package/src/adapters/anthropic/passthrough.ts +7 -23
  12. package/src/adapters/anthropic-progress.ts +84 -0
  13. package/src/adapters/anthropic.ts +108 -21
  14. package/src/adapters/base.ts +2 -0
  15. package/src/adapters/claude-cli/adapter.ts +111 -23
  16. package/src/adapters/claude-cli/profiles.ts +2 -1
  17. package/src/adapters/claude-cli/stable-replay.ts +108 -0
  18. package/src/adapters/claude-cli/usage-admission.ts +230 -0
  19. package/src/adapters/coding-agent/protocol.ts +1 -1
  20. package/src/adapters/coding-agent/turn.ts +18 -2
  21. package/src/adapters/dsh-account.ts +97 -0
  22. package/src/adapters/google.ts +35 -8
  23. package/src/adapters/openai-chat/messages.ts +4 -3
  24. package/src/adapters/openai-chat/passthrough.ts +8 -2
  25. package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
  26. package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
  27. package/src/adapters/openai-responses/passthrough.ts +57 -125
  28. package/src/adapters/openai-responses/request-strips.ts +25 -3
  29. package/src/adapters/openai-responses/transport.ts +81 -0
  30. package/src/adapters/qoder/adapter.ts +4 -2
  31. package/src/adapters/registry.ts +5 -0
  32. package/src/adapters/zed.ts +26 -1
  33. package/src/advisor/activity.ts +55 -0
  34. package/src/advisor/budget.ts +62 -0
  35. package/src/advisor/consult.ts +4 -1
  36. package/src/advisor/context.ts +16 -4
  37. package/src/advisor/evidence-tool.ts +21 -0
  38. package/src/advisor/evidence.ts +117 -0
  39. package/src/advisor/runtime.ts +79 -31
  40. package/src/advisor/settings.ts +11 -2
  41. package/src/bridge/errors.ts +19 -1
  42. package/src/bridge/internal.ts +3 -1
  43. package/src/bridge/response-json.ts +18 -3
  44. package/src/bridge/sse.ts +58 -8
  45. package/src/bridge/terminal-refusal.ts +59 -0
  46. package/src/claude/desktop-3p-library.ts +32 -7
  47. package/src/claude/desktop-3p.ts +55 -13
  48. package/src/claude/desktop-first-party.ts +1 -1
  49. package/src/claude/desktop-picker-platform.ts +4 -0
  50. package/src/claude/desktop-picker.ts +15 -8
  51. package/src/claude/desktop-system-proxy.ts +50 -4
  52. package/src/claude/inbound-content-options.ts +11 -0
  53. package/src/claude/inbound.ts +33 -0
  54. package/src/claude/intercept/picker-ca-startup.ts +2 -1
  55. package/src/claude/intercept/picker-runtime.ts +6 -5
  56. package/src/claude/intercept/picker-trust-windows.ts +338 -0
  57. package/src/claude/intercept/picker-trust.ts +19 -0
  58. package/src/claude/intercept/port-policy.ts +30 -0
  59. package/src/claude/intercept/runtime.ts +97 -94
  60. package/src/claude/outbound.ts +38 -13
  61. package/src/cli/account-api.ts +1 -0
  62. package/src/cli/account-policy-dto.ts +6 -0
  63. package/src/cli/account-policy.ts +34 -5
  64. package/src/cli/account-preservation.ts +44 -0
  65. package/src/cli/account.ts +8 -2
  66. package/src/cli/advisor.ts +17 -3
  67. package/src/cli/capabilities-accounts.ts +20 -1
  68. package/src/cli/capabilities-agents-routing.ts +5 -2
  69. package/src/cli/capabilities-base.ts +38 -10
  70. package/src/cli/capabilities-observe-system.ts +63 -3
  71. package/src/cli/capabilities-provider-models.ts +11 -0
  72. package/src/cli/codex-cli-update.ts +151 -41
  73. package/src/cli/codex-provider.ts +44 -0
  74. package/src/cli/combo-input.ts +10 -1
  75. package/src/cli/combo-result.ts +1 -1
  76. package/src/cli/combo.ts +2 -1
  77. package/src/cli/cross-home-owner.ts +17 -14
  78. package/src/cli/dispatch.ts +25 -4
  79. package/src/cli/doctor.ts +6 -1
  80. package/src/cli/ensure-desktop-cold-start.ts +60 -7
  81. package/src/cli/help.ts +3 -2
  82. package/src/cli/index.ts +1 -1
  83. package/src/cli/integration-plan-dto.ts +1 -0
  84. package/src/cli/log-history.ts +172 -0
  85. package/src/cli/models-runtime-subcommands.ts +1 -0
  86. package/src/cli/models-runtime.ts +72 -8
  87. package/src/cli/observe-stream.ts +2 -0
  88. package/src/cli/observe.ts +16 -4
  89. package/src/cli/provider.ts +27 -5
  90. package/src/cli/registry.ts +28 -8
  91. package/src/cli/runtime-api.ts +5 -3
  92. package/src/cli/system-command.ts +40 -8
  93. package/src/cli/uninstall-client-state.ts +32 -0
  94. package/src/cli/usage-compare.ts +309 -0
  95. package/src/cli/usage-model-search.ts +4 -4
  96. package/src/cli/usage-report.ts +2 -2
  97. package/src/cli/v2.ts +1 -1
  98. package/src/client/machine-listener.ts +1 -3
  99. package/src/client/runtime.ts +1 -0
  100. package/src/clients/client-path.ts +51 -0
  101. package/src/clients/config-export/contracts.ts +2 -1
  102. package/src/clients/config-export.ts +18 -44
  103. package/src/clients/gentle-shell-path.ts +87 -0
  104. package/src/codex/account-auto-switch.ts +2 -0
  105. package/src/codex/account-identity.ts +29 -0
  106. package/src/codex/account-label.ts +1 -1
  107. package/src/codex/account-lifecycle.ts +21 -5
  108. package/src/codex/account-preservation.ts +28 -0
  109. package/src/codex/account-use-remaining.ts +23 -0
  110. package/src/codex/app-server-processes.ts +97 -7
  111. package/src/codex/app-server-restart-service.ts +55 -4
  112. package/src/codex/auth-api/account-list.ts +4 -0
  113. package/src/codex/auth-api/account-pause-group.ts +6 -50
  114. package/src/codex/auth-api/account-preservation.ts +57 -0
  115. package/src/codex/auth-api/routes.ts +8 -0
  116. package/src/codex/auth-api/use-remaining-route.ts +36 -0
  117. package/src/codex/auth-api.ts +0 -1
  118. package/src/codex/auth-context.ts +2 -2
  119. package/src/codex/catalog/auto-review.ts +20 -3
  120. package/src/codex/catalog/build-entries.ts +9 -1
  121. package/src/codex/catalog/combo-member.ts +14 -5
  122. package/src/codex/catalog/configured-tiers.ts +1 -1
  123. package/src/codex/catalog/gather-capture.ts +2 -0
  124. package/src/codex/catalog/metadata.ts +11 -9
  125. package/src/codex/catalog/model-hints.ts +21 -16
  126. package/src/codex/catalog/model-visibility.ts +3 -1
  127. package/src/codex/catalog/parsing.ts +30 -86
  128. package/src/codex/catalog/provider-models.ts +36 -34
  129. package/src/codex/catalog/routed-gather.ts +12 -13
  130. package/src/codex/cli-install-provenance.ts +105 -17
  131. package/src/codex/cli-update-plan.ts +545 -0
  132. package/src/codex/config-write-lock.ts +23 -2
  133. package/src/codex/desktop-app/picker-freshness.ts +96 -0
  134. package/src/codex/desktop-app-restart.ts +21 -0
  135. package/src/codex/desktop-compatibility/installed-build.ts +24 -6
  136. package/src/codex/desktop-compatibility/routing-preflight.ts +1 -1
  137. package/src/codex/desktop-compatibility/runtime.ts +12 -3
  138. package/src/codex/desktop-compatibility/windows-key-protection.ts +115 -9
  139. package/src/codex/features.ts +85 -45
  140. package/src/codex/inject/history-failure.ts +27 -0
  141. package/src/codex/inject/restore.ts +24 -2
  142. package/src/codex/inject/routing-classify.ts +4 -3
  143. package/src/codex/inject.ts +18 -27
  144. package/src/codex/main-account-hard-lock.ts +30 -1
  145. package/src/codex/native-profile-startup.ts +1 -1
  146. package/src/codex/ocx-compaction-history.ts +12 -10
  147. package/src/codex/paths.ts +86 -1
  148. package/src/codex/provider-routing.ts +174 -0
  149. package/src/codex/refresh.ts +2 -2
  150. package/src/codex/routing/health-store.ts +1 -1
  151. package/src/codex/routing/selection.ts +4 -3
  152. package/src/codex/routing/thread-affinity.ts +1 -1
  153. package/src/codex/signed-in-identity.ts +43 -0
  154. package/src/codex/subagent-model-fallback.ts +1 -1
  155. package/src/codex/sync.ts +6 -1
  156. package/src/codex/user-identity.ts +16 -5
  157. package/src/codex/windows-local-appdata.ts +84 -0
  158. package/src/combos/failover.ts +6 -1
  159. package/src/combos/index.ts +1 -0
  160. package/src/combos/resolve.ts +46 -10
  161. package/src/combos/types.ts +15 -0
  162. package/src/config/diagnostics.ts +33 -6
  163. package/src/config/live-reconcile.ts +38 -2
  164. package/src/config/load-degrade.ts +17 -0
  165. package/src/config/opencode-wire-upgrade.ts +54 -0
  166. package/src/config/opencode-zen-upgrade.ts +52 -0
  167. package/src/config/owner-registry.ts +22 -17
  168. package/src/config/provider-validation.ts +45 -2
  169. package/src/config/schema/config-schema.ts +22 -0
  170. package/src/config/schema/leaf-validators.ts +38 -9
  171. package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
  172. package/src/config/schema/native-reasoning-retention.ts +26 -0
  173. package/src/config.ts +2 -0
  174. package/src/generated/compatibility-version.json +608 -284
  175. package/src/grok/sync.ts +1 -1
  176. package/src/images/loop.ts +46 -8
  177. package/src/integrations/catalog-refresh.ts +1 -1
  178. package/src/integrations/mutation-plan.ts +1 -0
  179. package/src/integrations/registry.ts +8 -0
  180. package/src/lib/codex-restart-contract.ts +15 -0
  181. package/src/lib/desktop-upstream-tunnel.ts +18 -53
  182. package/src/lib/empty-tool-catalog.ts +62 -0
  183. package/src/lib/errors.ts +19 -3
  184. package/src/lib/gcp-adc.ts +96 -9
  185. package/src/lib/gcp-credential-input.ts +12 -0
  186. package/src/lib/lab-live-route-production.ts +5 -0
  187. package/src/lib/opaque-proxy-tunnel.ts +217 -0
  188. package/src/lib/redact.ts +2 -2
  189. package/src/oauth/account-quota-rank.ts +69 -2
  190. package/src/oauth/anthropic-account-refusal.ts +20 -2
  191. package/src/oauth/anthropic-oauth-definitions.ts +3 -1
  192. package/src/oauth/anthropic-routing.ts +1 -21
  193. package/src/oauth/anthropic.ts +38 -7
  194. package/src/oauth/callback-server.ts +27 -1
  195. package/src/oauth/chatgpt-device.ts +1 -1
  196. package/src/oauth/chatgpt-shared.ts +83 -0
  197. package/src/oauth/chatgpt.ts +8 -72
  198. package/src/oauth/dsh.ts +203 -0
  199. package/src/oauth/generic-account-failover.ts +33 -7
  200. package/src/oauth/generic-session-affinity.ts +125 -0
  201. package/src/oauth/index.ts +184 -109
  202. package/src/oauth/local-token-detect.ts +21 -1
  203. package/src/oauth/login-cli-errors.ts +44 -0
  204. package/src/oauth/login-cli.ts +69 -7
  205. package/src/oauth/login-flow-state.ts +371 -23
  206. package/src/oauth/meta-muse-errors.ts +41 -0
  207. package/src/oauth/meta-muse-keychain.ts +52 -0
  208. package/src/oauth/meta-muse.ts +51 -84
  209. package/src/oauth/model-discovery-auth.ts +3 -0
  210. package/src/oauth/pool-settings-capability.ts +4 -2
  211. package/src/oauth/refresh-flight-retirement.ts +48 -0
  212. package/src/oauth/session-affinity-key.ts +23 -0
  213. package/src/oauth/store-anthropic-instance.ts +9 -2
  214. package/src/oauth/store.ts +12 -5
  215. package/src/protocols/encoders/adapter-events.ts +5 -4
  216. package/src/protocols/encoders/messages.ts +9 -6
  217. package/src/protocols/provider-summary.ts +2 -1
  218. package/src/providers/api-key-cooldowns.ts +49 -0
  219. package/src/providers/api-key-resolve.ts +11 -6
  220. package/src/providers/api-key-response-ownership.ts +57 -0
  221. package/src/providers/api-key-selection.ts +31 -6
  222. package/src/providers/api-keys.ts +214 -3
  223. package/src/providers/claude-cli-usage.ts +96 -0
  224. package/src/providers/dsh-account-destination.ts +31 -0
  225. package/src/providers/dsh-account-models.ts +41 -0
  226. package/src/providers/gcp-credential-cleanup.ts +59 -0
  227. package/src/providers/key-failover.ts +54 -50
  228. package/src/providers/key-store.ts +7 -2
  229. package/src/providers/model-rename-fields.ts +3 -0
  230. package/src/providers/model-rename-migration.ts +2 -2
  231. package/src/providers/openai-tiers-destination.ts +11 -2
  232. package/src/providers/openai-tiers.ts +5 -12
  233. package/src/providers/opencode-go-transport.ts +3 -1
  234. package/src/providers/quota/account-cache.ts +6 -5
  235. package/src/providers/quota/account-row.ts +34 -0
  236. package/src/providers/quota/antigravity.ts +28 -7
  237. package/src/providers/quota/dsh-account.ts +70 -0
  238. package/src/providers/quota/vendor-probes-oauth.ts +1 -93
  239. package/src/providers/quota-types.ts +2 -0
  240. package/src/providers/quota.ts +14 -20
  241. package/src/providers/registry/entries-core.ts +37 -8
  242. package/src/providers/registry/types.ts +1 -1
  243. package/src/providers/request-pacing.ts +77 -19
  244. package/src/providers/routed-config.ts +339 -0
  245. package/src/providers/service-tier.ts +2 -1
  246. package/src/quota/window-mapping.ts +5 -2
  247. package/src/responses/anthropic-progress.ts +34 -0
  248. package/src/responses/assistant-replay.ts +35 -0
  249. package/src/responses/compaction-history-framing.ts +65 -0
  250. package/src/responses/compaction.ts +6 -1
  251. package/src/responses/incomplete-reason.ts +31 -0
  252. package/src/responses/parser.ts +50 -5
  253. package/src/responses/reasoning-envelope.ts +4 -0
  254. package/src/responses/reasoning-replay-cache.ts +24 -2
  255. package/src/responses/reasoning-retention.ts +173 -0
  256. package/src/responses/retained-compaction.ts +46 -0
  257. package/src/responses/schema.ts +23 -0
  258. package/src/router.ts +8 -321
  259. package/src/routing/health.ts +37 -22
  260. package/src/routing/history/indexer.ts +6 -5
  261. package/src/routing/history/ingest.ts +6 -2
  262. package/src/routing/profile.ts +1 -1
  263. package/src/server/admission-model-scope.ts +17 -0
  264. package/src/server/auth-cors.ts +11 -0
  265. package/src/server/chat-completions.ts +7 -1
  266. package/src/server/chat-native-reasoning.ts +123 -0
  267. package/src/server/chat-native-sse.ts +110 -7
  268. package/src/server/chat-native.ts +76 -17
  269. package/src/server/claude-messages.ts +55 -414
  270. package/src/server/effort-policy.ts +1 -1
  271. package/src/server/images.ts +15 -2
  272. package/src/server/index/model-alias-id.ts +36 -0
  273. package/src/server/index/optional-listeners.ts +2 -0
  274. package/src/server/index/serve-options.ts +9 -1
  275. package/src/server/index/startup-warnings.ts +2 -0
  276. package/src/server/index.ts +1 -1
  277. package/src/server/inference/advisor-diagnostics.ts +31 -0
  278. package/src/server/management/advisor-routes.ts +15 -4
  279. package/src/server/management/claude-desktop-picker-routes.ts +1 -1
  280. package/src/server/management/combo-routes.ts +176 -50
  281. package/src/server/management/companion-routes.ts +1 -1
  282. package/src/server/management/config-routes.ts +75 -4
  283. package/src/server/management/cursor-integration-routes.ts +1 -1
  284. package/src/server/management/model-routes.ts +11 -6
  285. package/src/server/management/model-rows.ts +14 -0
  286. package/src/server/management/native-integration-routes.ts +2 -7
  287. package/src/server/management/native-reasoning-retention-routes.ts +41 -0
  288. package/src/server/management/oauth-account-routes.ts +87 -14
  289. package/src/server/management/provider-gcp-credential-routes.ts +29 -0
  290. package/src/server/management/provider-key-pacing-routes.ts +31 -0
  291. package/src/server/management/provider-overwrite-carry.ts +7 -0
  292. package/src/server/management/provider-routes.ts +25 -30
  293. package/src/server/management/route-registry.ts +10 -1
  294. package/src/server/management-api.ts +3 -1
  295. package/src/server/messages-native-tool-guard.ts +185 -0
  296. package/src/server/messages-native.ts +101 -21
  297. package/src/server/messages-shared.ts +431 -0
  298. package/src/server/relay.ts +1 -1
  299. package/src/server/request-log-terminal-status.ts +1 -1
  300. package/src/server/request-log.ts +6 -1
  301. package/src/server/responses/account-change-state.ts +8 -2
  302. package/src/server/responses/adapter-continuation.ts +13 -1
  303. package/src/server/responses/adapter-delivery.ts +19 -6
  304. package/src/server/responses/adapter-dispatch.ts +19 -2
  305. package/src/server/responses/advisor-retention.ts +117 -0
  306. package/src/server/responses/advisor-slot.ts +73 -41
  307. package/src/server/responses/codex-ws-wire.ts +15 -8
  308. package/src/server/responses/compact.ts +303 -125
  309. package/src/server/responses/compaction-recovery.ts +18 -10
  310. package/src/server/responses/compaction-retention.ts +61 -0
  311. package/src/server/responses/context-overflow.ts +11 -6
  312. package/src/server/responses/core-auth.ts +6 -0
  313. package/src/server/responses/core-codex-account.ts +11 -1
  314. package/src/server/responses/core-combo-failure.ts +2 -0
  315. package/src/server/responses/core-combo.ts +120 -36
  316. package/src/server/responses/core-errors.ts +3 -3
  317. package/src/server/responses/core-lifetime.ts +5 -2
  318. package/src/server/responses/core-opaque-recovery.ts +35 -0
  319. package/src/server/responses/core-options.ts +5 -0
  320. package/src/server/responses/core-pipeline.ts +141 -0
  321. package/src/server/responses/core-replay.ts +18 -2
  322. package/src/server/responses/core.ts +2 -115
  323. package/src/server/responses/fetch-helpers.ts +73 -19
  324. package/src/server/responses/main-hard-lock-routing.ts +109 -0
  325. package/src/server/responses/native-response-control.ts +4 -2
  326. package/src/server/responses/passthrough-delivery.ts +3 -1
  327. package/src/server/responses/passthrough-dispatch.ts +15 -13
  328. package/src/server/responses/request-prepare.ts +76 -12
  329. package/src/server/responses/request-sidecar-auth.ts +2 -2
  330. package/src/server/responses/request-transport.ts +104 -27
  331. package/src/server/responses/response-effects.ts +1 -0
  332. package/src/server/responses/run-turn-execution.ts +96 -30
  333. package/src/server/responses/sidecar-execution.ts +20 -2
  334. package/src/server/responses/terminal-guard.ts +2 -16
  335. package/src/service/auth-preflight.ts +71 -0
  336. package/src/service/cli.ts +4 -2
  337. package/src/service/definition.ts +97 -0
  338. package/src/service/guards.ts +1 -61
  339. package/src/service/health-sentinel-linux.ts +112 -0
  340. package/src/service/health-sentinel-main.ts +76 -57
  341. package/src/service/health.ts +5 -89
  342. package/src/service/launchd.ts +27 -7
  343. package/src/service/logging.ts +72 -9
  344. package/src/service/repair.ts +2 -1
  345. package/src/service/state.ts +7 -8
  346. package/src/service/systemd.ts +1 -1
  347. package/src/service/windows-guarded-manager.ts +2 -1
  348. package/src/service/windows-ops.ts +1 -1
  349. package/src/service/windows-scheduler.ts +2 -7
  350. package/src/service/windows-taskxml.ts +2 -2
  351. package/src/service/windows-wscript.ts +14 -0
  352. package/src/service.ts +4 -2
  353. package/src/sidecar/auth.ts +2 -0
  354. package/src/types/config.ts +64 -3
  355. package/src/types/opencode-go.ts +61 -0
  356. package/src/types/opencode-zen.ts +29 -0
  357. package/src/types/provider.ts +32 -6
  358. package/src/types/request.ts +23 -2
  359. package/src/types/wire.ts +29 -37
  360. package/src/types.ts +1 -0
  361. package/src/update/npm-invocation.mjs +12 -2
  362. package/src/usage/cost.ts +48 -12
  363. package/src/usage/expected-prices.ts +3 -0
  364. package/src/usage/ledger-retention.ts +2 -1
  365. package/src/usage/ledger-scanner.ts +6 -5
  366. package/src/usage/log.ts +17 -8
  367. package/src/usage/summary.ts +22 -9
  368. package/src/usage/user-cost-overlays.ts +14 -19
  369. package/src/usage/user-cost-validation.ts +38 -0
  370. package/src/vision/eligibility.ts +13 -0
  371. package/src/web-search/loop.ts +55 -5
  372. package/src/web-search/progress-stream.ts +4 -1
  373. package/src/web-search/run-turn-loop.ts +9 -1
  374. package/gui/dist/assets/App-BjlttVLy.js +0 -58
  375. package/gui/dist/assets/App-CSJvmjNs.css +0 -1
  376. package/gui/dist/assets/index-BB6uK6tU.css +0 -1
  377. package/gui/dist/assets/index-BMssP4k3.js +0 -94
  378. package/gui/dist/assets/quota-summary-D8M1bc_R.js +0 -1
@@ -18,6 +18,9 @@ import { isSpawnableCodexCandidate } from "./exec-invocation";
18
18
  import {
19
19
  codexRuntimeStatePath,
20
20
  parsePersistedCodexRuntime,
21
+ resolveCodexRuntime,
22
+ type ResolveCodexRuntimeDeps,
23
+ type ResolveCodexRuntimeResult,
21
24
  } from "./runtime";
22
25
  import {
23
26
  inspectCodexShimBackingForCommand,
@@ -46,12 +49,13 @@ export type CodexCliInstallReason =
46
49
  | "shim_state_unknown"
47
50
  | "shim_update_deferred"
48
51
  | "app_bundle"
49
- | "version_manager_owned"
50
- | "npm_global_unverified"
51
- | "selection_unattested"
52
- | "version_mismatch"
53
- | "unverified_standalone"
54
- | "inspection_failed";
52
+ | "version_manager_owned"
53
+ | "npm_global_unverified"
54
+ | "managed_npm_global"
55
+ | "selection_unattested"
56
+ | "version_mismatch"
57
+ | "unverified_standalone"
58
+ | "inspection_failed";
55
59
 
56
60
  export type CodexCliCandidateSource = "environment" | "persisted";
57
61
  export type CodexCliInstallEvidence =
@@ -82,6 +86,12 @@ export interface CodexCliInstallReport {
82
86
  readonly managed: boolean;
83
87
  readonly reason: CodexCliInstallReason;
84
88
  readonly location: string | null;
89
+ /**
90
+ * sha256 digest of the canonical package manifest root when one was observed,
91
+ * otherwise null. Digest-only so the public report still carries no path; plan
92
+ * identity binds this value so two different install roots cannot share a plan.
93
+ */
94
+ readonly installDigest: string | null;
85
95
  readonly packageVersion: string | null;
86
96
  readonly shim: Readonly<{
87
97
  status: "not-tracked" | "matched" | "unknown";
@@ -105,6 +115,19 @@ export interface CodexCliInstallProvenanceDeps {
105
115
  platform: NodeJS.Platform,
106
116
  configDir: string,
107
117
  ) => CodexShimBackingForCommand;
118
+ /**
119
+ * Caller assertion that `env.CODEX_CLI_PATH` is the runtime the launcher actually
120
+ * selected, not merely a configured name. Only a proof-bound caller may set this;
121
+ * a persisted selection and an arbitrary environment stay unattested.
122
+ */
123
+ readonly selectionAttested?: boolean;
124
+ /**
125
+ * The command the runtime resolver actually selected under the same evidence.
126
+ * Attestation additionally requires its canonical path to match the inspected
127
+ * candidate, so a snapshot candidate the resolver would have rejected cannot
128
+ * turn a different installation managed.
129
+ */
130
+ readonly selectedCommand?: string | null;
108
131
  }
109
132
 
110
133
  interface PackageManifestEvidence {
@@ -159,6 +182,7 @@ function unknownReport(
159
182
  managed: false,
160
183
  reason,
161
184
  location: extra.location ?? null,
185
+ installDigest: null,
162
186
  packageVersion: null,
163
187
  shim: Object.freeze({ status: "not-tracked", backingKind: null }),
164
188
  evidence: Object.freeze([]),
@@ -287,6 +311,38 @@ function resolveCandidateCommandPath(
287
311
  return null;
288
312
  }
289
313
 
314
+ /** Resolve selection under inspection's bounded, local-only filesystem policy. */
315
+ export function observeCodexCliSelectedCommand(
316
+ deps: CodexCliInstallProvenanceDeps,
317
+ resolve: (deps: ResolveCodexRuntimeDeps) => ResolveCodexRuntimeResult = resolveCodexRuntime,
318
+ ): string | null {
319
+ const platform = deps.platform ?? process.platform;
320
+ // Even the general resolver's existence checks can touch a remote Windows
321
+ // candidate. Deferred inspection must return before invoking it at all.
322
+ if (platform === "win32") return null;
323
+ const configDir = deps.configDir ?? getConfigDir();
324
+ if (!isSafeLocalInspectionPath(configDir, deps)) return null;
325
+ try {
326
+ return resolve({
327
+ platform,
328
+ env: deps.env,
329
+ configDir,
330
+ discoverAlternatives: false,
331
+ probeVersion: false,
332
+ // Runtime and shim state must use the same no-follow, nonblocking,
333
+ // size-bounded descriptor reads as provenance, including before selection.
334
+ readFileSync: path => {
335
+ const bytes = readBoundedFile(path, MAX_RUNTIME_STATE_BYTES, deps);
336
+ if (!bytes) throw new Error("inspection_state_unavailable");
337
+ return bytes.toString("utf8");
338
+ },
339
+ existsSync: path => resolveCandidateCommandPath(path, deps) !== null,
340
+ }).runtime.command ?? null;
341
+ } catch {
342
+ return null;
343
+ }
344
+ }
345
+
290
346
  function canonicalize(path: string, deps: CodexCliInstallProvenanceDeps): string | null {
291
347
  if (!isSafeLocalInspectionPath(path, deps)) return null;
292
348
  try {
@@ -630,15 +686,16 @@ export async function inspectCodexCliInstall(
630
686
  managed: false,
631
687
  reason: appBundle ? "app_bundle" : "version_manager_owned",
632
688
  location: publicExecutableLocation(lexicalCandidatePath, platform),
689
+ installDigest: null,
633
690
  packageVersion: null,
634
691
  shim: Object.freeze({ status: "unknown", backingKind: null }),
635
692
  evidence: Object.freeze([appBundle ? "app_bundle_path" : "version_manager_path"]),
636
693
  });
637
694
  }
638
- return unknownWindowsReport("windows_inspection_deferred", candidate, {
639
- location: publicExecutableLocation(lexicalCandidatePath, platform),
640
- });
641
- }
695
+ return unknownWindowsReport("windows_inspection_deferred", candidate, {
696
+ location: publicExecutableLocation(lexicalCandidatePath, platform),
697
+ });
698
+ }
642
699
  const configDir = deps.configDir ?? getConfigDir();
643
700
  if (!isSafeLocalInspectionPath(configDir, deps)) {
644
701
  return unknownReport("shim_state_unknown", candidate);
@@ -651,6 +708,23 @@ export async function inspectCodexCliInstall(
651
708
  if (!canonicalCandidatePath) {
652
709
  return unknownReport("candidate_path_unsafe", candidate);
653
710
  }
711
+ // Only a proof-bound caller may attest that the environment candidate is the
712
+ // runtime it actually selected, and only when the runtime resolver picked the
713
+ // same canonical path under the same evidence. A persisted selection records
714
+ // intent, not the resolved binary, and an arbitrary environment is ambient —
715
+ // neither can become managed here; a resolver that would choose a different
716
+ // executable cannot attest the snapshot's installation either.
717
+ const resolverPicked = deps.selectedCommand
718
+ ? canonicalize(
719
+ resolveCandidateCommandPath(deps.selectedCommand, deps) ?? deps.selectedCommand,
720
+ deps,
721
+ )
722
+ : null;
723
+ const selectionAttested =
724
+ deps.selectionAttested === true
725
+ && candidate.evidence === "environment"
726
+ && resolverPicked !== null
727
+ && samePath(resolverPicked, canonicalCandidatePath, platform);
654
728
  const inspectShim = deps.inspectShim ?? inspectCodexShimBackingForCommand;
655
729
  const shim = inspectShim(candidatePath, platform, configDir);
656
730
  if (shim.status === "unknown") {
@@ -658,6 +732,7 @@ export async function inspectCodexCliInstall(
658
732
  ...unknownReport("shim_state_unknown", candidate, {
659
733
  location: publicExecutableLocation(canonicalCandidatePath, platform),
660
734
  }),
735
+ selectionAttested,
661
736
  shim: shimReport(shim),
662
737
  });
663
738
  }
@@ -666,6 +741,7 @@ export async function inspectCodexCliInstall(
666
741
  ...unknownReport("shim_update_deferred", candidate, {
667
742
  location: publicExecutableLocation(canonicalCandidatePath, platform),
668
743
  }),
744
+ selectionAttested,
669
745
  provenance: "standalone-unverified",
670
746
  shim: shimReport(shim),
671
747
  evidence: Object.freeze(["canonical_path", "shim_backing"] as const),
@@ -685,7 +761,7 @@ export async function inspectCodexCliInstall(
685
761
  candidateAvailable: true,
686
762
  candidateVersion: candidate.version,
687
763
  candidateSource: candidate.evidence,
688
- selectionAttested: false,
764
+ selectionAttested,
689
765
  versionEvidence: Object.freeze({
690
766
  kind: candidate.version ? "advisory-runtime" as const : "unavailable" as const,
691
767
  }),
@@ -693,6 +769,7 @@ export async function inspectCodexCliInstall(
693
769
  managed: false,
694
770
  reason: "app_bundle",
695
771
  location,
772
+ installDigest: null,
696
773
  packageVersion: null,
697
774
  shim: shimReport(shim),
698
775
  evidence: Object.freeze(["canonical_path", "app_bundle_path"]),
@@ -706,7 +783,7 @@ export async function inspectCodexCliInstall(
706
783
  candidateAvailable: true,
707
784
  candidateVersion: candidate.version,
708
785
  candidateSource: candidate.evidence,
709
- selectionAttested: false,
786
+ selectionAttested,
710
787
  versionEvidence: Object.freeze({
711
788
  kind: candidate.version ? "advisory-runtime" as const : "unavailable" as const,
712
789
  }),
@@ -714,6 +791,7 @@ export async function inspectCodexCliInstall(
714
791
  managed: false,
715
792
  reason: "version_manager_owned",
716
793
  location,
794
+ installDigest: null,
717
795
  packageVersion: null,
718
796
  shim: shimReport(shim),
719
797
  evidence: Object.freeze(["canonical_path", "version_manager_path"]),
@@ -722,6 +800,7 @@ export async function inspectCodexCliInstall(
722
800
  if (/codex[.]opencodex-real(?:[.](?:cmd|bat|exe))?$/i.test(pathTools(platform).basename(candidatePath))) {
723
801
  return freezeReport({
724
802
  ...unknownReport("shim_state_unknown", candidate, { location }),
803
+ selectionAttested,
725
804
  shim: shimReport(shim),
726
805
  });
727
806
  }
@@ -745,22 +824,30 @@ export async function inspectCodexCliInstall(
745
824
  const versionMatches = candidate.version === null || candidate.version === manifest.version;
746
825
  const reason: CodexCliInstallReason = !global || !linked
747
826
  ? "npm_global_unverified"
748
- : !versionMatches ? "version_mismatch" : "selection_unattested";
827
+ : !versionMatches ? "version_mismatch"
828
+ : selectionAttested ? "managed_npm_global" : "selection_unattested";
749
829
  return freezeReport({
750
830
  schemaVersion: 1,
751
831
  candidateAvailable: true,
752
832
  candidateVersion: candidate.version,
753
833
  candidateSource: candidate.evidence,
754
- selectionAttested: false,
834
+ selectionAttested,
755
835
  versionEvidence: Object.freeze({
756
- kind: manifestOwned && candidate.version !== null && versionMatches
836
+ // The manifest is the on-disk record of what is installed. An absent advisory
837
+ // version (the launcher snapshot carries no version) cannot contradict it,
838
+ // while a reported one that disagrees already classified as version_mismatch.
839
+ kind: manifestOwned && versionMatches
757
840
  ? "package-manifest" as const
758
841
  : candidate.version !== null ? "advisory-runtime" as const : "unavailable" as const,
759
842
  }),
760
843
  provenance: manifestOwned ? "npm-global" : "standalone-unverified",
761
- managed: false,
844
+ managed: manifestOwned && versionMatches && selectionAttested,
762
845
  reason,
763
846
  location,
847
+ // Plan identity binds this digest, not the redacted display location: two
848
+ // package roots that resolve to the same "<path>/codex" string must still
849
+ // produce different plans.
850
+ installDigest: sha256("codex-cli-install-root-v1", normalizePath(manifest.root, platform)),
764
851
  packageVersion: manifest.version,
765
852
  shim: shimReport(shim),
766
853
  evidence: Object.freeze<CodexCliInstallEvidence[]>([
@@ -786,7 +873,7 @@ export async function inspectCodexCliInstall(
786
873
  candidateAvailable: true,
787
874
  candidateVersion: candidate.version,
788
875
  candidateSource: candidate.evidence,
789
- selectionAttested: false,
876
+ selectionAttested,
790
877
  versionEvidence: Object.freeze({
791
878
  kind: candidate.version ? "advisory-runtime" as const : "unavailable" as const,
792
879
  }),
@@ -794,6 +881,7 @@ export async function inspectCodexCliInstall(
794
881
  managed: false,
795
882
  reason: "unverified_standalone",
796
883
  location,
884
+ installDigest: null,
797
885
  packageVersion: null,
798
886
  shim: shimReport(shim),
799
887
  evidence: Object.freeze(["canonical_path"]),