@iislee/opencodex 2.11.0 → 2.31.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 (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -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 +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -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 +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. package/src/cli/internal-dispatch.ts +0 -20
@@ -1,4 +1,11 @@
1
1
  import { loadConfig } from "../config";
2
+ import { closeSync, openSync, readSync } from "node:fs";
3
+ import {
4
+ MAX_ACCOUNT_PRIORITY,
5
+ MIN_ACCOUNT_PRIORITY,
6
+ normalizeAccountPriority,
7
+ parseAccountPriority,
8
+ } from "../codex/pool-rotation";
2
9
  import {
3
10
  apiError,
4
11
  apiJson,
@@ -11,6 +18,20 @@ import {
11
18
  type AccountDeps, type AccountStdin, type FamilyRows,
12
19
  type ProviderQuotaDto, type ProviderQuotaReportDto,
13
20
  } from "./account-api";
21
+ import {
22
+ codexCatalogRefreshPending,
23
+ warnIfCodexCatalogRefreshPending,
24
+ } from "./account-catalog-refresh";
25
+ import {
26
+ ACCOUNT_IMPORT_DEADLINE_MS,
27
+ ACCOUNT_IMPORT_FORMAT,
28
+ ACCOUNT_IMPORT_MAX_BYTES,
29
+ ACCOUNT_IMPORT_PROVIDER,
30
+ type AccountImportCode,
31
+ type AccountImportRecordResult,
32
+ type AccountImportResult,
33
+ type AccountImportStatus,
34
+ } from "../oauth/account-import";
14
35
 
15
36
  const MAIN_ID = "__main__";
16
37
  const AUTO_NOTE = "auto (no pin — lowest-usage account is selected per request)";
@@ -18,12 +39,15 @@ const EXTENDED_USAGE = `Usage:
18
39
  ocx account refresh <provider> [--json]
19
40
  ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]
20
41
  ocx account alias <provider> <id|main> <display-name|-> [--json]
42
+ ocx account priority <provider> <id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]
21
43
  ocx account remove <provider> <id|main> --yes [--json]
22
44
  ocx account clear-cooldown <provider> <id|main> [--json]
23
- ocx account add-key <provider> [--label <label>] [--json]`;
45
+ ocx account add-key <provider> [--label <label>] [--json]
46
+ ocx account import <provider> --format <format> (--file <path>|--stdin) [--json]`;
24
47
  const PIPE_GUIDANCE = `Pipe the API key on stdin, for example:
25
48
  ocx account add-key <provider> <<< "$MY_KEY"
26
49
  security find-generic-password -w <item> | ocx account add-key <provider>`;
50
+ const ACCOUNT_IMPORT_TIMEOUT_MS = ACCOUNT_IMPORT_DEADLINE_MS;
27
51
 
28
52
  function flag(args: string[], value: string): boolean {
29
53
  const index = args.indexOf(value);
@@ -41,6 +65,162 @@ function flagValue(args: string[], value: string): { found: boolean; value?: str
41
65
  return { found: true, value: result };
42
66
  }
43
67
 
68
+ function boundedUtf8(bytes: Uint8Array): string {
69
+ try {
70
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
71
+ } catch {
72
+ throw new Error("invalid_document");
73
+ }
74
+ }
75
+
76
+ function readBoundedImportFile(path: string): string {
77
+ let descriptor: number | undefined;
78
+ try {
79
+ descriptor = openSync(path, "r");
80
+ const buffer = Buffer.allocUnsafe(ACCOUNT_IMPORT_MAX_BYTES + 1);
81
+ let offset = 0;
82
+ while (offset < buffer.length) {
83
+ const read = readSync(descriptor, buffer, offset, buffer.length - offset, null);
84
+ if (read === 0) break;
85
+ offset += read;
86
+ }
87
+ if (offset > ACCOUNT_IMPORT_MAX_BYTES) throw new Error("invalid_document");
88
+ return boundedUtf8(buffer.subarray(0, offset));
89
+ } catch (error) {
90
+ if (error instanceof Error && error.message === "invalid_document") throw error;
91
+ throw new Error("source_read_failed");
92
+ } finally {
93
+ if (descriptor !== undefined) closeSync(descriptor);
94
+ }
95
+ }
96
+
97
+ async function readBoundedImportStdin(deps: AccountDeps): Promise<string> {
98
+ const input: AccountStdin = deps.stdinImpl ?? process.stdin;
99
+ if (input.isTTY) throw new Error("stdin_required");
100
+ const timeoutMs = deps.stdinTimeoutMs ?? 15_000;
101
+ return await new Promise<string>((resolve, reject) => {
102
+ const chunks: Buffer[] = [];
103
+ let bytes = 0;
104
+ let settled = false;
105
+ const cleanup = () => {
106
+ clearTimeout(timer);
107
+ input.removeListener("data", onData);
108
+ input.removeListener("end", onEnd);
109
+ input.removeListener("error", onError);
110
+ };
111
+ const finish = (fn: () => void) => {
112
+ if (settled) return;
113
+ settled = true;
114
+ cleanup();
115
+ fn();
116
+ };
117
+ const onData = (chunk: unknown) => {
118
+ const encoded = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
119
+ bytes += encoded.byteLength;
120
+ if (bytes > ACCOUNT_IMPORT_MAX_BYTES) {
121
+ finish(() => reject(new Error("invalid_document")));
122
+ return;
123
+ }
124
+ chunks.push(encoded);
125
+ };
126
+ const onEnd = () => finish(() => {
127
+ try { resolve(boundedUtf8(Buffer.concat(chunks, bytes))); }
128
+ catch (error) { reject(error); }
129
+ });
130
+ const onError = () => finish(() => reject(new Error("source_read_failed")));
131
+ const timer = setTimeout(() => finish(() => reject(new Error("stdin_timeout"))), timeoutMs);
132
+ input.on("data", onData);
133
+ input.on("end", onEnd);
134
+ input.on("error", onError);
135
+ });
136
+ }
137
+
138
+ const IMPORT_STATUSES = new Set<AccountImportStatus>(["imported", "updated", "failed", "unsupported"]);
139
+ const IMPORT_CODES = new Set<AccountImportCode>([
140
+ "imported", "updated", "import_cancelled", "unsupported_provider", "unsupported_format", "invalid_document",
141
+ "invalid_record", "credential_rejected", "identity_mismatch", "missing_project", "persist_failed",
142
+ ]);
143
+ const IMPORT_RESULT_FIELDS = new Set([
144
+ "totalCount", "importedCount", "updatedCount", "failedCount", "unsupportedCount", "results",
145
+ ]);
146
+ const IMPORT_RECORD_FIELDS = new Set(["index", "status", "code"]);
147
+ const IMPORT_STATUS_CODES: Record<AccountImportStatus, ReadonlySet<AccountImportCode>> = {
148
+ imported: new Set(["imported"]),
149
+ updated: new Set(["updated"]),
150
+ failed: new Set(["invalid_record", "credential_rejected", "identity_mismatch", "missing_project", "persist_failed"]),
151
+ unsupported: new Set(["unsupported_provider", "unsupported_format"]),
152
+ };
153
+
154
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
155
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
156
+ const prototype = Object.getPrototypeOf(value);
157
+ return prototype === Object.prototype || prototype === null;
158
+ }
159
+
160
+ function hasExactFields(value: Record<string, unknown>, allowed: ReadonlySet<string>): boolean {
161
+ const fields = Object.keys(value);
162
+ return fields.length === allowed.size && fields.every(field => allowed.has(field));
163
+ }
164
+
165
+ function isNonNegativeSafeInteger(value: unknown): value is number {
166
+ return typeof value === "number" && Number.isFinite(value) && Number.isSafeInteger(value) && value >= 0;
167
+ }
168
+
169
+ function safeImportResult(json: unknown): AccountImportResult | null {
170
+ if (!isPlainObject(json) || !hasExactFields(json, IMPORT_RESULT_FIELDS)) return null;
171
+ if (
172
+ !isNonNegativeSafeInteger(json.totalCount)
173
+ || !isNonNegativeSafeInteger(json.importedCount)
174
+ || !isNonNegativeSafeInteger(json.updatedCount)
175
+ || !isNonNegativeSafeInteger(json.failedCount)
176
+ || !isNonNegativeSafeInteger(json.unsupportedCount)
177
+ ) return null;
178
+ if (!Array.isArray(json.results)) return null;
179
+ if (json.results.length !== json.totalCount) return null;
180
+
181
+ const results: AccountImportRecordResult[] = [];
182
+ const indices = new Set<number>();
183
+ const aggregate: Record<AccountImportStatus, number> = {
184
+ imported: 0,
185
+ updated: 0,
186
+ failed: 0,
187
+ unsupported: 0,
188
+ };
189
+ for (const raw of json.results) {
190
+ if (!isPlainObject(raw) || !hasExactFields(raw, IMPORT_RECORD_FIELDS)) return null;
191
+ const item = raw;
192
+ if (!isNonNegativeSafeInteger(item.index) || item.index >= json.totalCount || indices.has(item.index)) return null;
193
+ if (!IMPORT_STATUSES.has(item.status as AccountImportStatus)) return null;
194
+ if (!IMPORT_CODES.has(item.code as AccountImportCode)) return null;
195
+ const status = item.status as AccountImportStatus;
196
+ const code = item.code as AccountImportCode;
197
+ if (!IMPORT_STATUS_CODES[status].has(code)) return null;
198
+ indices.add(item.index);
199
+ aggregate[status] += 1;
200
+ results.push({
201
+ index: item.index,
202
+ status,
203
+ code,
204
+ });
205
+ }
206
+ if (
207
+ indices.size !== json.totalCount
208
+ || aggregate.imported !== json.importedCount
209
+ || aggregate.updated !== json.updatedCount
210
+ || aggregate.failed !== json.failedCount
211
+ || aggregate.unsupported !== json.unsupportedCount
212
+ ) return null;
213
+
214
+ return {
215
+ totalCount: json.totalCount,
216
+ importedCount: json.importedCount,
217
+ updatedCount: json.updatedCount,
218
+ failedCount: json.failedCount,
219
+ unsupportedCount: json.unsupportedCount,
220
+ results,
221
+ };
222
+ }
223
+
44
224
  function usage(message?: string): number {
45
225
  if (message) console.error(message);
46
226
  console.error(EXTENDED_USAGE);
@@ -234,18 +414,28 @@ export async function cmdRemove(args: string[], deps: AccountDeps): Promise<numb
234
414
  const response = await apiJson(deps, baseUrl, "DELETE", deletePath(classified.type, name, id));
235
415
  if (response.status === 0) return fail("Proxy not reachable. Start it with 'ocx start' or 'ocx ensure'.");
236
416
  if (response.status !== 200) return fail(errorText(response.json, `failed to remove ${requestedId}`));
417
+ const catalogRefreshPending = classified.type === "codex"
418
+ && codexCatalogRefreshPending(response.json);
237
419
  const after = await fetchRows(deps, baseUrl, name, classified.type);
238
420
  if (after.networkDown || after.errorJson) {
239
421
  const detail = after.networkDown ? "proxy not reachable" : typeof after.errorJson?.error === "string" ? after.errorJson.error : "unknown error";
240
422
  return fail(`post-delete verification failed; delete may have succeeded: ${detail}`);
241
423
  }
242
424
  const removedActive = before.activeId === id;
243
- const result = { ok: true, provider: name, id, removedActive, promotedActiveId: after.activeId };
425
+ const result = {
426
+ ok: true,
427
+ provider: name,
428
+ id,
429
+ removedActive,
430
+ promotedActiveId: after.activeId,
431
+ ...(classified.type === "codex" ? { catalogRefreshPending } : {}),
432
+ };
244
433
  if (wantsJson) console.log(JSON.stringify(result, null, 2));
245
434
  else if (classified.type === "codex" && removedActive && after.activeId === null) console.log(`openai: ${AUTO_NOTE}`);
246
435
  else if (classified.type === "oauth") console.log(after.rows.length ? `${name}: active account is now ${after.activeId}` : `${name}: no accounts remaining`);
247
436
  else if (classified.type === "api-key") console.log(after.rows.length ? `${name}: active key is now ${after.activeId}` : `${name}: no keys remaining`);
248
437
  else console.log(`${name}: removed account ${requestedId}`);
438
+ if (!wantsJson && catalogRefreshPending) warnIfCodexCatalogRefreshPending(response.json);
249
439
  return 0;
250
440
  }
251
441
 
@@ -283,6 +473,98 @@ export async function cmdAddKey(args: string[], deps: AccountDeps): Promise<numb
283
473
  return 0;
284
474
  }
285
475
 
476
+ export async function cmdImport(args: string[], deps: AccountDeps): Promise<number> {
477
+ const wantsJson = flag(args, "--json");
478
+ const formatArg = flagValue(args, "--format");
479
+ const fileArg = flagValue(args, "--file");
480
+ const fromStdin = flag(args, "--stdin");
481
+ const provider = args.shift();
482
+
483
+ // Admission happens before source I/O. In particular, an inline JSON positional argument is
484
+ // rejected without inspecting or echoing it, keeping secrets out of any subsequent surface.
485
+ if (
486
+ provider !== ACCOUNT_IMPORT_PROVIDER
487
+ || formatArg.value !== ACCOUNT_IMPORT_FORMAT
488
+ || formatArg.found !== true
489
+ ) {
490
+ const code = provider === ACCOUNT_IMPORT_PROVIDER ? "unsupported_format" : "unsupported_provider";
491
+ console.error(`Error: ${code}`);
492
+ return 1;
493
+ }
494
+ const hasFile = fileArg.found && typeof fileArg.value === "string" && fileArg.value.length > 0;
495
+ if (args.length > 0 || hasFile === fromStdin || (fileArg.found && !hasFile)) {
496
+ return usage("Error: choose exactly one bounded source: --file <path> or --stdin");
497
+ }
498
+
499
+ let source: string;
500
+ try {
501
+ source = hasFile ? readBoundedImportFile(fileArg.value!) : await readBoundedImportStdin(deps);
502
+ } catch (error) {
503
+ const code = error instanceof Error ? error.message : "source_read_failed";
504
+ console.error(`Error: ${["invalid_document", "source_read_failed", "stdin_required", "stdin_timeout"].includes(code) ? code : "source_read_failed"}`);
505
+ return 1;
506
+ }
507
+
508
+ let document: unknown;
509
+ try {
510
+ document = JSON.parse(source) as unknown;
511
+ } catch {
512
+ console.error("Error: invalid_document");
513
+ return 1;
514
+ }
515
+
516
+ const baseUrl = await resolveBaseUrl(deps);
517
+ if (!baseUrl) return proxyUnreachable();
518
+ const configuredImportTimeout = deps.importTimeoutMs;
519
+ const importTimeoutMs = typeof configuredImportTimeout === "number" && Number.isFinite(configuredImportTimeout)
520
+ ? Math.min(ACCOUNT_IMPORT_TIMEOUT_MS, Math.max(1, Math.floor(configuredImportTimeout)))
521
+ : ACCOUNT_IMPORT_TIMEOUT_MS;
522
+ const controller = new AbortController();
523
+ let timedOut = false;
524
+ const timer = setTimeout(() => {
525
+ timedOut = true;
526
+ controller.abort();
527
+ }, importTimeoutMs);
528
+ let response;
529
+ try {
530
+ response = await apiJson(deps, baseUrl, "POST", "/api/oauth/accounts/import", {
531
+ provider,
532
+ format: formatArg.value,
533
+ document,
534
+ }, { signal: controller.signal });
535
+ } finally {
536
+ clearTimeout(timer);
537
+ }
538
+ if (response.status === 0) {
539
+ if (!timedOut) return proxyUnreachable();
540
+ console.error(`Error: import_timeout after ${importTimeoutMs}ms`);
541
+ return 1;
542
+ }
543
+ if (response.status !== 200) {
544
+ if (IMPORT_CODES.has(response.json.code as AccountImportCode)) {
545
+ console.error(`Error: ${response.json.code as AccountImportCode}`);
546
+ } else {
547
+ console.error(`Error: import_request_failed (status ${response.status})`);
548
+ }
549
+ return 1;
550
+ }
551
+ const result = safeImportResult(response.json);
552
+ if (!result) {
553
+ console.error("Error: invalid_response");
554
+ return 1;
555
+ }
556
+
557
+ if (wantsJson) {
558
+ console.log(JSON.stringify(result, null, 2));
559
+ } else {
560
+ console.log(
561
+ `${provider}: ${result.importedCount} imported, ${result.updatedCount} updated, ${result.failedCount} failed, ${result.unsupportedCount} unsupported`,
562
+ );
563
+ for (const item of result.results) console.log(` #${item.index + 1} ${item.status} (${item.code})`);
564
+ }
565
+ return result.failedCount > 0 || result.unsupportedCount > 0 ? 1 : 0;
566
+ }
567
+
286
568
  /**
287
569
  * Lift a quota cooldown on a Codex account.
288
570
  *
@@ -316,6 +598,111 @@ export async function cmdClearCooldown(args: string[], deps: AccountDeps): Promi
316
598
  return 0;
317
599
  }
318
600
 
601
+ /**
602
+ * Named selection orders. The words convey sequence rather than rank because the
603
+ * pool moves down the list only when everything above it is drained — "high
604
+ * priority" would suggest the account gets more traffic, which is not what
605
+ * ordering does.
606
+ */
607
+ const PRIORITY_PRESETS: Record<string, number> = {
608
+ first: 2,
609
+ earlier: 1,
610
+ normal: 0,
611
+ later: -1,
612
+ last: -2,
613
+ };
614
+
615
+ function priorityPresetName(priority: number): string | null {
616
+ return Object.entries(PRIORITY_PRESETS).find(([, value]) => value === priority)?.[0] ?? null;
617
+ }
618
+
619
+ function formatPriority(priority: number): string {
620
+ const preset = priorityPresetName(priority);
621
+ const signed = priority > 0 ? `+${priority}` : String(priority);
622
+ return preset ? `${signed} (${preset})` : signed;
623
+ }
624
+
625
+ /** `null` = reset to the default; `undefined` = unparseable. */
626
+ function parsePriorityArgument(raw: string): number | null | undefined {
627
+ const word = raw.trim().toLowerCase();
628
+ if (word === "reset") return null;
629
+ // Own keys only: `in` also matches "constructor", "__proto__", and friends.
630
+ if (Object.hasOwn(PRIORITY_PRESETS, word)) return PRIORITY_PRESETS[word];
631
+ // The regex only rules out shapes Number() would coerce ("1e2", " 1 ", ""); the range
632
+ // itself comes from the core parser so the CLI cannot drift from what the API accepts.
633
+ if (!/^[+-]?\d+$/.test(word)) return undefined;
634
+ return parseAccountPriority(Number(word)) ?? undefined;
635
+ }
636
+
637
+ export async function cmdPriority(args: string[], deps: AccountDeps): Promise<number> {
638
+ const wantsJson = flag(args, "--json");
639
+ const name = args.shift();
640
+ const requestedId = args.shift();
641
+ const requestedPriority = args.shift();
642
+ if (!name || !requestedId || args.length) return usage();
643
+ const classified = configAndType(deps, name);
644
+ if ("error" in classified) return usage(`Error: ${classified.error}`);
645
+ if (classified.type !== "codex") {
646
+ return usage("Error: selection order only applies to the openai Codex account pool");
647
+ }
648
+ const id = requestedId === "main" ? MAIN_ID : requestedId;
649
+
650
+ // Validate before touching the network so a typo never reaches the proxy.
651
+ let priority: number | null | undefined;
652
+ if (requestedPriority !== undefined) {
653
+ priority = parsePriorityArgument(requestedPriority);
654
+ if (priority === undefined) {
655
+ return usage(`Error: selection order must be an integer ${MIN_ACCOUNT_PRIORITY}..${MAX_ACCOUNT_PRIORITY}, one of ${Object.keys(PRIORITY_PRESETS).join("/")}, or reset`);
656
+ }
657
+ }
658
+
659
+ const baseUrl = await resolveBaseUrl(deps);
660
+ if (!baseUrl) return proxyUnreachable();
661
+
662
+ // No value means "show" — a read must not rewrite what it is reporting.
663
+ if (priority === undefined) {
664
+ const result = await fetchCodexRows(deps, baseUrl);
665
+ const failed = familyFailure(result, `failed to read ${name} accounts`);
666
+ if (failed !== null) return failed;
667
+ const row = result.rows.find(candidate => candidate.id === id);
668
+ if (!row) return usage(`Error: no ${name} account ${requestedId}`);
669
+ const current = normalizeAccountPriority(row.priority);
670
+ if (wantsJson) {
671
+ console.log(JSON.stringify(
672
+ { ok: true, provider: name, id, priority: current, preset: priorityPresetName(current) },
673
+ null,
674
+ 2,
675
+ ));
676
+ } else {
677
+ console.log(`${name}: ${requestedId} selection order is ${formatPriority(current)}`);
678
+ }
679
+ return 0;
680
+ }
681
+
682
+ const response = await apiJson(deps, baseUrl, "PUT", "/api/codex-auth/accounts/priority", { id, priority });
683
+ if (response.status === 0) return proxyUnreachable();
684
+ if (response.status !== 200) return apiError(response.json, `failed to set selection order for ${requestedId}`);
685
+ const applied = typeof response.json.priority === "number" ? response.json.priority : (priority ?? 0);
686
+ if (wantsJson) {
687
+ console.log(JSON.stringify(
688
+ { ok: true, provider: name, id, priority: applied, preset: priorityPresetName(applied) },
689
+ null,
690
+ 2,
691
+ ));
692
+ } else {
693
+ console.log(`${name}: ${requestedId} selection order is now ${formatPriority(applied)}`);
694
+ }
695
+ // Not cmdUse's note: re-ordering takes effect on the next unbound request rather than
696
+ // only on new sessions, because preemption moves those requests up immediately.
697
+ console.error("Takes effect from the next unbound request; running threads keep their current account until drained.");
698
+ // The release is not optional and not conditional on the value changing, so it has to be
699
+ // stated: this route is the only way to clear a pin without immediately setting another,
700
+ // which means a write storing the order an account already had still releases it. Without
701
+ // this line that is a silent side effect of a command that looks purely declarative.
702
+ console.error('Also releases any manual "use this account now" pin, on any account.');
703
+ return 0;
704
+ }
705
+
319
706
  export async function cmdAlias(args: string[], deps: AccountDeps): Promise<number> {
320
707
  const wantsJson = flag(args, "--json");
321
708
  const name = args.shift();