@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,663 @@
1
+ import { createHash } from "node:crypto";
2
+ import { enforceAppOwnedMemoryBudget } from "../../lib/app-owned-memory";
3
+ import { create } from "@bufbuild/protobuf";
4
+ import {
5
+ DiagnosticsErrorSchema,
6
+ DiagnosticsResultSchema,
7
+ ErrorSchema,
8
+ GetBlobResultSchema,
9
+ KvClientMessageSchema,
10
+ McpErrorSchema,
11
+ McpResultSchema,
12
+ RequestContextResultSchema,
13
+ RequestContextSchema,
14
+ RequestContextSuccessSchema,
15
+ SetBlobResultSchema,
16
+ type ExecServerMessage,
17
+ type KvServerMessage,
18
+ } from "./gen/agent_pb";
19
+ import {
20
+ deleteExec,
21
+ grepExec,
22
+ lsExec,
23
+ readExec,
24
+ rejectDeleteExecForApplyPatch,
25
+ rejectDeleteExecForPolicy,
26
+ rejectGrepExecForPolicy,
27
+ rejectLsExecForPolicy,
28
+ rejectReadExecForPolicy,
29
+ rejectWriteExecForApplyPatch,
30
+ rejectWriteExecForPolicy,
31
+ writeExec,
32
+ } from "./native-exec-fs";
33
+ import { debugProviderDiagnostic } from "../../lib/debug";
34
+ import { fetchExec, rejectFetchExecForPolicy, type CursorNativeNetworkDeps } from "./native-exec-network";
35
+ import {
36
+ backgroundShellSpawnExec,
37
+ rejectBackgroundShellSpawnExecForPolicy,
38
+ rejectShellExecForPolicy,
39
+ rejectShellStreamExecForPolicy,
40
+ rejectWriteShellStdinExecForPolicy,
41
+ shellExec,
42
+ shellStreamExec,
43
+ writeShellStdinExec,
44
+ } from "./native-exec-shell";
45
+ import {
46
+ computerUseExec,
47
+ listMcpResourcesExec,
48
+ mcpExec,
49
+ readMcpResourceExec,
50
+ recordScreenExec,
51
+ type CursorNativeToolDeps,
52
+ } from "./native-exec-tools";
53
+ import { clientBytes, execBytes, execStreamCloseBytes, execThrowBytes } from "./native-exec-common";
54
+ import type { McpToolDefinition } from "./gen/agent_pb";
55
+ import { OCX_RESPONSES_TOOL_PROVIDER } from "./tool-definitions";
56
+
57
+ export type CursorNativeExecDeps = CursorNativeNetworkDeps & CursorNativeToolDeps;
58
+
59
+ /**
60
+ * Execution context for a Cursor stream: the per-call executors plus the MCP tool definitions
61
+ * advertised to the server via `requestContextResult`. Without `mcpToolDefs`, the server is
62
+ * never told any MCP tools exist, so it never sends `mcpArgs`.
63
+ */
64
+ export interface CursorNativeExecContext extends CursorNativeExecDeps {
65
+ /** Stable owner for background shells created by this transport session. */
66
+ sessionId?: string;
67
+ mcpToolDefs?: McpToolDefinition[];
68
+ clientToolDefs?: McpToolDefinition[];
69
+ /** Unsafe opt-in escape hatch for Cursor server-driven local fs/shell/fetch execution. */
70
+ unsafeAllowNativeLocalExec?: boolean;
71
+ /** apply_patch is visible for this request; Cursor-native write/delete must not bypass Codex. */
72
+ rejectNativeFileMutations?: boolean;
73
+ /** The synthetic exact-match edit tools (edit_file / multi_edit) are advertised this request. */
74
+ structuredEditAvailable?: boolean;
75
+ }
76
+
77
+ export function cursorUnsafeNativeLocalExecEnabled(input: Pick<CursorNativeExecContext, "unsafeAllowNativeLocalExec"> = {}): boolean {
78
+ return input.unsafeAllowNativeLocalExec === true;
79
+ }
80
+
81
+ /**
82
+ * Content-addressed blob store shared across streams. Bounded: without eviction a long-running
83
+ * proxy accumulates every conversation's prompt blobs forever (unbounded memory) and any stale
84
+ * blob stays servable indefinitely — a cross-conversation contamination enabler if Cursor's
85
+ * server-side state ever references old ids (devlog 260702 P0). Continuation requests re-store
86
+ * their blobs on every turn (`rootPromptMessages` → `storeCursorBlob`), so TTL + cap eviction is
87
+ * safe for live sessions: only genuinely abandoned entries age out.
88
+ */
89
+ const BLOB_TTL_MS = 15 * 60_000;
90
+ const BLOB_MAX_ENTRIES = 4_096;
91
+ const BLOB_MAX_ENTRY_BYTES = 16 * 1024 * 1024;
92
+ export const CURSOR_BLOB_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
93
+
94
+ type CursorBlobProvenance = "local-regenerated" | "remote-setBlobArgs";
95
+ export type CursorBlobRequestScopeToken = symbol;
96
+
97
+ interface CursorBlobEntry {
98
+ data: Uint8Array;
99
+ storedAt: number;
100
+ sizeBytes: number;
101
+ provenance: CursorBlobProvenance;
102
+ requestPins: Set<CursorBlobRequestScopeToken>;
103
+ }
104
+
105
+ type CursorBlobRejectionReason = "entry_too_large" | "pinned_saturation" | "request_pinned_conflict";
106
+ type CursorBlobAdmission =
107
+ | { admitted: true; replaced: boolean }
108
+ | { admitted: false; reason: CursorBlobRejectionReason };
109
+
110
+ interface CursorBlobLimits {
111
+ ttlMs: number;
112
+ maxEntries: number;
113
+ maxEntryBytes: number;
114
+ maxTotalBytes: number;
115
+ }
116
+
117
+ interface CursorBlobRequestScopeState {
118
+ keys: Set<string>;
119
+ sealed: boolean;
120
+ kind: "request" | "checkpoint";
121
+ }
122
+
123
+ const DEFAULT_BLOB_LIMITS: CursorBlobLimits = {
124
+ ttlMs: BLOB_TTL_MS,
125
+ maxEntries: BLOB_MAX_ENTRIES,
126
+ maxEntryBytes: BLOB_MAX_ENTRY_BYTES,
127
+ maxTotalBytes: CURSOR_BLOB_MAX_TOTAL_BYTES,
128
+ };
129
+
130
+ const blobs = new Map<string, CursorBlobEntry>();
131
+ const blobRequestScopes = new Map<CursorBlobRequestScopeToken, CursorBlobRequestScopeState>();
132
+ let blobLimits = { ...DEFAULT_BLOB_LIMITS };
133
+ let blobBytes = 0;
134
+ /** Retained key-string bytes (separate from the payload cap — see key()). */
135
+ let blobKeyBytes = 0;
136
+ let blobLocalBytes = 0;
137
+ let blobPinnedBytes = 0;
138
+ let blobEvictableBytes = 0;
139
+ let blobOldestEvictableAt: number | null = null;
140
+ let rejectedEntryTooLarge = 0;
141
+ let rejectedPinnedSaturation = 0;
142
+ let blobExpiryAccountingTimer: ReturnType<typeof setTimeout> | undefined;
143
+
144
+ function isExpired(entry: CursorBlobEntry, now: number): boolean {
145
+ return now - entry.storedAt >= blobLimits.ttlMs;
146
+ }
147
+
148
+ function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {
149
+ if (a.byteLength !== b.byteLength) return false;
150
+ for (let i = 0; i < a.byteLength; i++) if (a[i] !== b[i]) return false;
151
+ return true;
152
+ }
153
+
154
+ function recomputeBlobClassAccounting(): void {
155
+ const now = Date.now();
156
+ let localBytes = 0;
157
+ let pinnedBytes = 0;
158
+ let evictableBytes = 0;
159
+ let oldestAt: number | null = null;
160
+ for (const [k, entry] of blobs) {
161
+ const requestPinned = entry.requestPins.size > 0;
162
+ const provenancePinned = entry.provenance === "remote-setBlobArgs" && !isExpired(entry, now);
163
+ if (entry.provenance === "local-regenerated") localBytes += entry.sizeBytes;
164
+ // Key strings classify WITH their entry: a zero-payload blob must stay
165
+ // evictable/pinned exactly as its payload would be, or the budget cannot
166
+ // select it even though the total snapshot counts its key.
167
+ if (requestPinned || provenancePinned) pinnedBytes += entry.sizeBytes + k.length;
168
+ if (!requestPinned && (entry.provenance === "local-regenerated" || isExpired(entry, now))) {
169
+ evictableBytes += entry.sizeBytes + k.length;
170
+ oldestAt = oldestAt === null ? entry.storedAt : Math.min(oldestAt, entry.storedAt);
171
+ }
172
+ }
173
+ blobLocalBytes = localBytes;
174
+ blobPinnedBytes = pinnedBytes;
175
+ blobEvictableBytes = evictableBytes;
176
+ blobOldestEvictableAt = oldestAt;
177
+ scheduleBlobExpiryAccounting(now);
178
+ }
179
+
180
+ function reconcileBlobClassAccountingAndEnforce(): void {
181
+ recomputeBlobClassAccounting();
182
+ enforceAppOwnedMemoryBudget();
183
+ }
184
+
185
+ function scheduleBlobExpiryAccounting(now: number): void {
186
+ if (blobExpiryAccountingTimer) clearTimeout(blobExpiryAccountingTimer);
187
+ blobExpiryAccountingTimer = undefined;
188
+ let nextExpiry = Number.POSITIVE_INFINITY;
189
+ for (const entry of blobs.values()) {
190
+ if (entry.provenance !== "remote-setBlobArgs" || entry.requestPins.size > 0) continue;
191
+ const expiresAt = entry.storedAt + blobLimits.ttlMs;
192
+ if (expiresAt > now) nextExpiry = Math.min(nextExpiry, expiresAt);
193
+ }
194
+ if (!Number.isFinite(nextExpiry)) return;
195
+ blobExpiryAccountingTimer = setTimeout(() => {
196
+ blobExpiryAccountingTimer = undefined;
197
+ reconcileBlobClassAccountingAndEnforce();
198
+ }, Math.max(0, nextExpiry - now));
199
+ blobExpiryAccountingTimer.unref?.();
200
+ }
201
+
202
+ function deleteBlob(k: string, recompute = true): number {
203
+ const entry = blobs.get(k);
204
+ if (!entry) return 0;
205
+ blobs.delete(k);
206
+ blobBytes -= entry.sizeBytes;
207
+ blobKeyBytes -= k.length;
208
+ for (const scope of entry.requestPins) blobRequestScopes.get(scope)?.keys.delete(k);
209
+ if (recompute) recomputeBlobClassAccounting();
210
+ // Full logical release (payload + key): the retained-store snapshot counts
211
+ // both, so budget enforcement must see both leave.
212
+ return entry.sizeBytes + k.length;
213
+ }
214
+
215
+ function releaseHydratedBlob(k: string, requestScope?: CursorBlobRequestScopeToken): void {
216
+ const entry = blobs.get(k);
217
+ if (!entry) return;
218
+ const scopes = requestScope ? [requestScope] : [...entry.requestPins];
219
+ let changed = false;
220
+ for (const scope of scopes) {
221
+ if (!entry.requestPins.delete(scope)) continue;
222
+ changed = true;
223
+ const state = blobRequestScopes.get(scope);
224
+ state?.keys.delete(k);
225
+ if (state?.sealed && state.keys.size === 0) blobRequestScopes.delete(scope);
226
+ }
227
+ if (changed) reconcileBlobClassAccountingAndEnforce();
228
+ }
229
+
230
+ function setBlob(
231
+ k: string,
232
+ data: Uint8Array,
233
+ provenance: CursorBlobProvenance,
234
+ requestScope?: CursorBlobRequestScopeToken,
235
+ ): CursorBlobAdmission {
236
+ if (data.byteLength > blobLimits.maxEntryBytes) {
237
+ rejectedEntryTooLarge++;
238
+ return { admitted: false, reason: "entry_too_large" };
239
+ }
240
+
241
+ const now = Date.now();
242
+ const existing = blobs.get(k);
243
+ const sameData = existing ? bytesEqual(existing.data, data) : false;
244
+ if (existing && !sameData && existing.requestPins.size > 0) {
245
+ return { admitted: false, reason: "request_pinned_conflict" };
246
+ }
247
+
248
+ const removals = new Set<string>();
249
+ for (const [candidateKey, entry] of blobs) {
250
+ if (candidateKey === k && sameData) continue;
251
+ if (entry.requestPins.size === 0 && isExpired(entry, now)) removals.add(candidateKey);
252
+ }
253
+
254
+ const existingRemovedByTtl = existing !== undefined && removals.has(k);
255
+ const reuseExisting = existing !== undefined && sameData && !existingRemovedByTtl;
256
+ const mergedProvenance: CursorBlobProvenance = reuseExisting && existing.provenance === "remote-setBlobArgs"
257
+ ? "remote-setBlobArgs"
258
+ : provenance;
259
+ const storedAt = reuseExisting && existing.provenance === "remote-setBlobArgs" && provenance === "local-regenerated"
260
+ ? existing.storedAt
261
+ : now;
262
+
263
+ let projectedBytes = blobBytes;
264
+ let projectedCount = blobs.size;
265
+ for (const candidateKey of removals) {
266
+ const entry = blobs.get(candidateKey);
267
+ if (!entry) continue;
268
+ projectedBytes -= entry.sizeBytes;
269
+ projectedCount--;
270
+ }
271
+ if (existing && !existingRemovedByTtl) {
272
+ projectedBytes -= existing.sizeBytes;
273
+ projectedCount--;
274
+ }
275
+ projectedBytes += data.byteLength;
276
+ projectedCount++;
277
+
278
+ if (projectedBytes > blobLimits.maxTotalBytes || projectedCount > blobLimits.maxEntries) {
279
+ const localVictims = [...blobs.entries()].sort((a, b) => a[1].storedAt - b[1].storedAt);
280
+ for (const [candidateKey, entry] of localVictims) {
281
+ if (
282
+ candidateKey === k
283
+ || removals.has(candidateKey)
284
+ || entry.requestPins.size > 0
285
+ || entry.provenance !== "local-regenerated"
286
+ ) continue;
287
+ removals.add(candidateKey);
288
+ projectedBytes -= entry.sizeBytes;
289
+ projectedCount--;
290
+ if (projectedBytes <= blobLimits.maxTotalBytes && projectedCount <= blobLimits.maxEntries) break;
291
+ }
292
+ }
293
+
294
+ if (projectedBytes > blobLimits.maxTotalBytes || projectedCount > blobLimits.maxEntries) {
295
+ rejectedPinnedSaturation++;
296
+ return { admitted: false, reason: "pinned_saturation" };
297
+ }
298
+
299
+ // Carry forward only pins whose scope still has live state; a dead scope's
300
+ // token can never be released again (review C1-1).
301
+ const requestPins = new Set<CursorBlobRequestScopeToken>();
302
+ if (reuseExisting) {
303
+ for (const scope of existing.requestPins) {
304
+ if (blobRequestScopes.has(scope)) requestPins.add(scope);
305
+ }
306
+ }
307
+ // A pin is only attached when the scope still has live UNSEALED state:
308
+ // sealing fixes the advertised key set (locked contract), so a remote
309
+ // setBlobArgs arriving after seal must not extend the pin set — and a
310
+ // sealed scope whose advertised keys have all hydrated is already deleted,
311
+ // so attaching its stale token would create a permanent untracked pin the
312
+ // terminal release could never clear (reviews C1-1/C2-1).
313
+ const scopeState = requestScope ? blobRequestScopes.get(requestScope) : undefined;
314
+ if (requestScope && scopeState && !scopeState.sealed) requestPins.add(requestScope);
315
+ const entry: CursorBlobEntry = {
316
+ data: reuseExisting ? existing.data : data.slice(),
317
+ storedAt,
318
+ sizeBytes: data.byteLength,
319
+ provenance: mergedProvenance,
320
+ requestPins,
321
+ };
322
+
323
+ for (const candidateKey of removals) deleteBlob(candidateKey, false);
324
+ if (blobs.has(k)) deleteBlob(k, false);
325
+ blobs.set(k, entry);
326
+ blobBytes += entry.sizeBytes;
327
+ blobKeyBytes += k.length;
328
+ for (const scope of entry.requestPins) blobRequestScopes.get(scope)?.keys.add(k);
329
+ reconcileBlobClassAccountingAndEnforce();
330
+ return { admitted: true, replaced: existing !== undefined };
331
+ }
332
+
333
+ function getBlob(k: string): Uint8Array | undefined {
334
+ const entry = blobs.get(k);
335
+ if (!entry) return undefined;
336
+ if (entry.requestPins.size === 0 && isExpired(entry, Date.now())) {
337
+ deleteBlob(k);
338
+ return undefined;
339
+ }
340
+ return entry.data;
341
+ }
342
+
343
+ /**
344
+ * Raw blob IDs up to this size keep their hex passthrough (every ID the live
345
+ * protocol carries is a 32-byte digest). Anything larger maps to a fixed-size
346
+ * SHA-256 hex of the raw bytes — the derivation is symmetric across
347
+ * setBlobArgs/getBlobArgs, so the round-trip still works, but a hostile or
348
+ * malformed multi-MiB ID can never become an unbounded hex Map key.
349
+ * The `h:`/`d:` prefix domain-separates the two namespaces: a digested ID's
350
+ * key can never collide with a raw 32-byte ID that happens to BE that digest.
351
+ */
352
+ const MAX_BLOB_ID_PASSTHROUGH_BYTES = 64;
353
+
354
+ function key(bytes: Uint8Array): string {
355
+ if (bytes.byteLength <= MAX_BLOB_ID_PASSTHROUGH_BYTES) return `h:${Buffer.from(bytes).toString("hex")}`;
356
+ return `d:${createHash("sha256").update(bytes).digest("hex")}`;
357
+ }
358
+
359
+ /**
360
+ * Store a blob (SHA-256 keyed) in the shared map that `handleCursorNativeKv` serves, and return its
361
+ * blob id. Cursor's `rootPromptMessagesJson`/turn entries are blob IDS, not inline content — the
362
+ * server fetches the bytes back via `getBlobArgs`. Mirrors jawcode `createBlobId`/`storeCursorBlob`.
363
+ */
364
+ export class CursorBlobAdmissionError extends Error {
365
+ readonly code = "cursor_blob_capacity";
366
+
367
+ constructor(readonly reason: CursorBlobRejectionReason) {
368
+ super("Cursor blob capacity is exhausted; retry with a smaller request.");
369
+ this.name = "CursorBlobAdmissionError";
370
+ }
371
+ }
372
+
373
+ let blobScopeSequence = 0;
374
+
375
+ export function createCursorBlobRequestScope(): CursorBlobRequestScopeToken {
376
+ // Unique description per token so debug snapshots expose exact pin
377
+ // IDENTITY, not just pin counts (review C2-2: identical descriptions made
378
+ // scope-swap bugs invisible to deep comparison).
379
+ const scope = Symbol(`cursor-blob-request-${++blobScopeSequence}`);
380
+ blobRequestScopes.set(scope, { keys: new Set(), sealed: false, kind: "request" });
381
+ return scope;
382
+ }
383
+
384
+ export function sealCursorBlobRequestScope(scope: CursorBlobRequestScopeToken): void {
385
+ const state = blobRequestScopes.get(scope);
386
+ if (!state) return;
387
+ state.sealed = true;
388
+ if (state.keys.size === 0) blobRequestScopes.delete(scope);
389
+ }
390
+
391
+ export function releaseCursorBlobRequestScope(scope: CursorBlobRequestScopeToken): void {
392
+ const state = blobRequestScopes.get(scope);
393
+ if (!state) return;
394
+ for (const k of state.keys) blobs.get(k)?.requestPins.delete(scope);
395
+ blobRequestScopes.delete(scope);
396
+ reconcileBlobClassAccountingAndEnforce();
397
+ }
398
+
399
+ export function storeCursorBlob(data: Uint8Array, requestScope?: CursorBlobRequestScopeToken): Uint8Array {
400
+ const blobId = new Uint8Array(createHash("sha256").update(data).digest());
401
+ const admission = setBlob(key(blobId), data, "local-regenerated", requestScope);
402
+ if (!admission.admitted) throw new CursorBlobAdmissionError(admission.reason);
403
+ return blobId;
404
+ }
405
+
406
+ /**
407
+ * Long-lived pin for blobs referenced by an active Cursor conversation checkpoint.
408
+ * Unlike a request scope, this lease is not sealed and is not released by getBlob hydration.
409
+ */
410
+ export function createCursorBlobCheckpointLease(label: string): CursorBlobRequestScopeToken {
411
+ const scope = Symbol("cursor-blob-checkpoint-" + (++blobScopeSequence) + "-" + label.slice(0, 16));
412
+ blobRequestScopes.set(scope, { keys: new Set(), sealed: false, kind: "checkpoint" });
413
+ return scope;
414
+ }
415
+
416
+ export function pinCursorBlobIdsForCheckpoint(
417
+ blobIds: readonly Uint8Array[],
418
+ lease: CursorBlobRequestScopeToken,
419
+ ): boolean {
420
+ const state = blobRequestScopes.get(lease);
421
+ if (!state || state.sealed) return false;
422
+ const added: Array<{ entry: { requestPins: Set<CursorBlobRequestScopeToken> }; key: string }> = [];
423
+ for (const blobId of blobIds) {
424
+ if (blobId.byteLength === 0) continue;
425
+ const k = key(blobId);
426
+ const entry = blobs.get(k);
427
+ if (!entry || (isExpired(entry, Date.now()) && entry.requestPins.size === 0 && entry.provenance !== "remote-setBlobArgs")) {
428
+ for (const pinned of added) {
429
+ pinned.entry.requestPins.delete(lease);
430
+ state.keys.delete(pinned.key);
431
+ }
432
+ return false;
433
+ }
434
+ if (!entry.requestPins.has(lease)) {
435
+ entry.requestPins.add(lease);
436
+ state.keys.add(k);
437
+ added.push({ entry, key: k });
438
+ }
439
+ }
440
+ reconcileBlobClassAccountingAndEnforce();
441
+ return true;
442
+ }
443
+
444
+ export function hasCursorBlob(blobId: Uint8Array): boolean {
445
+ return getBlob(key(blobId)) !== undefined;
446
+ }
447
+
448
+ export interface CursorBlobMetrics {
449
+ count: number;
450
+ totalBytes: number;
451
+ keyBytes: number;
452
+ localBytes: number;
453
+ pinnedBytes: number;
454
+ rejectedEntryTooLarge: number;
455
+ rejectedPinnedSaturation: number;
456
+ oldestAt: number | null;
457
+ }
458
+
459
+ export function cursorBlobMetrics(): CursorBlobMetrics {
460
+ return {
461
+ count: blobs.size,
462
+ totalBytes: blobBytes,
463
+ keyBytes: blobKeyBytes,
464
+ localBytes: blobLocalBytes,
465
+ pinnedBytes: blobPinnedBytes,
466
+ rejectedEntryTooLarge,
467
+ rejectedPinnedSaturation,
468
+ oldestAt: blobOldestEvictableAt,
469
+ };
470
+ }
471
+
472
+ export function cursorBlobRetainedStoreSnapshot(): {
473
+ count: number;
474
+ bytes: number;
475
+ evictableBytes: number;
476
+ pinnedBytes: number;
477
+ oldestAt: number | null;
478
+ } {
479
+ return {
480
+ count: blobs.size,
481
+ // Payload + retained key strings: the framework must see everything the
482
+ // store retains. The 64 MiB admission cap stays payload-only by design.
483
+ bytes: blobBytes + blobKeyBytes,
484
+ evictableBytes: blobEvictableBytes,
485
+ pinnedBytes: blobPinnedBytes,
486
+ oldestAt: blobOldestEvictableAt,
487
+ };
488
+ }
489
+
490
+ export function evictOldestCursorBlobForBudget(): number {
491
+ const now = Date.now();
492
+ let oldest: [string, CursorBlobEntry] | undefined;
493
+ for (const candidate of blobs) {
494
+ const entry = candidate[1];
495
+ if (entry.requestPins.size > 0) continue;
496
+ if (entry.provenance !== "local-regenerated" && !isExpired(entry, now)) continue;
497
+ if (!oldest || entry.storedAt < oldest[1].storedAt) oldest = candidate;
498
+ }
499
+ return oldest ? deleteBlob(oldest[0]) : 0;
500
+ }
501
+
502
+ export function setCursorBlobLimitsForTests(limits?: Partial<CursorBlobLimits>): void {
503
+ resetCursorBlobStateForTests();
504
+ blobLimits = limits ? { ...DEFAULT_BLOB_LIMITS, ...limits } : { ...DEFAULT_BLOB_LIMITS };
505
+ }
506
+
507
+ /**
508
+ * The live per-blob admission ceiling. Callers that build a blob must budget against THIS value
509
+ * rather than a copy of the constant: the limit is test-overridable, and a hardcoded 16 MiB would
510
+ * silently drift from admission the moment either side changes.
511
+ */
512
+ export function cursorBlobMaxEntryBytes(): number {
513
+ return blobLimits.maxEntryBytes;
514
+ }
515
+
516
+ export function resetCursorBlobStateForTests(): void {
517
+ if (blobExpiryAccountingTimer) clearTimeout(blobExpiryAccountingTimer);
518
+ blobExpiryAccountingTimer = undefined;
519
+ blobs.clear();
520
+ blobRequestScopes.clear();
521
+ blobBytes = 0;
522
+ blobKeyBytes = 0;
523
+ rejectedEntryTooLarge = 0;
524
+ rejectedPinnedSaturation = 0;
525
+ recomputeBlobClassAccounting();
526
+ }
527
+
528
+ export function cursorBlobStoreDebugSnapshotForTests(): Array<{
529
+ key: string;
530
+ sizeBytes: number;
531
+ storedAt: number;
532
+ provenance: CursorBlobProvenance;
533
+ requestPins: number;
534
+ dataDigest: string;
535
+ pinTokens: string[];
536
+ }> {
537
+ return [...blobs].map(([blobKey, entry]) => ({
538
+ key: blobKey,
539
+ sizeBytes: entry.sizeBytes,
540
+ storedAt: entry.storedAt,
541
+ provenance: entry.provenance,
542
+ requestPins: entry.requestPins.size,
543
+ // Byte-for-byte content identity + exact pin-set membership so rollback
544
+ // tests can deep-compare complete state (review C1-2).
545
+ dataDigest: createHash("sha256").update(entry.data).digest("hex"),
546
+ pinTokens: [...entry.requestPins].map(scope => String(scope.description ?? "scope")).sort(),
547
+ }));
548
+ }
549
+
550
+ export async function handleCursorNativeExec(execMsg: ExecServerMessage, deps: CursorNativeExecContext = {}): Promise<Uint8Array[]> {
551
+ const execCase = execMsg.message.case;
552
+ if (execCase === "requestContextArgs") {
553
+ const tools = [...(deps.mcpToolDefs ?? []), ...(deps.clientToolDefs ?? [])];
554
+ return [execBytes(execMsg, "requestContextResult", create(RequestContextResultSchema, {
555
+ result: { case: "success", value: create(RequestContextSuccessSchema, { requestContext: create(RequestContextSchema, { tools }) }) },
556
+ }))];
557
+ }
558
+ if (!cursorUnsafeNativeLocalExecEnabled(deps)) {
559
+ if (execCase === "readArgs") return [rejectReadExecForPolicy(execMsg)];
560
+ if (execCase === "writeArgs") return [rejectWriteExecForPolicy(execMsg)];
561
+ if (execCase === "deleteArgs") return [rejectDeleteExecForPolicy(execMsg)];
562
+ if (execCase === "lsArgs") return [rejectLsExecForPolicy(execMsg)];
563
+ if (execCase === "grepArgs") return [rejectGrepExecForPolicy(execMsg)];
564
+ if (execCase === "shellArgs") return [rejectShellExecForPolicy(execMsg)];
565
+ if (execCase === "shellStreamArgs") return rejectShellStreamExecForPolicy(execMsg);
566
+ if (execCase === "backgroundShellSpawnArgs") return [rejectBackgroundShellSpawnExecForPolicy(execMsg)];
567
+ if (execCase === "writeShellStdinArgs") return [rejectWriteShellStdinExecForPolicy(execMsg)];
568
+ if (execCase === "fetchArgs") return [rejectFetchExecForPolicy(execMsg)];
569
+ }
570
+ if (execCase === "readArgs") return [readExec(execMsg)];
571
+ if (execCase === "writeArgs") return [deps.rejectNativeFileMutations ? rejectWriteExecForApplyPatch(execMsg, deps.structuredEditAvailable === true) : writeExec(execMsg)];
572
+ if (execCase === "deleteArgs") return [deps.rejectNativeFileMutations ? rejectDeleteExecForApplyPatch(execMsg, deps.structuredEditAvailable === true) : deleteExec(execMsg)];
573
+ if (execCase === "lsArgs") return [lsExec(execMsg)];
574
+ if (execCase === "grepArgs") return [grepExec(execMsg)];
575
+ if (execCase === "shellArgs") return [shellExec(execMsg)];
576
+ if (execCase === "shellStreamArgs") return shellStreamExec(execMsg);
577
+ if (execCase === "backgroundShellSpawnArgs") return [backgroundShellSpawnExec(execMsg, deps.sessionId ?? "")];
578
+ if (execCase === "writeShellStdinArgs") return [writeShellStdinExec(execMsg, deps.sessionId ?? "")];
579
+ if (execCase === "fetchArgs") return [await fetchExec(execMsg, deps)];
580
+ if (execCase === "mcpArgs" && execMsg.message.value.providerIdentifier === OCX_RESPONSES_TOOL_PROVIDER) {
581
+ return [execBytes(execMsg, "mcpResult", create(McpResultSchema, {
582
+ result: {
583
+ case: "error",
584
+ value: create(McpErrorSchema, { error: "Cursor requested a client Responses tool through the native exec channel; bridge suspension is not implemented." }),
585
+ },
586
+ }))];
587
+ }
588
+ if (execCase === "mcpArgs") return [await mcpExec(execMsg, deps)];
589
+ if (execCase === "listMcpResourcesExecArgs") return [await listMcpResourcesExec(execMsg, deps)];
590
+ if (execCase === "readMcpResourceExecArgs") return [await readMcpResourceExec(execMsg, deps)];
591
+ if (execCase === "computerUseArgs") return [await computerUseExec(execMsg, deps)];
592
+ if (execCase === "recordScreenArgs") return [await recordScreenExec(execMsg, deps)];
593
+ if (execCase === "diagnosticsArgs") {
594
+ const path = execMsg.message.value.path;
595
+ return [execBytes(execMsg, "diagnosticsResult", create(DiagnosticsResultSchema, {
596
+ result: {
597
+ case: "error",
598
+ value: create(DiagnosticsErrorSchema, {
599
+ path,
600
+ error: "Diagnostics are not supported by the opencodex Cursor transport.",
601
+ }),
602
+ },
603
+ }))];
604
+ }
605
+ // Unknown exec case — Cursor added a new native exec type that our protobuf definition does not
606
+ // include yet. T05 (senpi contract): reply with ExecClientThrow + stream-close so the server
607
+ // unblocks with a known failure. Previously this returned an empty reply (silence), which is
608
+ // the stall class senpi explicitly refused (#116 was about throwing into failAndClear and
609
+ // killing the whole connection; a typed in-band throw does not do that).
610
+ debugProviderDiagnostic("cursor", "unknown-exec-case", { execCase: execCase ?? "unknown", execId: execMsg.execId });
611
+ return [
612
+ execThrowBytes(execMsg, "Unknown exec message variant; this client does not implement it."),
613
+ execStreamCloseBytes(execMsg),
614
+ ];
615
+ }
616
+
617
+
618
+ export function handleCursorNativeKv(
619
+ kvMsg: KvServerMessage,
620
+ requestScope?: CursorBlobRequestScopeToken,
621
+ ): Uint8Array {
622
+ if (kvMsg.message.case === "getBlobArgs") {
623
+ const blobKey = key(kvMsg.message.value.blobId);
624
+ const blobData = getBlob(blobKey);
625
+ if (blobData && requestScope && blobRequestScopes.get(requestScope)?.kind === "request") {
626
+ releaseHydratedBlob(blobKey, requestScope);
627
+ }
628
+ return clientBytes({
629
+ message: {
630
+ case: "kvClientMessage",
631
+ value: create(KvClientMessageSchema, {
632
+ id: kvMsg.id,
633
+ message: { case: "getBlobResult", value: create(GetBlobResultSchema, blobData ? { blobData } : {}) },
634
+ }),
635
+ },
636
+ });
637
+ }
638
+ if (kvMsg.message.case === "setBlobArgs") {
639
+ const admission = setBlob(
640
+ key(kvMsg.message.value.blobId),
641
+ kvMsg.message.value.blobData,
642
+ "remote-setBlobArgs",
643
+ requestScope,
644
+ );
645
+ return clientBytes({
646
+ message: {
647
+ case: "kvClientMessage",
648
+ value: create(KvClientMessageSchema, {
649
+ id: kvMsg.id,
650
+ message: {
651
+ case: "setBlobResult",
652
+ value: create(SetBlobResultSchema, admission.admitted ? {} : {
653
+ error: create(ErrorSchema, {
654
+ message: "Cursor blob capacity is exhausted; the blob was not stored.",
655
+ }),
656
+ }),
657
+ },
658
+ }),
659
+ },
660
+ });
661
+ }
662
+ return clientBytes({ message: { case: "kvClientMessage", value: create(KvClientMessageSchema, { id: kvMsg.id }) } });
663
+ }