@bitkyc08/opencodex 2.60.0 → 2.61.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 (249) hide show
  1. package/AGENTS_INSTALL.md +64 -0
  2. package/README.md +28 -1
  3. package/bin/ocx.mjs +382 -209
  4. package/gui/dist/assets/App-CH6C5H7x.js +50 -0
  5. package/gui/dist/assets/Tray-CLZh48fM.js +1 -0
  6. package/gui/dist/assets/index-_bpvxJu0.css +1 -0
  7. package/gui/dist/assets/index-wpTOyepx.js +86 -0
  8. package/gui/dist/assets/usage-companion-chart-a0N58rRI.js +1 -0
  9. package/gui/dist/favicon.png +0 -0
  10. package/gui/dist/index.html +2 -2
  11. package/gui/dist/provider-icons/stepfun-color.svg +1 -0
  12. package/package.json +5 -1
  13. package/src/adapters/anthropic.ts +16 -0
  14. package/src/adapters/coding-agent/protocol.ts +36 -6
  15. package/src/adapters/coding-agent/turn.ts +10 -2
  16. package/src/adapters/command-code.ts +2 -1
  17. package/src/adapters/cursor/catalog.ts +51 -7
  18. package/src/adapters/cursor/protobuf-request.ts +6 -3
  19. package/src/adapters/cursor/request-builder.ts +13 -3
  20. package/src/adapters/cursor.ts +11 -2
  21. package/src/adapters/declaration-carrier.ts +45 -0
  22. package/src/adapters/devin.ts +75 -23
  23. package/src/adapters/google-antigravity-wire.ts +5 -2
  24. package/src/adapters/google-errors.ts +7 -1
  25. package/src/adapters/google.ts +29 -5
  26. package/src/adapters/image.ts +4 -1
  27. package/src/adapters/input-media-guard.ts +21 -9
  28. package/src/adapters/kiro/usage.ts +3 -2
  29. package/src/adapters/kiro-tool-fallback.ts +1 -1
  30. package/src/adapters/ollama-native.ts +6 -0
  31. package/src/adapters/openai-chat/developer-role.ts +61 -0
  32. package/src/adapters/openai-chat/messages.ts +46 -27
  33. package/src/adapters/openai-chat/parallel-tool-calls.ts +32 -0
  34. package/src/adapters/openai-chat/passthrough.ts +33 -9
  35. package/src/adapters/openai-chat/reasoning-wire.ts +89 -0
  36. package/src/adapters/openai-chat.ts +18 -57
  37. package/src/adapters/openai-responses/passthrough.ts +2 -0
  38. package/src/adapters/registry.ts +3 -2
  39. package/src/adapters/run-turn-queue.ts +178 -29
  40. package/src/adapters/xai-web-search.ts +16 -1
  41. package/src/bridge/errors.ts +8 -2
  42. package/src/bridge/response-json.ts +9 -1
  43. package/src/bridge/sse.ts +10 -0
  44. package/src/chat/inbound.ts +141 -5
  45. package/src/claude/desktop-3p.ts +7 -1
  46. package/src/claude/desktop-first-party.ts +183 -0
  47. package/src/claude/desktop-gateway-state.ts +41 -0
  48. package/src/claude/inbound-content-options.ts +6 -0
  49. package/src/claude/inbound.ts +32 -6
  50. package/src/claude/intercept/connect-proxy.ts +179 -0
  51. package/src/claude/intercept/listener.ts +122 -0
  52. package/src/claude/intercept/local-ca.ts +298 -0
  53. package/src/claude/intercept/runtime.ts +98 -0
  54. package/src/claude/intercept/settings.ts +189 -0
  55. package/src/cli/access.ts +87 -0
  56. package/src/cli/account-auth.ts +19 -0
  57. package/src/cli/capabilities.ts +31 -0
  58. package/src/cli/claude-desktop.ts +206 -16
  59. package/src/cli/codex-shim-autorestore.ts +3 -0
  60. package/src/cli/companion.ts +56 -0
  61. package/src/cli/dispatch.ts +43 -4
  62. package/src/cli/ensure-desired-integrations.ts +43 -5
  63. package/src/cli/help.ts +7 -9
  64. package/src/cli/index.ts +200 -61
  65. package/src/cli/init.ts +8 -0
  66. package/src/cli/integrations.ts +7 -1
  67. package/src/cli/registry.ts +41 -2
  68. package/src/cli/resolve.ts +230 -0
  69. package/src/cli/root.ts +24 -1
  70. package/src/cli/start-ownership-publication.ts +56 -0
  71. package/src/cli/status-probes.ts +2 -18
  72. package/src/cli/status.ts +62 -0
  73. package/src/cli/stop-report.ts +143 -0
  74. package/src/cli/uninstall-plan.ts +9 -0
  75. package/src/client/machine-listener.ts +2 -5
  76. package/src/clients/aside-profiles.ts +4 -0
  77. package/src/clients/config-export/zcode-store.ts +157 -0
  78. package/src/clients/config-export.ts +36 -0
  79. package/src/codex/app-server-processes.ts +72 -40
  80. package/src/codex/auth-api/login-flow.ts +6 -1
  81. package/src/codex/autostart-health.ts +28 -0
  82. package/src/codex/catalog/build-entries.ts +2 -2
  83. package/src/codex/catalog/effort.ts +3 -3
  84. package/src/codex/catalog/provider-models.ts +24 -15
  85. package/src/codex/catalog/retained-sync.ts +2 -2
  86. package/src/codex/convergence.ts +2 -2
  87. package/src/codex/history-provider.ts +12 -1
  88. package/src/codex/inject/config-toml.ts +41 -6
  89. package/src/codex/inject/paginated-openai-compat.ts +90 -0
  90. package/src/codex/inject.ts +18 -15
  91. package/src/codex/injected-marker.ts +18 -0
  92. package/src/codex/main-account.ts +6 -0
  93. package/src/codex/model-cache.ts +52 -6
  94. package/src/codex/model-entitlement-admission.ts +59 -0
  95. package/src/codex/model-entitlements.ts +87 -44
  96. package/src/codex/native-main-admission.ts +83 -0
  97. package/src/codex/routing/health-store.ts +39 -0
  98. package/src/codex/routing/selection.ts +37 -1
  99. package/src/codex/routing.ts +5 -41
  100. package/src/codex/shim-templates.ts +29 -3
  101. package/src/companion/settings.ts +132 -0
  102. package/src/config/atomic-write.ts +117 -5
  103. package/src/config/load-degrade.ts +34 -7
  104. package/src/config/process-state.ts +1 -1
  105. package/src/config/schema/config-schema.ts +27 -1
  106. package/src/config/schema/leaf-validators.ts +47 -0
  107. package/src/config.ts +1 -1
  108. package/src/generated/compatibility-version.json +418 -174
  109. package/src/integrations/config-io.ts +44 -10
  110. package/src/integrations/merge.ts +120 -13
  111. package/src/integrations/mutation-plan.ts +124 -18
  112. package/src/integrations/registry.ts +38 -0
  113. package/src/integrations/state.ts +78 -45
  114. package/src/integrations/target.ts +208 -0
  115. package/src/integrations/writer.ts +49 -11
  116. package/src/lab/conformance/fixture-provider.ts +5 -0
  117. package/src/lib/browser-launch-notice.ts +59 -0
  118. package/src/lib/bun-runtime.ts +6 -2
  119. package/src/lib/debug.ts +40 -0
  120. package/src/lib/open-url.ts +51 -7
  121. package/src/lib/package-tree-integrity.ts +2 -1
  122. package/src/lib/package-version.ts +8 -0
  123. package/src/lib/provider-egress.ts +310 -0
  124. package/src/lib/provider-outbound.ts +59 -14
  125. package/src/lib/proxy-env.ts +82 -7
  126. package/src/lib/request-execution-budget.ts +72 -0
  127. package/src/lib/request-failure-attribution.ts +183 -0
  128. package/src/lib/request-failure-model.ts +236 -0
  129. package/src/lib/request-resend-gate.ts +138 -0
  130. package/src/lib/standalone.ts +16 -0
  131. package/src/lib/upstream-retry.ts +167 -16
  132. package/src/lib/winsw.ts +2 -2
  133. package/src/oauth/index.ts +24 -1
  134. package/src/oauth/login-cli.ts +80 -29
  135. package/src/providers/api-key-resolve.ts +133 -0
  136. package/src/providers/api-key-selection.ts +5 -1
  137. package/src/providers/key-failover.ts +31 -1
  138. package/src/providers/key-store.ts +34 -110
  139. package/src/providers/model-rename-fields.ts +147 -0
  140. package/src/providers/model-rename-migration.ts +124 -37
  141. package/src/providers/quota/vendor-probes-key.ts +37 -22
  142. package/src/providers/reasoning-metadata.ts +43 -18
  143. package/src/providers/registry/entries-core.ts +9 -4
  144. package/src/providers/registry/entries-extended.ts +29 -4
  145. package/src/providers/registry/model-seeds.ts +47 -10
  146. package/src/providers/xai-transport.ts +12 -1
  147. package/src/reasoning-effort.ts +8 -0
  148. package/src/responses/function-call-compat.ts +38 -1
  149. package/src/responses/inline-document.ts +65 -0
  150. package/src/responses/input-media.ts +42 -8
  151. package/src/responses/muse-tool-name-alias.ts +19 -0
  152. package/src/responses/parser-content.ts +8 -2
  153. package/src/responses/parser-tools.ts +3 -0
  154. package/src/responses/parser.ts +3 -1
  155. package/src/responses/schema.ts +3 -0
  156. package/src/router.ts +17 -2
  157. package/src/server/admission-model-scope.ts +219 -0
  158. package/src/server/audio-live.ts +9 -3
  159. package/src/server/audio-upstream.ts +18 -0
  160. package/src/server/auth-cors.ts +26 -0
  161. package/src/server/chat-completions.ts +55 -2
  162. package/src/server/chat-native.ts +19 -4
  163. package/src/server/claude-messages.ts +55 -17
  164. package/src/server/grok-responses-snapshot-repair.ts +113 -11
  165. package/src/server/gui-freshness.ts +103 -0
  166. package/src/server/gui-static.ts +7 -9
  167. package/src/server/images.ts +59 -6
  168. package/src/server/index/claude-intercept-lifecycle.ts +49 -0
  169. package/src/server/index/serve-options.ts +56 -10
  170. package/src/server/index/spend-ledger-lifecycle.ts +34 -8
  171. package/src/server/index/startup-warnings.ts +24 -0
  172. package/src/server/index.ts +21 -28
  173. package/src/server/lifecycle.ts +4 -4
  174. package/src/server/live-call-bindings.ts +6 -0
  175. package/src/server/live.ts +88 -3
  176. package/src/server/management/agent-settings-routes.ts +121 -36
  177. package/src/server/management/companion-routes.ts +77 -0
  178. package/src/server/management/logs-usage-routes.ts +19 -0
  179. package/src/server/management/native-integration-routes.ts +103 -6
  180. package/src/server/management/oauth-account-routes.ts +45 -7
  181. package/src/server/management/route-registry.ts +6 -0
  182. package/src/server/management/shared.ts +18 -1
  183. package/src/server/management/usage-timeline-routes.ts +44 -0
  184. package/src/server/management-api.ts +8 -9
  185. package/src/server/proxy-liveness.ts +75 -0
  186. package/src/server/relay.ts +19 -2
  187. package/src/server/request-log-failure-attribution.ts +99 -0
  188. package/src/server/request-log.ts +114 -0
  189. package/src/server/request-metrics.ts +92 -30
  190. package/src/server/responses/codex-ws-wire.ts +34 -8
  191. package/src/server/responses/combo-stream-preflight.ts +168 -6
  192. package/src/server/responses/compact.ts +11 -0
  193. package/src/server/responses/core-opaque-recovery.ts +90 -0
  194. package/src/server/responses/fetch-helpers.ts +124 -8
  195. package/src/server/responses/input-admission.ts +10 -0
  196. package/src/server/responses/passthrough-delivery.ts +14 -1
  197. package/src/server/responses/passthrough-dispatch.ts +179 -35
  198. package/src/server/responses/passthrough-error.ts +27 -8
  199. package/src/server/responses/request-prepare.ts +42 -1
  200. package/src/server/responses/request-send-budget.ts +12 -0
  201. package/src/server/responses/request-transport.ts +24 -4
  202. package/src/server/responses/reset-replay.ts +108 -0
  203. package/src/server/responses-request-tool-scope.ts +214 -0
  204. package/src/server/responses-undeclared-tool-guard.ts +4 -1
  205. package/src/server/search.ts +25 -1
  206. package/src/server/usage-ledger-retention.ts +73 -0
  207. package/src/service/cli.ts +48 -2
  208. package/src/service/health.ts +3 -2
  209. package/src/service/install-state-contract.d.mts +27 -0
  210. package/src/service/install-state-contract.mjs +34 -0
  211. package/src/service/launchd.ts +1 -1
  212. package/src/service/orchestration.ts +2 -4
  213. package/src/service/ownership-compatibility.ts +164 -0
  214. package/src/service/ownership-mutation-lease.d.mts +32 -0
  215. package/src/service/ownership-mutation-lease.mjs +211 -0
  216. package/src/service/repair.ts +45 -1
  217. package/src/service/state-lock.ts +269 -0
  218. package/src/service/state-record.d.mts +36 -0
  219. package/src/service/state-record.mjs +138 -0
  220. package/src/service/state.ts +582 -68
  221. package/src/service/windows-taskxml.ts +11 -10
  222. package/src/service.ts +7 -3
  223. package/src/tray/windows-tray.ps1 +1 -1
  224. package/src/types/config.ts +37 -0
  225. package/src/types/provider.ts +73 -0
  226. package/src/types/request.ts +28 -2
  227. package/src/types/tools.ts +19 -0
  228. package/src/types.ts +3 -0
  229. package/src/update/index.ts +207 -63
  230. package/src/update/job.ts +9 -5
  231. package/src/update/ownership-transaction.ts +47 -0
  232. package/src/update/restart-ownership.ts +54 -0
  233. package/src/update/runtime-ownership.d.mts +40 -0
  234. package/src/update/runtime-ownership.mjs +122 -0
  235. package/src/usage/attempt-delivery.ts +198 -0
  236. package/src/usage/cache-diagnostic.ts +305 -0
  237. package/src/usage/failure-fingerprint.ts +118 -0
  238. package/src/usage/failure-projection-cache.ts +174 -0
  239. package/src/usage/failure-projection.ts +174 -0
  240. package/src/usage/ledger-retention.ts +165 -0
  241. package/src/usage/log.ts +126 -79
  242. package/src/usage/request-outcome.ts +150 -0
  243. package/src/usage/retention-contract.ts +28 -0
  244. package/src/usage/summary.ts +2 -2
  245. package/src/usage/telemetry-contract.ts +237 -0
  246. package/src/usage/timeline.ts +236 -0
  247. package/src/web-search/alpha-search.ts +21 -1
  248. package/gui/dist/assets/index-BTuCbqQd.css +0 -1
  249. package/gui/dist/assets/index-DoBVdPHP.js +0 -134
@@ -79,10 +79,11 @@ export function buildWindowsServiceScript(
79
79
  windowsBatchSet("OCX_API_TOKEN_FILE", serviceApiTokenFilePath(), "path"),
80
80
  windowsBatchSet("OCX_SERVICE_LOG", serviceLogPath(), "path"),
81
81
  windowsBatchSet("OCX_BUN", bun, "path"),
82
- windowsBatchSet("OCX_CLI", cli, "path"),
82
+ windowsBatchSet("OCX_CLI", cli ?? undefined, "path"),
83
+ // Standalone executables have no npm package tree; recovery is "replace the executable", so no OCX_PKG_DIR/restore_backup wiring.
83
84
  // Package root for the transactional-update restore path (#1942): cli is
84
85
  // <pkg>\src\cli\index.ts, so the package dir is three levels up.
85
- 'for %%I in ("%OCX_CLI%\\..\\..\\..") do set "OCX_PKG_DIR=%%~fI"',
86
+ cli ? 'for %%I in ("%OCX_CLI%\\..\\..\\..") do set "OCX_PKG_DIR=%%~fI"' : null,
86
87
  'if exist "%OCX_API_TOKEN_FILE%" (',
87
88
  ' set /p OPENCODEX_API_AUTH_TOKEN=<"%OCX_API_TOKEN_FILE%"',
88
89
  ")",
@@ -101,14 +102,14 @@ export function buildWindowsServiceScript(
101
102
  ' >>"%OCX_SERVICE_LOG%" echo [%DATE% %TIME%] installation is incomplete: bundled Bun is missing; reinstall opencodex, then run ocx service repair',
102
103
  " exit /b 3",
103
104
  ")",
104
- 'if not exist "%OCX_CLI%" (',
105
- " call :restore_backup",
106
- ")",
107
- 'if not exist "%OCX_CLI%" (',
108
- ' >>"%OCX_SERVICE_LOG%" echo [%DATE% %TIME%] installation is incomplete: CLI entry is missing; reinstall opencodex, then run ocx service repair',
109
- " exit /b 3",
110
- ")",
111
- `"%OCX_BUN%" "%OCX_CLI%" start --port ${port} >>"%OCX_SERVICE_LOG%" 2>&1`,
105
+ cli ? 'if not exist "%OCX_CLI%" (' : null,
106
+ cli ? " call :restore_backup" : null,
107
+ cli ? ")" : null,
108
+ cli ? 'if not exist "%OCX_CLI%" (' : null,
109
+ cli ? ' >>"%OCX_SERVICE_LOG%" echo [%DATE% %TIME%] installation is incomplete: CLI entry is missing; reinstall opencodex, then run ocx service repair' : null,
110
+ cli ? " exit /b 3" : null,
111
+ cli ? ")" : null,
112
+ cli ? `"%OCX_BUN%" "%OCX_CLI%" start --port ${port} >>"%OCX_SERVICE_LOG%" 2>&1` : `"%OCX_BUN%" start --port ${port} >>"%OCX_SERVICE_LOG%" 2>&1`,
112
113
  "if %ERRORLEVEL% NEQ 0 (",
113
114
  ' >>"%OCX_SERVICE_LOG%" echo [%DATE% %TIME%] child exited with code %ERRORLEVEL%; restarting in 5s',
114
115
  // `timeout` needs console stdin and dies with "Input redirection is not supported"
package/src/service.ts CHANGED
@@ -6,8 +6,12 @@
6
6
  * restore it via the command.
7
7
  */
8
8
 
9
- export type { ServiceBackend, ServiceInstallState, ServiceStateEvidence } from "./service/state";
10
- export { SERVICE_MANAGED_ENV, stableLauncherEntry, serviceLogPath, serviceStatePathsForOpenCodexHome, parseServiceInstallState, inspectServiceStateEvidence, currentServiceHomes, serviceHomeMatches, readServiceBackend, serviceReinstallArgs, serviceInstallArgs } from "./service/state";
9
+ export type { ServiceBackend, ServiceInstallState, ServiceStateEvidence, ServiceStateResolution, ServiceOwner, ServiceOwnership, ServiceOwnershipSubject, ServiceOwnershipResolution, ServiceStateSwapDeps, RecordServiceOwnerRequest, RecordServiceOwnerDeps, ReleaseServiceOwnerDeps, RemoveServiceStateDeps } from "./service/state";
10
+ export { SERVICE_MANAGED_ENV, SERVICE_OWNERSHIP_PROTOCOL_VERSION, SERVICE_OWNERSHIP_MINIMUM_CLI_VERSION, stableLauncherEntry, serviceLogPath, serviceStatePaths, serviceStatePathsForOpenCodexHome, parseServiceInstallState, parseServiceOwnership, inspectServiceStateEvidence, resolveServiceState, currentServiceHomes, serviceHomeMatches, readServiceBackend, serviceReinstallArgs, serviceInstallArgs, ServiceStateConflictError, ServiceOwnershipSubjectMismatchError, ServiceOwnershipSubjectUnknownError, ServiceTakeoverCompatibilityChangedError, swapServiceInstallState, removeServiceInstallStateRecords, serviceOwnership, resolveServiceOwnership, sameServiceOwnershipSubject, desktopOwnsService, ownershipGrantedTo, recordServiceOwner, releaseServiceOwner } from "./service/state";
11
+ export type { OwnershipMutationLeaseOptions, OwnershipMutationLease } from "./service/ownership-mutation-lease.mjs";
12
+ export { acquireOwnershipMutationLease, withOwnershipMutationLease } from "./service/ownership-mutation-lease.mjs";
13
+ export type { ManagingCliRole, ManagingCliObservation, RegisteredManagingCliInvocation, ServiceTakeoverCompatibilityInput, ServiceTakeoverCompatibility } from "./service/ownership-compatibility";
14
+ export { registeredManagingCliInvocation, assessServiceTakeoverCompatibility, sameServiceTakeoverCompatibility } from "./service/ownership-compatibility";
11
15
  export type { ServiceApiTokenOrigin, ProvisionedServiceApiToken } from "./service/guards";
12
16
  export { ServiceOwnershipError, isServiceOwnershipError, serviceEnvironmentOwnedHere, assertServiceEnvironmentMatchesInstall, serviceRetryCommand, assertNotAdminToken, assertServiceAuthEnvironment, writeServiceApiTokenFile, assertLiveServiceManagerAllowed } from "./service/guards";
13
17
  export { resolveServiceListenPort, installedServiceListenPort, SERVICE_INSTALL_HEALTH_MS, SERVICE_INSTALL_HEALTH_WINDOWS_MS, serviceInstallHealthMs, confirmServiceServing, reportServiceServing, resolvedProxyEnv } from "./service/health";
@@ -21,7 +25,7 @@ export { buildWindowsServiceScript, buildWindowsSchtasksCreateArgs, buildWindows
21
25
  export type { WindowsSchedulerRegistrationStageDeps, FreshWindowsSchedulerRegistrationDeps, RemoveNativeWindowsServiceDeps } from "./service/windows-ops";
22
26
  export { windowsListenPort, winswListenPort, writeServiceDefinitionFile, definitionCarriesCredential, stageWindowsSchedulerRegistrationXml, stageElevatedSchedulerRegistration, describeElevatedRegistrationFailure, registerFreshWindowsSchedulerTask, removeNativeWindowsServiceForScheduler, assertWindowsNativeServiceAccountSupported, isWindowsSchedulerEndBenign, stopWindows, stopWindowsChecked, classifyWindowsServiceStop } from "./service/windows-ops";
23
27
  export type { ServiceRepairVerb, RepairServiceDeps } from "./service/repair";
24
- export { repairService } from "./service/repair";
28
+ export { repairService, foreignServiceOwnerRefusal, unknownServiceOwnerRefusal } from "./service/repair";
25
29
  export type { ServiceInstallPreparationDeps, FreshWindowsSchedulerInstallDeps, ServiceStopOutcome, ServiceUninstallOutcome } from "./service/orchestration";
26
30
  export { proxyStillLiveAfterStop, prepareServiceInstall, installServiceSafely, installFreshWindowsSchedulerSafely, installedServiceRespawnRisk, stopServiceIfInstalledDetailed, setUninstallServiceHooksForTests, uninstallServiceDetailed, uninstallServiceIfInstalled, isServiceInstalled, isServiceViable } from "./service/orchestration";
27
31
  export type { ServiceDiagnostic, WindowsTaskDiagnosticIdentityDeps, WindowsServiceDiagnosticInputs, LaunchdServiceDiagnosticInputs } from "./service/diagnostics";
@@ -5,7 +5,7 @@ param(
5
5
  [Parameter(Mandatory = $true)][string]$OpenCodexHome,
6
6
  # Provenance of $BunPath, chosen when the tray entry was built. Optional so an
7
7
  # already-installed launcher command from an older version still starts.
8
- [ValidateSet("", "override", "bundled", "process")][string]$BunRuntimeSource = "",
8
+ [ValidateSet("", "override", "bundled", "process", "standalone")][string]$BunRuntimeSource = "",
9
9
  [ValidateSet("Run", "Stop")][string]$Mode = "Run",
10
10
  [int]$HostPid = 0
11
11
  )
@@ -137,6 +137,13 @@ export interface OcxClaudeCodeConfig {
137
137
  autoContext?: boolean;
138
138
  /** Compact-window tokens for auto-context. Default 829_800 (AUTO_COMPACT_WINDOW_DEFAULT). */
139
139
  autoCompactWindow?: number;
140
+ /**
141
+ * Local CONNECT proxy + TLS listener that intercepts Claude Code's own `api.anthropic.com`
142
+ * traffic without any `ANTHROPIC_BASE_URL` rewrite (src/claude/intercept). Claude Code reaches
143
+ * it via `HTTPS_PROXY`/`NODE_EXTRA_CA_CERTS` in its settings env. Default: enabled on a
144
+ * hub; the proxy port defaults to the public port + 100.
145
+ */
146
+ intercept?: { enabled?: boolean; port?: number };
140
147
  /**
141
148
  * Bundled-skill content elision for ROUTED (non-Anthropic) models (devlog 260712
142
149
  * 060): Skill-tool results whose skill name matches an entry here are replaced
@@ -166,6 +173,14 @@ export interface OcxClaudeCodeConfig {
166
173
  visionSidecar?: { backend?: "openai" | "anthropic" | "routed"; model?: string };
167
174
  /** Persisted Claude Desktop four-family routing profile. */
168
175
  desktopProfile?: OcxClaudeDesktopProfile;
176
+ /**
177
+ * How Claude Desktop reaches opencodex (src/claude/desktop-first-party.ts).
178
+ * `first-party` (default) leaves the app on its normal claude.ai login and redirects only the
179
+ * Code tab's Claude Code process through the intercept pair via settings.json env.
180
+ * `gateway` installs the third-party deployment profile (desktop-3p) for the whole app.
181
+ * Unset on an install that already applied a gateway profile resolves to `gateway`.
182
+ */
183
+ desktopMode?: "first-party" | "gateway";
169
184
  /** Auto-reconcile Desktop 3P config when provider catalog changes. Default: enabled. */
170
185
  desktopAutoApply?: boolean;
171
186
  /**
@@ -253,6 +268,21 @@ export interface OcxApiKeyEntry {
253
268
  key: string;
254
269
  createdAt: string;
255
270
  pendingRotation?: OcxPendingApiKeyRotation;
271
+ /**
272
+ * Resolved provider names this key may reach. Absent or empty means every
273
+ * provider, which is what every existing key has, so adding the field
274
+ * changes nothing until an operator sets one.
275
+ */
276
+ allowedProviders?: string[];
277
+ /**
278
+ * Resolved destinations this key may reach, as a bare model id or a
279
+ * `provider/model` pair. Absent or empty means every model.
280
+ *
281
+ * These name destinations, not the selectors a client sends: they are
282
+ * checked after alias, combo, fallback and compaction resolution, because
283
+ * that is the only point at which the model about to be billed is known.
284
+ */
285
+ allowedModels?: string[];
256
286
  }
257
287
 
258
288
  export interface OcxPendingApiKeyRotation {
@@ -794,6 +824,13 @@ export interface OcxConfig {
794
824
  * See `src/storage/policy.ts`.
795
825
  */
796
826
  storageCleanupPolicy?: StorageCleanupPolicy;
827
+ /**
828
+ * Opt-in ceiling in bytes for `usage.jsonl`. Absent means the ledger grows without limit,
829
+ * which stays the default: history an operator did not ask to delete is not deleted. Values
830
+ * below the documented floor are treated as unset rather than enforced, because a ceiling
831
+ * smaller than a row cannot be met without emptying the file.
832
+ */
833
+ usageLedgerMaxBytes?: number;
797
834
  /** Generated API keys for external access to the proxy's /v1/responses endpoint. */
798
835
  apiKeys?: OcxApiKeyEntry[];
799
836
  /** Auto-start/sync the proxy from the Codex shim before launching Codex. Default true. */
@@ -67,6 +67,31 @@ export interface TransientRetryPolicy {
67
67
  attempts?: number;
68
68
  }
69
69
 
70
+ /**
71
+ * Opt-in replacement of a native Responses send whose upstream connection closed while the
72
+ * caller had observed nothing (`providers.<name>.retryOnReset`).
73
+ *
74
+ * Covers both ambiguous stages the proxy can be in: no response head at all, and a head whose
75
+ * SSE body carried only control events. Disabled unless the object is present; a bare `{}`
76
+ * opts in with defaults. Only a request the proxy can judge self-contained is ever replaced;
77
+ * see `src/server/responses/reset-replay.ts`. The replacement inference may still be billed if
78
+ * the origin had already started the first one, which is what makes this opt-in rather than
79
+ * default.
80
+ */
81
+ export interface ResetReplayPolicy {
82
+ /** Master switch. Presence of the object also enables the policy (default true). */
83
+ enabled?: boolean;
84
+ /**
85
+ * Replacement sends one LOGICAL request may make, across every leg and every combo child
86
+ * (1..2, default 1).
87
+ *
88
+ * Not a per-leg retry count and not a send budget. A request that resets before the head and
89
+ * again after it draws on this one number, and each replacement still has to fit inside the
90
+ * send allowance the leg already had.
91
+ */
92
+ replacements?: number;
93
+ }
94
+
70
95
  /**
71
96
  * Same-target 429 wait-and-retry policy (`providers.<name>.retryOn429`). When present and not
72
97
  * explicitly disabled, the proxy waits and replays the identical request on the same key before
@@ -388,6 +413,35 @@ export interface OcxProviderConfig {
388
413
  * link-local, or unique-local upstreams. Metadata endpoints remain blocked.
389
414
  */
390
415
  allowPrivateNetwork?: boolean;
416
+ /**
417
+ * Outbound egress for THIS provider, overriding the process-wide `proxy` decision.
418
+ *
419
+ * The global `proxy` is one value for every upstream, so it cannot express the split
420
+ * operators actually need: reach one gateway through a regional proxy while another stays
421
+ * direct on the local network (#2894). Accepted values:
422
+ *
423
+ * - absent — inherit the global proxy decision. Unchanged behaviour.
424
+ * - `"direct"` or `null` — never use the global proxy for this provider.
425
+ * - `"http://…"` / `"https://…"` — this provider's own HTTP(S) proxy.
426
+ * - `"socks5://…"` / `"socks5h://…"` — this provider's own SOCKS5 proxy.
427
+ *
428
+ * An empty string is rejected rather than read as DIRECT: a cleared dashboard field must not
429
+ * silently switch a provider from inheriting the global proxy to refusing it. A malformed
430
+ * value is rejected at configuration time and again at request time; it never degrades to
431
+ * either neighbour, because both degradations look like success at the call site.
432
+ *
433
+ * Not every transport can carry this. `structure/transports/inventory.md` records which
434
+ * request paths honour it and which still follow the process-wide value only.
435
+ */
436
+ proxy?: string | null;
437
+ /**
438
+ * Destinations this provider reaches without a proxy, in `NO_PROXY` syntax.
439
+ *
440
+ * Applied to whichever route `proxy` resolved to, so it carves an exemption out of this
441
+ * provider's own proxy AND out of an inherited global one. That second case is how a
442
+ * provider exempts a single host without owning a proxy of its own.
443
+ */
444
+ noProxy?: string | string[];
391
445
  /**
392
446
  * Pin the HTTP version used for upstream provider requests. Bun's fetch negotiates
393
447
  * HTTP/2 via TLS ALPN by default; some Cloudflare-fronted SSE endpoints hang on
@@ -816,6 +870,19 @@ export interface OcxProviderConfig {
816
870
  * incomplete JSON, missing arguments, and empty streams remain truncation errors.
817
871
  */
818
872
  openaiChatEofTolerance?: boolean;
873
+ /**
874
+ * Opt-in: fold a `developer` message into a `system` message instead of forwarding the role.
875
+ *
876
+ * `developer` is part of the Chat Completions message role set, so forwarding it is the
877
+ * default. The role used to be decided by testing the base URL host against
878
+ * `api.openai.com`, which assumed every OpenAI-compatible gateway rejects a standard role
879
+ * until proven otherwise — including gateways that proxy OpenAI itself — and quietly gave the
880
+ * instruction `system` precedence instead (#5213). This flag exists for a destination that
881
+ * genuinely rejects the role, so the conversion is a recorded decision about that destination
882
+ * rather than an inference from its hostname. Position is unaffected either way: the message
883
+ * keeps its slot in the conversation.
884
+ */
885
+ foldDeveloperRoleToSystem?: boolean;
819
886
  /**
820
887
  * Opt-in: forward `prompt_cache_key` to the upstream `/chat/completions` body.
821
888
  * OpenAI-specific extension; strict backends (Groq, Cerebras, etc.) reject unknown
@@ -872,6 +939,12 @@ export interface OcxProviderConfig {
872
939
  * with defaults. Key-auth `openai-chat` only.
873
940
  */
874
941
  transientRetryOn5xx?: TransientRetryPolicy;
942
+ /**
943
+ * Opt-in replacement of a native Responses send that died while the caller had observed
944
+ * nothing (`providers.<name>.retryOnReset`). Disabled unless present; a bare `{}` opts in
945
+ * with defaults. Native Responses sends only, and only for self-contained requests.
946
+ */
947
+ retryOnReset?: ResetReplayPolicy;
875
948
  /**
876
949
  * Model ids whose OpenAI-compatible chat endpoint accepts `reasoning_split: true` and returns
877
950
  * thinking separately in `reasoning_content` / `reasoning_details` instead of visible content.
@@ -210,8 +210,34 @@ export interface OcxVideoContent {
210
210
  videoUrl: string;
211
211
  }
212
212
 
213
- /** A user/developer message content part: text or native media. */
214
- export type OcxContentPart = OcxTextContent | OcxImageContent | OcxVideoContent;
213
+ /**
214
+ * An attached document carried as bytes rather than as a description of itself.
215
+ *
216
+ * Both inbound parsers used to reduce an attachment to a title before any adapter ran, so no
217
+ * adapter could forward one even to a target that has a representation for it, and the caller
218
+ * could not tell "the model read the document" from "the model was told a document existed"
219
+ * (#5212).
220
+ *
221
+ * `text` is that marker, derived once from what the part knows and kept on the part itself.
222
+ * Every text-only consumer in the tree reaches a `.text` fallback for a part it does not
223
+ * recognize, so carrying it here means a wire with no document representation still states the
224
+ * attachment instead of emitting `undefined` or a mislabelled `[video]`. Only the wires that
225
+ * have a counterpart read `data`.
226
+ */
227
+ export interface OcxDocumentContent {
228
+ type: "document";
229
+ /** `[document: name]` marker, for every wire with no document representation. */
230
+ text: string;
231
+ /** IANA media type of the payload, for example `application/pdf`. */
232
+ mediaType: string;
233
+ /** Base64 payload with no `data:` prefix. */
234
+ data: string;
235
+ /** The document's own name: an Anthropic document title or a Chat file part's filename. */
236
+ filename?: string;
237
+ }
238
+
239
+ /** A user/developer message content part: text, native media, or an attached document. */
240
+ export type OcxContentPart = OcxTextContent | OcxImageContent | OcxVideoContent | OcxDocumentContent;
215
241
 
216
242
  export interface OcxThinkingContent {
217
243
  type: "thinking";
@@ -3,6 +3,12 @@ export interface OcxTool {
3
3
  description: string;
4
4
  parameters: Record<string, unknown>;
5
5
  strict?: boolean;
6
+ /**
7
+ * Anthropic `tools[*].allowed_callers`: which callers may invoke this tool. Carried rather
8
+ * than diagnosed, because rebuilding the declaration without it hands the model a tool the
9
+ * caller had restricted and returns a normal response (#5210).
10
+ */
11
+ allowedCallers?: string[];
6
12
  /** MCP namespace (e.g. "mcp__context7") for tools flattened out of a Responses "namespace" tool. */
7
13
  namespace?: string;
8
14
  /** Freeform/custom tool (e.g. apply_patch): the model's call must be relayed as a custom_tool_call. */
@@ -31,6 +37,19 @@ export function namespacedToolName(namespace: string | undefined, name: string):
31
37
  return namespace ? `${namespace}__${name}` : name;
32
38
  }
33
39
 
40
+ /**
41
+ * Whether a declaration actually narrows who may call the tool.
42
+ *
43
+ * `["direct"]` is the state every unrestricted tool is already in, so treating it as a
44
+ * restriction would refuse ordinary traffic. Mirrors the `caller_mode` predicate in
45
+ * src/claude/compatibility.ts, which draws the same line.
46
+ */
47
+ export function toolRestrictsCallers(tool: Pick<OcxTool, "allowedCallers">): boolean {
48
+ const callers = tool.allowedCallers;
49
+ if (callers === undefined) return false;
50
+ return !(callers.length === 1 && callers[0] === "direct");
51
+ }
52
+
34
53
  /**
35
54
  * Dotted alias of a namespaced tool's wire name. Some routed providers (observed: muse-spark
36
55
  * via opencode-go) echo a namespaced tool call as "<namespace>.<name>" instead of the flattened
package/src/types.ts CHANGED
@@ -17,6 +17,7 @@ export {
17
17
  isAllowedToolChoice,
18
18
  toolChoiceToolPredicate,
19
19
  declaresCodeModeExec,
20
+ toolRestrictsCallers,
20
21
  NAMESPACED_BARE_ALIAS_EXCLUDED_NAMES,
21
22
  } from "./types/tools";
22
23
 
@@ -43,6 +44,7 @@ export type {
43
44
  OcxToolResultMessage,
44
45
  OcxTextContent,
45
46
  OcxImageContent,
47
+ OcxDocumentContent,
46
48
  OcxContentPart,
47
49
  OcxThinkingContent,
48
50
  OcxToolCall,
@@ -104,6 +106,7 @@ export type {
104
106
  ResponsesItemIdRepairConfig,
105
107
  RateLimitRetryPolicy,
106
108
  TransientRetryPolicy,
109
+ ResetReplayPolicy,
107
110
  ProviderWebSearchBridgeBackend,
108
111
  ProviderWebSearchBridgeConfig,
109
112
  ProviderCostOverlay,