@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,211 @@
1
+ import * as readline from "node:readline";
2
+ import { existsSync, readFileSync, unlinkSync } from "node:fs";
3
+ import { injectCodexConfig } from "../codex/inject";
4
+ import { classifyOpenAiTierBackup, getConfigPath, getDefaultConfig, isValidProviderName, preserveOpenAiTierRollbackSnapshot, saveConfig } from "../config";
5
+ import { enrichProviderFromCatalog } from "../oauth/key-providers";
6
+ import { deriveInitProviders } from "../providers/derive";
7
+ import type { OcxConfig, OcxProviderConfig } from "../types";
8
+
9
+ function createPrompt(): { ask(question: string): Promise<string>; close(): void } {
10
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
11
+ let closed = false;
12
+ rl.on("close", () => { closed = true; });
13
+ return {
14
+ ask(question: string): Promise<string> {
15
+ return new Promise((resolve, reject) => {
16
+ if (closed) {
17
+ reject(new Error("stdin closed before the prompt could be answered"));
18
+ return;
19
+ }
20
+ const onClose = () => {
21
+ reject(new Error("stdin reached EOF while waiting for input"));
22
+ };
23
+ rl.once("close", onClose);
24
+ rl.question(question, answer => {
25
+ rl.off("close", onClose);
26
+ resolve(answer);
27
+ });
28
+ });
29
+ },
30
+ close() {
31
+ if (!closed) rl.close();
32
+ },
33
+ };
34
+ }
35
+
36
+ type InitKind = "forward" | "oauth" | "key" | "local";
37
+ export interface InitProvider {
38
+ id: string;
39
+ label: string;
40
+ adapter: string;
41
+ baseUrl: string;
42
+ kind: InitKind;
43
+ dashboardUrl?: string;
44
+ defaultModel?: string;
45
+ }
46
+
47
+ /**
48
+ * The full CLI provider menu, derived from the canonical provider registry so `ocx init`,
49
+ * the GUI picker, key-login catalog, OAuth seeds, and metadata aliases cannot drift.
50
+ */
51
+ export function buildInitProviders(): InitProvider[] {
52
+ return deriveInitProviders();
53
+ }
54
+
55
+ const KIND_HEADING: Record<InitKind, string> = {
56
+ forward: "ChatGPT login",
57
+ oauth: "Account login (OAuth — then run: ocx login <id>)",
58
+ key: "API key (paste a key from the provider's dashboard)",
59
+ local: "Local servers (usually no key)",
60
+ };
61
+
62
+ function printMenu(providers: InitProvider[]): void {
63
+ console.log("Choose your default provider (you can add more later):");
64
+ let lastKind: InitKind | null = null;
65
+ providers.forEach((p, i) => {
66
+ if (p.kind !== lastKind) { console.log(`\n ${KIND_HEADING[p.kind]}:`); lastKind = p.kind; }
67
+ console.log(` ${String(i + 1).padStart(2)}. ${p.label}`);
68
+ });
69
+ console.log(`\n ${providers.length + 1}. custom (enter URL manually)`);
70
+ }
71
+
72
+ const envKeyFor = (id: string) => `${id.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
73
+
74
+ /** Post-init cleanup of `.pre-openai-tiers-v2.bak` with rollback preservation (issue #257). */
75
+ export function cleanupOpenAiTierBackupAfterInit(configPath = getConfigPath()): void {
76
+ const backup = `${configPath}.pre-openai-tiers-v2.bak`;
77
+ try {
78
+ if (!existsSync(backup)) return;
79
+ if (classifyOpenAiTierBackup(readFileSync(backup)) === "stale") {
80
+ unlinkSync(backup);
81
+ return;
82
+ }
83
+ const preserved = preserveOpenAiTierRollbackSnapshot(configPath);
84
+ console.warn(`⚠️ Kept your pre-migration config rollback snapshot at ${preserved}`);
85
+ } catch { /* cleanup is best-effort; never block init on backup housekeeping */ }
86
+ }
87
+
88
+ export async function runInit(): Promise<void> {
89
+ const prompt = createPrompt();
90
+ try {
91
+ console.log("\n🔧 opencodex (ocx) setup\n");
92
+
93
+ const providers = buildInitProviders();
94
+ printMenu(providers);
95
+
96
+ const choice = await prompt.ask("\nSelect default provider (number): ");
97
+ const idx = parseInt(choice, 10) - 1;
98
+
99
+ let providerName: string;
100
+ let providerConfig: OcxProviderConfig;
101
+ let oauthHint = false;
102
+
103
+ if (idx >= 0 && idx < providers.length) {
104
+ const p = providers[idx];
105
+ providerName = p.id;
106
+ console.log(`\n📡 ${p.label}`);
107
+ console.log(` Base URL: ${p.baseUrl}`);
108
+
109
+ if (p.kind === "forward") {
110
+ providerConfig = { adapter: p.adapter, baseUrl: p.baseUrl, authMode: "forward" };
111
+ console.log(" No API key needed — forwards your existing `codex login`.");
112
+ } else if (p.kind === "oauth") {
113
+ providerConfig = { adapter: p.adapter, baseUrl: p.baseUrl, authMode: "oauth", ...(p.defaultModel ? { defaultModel: p.defaultModel } : {}) };
114
+ oauthHint = true;
115
+ } else {
116
+ // key + local: collect a key (local usually blank).
117
+ if (p.dashboardUrl) console.log(` 🔑 Get your key: ${p.dashboardUrl}`);
118
+ // Template URL with placeholders (e.g. Cloudflare's {account_id}) needs a resolved value.
119
+ let baseUrl = p.baseUrl;
120
+ if (/\{[^}]*\}/.test(baseUrl)) {
121
+ const resolved = (await prompt.ask(` Your endpoint URL (${baseUrl}): `)).trim();
122
+ if (!resolved) {
123
+ console.error(" A resolved URL is required — replace the {placeholder} with your actual value.");
124
+ process.exit(1);
125
+ }
126
+ baseUrl = resolved;
127
+ }
128
+ const env = envKeyFor(p.id);
129
+ const hint = p.kind === "local" ? "API key (usually blank — press Enter): " : `API key (paste, or env var $${env}): `;
130
+ const apiKey = (await prompt.ask(`\n${hint}`)).trim();
131
+ const modelChoice = (await prompt.ask(`Default model${p.defaultModel ? ` [${p.defaultModel}]` : " (optional)"}: `)).trim();
132
+ const defaultModel = modelChoice || p.defaultModel;
133
+ providerConfig = {
134
+ adapter: p.adapter,
135
+ baseUrl,
136
+ ...(p.kind === "key" ? { apiKey: apiKey || `\${${env}}` } : apiKey ? { apiKey } : {}),
137
+ ...(defaultModel ? { defaultModel } : {}),
138
+ };
139
+ // Apply the catalog's models / vision classification (same enrichment as the GUI).
140
+ enrichProviderFromCatalog(p.id, providerConfig);
141
+ }
142
+ } else {
143
+ providerName = (await prompt.ask("Provider name: ")).trim();
144
+ if (!isValidProviderName(providerName)) {
145
+ console.error("Provider name must use letters, numbers, dot, underscore, or hyphen and cannot be a reserved object key.");
146
+ process.exit(1);
147
+ }
148
+ const baseUrl = await prompt.ask("Base URL (e.g. http://localhost:11434/v1): ");
149
+ const adapter = await prompt.ask("Adapter [openai-chat]: ") || "openai-chat";
150
+ const apiKey = await prompt.ask("API key (optional): ");
151
+ const defaultModel = await prompt.ask("Default model: ");
152
+ providerConfig = {
153
+ adapter: adapter.trim(),
154
+ baseUrl: baseUrl.trim(),
155
+ ...(apiKey.trim() ? { apiKey: apiKey.trim() } : {}),
156
+ ...(defaultModel.trim() ? { defaultModel: defaultModel.trim() } : {}),
157
+ };
158
+ }
159
+
160
+ const portStr = await prompt.ask("\nProxy port [10100]: ");
161
+ const port = parseInt(portStr, 10) || 10100;
162
+
163
+ const config: OcxConfig = {
164
+ ...getDefaultConfig(),
165
+ port,
166
+ providers: { [providerName]: providerConfig },
167
+ defaultProvider: providerName,
168
+ };
169
+
170
+ saveConfig(config);
171
+ // Init writes a fresh config, so a stale pre-migration backup from a previous
172
+ // installation would make the next `ocx start` crash on a stale-backup
173
+ // collision (issue #257). But only a STALE backup (unparseable, or already a
174
+ // post-migration v2 snapshot) may be deleted; a backup that still parses as a
175
+ // valid pre-migration (v1) config is a user-intentional rollback point and is
176
+ // preserved by renaming it out of the collision path (sol review 260722).
177
+ cleanupOpenAiTierBackupAfterInit();
178
+ console.log(`\n✅ Config saved to ~/.opencodex/config.json`);
179
+ if (oauthHint) console.log(`🔐 Authenticate this provider with: ocx login ${providerName}`);
180
+
181
+ const injectAnswer = await prompt.ask("Inject into Codex config.toml? [Y/n]: ");
182
+ if (injectAnswer.trim().toLowerCase() !== "n") {
183
+ console.log("Fetching available models from provider...");
184
+ const result = await injectCodexConfig(port, config);
185
+ console.log(result.success ? `✅ ${result.message}` : `⚠️ ${result.message}`);
186
+ }
187
+
188
+ const shimAnswer = await prompt.ask("Install Codex autostart shim? [Y/n]: ");
189
+ if (shimAnswer.trim().toLowerCase() !== "n") {
190
+ try {
191
+ const { installCodexShim } = await import("../codex/shim");
192
+ const result = installCodexShim();
193
+ console.log(result.installed ? `✅ ${result.message}` : `⚠️ ${result.message}`);
194
+ } catch (err) {
195
+ console.log(`⚠️ Codex autostart shim skipped: ${err instanceof Error ? err.message : String(err)}`);
196
+ }
197
+ }
198
+
199
+ console.log(`\n🚀 Setup complete! Run 'ocx start' to start the proxy.`);
200
+ } catch (error) {
201
+ const message = error instanceof Error ? error.message : String(error);
202
+ if (/stdin (closed|reached EOF)/i.test(message)) {
203
+ console.error(`\n❌ ${message}. Re-run \`ocx init\` in an interactive terminal.`);
204
+ process.exitCode = 1;
205
+ return;
206
+ }
207
+ throw error;
208
+ } finally {
209
+ prompt.close();
210
+ }
211
+ }
@@ -0,0 +1,260 @@
1
+ import {
2
+ CliUsageError,
3
+ csv,
4
+ printData,
5
+ rejectArgs,
6
+ runCliAction,
7
+ runtimeRequest,
8
+ summaryLines,
9
+ takeBooleanOption,
10
+ takeFlag,
11
+ takeOption,
12
+ type RuntimeApiDeps,
13
+ } from "./runtime-api";
14
+
15
+ const CLAUDE_USAGE = `Usage:
16
+ ocx claude config [status] [--json]
17
+ ocx claude config set [--enabled <on|off>] [--auth-mode <auto|proxy|subscription>]
18
+ [--system-env <on|off>] [--fast-mode <on|off>] [--auto-context <on|off>]
19
+ [--compact-window <tokens|default>] [--inject-agents <on|off>]
20
+ [--small-fast-model <id|->] [--model-map <from=to,from=to|->]
21
+ [--blocked-skills <name,name|->] [--web-model <id|->] [--web-backend <openai|anthropic|xai|gemini|exa|->]
22
+ [--vision-model <id|->] [--vision-backend <openai|anthropic|->] [--json]`;
23
+
24
+ const GROK_USAGE = `Usage:
25
+ ocx grok [status] [--json]
26
+ ocx grok <exclude|include|set> <model,model...> [--json]
27
+ ocx grok clear [--json]
28
+ ocx grok apply [--json]`;
29
+
30
+ const CLIENT_USAGE = `Usage:
31
+ ocx integration client [status] [--client <id>] [--json]
32
+ ocx integration client <enable|disable> --client <id> [--json]
33
+ ocx integration client history [--client <id>] [--json]
34
+ ocx integration client restore --op <opId> [--confirm-drift] [--json]`;
35
+
36
+ function parseMap(raw: string): Record<string, string> {
37
+ if (raw === "-") return {};
38
+ const map: Record<string, string> = {};
39
+ for (const pair of raw.split(",")) {
40
+ const index = pair.indexOf("=");
41
+ if (index <= 0 || index === pair.length - 1) throw new CliUsageError(`invalid model map entry "${pair}"; use from=to`, CLAUDE_USAGE);
42
+ map[pair.slice(0, index).trim()] = pair.slice(index + 1).trim();
43
+ }
44
+ return map;
45
+ }
46
+
47
+ export async function handleClaudeConfigCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
48
+ return runCliAction(async () => {
49
+ const args = [...argv];
50
+ const action = (args.shift() ?? "status").toLowerCase();
51
+ const wantsJson = takeFlag(args, "--json");
52
+ if (action === "status" || action === "show") {
53
+ rejectArgs(args, CLAUDE_USAGE);
54
+ const result = await runtimeRequest("/api/claude-code", {}, deps);
55
+ printData(result, wantsJson, summaryLines(result));
56
+ return;
57
+ }
58
+ if (action !== "set") throw new CliUsageError(`unknown Claude config command ${action}`, CLAUDE_USAGE);
59
+ const body: Record<string, unknown> = {};
60
+ const enabled = takeBooleanOption(args, "--enabled");
61
+ const authMode = takeOption(args, "--auth-mode");
62
+ const systemEnv = takeBooleanOption(args, "--system-env");
63
+ const fastMode = takeBooleanOption(args, "--fast-mode");
64
+ const autoContext = takeBooleanOption(args, "--auto-context");
65
+ const compact = takeOption(args, "--compact-window");
66
+ const injectAgents = takeBooleanOption(args, "--inject-agents");
67
+ const smallFastModel = takeOption(args, "--small-fast-model");
68
+ const modelMap = takeOption(args, "--model-map");
69
+ const blockedSkills = takeOption(args, "--blocked-skills");
70
+ const webModel = takeOption(args, "--web-model");
71
+ const webBackend = takeOption(args, "--web-backend");
72
+ const visionModel = takeOption(args, "--vision-model");
73
+ const visionBackend = takeOption(args, "--vision-backend");
74
+ rejectArgs(args, CLAUDE_USAGE);
75
+ if (enabled !== undefined) body.enabled = enabled;
76
+ if (authMode !== undefined) body.authMode = authMode;
77
+ if (systemEnv !== undefined) body.systemEnv = systemEnv;
78
+ if (fastMode !== undefined) body.fastMode = fastMode;
79
+ if (autoContext !== undefined) body.autoContext = autoContext;
80
+ if (compact !== undefined) {
81
+ if (compact === "default" || compact === "-") body.autoCompactWindow = null;
82
+ else {
83
+ const value = Number(compact.replace(/[_,]/g, ""));
84
+ if (!Number.isInteger(value) || value <= 0) throw new CliUsageError("--compact-window must be a positive integer or default", CLAUDE_USAGE);
85
+ body.autoCompactWindow = value;
86
+ }
87
+ }
88
+ if (injectAgents !== undefined) body.injectAgents = injectAgents;
89
+ if (smallFastModel !== undefined) body.smallFastModel = smallFastModel === "-" ? "" : smallFastModel;
90
+ if (modelMap !== undefined) body.modelMap = parseMap(modelMap);
91
+ if (blockedSkills !== undefined) body.blockedSkills = blockedSkills === "-" ? null : csv(blockedSkills);
92
+ const sidecar = (model: string | undefined, backend: string | undefined): Record<string, unknown> | undefined => {
93
+ if (model === undefined && backend === undefined) return undefined;
94
+ const result: Record<string, unknown> = {};
95
+ if (model !== undefined) result.model = model === "-" ? "" : model;
96
+ if (backend !== undefined) result.backend = backend === "-" ? null : backend;
97
+ return result;
98
+ };
99
+ const web = sidecar(webModel, webBackend);
100
+ const vision = sidecar(visionModel, visionBackend);
101
+ if (web) body.webSearchSidecar = web;
102
+ if (vision) body.visionSidecar = vision;
103
+ if (Object.keys(body).length === 0) throw new CliUsageError("at least one Claude setting is required", CLAUDE_USAGE);
104
+ const result = await runtimeRequest("/api/claude-code", { method: "PUT", body: JSON.stringify(body) }, deps);
105
+ printData(result, wantsJson, ["Claude Code settings updated."]);
106
+ });
107
+ }
108
+
109
+ type GrokState = Record<string, unknown> & { excluded?: string[] };
110
+
111
+ export async function handleGrokCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
112
+ return runCliAction(async () => {
113
+ const args = [...argv];
114
+ const action = (args.shift() ?? "status").toLowerCase();
115
+ const wantsJson = takeFlag(args, "--json");
116
+ if (action === "status" || action === "show") {
117
+ rejectArgs(args, GROK_USAGE);
118
+ const result = await runtimeRequest("/api/grok", {}, deps);
119
+ printData(result, wantsJson, summaryLines(result));
120
+ return;
121
+ }
122
+ if (action === "apply") {
123
+ rejectArgs(args, GROK_USAGE);
124
+ const result = await runtimeRequest("/api/grok/apply", { method: "POST" }, deps);
125
+ printData(result, wantsJson, [String((result as Record<string, unknown>).message ?? "Grok configuration applied.")]);
126
+ return;
127
+ }
128
+ let excluded: string[];
129
+ if (action === "clear") excluded = [];
130
+ else if (["exclude", "include", "set"].includes(action)) {
131
+ const raw = args.shift();
132
+ if (!raw) throw new CliUsageError("comma-separated models are required", GROK_USAGE);
133
+ const requested = csv(raw) ?? [];
134
+ if (action === "set") excluded = requested;
135
+ else {
136
+ const state = await runtimeRequest<GrokState>("/api/grok", {}, deps);
137
+ const current = new Set(state.excluded ?? []);
138
+ for (const model of requested) action === "exclude" ? current.add(model) : current.delete(model);
139
+ excluded = [...current].sort();
140
+ }
141
+ } else throw new CliUsageError(`unknown Grok command ${action}`, GROK_USAGE);
142
+ rejectArgs(args, GROK_USAGE);
143
+ const result = await runtimeRequest("/api/grok/selection", { method: "PUT", body: JSON.stringify({ excluded }) }, deps);
144
+ printData(result, wantsJson, [`Grok exclusions: ${excluded.join(", ") || "none"}`]);
145
+ });
146
+ }
147
+
148
+ /**
149
+ * The headless half of the client-integration toggle.
150
+ *
151
+ * Every safety property lives behind the management API — ownership, the
152
+ * pre-write snapshot, the journal, the drift refusal — so this command is a
153
+ * thin caller and deliberately re-implements none of it. That is also why
154
+ * `restore` surfaces the drift refusal as an error telling the user to pass
155
+ * `--confirm-drift` rather than retrying on their behalf: replacing edits a
156
+ * user made after the snapshot is exactly the decision they have to make.
157
+ */
158
+ export async function handleClientIntegrationCommand(
159
+ argv: string[],
160
+ deps: RuntimeApiDeps = {},
161
+ ): Promise<number> {
162
+ return runCliAction(async () => {
163
+ const args = [...argv];
164
+ const action = (args.shift() ?? "status").toLowerCase();
165
+ const wantsJson = takeFlag(args, "--json");
166
+
167
+ if (action === "status" || action === "show" || action === "list") {
168
+ const client = takeOption(args, "--client");
169
+ rejectArgs(args, CLIENT_USAGE);
170
+ const path = client
171
+ ? `/api/client-integrations/${encodeURIComponent(client)}`
172
+ : "/api/client-integrations";
173
+ const result = await runtimeRequest(path, {}, deps);
174
+ const rows = (result as { clients?: Array<Record<string, unknown>> }).clients;
175
+ printData(result, wantsJson, rows
176
+ ? rows.map(row => `${String(row.clientId)}: ${String(row.state)}${row.installed ? "" : " (not installed)"}`)
177
+ : summaryLines(result));
178
+ return;
179
+ }
180
+
181
+ if (action === "history" || action === "journal") {
182
+ const client = takeOption(args, "--client");
183
+ rejectArgs(args, CLIENT_USAGE);
184
+ const query = client ? `?client=${encodeURIComponent(client)}` : "";
185
+ const result = await runtimeRequest(`/api/client-integrations/journal${query}`, {}, deps);
186
+ const operations = (result as { operations?: Array<Record<string, unknown>> }).operations ?? [];
187
+ printData(result, wantsJson, operations.length === 0
188
+ ? ["No integration operations recorded yet."]
189
+ : operations.map(row => {
190
+ // `snapshot` is resolved against the disk by the route, so "expired"
191
+ // here means the bytes are genuinely gone, not merely old.
192
+ const backup = row.snapshot === "expired" ? "backup expired" : `op ${String(row.opId)}`;
193
+ return `${String(row.at)} ${String(row.clientId)} ${String(row.kind)} (${backup})`;
194
+ }));
195
+ return;
196
+ }
197
+
198
+ if (action === "restore") {
199
+ const opId = takeOption(args, "--op") ?? takeOption(args, "--op-id");
200
+ const confirmDrift = takeFlag(args, "--confirm-drift");
201
+ rejectArgs(args, CLIENT_USAGE);
202
+ if (!opId) throw new CliUsageError("--op <opId> is required", CLIENT_USAGE);
203
+ const result = await runtimeRequest("/api/client-integrations/restore", {
204
+ method: "POST",
205
+ body: JSON.stringify({ opId, confirmDrift }),
206
+ }, deps);
207
+ printData(result, wantsJson, [String((result as Record<string, unknown>).message ?? "Restored.")]);
208
+ return;
209
+ }
210
+
211
+ if (action !== "enable" && action !== "disable") {
212
+ throw new CliUsageError(`unknown client integration command ${action}`, CLIENT_USAGE);
213
+ }
214
+ const client = takeOption(args, "--client");
215
+ rejectArgs(args, CLIENT_USAGE);
216
+ if (!client) throw new CliUsageError("--client <id> is required", CLIENT_USAGE);
217
+ const result = await runtimeRequest(`/api/client-integrations/${encodeURIComponent(client)}`, {
218
+ method: "PUT",
219
+ body: JSON.stringify({ enabled: action === "enable" }),
220
+ }, deps);
221
+ printData(result, wantsJson, [String((result as Record<string, unknown>).message ?? `${client} ${action}d.`)]);
222
+ });
223
+ }
224
+
225
+ export const INTEGRATION_USAGE = { claude: CLAUDE_USAGE, grok: GROK_USAGE, client: CLIENT_USAGE };
226
+
227
+ const ZCODE_USAGE = `Usage:
228
+ ocx zcode [status] [--json]
229
+ ocx zcode <enable|disable> [--json]
230
+ ocx zcode history [--json]
231
+ ocx zcode restore --op <opId> [--confirm-drift] [--json]`;
232
+
233
+ /**
234
+ * Thin alias over the client-integration surface for ZCode (Z.ai's desktop
235
+ * client). ZCode is a GUI app with no launch surface to wrap, so unlike
236
+ * `ocx mcode` there is no exec step: connecting the managed provider block is
237
+ * the whole integration, and every safety property (ownership, snapshots,
238
+ * journal, drift refusal) stays behind the shared management API. ZCode reads
239
+ * its config at startup, so enable/disable print a restart reminder.
240
+ */
241
+ export async function handleZcodeCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
242
+ const args = [...argv];
243
+ // Find the first non-flag token so `ocx zcode --json enable` still enables.
244
+ const verbIndex = args.findIndex(arg => !arg.startsWith("-"));
245
+ const action = (verbIndex === -1 ? "status" : args[verbIndex]).toLowerCase();
246
+ const known = ["status", "show", "list", "enable", "disable", "history", "journal", "restore"];
247
+ if (!known.includes(action)) {
248
+ console.error(`unknown zcode command ${action}`);
249
+ console.error(ZCODE_USAGE);
250
+ return 2;
251
+ }
252
+ const rest = verbIndex === -1 ? args : [...args.slice(0, verbIndex), ...args.slice(verbIndex + 1)];
253
+ // `restore` addresses an operation id, not a client, so nothing is injected.
254
+ const forwarded = action === "restore" ? [action, ...rest] : [action, ...rest, "--client", "zcode"];
255
+ const code = await handleClientIntegrationCommand(forwarded, deps);
256
+ if (code === 0 && (action === "enable" || action === "disable")) {
257
+ console.error("Restart ZCode to pick up the provider change.");
258
+ }
259
+ return code;
260
+ }
@@ -0,0 +1,133 @@
1
+ import { createInterface } from "node:readline/promises";
2
+
3
+ /**
4
+ * Inline yes/no selector for interactive CLI prompts.
5
+ *
6
+ * Both choices are drawn on one line: the user moves between them with the
7
+ * arrow keys (or Tab), confirms with Enter, or answers straight away with
8
+ * `y`/`n`. Escape and Ctrl-C resolve to "no", so backing out never counts as
9
+ * consent.
10
+ *
11
+ * The highlighted choice is caller-supplied and is what a bare Enter returns.
12
+ * Whatever the default, the selector always shows which side is highlighted, so
13
+ * Enter never does something the screen did not already say it would.
14
+ */
15
+
16
+ export interface InteractiveConfirmOptions {
17
+ /** Question text rendered before the choices. May contain ANSI styling. */
18
+ question: string;
19
+ /** Which choice starts highlighted, and therefore what a bare Enter returns. */
20
+ defaultYes: boolean;
21
+ /** Key hint shown after the choices. */
22
+ hint?: string;
23
+ /** Overridable for tests; defaults to the process streams. */
24
+ input?: NodeJS.ReadStream;
25
+ output?: NodeJS.WriteStream;
26
+ }
27
+
28
+ // The highlight sets an explicit black-on-white pair rather than bare reverse
29
+ // video (\x1b[7m). Reverse alone inherits whatever foreground colour is in
30
+ // effect, so on some themes the selected label rendered as black text on a black
31
+ // block and the choice became invisible.
32
+ const REVERSE = "\x1b[30;47m";
33
+ const DIM = "\x1b[2m";
34
+ const RESET = "\x1b[0m";
35
+ const CLEAR_LINE = "\r\x1b[K";
36
+
37
+ const KEY_ENTER = new Set(["\r", "\n"]);
38
+ const KEY_YES_SIDE = new Set(["\x1b[D", "\x1b[A", "\x1bOD", "\x1bOA"]); // left / up
39
+ const KEY_NO_SIDE = new Set(["\x1b[C", "\x1b[B", "\x1bOC", "\x1bOB"]); // right / down
40
+ const KEY_ESCAPE = "\x1b";
41
+ const KEY_INTERRUPT = "\x03";
42
+ const KEY_TAB = "\t";
43
+
44
+ function renderChoices(question: string, yes: boolean, hint: string): string {
45
+ const yesLabel = yes ? `${REVERSE} Yes ${RESET}` : `${DIM} Yes ${RESET}`;
46
+ const noLabel = yes ? `${DIM} No ${RESET}` : `${REVERSE} No ${RESET}`;
47
+ return `${CLEAR_LINE}${question} ${yesLabel} ${noLabel} ${DIM}${hint}${RESET}`;
48
+ }
49
+
50
+ function renderAnswer(question: string, yes: boolean): string {
51
+ return `${CLEAR_LINE}${question} ${yes ? "Yes" : "No"}\n`;
52
+ }
53
+
54
+ /** Fallback for terminals without raw mode: a plain typed answer. */
55
+ async function readlineConfirm(
56
+ options: InteractiveConfirmOptions,
57
+ input: NodeJS.ReadStream,
58
+ output: NodeJS.WriteStream,
59
+ ): Promise<boolean> {
60
+ const suffix = options.defaultYes ? "[Y/n]" : "[y/N]";
61
+ const rl = createInterface({ input, output });
62
+ try {
63
+ const answer = (await rl.question(`${options.question} ${suffix} `)).trim().toLowerCase();
64
+ if (answer === "") return options.defaultYes;
65
+ return answer === "y" || answer === "yes";
66
+ } finally {
67
+ rl.close();
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Ask a yes/no question with an inline arrow-key selector. Resolves to the
73
+ * user's choice; never throws for input handling and always restores the
74
+ * terminal mode it changed.
75
+ */
76
+ export async function interactiveConfirm(options: InteractiveConfirmOptions): Promise<boolean> {
77
+ const input = options.input ?? process.stdin;
78
+ const output = options.output ?? process.stdout;
79
+ const hint = options.hint ?? "←/→ move · y/n · enter";
80
+
81
+ // Raw mode is what makes single-keypress navigation possible. Without it
82
+ // (pipes, some CI shells, Windows consoles without a TTY) fall back to a
83
+ // typed answer rather than silently swallowing the question.
84
+ if (typeof input.setRawMode !== "function") {
85
+ return await readlineConfirm(options, input, output);
86
+ }
87
+
88
+ return await new Promise<boolean>(resolve => {
89
+ let yes = options.defaultYes;
90
+ const wasRaw = input.isRaw === true;
91
+ const hadOtherReaders = input.listenerCount("data") > 0;
92
+
93
+ const paint = () => {
94
+ output.write(renderChoices(options.question, yes, hint));
95
+ };
96
+
97
+ const finish = (answer: boolean, interrupted: boolean) => {
98
+ input.off("data", onData);
99
+ if (!wasRaw) input.setRawMode(false);
100
+ if (!hadOtherReaders) input.pause();
101
+ output.write(renderAnswer(options.question, answer));
102
+ resolve(answer);
103
+ // A Ctrl-C during the prompt is still a Ctrl-C: hand it back to the
104
+ // process so the normal shutdown path runs instead of being eaten here.
105
+ if (interrupted) process.kill(process.pid, "SIGINT");
106
+ };
107
+
108
+ const onData = (chunk: Buffer | string) => {
109
+ const key = typeof chunk === "string" ? chunk : chunk.toString("utf8");
110
+ if (key === KEY_INTERRUPT) return finish(false, true);
111
+ if (key === KEY_ESCAPE) return finish(false, false);
112
+ if (KEY_ENTER.has(key)) return finish(yes, false);
113
+ const lower = key.toLowerCase();
114
+ if (lower === "y") return finish(true, false);
115
+ if (lower === "n") return finish(false, false);
116
+ if (KEY_YES_SIDE.has(key)) {
117
+ yes = true;
118
+ paint();
119
+ return;
120
+ }
121
+ if (KEY_NO_SIDE.has(key) || key === KEY_TAB) {
122
+ yes = key === KEY_TAB ? !yes : false;
123
+ paint();
124
+ return;
125
+ }
126
+ };
127
+
128
+ input.setRawMode(true);
129
+ input.resume();
130
+ input.on("data", onData);
131
+ paint();
132
+ });
133
+ }