@yansigit/opencodex 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 (826) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/LICENSE +21 -0
  3. package/README.md +303 -0
  4. package/assets/architecture.png +0 -0
  5. package/assets/banner.png +0 -0
  6. package/assets/claude-code-models.gif +0 -0
  7. package/assets/codex-app-picker.png +0 -0
  8. package/bin/ocx.mjs +587 -0
  9. package/bin/package-main.mjs +9 -0
  10. package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
  11. package/gui/dist/assets/index-CGoDO3uO.css +1 -0
  12. package/gui/dist/favicon.png +0 -0
  13. package/gui/dist/icons.svg +24 -0
  14. package/gui/dist/index.html +25 -0
  15. package/gui/dist/logo.png +0 -0
  16. package/gui/dist/provider-icons/alibaba-color.svg +1 -0
  17. package/gui/dist/provider-icons/antigravity-color.svg +1 -0
  18. package/gui/dist/provider-icons/claude-color.svg +1 -0
  19. package/gui/dist/provider-icons/cline-color.svg +16 -0
  20. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
  21. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  22. package/gui/dist/provider-icons/copilot-color.svg +1 -0
  23. package/gui/dist/provider-icons/cursor-color.svg +2 -0
  24. package/gui/dist/provider-icons/deepseek-color.svg +1 -0
  25. package/gui/dist/provider-icons/discord.svg +1 -0
  26. package/gui/dist/provider-icons/firepass-color.svg +1 -0
  27. package/gui/dist/provider-icons/fireworks-color.svg +1 -0
  28. package/gui/dist/provider-icons/gemini-color.svg +1 -0
  29. package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
  30. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
  31. package/gui/dist/provider-icons/grok.svg +1 -0
  32. package/gui/dist/provider-icons/groq-color.svg +1 -0
  33. package/gui/dist/provider-icons/huggingface-color.svg +1 -0
  34. package/gui/dist/provider-icons/kimi-color.svg +1 -0
  35. package/gui/dist/provider-icons/kiro-color.svg +15 -0
  36. package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
  37. package/gui/dist/provider-icons/mistral-color.svg +1 -0
  38. package/gui/dist/provider-icons/moonshot-color.svg +1 -0
  39. package/gui/dist/provider-icons/nvidia-color.svg +1 -0
  40. package/gui/dist/provider-icons/ollama-color.svg +1 -0
  41. package/gui/dist/provider-icons/openai.svg +1 -0
  42. package/gui/dist/provider-icons/opencode.svg +2 -0
  43. package/gui/dist/provider-icons/openrouter-color.svg +1 -0
  44. package/gui/dist/provider-icons/pi.svg +21 -0
  45. package/gui/dist/provider-icons/qianfan-color.svg +1 -0
  46. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
  47. package/gui/dist/provider-icons/telegram.svg +1 -0
  48. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
  49. package/gui/dist/provider-icons/vllm-color.svg +1 -0
  50. package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
  51. package/package.json +108 -0
  52. package/src/AGENTS.md +28 -0
  53. package/src/adapters/anthropic-image-guard.ts +251 -0
  54. package/src/adapters/anthropic-image-normalize.ts +518 -0
  55. package/src/adapters/anthropic-output-schema.ts +137 -0
  56. package/src/adapters/anthropic.ts +1327 -0
  57. package/src/adapters/azure.ts +36 -0
  58. package/src/adapters/base.ts +121 -0
  59. package/src/adapters/client-fingerprint.ts +65 -0
  60. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  61. package/src/adapters/command-code.ts +601 -0
  62. package/src/adapters/cursor/arg-codec.ts +38 -0
  63. package/src/adapters/cursor/arg-normalize.ts +104 -0
  64. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  65. package/src/adapters/cursor/cursor-errors.ts +288 -0
  66. package/src/adapters/cursor/discovery.ts +333 -0
  67. package/src/adapters/cursor/effort-map.ts +151 -0
  68. package/src/adapters/cursor/exec-policy.ts +88 -0
  69. package/src/adapters/cursor/framing.ts +250 -0
  70. package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
  71. package/src/adapters/cursor/h2-pool.ts +123 -0
  72. package/src/adapters/cursor/http1-bidi.ts +361 -0
  73. package/src/adapters/cursor/images.ts +704 -0
  74. package/src/adapters/cursor/kv-store.ts +52 -0
  75. package/src/adapters/cursor/live-models.ts +269 -0
  76. package/src/adapters/cursor/live-smoke-gate.ts +41 -0
  77. package/src/adapters/cursor/live-transport.ts +1653 -0
  78. package/src/adapters/cursor/mcp-config.ts +42 -0
  79. package/src/adapters/cursor/mcp-manager.ts +333 -0
  80. package/src/adapters/cursor/message-mapper.ts +49 -0
  81. package/src/adapters/cursor/native-exec-common.ts +76 -0
  82. package/src/adapters/cursor/native-exec-desktop.ts +184 -0
  83. package/src/adapters/cursor/native-exec-fs.ts +332 -0
  84. package/src/adapters/cursor/native-exec-mcp.ts +153 -0
  85. package/src/adapters/cursor/native-exec-network.ts +43 -0
  86. package/src/adapters/cursor/native-exec-shell.ts +547 -0
  87. package/src/adapters/cursor/native-exec-tools.ts +118 -0
  88. package/src/adapters/cursor/native-exec.ts +663 -0
  89. package/src/adapters/cursor/protobuf-events.ts +1381 -0
  90. package/src/adapters/cursor/protobuf-request.ts +1032 -0
  91. package/src/adapters/cursor/request-builder.ts +461 -0
  92. package/src/adapters/cursor/thread-continuity.ts +67 -0
  93. package/src/adapters/cursor/tool-definitions.ts +735 -0
  94. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  95. package/src/adapters/cursor/transport-retry.ts +132 -0
  96. package/src/adapters/cursor/transport.ts +79 -0
  97. package/src/adapters/cursor/types.ts +79 -0
  98. package/src/adapters/cursor.ts +322 -0
  99. package/src/adapters/google-antigravity-hosts.ts +48 -0
  100. package/src/adapters/google-antigravity-replay.ts +827 -0
  101. package/src/adapters/google-antigravity-tools.ts +105 -0
  102. package/src/adapters/google-antigravity-wire.ts +141 -0
  103. package/src/adapters/google-errors.ts +92 -0
  104. package/src/adapters/google-http.ts +460 -0
  105. package/src/adapters/google-tool-schema.ts +238 -0
  106. package/src/adapters/google-truncation.ts +24 -0
  107. package/src/adapters/google-wire-compiler.ts +232 -0
  108. package/src/adapters/google.ts +1377 -0
  109. package/src/adapters/identity.ts +77 -0
  110. package/src/adapters/image.ts +23 -0
  111. package/src/adapters/kiro-constants.ts +16 -0
  112. package/src/adapters/kiro-errors.ts +208 -0
  113. package/src/adapters/kiro-events.ts +197 -0
  114. package/src/adapters/kiro-images.ts +129 -0
  115. package/src/adapters/kiro-retry.ts +312 -0
  116. package/src/adapters/kiro-thinking.ts +112 -0
  117. package/src/adapters/kiro-tool-fallback.ts +36 -0
  118. package/src/adapters/kiro-tools.ts +224 -0
  119. package/src/adapters/kiro-truncation.ts +33 -0
  120. package/src/adapters/kiro-wire.ts +129 -0
  121. package/src/adapters/kiro.ts +1936 -0
  122. package/src/adapters/mimo-free.ts +280 -0
  123. package/src/adapters/openai-chat-url.ts +11 -0
  124. package/src/adapters/openai-chat.ts +1980 -0
  125. package/src/adapters/openai-responses-url.ts +16 -0
  126. package/src/adapters/openai-responses.ts +1911 -0
  127. package/src/adapters/registry.ts +175 -0
  128. package/src/adapters/responses-tool-schema.ts +67 -0
  129. package/src/adapters/run-turn-queue.ts +114 -0
  130. package/src/adapters/tool-call-id.ts +119 -0
  131. package/src/adapters/tool-catalog-nudge.ts +154 -0
  132. package/src/adapters/upstream-http-error.ts +48 -0
  133. package/src/adapters/xai-web-search.ts +185 -0
  134. package/src/bridge.ts +1986 -0
  135. package/src/chat/inbound.ts +319 -0
  136. package/src/chat/outbound.ts +821 -0
  137. package/src/claude/agents-inject.ts +266 -0
  138. package/src/claude/alias.ts +149 -0
  139. package/src/claude/auth-detect.ts +229 -0
  140. package/src/claude/auth-mode-migration.ts +32 -0
  141. package/src/claude/auth-mode.ts +62 -0
  142. package/src/claude/context-windows.ts +205 -0
  143. package/src/claude/desktop-3p-guard.ts +35 -0
  144. package/src/claude/desktop-3p-paths.ts +84 -0
  145. package/src/claude/desktop-3p.ts +615 -0
  146. package/src/claude/desktop-health.ts +26 -0
  147. package/src/claude/desktop-profile.ts +263 -0
  148. package/src/claude/gateway-cache.ts +107 -0
  149. package/src/claude/inbound-debug.ts +163 -0
  150. package/src/claude/inbound.ts +578 -0
  151. package/src/claude/model-info.ts +174 -0
  152. package/src/claude/outbound.ts +926 -0
  153. package/src/cli/access.ts +108 -0
  154. package/src/cli/account-api.ts +302 -0
  155. package/src/cli/account-auth.ts +250 -0
  156. package/src/cli/account-catalog-refresh.ts +14 -0
  157. package/src/cli/account-extended.ts +737 -0
  158. package/src/cli/account-main.ts +317 -0
  159. package/src/cli/account.ts +299 -0
  160. package/src/cli/agent-driven.ts +70 -0
  161. package/src/cli/agent.ts +290 -0
  162. package/src/cli/catalog-prewarm.ts +27 -0
  163. package/src/cli/claude-agent-startup-sync.ts +73 -0
  164. package/src/cli/claude-desktop.ts +213 -0
  165. package/src/cli/claude.ts +355 -0
  166. package/src/cli/codex-log-guard-doctor.ts +103 -0
  167. package/src/cli/codex-shim-autorestore.ts +47 -0
  168. package/src/cli/codex-shim-readiness.ts +76 -0
  169. package/src/cli/combo.ts +127 -0
  170. package/src/cli/config-command.ts +209 -0
  171. package/src/cli/debug.ts +228 -0
  172. package/src/cli/dispatch.ts +585 -0
  173. package/src/cli/doctor.ts +1202 -0
  174. package/src/cli/ensure-desired-integrations.ts +152 -0
  175. package/src/cli/export-command.ts +213 -0
  176. package/src/cli/help.ts +101 -0
  177. package/src/cli/index.ts +973 -0
  178. package/src/cli/init.ts +211 -0
  179. package/src/cli/integrations.ts +260 -0
  180. package/src/cli/interactive-confirm.ts +133 -0
  181. package/src/cli/lab.ts +607 -0
  182. package/src/cli/launcher-context.ts +77 -0
  183. package/src/cli/minimax.ts +497 -0
  184. package/src/cli/models-runtime.ts +245 -0
  185. package/src/cli/models.ts +422 -0
  186. package/src/cli/observe.ts +206 -0
  187. package/src/cli/opencode.ts +588 -0
  188. package/src/cli/provider-replit.ts +232 -0
  189. package/src/cli/provider-runtime.ts +179 -0
  190. package/src/cli/provider.ts +492 -0
  191. package/src/cli/ready.ts +301 -0
  192. package/src/cli/registry.ts +422 -0
  193. package/src/cli/replit-gateway-key-input.ts +138 -0
  194. package/src/cli/root.ts +86 -0
  195. package/src/cli/route-policy.ts +92 -0
  196. package/src/cli/runtime-api.ts +328 -0
  197. package/src/cli/star-prompt.ts +211 -0
  198. package/src/cli/status-oauth.ts +78 -0
  199. package/src/cli/status.ts +328 -0
  200. package/src/cli/system-command.ts +112 -0
  201. package/src/cli/system-restart-client.ts +146 -0
  202. package/src/cli/tray-proxy.ts +199 -0
  203. package/src/cli/v2.ts +268 -0
  204. package/src/cli.ts +10 -0
  205. package/src/clients/config-export.ts +1704 -0
  206. package/src/codex/account-id.ts +34 -0
  207. package/src/codex/account-label.ts +47 -0
  208. package/src/codex/account-lifecycle.ts +172 -0
  209. package/src/codex/account-namespace-match.ts +63 -0
  210. package/src/codex/account-namespaces.ts +195 -0
  211. package/src/codex/account-pause.ts +20 -0
  212. package/src/codex/account-priority.ts +83 -0
  213. package/src/codex/account-runtime-state.ts +31 -0
  214. package/src/codex/account-store.ts +544 -0
  215. package/src/codex/account-usability.ts +43 -0
  216. package/src/codex/admission.ts +256 -0
  217. package/src/codex/affinity-debug.ts +162 -0
  218. package/src/codex/agent-roles-sync.ts +225 -0
  219. package/src/codex/agent-roles.ts +238 -0
  220. package/src/codex/app-server-processes.ts +1143 -0
  221. package/src/codex/app-server-restart-service.ts +232 -0
  222. package/src/codex/auth-api.ts +2147 -0
  223. package/src/codex/auth-collision.ts +109 -0
  224. package/src/codex/auth-context.ts +665 -0
  225. package/src/codex/autostart-health.ts +156 -0
  226. package/src/codex/catalog/account-models.ts +67 -0
  227. package/src/codex/catalog/aggregation.ts +436 -0
  228. package/src/codex/catalog/bundled.ts +549 -0
  229. package/src/codex/catalog/effort.ts +446 -0
  230. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  231. package/src/codex/catalog/kinds.ts +2 -0
  232. package/src/codex/catalog/metadata.ts +664 -0
  233. package/src/codex/catalog/native-models.ts +72 -0
  234. package/src/codex/catalog/parsing.ts +650 -0
  235. package/src/codex/catalog/provider-fetch.ts +2064 -0
  236. package/src/codex/catalog/sync.ts +1883 -0
  237. package/src/codex/catalog-admission.ts +199 -0
  238. package/src/codex/catalog-refresh-status.ts +105 -0
  239. package/src/codex/catalog-write-serialization.ts +242 -0
  240. package/src/codex/catalog.ts +14 -0
  241. package/src/codex/codex-write-lock.ts +384 -0
  242. package/src/codex/convergence-types.ts +614 -0
  243. package/src/codex/convergence.ts +651 -0
  244. package/src/codex/coordinator-doctor.ts +332 -0
  245. package/src/codex/custom-model-catalog-migration.ts +176 -0
  246. package/src/codex/data/upstream-models.json +830 -0
  247. package/src/codex/desired-state.ts +230 -0
  248. package/src/codex/exec-invocation.ts +22 -0
  249. package/src/codex/features.ts +1566 -0
  250. package/src/codex/generation.ts +202 -0
  251. package/src/codex/history-job.ts +407 -0
  252. package/src/codex/history-lock.ts +242 -0
  253. package/src/codex/history-migration-guardian.ts +108 -0
  254. package/src/codex/history-provider.ts +979 -0
  255. package/src/codex/history-transition.ts +105 -0
  256. package/src/codex/history-worker.ts +220 -0
  257. package/src/codex/home.ts +206 -0
  258. package/src/codex/inject-coordination.ts +290 -0
  259. package/src/codex/inject.ts +1733 -0
  260. package/src/codex/injected-marker.ts +106 -0
  261. package/src/codex/integration-record.ts +266 -0
  262. package/src/codex/internal/catalog-writer.ts +203 -0
  263. package/src/codex/internal/history-writer.ts +80 -0
  264. package/src/codex/journal.ts +225 -0
  265. package/src/codex/log-guard/inspect.ts +506 -0
  266. package/src/codex/log-guard/lock.ts +150 -0
  267. package/src/codex/log-guard/maintenance.ts +403 -0
  268. package/src/codex/log-guard/path-safety.ts +88 -0
  269. package/src/codex/log-guard/policy.ts +44 -0
  270. package/src/codex/log-guard/processes.ts +205 -0
  271. package/src/codex/log-guard/protection.ts +489 -0
  272. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  273. package/src/codex/main-account-cache.ts +56 -0
  274. package/src/codex/main-account.ts +68 -0
  275. package/src/codex/management-convergence.ts +167 -0
  276. package/src/codex/model-cache.ts +273 -0
  277. package/src/codex/model-entitlements.ts +353 -0
  278. package/src/codex/native-main-admission.ts +47 -0
  279. package/src/codex/native-main-auth-temp.ts +187 -0
  280. package/src/codex/native-main-claim.ts +178 -0
  281. package/src/codex/native-main-lock-file.ts +162 -0
  282. package/src/codex/native-main-owner.ts +329 -0
  283. package/src/codex/native-profile-api.ts +247 -0
  284. package/src/codex/native-profile-manager.ts +1531 -0
  285. package/src/codex/native-profile-processes.ts +121 -0
  286. package/src/codex/native-profile-recovery.ts +99 -0
  287. package/src/codex/native-profile-stage-store.ts +387 -0
  288. package/src/codex/native-profile-startup.ts +492 -0
  289. package/src/codex/native-profile-store.ts +855 -0
  290. package/src/codex/native-profile-types.ts +120 -0
  291. package/src/codex/native-residue.ts +682 -0
  292. package/src/codex/paths.ts +144 -0
  293. package/src/codex/plan-from-token.ts +140 -0
  294. package/src/codex/plan.ts +40 -0
  295. package/src/codex/plugins-doctor.ts +242 -0
  296. package/src/codex/pool-rotation.ts +295 -0
  297. package/src/codex/project-config-warnings.ts +425 -0
  298. package/src/codex/prompt-journal.ts +352 -0
  299. package/src/codex/prompt-layers.ts +967 -0
  300. package/src/codex/prompt-lock.ts +143 -0
  301. package/src/codex/quota-rejection.ts +298 -0
  302. package/src/codex/quota.ts +573 -0
  303. package/src/codex/refresh.ts +62 -0
  304. package/src/codex/reset-credit-recovery.ts +1044 -0
  305. package/src/codex/routing.ts +1888 -0
  306. package/src/codex/runtime.ts +659 -0
  307. package/src/codex/shim.ts +2170 -0
  308. package/src/codex/subagent-defaults.ts +550 -0
  309. package/src/codex/subagent-model-fallback.ts +784 -0
  310. package/src/codex/sync.ts +319 -0
  311. package/src/codex/transition-state.ts +612 -0
  312. package/src/codex/upstream-host-health.ts +368 -0
  313. package/src/codex/user-identity.ts +557 -0
  314. package/src/codex/warmup.ts +298 -0
  315. package/src/codex/websocket-registry.ts +100 -0
  316. package/src/codex/write-coordination.ts +114 -0
  317. package/src/combos/failover.ts +160 -0
  318. package/src/combos/index.ts +45 -0
  319. package/src/combos/request.ts +94 -0
  320. package/src/combos/resolve.ts +232 -0
  321. package/src/combos/types.ts +398 -0
  322. package/src/config/provider-name.ts +24 -0
  323. package/src/config.ts +4041 -0
  324. package/src/fork/register.ts +3 -0
  325. package/src/generated/compatibility-version.json +3116 -0
  326. package/src/generated/model-metadata.ts +106 -0
  327. package/src/github/star-state.ts +203 -0
  328. package/src/grok/inject.ts +530 -0
  329. package/src/grok/inspect.ts +45 -0
  330. package/src/grok/status.ts +121 -0
  331. package/src/grok/sync.ts +66 -0
  332. package/src/images/artifacts.ts +516 -0
  333. package/src/images/fulfill-video.ts +163 -0
  334. package/src/images/fulfill.ts +149 -0
  335. package/src/images/index.ts +4 -0
  336. package/src/images/loop.ts +955 -0
  337. package/src/images/plan.ts +143 -0
  338. package/src/images/synthetic-tool.ts +133 -0
  339. package/src/images/types.ts +41 -0
  340. package/src/images/xai-client.ts +141 -0
  341. package/src/images/xai-video-client.ts +163 -0
  342. package/src/index.ts +22 -0
  343. package/src/integrations/config-io.ts +269 -0
  344. package/src/integrations/journal.ts +315 -0
  345. package/src/integrations/merge.ts +135 -0
  346. package/src/integrations/mutation-flight.ts +71 -0
  347. package/src/integrations/native/ownership-preflight.ts +202 -0
  348. package/src/integrations/omp-yaml-source.ts +358 -0
  349. package/src/integrations/owned-refresh.ts +74 -0
  350. package/src/integrations/ownership.ts +111 -0
  351. package/src/integrations/registry.ts +159 -0
  352. package/src/integrations/serialize.ts +314 -0
  353. package/src/integrations/state.ts +361 -0
  354. package/src/integrations/store.ts +103 -0
  355. package/src/integrations/writer-lock.ts +98 -0
  356. package/src/integrations/writer.ts +691 -0
  357. package/src/lab/artifacts/sanitize.ts +586 -0
  358. package/src/lab/artifacts/secure-fs.ts +475 -0
  359. package/src/lab/artifacts/store.ts +310 -0
  360. package/src/lab/automation/budgets.ts +78 -0
  361. package/src/lab/automation/config-persistence.ts +256 -0
  362. package/src/lab/automation/constants.ts +39 -0
  363. package/src/lab/automation/cooldown.ts +103 -0
  364. package/src/lab/automation/dispatch.ts +211 -0
  365. package/src/lab/automation/index.ts +13 -0
  366. package/src/lab/automation/orchestrator.ts +499 -0
  367. package/src/lab/automation/persistence.ts +512 -0
  368. package/src/lab/automation/planner.ts +371 -0
  369. package/src/lab/automation/policy.ts +136 -0
  370. package/src/lab/automation/queue.ts +191 -0
  371. package/src/lab/automation/recovery.ts +24 -0
  372. package/src/lab/automation/route-context.ts +21 -0
  373. package/src/lab/automation/run-key.ts +44 -0
  374. package/src/lab/automation/runs-query.ts +34 -0
  375. package/src/lab/automation/types.ts +160 -0
  376. package/src/lab/conformance/assertion.ts +325 -0
  377. package/src/lab/conformance/digest.ts +22 -0
  378. package/src/lab/conformance/executor.ts +741 -0
  379. package/src/lab/conformance/fixture-provider.ts +27 -0
  380. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  381. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  382. package/src/lab/conformance/harness-budget.ts +47 -0
  383. package/src/lab/conformance/index.ts +5 -0
  384. package/src/lab/conformance/jcs.ts +64 -0
  385. package/src/lab/conformance/json-pointer.ts +39 -0
  386. package/src/lab/conformance/manifest.ts +180 -0
  387. package/src/lab/conformance/mcp-stub.ts +179 -0
  388. package/src/lab/conformance/negative-controls.ts +164 -0
  389. package/src/lab/conformance/observation.ts +355 -0
  390. package/src/lab/conformance/runner.ts +68 -0
  391. package/src/lab/conformance/sse-normalize.ts +59 -0
  392. package/src/lab/conformance/suite-manifest.ts +78 -0
  393. package/src/lab/conformance/types.ts +214 -0
  394. package/src/lab/constants.ts +126 -0
  395. package/src/lab/digest.ts +64 -0
  396. package/src/lab/events/errors.ts +9 -0
  397. package/src/lab/events/limits.ts +117 -0
  398. package/src/lab/events/types.ts +229 -0
  399. package/src/lab/events/validate.ts +781 -0
  400. package/src/lab/fabric/constants.ts +40 -0
  401. package/src/lab/fabric/executor.ts +492 -0
  402. package/src/lab/fabric/index.ts +80 -0
  403. package/src/lab/fabric/manifest.ts +222 -0
  404. package/src/lab/fabric/observe.ts +489 -0
  405. package/src/lab/fabric/patch.ts +79 -0
  406. package/src/lab/fabric/producer-child.ts +139 -0
  407. package/src/lab/fabric/producer-isolate.ts +276 -0
  408. package/src/lab/fabric/producer-protocol.ts +61 -0
  409. package/src/lab/fabric/scratch.ts +439 -0
  410. package/src/lab/fabric/subject.ts +106 -0
  411. package/src/lab/fabric/types.ts +134 -0
  412. package/src/lab/fabric/verifier.ts +98 -0
  413. package/src/lab/index.ts +54 -0
  414. package/src/lab/ledger/artifact-refs.ts +127 -0
  415. package/src/lab/ledger/invalidation.ts +136 -0
  416. package/src/lab/ledger/purge.ts +310 -0
  417. package/src/lab/ledger/store.ts +532 -0
  418. package/src/lab/live/credential-lease.ts +53 -0
  419. package/src/lab/live/destination.ts +155 -0
  420. package/src/lab/live/executor.ts +336 -0
  421. package/src/lab/live/inert-tools.ts +56 -0
  422. package/src/lab/live/manifest.ts +85 -0
  423. package/src/lab/live/mcp-loopback.ts +57 -0
  424. package/src/lab/live/runner.ts +19 -0
  425. package/src/lab/live/sandbox.ts +61 -0
  426. package/src/lab/live/suite-manifest.ts +41 -0
  427. package/src/lab/live/transport.ts +118 -0
  428. package/src/lab/live/types.ts +197 -0
  429. package/src/lab/observe/from-conformance.ts +301 -0
  430. package/src/lab/observe/from-live.ts +117 -0
  431. package/src/lab/paths.ts +153 -0
  432. package/src/lab/projection/rebuild.ts +495 -0
  433. package/src/lab/projection/schema.ts +135 -0
  434. package/src/lab/projection/verdicts.ts +474 -0
  435. package/src/lab/projection/verification.ts +412 -0
  436. package/src/lab/public/bundle.ts +217 -0
  437. package/src/lab/public/community-authority.ts +175 -0
  438. package/src/lab/public/community-files.ts +29 -0
  439. package/src/lab/public/community.ts +479 -0
  440. package/src/lab/public/file-safety.ts +155 -0
  441. package/src/lab/public/ids.ts +26 -0
  442. package/src/lab/public/index.ts +16 -0
  443. package/src/lab/public/mutation-lock.ts +424 -0
  444. package/src/lab/public/operator.ts +353 -0
  445. package/src/lab/public/origin-purge.ts +79 -0
  446. package/src/lab/public/origin.ts +203 -0
  447. package/src/lab/public/privacy.ts +143 -0
  448. package/src/lab/public/private-file.ts +261 -0
  449. package/src/lab/public/project.ts +124 -0
  450. package/src/lab/public/purge-test-fault.ts +21 -0
  451. package/src/lab/public/purge.ts +223 -0
  452. package/src/lab/public/registry.ts +44 -0
  453. package/src/lab/public/revocation.ts +252 -0
  454. package/src/lab/public/signature.ts +243 -0
  455. package/src/lab/public/storage.ts +105 -0
  456. package/src/lab/public/strict-json.ts +206 -0
  457. package/src/lab/public/time.ts +26 -0
  458. package/src/lab/public/types.ts +172 -0
  459. package/src/lab/public/validate.ts +391 -0
  460. package/src/lab/query/catalog.ts +101 -0
  461. package/src/lab/query/connection.ts +107 -0
  462. package/src/lab/query/constants.ts +4 -0
  463. package/src/lab/query/cursor.ts +132 -0
  464. package/src/lab/query/dto-map.ts +277 -0
  465. package/src/lab/query/errors.ts +22 -0
  466. package/src/lab/query/freshness.ts +53 -0
  467. package/src/lab/query/index.ts +45 -0
  468. package/src/lab/query/latest-observation.ts +59 -0
  469. package/src/lab/query/passive-production.ts +159 -0
  470. package/src/lab/query/queries.ts +444 -0
  471. package/src/lab/query/types.ts +266 -0
  472. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  473. package/src/lab/subject/installation-salt.ts +112 -0
  474. package/src/lab/subject/protocol-subject.ts +80 -0
  475. package/src/lab/subject/route-subject.ts +74 -0
  476. package/src/lib/abort.ts +146 -0
  477. package/src/lib/admin-secrets.ts +25 -0
  478. package/src/lib/admission.ts +83 -0
  479. package/src/lib/app-owned-memory-stores.ts +195 -0
  480. package/src/lib/app-owned-memory.ts +265 -0
  481. package/src/lib/bounded-body.ts +346 -0
  482. package/src/lib/bun-binary-validator.d.mts +3 -0
  483. package/src/lib/bun-binary-validator.mjs +18 -0
  484. package/src/lib/bun-runtime.ts +184 -0
  485. package/src/lib/bun-stream-caps.ts +130 -0
  486. package/src/lib/codex-restart-contract.ts +120 -0
  487. package/src/lib/config-ownership.ts +364 -0
  488. package/src/lib/crash-guard.ts +344 -0
  489. package/src/lib/debug-log-buffer.ts +83 -0
  490. package/src/lib/debug-settings.ts +108 -0
  491. package/src/lib/debug.ts +31 -0
  492. package/src/lib/destination-policy.ts +380 -0
  493. package/src/lib/errors.ts +406 -0
  494. package/src/lib/eventstream-decoder.ts +253 -0
  495. package/src/lib/fabric-task-execution-authority.ts +7 -0
  496. package/src/lib/fabric-task-host.ts +29 -0
  497. package/src/lib/gcp-adc.ts +341 -0
  498. package/src/lib/injection-debug-log.ts +58 -0
  499. package/src/lib/lab-activation.ts +223 -0
  500. package/src/lib/lab-live-execution-authority.ts +13 -0
  501. package/src/lib/lab-live-host.ts +30 -0
  502. package/src/lib/lab-live-pinned-sender.ts +56 -0
  503. package/src/lib/lab-live-route-production.ts +130 -0
  504. package/src/lib/lab-passive-linker-registration.ts +26 -0
  505. package/src/lib/local-management-attestation.ts +51 -0
  506. package/src/lib/local-management-capability.ts +100 -0
  507. package/src/lib/local-provider-reload-contract.ts +100 -0
  508. package/src/lib/open-url.ts +25 -0
  509. package/src/lib/optional-shutdown-hooks.ts +57 -0
  510. package/src/lib/pinned-http.ts +270 -0
  511. package/src/lib/privacy.ts +20 -0
  512. package/src/lib/process-control.ts +168 -0
  513. package/src/lib/provider-outbound.ts +210 -0
  514. package/src/lib/provider-url.ts +14 -0
  515. package/src/lib/proxy-env.ts +18 -0
  516. package/src/lib/redact.ts +521 -0
  517. package/src/lib/retry-after.ts +55 -0
  518. package/src/lib/self-launch-argv.ts +15 -0
  519. package/src/lib/server-resource-ownership.ts +71 -0
  520. package/src/lib/service-secrets.ts +25 -0
  521. package/src/lib/shadow-call.ts +61 -0
  522. package/src/lib/sidecar-tracker.ts +52 -0
  523. package/src/lib/sse-decoder.ts +364 -0
  524. package/src/lib/state-store-registrations.ts +119 -0
  525. package/src/lib/state-store-sweeper.ts +184 -0
  526. package/src/lib/system-restart-contract.ts +73 -0
  527. package/src/lib/test-home-guard.ts +90 -0
  528. package/src/lib/token-estimate.ts +86 -0
  529. package/src/lib/tool-argument-integers.ts +202 -0
  530. package/src/lib/translator-budget.ts +400 -0
  531. package/src/lib/upstream-http-version.ts +57 -0
  532. package/src/lib/upstream-reachability.ts +95 -0
  533. package/src/lib/upstream-retry.ts +392 -0
  534. package/src/lib/win-exec.ts +115 -0
  535. package/src/lib/win-paths.ts +68 -0
  536. package/src/lib/windows-atomic-replace.ts +156 -0
  537. package/src/lib/windows-elevation.ts +773 -0
  538. package/src/lib/windows-secret-acl.ts +854 -0
  539. package/src/lib/windows-service-wrappers.ts +72 -0
  540. package/src/lib/windows-text.ts +106 -0
  541. package/src/lib/windows-user-principal.ts +341 -0
  542. package/src/lib/winsw.ts +403 -0
  543. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  544. package/src/oauth/account-import/index.ts +15 -0
  545. package/src/oauth/account-import/parser.ts +83 -0
  546. package/src/oauth/account-import/registry.ts +18 -0
  547. package/src/oauth/account-import/service.ts +75 -0
  548. package/src/oauth/account-import/types.ts +91 -0
  549. package/src/oauth/anthropic-routing.ts +594 -0
  550. package/src/oauth/anthropic.ts +188 -0
  551. package/src/oauth/antigravity-routing.ts +151 -0
  552. package/src/oauth/callback-server.ts +300 -0
  553. package/src/oauth/chatgpt.ts +161 -0
  554. package/src/oauth/command-code.ts +239 -0
  555. package/src/oauth/cursor.ts +252 -0
  556. package/src/oauth/github-copilot.ts +428 -0
  557. package/src/oauth/google-antigravity.ts +262 -0
  558. package/src/oauth/health.ts +407 -0
  559. package/src/oauth/index.ts +1504 -0
  560. package/src/oauth/key-providers.ts +124 -0
  561. package/src/oauth/kimi.ts +227 -0
  562. package/src/oauth/kiro-credentials.ts +726 -0
  563. package/src/oauth/kiro.ts +621 -0
  564. package/src/oauth/local-token-detect.ts +130 -0
  565. package/src/oauth/log.ts +50 -0
  566. package/src/oauth/login-cli.ts +223 -0
  567. package/src/oauth/nous.ts +798 -0
  568. package/src/oauth/pkce.ts +15 -0
  569. package/src/oauth/store.ts +728 -0
  570. package/src/oauth/token-guardian.ts +309 -0
  571. package/src/oauth/types.ts +62 -0
  572. package/src/oauth/xai.ts +241 -0
  573. package/src/providers/alibaba-region-backup.ts +75 -0
  574. package/src/providers/alibaba-region-migration.ts +156 -0
  575. package/src/providers/alibaba-region-startup.ts +36 -0
  576. package/src/providers/antigravity-models.ts +695 -0
  577. package/src/providers/antigravity-quota.ts +216 -0
  578. package/src/providers/api-keys.ts +140 -0
  579. package/src/providers/base-url-choices.ts +74 -0
  580. package/src/providers/codex-capacity.ts +292 -0
  581. package/src/providers/command-code-efforts.ts +144 -0
  582. package/src/providers/context-cap.ts +82 -0
  583. package/src/providers/cursor-pool.ts +72 -0
  584. package/src/providers/derive.ts +586 -0
  585. package/src/providers/fastwire.ts +501 -0
  586. package/src/providers/free-directory.ts +187 -0
  587. package/src/providers/github-copilot-transport.ts +56 -0
  588. package/src/providers/google-vertex-location.ts +14 -0
  589. package/src/providers/key-failover.ts +271 -0
  590. package/src/providers/kiro-models.ts +67 -0
  591. package/src/providers/label.ts +19 -0
  592. package/src/providers/model-discovery-limits.ts +16 -0
  593. package/src/providers/model-discovery.ts +449 -0
  594. package/src/providers/model-rename-migration.ts +255 -0
  595. package/src/providers/model-rename-startup.ts +28 -0
  596. package/src/providers/openai-sidecar.ts +243 -0
  597. package/src/providers/openai-tier-startup.ts +56 -0
  598. package/src/providers/openai-tiers.ts +423 -0
  599. package/src/providers/openai-virtual-models.ts +83 -0
  600. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  601. package/src/providers/openrouter-routing.ts +102 -0
  602. package/src/providers/provider-id-rewrite.ts +185 -0
  603. package/src/providers/quota.ts +2345 -0
  604. package/src/providers/registry.ts +2918 -0
  605. package/src/providers/replit/constants.ts +27 -0
  606. package/src/providers/replit/derive.ts +85 -0
  607. package/src/providers/replit/headers.ts +28 -0
  608. package/src/providers/replit/origin.ts +55 -0
  609. package/src/providers/replit/pair-install-response.ts +72 -0
  610. package/src/providers/replit/probe.ts +199 -0
  611. package/src/providers/replit/setup.ts +350 -0
  612. package/src/providers/request-pacing.ts +310 -0
  613. package/src/providers/service-tier.ts +277 -0
  614. package/src/providers/slug-codec.ts +103 -0
  615. package/src/providers/static-model-discovery.ts +86 -0
  616. package/src/providers/xai-responses-opt-in.ts +15 -0
  617. package/src/providers/xai-transport.ts +148 -0
  618. package/src/reasoning-effort.ts +183 -0
  619. package/src/responses/compaction.ts +142 -0
  620. package/src/responses/custom-tool-compat.ts +266 -0
  621. package/src/responses/hosted-tool-policy.ts +9 -0
  622. package/src/responses/namespace-tool-compat.ts +355 -0
  623. package/src/responses/parser.ts +838 -0
  624. package/src/responses/provider-continuation.ts +98 -0
  625. package/src/responses/provider-opaque-metadata.ts +73 -0
  626. package/src/responses/reasoning-envelope.ts +60 -0
  627. package/src/responses/reasoning-replay-cache.ts +426 -0
  628. package/src/responses/schema.ts +165 -0
  629. package/src/responses/spill-store.ts +459 -0
  630. package/src/responses/state.ts +1433 -0
  631. package/src/responses/thought-signature-replay.ts +347 -0
  632. package/src/responses/tool-groups.ts +19 -0
  633. package/src/responses/tool-search-compat.ts +301 -0
  634. package/src/responses/truncated-stop-reason.ts +60 -0
  635. package/src/router.ts +761 -0
  636. package/src/routing/analytics.ts +378 -0
  637. package/src/routing/capability.ts +244 -0
  638. package/src/routing/compatibility/assemble.ts +73 -0
  639. package/src/routing/compatibility/behavior.ts +278 -0
  640. package/src/routing/compatibility/catalog.ts +99 -0
  641. package/src/routing/compatibility/endpoint.ts +52 -0
  642. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  643. package/src/routing/compatibility/policy.ts +181 -0
  644. package/src/routing/compatibility/provider-slot.ts +56 -0
  645. package/src/routing/compatibility/reader.ts +110 -0
  646. package/src/routing/compatibility/subject.ts +191 -0
  647. package/src/routing/compatibility/types.ts +64 -0
  648. package/src/routing/compatibility/version.ts +104 -0
  649. package/src/routing/cost.ts +77 -0
  650. package/src/routing/evaluator.ts +495 -0
  651. package/src/routing/health.ts +412 -0
  652. package/src/routing/history/cursor.ts +43 -0
  653. package/src/routing/history/indexer.ts +605 -0
  654. package/src/routing/history/schema.ts +72 -0
  655. package/src/routing/profile-namespace.ts +15 -0
  656. package/src/routing/profile.ts +547 -0
  657. package/src/routing/quota.ts +145 -0
  658. package/src/routing/request-evidence.ts +45 -0
  659. package/src/routing/trace.ts +776 -0
  660. package/src/server/adapter-resolve.ts +53 -0
  661. package/src/server/auth-cors.ts +751 -0
  662. package/src/server/background-lifecycle.ts +182 -0
  663. package/src/server/chat-completions.ts +442 -0
  664. package/src/server/chat-native-sse.ts +331 -0
  665. package/src/server/chat-native.ts +426 -0
  666. package/src/server/claude-messages.ts +1030 -0
  667. package/src/server/direct-local-http.ts +347 -0
  668. package/src/server/effort-policy.ts +190 -0
  669. package/src/server/github-copilot-responses-repair.ts +338 -0
  670. package/src/server/gui-static.ts +152 -0
  671. package/src/server/image-retry.ts +42 -0
  672. package/src/server/images.ts +568 -0
  673. package/src/server/index.ts +1813 -0
  674. package/src/server/lifecycle.ts +498 -0
  675. package/src/server/live.ts +717 -0
  676. package/src/server/local-management-read-client.ts +90 -0
  677. package/src/server/local-provider-reload-client.ts +137 -0
  678. package/src/server/management/agent-settings-routes.ts +1433 -0
  679. package/src/server/management/api-access.ts +141 -0
  680. package/src/server/management/api-key-usage.ts +193 -0
  681. package/src/server/management/body.ts +41 -0
  682. package/src/server/management/combo-routes.ts +263 -0
  683. package/src/server/management/config-routes.ts +835 -0
  684. package/src/server/management/context.ts +113 -0
  685. package/src/server/management/integration-routes.ts +498 -0
  686. package/src/server/management/lab-automation-routes.ts +206 -0
  687. package/src/server/management/lab-routes.ts +563 -0
  688. package/src/server/management/logs-usage-routes.ts +586 -0
  689. package/src/server/management/model-routes.ts +560 -0
  690. package/src/server/management/model-rows.ts +163 -0
  691. package/src/server/management/native-integration-routes.ts +769 -0
  692. package/src/server/management/oauth-account-routes.ts +637 -0
  693. package/src/server/management/provider-capability-config.ts +48 -0
  694. package/src/server/management/provider-routes.ts +1033 -0
  695. package/src/server/management/replit-provider-routes.ts +86 -0
  696. package/src/server/management/request-history-routes.ts +191 -0
  697. package/src/server/management/routing-analytics-routes.ts +74 -0
  698. package/src/server/management/routing-profile-routes.ts +385 -0
  699. package/src/server/management/shared.ts +286 -0
  700. package/src/server/management/sidebar-routes.ts +106 -0
  701. package/src/server/management/storage-log-guard-routes.ts +186 -0
  702. package/src/server/management/sync-response.ts +69 -0
  703. package/src/server/management/system-restart.ts +435 -0
  704. package/src/server/management/system-routes.ts +194 -0
  705. package/src/server/management/usage-summary-cache.ts +94 -0
  706. package/src/server/management/vision-sidecar-options.ts +167 -0
  707. package/src/server/management/web-search-sidecar-options.ts +120 -0
  708. package/src/server/management-api.ts +314 -0
  709. package/src/server/management-auth.ts +482 -0
  710. package/src/server/memory-watchdog.ts +156 -0
  711. package/src/server/passive-route-linker.ts +66 -0
  712. package/src/server/port-reclaim.ts +307 -0
  713. package/src/server/ports.ts +156 -0
  714. package/src/server/proxy-liveness.ts +328 -0
  715. package/src/server/readiness.ts +99 -0
  716. package/src/server/relay-eager.ts +353 -0
  717. package/src/server/relay.ts +1209 -0
  718. package/src/server/request-decompress.ts +239 -0
  719. package/src/server/request-log-conversation.ts +168 -0
  720. package/src/server/request-log.ts +1259 -0
  721. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  722. package/src/server/responses/agent-task-recovery.ts +465 -0
  723. package/src/server/responses/collaboration.ts +551 -0
  724. package/src/server/responses/compact.ts +771 -0
  725. package/src/server/responses/core.ts +5389 -0
  726. package/src/server/responses/empty-completion-guard.ts +276 -0
  727. package/src/server/responses/encrypted-payload.ts +331 -0
  728. package/src/server/responses/fetch-helpers.ts +232 -0
  729. package/src/server/responses/input-admission.ts +185 -0
  730. package/src/server/responses/pacing-overload.ts +13 -0
  731. package/src/server/responses/passthrough-error.ts +78 -0
  732. package/src/server/responses/policy-fallback.ts +178 -0
  733. package/src/server/responses/responses-field-backfill.ts +251 -0
  734. package/src/server/responses/terminal-guard.ts +251 -0
  735. package/src/server/responses/upstream-error.ts +53 -0
  736. package/src/server/responses/ws-upstream.ts +308 -0
  737. package/src/server/responses-custom-tool-repair.ts +282 -0
  738. package/src/server/responses-image-gen-repair.ts +132 -0
  739. package/src/server/responses-item-id-repair.ts +272 -0
  740. package/src/server/responses-json-events.ts +90 -0
  741. package/src/server/responses-model-rewrite.ts +29 -0
  742. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  743. package/src/server/responses-snapshot-repair.ts +621 -0
  744. package/src/server/responses-terminal-repair.ts +342 -0
  745. package/src/server/responses-tool-search-repair.ts +267 -0
  746. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  747. package/src/server/responses.ts +25 -0
  748. package/src/server/search.ts +201 -0
  749. package/src/server/sse-frame-buffer.ts +292 -0
  750. package/src/server/sse-payload-rewrite.ts +263 -0
  751. package/src/server/startup-action-control.ts +315 -0
  752. package/src/server/startup-health-cache.ts +131 -0
  753. package/src/server/system-env.ts +484 -0
  754. package/src/server/windows-tcp-drop.ts +184 -0
  755. package/src/server/windows-tray-control.ts +41 -0
  756. package/src/server/ws-bridge.ts +472 -0
  757. package/src/service-manager-probe.ts +892 -0
  758. package/src/service.ts +3575 -0
  759. package/src/sidecar/auth.ts +92 -0
  760. package/src/sidecar/candidates.ts +83 -0
  761. package/src/stall-timeout.ts +20 -0
  762. package/src/storage/cleanup-job.ts +57 -0
  763. package/src/storage/cleanup.ts +3085 -0
  764. package/src/storage/policy-job.ts +457 -0
  765. package/src/storage/policy-scheduler.ts +40 -0
  766. package/src/storage/policy-worker.ts +59 -0
  767. package/src/storage/policy.ts +527 -0
  768. package/src/storage/restore-job.ts +299 -0
  769. package/src/storage/restore-worker.ts +58 -0
  770. package/src/storage/scanner.ts +238 -0
  771. package/src/storage/storage-mutation-coordinator.ts +139 -0
  772. package/src/storage/worker-lifecycle.ts +215 -0
  773. package/src/tray/assets/opencodex-tray-offline.ico +0 -0
  774. package/src/tray/assets/opencodex-tray-online.ico +0 -0
  775. package/src/tray/assets/opencodex-tray-warning.ico +0 -0
  776. package/src/tray/assets/opencodex-tray.png +0 -0
  777. package/src/tray/windows-tray.ps1 +364 -0
  778. package/src/tray/windows.ts +757 -0
  779. package/src/types/accounts.ts +37 -0
  780. package/src/types/config.ts +876 -0
  781. package/src/types/provider.ts +545 -0
  782. package/src/types/request.ts +384 -0
  783. package/src/types/tools.ts +131 -0
  784. package/src/types/wire.ts +80 -0
  785. package/src/types.ts +106 -0
  786. package/src/update/badge.ts +72 -0
  787. package/src/update/index.ts +415 -0
  788. package/src/update/job.ts +1887 -0
  789. package/src/update/notify.ts +263 -0
  790. package/src/update/npm-cache-preflight.d.mts +47 -0
  791. package/src/update/npm-cache-preflight.mjs +201 -0
  792. package/src/update/npm-invocation.d.mts +23 -0
  793. package/src/update/npm-invocation.mjs +94 -0
  794. package/src/update/transactional-install.d.mts +22 -0
  795. package/src/update/transactional-install.mjs +259 -0
  796. package/src/update/tray-update-plan.d.mts +18 -0
  797. package/src/update/tray-update-plan.mjs +38 -0
  798. package/src/usage/cost.ts +625 -0
  799. package/src/usage/debug.ts +97 -0
  800. package/src/usage/expected-prices.ts +416 -0
  801. package/src/usage/log.ts +1223 -0
  802. package/src/usage/summary.ts +753 -0
  803. package/src/usage/totals.ts +14 -0
  804. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  805. package/src/usage/user-cost-overlays.ts +314 -0
  806. package/src/vision/anthropic-describe.ts +189 -0
  807. package/src/vision/backends.ts +97 -0
  808. package/src/vision/describe.ts +131 -0
  809. package/src/vision/eligibility.ts +250 -0
  810. package/src/vision/index.ts +681 -0
  811. package/src/vision/reasoning.ts +55 -0
  812. package/src/vision/routed-describe.ts +175 -0
  813. package/src/vision/timeout-bounds.ts +9 -0
  814. package/src/web-search/anthropic-executor.ts +195 -0
  815. package/src/web-search/backends.ts +108 -0
  816. package/src/web-search/exa-executor.ts +88 -0
  817. package/src/web-search/executor.ts +113 -0
  818. package/src/web-search/format-result.ts +89 -0
  819. package/src/web-search/gemini-executor.ts +141 -0
  820. package/src/web-search/index.ts +331 -0
  821. package/src/web-search/loop.ts +896 -0
  822. package/src/web-search/parse.ts +315 -0
  823. package/src/web-search/progress-stream.ts +342 -0
  824. package/src/web-search/sources.ts +60 -0
  825. package/src/web-search/synthetic-tool.ts +47 -0
  826. package/src/web-search/xai-executor.ts +219 -0
@@ -0,0 +1,290 @@
1
+ import {
2
+ CliUsageError,
3
+ csv,
4
+ printData,
5
+ rejectArgs,
6
+ runCliAction,
7
+ runtimeRequest,
8
+ summaryLines,
9
+ takeBooleanOption,
10
+ takeFlag,
11
+ takeIntegerOption,
12
+ takeOption,
13
+ type RuntimeApiDeps,
14
+ } from "./runtime-api";
15
+ import { readFileSync } from "node:fs";
16
+
17
+ interface WebSearchModelOption {
18
+ value: string;
19
+ model: string;
20
+ backend: "openai" | "anthropic";
21
+ authSlot?: boolean;
22
+ }
23
+
24
+ const USAGE = `Usage:
25
+ ocx agent [status] [--json]
26
+ ocx agent injection <status|set> [--model <id|->] [--effort <level|->]
27
+ [--prompt <text|->] [--guidance <on|off>] [--json]
28
+ ocx agent effort <status|set> [--main <level|->] [--subagent <level|->] [--json]
29
+ ocx agent subagents <status|set|clear> [model,model...] [--json]
30
+ ocx agent roles <status|set|remove> [--file <path>] [--json]
31
+ ocx agent fallback <status|set|clear> [model,model...] [--poll-ms <5000-600000>] [--json]
32
+ ocx agent sidecar <status|web|vision> [--list] [--model <id|->]
33
+ [--backend web:<openai|anthropic|xai|gemini|exa|-> vision:<openai|anthropic|routed|->]
34
+ [--reasoning <level>] [--max-descriptions <n>] [--json]`;
35
+
36
+ function clearable(value: string | undefined): string | null | undefined {
37
+ return value === "-" ? null : value;
38
+ }
39
+
40
+ async function status(argv: string[], deps: RuntimeApiDeps): Promise<void> {
41
+ const args = [...argv];
42
+ const wantsJson = takeFlag(args, "--json");
43
+ rejectArgs(args, USAGE);
44
+ const [v2, injection, caps, subagents, roles, fallback, sidecars] = await Promise.all([
45
+ runtimeRequest("/api/v2", {}, deps),
46
+ runtimeRequest("/api/injection-model", {}, deps),
47
+ runtimeRequest("/api/effort-caps", {}, deps),
48
+ runtimeRequest("/api/subagent-models", {}, deps),
49
+ runtimeRequest("/api/subagent-roles", {}, deps),
50
+ runtimeRequest("/api/subagent-model-fallback", {}, deps),
51
+ runtimeRequest("/api/sidecar-settings", {}, deps),
52
+ ]);
53
+ const result = { v2, injection, caps, subagents, roles, fallback, sidecars };
54
+ printData(result, wantsJson, summaryLines(result));
55
+ }
56
+
57
+ async function injection(argv: string[], deps: RuntimeApiDeps): Promise<void> {
58
+ const args = [...argv];
59
+ const action = (args.shift() ?? "status").toLowerCase();
60
+ const wantsJson = takeFlag(args, "--json");
61
+ if (action === "status") {
62
+ rejectArgs(args, USAGE);
63
+ const result = await runtimeRequest("/api/injection-model", {}, deps);
64
+ printData(result, wantsJson, summaryLines(result));
65
+ return;
66
+ }
67
+ if (action !== "set") throw new CliUsageError(`unknown injection action ${action}`, USAGE);
68
+ const model = clearable(takeOption(args, "--model"));
69
+ const effort = clearable(takeOption(args, "--effort"));
70
+ const prompt = clearable(takeOption(args, "--prompt"));
71
+ const guidance = takeBooleanOption(args, "--guidance");
72
+ rejectArgs(args, USAGE);
73
+ const body: Record<string, unknown> = {};
74
+ if (model !== undefined) body.model = model;
75
+ if (effort !== undefined) body.effort = effort;
76
+ if (prompt !== undefined) body.prompt = prompt;
77
+ if (guidance !== undefined) body.multiAgentGuidanceEnabled = guidance;
78
+ if (Object.keys(body).length === 0) throw new CliUsageError("at least one injection option is required", USAGE);
79
+ const result = await runtimeRequest("/api/injection-model", { method: "PUT", body: JSON.stringify(body) }, deps);
80
+ printData(result, wantsJson, ["Agent injection settings updated."]);
81
+ }
82
+
83
+ async function effort(argv: string[], deps: RuntimeApiDeps): Promise<void> {
84
+ const args = [...argv];
85
+ const action = (args.shift() ?? "status").toLowerCase();
86
+ const wantsJson = takeFlag(args, "--json");
87
+ if (action === "status") {
88
+ rejectArgs(args, USAGE);
89
+ const result = await runtimeRequest("/api/effort-caps", {}, deps);
90
+ printData(result, wantsJson, summaryLines(result));
91
+ return;
92
+ }
93
+ if (action !== "set") throw new CliUsageError(`unknown effort action ${action}`, USAGE);
94
+ const main = clearable(takeOption(args, "--main"));
95
+ const subagent = clearable(takeOption(args, "--subagent"));
96
+ rejectArgs(args, USAGE);
97
+ const body: Record<string, unknown> = {};
98
+ if (main !== undefined) body.effortCap = main;
99
+ if (subagent !== undefined) body.subagentEffortCap = subagent;
100
+ if (Object.keys(body).length === 0) throw new CliUsageError("--main and/or --subagent is required", USAGE);
101
+ const result = await runtimeRequest("/api/effort-caps", { method: "PUT", body: JSON.stringify(body) }, deps);
102
+ printData(result, wantsJson, ["Agent effort caps updated."]);
103
+ }
104
+
105
+ async function subagents(argv: string[], deps: RuntimeApiDeps): Promise<void> {
106
+ const args = [...argv];
107
+ const action = (args.shift() ?? "status").toLowerCase();
108
+ const wantsJson = takeFlag(args, "--json");
109
+ if (action === "status") {
110
+ rejectArgs(args, USAGE);
111
+ const result = await runtimeRequest("/api/subagent-models", {}, deps);
112
+ printData(result, wantsJson, summaryLines(result));
113
+ return;
114
+ }
115
+ let models: string[];
116
+ if (action === "clear") models = [];
117
+ else if (action === "set") {
118
+ const raw = args.shift();
119
+ if (!raw) throw new CliUsageError("comma-separated subagent models are required", USAGE);
120
+ models = csv(raw) ?? [];
121
+ } else throw new CliUsageError(`unknown subagents action ${action}`, USAGE);
122
+ rejectArgs(args, USAGE);
123
+ if (models.length > 5) throw new CliUsageError("at most 5 subagent models are allowed", USAGE);
124
+ const result = await runtimeRequest("/api/subagent-models", { method: "PUT", body: JSON.stringify({ models }) }, deps);
125
+ printData(result, wantsJson, [`Subagent roster: ${models.join(", ") || "cleared"}`]);
126
+ }
127
+
128
+ async function readRolesDocument(deps: RuntimeApiDeps, file: string | undefined): Promise<unknown> {
129
+ const raw = file
130
+ ? readFileSync(file, "utf8")
131
+ : await readStdinDocument(deps);
132
+ let parsed: unknown;
133
+ try {
134
+ parsed = JSON.parse(raw);
135
+ } catch {
136
+ throw new CliUsageError("roles JSON is invalid", USAGE);
137
+ }
138
+ if (Array.isArray(parsed)) return { roles: parsed };
139
+ return parsed;
140
+ }
141
+
142
+ async function readStdinDocument(deps: RuntimeApiDeps): Promise<string> {
143
+ const input = deps.stdinImpl ?? process.stdin;
144
+ if (input.isTTY) throw new CliUsageError("roles set requires --file <path> or JSON on stdin", USAGE);
145
+ const chunks: Buffer[] = [];
146
+ for await (const chunk of input) {
147
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
148
+ }
149
+ const text = Buffer.concat(chunks).toString("utf8").trim();
150
+ if (!text) throw new CliUsageError("roles JSON was empty", USAGE);
151
+ return text;
152
+ }
153
+
154
+ async function roles(argv: string[], deps: RuntimeApiDeps): Promise<void> {
155
+ const args = [...argv];
156
+ const action = (args.shift() ?? "status").toLowerCase();
157
+ const wantsJson = takeFlag(args, "--json");
158
+ if (action === "status") {
159
+ rejectArgs(args, USAGE);
160
+ const result = await runtimeRequest("/api/subagent-roles", {}, deps);
161
+ printData(result, wantsJson, summaryLines(result));
162
+ return;
163
+ }
164
+ if (action === "set") {
165
+ const file = takeOption(args, "--file");
166
+ rejectArgs(args, USAGE);
167
+ const body = await readRolesDocument(deps, file);
168
+ if (!body || typeof body !== "object" || Array.isArray(body) || !("roles" in body)) {
169
+ throw new CliUsageError("roles JSON must be { roles: [...] } or an array", USAGE);
170
+ }
171
+ const result = await runtimeRequest("/api/subagent-roles", { method: "PUT", body: JSON.stringify(body) }, deps);
172
+ printData(result, wantsJson, ["Agent roles updated."]);
173
+ return;
174
+ }
175
+ if (action !== "remove") throw new CliUsageError(`unknown roles action ${action}`, USAGE);
176
+ const id = args.shift();
177
+ if (!id) throw new CliUsageError("role id is required", USAGE);
178
+ rejectArgs(args, USAGE);
179
+ const result = await runtimeRequest("/api/subagent-roles", {
180
+ method: "PUT",
181
+ body: JSON.stringify({ remove: id }),
182
+ }, deps);
183
+ printData(result, wantsJson, [`Removed role ${id}.`]);
184
+ }
185
+
186
+ async function fallback(argv: string[], deps: RuntimeApiDeps): Promise<void> {
187
+ const args = [...argv];
188
+ const action = (args.shift() ?? "status").toLowerCase();
189
+ const wantsJson = takeFlag(args, "--json");
190
+ if (action === "status") {
191
+ rejectArgs(args, USAGE);
192
+ const result = await runtimeRequest("/api/subagent-model-fallback", {}, deps);
193
+ printData(result, wantsJson, summaryLines(result));
194
+ return;
195
+ }
196
+ const body: Record<string, unknown> = {};
197
+ if (action === "clear") body.models = [];
198
+ else if (action === "set") {
199
+ const raw = args[0] && !args[0].startsWith("--") ? args.shift() : undefined;
200
+ if (raw) body.models = csv(raw) ?? [];
201
+ } else throw new CliUsageError(`unknown fallback action ${action}`, USAGE);
202
+ const pollMs = takeIntegerOption(args, "--poll-ms", { min: 5_000 });
203
+ if (pollMs !== undefined) {
204
+ if (pollMs > 600_000) throw new CliUsageError("--poll-ms must be <= 600000", USAGE);
205
+ body.pollMs = pollMs;
206
+ }
207
+ rejectArgs(args, USAGE);
208
+ if (Object.keys(body).length === 0) throw new CliUsageError("models and/or --poll-ms is required", USAGE);
209
+ const result = await runtimeRequest("/api/subagent-model-fallback", { method: "PUT", body: JSON.stringify(body) }, deps);
210
+ printData(result, wantsJson, ["Subagent fallback settings updated."]);
211
+ }
212
+
213
+ async function sidecar(argv: string[], deps: RuntimeApiDeps): Promise<void> {
214
+ const args = [...argv];
215
+ const section = (args.shift() ?? "status").toLowerCase();
216
+ const wantsJson = takeFlag(args, "--json");
217
+ if (section === "status") {
218
+ rejectArgs(args, USAGE);
219
+ const result = await runtimeRequest("/api/sidecar-settings", {}, deps);
220
+ printData(result, wantsJson, summaryLines(result));
221
+ return;
222
+ }
223
+ if (section !== "web" && section !== "vision") throw new CliUsageError("sidecar must be web, vision, or status", USAGE);
224
+ // --list must be consumed BEFORE rejectArgs sees it. It prints the server's
225
+ // candidate set — the exact list the GUI picker shows (#2188): the server
226
+ // computes it once and every surface consumes it, so the CLI cannot drift.
227
+ const wantsList = takeFlag(args, "--list");
228
+ if (wantsList) {
229
+ rejectArgs(args, USAGE);
230
+ const settings = await runtimeRequest("/api/sidecar-settings", {}, deps) as {
231
+ webSearchModels?: WebSearchModelOption[];
232
+ visionModels?: Array<{ value: string; backend?: string; baseline?: boolean }>;
233
+ };
234
+ if (section === "web") {
235
+ const options = settings.webSearchModels ?? [];
236
+ printData(options, wantsJson, options.length === 0
237
+ ? ["no runnable web-search sidecar models (log in to ChatGPT or Anthropic)"]
238
+ : options.map(option => `${option.value} [${option.backend}]${option.authSlot ? " (auth slot)" : ""}`));
239
+ } else {
240
+ const options = settings.visionModels ?? [];
241
+ printData(options, wantsJson, options.length === 0
242
+ ? ["no eligible vision describers"]
243
+ : options.map(option => `${option.value}${option.backend ? ` [${option.backend}]` : ""}${option.baseline ? " (baseline)" : ""}`));
244
+ }
245
+ return;
246
+ }
247
+ const model = takeOption(args, "--model");
248
+ const backend = takeOption(args, "--backend");
249
+ const reasoning = takeOption(args, "--reasoning");
250
+ const maxDescriptionsPerTurn = takeIntegerOption(args, "--max-descriptions", { min: 1 });
251
+ rejectArgs(args, USAGE);
252
+ const settings: Record<string, unknown> = {};
253
+ if (model !== undefined) settings.model = model === "-" ? "" : model;
254
+ if (backend !== undefined) settings.backend = backend === "-" ? null : backend;
255
+ if (reasoning !== undefined) settings.reasoning = reasoning;
256
+ if (maxDescriptionsPerTurn !== undefined) settings.maxDescriptionsPerTurn = maxDescriptionsPerTurn;
257
+ if (Object.keys(settings).length === 0) throw new CliUsageError("at least one sidecar option is required", USAGE);
258
+ if (section === "web" && model !== undefined && model !== "-") {
259
+ const offered = await runtimeRequest("/api/sidecar-settings", {}, deps) as {
260
+ webSearchModels?: WebSearchModelOption[];
261
+ };
262
+ const requestedBackend = backend === "-" ? "openai" : backend;
263
+ const option = offered.webSearchModels?.find(candidate =>
264
+ (candidate.value === model || candidate.model === model)
265
+ && (requestedBackend === undefined || candidate.backend === requestedBackend));
266
+ if (option) {
267
+ settings.model = option.model;
268
+ if (backend !== "-") settings.backend = option.backend;
269
+ }
270
+ }
271
+ const body = section === "web" ? { webSearch: settings } : { vision: settings };
272
+ const result = await runtimeRequest("/api/sidecar-settings", { method: "PUT", body: JSON.stringify(body) }, deps);
273
+ printData(result, wantsJson, [`${section} sidecar settings updated.`]);
274
+ }
275
+
276
+ export async function handleAgentCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
277
+ return runCliAction(async () => {
278
+ const [sub = "status", ...rest] = argv;
279
+ if (sub === "status") await status(rest, deps);
280
+ else if (sub === "injection" || sub === "guidance") await injection(rest, deps);
281
+ else if (sub === "effort") await effort(rest, deps);
282
+ else if (sub === "subagents" || sub === "roster") await subagents(rest, deps);
283
+ else if (sub === "roles") await roles(rest, deps);
284
+ else if (sub === "fallback") await fallback(rest, deps);
285
+ else if (sub === "sidecar") await sidecar(rest, deps);
286
+ else throw new CliUsageError(`unknown agent command ${sub}`, USAGE);
287
+ });
288
+ }
289
+
290
+ export const AGENT_USAGE = USAGE;
@@ -0,0 +1,27 @@
1
+ import type { OcxConfig } from "../types";
2
+
3
+ type GatherRoutedModels = (config: OcxConfig) => Promise<unknown>;
4
+
5
+ export type CatalogPrewarmDeps = {
6
+ loadConfig?: () => OcxConfig;
7
+ importCatalog?: () => Promise<{ gatherRoutedModels: GatherRoutedModels }>;
8
+ };
9
+
10
+ /**
11
+ * After the listen port is bound, kick off live provider discovery so the first
12
+ * GUI /v1/models and syncModelsToCodex share one gather flight instead of racing
13
+ * duplicate upstream /models fetches.
14
+ */
15
+ export function scheduleCatalogPrewarm(deps: CatalogPrewarmDeps = {}): void {
16
+ void Promise.resolve()
17
+ .then(async () => {
18
+ const load = deps.loadConfig ?? (await import("../config")).loadConfig;
19
+ const { gatherRoutedModels } = await (deps.importCatalog?.() ?? import("../codex/catalog"));
20
+ return gatherRoutedModels(load());
21
+ })
22
+ .catch(error => {
23
+ if (error && typeof error === "object" && (error as { code?: unknown }).code === "catalog_busy") {
24
+ console.warn("[catalog] startup discovery skipped: catalog gather is busy");
25
+ }
26
+ });
27
+ }
@@ -0,0 +1,73 @@
1
+ import type { OcxConfig } from "../types";
2
+ import { injectClaudeAgentDefs } from "../claude/agents-inject";
3
+ import { fetchClaudeContextWindows } from "./claude";
4
+ import type { ReadinessGate } from "../server/readiness";
5
+
6
+ export interface ClaudeAgentStartupSyncDeps {
7
+ fetchContextWindows?: typeof fetchClaudeContextWindows;
8
+ injectAgentDefs?: typeof injectClaudeAgentDefs;
9
+ warn?: (message: string) => void;
10
+ }
11
+
12
+ /**
13
+ * Keep the public readiness gate pending until both startup reconciliations have settled.
14
+ *
15
+ * The Codex sync remains the authority for ready versus failed. Claude roster repair is
16
+ * deliberately best-effort (#2200), but readiness must not become observable between the
17
+ * Codex write and that repair: a service manager could otherwise launch Claude Code against
18
+ * stale `ocx-*.md` files. A small forwarding gate delays only the successful transition;
19
+ * terminal Codex failure is still published immediately.
20
+ */
21
+ export async function reconcileClientStartupBeforeReady<T>(
22
+ readinessGate: ReadinessGate,
23
+ syncCodex: (deferredGate: ReadinessGate) => Promise<T>,
24
+ syncClaudeRoster: () => Promise<unknown>,
25
+ ): Promise<T> {
26
+ let codexReady = false;
27
+ const deferredGate: ReadinessGate = {
28
+ getStatus: () => readinessGate.getStatus(),
29
+ markReady: () => { codexReady = true; },
30
+ markFailed: () => readinessGate.markFailed(),
31
+ };
32
+
33
+ const result = await syncCodex(deferredGate);
34
+ await syncClaudeRoster();
35
+ if (codexReady) readinessGate.markReady();
36
+ return result;
37
+ }
38
+
39
+ /**
40
+ * Reconcile the generated Claude Code roster after the proxy listener is live.
41
+ *
42
+ * This belongs to the owning CLI lifecycle rather than `startServer`: the latter is also a
43
+ * library/test primitive and must not mutate a developer's real `~/.claude` directory merely
44
+ * because an in-process test server was created. The live Management API supplies the same bounded
45
+ * context-window map used by `ocx claude`; failure keeps startup available and falls back to an
46
+ * unmarked roster. Disabled integrations skip discovery and prune verified-owned definitions.
47
+ */
48
+ export async function syncClaudeAgentDefsAtProxyStartup(
49
+ config: OcxConfig,
50
+ port: number,
51
+ deps: ClaudeAgentStartupSyncDeps = {},
52
+ ): Promise<string[] | null> {
53
+ const inject = deps.injectAgentDefs ?? injectClaudeAgentDefs;
54
+ const warn = deps.warn ?? (message => console.warn(message));
55
+
56
+ try {
57
+ if (config.claudeCode?.enabled === false || config.claudeCode?.injectAgents === false) {
58
+ return inject(config, {});
59
+ }
60
+
61
+ let windows: Record<string, number> = {};
62
+ try {
63
+ windows = await (deps.fetchContextWindows ?? fetchClaudeContextWindows)(config, port);
64
+ } catch {
65
+ // Startup remains best-effort. The next management mutation or `ocx claude` launch can
66
+ // restore context markers after a transient catalog/Management API failure.
67
+ }
68
+ return inject(config, windows);
69
+ } catch (error) {
70
+ warn(`⚠ Claude agent definitions could not be synced at proxy startup: ${error instanceof Error ? error.message : String(error)}`);
71
+ return null;
72
+ }
73
+ }
@@ -0,0 +1,213 @@
1
+ import { readFileSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { loadConfig, saveConfigPreservingClaudeCode } from "../config";
4
+ import { setIntegrationEnabled } from "../codex/desired-state";
5
+ import {
6
+ DESKTOP_FAMILIES,
7
+ moveDesktopRoute,
8
+ parseDesktopProfile,
9
+ setDesktopFamilyDefault,
10
+ type DesktopFamily,
11
+ type DesktopProfile,
12
+ } from "../claude/desktop-profile";
13
+ import { writeDesktop3pConfig, type Desktop3pConfigMode, parseDesktop3pModeArgs } from "../claude/desktop-3p";
14
+ import { filterCatalogVisibleModels, desktopVisibleNativeSlugs, nativeContextLimits } from "../codex/catalog";
15
+ import { buildClaudeDesktopState, fetchAllModels } from "../server/management-api";
16
+ import { findLiveProxy } from "../server/proxy-liveness";
17
+ import { runtimeRequest } from "./runtime-api";
18
+ import { OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
19
+
20
+ function isFamily(value: string | undefined): value is DesktopFamily {
21
+ return !!value && (DESKTOP_FAMILIES as readonly string[]).includes(value);
22
+ }
23
+
24
+ function printDesktopHelp(): void {
25
+ console.log(`Usage:
26
+ ocx claude desktop [apply] [--static|--hybrid|--discovery-only]
27
+ ocx claude desktop show [--json]
28
+ ocx claude desktop move <provider/model> <opus|fable|sonnet|haiku> [--default]
29
+ ocx claude desktop default <family> <provider/model|none>
30
+ ocx claude desktop export <path|->
31
+ ocx claude desktop import <path> [--apply]`);
32
+ }
33
+
34
+ export interface ApplyProfileDeps {
35
+ findLiveProxyImpl?: typeof findLiveProxy;
36
+ postApplyImpl?: (
37
+ mode: Desktop3pConfigMode,
38
+ profile: DesktopProfile,
39
+ ) => Promise<{ ok?: boolean; path?: string; error?: string }>;
40
+ }
41
+
42
+ export async function applyProfile(
43
+ profile: DesktopProfile,
44
+ mode: Desktop3pConfigMode,
45
+ deps: ApplyProfileDeps = {},
46
+ ): Promise<{ ok: boolean; path: string; reason?: string; warning?: string }> {
47
+ // Explicit apply is an enable action. Persist intent before any Desktop write
48
+ // so a process crash cannot leave a gateway profile that startup immediately removes.
49
+ const desired = setIntegrationEnabled("claude-desktop", true);
50
+ if (!desired.ok) return { ok: false, path: "", reason: desired.message };
51
+ const config = loadConfig();
52
+ const state = await buildClaudeDesktopState(config, profile);
53
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: state.profile };
54
+ saveConfigPreservingClaudeCode(config);
55
+ const live = await (deps.findLiveProxyImpl ?? findLiveProxy)();
56
+ if (live) {
57
+ // #859: the Desktop alias reverse-map is process-local. Applying through the
58
+ // serving process installs the map there; a local-only write leaves the
59
+ // daemon unable to decode aliases, and the provider rejects them (400).
60
+ const post = deps.postApplyImpl ?? (async (m: Desktop3pConfigMode, p: DesktopProfile) =>
61
+ runtimeRequest<{ ok?: boolean; path?: string; error?: string; saved?: boolean; warning?: string }>(
62
+ "/api/claude-desktop/apply",
63
+ // The daemon's config may be older than what we just saved, so the
64
+ // profile travels with the request instead of being re-read there.
65
+ { method: "POST", body: JSON.stringify({ mode: m, profile: p }) },
66
+ ));
67
+ try {
68
+ const applied = await post(mode, state.profile);
69
+ if (applied.ok === false) return { ok: false, path: applied.path ?? "", reason: applied.error ?? "daemon apply failed" };
70
+ // Partial success: Desktop was written but the applied marker was not
71
+ // persisted. Pass the degradation up instead of reporting a clean apply.
72
+ const partial = (applied as { saved?: boolean; warning?: string }).saved === false;
73
+ return {
74
+ ok: true,
75
+ path: applied.path ?? "",
76
+ ...(partial ? { warning: (applied as { warning?: string }).warning ?? "applied marker was not saved" } : {}),
77
+ };
78
+ } catch (error) {
79
+ return { ok: false, path: "", reason: error instanceof Error ? error.message : String(error) };
80
+ }
81
+ }
82
+ const allModels = await fetchAllModels(config);
83
+ // The toggle can persist OFF while fetchAllModels was awaiting (same race the
84
+ // management writers fence). Re-read persisted intent immediately before the
85
+ // writer; a lost race is a discriminated skip, not a write.
86
+ const { claudeDesktopIntegrationEnabledNow } = await import("../codex/desired-state");
87
+ if (!claudeDesktopIntegrationEnabledNow()) {
88
+ return { ok: false, path: "", reason: "desired_state_changed" };
89
+ }
90
+ const routed = filterCatalogVisibleModels(allModels, config).map(model => ({
91
+ provider: model.provider,
92
+ id: model.id,
93
+ contextWindow: model.contextWindow,
94
+ }));
95
+ const result = writeDesktop3pConfig(
96
+ config.port ?? 10100,
97
+ [...desktopVisibleNativeSlugs(config)],
98
+ routed,
99
+ config.apiKeys?.[0]?.key,
100
+ mode,
101
+ state.profile,
102
+ nativeContextLimits(config),
103
+ );
104
+ return { ok: result.written, path: result.path, reason: result.reason };
105
+ }
106
+
107
+ export async function handleClaudeDesktopCommand(argv: string[], deps: ApplyProfileDeps = {}): Promise<number> {
108
+ const command = argv[0];
109
+ if (command === "help" || command === "--help" || command === "-h") {
110
+ printDesktopHelp();
111
+ return 0;
112
+ }
113
+
114
+ // Legacy mode flags remain apply aliases and are parsed before subcommands.
115
+ const legacyFlags = argv.filter(arg => ["--static", "--hybrid", "--discovery-only"].includes(arg));
116
+ const applyInvocation = argv.length === 0 || command === "apply" || legacyFlags.length > 0;
117
+ if (applyInvocation) {
118
+ const nonMode = argv.filter(arg => !["apply", "--static", "--hybrid", "--discovery-only"].includes(arg));
119
+ if (nonMode.length > 0) {
120
+ console.error(`알 수 없는 인자: ${nonMode.join(" ")}`);
121
+ return 1;
122
+ }
123
+ const parsedMode = parseDesktop3pModeArgs(legacyFlags);
124
+ if ("error" in parsedMode) { console.error(parsedMode.error); return 1; }
125
+ try {
126
+ const config = loadConfig();
127
+ const state = await buildClaudeDesktopState(config);
128
+ const result = await applyProfile(state.profile, parsedMode.mode, deps);
129
+ if (!result.ok) {
130
+ console.error(`설정 적용 실패: ${result.reason ?? "unknown error"}`);
131
+ console.error("프로필은 저장되었지만 Claude Desktop 설정 파일에는 반영되지 않았습니다. 프록시 상태를 확인한 뒤 다시 적용해 주세요.");
132
+ return 1;
133
+ }
134
+ console.log(`Claude Desktop 설정을 적용했습니다: ${result.path}`);
135
+ // The write landed; only the bookkeeping marker did not. Saying nothing
136
+ // would leave the saved-vs-applied display wrong with no explanation.
137
+ if (result.warning) console.warn(`⚠️ ${result.warning}`);
138
+ console.log("Claude Desktop을 완전히 종료한 뒤 다시 열어 주세요.");
139
+ return 0;
140
+ } catch (error) {
141
+ console.error(error instanceof Error ? error.message : String(error));
142
+ return 1;
143
+ }
144
+ }
145
+
146
+ try {
147
+ const config = loadConfig();
148
+ const state = await buildClaudeDesktopState(config);
149
+ if (command === "show") {
150
+ if (argv.length > 2 || (argv[1] && argv[1] !== "--json")) throw new Error("Usage: ocx claude desktop show [--json]");
151
+ if (argv[1] === "--json") console.log(JSON.stringify(state));
152
+ else {
153
+ for (const family of DESKTOP_FAMILIES) {
154
+ console.log(`${family.toUpperCase()}${state.profile.defaults[family] ? ` (default: ${state.profile.defaults[family]})` : ""}`);
155
+ for (const model of state.models.filter(item => item.assignment.family === family)) {
156
+ console.log(` ${model.available ? "•" : "○"} ${model.route} -> ${model.assignment.alias}${model.available ? "" : " (unavailable)"}`);
157
+ }
158
+ }
159
+ }
160
+ return 0;
161
+ }
162
+ if (command === "move") {
163
+ const [, route, familyRaw, ...flags] = argv;
164
+ if (!route || !isFamily(familyRaw) || flags.some(flag => flag !== "--default")) throw new Error("Usage: ocx claude desktop move <route> <family> [--default]");
165
+ if (!state.models.some(model => model.route === route && model.available)) throw new Error(`현재 사용할 수 없는 모델입니다: ${route}`);
166
+ const profile = moveDesktopRoute(state.profile, route, familyRaw, flags.includes("--default"));
167
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: profile };
168
+ saveConfigPreservingClaudeCode(config);
169
+ console.log(`${route} 모델을 ${familyRaw} 그룹으로 옮겼습니다.`);
170
+ return 0;
171
+ }
172
+ if (command === "default") {
173
+ const [, familyRaw, routeRaw] = argv;
174
+ if (!isFamily(familyRaw) || !routeRaw || argv.length !== 3) throw new Error("Usage: ocx claude desktop default <family> <route|none>");
175
+ const route = routeRaw === "none" ? null : routeRaw;
176
+ if (route && !state.models.some(model => model.route === route && model.available)) throw new Error(`현재 사용할 수 없는 모델입니다: ${route}`);
177
+ const profile = setDesktopFamilyDefault(state.profile, familyRaw, route);
178
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: profile };
179
+ saveConfigPreservingClaudeCode(config);
180
+ console.log(`${familyRaw} 기본 모델을 ${route ?? "없음"}으로 지정했습니다.`);
181
+ return 0;
182
+ }
183
+ if (command === "export") {
184
+ const target = argv[1];
185
+ if (!target || argv.length !== 2) throw new Error("Usage: ocx claude desktop export <path|->");
186
+ const json = JSON.stringify(state.profile, null, 2) + "\n";
187
+ if (target === "-") process.stdout.write(json);
188
+ else writeFileSync(resolve(target), json, { encoding: "utf8", mode: 0o600 });
189
+ return 0;
190
+ }
191
+ if (command === "import") {
192
+ const source = argv[1];
193
+ const flags = argv.slice(2);
194
+ if (!source || flags.some(flag => flag !== "--apply")) throw new Error("Usage: ocx claude desktop import <path> [--apply]");
195
+ const profile = parseDesktopProfile(JSON.parse(readFileSync(resolve(source), "utf8")));
196
+ const reconciled = (await buildClaudeDesktopState(config, profile)).profile;
197
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: reconciled };
198
+ saveConfigPreservingClaudeCode(config);
199
+ if (flags.includes("--apply")) {
200
+ const result = await applyProfile(reconciled, "static", deps);
201
+ if (!result.ok) { console.error(`프로필은 저장했지만 Desktop 적용에 실패했습니다: ${result.reason ?? "unknown error"}`); return 1; }
202
+ if (result.warning) console.warn(`⚠️ ${result.warning}`);
203
+ }
204
+ console.log("Claude Desktop 프로필을 가져왔습니다.");
205
+ return 0;
206
+ }
207
+ printDesktopHelp();
208
+ return 1;
209
+ } catch (error) {
210
+ console.error(error instanceof Error ? error.message : String(error));
211
+ return 1;
212
+ }
213
+ }