@bitkyc08/opencodex 2.64.0 → 2.65.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 (208) hide show
  1. package/README.md +28 -25
  2. package/bin/ocx.mjs +16 -2
  3. package/gui/dist/assets/App-8NMiZxT0.css +1 -0
  4. package/gui/dist/assets/App-DGLte6IR.js +50 -0
  5. package/gui/dist/assets/Tray-D4bA1vff.js +1 -0
  6. package/gui/dist/assets/{index-DiBRuK-d.css → index--EWgGQvZ.css} +1 -1
  7. package/gui/dist/assets/{index-SggB6t3z.js → index-Bi1K37Wl.js} +12 -12
  8. package/gui/dist/assets/tray-data-BZXhB3qz.js +1 -0
  9. package/gui/dist/index.html +2 -2
  10. package/package.json +1 -4
  11. package/src/adapters/anthropic.ts +30 -1
  12. package/src/adapters/claude-cli/adapter.ts +218 -0
  13. package/src/adapters/claude-cli/profiles.ts +38 -0
  14. package/src/adapters/codebuddy/profiles.ts +2 -0
  15. package/src/adapters/coding-agent/profile.ts +12 -4
  16. package/src/adapters/coding-agent/turn.ts +16 -6
  17. package/src/adapters/command-code-tool-text.ts +133 -23
  18. package/src/adapters/cursor/catalog.ts +4 -8
  19. package/src/adapters/cursor/discovery.ts +10 -5
  20. package/src/adapters/cursor/effort-map.ts +2 -6
  21. package/src/adapters/cursor/envelope-echo.ts +10 -5
  22. package/src/adapters/cursor/request-builder.ts +9 -4
  23. package/src/adapters/cursor/thread-continuity.ts +53 -0
  24. package/src/adapters/cursor.ts +29 -13
  25. package/src/adapters/devin/cloud-direct/chat.ts +3 -1
  26. package/src/adapters/google-tool-schema.ts +26 -3
  27. package/src/adapters/identity.ts +214 -2
  28. package/src/adapters/openai-chat/passthrough.ts +1 -0
  29. package/src/adapters/openai-chat/serialized-tool-call-content.ts +569 -0
  30. package/src/adapters/openai-chat.ts +43 -15
  31. package/src/adapters/openai-responses/canonical-forward.ts +17 -10
  32. package/src/adapters/openai-responses/passthrough.ts +19 -4
  33. package/src/adapters/openai-responses/request-strips.ts +25 -0
  34. package/src/adapters/openai-responses/web-search.ts +22 -4
  35. package/src/adapters/qoder/profiles.ts +2 -0
  36. package/src/adapters/registry.ts +8 -0
  37. package/src/adapters/run-turn-queue.ts +7 -0
  38. package/src/bridge/response-json.ts +6 -4
  39. package/src/bridge/sse.ts +7 -5
  40. package/src/claude/alias.ts +73 -26
  41. package/src/claude/context-windows.ts +15 -6
  42. package/src/claude/desktop-3p-library.ts +3 -2
  43. package/src/claude/desktop-3p.ts +1 -1
  44. package/src/claude/desktop-first-party.ts +63 -22
  45. package/src/claude/desktop-picker-profile.ts +302 -0
  46. package/src/claude/desktop-picker.ts +365 -0
  47. package/src/claude/desktop-risk.ts +20 -0
  48. package/src/claude/gateway-cache.ts +13 -4
  49. package/src/claude/inbound.ts +5 -2
  50. package/src/claude/intercept/connect-proxy.ts +106 -29
  51. package/src/claude/intercept/local-ca.ts +76 -18
  52. package/src/claude/intercept/model-bindings.ts +145 -0
  53. package/src/claude/intercept/picker-bootstrap.ts +141 -0
  54. package/src/claude/intercept/picker-ca.ts +126 -0
  55. package/src/claude/intercept/picker-listener.ts +213 -0
  56. package/src/claude/intercept/picker-models.ts +101 -0
  57. package/src/claude/intercept/picker-runtime.ts +330 -0
  58. package/src/claude/intercept/picker-trust.ts +125 -0
  59. package/src/claude/intercept/runtime.ts +149 -2
  60. package/src/claude/model-info.ts +18 -4
  61. package/src/cli/agent.ts +16 -2
  62. package/src/cli/capabilities.ts +71 -2
  63. package/src/cli/claude-desktop.ts +319 -33
  64. package/src/cli/claude.ts +15 -7
  65. package/src/cli/codex-shim-autorestore.ts +1 -0
  66. package/src/cli/dispatch.ts +29 -23
  67. package/src/cli/effort.ts +16 -6
  68. package/src/cli/ensure-desired-integrations.ts +29 -4
  69. package/src/cli/ready.ts +1 -1
  70. package/src/cli/registry.ts +8 -0
  71. package/src/cli/restart-scope.ts +9 -1
  72. package/src/cli/runtime-api.ts +17 -0
  73. package/src/cli/system-command.ts +11 -12
  74. package/src/client/connect.ts +12 -2
  75. package/src/client/state.ts +39 -1
  76. package/src/clients/config-export.ts +57 -9
  77. package/src/codex/auth-context.ts +51 -11
  78. package/src/codex/catalog/derive-entry.ts +5 -5
  79. package/src/codex/catalog/gather-capture.ts +25 -6
  80. package/src/codex/catalog/metadata.ts +3 -3
  81. package/src/codex/catalog/parsing.ts +39 -1
  82. package/src/codex/catalog/provider-models.ts +8 -6
  83. package/src/codex/catalog/retained-sync.ts +17 -7
  84. package/src/codex/catalog/sync.ts +2 -2
  85. package/src/codex/desktop-app-restart.ts +8 -0
  86. package/src/codex/desktop-switches.ts +9 -1
  87. package/src/codex/home.ts +43 -4
  88. package/src/codex/inject/config-toml.ts +137 -0
  89. package/src/codex/inject/plan.ts +23 -0
  90. package/src/codex/inject/remove.ts +21 -1
  91. package/src/codex/inject.ts +63 -8
  92. package/src/codex/journal.ts +36 -0
  93. package/src/codex/main-account-hard-lock.ts +14 -1
  94. package/src/codex/main-account-policy-wait.ts +109 -0
  95. package/src/codex/native-profile-startup.ts +24 -6
  96. package/src/codex/native-residue.ts +28 -10
  97. package/src/codex/quota-types.ts +8 -1
  98. package/src/codex/quota.ts +49 -7
  99. package/src/codex/runtime.ts +31 -10
  100. package/src/combos/failover.ts +7 -6
  101. package/src/combos/resolve.ts +91 -14
  102. package/src/combos/types.ts +18 -1
  103. package/src/config/load-degrade.ts +2 -0
  104. package/src/config/schema/config-schema.ts +21 -2
  105. package/src/config/schema/leaf-validators.ts +6 -3
  106. package/src/config/subagent-models.ts +3 -1
  107. package/src/generated/compatibility-version.json +275 -163
  108. package/src/images/artifacts.ts +14 -0
  109. package/src/integrations/owned-refresh.ts +1 -1
  110. package/src/integrations/ownership-policy.ts +32 -1
  111. package/src/integrations/state.ts +3 -1
  112. package/src/integrations/writer.ts +9 -0
  113. package/src/lib/config-ownership.ts +3 -0
  114. package/src/lib/errors.ts +87 -0
  115. package/src/lib/package-tree-integrity.ts +1 -1
  116. package/src/lib/request-execution-budget.ts +42 -14
  117. package/src/lib/request-resend-gate.ts +4 -3
  118. package/src/lib/retry-delay.ts +7 -1
  119. package/src/lib/tool-envelope-echo-filter.ts +236 -0
  120. package/src/lib/upstream-retry.ts +20 -12
  121. package/src/oauth/index.ts +1 -0
  122. package/src/oauth/kiro-credentials.ts +14 -1
  123. package/src/oauth/login-cli.ts +1 -0
  124. package/src/providers/derive.ts +4 -0
  125. package/src/providers/fast-opt-in.ts +31 -0
  126. package/src/providers/model-rename-fields.ts +2 -0
  127. package/src/providers/provider-id-rewrite.ts +2 -0
  128. package/src/providers/quota/vendor-probes-key.ts +8 -2
  129. package/src/providers/registry/entries-core.ts +45 -2
  130. package/src/providers/registry/entries-extended.ts +99 -12
  131. package/src/providers/registry/model-ids.ts +2 -0
  132. package/src/providers/registry/types.ts +7 -1
  133. package/src/providers/resolved-model-policy.ts +11 -4
  134. package/src/providers/service-tier.ts +10 -3
  135. package/src/responses/code-mode-helper-compat.ts +3 -0
  136. package/src/responses/parser.ts +45 -3
  137. package/src/router.ts +6 -0
  138. package/src/server/auth-cors.ts +8 -0
  139. package/src/server/chat-completions.ts +3 -1
  140. package/src/server/claude-messages.ts +69 -14
  141. package/src/server/grok-upstream-envelope-echo.ts +120 -0
  142. package/src/server/index/claude-intercept-lifecycle.ts +24 -0
  143. package/src/server/index/serve-options.ts +2 -2
  144. package/src/server/index.ts +7 -0
  145. package/src/server/management/agent-settings-routes.ts +204 -112
  146. package/src/server/management/claude-desktop-picker-routes.ts +128 -0
  147. package/src/server/management/combo-routes.ts +59 -2
  148. package/src/server/management/config-routes.ts +81 -39
  149. package/src/server/management/context.ts +3 -0
  150. package/src/server/management/native-integration-routes.ts +169 -93
  151. package/src/server/management/provider-routes.ts +46 -4
  152. package/src/server/management/route-registry.ts +10 -0
  153. package/src/server/management/routing-profile-routes.ts +9 -0
  154. package/src/server/management/sidebar-routes.ts +52 -0
  155. package/src/server/management-api.ts +2 -0
  156. package/src/server/proxy-liveness.ts +38 -3
  157. package/src/server/request-log-account-rotation.ts +53 -0
  158. package/src/server/request-log.ts +3 -16
  159. package/src/server/responses/adapter-dispatch.ts +17 -1
  160. package/src/server/responses/agent-task-recovery.ts +49 -26
  161. package/src/server/responses/codex-ws-exchange.ts +18 -7
  162. package/src/server/responses/codex-ws-wire.ts +27 -4
  163. package/src/server/responses/core-combo.ts +21 -3
  164. package/src/server/responses/core-normalize.ts +7 -0
  165. package/src/server/responses/core-opaque-recovery.ts +3 -2
  166. package/src/server/responses/encrypted-payload.ts +15 -14
  167. package/src/server/responses/fetch-helpers.ts +1 -1
  168. package/src/server/responses/input-admission.ts +10 -6
  169. package/src/server/responses/native-response-control.ts +2 -2
  170. package/src/server/responses/passthrough-delivery.ts +182 -12
  171. package/src/server/responses/passthrough-dispatch.ts +102 -44
  172. package/src/server/responses/policy-fallback.ts +3 -0
  173. package/src/server/responses/policy-refusal.ts +67 -0
  174. package/src/server/responses/request-send-budget.ts +4 -0
  175. package/src/server/responses/run-turn-execution.ts +42 -11
  176. package/src/server/responses/ws-upstream.ts +2 -1
  177. package/src/server/system-env-shell.ts +0 -1
  178. package/src/server/system-env.ts +25 -4
  179. package/src/service/cli.ts +34 -3
  180. package/src/tray/assets/opencodex-tray-offline-update.ico +0 -0
  181. package/src/tray/assets/opencodex-tray-online-update.ico +0 -0
  182. package/src/tray/assets/opencodex-tray-warning-update.ico +0 -0
  183. package/src/tray/windows-tray.ps1 +188 -7
  184. package/src/tray/windows.ts +23 -2
  185. package/src/types/config.ts +52 -12
  186. package/src/types/provider.ts +22 -5
  187. package/src/types/tools.ts +11 -5
  188. package/src/types.ts +1 -0
  189. package/src/update/async-check.ts +109 -0
  190. package/src/update/badge.ts +11 -17
  191. package/src/update/check-types.ts +9 -0
  192. package/src/update/desktop-badge.ts +102 -0
  193. package/src/update/index.ts +48 -8
  194. package/src/update/install-detection.d.mts +29 -2
  195. package/src/update/install-detection.mjs +213 -7
  196. package/src/update/job.ts +17 -12
  197. package/src/update/notify.ts +16 -11
  198. package/src/update/pnpm-owner-worker.ts +12 -0
  199. package/src/update/refresh-scheduler.ts +141 -0
  200. package/src/usage/cost.ts +31 -4
  201. package/src/usage/expected-prices.ts +57 -0
  202. package/assets/download-linux.svg +0 -10
  203. package/assets/download-macos.svg +0 -10
  204. package/assets/download-windows.svg +0 -10
  205. package/gui/dist/assets/App-CpuDF3ci.js +0 -50
  206. package/gui/dist/assets/App-I5AnaSLh.css +0 -1
  207. package/gui/dist/assets/Tray-B4uEIa1O.js +0 -1
  208. package/gui/dist/assets/usage-companion-chart-DLbKOJml.js +0 -1
@@ -80,9 +80,14 @@ export interface AnthropicModelInfo {
80
80
  capabilities: ReturnType<typeof modelCapabilities>;
81
81
  max_input_tokens: number | null;
82
82
  max_tokens: null;
83
+ /**
84
+ * Claude Code (>= 2.1.257) shows this under the picker row instead of the generic
85
+ * "From gateway". Readable (CLI) rows only; Desktop 3P rows keep the ModelInfo shape.
86
+ */
87
+ description?: string;
83
88
  }
84
89
 
85
- function modelInfo(id: string, displayName: string, ladder: readonly string[], imageInput: boolean, contextWindow?: number): AnthropicModelInfo {
90
+ function modelInfo(id: string, displayName: string, ladder: readonly string[], imageInput: boolean, contextWindow?: number, description?: string): AnthropicModelInfo {
86
91
  return {
87
92
  id,
88
93
  display_name: displayName,
@@ -91,6 +96,7 @@ function modelInfo(id: string, displayName: string, ladder: readonly string[], i
91
96
  capabilities: modelCapabilities(ladder, imageInput),
92
97
  max_input_tokens: typeof contextWindow === "number" && contextWindow > 0 ? contextWindow : null,
93
98
  max_tokens: null,
99
+ ...(description === undefined ? {} : { description }),
94
100
  };
95
101
  }
96
102
 
@@ -182,7 +188,13 @@ export function buildAnthropicModelInfos(
182
188
  // A real model always wins its own id, whatever the iteration order.
183
189
  if (realDiscoveryIds.has(id) || seen.has(id)) return;
184
190
  seen.add(id);
185
- out.push({ ...base, id, display_name: `${base.display_name} · Fast` });
191
+ out.push({
192
+ ...base,
193
+ id,
194
+ display_name: `${base.display_name} · Fast`,
195
+ // Fast picks a different tier/variant, so the picker line says so like the name does.
196
+ ...(base.description === undefined ? {} : { description: `${base.description} · Fast` }),
197
+ });
186
198
  };
187
199
  for (const slug of nativeSlugs) {
188
200
  const id = idStyle === "readable" ? claudeCodeNativeAlias(slug) : aliasForRoute("native", slug);
@@ -192,7 +204,8 @@ export function buildAnthropicModelInfos(
192
204
  const nativeMaxInput = nativeOpenAiMaxInputTokens(slug, nativeContextCap);
193
205
  // max_input_tokens is an INPUT limit, so it follows the measured input ceiling rather
194
206
  // than the total window whenever the model publishes one.
195
- const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true, nativeMaxInput ?? nativeWindow);
207
+ const description = idStyle === "readable" ? `Routed by OpenCodex to native ${slug}` : undefined;
208
+ const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true, nativeMaxInput ?? nativeWindow, description);
196
209
  out.push(info);
197
210
  push1mVariant(info, nativeWindow, nativeMaxInput);
198
211
  // Natives too, not only routed rows: gpt-5.6-sol is the flagship Fast model, and
@@ -225,7 +238,8 @@ export function buildAnthropicModelInfos(
225
238
  ? Math.min(m.maxInputTokens, m.contextWindow)
226
239
  : m.maxInputTokens)
227
240
  : undefined;
228
- const info = modelInfo(id, `${listedModelId} (${m.provider})`, ladder, imageInput, routedMaxInput ?? m.contextWindow);
241
+ const description = idStyle === "readable" ? `Routed by OpenCodex to ${m.provider}/${listedModelId}` : undefined;
242
+ const info = modelInfo(id, `${listedModelId} (${m.provider})`, ladder, imageInput, routedMaxInput ?? m.contextWindow, description);
229
243
  out.push(info);
230
244
  // Anthropic passthrough guard (audit 021 #3): never auto-widen canonical claude
231
245
  // routes — only a genuine >=1M window earns the variant row there.
package/src/cli/agent.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  CliUsageError,
3
3
  csv,
4
+ desktopSwitchApplyReason,
4
5
  printData,
5
6
  rejectArgs,
6
7
  runCliAction,
@@ -29,7 +30,7 @@ const USAGE = `Usage:
29
30
  ocx agent fallback <status|set|clear> [model,model...] [--poll-ms <5000-600000>] [--json]
30
31
  ocx agent sidecar <status|web|vision> [--list] [--model <id|->]
31
32
  [--backend web:<openai|anthropic|xai|gemini|exa|-> vision:<openai|anthropic|routed|->]
32
- [--reasoning <level>] [--max-descriptions <n>] [--json]
33
+ [--reasoning <level>] [--max-descriptions <n>] [--enabled <on|off>] [--json]
33
34
  ocx agent request-user-input [on|off] [--json]`;
34
35
 
35
36
  function clearable(value: string | undefined): string | null | undefined {
@@ -188,12 +189,14 @@ async function sidecar(argv: string[], deps: RuntimeApiDeps): Promise<void> {
188
189
  const backend = takeOption(args, "--backend");
189
190
  const reasoning = takeOption(args, "--reasoning");
190
191
  const maxDescriptionsPerTurn = takeIntegerOption(args, "--max-descriptions", { min: 1 });
192
+ const enabled = takeBooleanOption(args, "--enabled");
191
193
  rejectArgs(args, USAGE);
192
194
  const settings: Record<string, unknown> = {};
193
195
  if (model !== undefined) settings.model = model === "-" ? "" : model;
194
196
  if (backend !== undefined) settings.backend = backend === "-" ? null : backend;
195
197
  if (reasoning !== undefined) settings.reasoning = reasoning;
196
198
  if (maxDescriptionsPerTurn !== undefined) settings.maxDescriptionsPerTurn = maxDescriptionsPerTurn;
199
+ if (enabled !== undefined) settings.enabled = enabled;
197
200
  if (Object.keys(settings).length === 0) throw new CliUsageError("at least one sidecar option is required", USAGE);
198
201
  if (section === "web" && model !== undefined && model !== "-") {
199
202
  const offered = await runtimeRequest("/api/sidecar-settings", {}, deps) as {
@@ -210,7 +213,18 @@ async function sidecar(argv: string[], deps: RuntimeApiDeps): Promise<void> {
210
213
  }
211
214
  const body = section === "web" ? { webSearch: settings } : { vision: settings };
212
215
  const result = await runtimeRequest("/api/sidecar-settings", { method: "PUT", body: JSON.stringify(body) }, deps);
213
- printData(result, wantsJson, [`${section} sidecar settings updated.`]);
216
+ const lines = [`${section} sidecar settings updated.`];
217
+ // Only a switch that MOVED owes a Codex-side write, and only the server can say whether that
218
+ // write happened — silence here would read as "the native tool is off now" either way. The
219
+ // wording is the Desktop switches' one vocabulary for the same report.
220
+ const apply = (result as { codexWebSearch?: { applied?: boolean; reason?: string; detail?: string } } | null)?.codexWebSearch;
221
+ if (apply && apply.reason !== "not_requested") {
222
+ const detail = typeof apply.detail === "string" && apply.detail.length > 0 ? ` Details: ${apply.detail}` : "";
223
+ lines.push(apply.applied === true
224
+ ? "Codex config: ~/.codex/config.toml was rewritten."
225
+ : `Codex config: ~/.codex/config.toml was not rewritten because ${desktopSwitchApplyReason(apply.reason)}.${detail} Run 'ocx sync' to apply the stored settings.`);
226
+ }
227
+ printData(result, wantsJson, lines);
214
228
  }
215
229
 
216
230
  export async function handleAgentCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
@@ -784,7 +784,7 @@ export const CAPABILITIES: readonly Capability[] = [
784
784
  summary: "Restart the Codex desktop app and app-servers.",
785
785
  routes: [{ method: "POST", path: "/api/system/codex-restart" }],
786
786
  flags: [
787
- { name: "--yes", value: "boolean", summary: "Required: fully quits and relaunches the operator's Codex desktop app and restarts its app-servers." },
787
+ { name: "--yes", value: "boolean", summary: "Required: fully quits and relaunches the operator's Codex desktop app, which may discard unsaved composer drafts, model-picker selections, and pending approval prompts; also restarts its app-servers." },
788
788
  { name: "--json", value: "boolean", summary: "Emit the restart result as JSON." },
789
789
  ],
790
790
  mutates: true,
@@ -792,7 +792,7 @@ export const CAPABILITIES: readonly Capability[] = [
792
792
  details: [
793
793
  "`sync --restart-codex` is not a substitute: it restarts only as a side effect after a catalog or cache write, so it cannot restart a healthy install on request.",
794
794
  "Restarts the Codex desktop app as well as the app-servers, through the same module the CLI uses. When the proxy itself runs inside the Codex app it refuses instead, because restarting the app would kill the request.",
795
- "--yes is mandatory because this interrupts a running editor session, which must never happen because an agent guessed a subcommand.",
795
+ "--yes is mandatory because this interrupts a running editor session and may discard unsaved composer drafts, model-picker selections, and pending approval prompts; it must never happen because an agent guessed a subcommand.",
796
796
  ],
797
797
  },
798
798
  {
@@ -806,6 +806,75 @@ export const CAPABILITIES: readonly Capability[] = [
806
806
  "Distinct from `claude desktop show`, which reports what this machine WOULD write; this reports what is actually in effect, which only the running proxy knows.",
807
807
  ],
808
808
  },
809
+ {
810
+ command: ["claude", "desktop", "bind"],
811
+ summary: "First-party: serve a Claude Desktop Code tab picker model with an opencodex route.",
812
+ routes: [{ method: "PUT", path: "/api/claude-desktop/first-party-bindings" }],
813
+ flags: [],
814
+ mutates: true,
815
+ json: "none",
816
+ details: [
817
+ "Takes a picker model id (claude-sonnet-4-6) and a route in the Desktop route vocabulary (provider/model or native/<slug>); the route must be one the Desktop profile can offer.",
818
+ "Only Claude Code traffic that reaches the proxy through the first-party intercept (Desktop's Code tab, the claude CLI) honours it; ocx claude and the public Messages endpoint are unaffected.",
819
+ "The Desktop picker keeps Anthropic's label; the binding changes which model answers, starting with the next request.",
820
+ ],
821
+ },
822
+ {
823
+ command: ["claude", "desktop", "unbind"],
824
+ summary: "Remove a first-party Claude Desktop Code tab picker binding.",
825
+ routes: [{ method: "PUT", path: "/api/claude-desktop/first-party-bindings" }],
826
+ flags: [],
827
+ mutates: true,
828
+ json: "none",
829
+ details: [
830
+ "Removing an id that is not bound is a no-op; the remaining bindings are printed.",
831
+ ],
832
+ },
833
+ {
834
+ command: ["claude", "desktop", "picker", "status"],
835
+ summary: "First-party picker mode: whether Claude Desktop's Code tab lists opencodex models, and what is missing if not.",
836
+ routes: [{ method: "GET", path: "/api/claude-desktop/picker" }],
837
+ flags: [],
838
+ mutates: false,
839
+ json: "none",
840
+ details: [
841
+ "Reports desired, effective, keychain trust, the Desktop egress profile, the model count and a reason with the next command to run.",
842
+ ],
843
+ },
844
+ {
845
+ command: ["claude", "desktop", "picker", "on"],
846
+ summary: "Turn first-party picker mode on and remember the choice.",
847
+ routes: [{ method: "PUT", path: "/api/claude-desktop/picker" }],
848
+ flags: [],
849
+ mutates: true,
850
+ json: "none",
851
+ details: [
852
+ "Needs a running proxy, first-party mode and macOS. The first time, macOS asks to trust a local certificate authority limited to claude.ai; when the server cannot show that prompt the command runs the trust step in this terminal.",
853
+ "Claude Desktop then reaches the network through opencodex; fully quit and reopen Desktop afterwards.",
854
+ ],
855
+ },
856
+ {
857
+ command: ["claude", "desktop", "picker", "off"],
858
+ summary: "Turn first-party picker mode off, remove its Desktop egress profile and certificate trust, and remember the choice.",
859
+ routes: [{ method: "PUT", path: "/api/claude-desktop/picker" }],
860
+ flags: [],
861
+ mutates: true,
862
+ json: "none",
863
+ details: [
864
+ "Works without a running proxy: the preference is saved and the picker profile and trust are removed locally.",
865
+ ],
866
+ },
867
+ {
868
+ command: ["claude", "desktop", "picker", "trust"],
869
+ summary: "Run the macOS keychain step for picker mode in this terminal, then ask the server to finish enabling it.",
870
+ routes: [{ method: "PUT", path: "/api/claude-desktop/picker" }],
871
+ flags: [],
872
+ mutates: true,
873
+ json: "none",
874
+ details: [
875
+ "The server removes trust this command added if the enable is refused; if the request is lost, trust is left alone and picker status tells what happened.",
876
+ ],
877
+ },
809
878
  {
810
879
  command: ["integration", "native"],
811
880
  summary: "Show or toggle the native Claude, Claude Desktop, Codex, and Grok integrations, and read the Cursor status (which builds are installed, gateway values, last request seen).",