@bitkyc08/opencodex 2.83.0 → 2.86.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 (405) hide show
  1. package/README.md +0 -4
  2. package/bin/ocx.mjs +61 -3
  3. package/gui/dist/assets/App-BjlttVLy.js +58 -0
  4. package/gui/dist/assets/Tray-DyR9yBee.js +1 -0
  5. package/gui/dist/assets/{index-BAbcj51J.css → index-BB6uK6tU.css} +1 -1
  6. package/gui/dist/assets/index-BMssP4k3.js +94 -0
  7. package/gui/dist/assets/quota-summary-D8M1bc_R.js +1 -0
  8. package/gui/dist/index.html +2 -2
  9. package/package.json +2 -3
  10. package/src/adapters/anthropic/beta-allowlist.ts +87 -8
  11. package/src/adapters/anthropic/client-identity.ts +1 -1
  12. package/src/adapters/anthropic/passthrough.ts +33 -4
  13. package/src/adapters/azure.ts +19 -1
  14. package/src/adapters/client-fingerprint.ts +24 -0
  15. package/src/adapters/coding-agent/protocol.ts +15 -8
  16. package/src/adapters/coding-agent/turn.ts +22 -9
  17. package/src/adapters/cursor/arg-codec.ts +17 -5
  18. package/src/adapters/cursor/catalog.ts +8 -0
  19. package/src/adapters/cursor/effort-map.ts +3 -0
  20. package/src/adapters/cursor/freeform-args.ts +75 -0
  21. package/src/adapters/cursor/protobuf-events.ts +36 -23
  22. package/src/adapters/google-antigravity-wire.ts +22 -1
  23. package/src/adapters/google.ts +2 -2
  24. package/src/adapters/ollama-native.ts +29 -1
  25. package/src/adapters/openai-chat/messages.ts +8 -4
  26. package/src/adapters/openai-chat/response-events.ts +59 -1
  27. package/src/adapters/openai-chat.ts +8 -5
  28. package/src/adapters/openai-responses/empty-assistant.ts +32 -0
  29. package/src/adapters/openai-responses/passthrough.ts +3 -0
  30. package/src/adapters/openai-responses/request-strips.ts +10 -2
  31. package/src/adapters/qoder/adapter.ts +56 -15
  32. package/src/advisor/consult.ts +220 -0
  33. package/src/advisor/context.ts +226 -0
  34. package/src/advisor/disclosure.ts +20 -0
  35. package/src/advisor/runtime.ts +305 -0
  36. package/src/advisor/settings.ts +135 -0
  37. package/src/advisor/state.ts +369 -0
  38. package/src/advisor/synthetic-tool.ts +33 -0
  39. package/src/bridge/errors.ts +24 -0
  40. package/src/bridge.ts +1 -1
  41. package/src/chat/inbound.ts +30 -6
  42. package/src/chat/outbound.ts +5 -0
  43. package/src/claude/context-windows.ts +54 -1
  44. package/src/claude/desktop-3p-library.ts +43 -3
  45. package/src/claude/desktop-3p.ts +22 -8
  46. package/src/claude/desktop-picker-profile.ts +11 -4
  47. package/src/claude/desktop-profile.ts +10 -1
  48. package/src/claude/desktop-remote-store-io.ts +5 -3
  49. package/src/claude/inbound.ts +121 -50
  50. package/src/claude/intercept/connect-proxy.ts +10 -3
  51. package/src/claude/intercept/local-ca.ts +8 -1
  52. package/src/claude/intercept/picker-ca-persistence.ts +3 -1
  53. package/src/claude/intercept/picker-listener.ts +49 -1
  54. package/src/claude/intercept/settings-no-proxy.ts +146 -0
  55. package/src/claude/intercept/settings.ts +101 -9
  56. package/src/claude/model-default-settings.ts +154 -0
  57. package/src/claude/model-info.ts +7 -7
  58. package/src/claude/outbound.ts +13 -6
  59. package/src/cli/account-api.ts +65 -0
  60. package/src/cli/account-auth.ts +26 -2
  61. package/src/cli/account.ts +41 -5
  62. package/src/cli/advisor.ts +151 -0
  63. package/src/cli/auxiliary-listener-preflight.ts +37 -0
  64. package/src/cli/capabilities-access-remote.ts +8 -0
  65. package/src/cli/capabilities-agents-routing.ts +18 -0
  66. package/src/cli/capabilities-base.ts +14 -2
  67. package/src/cli/catalog-command-result.ts +2 -1
  68. package/src/cli/chatgpt-command.ts +35 -14
  69. package/src/cli/claude.ts +60 -11
  70. package/src/cli/config-command.ts +8 -2
  71. package/src/cli/debug.ts +8 -0
  72. package/src/cli/dispatch.ts +21 -4
  73. package/src/cli/doctor.ts +9 -0
  74. package/src/cli/ensure-desktop-cold-start.ts +329 -0
  75. package/src/cli/export-command.ts +15 -2
  76. package/src/cli/help.ts +2 -1
  77. package/src/cli/hub-disable.ts +99 -0
  78. package/src/cli/hub.ts +4 -2
  79. package/src/cli/index.ts +26 -8
  80. package/src/cli/integration-plan-dto.ts +2 -0
  81. package/src/cli/link-child.ts +104 -0
  82. package/src/cli/link-enrollment.ts +96 -0
  83. package/src/cli/link.ts +39 -24
  84. package/src/cli/observe-stream.ts +6 -1
  85. package/src/cli/observe.ts +10 -2
  86. package/src/cli/provider.ts +12 -0
  87. package/src/cli/registry.ts +20 -7
  88. package/src/cli/restart-scope.ts +3 -1
  89. package/src/cli/runtime-api.ts +27 -2
  90. package/src/cli/status.ts +104 -20
  91. package/src/client/connect.ts +39 -4
  92. package/src/client/hub-client.ts +14 -7
  93. package/src/client/hub-state.ts +25 -14
  94. package/src/client/link-home.ts +248 -0
  95. package/src/client/link-management-relay.ts +61 -0
  96. package/src/client/link-relay.ts +6 -1
  97. package/src/client/link-status.ts +14 -0
  98. package/src/client/machine-api.ts +14 -7
  99. package/src/client/machine-listener.ts +29 -4
  100. package/src/clients/config-export/contracts.ts +1 -0
  101. package/src/clients/config-export/model-metadata.ts +3 -2
  102. package/src/clients/config-export/qoder.ts +93 -0
  103. package/src/clients/config-export.ts +59 -16
  104. package/src/clients/omo-role-models.ts +6 -3
  105. package/src/codex/agent-role-models.ts +26 -8
  106. package/src/codex/auth-api/account-list.ts +17 -2
  107. package/src/codex/auth-api/account-selection.ts +17 -7
  108. package/src/codex/auth-api/pool-mode-gate.ts +5 -2
  109. package/src/codex/auth-api/routes.ts +5 -1
  110. package/src/codex/auth-context.ts +79 -5
  111. package/src/codex/autostart-health.ts +7 -1
  112. package/src/codex/catalog/build-entries.ts +11 -2
  113. package/src/codex/catalog/bundled.ts +5 -1
  114. package/src/codex/catalog/configured-tiers.ts +50 -0
  115. package/src/codex/catalog/effort.ts +6 -3
  116. package/src/codex/catalog/metadata.ts +4 -2
  117. package/src/codex/catalog/model-hints.ts +21 -3
  118. package/src/codex/catalog/native-models.ts +16 -2
  119. package/src/codex/catalog/native-ultrafast.ts +106 -0
  120. package/src/codex/catalog/parsing.ts +5 -0
  121. package/src/codex/catalog/provider-models.ts +4 -0
  122. package/src/codex/catalog/retained-sync.ts +2 -0
  123. package/src/codex/catalog/routed-gather.ts +22 -4
  124. package/src/codex/catalog/vendor-context.ts +82 -0
  125. package/src/codex/config-write-lock.ts +40 -2
  126. package/src/codex/convergence.ts +2 -0
  127. package/src/codex/desktop-app/types.ts +2 -0
  128. package/src/codex/desktop-app/windows.ts +29 -16
  129. package/src/codex/desktop-app-restart.ts +4 -2
  130. package/src/codex/desktop-compatibility/certificate-service.ts +99 -0
  131. package/src/codex/desktop-compatibility/certificate-store.ts +193 -0
  132. package/src/codex/desktop-compatibility/connection-store.ts +87 -0
  133. package/src/codex/desktop-compatibility/installed-build.ts +55 -0
  134. package/src/codex/desktop-compatibility/json-body.ts +29 -0
  135. package/src/codex/desktop-compatibility/native-identity.ts +62 -0
  136. package/src/codex/desktop-compatibility/relay-listener.ts +93 -0
  137. package/src/codex/desktop-compatibility/routing-binding.ts +10 -0
  138. package/src/codex/desktop-compatibility/routing-preflight.ts +69 -0
  139. package/src/codex/desktop-compatibility/runtime-ownership.ts +28 -0
  140. package/src/codex/desktop-compatibility/runtime.ts +173 -0
  141. package/src/codex/desktop-compatibility/service.ts +30 -0
  142. package/src/codex/desktop-compatibility/startup-settings.ts +50 -0
  143. package/src/codex/desktop-compatibility/usage-activation.ts +86 -0
  144. package/src/codex/desktop-compatibility/usage-controlled-fetch.ts +59 -0
  145. package/src/codex/desktop-compatibility/usage-controller.ts +107 -0
  146. package/src/codex/desktop-compatibility/usage-policy.ts +59 -0
  147. package/src/codex/desktop-compatibility/usage-refresh.ts +33 -0
  148. package/src/codex/desktop-compatibility/usage-sse-controller.ts +86 -0
  149. package/src/codex/desktop-compatibility/windows-activation-source.ts +44 -0
  150. package/src/codex/desktop-compatibility/windows-certificate-trust.ts +81 -0
  151. package/src/codex/desktop-compatibility/windows-key-protection.ts +59 -0
  152. package/src/codex/desktop-compatibility/windows-package-command.ts +86 -0
  153. package/src/codex/desktop-compatibility/windows-package-launch.ts +28 -0
  154. package/src/codex/history-provider.ts +1 -1
  155. package/src/codex/inject/config-write-section.ts +4 -1
  156. package/src/codex/inject/remove.ts +18 -6
  157. package/src/codex/journal.ts +16 -1
  158. package/src/codex/main-account.ts +99 -15
  159. package/src/codex/native-main-refresh-mode.ts +217 -0
  160. package/src/codex/native-profile-startup.ts +4 -1
  161. package/src/codex/prompt-journal.ts +20 -2
  162. package/src/codex/prompt-layers/encoding.ts +49 -0
  163. package/src/codex/prompt-layers/import-source.ts +30 -0
  164. package/src/codex/prompt-layers/toml-edit.ts +269 -37
  165. package/src/codex/prompt-layers/toml-read.ts +52 -4
  166. package/src/codex/prompt-layers.ts +383 -20
  167. package/src/codex/prompt-lock-claim.ts +13 -3
  168. package/src/codex/prompt-lock-evidence.ts +3 -3
  169. package/src/codex/prompt-lock-owner.ts +14 -6
  170. package/src/codex/prompt-text-probe.ts +34 -5
  171. package/src/codex/quota.ts +13 -6
  172. package/src/codex/role-auto-assign.ts +2 -5
  173. package/src/codex/routing/active-account.ts +21 -0
  174. package/src/codex/routing/health-store.ts +1 -1
  175. package/src/codex/routing/pool-recovery.ts +79 -0
  176. package/src/codex/routing.ts +1 -1
  177. package/src/codex/runtime.ts +196 -8
  178. package/src/codex/shim-diagnostics.ts +6 -0
  179. package/src/codex/shim-overlay.ts +15 -6
  180. package/src/codex/shim.ts +1 -1
  181. package/src/combos/failover.ts +3 -0
  182. package/src/config/api-key-reconcile.ts +34 -0
  183. package/src/config/diagnostics.ts +18 -1
  184. package/src/config/feature-flags.ts +5 -0
  185. package/src/config/live-reconcile.ts +56 -29
  186. package/src/config/live-topology.ts +29 -0
  187. package/src/config/load-degrade.ts +8 -2
  188. package/src/config/paths.ts +13 -3
  189. package/src/config/salvage.ts +3 -1
  190. package/src/config/schema/config-schema.ts +19 -0
  191. package/src/config/schema/desktop-compatibility.ts +9 -0
  192. package/src/config/schema/leaf-validators.ts +1 -0
  193. package/src/generated/compatibility-version.json +713 -285
  194. package/src/generated/model-metadata.ts +1 -1
  195. package/src/grok/grpc-web.ts +23 -1
  196. package/src/grok/reset-coupon-ledger.ts +75 -5
  197. package/src/grok/reset-coupons.ts +4 -2
  198. package/src/integrations/catalog-refresh.ts +1 -1
  199. package/src/integrations/config-io.ts +20 -2
  200. package/src/integrations/journal.ts +15 -1
  201. package/src/integrations/mutation-plan.ts +14 -7
  202. package/src/integrations/registry.ts +52 -11
  203. package/src/integrations/state.ts +19 -7
  204. package/src/integrations/store.ts +3 -0
  205. package/src/integrations/target.ts +42 -5
  206. package/src/integrations/writer.ts +24 -7
  207. package/src/lib/advisor-activation.ts +16 -0
  208. package/src/lib/app-owned-memory-stores.ts +4 -0
  209. package/src/lib/app-owned-memory.ts +11 -0
  210. package/src/lib/background-work.ts +65 -0
  211. package/src/lib/bounded-file-read.ts +58 -0
  212. package/src/lib/bun-path-runtime.d.mts +10 -1
  213. package/src/lib/bun-path-runtime.mjs +62 -3
  214. package/src/lib/desktop-proxy-route.ts +30 -0
  215. package/src/lib/desktop-upstream-tunnel.ts +107 -0
  216. package/src/lib/errors.ts +7 -0
  217. package/src/lib/json-byte-size.ts +31 -0
  218. package/src/lib/local-internal-call-capability.ts +55 -0
  219. package/src/lib/optional-shutdown-hooks.ts +35 -0
  220. package/src/lib/outbound-credential-registry.ts +210 -0
  221. package/src/lib/package-tree-integrity.ts +2 -2
  222. package/src/lib/passive-read.ts +35 -0
  223. package/src/lib/shadow-call.ts +44 -5
  224. package/src/lib/socks5-fetch.ts +48 -71
  225. package/src/lib/socks5-handshake.ts +112 -0
  226. package/src/lib/translator-budget.ts +7 -1
  227. package/src/link/codex-settings.ts +155 -0
  228. package/src/link/management-routes.ts +89 -0
  229. package/src/link/remote-probe.ts +38 -0
  230. package/src/link/ssh-argv.ts +26 -5
  231. package/src/link/ssh-runner.ts +58 -27
  232. package/src/link/status-projection.ts +22 -4
  233. package/src/link/supervisor.ts +144 -49
  234. package/src/link/tunnel-state.ts +11 -4
  235. package/src/oauth/anthropic-continuity.ts +4 -3
  236. package/src/oauth/anthropic-identity.ts +13 -2
  237. package/src/oauth/anthropic-model-quota.ts +13 -1
  238. package/src/oauth/anthropic-routing.ts +230 -23
  239. package/src/oauth/anthropic.ts +18 -4
  240. package/src/oauth/generic-account-failover.ts +29 -5
  241. package/src/oauth/google-antigravity.ts +24 -7
  242. package/src/oauth/index.ts +28 -17
  243. package/src/oauth/kiro-account-identity.ts +106 -0
  244. package/src/oauth/kiro-device-login.ts +2 -1
  245. package/src/oauth/kiro.ts +55 -6
  246. package/src/oauth/plan.ts +29 -0
  247. package/src/oauth/store.ts +40 -3
  248. package/src/oauth/types.ts +2 -0
  249. package/src/plugins/loader.ts +11 -0
  250. package/src/protocols/codecs/chat-ir.ts +467 -0
  251. package/src/protocols/codecs/chat.ts +10 -1
  252. package/src/protocols/codecs/messages-ir.ts +500 -0
  253. package/src/protocols/features.ts +10 -2
  254. package/src/protocols/path.ts +11 -1
  255. package/src/protocols/plan-snapshot.ts +39 -16
  256. package/src/protocols/plan.ts +9 -1
  257. package/src/protocols/settings.ts +8 -0
  258. package/src/providers/anthropic-billing-ownership.ts +74 -0
  259. package/src/providers/anthropic-billing-recovery.ts +31 -0
  260. package/src/providers/anthropic-billing-refusal.ts +55 -0
  261. package/src/providers/anthropic-reset-admission.ts +62 -0
  262. package/src/providers/anthropic-reset-grant-ledger.ts +28 -6
  263. package/src/providers/antigravity-account-roster.ts +102 -0
  264. package/src/providers/antigravity-models.ts +85 -7
  265. package/src/providers/api-key-resolve.ts +17 -2
  266. package/src/providers/key-failover.ts +52 -5
  267. package/src/providers/model-rename-fields.ts +2 -0
  268. package/src/providers/model-rename-migration.ts +5 -3
  269. package/src/providers/model-rename-startup.ts +5 -3
  270. package/src/providers/quota/account-cache.ts +11 -0
  271. package/src/providers/quota/anthropic-account-quota.ts +4 -2
  272. package/src/providers/quota/report-cache.ts +14 -0
  273. package/src/providers/quota/vendor-probes-oauth.ts +3 -3
  274. package/src/providers/quota.ts +4 -1
  275. package/src/providers/registry/entries-core.ts +21 -20
  276. package/src/providers/registry/entries-extended.ts +19 -1
  277. package/src/providers/registry/model-seeds.ts +17 -0
  278. package/src/providers/request-pacing.ts +9 -0
  279. package/src/providers/stale-no-vision-seed-migration.ts +72 -0
  280. package/src/responses/compaction.ts +14 -0
  281. package/src/responses/parser.ts +37 -20
  282. package/src/responses/state.ts +32 -29
  283. package/src/routing/history/build-file.ts +92 -0
  284. package/src/routing/history/indexer.ts +248 -216
  285. package/src/routing/history/ingest.ts +238 -0
  286. package/src/routing/history/rebuild-job.ts +111 -0
  287. package/src/routing/history/rebuild-protocol.ts +15 -0
  288. package/src/routing/history/rebuild-worker.ts +34 -0
  289. package/src/server/admission-model-scope.ts +4 -1
  290. package/src/server/antigravity-direct-eligibility.ts +208 -0
  291. package/src/server/auth-cors.ts +46 -0
  292. package/src/server/chat-completions.ts +75 -9
  293. package/src/server/claude-messages.ts +110 -20
  294. package/src/server/configured-credentials.ts +194 -0
  295. package/src/server/index/desktop-compatibility-startup.ts +56 -0
  296. package/src/server/index/link-management.ts +58 -0
  297. package/src/server/index/optional-listeners.ts +5 -1
  298. package/src/server/index/serve-options.ts +15 -2
  299. package/src/server/index/startup-warnings.ts +9 -0
  300. package/src/server/index/websocket-handler.ts +9 -0
  301. package/src/server/index.ts +13 -10
  302. package/src/server/inference/client-encoder-delivery.ts +6 -5
  303. package/src/server/lifecycle.ts +2 -1
  304. package/src/server/login-shell-path.ts +146 -0
  305. package/src/server/management/advisor-routes.ts +191 -0
  306. package/src/server/management/agent-settings-routes.ts +50 -14
  307. package/src/server/management/anthropic-reset-grant-routes.ts +17 -1
  308. package/src/server/management/codex-agent-role-routes.ts +19 -6
  309. package/src/server/management/codex-prompt-routes.ts +136 -5
  310. package/src/server/management/codex-role-auto-assign.ts +1 -1
  311. package/src/server/management/companion-routes.ts +4 -0
  312. package/src/server/management/config-routes.ts +2 -2
  313. package/src/server/management/context.ts +4 -0
  314. package/src/server/management/desktop-compatibility-routes.ts +46 -0
  315. package/src/server/management/desktop-compatibility-runtime-routes.ts +46 -0
  316. package/src/server/management/desktop-compatibility-settings-routes.ts +27 -0
  317. package/src/server/management/grok-coupon-routes.ts +78 -27
  318. package/src/server/management/link-enrollment.ts +192 -0
  319. package/src/server/management/link-route-state.ts +185 -0
  320. package/src/server/management/link-routes.ts +82 -402
  321. package/src/server/management/model-routes.ts +2 -2
  322. package/src/server/management/model-rows.ts +3 -1
  323. package/src/server/management/protocol-settings-patch.ts +1 -0
  324. package/src/server/management/provider-overwrite-carry.ts +10 -0
  325. package/src/server/management/provider-routes.ts +1 -0
  326. package/src/server/management/route-registry.ts +16 -3
  327. package/src/server/management/shared.ts +3 -0
  328. package/src/server/management/sibling-guard.ts +1 -0
  329. package/src/server/management-api.ts +9 -1
  330. package/src/server/messages-antigravity-direct.ts +195 -0
  331. package/src/server/messages-native.ts +73 -43
  332. package/src/server/relay-eager.ts +2 -0
  333. package/src/server/request-log-filter.ts +6 -1
  334. package/src/server/request-log-terminal-status.ts +63 -6
  335. package/src/server/request-log.ts +7 -0
  336. package/src/server/responses/adapter-continuation.ts +35 -18
  337. package/src/server/responses/adapter-delivery.ts +24 -2
  338. package/src/server/responses/adapter-dispatch.ts +261 -81
  339. package/src/server/responses/advisor-plan-slot.ts +27 -0
  340. package/src/server/responses/advisor-slot.ts +336 -0
  341. package/src/server/responses/code-mode-collab-surface.ts +313 -0
  342. package/src/server/responses/codex-ws-exchange.ts +147 -6
  343. package/src/server/responses/codex-ws-wire.ts +203 -0
  344. package/src/server/responses/collaboration.ts +36 -7
  345. package/src/server/responses/compact.ts +126 -48
  346. package/src/server/responses/context-overflow.ts +13 -1
  347. package/src/server/responses/core-codex-account.ts +105 -1
  348. package/src/server/responses/core-combo-failure.ts +24 -1
  349. package/src/server/responses/core-combo.ts +28 -2
  350. package/src/server/responses/core-errors.ts +29 -1
  351. package/src/server/responses/core-lifetime.ts +2 -0
  352. package/src/server/responses/core-normalize.ts +11 -0
  353. package/src/server/responses/core-options.ts +48 -0
  354. package/src/server/responses/core-replay.ts +7 -4
  355. package/src/server/responses/core.ts +1 -1
  356. package/src/server/responses/deferred-collab-surface.ts +158 -0
  357. package/src/server/responses/deferred-send-reporter.ts +25 -0
  358. package/src/server/responses/fetch-helpers.ts +12 -1
  359. package/src/server/responses/passthrough-delivery.ts +20 -11
  360. package/src/server/responses/passthrough-dispatch.ts +29 -7
  361. package/src/server/responses/request-prepare.ts +74 -9
  362. package/src/server/responses/request-transport.ts +22 -8
  363. package/src/server/responses/run-turn-execution.ts +70 -8
  364. package/src/server/responses/sidecar-execution.ts +89 -5
  365. package/src/server/responses/terminal-guard.ts +2 -1
  366. package/src/server/responses/ws-upstream.ts +9 -1
  367. package/src/server/responses-undeclared-tool-guard.ts +30 -9
  368. package/src/server/startup-action-control.ts +38 -4
  369. package/src/server/startup-health-cache.ts +5 -0
  370. package/src/server/system-env-shell.ts +7 -2
  371. package/src/server/system-env.ts +11 -1
  372. package/src/service/cli.ts +5 -1
  373. package/src/service/desktop-startup.ts +161 -34
  374. package/src/service/desktop-supervision.d.mts +27 -1
  375. package/src/service/desktop-supervision.mjs +111 -5
  376. package/src/service/health-sentinel-launch.ts +176 -0
  377. package/src/service/health-sentinel-main.ts +466 -0
  378. package/src/service/health-sentinel-policy.ts +241 -0
  379. package/src/service/health-sentinel-probe.ts +71 -0
  380. package/src/service/health-sentinel-windows.ts +87 -0
  381. package/src/service/linux-linger.ts +20 -0
  382. package/src/service/logging.ts +72 -0
  383. package/src/tray/windows-tray.ps1 +43 -24
  384. package/src/types/config.ts +68 -6
  385. package/src/types/provider.ts +7 -0
  386. package/src/types/request.ts +15 -0
  387. package/src/types/tools.ts +2 -0
  388. package/src/update/async-check.ts +1 -1
  389. package/src/update/badge.ts +2 -2
  390. package/src/update/index.ts +88 -15
  391. package/src/update/job-supervised-restart.ts +107 -0
  392. package/src/update/job.ts +32 -32
  393. package/src/update/notify.ts +1 -1
  394. package/src/update/refresh-scheduler.ts +2 -2
  395. package/src/update/supervised-recovery.d.mts +27 -0
  396. package/src/update/supervised-recovery.mjs +157 -0
  397. package/src/usage/cache-diagnostic.ts +2 -0
  398. package/src/usage/expected-prices.ts +16 -0
  399. package/src/usage/log.ts +19 -1
  400. package/src/web-search/gemini-executor.ts +2 -2
  401. package/assets/sponsors/packycode.png +0 -0
  402. package/gui/dist/assets/App-Ba8uG696.js +0 -54
  403. package/gui/dist/assets/Tray-IImbNPRy.js +0 -1
  404. package/gui/dist/assets/index-BHRZdJuv.js +0 -94
  405. package/gui/dist/assets/quota-summary-DiJO6sYY.js +0 -1
@@ -0,0 +1,305 @@
1
+ /**
2
+ * The advisor request plan: what the optional subsystem registers into the core Responses path.
3
+ *
4
+ * Created PER REQUEST through the activated factory called by the sidecar planner — never
5
+ * at module load and never globally. All mutable state is request-scoped except the bounded
6
+ * task-scoped preflight ledger (src/advisor/state.ts).
7
+ *
8
+ * Responsibilities:
9
+ * - decide whether the advisor applies to this request (settings + capability of the path);
10
+ * - preflight: one automatic consultation ATTEMPT per task when the orientation evidence exists,
11
+ * claimed atomically in the ledger and injected as user-role advisory data;
12
+ * - manual: back the synthetic `advisor` tool guard with real consultations through the routing
13
+ * authority (loopback chat completion);
14
+ * - observability: one structured log line per consultation — proof that the advisor actually
15
+ * ran (worker model, advisor model, trigger, duration, status, usage).
16
+ *
17
+ * Preflight injection transport: the runtime-owned instruction is fixed developer policy;
18
+ * all Advisor-generated bytes are a separate JSON-quoted user-role advisory message. Manual
19
+ * consultations remain paired tool results. No automatic path fabricates a tool call or
20
+ * places Advisor output in developer/system content. User-role advice can still contain
21
+ * hostile recommendations; the fixed policy tells the worker how to interpret that data.
22
+ */
23
+ import type { OcxConfig, OcxParsedRequest } from "../types";
24
+ import type { AdvisorPlan, AdvisorConsultOutcome } from "../server/responses/advisor-slot";
25
+ import { createAdvisorGuard } from "../server/responses/advisor-slot";
26
+ import { resolveAdvisorSettings } from "./settings";
27
+ import { consultAdvisor } from "./consult";
28
+ import { buildAdvisorTool } from "./synthetic-tool";
29
+ import { sanitizeLogMetadataString } from "../lib/redact";
30
+ import {
31
+ advisorLedgerKey,
32
+ createAdvisorPreflightLedger,
33
+ hasOrientationEvidence,
34
+ historyHasManualAdvisorResult,
35
+ type AdvisorPreflightLedger,
36
+ } from "./state";
37
+ import { formatAdvisorAdvice, advisorPreflightMessages, formatAdvisorUnavailable } from "./context";
38
+
39
+ /**
40
+ * Process-local task ledger. Bounded (entries + per-state TTL) in src/advisor/state.ts; one
41
+ * instance per process so the claim is atomic across concurrent requests. Not durable by design
42
+ * — see the documented restart limitation.
43
+ */
44
+ const sharedPreflightLedger = createAdvisorPreflightLedger();
45
+
46
+ export const ADVISOR_SHARED_LEDGER = sharedPreflightLedger;
47
+
48
+ export interface AdvisorRuntimeDeps {
49
+ config: Pick<OcxConfig, "advisor" | "port" | "hostname" | "apiKeys" | "unauthenticatedLoopbackListener">;
50
+ /** Routed worker identity for logs and the advisor payload, e.g. "deepseek-chat (provider deepseek)". */
51
+ workerIdentity: string;
52
+ workerModelId: string;
53
+ abortSignal?: AbortSignal;
54
+ /** Test seam; production always self-fetches the resolved local destination. */
55
+ baseUrlOverride?: string;
56
+ /** Test seam; production uses the process-wide ledger. */
57
+ ledger?: AdvisorPreflightLedger;
58
+ /** Deterministic clock seam for the ledger's TTL/cooldown arithmetic (tests only). */
59
+ now?: () => number;
60
+ /**
61
+ * Test seam: runs after a preflight claim is taken and before the consultation
62
+ * dispatch, so a test can revoke consent in the claim-to-outbound window.
63
+ */
64
+ afterPreflightClaim?: () => void;
65
+ }
66
+
67
+ export interface AdvisorRuntimePlan extends AdvisorPlan {
68
+ readonly policy: "manual" | "preflight";
69
+ readonly toolEnabled: boolean;
70
+ readonly tool: import("../types").OcxTool;
71
+ /**
72
+ * The automatic preflight pass. Returns true when advice was injected. A cancelled
73
+ * consultation injects nothing and leaves the task eligible for a later attempt.
74
+ */
75
+ preflightInject(parsed: OcxParsedRequest): Promise<boolean>;
76
+ /** Attach the stream guard for the synthetic tool to the parsed request. */
77
+ attachGuard(parsed: OcxParsedRequest): void;
78
+ }
79
+
80
+ export function createAdvisorRuntimePlan(deps: AdvisorRuntimeDeps): AdvisorRuntimePlan | null {
81
+ const initial = resolveAdvisorSettings(deps.config);
82
+ // A model is required before the synthetic tool exists. Consent is checked at every
83
+ // consultation against the live config, so an enabled advisor without current consent can
84
+ // still refuse a manual call in-band without sending task context. Disabled, or enabled
85
+ // with no model, stays off the path.
86
+ if (!initial.enabled || initial.model.trim() === "") return null;
87
+ const ledger = deps.ledger ?? sharedPreflightLedger;
88
+ const now = deps.now ?? (() => Date.now());
89
+ // Management PUT mutates this same config object (`config.advisor = ...`). Re-resolving
90
+ // at dispatch is what makes a mid-request consent revocation stop outbound transfer.
91
+ const liveSettings = () => resolveAdvisorSettings(deps.config);
92
+
93
+ // Request-scoped state: born here, dies with the request. Never global.
94
+ const fingerprints = new Set<string>();
95
+ let preflightUsed = false;
96
+
97
+ const taskKey = (parsed: OcxParsedRequest): string | undefined =>
98
+ advisorLedgerKey(parsed, deps.workerModelId);
99
+
100
+ const logConsultation = (
101
+ trigger: "manual" | "preflight",
102
+ outcome: { ok: boolean; cancelled?: boolean; durationMs: number; error?: string; usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number } },
103
+ advisorModel: string,
104
+ ): void => {
105
+ const usage = outcome.usage
106
+ ? ` usage=in=${outcome.usage.inputTokens ?? "?"} out=${outcome.usage.outputTokens ?? "?"}`
107
+ : "";
108
+ const status = outcome.ok ? "ok" : outcome.cancelled ? "cancelled" : "failed";
109
+ const errorNote = outcome.ok || outcome.cancelled
110
+ ? ""
111
+ : ` error=${sanitizeLogMetadataString(outcome.error ?? "unknown", 160) ?? "unknown"}`;
112
+ // One structured line per consultation: model ids, timing, and a bounded status. No prompt,
113
+ // no tool output, no capability.
114
+ console.warn(
115
+ `[advisor] consultation ${status} trigger=${trigger} worker=${deps.workerModelId}`
116
+ + ` advisor=${advisorModel} durationMs=${outcome.durationMs}${usage}${errorNote}`,
117
+ );
118
+ };
119
+
120
+ const runConsultation = async (
121
+ parsed: OcxParsedRequest,
122
+ reason: "manual" | "preflight",
123
+ question: string | undefined,
124
+ ): Promise<AdvisorConsultOutcome> => {
125
+ const current = liveSettings();
126
+ if (!current.enabled || current.model.trim() === "") {
127
+ return {
128
+ ok: false,
129
+ isError: true,
130
+ blocked: "settings",
131
+ content: formatAdvisorUnavailable(
132
+ reason === "preflight" ? "preflight" : "manual",
133
+ "advisor is not configured",
134
+ ),
135
+ };
136
+ }
137
+ // Consent is operator config. Task text, the worker, and the advisor cannot grant it.
138
+ // The live object is re-read here so a revocation after plan creation still blocks
139
+ // outbound transfer. No fingerprint, no ledger write, no fetch.
140
+ if (current.contextSharingConsent === null) {
141
+ console.warn(
142
+ `[advisor] consultation blocked trigger=${reason} reason=advisor_context_sharing_consent_required`,
143
+ );
144
+ return {
145
+ ok: false,
146
+ isError: true,
147
+ blocked: "consent",
148
+ content: formatAdvisorUnavailable(
149
+ "consent",
150
+ "advisor_context_sharing_consent_required",
151
+ ),
152
+ };
153
+ }
154
+ // Same-consultation dedup within this request: identical trigger + focus returns a
155
+ // non-advice outcome instead of a second expert call.
156
+ const fingerprint = `${reason}|${question ?? ""}`;
157
+ let result;
158
+ if (fingerprints.has(fingerprint)) {
159
+ result = {
160
+ ok: false,
161
+ advice: "",
162
+ advisorModel: current.model,
163
+ error: "duplicate consultation request (already consulted with this focus in this request)",
164
+ durationMs: 0,
165
+ };
166
+ return {
167
+ ok: false,
168
+ isError: true,
169
+ content: formatAdvisorUnavailable(reason === "preflight" ? "preflight" : "manual", result.error),
170
+ };
171
+ }
172
+ fingerprints.add(fingerprint);
173
+ result = await consultAdvisor(
174
+ {
175
+ parsed,
176
+ workerIdentity: deps.workerIdentity,
177
+ advisorModel: current.model,
178
+ reason,
179
+ ...(question !== undefined ? { question } : {}),
180
+ },
181
+ deps.config,
182
+ current.effort,
183
+ current.timeoutMs,
184
+ deps.abortSignal,
185
+ deps.baseUrlOverride,
186
+ );
187
+ logConsultation(reason, result, current.model);
188
+
189
+ if (result.ok) {
190
+ // A genuine result suppresses further automatic consultation for the task. Manual success
191
+ // settles it too: a task the worker already had advised does not need a preflight attempt.
192
+ if (reason === "manual") {
193
+ const key = taskKey(parsed);
194
+ // A manual consultation owns no preflight claim; this records the FACT that the task was
195
+ // advised, which is true whichever consultation produced the advice.
196
+ if (key) ledger.markAdvised(key, now());
197
+ }
198
+ return {
199
+ ok: true,
200
+ isError: false,
201
+ content: formatAdvisorAdvice({
202
+ advisorModel: result.advisorModel,
203
+ reason,
204
+ advice: result.advice,
205
+ channel: reason === "preflight" ? "preflight" : "manual",
206
+ }),
207
+ };
208
+ }
209
+ return {
210
+ ok: false,
211
+ isError: true,
212
+ ...(result.cancelled ? { cancelled: true } : {}),
213
+ content: formatAdvisorUnavailable(reason === "preflight" ? "preflight" : "manual", result.error ?? "unavailable"),
214
+ };
215
+ };
216
+
217
+ const preflightInject = async (parsed: OcxParsedRequest): Promise<boolean> => {
218
+ const current = liveSettings();
219
+ if (current.policy !== "preflight" || preflightUsed) return false;
220
+ // No consent, disabled, or no model: do not claim, do not inject, do not send task context.
221
+ if (!current.enabled || current.model.trim() === "" || current.contextSharingConsent === null) return false;
222
+ // A genuine MANUAL consultation already advised this task (verifiable tool-result
223
+ // provenance), or the task has no orientation evidence yet: skip.
224
+ if (historyHasManualAdvisorResult(parsed)) return false;
225
+ if (!hasOrientationEvidence(parsed)) return false;
226
+
227
+ // Atomic claim. A client with a stable conversation identity participates in the
228
+ // process-global ledger, so concurrent requests for one task consult at most once and a
229
+ // settled task is not re-consulted. A client with NO stable identity stays out of the
230
+ // ledger on purpose: request-scoped dedup plus genuine in-history provenance are the only
231
+ // suppression it gets — fail-open, so two independent identity-less conversations can never
232
+ // suppress each other through a shared guess.
233
+ const key = taskKey(parsed);
234
+ let claimToken: string | undefined;
235
+ if (key) {
236
+ const claim = ledger.claim(key, now());
237
+ if (claim.state !== "claimed") return false;
238
+ claimToken = claim.token;
239
+ }
240
+ preflightUsed = true;
241
+ deps.afterPreflightClaim?.();
242
+
243
+ let outcome: AdvisorConsultOutcome;
244
+ try {
245
+ outcome = await runConsultation(parsed, "preflight", undefined);
246
+ } catch (error) {
247
+ if (key && claimToken) ledger.fail(key, claimToken, now());
248
+ console.warn(`[advisor] consultation failed trigger=preflight worker=${deps.workerModelId} error=plan_threw`);
249
+ parsed.context.messages = [
250
+ ...parsed.context.messages,
251
+ {
252
+ role: "user",
253
+ content: "An automatic advisor consultation could not be completed. Continue with your own judgment.",
254
+ timestamp: Date.now(),
255
+ },
256
+ ];
257
+ void error;
258
+ return false;
259
+ }
260
+
261
+ if (outcome.blocked) {
262
+ // Operator revoked consent (or disabled the sidecar) after the claim: not a provider
263
+ // failure. Release so the task is not put on cooldown and nothing is injected.
264
+ if (key && claimToken) ledger.release(key, claimToken, now());
265
+ return false;
266
+ }
267
+ if (outcome.ok) {
268
+ if (key && claimToken) ledger.complete(key, claimToken, now());
269
+ } else if (outcome.cancelled) {
270
+ // Client cancellation is not a provider failure: no cooldown, the task may retry later.
271
+ if (key && claimToken) ledger.release(key, claimToken, now());
272
+ // Nothing to inject — the caller is gone or aborting; do not add noise to a live turn.
273
+ return false;
274
+ } else {
275
+ if (key && claimToken) ledger.fail(key, claimToken, now());
276
+ }
277
+
278
+ parsed.context.messages = [
279
+ ...parsed.context.messages,
280
+ ...advisorPreflightMessages(outcome.content),
281
+ ];
282
+ return outcome.ok;
283
+ };
284
+
285
+ const plan: AdvisorPlan = {
286
+ consult: (parsed, reason, question) => runConsultation(parsed, reason, question),
287
+ // The guard's own failure/limit text goes through the same runtime-owned, marker-neutralized
288
+ // formatter so no guard path can emit text that looks like a genuine advice wrapper.
289
+ formatUnavailable: (kind, error) => formatAdvisorUnavailable(kind, error),
290
+ };
291
+
292
+ return {
293
+ policy: initial.policy,
294
+ // The synthetic tool is only safe where the guard can intercept: run-turn adapters own their
295
+ // own loops, so they get preflight support but never the tool (documented limitation).
296
+ toolEnabled: initial.enabled,
297
+ tool: buildAdvisorTool(),
298
+ consult: plan.consult,
299
+ formatUnavailable: plan.formatUnavailable,
300
+ preflightInject,
301
+ attachGuard: parsed => {
302
+ parsed._advisorGuard = createAdvisorGuard(plan);
303
+ },
304
+ };
305
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * The single reader of `advisor` config.
3
+ *
4
+ * Nothing else reads the `advisor` key directly: the sidecar planner, the management API and the
5
+ * CLI all resolve through here, so they cannot disagree about defaults or validity. Type-only
6
+ * config import keeps this module free of runtime edges.
7
+ */
8
+ import type { OcxConfig } from "../types";
9
+ import { ADVISOR_CONTEXT_SHARING_CONSENT_VERSION } from "./disclosure";
10
+
11
+ export { ADVISOR_CONTEXT_SHARING_CONSENT_VERSION };
12
+
13
+ export type AdvisorPolicy = "manual" | "preflight";
14
+
15
+ export const ADVISOR_EFFORTS = ["low", "medium", "high", "xhigh", "max", "ultra"] as const;
16
+ export type AdvisorEffort = (typeof ADVISOR_EFFORTS)[number];
17
+
18
+ export const ADVISOR_POLICIES = ["manual", "preflight"] as const;
19
+
20
+ export interface AdvisorSettings {
21
+ enabled: boolean;
22
+ model: string;
23
+ effort: AdvisorEffort;
24
+ policy: AdvisorPolicy;
25
+ timeoutMs: number;
26
+ /**
27
+ * Current context-sharing consent, or null when absent, stale, or malformed.
28
+ * `enabled` does not imply this. Only the current version allows data transfer.
29
+ */
30
+ contextSharingConsent: typeof ADVISOR_CONTEXT_SHARING_CONSENT_VERSION | null;
31
+ /** Where each resolved value came from, so the GUI/CLI can show real runtime state. */
32
+ sources: {
33
+ enabled: "default" | "configured";
34
+ model: "default" | "configured";
35
+ effort: "default" | "configured";
36
+ policy: "default" | "configured";
37
+ contextSharingConsent: "default" | "configured";
38
+ };
39
+ }
40
+
41
+ export const DEFAULT_ADVISOR_SETTINGS: Readonly<AdvisorSettings> = Object.freeze({
42
+ enabled: false,
43
+ model: "",
44
+ effort: "max",
45
+ policy: "manual",
46
+ timeoutMs: 120_000,
47
+ contextSharingConsent: null,
48
+ sources: Object.freeze({
49
+ enabled: "default",
50
+ model: "default",
51
+ effort: "default",
52
+ policy: "default",
53
+ contextSharingConsent: "default",
54
+ }),
55
+ });
56
+
57
+ type Rec = Record<string, unknown>;
58
+ function isRec(value: unknown): value is Rec {
59
+ return !!value && typeof value === "object" && !Array.isArray(value);
60
+ }
61
+
62
+ export function isValidAdvisorEffort(value: unknown): value is AdvisorEffort {
63
+ return typeof value === "string" && (ADVISOR_EFFORTS as readonly string[]).includes(value);
64
+ }
65
+
66
+ export function isValidAdvisorPolicy(value: unknown): value is AdvisorPolicy {
67
+ return typeof value === "string" && (ADVISOR_POLICIES as readonly string[]).includes(value);
68
+ }
69
+
70
+ /** True only for the current context-sharing consent version. Anything else is not a grant. */
71
+ export function isCurrentAdvisorContextSharingConsent(
72
+ value: unknown,
73
+ ): value is typeof ADVISOR_CONTEXT_SHARING_CONSENT_VERSION {
74
+ return value === ADVISOR_CONTEXT_SHARING_CONSENT_VERSION;
75
+ }
76
+
77
+ /**
78
+ * Resolve advisor settings with conservative defaults for every absent or malformed field.
79
+ * A malformed block resolves to fully disabled defaults rather than throwing: the advisor is
80
+ * optional and must never take the request path down with it.
81
+ */
82
+ export function resolveAdvisorSettings(config: Pick<OcxConfig, "advisor">): AdvisorSettings {
83
+ const raw: unknown = config.advisor;
84
+ if (!isRec(raw)) return { ...DEFAULT_ADVISOR_SETTINGS, sources: { ...DEFAULT_ADVISOR_SETTINGS.sources } };
85
+ const enabled = typeof raw.enabled === "boolean" ? raw.enabled : DEFAULT_ADVISOR_SETTINGS.enabled;
86
+ const model = typeof raw.model === "string" ? raw.model.trim() : DEFAULT_ADVISOR_SETTINGS.model;
87
+ const effort = isValidAdvisorEffort(raw.effort) ? raw.effort : DEFAULT_ADVISOR_SETTINGS.effort;
88
+ const policy = isValidAdvisorPolicy(raw.policy) ? raw.policy : DEFAULT_ADVISOR_SETTINGS.policy;
89
+ const timeoutRaw = raw.timeoutMs;
90
+ const timeoutMs = typeof timeoutRaw === "number" && Number.isFinite(timeoutRaw) && timeoutRaw >= 1_000
91
+ ? Math.min(Math.floor(timeoutRaw), 600_000)
92
+ : DEFAULT_ADVISOR_SETTINGS.timeoutMs;
93
+ // A present but non-current value (stale version, wrong type) resolves as no consent.
94
+ // The stored bytes are left untouched; this reader never writes an upgrade.
95
+ const consentConfigured = Object.prototype.hasOwnProperty.call(raw, "contextSharingConsent");
96
+ const contextSharingConsent = isCurrentAdvisorContextSharingConsent(raw.contextSharingConsent)
97
+ ? raw.contextSharingConsent
98
+ : null;
99
+ return {
100
+ enabled,
101
+ model,
102
+ effort,
103
+ policy,
104
+ timeoutMs,
105
+ contextSharingConsent,
106
+ sources: {
107
+ enabled: typeof raw.enabled === "boolean" ? "configured" : "default",
108
+ model: typeof raw.model === "string" && raw.model.trim() !== "" ? "configured" : "default",
109
+ effort: isValidAdvisorEffort(raw.effort) ? "configured" : "default",
110
+ policy: isValidAdvisorPolicy(raw.policy) ? "configured" : "default",
111
+ contextSharingConsent: consentConfigured ? "configured" : "default",
112
+ },
113
+ };
114
+ }
115
+
116
+ /**
117
+ * Whether a consultation may send task context. Requires the switch, a model, and the
118
+ * current context-sharing consent. `enabled` is not consent. A miss fails closed for the
119
+ * data transfer and leaves the worker request itself running.
120
+ */
121
+ export function advisorRunnable(settings: AdvisorSettings): boolean {
122
+ return settings.enabled
123
+ && settings.model.trim() !== ""
124
+ && settings.contextSharingConsent === ADVISOR_CONTEXT_SHARING_CONSENT_VERSION;
125
+ }
126
+
127
+ /**
128
+ * Enabled, with a model, but without current consent. The management surface reports
129
+ * `advisor_context_sharing_consent_required` and the runtime sends no task context.
130
+ */
131
+ export function advisorContextSharingBlocked(settings: AdvisorSettings): boolean {
132
+ return settings.enabled
133
+ && settings.model.trim() !== ""
134
+ && settings.contextSharingConsent !== ADVISOR_CONTEXT_SHARING_CONSENT_VERSION;
135
+ }