@iislee/opencodex 2.11.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 (476) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -0
  3. package/assets/architecture.png +0 -0
  4. package/assets/banner.png +0 -0
  5. package/assets/claude-code-models.gif +0 -0
  6. package/assets/codex-app-picker.png +0 -0
  7. package/bin/ocx.mjs +451 -0
  8. package/bin/package-main.mjs +9 -0
  9. package/gui/dist/assets/index-DTpMHS4F.js +67 -0
  10. package/gui/dist/assets/index-ZNVDE3C7.css +1 -0
  11. package/gui/dist/favicon.png +0 -0
  12. package/gui/dist/icons.svg +24 -0
  13. package/gui/dist/index.html +25 -0
  14. package/gui/dist/logo.png +0 -0
  15. package/gui/dist/provider-icons/alibaba-color.svg +1 -0
  16. package/gui/dist/provider-icons/antigravity-color.svg +1 -0
  17. package/gui/dist/provider-icons/antigravity.svg +1 -0
  18. package/gui/dist/provider-icons/claude-color.svg +1 -0
  19. package/gui/dist/provider-icons/claude.svg +1 -0
  20. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
  21. package/gui/dist/provider-icons/copilot-color.svg +1 -0
  22. package/gui/dist/provider-icons/copilot.svg +1 -0
  23. package/gui/dist/provider-icons/cursor-color.svg +2 -0
  24. package/gui/dist/provider-icons/cursor.svg +2 -0
  25. package/gui/dist/provider-icons/deepseek-color.svg +1 -0
  26. package/gui/dist/provider-icons/discord.svg +1 -0
  27. package/gui/dist/provider-icons/firepass-color.svg +1 -0
  28. package/gui/dist/provider-icons/fireworks-color.svg +1 -0
  29. package/gui/dist/provider-icons/gemini-color.svg +1 -0
  30. package/gui/dist/provider-icons/gemini.svg +1 -0
  31. package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
  32. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
  33. package/gui/dist/provider-icons/grok-color.svg +1 -0
  34. package/gui/dist/provider-icons/grok.svg +1 -0
  35. package/gui/dist/provider-icons/groq-color.svg +1 -0
  36. package/gui/dist/provider-icons/huggingface-color.svg +1 -0
  37. package/gui/dist/provider-icons/kimi-color.svg +1 -0
  38. package/gui/dist/provider-icons/kiro-color.svg +15 -0
  39. package/gui/dist/provider-icons/kiro.svg +14 -0
  40. package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
  41. package/gui/dist/provider-icons/mistral-color.svg +1 -0
  42. package/gui/dist/provider-icons/moonshot-color.svg +1 -0
  43. package/gui/dist/provider-icons/nvidia-color.svg +1 -0
  44. package/gui/dist/provider-icons/ollama-color.svg +1 -0
  45. package/gui/dist/provider-icons/openai.svg +1 -0
  46. package/gui/dist/provider-icons/opencode.svg +1 -0
  47. package/gui/dist/provider-icons/openrouter-color.svg +1 -0
  48. package/gui/dist/provider-icons/pi.svg +21 -0
  49. package/gui/dist/provider-icons/qianfan-color.svg +1 -0
  50. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
  51. package/gui/dist/provider-icons/telegram.svg +1 -0
  52. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
  53. package/gui/dist/provider-icons/vllm-color.svg +1 -0
  54. package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
  55. package/package.json +102 -0
  56. package/src/AGENTS.md +28 -0
  57. package/src/adapters/anthropic-image-guard.ts +251 -0
  58. package/src/adapters/anthropic-image-normalize.ts +518 -0
  59. package/src/adapters/anthropic.ts +1003 -0
  60. package/src/adapters/azure.ts +36 -0
  61. package/src/adapters/base.ts +72 -0
  62. package/src/adapters/client-fingerprint.ts +59 -0
  63. package/src/adapters/cursor/arg-codec.ts +38 -0
  64. package/src/adapters/cursor/arg-normalize.ts +104 -0
  65. package/src/adapters/cursor/cursor-errors.ts +165 -0
  66. package/src/adapters/cursor/discovery.ts +276 -0
  67. package/src/adapters/cursor/effort-map.ts +127 -0
  68. package/src/adapters/cursor/exec-policy.ts +88 -0
  69. package/src/adapters/cursor/framing.ts +211 -0
  70. package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
  71. package/src/adapters/cursor/kv-store.ts +52 -0
  72. package/src/adapters/cursor/live-models.ts +153 -0
  73. package/src/adapters/cursor/live-smoke-gate.ts +41 -0
  74. package/src/adapters/cursor/live-transport.ts +1214 -0
  75. package/src/adapters/cursor/mcp-config.ts +42 -0
  76. package/src/adapters/cursor/mcp-manager.ts +333 -0
  77. package/src/adapters/cursor/message-mapper.ts +49 -0
  78. package/src/adapters/cursor/native-exec-common.ts +55 -0
  79. package/src/adapters/cursor/native-exec-desktop.ts +184 -0
  80. package/src/adapters/cursor/native-exec-fs.ts +329 -0
  81. package/src/adapters/cursor/native-exec-mcp.ts +153 -0
  82. package/src/adapters/cursor/native-exec-network.ts +43 -0
  83. package/src/adapters/cursor/native-exec-shell.ts +548 -0
  84. package/src/adapters/cursor/native-exec-tools.ts +118 -0
  85. package/src/adapters/cursor/native-exec.ts +576 -0
  86. package/src/adapters/cursor/protobuf-events.ts +563 -0
  87. package/src/adapters/cursor/protobuf-request.ts +714 -0
  88. package/src/adapters/cursor/request-builder.ts +255 -0
  89. package/src/adapters/cursor/thread-continuity.ts +67 -0
  90. package/src/adapters/cursor/tool-definitions.ts +505 -0
  91. package/src/adapters/cursor/transport-retry.ts +132 -0
  92. package/src/adapters/cursor/transport.ts +57 -0
  93. package/src/adapters/cursor/types.ts +52 -0
  94. package/src/adapters/cursor.ts +196 -0
  95. package/src/adapters/google-antigravity-replay.ts +303 -0
  96. package/src/adapters/google-antigravity-wire.ts +108 -0
  97. package/src/adapters/google-errors.ts +85 -0
  98. package/src/adapters/google-http.ts +100 -0
  99. package/src/adapters/google-tool-schema.ts +173 -0
  100. package/src/adapters/google-truncation.ts +13 -0
  101. package/src/adapters/google-wire-compiler.ts +232 -0
  102. package/src/adapters/google.ts +758 -0
  103. package/src/adapters/identity.ts +44 -0
  104. package/src/adapters/image.ts +23 -0
  105. package/src/adapters/kiro-constants.ts +16 -0
  106. package/src/adapters/kiro-errors.ts +197 -0
  107. package/src/adapters/kiro-events.ts +179 -0
  108. package/src/adapters/kiro-images.ts +129 -0
  109. package/src/adapters/kiro-retry.ts +312 -0
  110. package/src/adapters/kiro-thinking.ts +96 -0
  111. package/src/adapters/kiro-tool-fallback.ts +36 -0
  112. package/src/adapters/kiro-tools.ts +215 -0
  113. package/src/adapters/kiro-truncation.ts +33 -0
  114. package/src/adapters/kiro-wire.ts +129 -0
  115. package/src/adapters/kiro.ts +1898 -0
  116. package/src/adapters/mimo-free.ts +263 -0
  117. package/src/adapters/openai-chat.ts +1005 -0
  118. package/src/adapters/openai-responses.ts +1137 -0
  119. package/src/adapters/run-turn-queue.ts +114 -0
  120. package/src/adapters/tool-catalog-nudge.ts +71 -0
  121. package/src/adapters/upstream-http-error.ts +48 -0
  122. package/src/bridge.ts +1619 -0
  123. package/src/chat/inbound.ts +295 -0
  124. package/src/chat/outbound.ts +765 -0
  125. package/src/claude/agents-inject.ts +243 -0
  126. package/src/claude/alias.ts +149 -0
  127. package/src/claude/auth-detect.ts +229 -0
  128. package/src/claude/auth-mode-migration.ts +32 -0
  129. package/src/claude/auth-mode.ts +62 -0
  130. package/src/claude/context-windows.ts +189 -0
  131. package/src/claude/desktop-3p-guard.ts +35 -0
  132. package/src/claude/desktop-3p-paths.ts +84 -0
  133. package/src/claude/desktop-3p.ts +381 -0
  134. package/src/claude/desktop-health.ts +26 -0
  135. package/src/claude/desktop-profile.ts +263 -0
  136. package/src/claude/gateway-cache.ts +70 -0
  137. package/src/claude/inbound-debug.ts +163 -0
  138. package/src/claude/inbound.ts +509 -0
  139. package/src/claude/model-info.ts +151 -0
  140. package/src/claude/outbound.ts +872 -0
  141. package/src/cli/access.ts +108 -0
  142. package/src/cli/account-api.ts +268 -0
  143. package/src/cli/account-auth.ts +223 -0
  144. package/src/cli/account-extended.ts +350 -0
  145. package/src/cli/account.ts +275 -0
  146. package/src/cli/agent-driven.ts +70 -0
  147. package/src/cli/agent.ts +184 -0
  148. package/src/cli/catalog-prewarm.ts +27 -0
  149. package/src/cli/claude-desktop.ts +188 -0
  150. package/src/cli/claude.ts +286 -0
  151. package/src/cli/codex-shim-autorestore.ts +45 -0
  152. package/src/cli/combo.ts +119 -0
  153. package/src/cli/config-command.ts +145 -0
  154. package/src/cli/debug.ts +228 -0
  155. package/src/cli/doctor.ts +930 -0
  156. package/src/cli/export-command.ts +187 -0
  157. package/src/cli/help.ts +354 -0
  158. package/src/cli/index.ts +1113 -0
  159. package/src/cli/init.ts +224 -0
  160. package/src/cli/integrations.ts +142 -0
  161. package/src/cli/interactive-confirm.ts +133 -0
  162. package/src/cli/internal-dispatch.ts +20 -0
  163. package/src/cli/models-runtime.ts +212 -0
  164. package/src/cli/models.ts +336 -0
  165. package/src/cli/observe.ts +117 -0
  166. package/src/cli/opencode.ts +586 -0
  167. package/src/cli/pi.ts +188 -0
  168. package/src/cli/provider-runtime.ts +162 -0
  169. package/src/cli/provider.ts +463 -0
  170. package/src/cli/runtime-api.ts +325 -0
  171. package/src/cli/star-prompt.ts +155 -0
  172. package/src/cli/status-oauth.ts +78 -0
  173. package/src/cli/status.ts +321 -0
  174. package/src/cli/sync-cloud.ts +283 -0
  175. package/src/cli/system-command.ts +112 -0
  176. package/src/cli/tray-proxy.ts +52 -0
  177. package/src/cli/v2.ts +173 -0
  178. package/src/cli.ts +10 -0
  179. package/src/clients/config-export.ts +377 -0
  180. package/src/clients/effective-status.ts +385 -0
  181. package/src/clients/probes/agy.ts +55 -0
  182. package/src/clients/probes/cc-switch.ts +110 -0
  183. package/src/clients/probes/claude.ts +90 -0
  184. package/src/clients/probes/codex.ts +125 -0
  185. package/src/clients/probes/grok.ts +29 -0
  186. package/src/clients/probes/opencode.ts +109 -0
  187. package/src/clients/probes/paseo.ts +55 -0
  188. package/src/clients/probes/pi.ts +55 -0
  189. package/src/cloud/onedrive-auth.ts +666 -0
  190. package/src/cloud/onedrive-graph.ts +108 -0
  191. package/src/cloud/settings.ts +75 -0
  192. package/src/cloud/sync.ts +212 -0
  193. package/src/cloud/types.ts +56 -0
  194. package/src/cloud/vault.ts +89 -0
  195. package/src/codex/account-id.ts +34 -0
  196. package/src/codex/account-label.ts +34 -0
  197. package/src/codex/account-lifecycle.ts +55 -0
  198. package/src/codex/account-namespace-match.ts +63 -0
  199. package/src/codex/account-namespaces.ts +149 -0
  200. package/src/codex/account-pause.ts +20 -0
  201. package/src/codex/account-runtime-state.ts +31 -0
  202. package/src/codex/account-store.ts +517 -0
  203. package/src/codex/account-usability.ts +20 -0
  204. package/src/codex/app-server-processes.ts +756 -0
  205. package/src/codex/auth-api.ts +1540 -0
  206. package/src/codex/auth-collision.ts +107 -0
  207. package/src/codex/auth-context.ts +352 -0
  208. package/src/codex/autostart-health.ts +149 -0
  209. package/src/codex/catalog/aggregation.ts +378 -0
  210. package/src/codex/catalog/bundled.ts +251 -0
  211. package/src/codex/catalog/effort.ts +355 -0
  212. package/src/codex/catalog/metadata.ts +180 -0
  213. package/src/codex/catalog/parsing.ts +456 -0
  214. package/src/codex/catalog/provider-fetch.ts +902 -0
  215. package/src/codex/catalog/sync.ts +620 -0
  216. package/src/codex/catalog.ts +12 -0
  217. package/src/codex/data/upstream-models.json +830 -0
  218. package/src/codex/exec-invocation.ts +22 -0
  219. package/src/codex/features.ts +969 -0
  220. package/src/codex/history-migration-guardian.ts +102 -0
  221. package/src/codex/history-provider.ts +776 -0
  222. package/src/codex/home.ts +206 -0
  223. package/src/codex/inject.ts +799 -0
  224. package/src/codex/injected-marker.ts +72 -0
  225. package/src/codex/journal.ts +163 -0
  226. package/src/codex/main-account-cache.ts +32 -0
  227. package/src/codex/main-account.ts +40 -0
  228. package/src/codex/model-cache.ts +227 -0
  229. package/src/codex/paths.ts +65 -0
  230. package/src/codex/plugins-doctor.ts +242 -0
  231. package/src/codex/pool-rotation.ts +225 -0
  232. package/src/codex/project-config-warnings.ts +411 -0
  233. package/src/codex/quota.ts +411 -0
  234. package/src/codex/refresh.ts +53 -0
  235. package/src/codex/routing.ts +1477 -0
  236. package/src/codex/runtime.ts +538 -0
  237. package/src/codex/shim.ts +1189 -0
  238. package/src/codex/subagent-defaults.ts +550 -0
  239. package/src/codex/subagent-model-fallback.ts +469 -0
  240. package/src/codex/sync.ts +130 -0
  241. package/src/codex/warmup.ts +192 -0
  242. package/src/codex/websocket-registry.ts +100 -0
  243. package/src/combos/failover.ts +140 -0
  244. package/src/combos/index.ts +41 -0
  245. package/src/combos/request.ts +62 -0
  246. package/src/combos/resolve.ts +232 -0
  247. package/src/combos/types.ts +326 -0
  248. package/src/config.ts +2356 -0
  249. package/src/generated/jawcode-model-metadata.ts +104 -0
  250. package/src/github/star-state.ts +203 -0
  251. package/src/grok/inject.ts +545 -0
  252. package/src/grok/status.ts +121 -0
  253. package/src/grok/sync.ts +103 -0
  254. package/src/grok/usage-hook/report.mjs +348 -0
  255. package/src/grok/usage-hook.ts +278 -0
  256. package/src/images/artifacts.ts +516 -0
  257. package/src/images/fulfill-video.ts +163 -0
  258. package/src/images/fulfill.ts +149 -0
  259. package/src/images/index.ts +4 -0
  260. package/src/images/loop.ts +829 -0
  261. package/src/images/plan.ts +133 -0
  262. package/src/images/synthetic-tool.ts +133 -0
  263. package/src/images/types.ts +41 -0
  264. package/src/images/xai-client.ts +141 -0
  265. package/src/images/xai-video-client.ts +163 -0
  266. package/src/index.ts +22 -0
  267. package/src/lib/abort.ts +146 -0
  268. package/src/lib/admin-secrets.ts +25 -0
  269. package/src/lib/admission.ts +83 -0
  270. package/src/lib/app-owned-memory-stores.ts +173 -0
  271. package/src/lib/app-owned-memory.ts +265 -0
  272. package/src/lib/bounded-body.ts +202 -0
  273. package/src/lib/bun-binary-validator.d.mts +3 -0
  274. package/src/lib/bun-binary-validator.mjs +18 -0
  275. package/src/lib/bun-runtime.ts +71 -0
  276. package/src/lib/bun-stream-caps.ts +126 -0
  277. package/src/lib/config-ownership.ts +360 -0
  278. package/src/lib/crash-guard.ts +344 -0
  279. package/src/lib/debug-log-buffer.ts +83 -0
  280. package/src/lib/debug-settings.ts +108 -0
  281. package/src/lib/debug.ts +31 -0
  282. package/src/lib/destination-policy.ts +316 -0
  283. package/src/lib/errors.ts +364 -0
  284. package/src/lib/eventstream-decoder.ts +253 -0
  285. package/src/lib/gcp-adc.ts +341 -0
  286. package/src/lib/injection-debug-log.ts +58 -0
  287. package/src/lib/open-url.ts +25 -0
  288. package/src/lib/pinned-http.ts +151 -0
  289. package/src/lib/privacy.ts +20 -0
  290. package/src/lib/process-control.ts +165 -0
  291. package/src/lib/provider-outbound.ts +170 -0
  292. package/src/lib/provider-url.ts +14 -0
  293. package/src/lib/proxy-env.ts +18 -0
  294. package/src/lib/redact.ts +105 -0
  295. package/src/lib/retry-after.ts +55 -0
  296. package/src/lib/service-secrets.ts +25 -0
  297. package/src/lib/shadow-call.ts +30 -0
  298. package/src/lib/sidecar-tracker.ts +52 -0
  299. package/src/lib/sse-decoder.ts +323 -0
  300. package/src/lib/state-store-registrations.ts +109 -0
  301. package/src/lib/state-store-sweeper.ts +184 -0
  302. package/src/lib/test-home-guard.ts +90 -0
  303. package/src/lib/token-estimate.ts +69 -0
  304. package/src/lib/translator-budget.ts +356 -0
  305. package/src/lib/upstream-retry.ts +239 -0
  306. package/src/lib/win-exec.ts +115 -0
  307. package/src/lib/win-paths.ts +68 -0
  308. package/src/lib/windows-elevation.ts +705 -0
  309. package/src/lib/windows-secret-acl.ts +514 -0
  310. package/src/lib/winsw.ts +375 -0
  311. package/src/oauth/anthropic-routing.ts +594 -0
  312. package/src/oauth/anthropic.ts +177 -0
  313. package/src/oauth/callback-server.ts +294 -0
  314. package/src/oauth/chatgpt.ts +150 -0
  315. package/src/oauth/cursor.ts +211 -0
  316. package/src/oauth/github-copilot.ts +428 -0
  317. package/src/oauth/google-antigravity.ts +230 -0
  318. package/src/oauth/health.ts +399 -0
  319. package/src/oauth/index.ts +1174 -0
  320. package/src/oauth/key-providers.ts +108 -0
  321. package/src/oauth/kimi.ts +213 -0
  322. package/src/oauth/kiro-credentials.ts +726 -0
  323. package/src/oauth/kiro.ts +577 -0
  324. package/src/oauth/local-token-detect.ts +121 -0
  325. package/src/oauth/log.ts +48 -0
  326. package/src/oauth/login-cli.ts +163 -0
  327. package/src/oauth/pkce.ts +15 -0
  328. package/src/oauth/store.ts +630 -0
  329. package/src/oauth/token-guardian.ts +303 -0
  330. package/src/oauth/types.ts +62 -0
  331. package/src/oauth/xai.ts +241 -0
  332. package/src/pi/extensions.ts +72 -0
  333. package/src/pi/home.ts +42 -0
  334. package/src/pi/index.ts +40 -0
  335. package/src/pi/models.ts +278 -0
  336. package/src/pi/packages.ts +219 -0
  337. package/src/pi/settings.ts +365 -0
  338. package/src/pi/status.ts +68 -0
  339. package/src/pi/sync.ts +75 -0
  340. package/src/providers/alibaba-region-backup.ts +75 -0
  341. package/src/providers/alibaba-region-migration.ts +156 -0
  342. package/src/providers/alibaba-region-startup.ts +36 -0
  343. package/src/providers/antigravity-models.ts +205 -0
  344. package/src/providers/api-keys.ts +140 -0
  345. package/src/providers/base-url-choices.ts +64 -0
  346. package/src/providers/context-cap.ts +65 -0
  347. package/src/providers/derive.ts +339 -0
  348. package/src/providers/free-directory.ts +184 -0
  349. package/src/providers/github-copilot-transport.ts +56 -0
  350. package/src/providers/key-failover.ts +203 -0
  351. package/src/providers/kiro-models.ts +67 -0
  352. package/src/providers/label.ts +19 -0
  353. package/src/providers/model-discovery.ts +356 -0
  354. package/src/providers/openai-sidecar.ts +175 -0
  355. package/src/providers/openai-tier-startup.ts +27 -0
  356. package/src/providers/openai-tiers.ts +301 -0
  357. package/src/providers/openai-virtual-models.ts +82 -0
  358. package/src/providers/openrouter-routing.ts +102 -0
  359. package/src/providers/provider-id-rewrite.ts +150 -0
  360. package/src/providers/quota.ts +1260 -0
  361. package/src/providers/registry.ts +1600 -0
  362. package/src/providers/slug-codec.ts +67 -0
  363. package/src/providers/xai-transport.ts +141 -0
  364. package/src/reasoning-effort.ts +135 -0
  365. package/src/responses/compaction.ts +117 -0
  366. package/src/responses/parser.ts +656 -0
  367. package/src/responses/reasoning-envelope.ts +52 -0
  368. package/src/responses/schema.ts +159 -0
  369. package/src/responses/spill-store.ts +394 -0
  370. package/src/responses/state.ts +895 -0
  371. package/src/responses/tool-groups.ts +19 -0
  372. package/src/router.ts +425 -0
  373. package/src/server/adapter-resolve.ts +80 -0
  374. package/src/server/auth-cors.ts +530 -0
  375. package/src/server/chat-completions.ts +368 -0
  376. package/src/server/claude-messages.ts +914 -0
  377. package/src/server/effort-policy.ts +172 -0
  378. package/src/server/gui-static.ts +123 -0
  379. package/src/server/image-retry.ts +42 -0
  380. package/src/server/images.ts +476 -0
  381. package/src/server/index.ts +1126 -0
  382. package/src/server/lifecycle.ts +227 -0
  383. package/src/server/live.ts +598 -0
  384. package/src/server/management/agent-settings-routes.ts +1169 -0
  385. package/src/server/management/api-access.ts +141 -0
  386. package/src/server/management/api-key-usage.ts +167 -0
  387. package/src/server/management/body.ts +35 -0
  388. package/src/server/management/clients-routes.ts +63 -0
  389. package/src/server/management/cloud-sync-routes.ts +266 -0
  390. package/src/server/management/combo-routes.ts +220 -0
  391. package/src/server/management/config-routes.ts +422 -0
  392. package/src/server/management/context.ts +31 -0
  393. package/src/server/management/logs-usage-routes.ts +707 -0
  394. package/src/server/management/model-routes.ts +525 -0
  395. package/src/server/management/oauth-account-routes.ts +563 -0
  396. package/src/server/management/provider-routes.ts +556 -0
  397. package/src/server/management/shared.ts +277 -0
  398. package/src/server/management/sidebar-routes.ts +90 -0
  399. package/src/server/management/system-restart.ts +179 -0
  400. package/src/server/management/system-routes.ts +117 -0
  401. package/src/server/management/usage-summary-cache.ts +86 -0
  402. package/src/server/management-api.ts +215 -0
  403. package/src/server/management-auth.ts +267 -0
  404. package/src/server/memory-watchdog.ts +156 -0
  405. package/src/server/port-reclaim.ts +307 -0
  406. package/src/server/ports.ts +116 -0
  407. package/src/server/proxy-liveness.ts +201 -0
  408. package/src/server/relay-eager.ts +313 -0
  409. package/src/server/relay.ts +1049 -0
  410. package/src/server/request-decompress.ts +132 -0
  411. package/src/server/request-log-conversation.ts +168 -0
  412. package/src/server/request-log.ts +1046 -0
  413. package/src/server/responses/collaboration.ts +354 -0
  414. package/src/server/responses/compact.ts +384 -0
  415. package/src/server/responses/core.ts +2758 -0
  416. package/src/server/responses/encrypted-payload.ts +308 -0
  417. package/src/server/responses/fetch-helpers.ts +157 -0
  418. package/src/server/responses/passthrough-error.ts +78 -0
  419. package/src/server/responses/terminal-guard.ts +230 -0
  420. package/src/server/responses/upstream-error.ts +48 -0
  421. package/src/server/responses-image-gen-repair.ts +132 -0
  422. package/src/server/responses-item-id-repair.ts +224 -0
  423. package/src/server/responses.ts +9 -0
  424. package/src/server/search.ts +136 -0
  425. package/src/server/sse-payload-rewrite.ts +175 -0
  426. package/src/server/startup-action-control.ts +308 -0
  427. package/src/server/startup-health-cache.ts +113 -0
  428. package/src/server/system-env.ts +413 -0
  429. package/src/server/windows-tcp-drop.ts +184 -0
  430. package/src/server/windows-tray-control.ts +41 -0
  431. package/src/server/ws-bridge.ts +471 -0
  432. package/src/service.ts +2554 -0
  433. package/src/stall-timeout.ts +20 -0
  434. package/src/storage/cleanup-job.ts +57 -0
  435. package/src/storage/cleanup.ts +3085 -0
  436. package/src/storage/policy-job.ts +457 -0
  437. package/src/storage/policy-scheduler.ts +40 -0
  438. package/src/storage/policy-worker.ts +59 -0
  439. package/src/storage/policy.ts +527 -0
  440. package/src/storage/restore-job.ts +299 -0
  441. package/src/storage/restore-worker.ts +58 -0
  442. package/src/storage/scanner.ts +238 -0
  443. package/src/storage/storage-mutation-coordinator.ts +139 -0
  444. package/src/storage/worker-lifecycle.ts +215 -0
  445. package/src/tray/assets/opencodex-tray-offline.ico +0 -0
  446. package/src/tray/assets/opencodex-tray-online.ico +0 -0
  447. package/src/tray/assets/opencodex-tray-warning.ico +0 -0
  448. package/src/tray/assets/opencodex-tray.png +0 -0
  449. package/src/tray/windows-tray.ps1 +290 -0
  450. package/src/tray/windows.ts +730 -0
  451. package/src/types.ts +1237 -0
  452. package/src/update/badge.ts +72 -0
  453. package/src/update/index.ts +407 -0
  454. package/src/update/job.ts +1520 -0
  455. package/src/update/notify.ts +257 -0
  456. package/src/update/npm-invocation.d.mts +23 -0
  457. package/src/update/npm-invocation.mjs +94 -0
  458. package/src/update/tray-update-plan.d.mts +18 -0
  459. package/src/update/tray-update-plan.mjs +38 -0
  460. package/src/usage/cost.ts +0 -0
  461. package/src/usage/debug.ts +97 -0
  462. package/src/usage/expected-prices.ts +164 -0
  463. package/src/usage/log.ts +658 -0
  464. package/src/usage/summary.ts +585 -0
  465. package/src/usage/totals.ts +14 -0
  466. package/src/vision/anthropic-describe.ts +185 -0
  467. package/src/vision/describe.ts +125 -0
  468. package/src/vision/index.ts +467 -0
  469. package/src/web-search/anthropic-executor.ts +189 -0
  470. package/src/web-search/executor.ts +105 -0
  471. package/src/web-search/format-result.ts +89 -0
  472. package/src/web-search/index.ts +196 -0
  473. package/src/web-search/loop.ts +664 -0
  474. package/src/web-search/parse.ts +220 -0
  475. package/src/web-search/progress-stream.ts +342 -0
  476. package/src/web-search/synthetic-tool.ts +47 -0
@@ -0,0 +1,132 @@
1
+ import { gunzipSync, inflateRawSync, inflateSync, zstdDecompressSync } from "node:zlib";
2
+ import type { TranslatorBudget } from "../lib/translator-budget";
3
+
4
+ /**
5
+ * Request-body decompression for the /v1/responses data plane.
6
+ *
7
+ * Codex CLI compresses Responses HTTP bodies with zstd when its
8
+ * `enable_request_compression` feature fires (default ON): auth is the codex
9
+ * backend AND the provider is the built-in `openai` id (codex-rs client.rs
10
+ * responses_request_compression). Under Design B injection the provider id IS
11
+ * `openai`, so the HTTP fallback path (WebSocket unavailable) delivers
12
+ * `content-encoding: zstd` bodies that `req.json()` cannot parse.
13
+ */
14
+
15
+ /**
16
+ * Cap decompressed request bodies (a compressed bomb must not inflate unbounded). Codex compresses
17
+ * EVERY responses request with zstd (no size threshold), and image-heavy histories inflate fast:
18
+ * ~12 full-res screenshots as base64 already cross 64MB decompressed. The proxy is fed by the user's
19
+ * own local Codex over loopback, so the bomb threat is weak; this cap is really an OOM guard. Keep it
20
+ * generous enough that ordinary multi-image sessions decode, while still bounding a runaway body.
21
+ */
22
+ export const MAX_DECOMPRESSED_BODY_BYTES = 256 * 1024 * 1024;
23
+
24
+ export class UnsupportedContentEncodingError extends Error {
25
+ constructor(readonly encoding: string) {
26
+ super(`Unsupported content-encoding: ${encoding}`);
27
+ }
28
+ }
29
+
30
+ export class DecompressedBodyTooLargeError extends Error {
31
+ constructor(readonly bytes: number, limit: number = MAX_DECOMPRESSED_BODY_BYTES) {
32
+ super(`Decompressed request body exceeds ${limit} bytes`);
33
+ }
34
+ }
35
+
36
+ function assertBodySizeWithinLimit(body: Uint8Array, maxBytes: number): Uint8Array {
37
+ if (body.byteLength > maxBytes) throw new DecompressedBodyTooLargeError(body.byteLength, maxBytes);
38
+ return body;
39
+ }
40
+
41
+ function declaredBodyLength(req: Request): number | null {
42
+ const raw = req.headers.get("content-length");
43
+ if (raw === null || raw.trim() === "") return null;
44
+ const length = Number(raw);
45
+ return Number.isFinite(length) && length >= 0 ? length : null;
46
+ }
47
+
48
+ function inflateDeflateBody(compressed: Uint8Array<ArrayBuffer>, opts: { maxOutputLength: number }): Uint8Array {
49
+ // HTTP "deflate" appears both zlib-wrapped and raw in the wild (Bun.deflateSync emits raw,
50
+ // which the previous Bun.inflateSync accepted). Try zlib-wrapped first, fall back to raw —
51
+ // but never swallow the size-cap abort.
52
+ try {
53
+ return inflateSync(compressed, opts);
54
+ } catch (err) {
55
+ if ((err as NodeJS.ErrnoException | null)?.code === "ERR_BUFFER_TOO_LARGE") throw err;
56
+ return inflateRawSync(compressed, opts);
57
+ }
58
+ }
59
+
60
+ export function decodeRequestBody(
61
+ raw: Uint8Array,
62
+ contentEncoding: string | null,
63
+ maxBytes: number = MAX_DECOMPRESSED_BODY_BYTES,
64
+ ): Uint8Array {
65
+ const encoding = (contentEncoding ?? "").trim().toLowerCase();
66
+ if (encoding === "" || encoding === "identity") return assertBodySizeWithinLimit(raw, maxBytes);
67
+ const compressed = raw as Uint8Array<ArrayBuffer>;
68
+ // `maxOutputLength` makes zlib abort DURING inflation (ERR_BUFFER_TOO_LARGE), so a
69
+ // decompression bomb never allocates beyond the cap — checking after the fact would
70
+ // already have paid the full allocation (review finding, PR #96).
71
+ const opts = { maxOutputLength: maxBytes };
72
+ let decoded: Uint8Array;
73
+ try {
74
+ if (encoding === "zstd") decoded = zstdDecompressSync(compressed, opts);
75
+ else if (encoding === "gzip" || encoding === "x-gzip") decoded = gunzipSync(compressed, opts);
76
+ else if (encoding === "deflate") decoded = inflateDeflateBody(compressed, opts);
77
+ // Multi-codings ("zstd, gzip") and unknown tokens are rejected rather than guessed.
78
+ else throw new UnsupportedContentEncodingError(encoding);
79
+ } catch (err) {
80
+ if ((err as NodeJS.ErrnoException | null)?.code === "ERR_BUFFER_TOO_LARGE") {
81
+ throw new DecompressedBodyTooLargeError(maxBytes + 1, maxBytes);
82
+ }
83
+ throw err;
84
+ }
85
+ return assertBodySizeWithinLimit(decoded, maxBytes);
86
+ }
87
+
88
+ /** Parse a bounded JSON request body, transparently decoding compressed payloads. */
89
+ export async function readBoundedJsonRequestBody(
90
+ req: Request,
91
+ maxBytes: number,
92
+ budget?: TranslatorBudget,
93
+ ): Promise<unknown> {
94
+ const encoding = req.headers.get("content-encoding");
95
+ const declaredLength = declaredBodyLength(req);
96
+ // Reject an honest oversized declaration before req.arrayBuffer() can allocate it.
97
+ // Missing, malformed, or dishonest declarations remain covered by decodeRequestBody's
98
+ // post-read cap below.
99
+ if (declaredLength !== null && declaredLength > maxBytes) {
100
+ throw new DecompressedBodyTooLargeError(declaredLength, maxBytes);
101
+ }
102
+ const releaseReservation = budget && declaredLength !== null && declaredLength > 0
103
+ ? budget.observeAcceptedRequestCopy(declaredLength)
104
+ : undefined;
105
+ let raw: Uint8Array;
106
+ try {
107
+ raw = new Uint8Array(await req.arrayBuffer());
108
+ } finally {
109
+ releaseReservation?.();
110
+ }
111
+ const releaseRaw = budget?.observeAcceptedRequestCopy(raw.byteLength);
112
+ let releaseDecoded: (() => void) | undefined;
113
+ let releaseText: (() => void) | undefined;
114
+ try {
115
+ const decoded = decodeRequestBody(raw, encoding, maxBytes);
116
+ releaseDecoded = decoded === raw ? undefined : budget?.observeAcceptedRequestCopy(decoded.byteLength);
117
+ const text = new TextDecoder().decode(decoded);
118
+ releaseText = budget?.observeAcceptedRequestCopy(new TextEncoder().encode(text).byteLength);
119
+ const parsed = JSON.parse(text);
120
+ budget?.observeAcceptedRequestCopy(new TextEncoder().encode(JSON.stringify(parsed)).byteLength);
121
+ return parsed;
122
+ } finally {
123
+ releaseText?.();
124
+ releaseDecoded?.();
125
+ releaseRaw?.();
126
+ }
127
+ }
128
+
129
+ /** Parse a JSON data-plane body using the shared 256 MiB admission cap. */
130
+ export function readJsonRequestBody(req: Request, budget?: TranslatorBudget): Promise<unknown> {
131
+ return readBoundedJsonRequestBody(req, MAX_DECOMPRESSED_BODY_BYTES, budget);
132
+ }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Best-effort chat/session correlation for Logs / usage.jsonl (#330).
3
+ * Opaque ids only — never persist raw emails or Claude Desktop system-hash fallbacks.
4
+ */
5
+ import { createHash } from "node:crypto";
6
+
7
+ /** Reject absurdly long client strings before hashing (DoS / JSONL bloat). */
8
+ export const LOG_CONVERSATION_ID_INPUT_MAX = 4096;
9
+ /** Persisted / filterable form is always a 32-char hex digest. */
10
+ export const LOG_CONVERSATION_ID_LEN = 32;
11
+
12
+ function hasControlChars(value: string): boolean {
13
+ for (let i = 0; i < value.length; i++) {
14
+ const code = value.charCodeAt(i);
15
+ if (code <= 0x1f || code === 0x7f) return true;
16
+ }
17
+ return false;
18
+ }
19
+
20
+ function sanitizeConversationIdInput(raw: string | undefined | null): string | undefined {
21
+ if (typeof raw !== "string") return undefined;
22
+ const trimmed = raw.trim();
23
+ if (!trimmed) return undefined;
24
+ // Reject control characters that would break JSONL / UI paste.
25
+ if (hasControlChars(trimmed)) return undefined;
26
+ if (trimmed.length > LOG_CONVERSATION_ID_INPUT_MAX) return undefined;
27
+ return trimmed;
28
+ }
29
+
30
+ /**
31
+ * Cap / sanitize a correlation id for persistence.
32
+ * Always hashes so client-controlled headers cannot land emails or short secrets in usage.jsonl.
33
+ */
34
+ export function normalizeLogConversationId(raw: string | undefined | null): string | undefined {
35
+ const trimmed = sanitizeConversationIdInput(raw);
36
+ if (!trimmed) return undefined;
37
+ return createHash("sha256").update(trimmed).digest("hex").slice(0, LOG_CONVERSATION_ID_LEN);
38
+ }
39
+
40
+ /**
41
+ * Filter match: accept either the persisted digest or the original preimage
42
+ * (so pasting from Logs detail or the client-facing session id both work).
43
+ */
44
+ export function matchesLogConversationId(
45
+ stored: string | undefined,
46
+ query: string | undefined | null,
47
+ ): boolean {
48
+ if (!stored) return false;
49
+ const trimmed = typeof query === "string" ? query.trim() : "";
50
+ if (!trimmed) return false;
51
+ if (stored === trimmed) return true;
52
+ const hashed = normalizeLogConversationId(trimmed);
53
+ return hashed !== undefined && stored === hashed;
54
+ }
55
+
56
+ /**
57
+ * Codex/Claude/Cursor priority for Responses-shaped requests:
58
+ * parent thread header > session_id / session-id > thread-id > cursor conversation id.
59
+ */
60
+ export function sessionIdHeaderFromRequest(headers: Headers): string | null {
61
+ return headers.get("session_id") ?? headers.get("session-id");
62
+ }
63
+
64
+ export function conversationIdFromResponsesRequest(input: {
65
+ clientThreadId?: string;
66
+ sessionIdHeader?: string | null;
67
+ threadIdHeader?: string | null;
68
+ cursorConversationId?: string;
69
+ }): string | undefined {
70
+ return normalizeLogConversationId(
71
+ input.clientThreadId
72
+ ?? input.sessionIdHeader
73
+ ?? input.threadIdHeader
74
+ ?? input.cursorConversationId,
75
+ );
76
+ }
77
+
78
+ /**
79
+ * Claude Code metadata.user_id only — never the system-hash Desktop fallback.
80
+ * Hashes the raw user_id once (same opacity goal as inbound prompt_cache_key).
81
+ */
82
+ export function conversationIdFromClaudeMetadata(
83
+ metadata: { user_id?: unknown } | null | undefined,
84
+ ): string | undefined {
85
+ if (!metadata || typeof metadata.user_id !== "string") return undefined;
86
+ return normalizeLogConversationId(metadata.user_id);
87
+ }
88
+
89
+ /** @deprecated Prefer conversationIdFromClaudeMetadata; kept for call-site clarity. */
90
+ export function conversationIdFromClaudeCacheKey(
91
+ cacheKeySource: "metadata" | "system" | null | undefined,
92
+ promptCacheKey: string | undefined,
93
+ ): string | undefined {
94
+ if (cacheKeySource !== "metadata") return undefined;
95
+ // prompt_cache_key is already sha256(user_id)[:32] from inbound — persist as-is
96
+ // (do not re-hash) so native and translated paths stay aligned when callers pass
97
+ // the preimage via conversationIdFromClaudeMetadata instead.
98
+ const trimmed = sanitizeConversationIdInput(promptCacheKey);
99
+ if (!trimmed) return undefined;
100
+ if (trimmed.length === LOG_CONVERSATION_ID_LEN && /^[0-9a-f]+$/i.test(trimmed)) return trimmed.toLowerCase();
101
+ return normalizeLogConversationId(trimmed);
102
+ }
103
+
104
+ export interface ConversationLogTotals {
105
+ requests: number;
106
+ totalTokens: number;
107
+ estimatedCostUsd: number;
108
+ pricedRequests: number;
109
+ unpricedRequests: number;
110
+ unmeteredRequests: number;
111
+ }
112
+
113
+ type TotalsSource = {
114
+ totalTokens?: number;
115
+ usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number };
116
+ usageStatus?: string;
117
+ displayMetrics?: {
118
+ cost?:
119
+ | { kind: "value"; estimate: { cost: { total: number } } }
120
+ | { kind: "unavailable"; reason: string };
121
+ };
122
+ };
123
+
124
+ function rowTokenTotal(entry: TotalsSource): number | undefined {
125
+ if (typeof entry.totalTokens === "number" && Number.isFinite(entry.totalTokens) && entry.totalTokens >= 0) {
126
+ return entry.totalTokens;
127
+ }
128
+ const usageTotal = entry.usage?.totalTokens;
129
+ if (typeof usageTotal === "number" && Number.isFinite(usageTotal) && usageTotal >= 0) return usageTotal;
130
+ const input = entry.usage?.inputTokens;
131
+ const output = entry.usage?.outputTokens;
132
+ if (typeof input === "number" && typeof output === "number" && Number.isFinite(input) && Number.isFinite(output)) {
133
+ return Math.max(0, input) + Math.max(0, output);
134
+ }
135
+ return undefined;
136
+ }
137
+
138
+ /** Sum tokens/cost for the currently loaded log slice matching a conversation filter. */
139
+ export function summarizeConversationLogs(entries: readonly TotalsSource[]): ConversationLogTotals {
140
+ let totalTokens = 0;
141
+ let estimatedCostUsd = 0;
142
+ let pricedRequests = 0;
143
+ let unpricedRequests = 0;
144
+ let unmeteredRequests = 0;
145
+ for (const entry of entries) {
146
+ const tokens = rowTokenTotal(entry);
147
+ if (tokens !== undefined) totalTokens += tokens;
148
+ if (entry.usageStatus === "unsupported") {
149
+ unmeteredRequests += 1;
150
+ continue;
151
+ }
152
+ const cost = entry.displayMetrics?.cost;
153
+ if (cost?.kind === "value" && Number.isFinite(cost.estimate.cost.total) && cost.estimate.cost.total >= 0) {
154
+ estimatedCostUsd += cost.estimate.cost.total;
155
+ pricedRequests += 1;
156
+ continue;
157
+ }
158
+ unpricedRequests += 1;
159
+ }
160
+ return {
161
+ requests: entries.length,
162
+ totalTokens,
163
+ estimatedCostUsd,
164
+ pricedRequests,
165
+ unpricedRequests,
166
+ unmeteredRequests,
167
+ };
168
+ }