@bitkyc08/opencodex 2.77.0 → 2.78.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 (222) hide show
  1. package/bin/ocx.mjs +11 -10
  2. package/gui/dist/assets/App-BtfG5id-.js +54 -0
  3. package/gui/dist/assets/App-lCIslZ1L.css +1 -0
  4. package/gui/dist/assets/{Tray-gloIYNaW.js → Tray-DiJpSub0.js} +1 -1
  5. package/gui/dist/assets/index-Btc3Ogw4.js +94 -0
  6. package/gui/dist/assets/index-DmQB8D_R.css +1 -0
  7. package/gui/dist/assets/quota-summary-B_a96nXj.js +1 -0
  8. package/gui/dist/index.html +2 -2
  9. package/package.json +1 -1
  10. package/src/adapters/anthropic/beta-allowlist.ts +19 -2
  11. package/src/adapters/anthropic/client-identity.ts +13 -4
  12. package/src/adapters/anthropic/native-client-preamble.ts +31 -0
  13. package/src/adapters/anthropic/passthrough.ts +103 -25
  14. package/src/adapters/devin/cloud-direct/chat.ts +7 -2
  15. package/src/adapters/devin/trajectory.ts +49 -0
  16. package/src/adapters/devin.ts +13 -0
  17. package/src/adapters/ollama-native.ts +35 -19
  18. package/src/claude/intercept/client-hello.ts +103 -0
  19. package/src/claude/intercept/model-bindings.ts +3 -2
  20. package/src/claude/intercept/picker-listener.ts +279 -66
  21. package/src/cli/access-audio-input.ts +84 -0
  22. package/src/cli/access-audio-live.ts +99 -0
  23. package/src/cli/access-audio.ts +123 -0
  24. package/src/cli/access-data-client.ts +127 -0
  25. package/src/cli/access-data-plane.ts +104 -0
  26. package/src/cli/access-data-response.ts +76 -0
  27. package/src/cli/access.ts +65 -2
  28. package/src/cli/account-api.ts +30 -6
  29. package/src/cli/account-auth.ts +111 -42
  30. package/src/cli/account-key-quota.ts +118 -0
  31. package/src/cli/account-main.ts +11 -4
  32. package/src/cli/account-next-actions.ts +63 -0
  33. package/src/cli/account-policy-dto.ts +68 -0
  34. package/src/cli/account-policy.ts +167 -0
  35. package/src/cli/account-target.ts +8 -0
  36. package/src/cli/account.ts +34 -8
  37. package/src/cli/agent-runtime-settings.ts +130 -0
  38. package/src/cli/agent-settings.ts +101 -0
  39. package/src/cli/agent.ts +19 -2
  40. package/src/cli/alias.ts +7 -2
  41. package/src/cli/aside-profiles.ts +2 -2
  42. package/src/cli/capabilities-access-remote.ts +147 -0
  43. package/src/cli/capabilities-accounts.ts +195 -0
  44. package/src/cli/capabilities-agents-routing.ts +414 -0
  45. package/src/cli/capabilities-base.ts +783 -0
  46. package/src/cli/capabilities-command.ts +1 -0
  47. package/src/cli/capabilities-integrations.ts +264 -0
  48. package/src/cli/capabilities-lab.ts +214 -0
  49. package/src/cli/capabilities-observe-system.ts +662 -0
  50. package/src/cli/capabilities-provider-models.ts +302 -0
  51. package/src/cli/capabilities.ts +30 -1199
  52. package/src/cli/capability-types.ts +54 -0
  53. package/src/cli/catalog-command-result.ts +57 -0
  54. package/src/cli/chatgpt-command.ts +25 -2
  55. package/src/cli/claude-agent-startup-sync.ts +17 -0
  56. package/src/cli/claude-desktop-profile.ts +100 -0
  57. package/src/cli/claude-desktop.ts +39 -6
  58. package/src/cli/codex-shim-autorestore.ts +2 -1
  59. package/src/cli/codex-shim-readiness.ts +23 -3
  60. package/src/cli/combo-input.ts +88 -0
  61. package/src/cli/combo-result.ts +52 -0
  62. package/src/cli/combo-stats.ts +123 -0
  63. package/src/cli/combo.ts +37 -14
  64. package/src/cli/companion-timeline.ts +142 -0
  65. package/src/cli/companion-usage.ts +146 -0
  66. package/src/cli/companion.ts +12 -3
  67. package/src/cli/config-command.ts +24 -8
  68. package/src/cli/dispatch.ts +52 -79
  69. package/src/cli/doctor.ts +22 -4
  70. package/src/cli/help-catalog.ts +31 -14
  71. package/src/cli/help-recovery.ts +2 -2
  72. package/src/cli/help.ts +25 -11
  73. package/src/cli/index.ts +38 -27
  74. package/src/cli/injection-follow.ts +35 -0
  75. package/src/cli/inspect.ts +5 -0
  76. package/src/cli/integration-aside-sync.ts +69 -0
  77. package/src/cli/integration-cursor.ts +106 -0
  78. package/src/cli/integration-input.ts +60 -0
  79. package/src/cli/integration-journal.ts +49 -0
  80. package/src/cli/integration-plan-dto.ts +156 -0
  81. package/src/cli/integration-preview.ts +215 -0
  82. package/src/cli/integrations.ts +24 -18
  83. package/src/cli/json-input.ts +134 -0
  84. package/src/cli/link.ts +32 -4
  85. package/src/cli/local-sync-result.ts +41 -0
  86. package/src/cli/log-follow.ts +84 -0
  87. package/src/cli/log-view-filter.ts +146 -0
  88. package/src/cli/logout-command.ts +44 -0
  89. package/src/cli/model-picker-ordering.ts +137 -0
  90. package/src/cli/models-custom-input.ts +107 -0
  91. package/src/cli/models-custom-runtime.ts +112 -0
  92. package/src/cli/models-order.ts +194 -0
  93. package/src/cli/models-runtime-subcommands.ts +2 -0
  94. package/src/cli/models-runtime.ts +7 -0
  95. package/src/cli/models.ts +66 -81
  96. package/src/cli/observe-stream.ts +142 -0
  97. package/src/cli/observe.ts +75 -34
  98. package/src/cli/provider-batch.ts +77 -0
  99. package/src/cli/provider-lifecycle-runtime.ts +170 -0
  100. package/src/cli/provider-result.ts +124 -0
  101. package/src/cli/provider-runtime.ts +15 -12
  102. package/src/cli/provider-settings.ts +143 -0
  103. package/src/cli/provider.ts +112 -34
  104. package/src/cli/registry.ts +62 -20
  105. package/src/cli/remote-workspace-hub.ts +83 -0
  106. package/src/cli/remote-workspace.ts +6 -1
  107. package/src/cli/restart-failure.ts +27 -0
  108. package/src/cli/root.ts +12 -0
  109. package/src/cli/route-policy-write.ts +137 -0
  110. package/src/cli/route-policy.ts +8 -0
  111. package/src/cli/runtime-api.ts +56 -79
  112. package/src/cli/secret-args.ts +149 -0
  113. package/src/cli/settings-result.ts +30 -0
  114. package/src/cli/storage.ts +77 -7
  115. package/src/cli/system-command.ts +60 -2
  116. package/src/cli/system-restart-client.ts +20 -3
  117. package/src/cli/system-settings-parity.ts +83 -0
  118. package/src/cli/update-restart-candidate.ts +21 -0
  119. package/src/cli/update-restart-child.ts +81 -0
  120. package/src/cli/update-restart-home.ts +38 -0
  121. package/src/cli/update-restart-transport.ts +193 -0
  122. package/src/cli/update-restart.ts +260 -0
  123. package/src/cli/usage-model-search.ts +58 -0
  124. package/src/cli/usage-report.ts +13 -5
  125. package/src/cli/v2-input.ts +66 -0
  126. package/src/cli/v2-local-output.ts +37 -0
  127. package/src/cli/v2-runtime.ts +90 -0
  128. package/src/cli/v2.ts +102 -144
  129. package/src/clients/config-export/dsh.ts +21 -0
  130. package/src/clients/config-export.ts +7 -1
  131. package/src/codex/catalog/build-entries.ts +1 -1
  132. package/src/codex/catalog/bundled.ts +9 -2
  133. package/src/codex/catalog/heal-observation.ts +66 -0
  134. package/src/codex/catalog/publication-observer.ts +19 -0
  135. package/src/codex/catalog/remote.ts +13 -15
  136. package/src/codex/catalog/restore.ts +19 -6
  137. package/src/codex/catalog/retained-sync.ts +58 -10
  138. package/src/codex/catalog/routed-removal.ts +116 -0
  139. package/src/codex/catalog/write-audit-contract.ts +21 -0
  140. package/src/codex/catalog/write-audit.ts +171 -0
  141. package/src/codex/catalog-self-heal.ts +284 -0
  142. package/src/codex/catalog-write-serialization.ts +71 -7
  143. package/src/codex/codex-home-owner.ts +124 -0
  144. package/src/codex/convergence.ts +55 -15
  145. package/src/codex/features.ts +8 -1
  146. package/src/codex/inject/restore.ts +46 -4
  147. package/src/codex/inject.ts +11 -1
  148. package/src/codex/internal/catalog-writer.ts +120 -13
  149. package/src/codex/journal.ts +49 -13
  150. package/src/codex/management-convergence.ts +3 -0
  151. package/src/codex/quota-types.ts +3 -0
  152. package/src/codex/quota.ts +13 -3
  153. package/src/codex/refresh.ts +20 -9
  154. package/src/codex/runtime.ts +7 -1
  155. package/src/codex/shim-diagnostics.ts +80 -0
  156. package/src/codex/shim-fingerprint.ts +7 -2
  157. package/src/codex/shim-migration.ts +153 -0
  158. package/src/codex/shim-overlay.ts +509 -0
  159. package/src/codex/shim-path-resolution.ts +14 -2
  160. package/src/codex/shim-probe.ts +4 -3
  161. package/src/codex/shim-state-file.ts +93 -7
  162. package/src/codex/shim.ts +15 -68
  163. package/src/codex/sync.ts +24 -4
  164. package/src/combos/failover.ts +19 -0
  165. package/src/combos/index.ts +1 -0
  166. package/src/combos/resolve.ts +12 -0
  167. package/src/config/atomic-write.ts +13 -8
  168. package/src/config/diagnostics.ts +19 -1
  169. package/src/config/load-degrade.ts +3 -0
  170. package/src/config/schema/chatgpt-desktop.ts +22 -0
  171. package/src/config/schema/config-schema.ts +32 -14
  172. package/src/config/schema/leaf-validators.ts +3 -2
  173. package/src/generated/compatibility-version.json +445 -129
  174. package/src/integrations/merge.ts +13 -5
  175. package/src/integrations/mutation-plan.ts +46 -3
  176. package/src/integrations/omp-yaml-source.ts +181 -1
  177. package/src/integrations/ownership-policy.ts +66 -0
  178. package/src/integrations/registry.ts +50 -1
  179. package/src/integrations/state.ts +46 -21
  180. package/src/integrations/target.ts +25 -2
  181. package/src/integrations/writer.ts +89 -31
  182. package/src/lib/package-tree-integrity.ts +42 -1
  183. package/src/lib/proxy-env.ts +3 -0
  184. package/src/lib/test-home-guard.ts +2 -1
  185. package/src/oauth/anthropic-account-refusal.ts +19 -8
  186. package/src/oauth/anthropic-routing.ts +17 -12
  187. package/src/oauth/anthropic.ts +27 -2
  188. package/src/oauth/index.ts +6 -8
  189. package/src/oauth/pool-settings-capability.ts +9 -2
  190. package/src/protocols/plan-snapshot.ts +1 -1
  191. package/src/protocols/settings.ts +28 -4
  192. package/src/server/caller-session-identity.ts +32 -0
  193. package/src/server/claude-messages.ts +11 -4
  194. package/src/server/index/serve-options.ts +12 -7
  195. package/src/server/index.ts +1 -1
  196. package/src/server/management/agent-settings-routes.ts +6 -5
  197. package/src/server/management/context.ts +8 -1
  198. package/src/server/management/cursor-integration-routes.ts +3 -3
  199. package/src/server/management/integration-routes.ts +5 -5
  200. package/src/server/management/model-routes.ts +3 -3
  201. package/src/server/management/native-integration-routes.ts +2 -2
  202. package/src/server/management/oauth-account-routes.ts +96 -30
  203. package/src/server/management/route-registry.ts +25 -24
  204. package/src/server/messages-native-eligibility.ts +3 -6
  205. package/src/server/messages-native-oauth.ts +82 -35
  206. package/src/server/messages-native.ts +78 -16
  207. package/src/server/responses/adapter-dispatch.ts +53 -28
  208. package/src/server/responses/core-auth.ts +10 -4
  209. package/src/server/responses/core-combo.ts +46 -6
  210. package/src/service/cli.ts +6 -1
  211. package/src/service/ownership-mutation-lease.d.mts +26 -0
  212. package/src/service/ownership-mutation-lease.mjs +76 -1
  213. package/src/types/config.ts +2 -0
  214. package/src/types/provider.ts +10 -10
  215. package/src/update/index.ts +2 -1
  216. package/src/update/update-failure-guidance.d.mts +6 -0
  217. package/src/update/update-failure-guidance.mjs +30 -5
  218. package/gui/dist/assets/App-COdEeqSj.css +0 -1
  219. package/gui/dist/assets/App-DEpCJEP_.js +0 -54
  220. package/gui/dist/assets/index-Cd7ittMv.css +0 -1
  221. package/gui/dist/assets/index-DwJKFJm5.js +0 -94
  222. package/gui/dist/assets/quota-summary-DGcEJU3h.js +0 -1
@@ -1,1208 +1,39 @@
1
1
  /**
2
- * What `ocx` can do, as data an agent can read without parsing help text.
3
- *
4
- * This is the machine-readable index behind `ocx capabilities`. It relates each CLI
5
- * capability to the management route(s) it drives, which nothing in this repository did
6
- * before: help lived in twenty per-module `USAGE` constants and a hand-written banner
7
- * that a test explicitly licensed to drift from the command registry.
8
- *
9
- * LEAF MODULE. It imports nothing from `src/cli/`, and nothing here may import a command
10
- * module. That is not tidiness. Each command module declares its usage text as a
11
- * top-level `const USAGE`, evaluated at import time, so a cycle back into this table
12
- * would resolve to `undefined` under ESM rather than throwing -- silently emptying the
13
- * usage text that `rejectArgs` hands to `CliUsageError`, in the exact error-reporting
14
- * surface the CLI-operability issues are about. `tests/cli/cli-capabilities.test.ts` asserts
15
- * the absence of those imports and that every rendered usage string is non-empty, so the
16
- * failure mode is loud instead of degraded.
17
- *
18
- * Head-handled surfaces (`--version`, `help`) are declared separately in
19
- * `HEAD_CAPABILITIES`. They exit in the CLI head (`root.ts`) before dispatch and have no
20
- * runner key, so listing them as ordinary capabilities would break the registry parity
21
- * assertion that every canonical entry is a direct runner. `help` is excluded from
22
- * `CLI_COMMANDS` deliberately -- `tests/cli/cli-registry.test.ts` documents it as a
23
- * head-handled pseudo-case -- and that decision is preserved here rather than reversed.
2
+ * Stable discovery facade: literal metadata and types have separate pure owners.
3
+ * The transitive dependency boundary is checked by the CLI capability tests.
4
+ * Command modules must never enter this graph: their top-level usage constants
5
+ * can become undefined through an ESM cycle. This is not an execution sandbox.
24
6
  */
7
+ import { CAPABILITIES as BASE_CAPABILITIES } from "./capabilities-base";
8
+ import type { Capability } from "./capability-types";
9
+ import { PROVIDER_MODEL_CAPABILITIES } from "./capabilities-provider-models";
10
+ import { ACCOUNT_CAPABILITIES } from "./capabilities-accounts";
11
+ import { AGENT_ROUTING_CAPABILITIES } from "./capabilities-agents-routing";
12
+ import { INTEGRATION_CAPABILITIES } from "./capabilities-integrations";
13
+ import { OBSERVE_SYSTEM_CAPABILITIES } from "./capabilities-observe-system";
14
+ import { ACCESS_REMOTE_CAPABILITIES } from "./capabilities-access-remote";
15
+ import { LAB_CAPABILITIES } from "./capabilities-lab";
25
16
 
26
- /** A management route a capability drives. Path text only; never a handler reference. */
27
- export interface CapabilityRoute {
28
- readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
29
- readonly path: string;
30
- }
31
-
32
- export interface CapabilityFlag {
33
- readonly name: string;
34
- readonly value?: "string" | "number" | "boolean";
35
- readonly required?: boolean;
36
- readonly summary: string;
37
- }
38
-
39
- /**
40
- * How a capability emits JSON.
41
- *
42
- * - `payload`: the API payload, largely unwrapped.
43
- * - `envelope`: a CLI-shaped object with its own schema.
44
- * - `none`: no `--json` mode.
45
- */
46
- export type CapabilityJsonMode = "payload" | "envelope" | "none";
47
-
48
- export interface Capability {
49
- /** Command path, e.g. `["account", "pause"]`. */
50
- readonly command: readonly string[];
51
- readonly summary: string;
52
- readonly routes: readonly CapabilityRoute[];
53
- readonly flags: readonly CapabilityFlag[];
54
- readonly mutates: boolean;
55
- readonly json: CapabilityJsonMode;
56
- readonly details?: readonly string[];
57
- /**
58
- * Extra banner rows this capability owns, for surfaces the banner shows separately
59
- * from the bare command (`ocx restore back`, `ocx doctor --reclaim-response-temps`).
60
- * Without this the banner cannot equal the capability set: it legitimately carries more
61
- * rows than there are commands.
62
- */
63
- readonly bannerLines?: readonly string[];
64
- }
65
-
66
- /**
67
- * Surfaces resolved in the CLI head, before dispatch.
68
- *
69
- * They belong in `ocx capabilities` output and in the banner, but not in `CLI_COMMANDS`:
70
- * `--version`, `-v`, and `version` are answered at `root.ts` and exit, so none of them is
71
- * a runner key to parity-check against.
72
- */
73
- export interface HeadCapability {
74
- readonly invocations: readonly string[];
75
- readonly summary: string;
76
- readonly bannerLine: string;
77
- }
78
-
79
- export const HEAD_CAPABILITIES: readonly HeadCapability[] = [
80
- {
81
- invocations: ["--version", "-v", "version"],
82
- summary: "Print the CLI version and exit.",
83
- bannerLine: "ocx --version | -v Print version",
84
- },
85
- {
86
- invocations: ["help", "--help", "-h"],
87
- summary: "Print the command list, or one command's usage with `ocx help <command>`.",
88
- bannerLine: "ocx help [command] Show help for a command",
89
- },
90
- ];
91
-
92
- /**
93
- * Capabilities declared so far. Incomplete by design: later phases add verbs.
94
- * `ocx capabilities` is the index of what is listed here, not of every CLI command.
95
- * A capability must not name a route the command does not actually fetch.
96
- */
97
17
  export const CAPABILITIES: readonly Capability[] = [
98
- {
99
- command: ["chatgpt"],
100
- summary: "Experimental ChatGPT app-server shim: launch, restore or status (macOS only).",
101
- routes: [], flags: [], mutates: true, json: "none",
102
- bannerLines: ["ocx chatgpt <sub> Experimental app-server shim: launch|restore|status (macOS)"],
103
- details: ["Default off; launch requires chatgptDesktop.appServerShim: true. Restore removes the generated launcher."],
104
- },
105
- {
106
- command: ["link", "port"],
107
- summary: "Allocate a free loopback port for a remote home link.",
108
- routes: [],
109
- flags: [{ name: "--json", value: "boolean", summary: "Emit the selected port as JSON." }],
110
- mutates: false,
111
- json: "payload",
112
- },
113
- {
114
- command: ["link", "issue"],
115
- summary: "Issue one link credential and record its tunnel metadata.",
116
- routes: [{ method: "POST", path: "/api/link/issue" }],
117
- flags: [
118
- { name: "--alias", value: "string", required: true, summary: "SSH host alias for the linked machine." },
119
- { name: "--tunnel-port", value: "number", required: true, summary: "Remote loopback port for the reverse tunnel." },
120
- { name: "--json", value: "boolean", summary: "Emit the issue result as JSON." },
121
- ],
122
- mutates: true,
123
- json: "payload",
124
- details: ["Requires the running proxy's admin token on loopback; the one-time data key is printed only on stdout."],
125
- },
126
- {
127
- command: ["link", "status"],
128
- summary: "Read link listener and tunnel status.",
129
- routes: [{ method: "GET", path: "/api/link/status" }],
130
- flags: [{ name: "--json", value: "boolean", summary: "Emit the K16 status payload as JSON." }],
131
- mutates: false,
132
- json: "payload",
133
- },
134
- {
135
- command: ["link", "revoke"],
136
- summary: "Revoke a link credential and remove its link record.",
137
- routes: [{ method: "DELETE", path: "/api/link/{id}" }],
138
- flags: [
139
- { name: "--link-id", value: "string", required: true, summary: "Link id to revoke." },
140
- { name: "--json", value: "boolean", summary: "Emit the revoked link id as JSON." },
141
- ],
142
- mutates: true,
143
- json: "payload",
144
- details: ["Requires the running proxy's admin token on loopback."],
145
- },
146
- {
147
- "command": [
148
- "remote-workspace",
149
- "pair"
150
- ],
151
- "summary": "Enroll this executor with one Hub using a one-time code from stdin and locally approved roots.",
152
- "routes": [],
153
- "flags": [
154
- {
155
- "name": "--json",
156
- "value": "boolean",
157
- "summary": "Emit the public local executor status."
158
- },
159
- {
160
- "name": "--pairing-code-stdin",
161
- "value": "boolean",
162
- "summary": "Read the one-time pairing code from stdin."
163
- },
164
- {
165
- "name": "--root",
166
- "value": "string",
167
- "summary": "Approve an absolute workspace directory; repeatable."
168
- },
169
- {
170
- "name": "--toolchain-root",
171
- "value": "string",
172
- "summary": "Approve a read-only toolchain directory; repeatable."
173
- },
174
- {
175
- "name": "--executor-helper",
176
- "value": "string",
177
- "summary": "Select a reviewed native helper file."
178
- },
179
- {
180
- "name": "--name",
181
- "value": "string",
182
- "summary": "Name this executor."
183
- }
184
- ],
185
- "mutates": true,
186
- "json": "payload",
187
- "details": [
188
- "Executor-local operation; Hub consent and session control stay in the dashboard."
189
- ]
190
- },
191
- {
192
- "command": [
193
- "remote-workspace",
194
- "agent"
195
- ],
196
- "summary": "Keep the paired executor connected to its Hub.",
197
- "routes": [],
198
- "flags": [],
199
- "mutates": true,
200
- "json": "none",
201
- "details": [
202
- "Executor-local operation; Hub consent and session control stay in the dashboard."
203
- ]
204
- },
205
- {
206
- "command": [
207
- "remote-workspace",
208
- "status"
209
- ],
210
- "summary": "Read local executor enrollment and available capabilities without printing credentials.",
211
- "routes": [],
212
- "flags": [
213
- {
214
- "name": "--json",
215
- "value": "boolean",
216
- "summary": "Emit the public local executor status."
217
- }
218
- ],
219
- "mutates": false,
220
- "json": "payload",
221
- "details": [
222
- "Executor-local operation; Hub consent and session control stay in the dashboard."
223
- ]
224
- },
225
- {
226
- command: ["models", "price"],
227
- summary: "Read the saved manual price for an exact provider/model selector.",
228
- routes: [{ method: "GET", path: "/api/providers/{provider}/model-costs" }],
229
- flags: [{ name: "--json", value: "boolean", summary: "Emit provider, modelId, and cost (null for automatic pricing)." }],
230
- mutates: false,
231
- json: "envelope",
232
- details: ["The provider must be configured; everything after the first slash is the exact upstream model ID."],
233
- },
234
- {
235
- command: ["models", "set-price"],
236
- summary: "Save four manual USD-per-1M-token rates, or restore automatic pricing for one model.",
237
- routes: [{ method: "PUT", path: "/api/providers/{provider}/model-costs" }],
238
- flags: [
239
- { name: "--input", value: "number", summary: "Input rate; required unless --auto is used." },
240
- { name: "--output", value: "number", summary: "Output rate; required unless --auto is used." },
241
- { name: "--cache-read", value: "number", summary: "Cache read rate; defaults to 0." },
242
- { name: "--cache-write", value: "number", summary: "Cache write rate; defaults to 0." },
243
- { name: "--auto", value: "boolean", summary: "Remove this model's override; cannot be combined with rates." },
244
- { name: "--json", value: "boolean", summary: "Emit the saved price or reset result as JSON." },
245
- ],
246
- mutates: true,
247
- json: "payload",
248
- details: ["Uses the exact upstream model ID after the first slash. Omitted cache rates default to zero; sibling model prices are preserved."],
249
- },
250
- {
251
- command: ["models", "set"],
252
- summary: "Save per-model overrides for a routed model, or clear them back to the computed values.",
253
- routes: [{ method: "PUT", path: "/api/model-settings" }],
254
- flags: [
255
- { name: "--context-window", value: "string", summary: "Context window in tokens; 0 or - clears the override." },
256
- { name: "--modalities", value: "string", summary: "Comma-separated text,image,audio; - clears the override." },
257
- { name: "--reasoning-efforts", value: "string", summary: "Comma-separated ladder; \"\" for no reasoning, - to inherit." },
258
- { name: "--default-reasoning-effort", value: "string", summary: "Ladder member a request inherits when it omits one; - to inherit." },
259
- { name: "--reset", value: "boolean", summary: "Clear every override on this model; cannot be combined with the options above." },
260
- { name: "--json", value: "boolean", summary: "Emit the saved state as JSON." },
261
- ],
262
- mutates: true,
263
- json: "envelope",
264
- details: [
265
- "Addresses a routed model as provider/model. The native openai lane and combos have no per-model overrides.",
266
- "Unlike ocx models edit, which changes a custom model's own definition, this edits a row that already exists.",
267
- ],
268
- },
269
- {
270
- command: ["status"],
271
- summary: "Proxy status, injection state, and version skew between this CLI and the running proxy.",
272
- // No management route: `collectStatus` identity-probes `/healthz` through
273
- // `findLiveProxy` and reads local config. Declaring `GET /api/status` here was wrong
274
- // -- that route does not exist, and the registry cross-check caught it.
275
- routes: [],
276
- flags: [{ name: "--json", value: "boolean", summary: "Emit the status envelope as JSON." }],
277
- mutates: false,
278
- json: "envelope",
279
- details: ["Reads /healthz plus local config; drives no management API route."],
280
- },
281
- {
282
- command: ["resolve"],
283
- summary: "One JSON document naming the config home, the effective port, and the identity-checked proxy liveness verdict.",
284
- // No management route, same split as status: discovery is the identity-checked
285
- // /healthz probe inside findLiveProxy plus local config and the home from
286
- // src/config/paths.ts.
287
- routes: [],
288
- flags: [{ name: "--json", value: "boolean", summary: "Emit the resolve document as JSON (the shell contract)." }],
289
- mutates: false,
290
- json: "envelope",
291
- details: [
292
- "Exit 0 carries a trustworthy verdict (live or proven absent); exit 1 means the CLI could not resolve and a caller must refuse to guess — unknown liveness never reads as absent.",
293
- "Built for embedding shells (desktop app): the liveness budgets stay owned by src/server/proxy-liveness.ts.",
294
- ],
295
- },
296
- {
297
- command: ["hub", "invite"],
298
- summary: "Mint a single-use pairing code on a hub and print the exact `ocx connect` line for one more machine.",
299
- // Deliberately empty. The command DOES drive `POST /api/gui/pairing-grants` -- the attested
300
- // local mint route `ocx gui pair` uses, authorized by a capability HMAC'd with the running
301
- // proxy's own attestation secret rather than by the admin token, which is why it needs
302
- // nothing exported in the shell. That route is answered in the composition root, ahead of
303
- // `handleManagementAPI`, so it is not in MANAGEMENT_ROUTES; declaring it here would fail the
304
- // capability/registry reconciliation rather than inform anyone. Widening the registry's scope
305
- // to `src/server/index.ts` is its own change.
306
- routes: [],
307
- flags: [
308
- { name: "--json", value: "boolean", summary: "Emit code, expiresAt, dataUrl, managementUrl, and command." },
309
- { name: "--data-url", value: "string", summary: "Advertise this data origin instead of hub.dataPublicOrigin or the bind address." },
310
- { name: "--management-url", value: "string", summary: "Confirm the management origin; it must equal hub.managementPublicOrigin." },
311
- { name: "--clients", value: "string", summary: "Pre-select codex and/or claude in the printed connect command." },
312
- ],
313
- mutates: true,
314
- json: "envelope",
315
- details: [
316
- "Hub only: refuses when runtimeRole is not hub, and requires a running attested proxy.",
317
- "The code is secret, single-use and short-lived; it is bound to hub.managementPublicOrigin and to the connecting machine's loopback browser origin.",
318
- "The bound browser origin is always printed; when it is not http://localhost:10100 the warning names the port the connecting machine must use.",
319
- "Refuses when the advertised data origin would be loopback (a loopback or wildcard bind with no hub.dataPublicOrigin and no --data-url) rather than printing a line that dials the other machine itself.",
320
- "Prints no data-plane token. Remote machines receive their own revocable per-client key from the exchange.",
321
- "Mints through the attested local pairing-grant route, the same one ocx gui pair uses; no admin token is read.",
322
- ],
323
- },
324
- {
325
- command: ["connect", "rotate"],
326
- summary: "Rotate the connected client's data key against the hub, with commit and abort.",
327
- // One command drives all three: start returns the new secret once, commit promotes it,
328
- // and abort unwinds a rotation that could not be confirmed. They are not separate verbs
329
- // because a half-rotation is not a state an operator should be able to leave behind.
330
- routes: [
331
- { method: "POST", path: "/api/keys/rotate" },
332
- { method: "POST", path: "/api/keys/rotate/commit" },
333
- { method: "DELETE", path: "/api/keys/rotate" },
334
- ],
335
- flags: [
336
- { name: "--pairing-code-stdin", value: "boolean", summary: "Read a one-time pairing code from stdin as the rotation authority." },
337
- { name: "--admin-token-stdin", value: "boolean", summary: "Read the hub admin token from stdin as the rotation authority." },
338
- { name: "--json", value: "boolean", summary: "Emit the rotation result as JSON." },
339
- ],
340
- mutates: true,
341
- json: "payload",
342
- details: [
343
- "Requires transient authority on stdin; the credential is never persisted or echoed.",
344
- "A rotation left pending by a crash is resumed here — startup and status stop rather than guess which key generation is live.",
345
- ],
346
- },
347
- {
348
- command: ["capabilities"],
349
- summary: "List the declared CLI capabilities and the management routes they drive.",
350
- routes: [],
351
- flags: [
352
- { name: "--json", value: "boolean", summary: "Emit the full capability table as JSON." },
353
- { name: "--mutating-only", value: "boolean", summary: "Restrict output to capabilities that mutate state." },
354
- { name: "--route", value: "string", summary: "Show which capabilities drive a management route." },
355
- ],
356
- mutates: false,
357
- json: "envelope",
358
- details: ["Start here when driving ocx programmatically: it is the declared surface index, not a complete verb list."],
359
- },
360
- {
361
- command: ["provider", "list"],
362
- summary: "Configured providers with connectivity and selected models.",
363
- // Local config + PROVIDER_REGISTRY. Does not call GET /api/providers.
364
- routes: [],
365
- flags: [
366
- { name: "--json", value: "boolean", summary: "Emit the provider list as JSON." },
367
- { name: "--jsonl", value: "boolean", summary: "Emit one configured provider per JSON line." },
368
- ],
369
- mutates: false,
370
- json: "envelope",
371
- details: ["Reads local config; drives no management API route."],
372
- },
373
- {
374
- command: ["provider", "resets"],
375
- summary: "Recently detected quota resets and whether reset notifications are enabled.",
376
- routes: [{ method: "GET", path: "/api/quota-resets" }],
377
- flags: [
378
- { name: "--json", value: "boolean", summary: "Emit reset events as JSON." },
379
- { name: "--limit", value: "number", summary: "Limit returned events; defaults to 20, capped at 100." },
380
- ],
381
- mutates: false,
382
- json: "payload",
383
- },
384
- {
385
- command: ["provider", "keychain"],
386
- summary: "Move a provider's API key into the OS keychain, restore it, or report where it lives.",
387
- routes: [
388
- { method: "GET", path: "/api/providers/keychain" },
389
- { method: "POST", path: "/api/providers/keychain" },
390
- ],
391
- flags: [{ name: "--json", value: "boolean", summary: "Emit the keychain status or result as JSON." }],
392
- mutates: true,
393
- json: "payload",
394
- details: [
395
- "`store` verifies every keychain write by read-back before config.json is rewritten with keychain: references; an unavailable keychain refuses with 503 and leaves the file untouched.",
396
- "Headless services usually have no unlocked keychain session; prefer ${ENV_VAR} references there.",
397
- ],
398
- },
399
- {
400
- command: ["companion"],
401
- summary: "Inspect and configure menu-bar and widget companion usage settings.",
402
- routes: [
403
- { method: "GET", path: "/api/companion/settings" },
404
- { method: "GET", path: "/api/usage/timeline" },
405
- { method: "PUT", path: "/api/companion/settings" },
406
- ],
407
- flags: [{ name: "--json", value: "boolean", summary: "Emit companion settings as JSON." }],
408
- mutates: true,
409
- json: "payload",
410
- details: [
411
- "`show` (the default) reads settings; `set key=value ...` updates selected settings; `reset` restores defaults.",
412
- "Values accepted by `set` are parsed as JSON when valid, so booleans, numbers, arrays, objects, and null can be passed directly.",
413
- ],
414
- },
415
- {
416
- command: ["account", "login"],
417
- summary: "Log in to an OAuth provider; Kiro can add a native device account.",
418
- routes: [
419
- { method: "POST", path: "/api/oauth/login" },
420
- { method: "GET", path: "/api/oauth/status" },
421
- ],
422
- flags: [
423
- { name: "--method", value: "string", summary: "For Kiro: builder-id, google, or github device login (add only)." },
424
- { name: "--reauth", value: "boolean", summary: "Reauthenticate a selected existing account." },
425
- { name: "--id", value: "string", summary: "Account id for reauthentication." },
426
- { name: "--no-wait", value: "boolean", summary: "Return after the login flow starts." },
427
- { name: "--json", value: "boolean", summary: "Emit flow state as JSON." },
428
- ],
429
- mutates: true,
430
- json: "payload",
431
- },
432
- {
433
- command: ["account", "history"],
434
- summary: "Cached quota observations for one stored Codex pool account.",
435
- routes: [{ method: "GET", path: "/api/codex-auth/quota/history" }],
436
- flags: [
437
- { name: "--json", value: "boolean", summary: "Emit the bounded observation history." },
438
- { name: "--limit", value: "number", summary: "Return the newest 1 to 200 observations." },
439
- ],
440
- mutates: false,
441
- json: "payload",
442
- details: ["Use account history openai <pool-account-id>. Reads cached observations only; no refresh or warmup. Native main is not included."],
443
- },
444
- {
445
- command: ["account", "main", "reauth"],
446
- summary: "Reauthenticate the native main Codex login with a device code (#3898); headless hubs need no Codex App or keyring.",
447
- routes: [
448
- { method: "POST", path: "/api/codex-auth/main/reauth-device" },
449
- { method: "GET", path: "/api/codex-auth/main/reauth-device" },
450
- { method: "DELETE", path: "/api/codex-auth/main/reauth-device" },
451
- ],
452
- flags: [
453
- { name: "--device", value: "boolean", summary: "Run the device-code flow (the only reauth mode)." },
454
- { name: "--no-wait", value: "boolean", summary: "Print the flow handle and code without waiting for completion." },
455
- { name: "--flow", value: "string", summary: "Flow id for status and cancel." },
456
- { name: "--json", value: "boolean", summary: "Emit the flow status as JSON." },
457
- ],
458
- mutates: true,
459
- json: "payload",
460
- details: [
461
- "Same-identity reauth only: the device login must complete for the ChatGPT account that already holds the native main slot, and the commit is fenced by the exclusive claim plus a path/hash/inode snapshot.",
462
- "/api/codex-auth/login stays pool-only and keeps rejecting __main__; this namespace is the only device-reauth surface for the native main slot.",
463
- "Payloads carry only flowId, status, the verification URL, the device code, and a closed set of failure codes -- never tokens, emails, or raw account ids.",
464
- ],
465
- },
466
- {
467
- command: ["account", "list"],
468
- summary: "Codex OAuth accounts with pool priority and pause state.",
469
- routes: [{ method: "GET", path: "/api/codex-auth/accounts" }],
470
- flags: [{ name: "--json", value: "boolean", summary: "Emit the account list as JSON." }],
471
- mutates: false,
472
- json: "payload",
473
- details: [
474
- "STATUS names `paused` alongside `selected`: a paused-but-selected account still receives requests.",
475
- "`--quota` shows cached Codex windows (including 5h); `--refresh` bypasses the server TTL.",
476
- ],
477
- },
478
- {
479
- command: ["account", "import-orca"],
480
- summary: "Preview or register read-only links to Orca-managed Codex accounts without another login.",
481
- routes: [],
482
- flags: [
483
- { name: "--source", value: "string", required: true, summary: "Orca data directory containing codex-accounts." },
484
- { name: "--registry", value: "string", required: true, summary: "The chosen Orca profile's orca-data.json account registry." },
485
- { name: "--apply", value: "boolean", summary: "Register new accounts; requires a stopped proxy. Default is preview." },
486
- { name: "--json", value: "boolean", summary: "Emit counts and fixed invalid-reason codes without credentials or source paths." },
487
- ],
488
- mutates: true,
489
- json: "envelope",
490
- details: [
491
- "Local files only; never copies refresh tokens or changes Orca authentication files.",
492
- "Skips existing ChatGPT identities. New accounts remain pending until dashboard validation.",
493
- "Orca must keep the source login available and refreshed; a missing or expired source fails closed.",
494
- "Mixed eligible and invalid entries exit successfully; an all-invalid result exits nonzero.",
495
- ],
496
- },
497
- {
498
- command: ["account", "refresh"],
499
- summary: "Refresh account quotas without model validation; pending Codex accounts require dashboard consent.",
500
- routes: [
501
- { method: "POST", path: "/api/codex-auth/accounts/refresh" },
502
- { method: "GET", path: "/api/provider-quotas" },
503
- ],
504
- flags: [{ name: "--json", value: "boolean", summary: "Emit the refresh result as JSON." }],
505
- mutates: true,
506
- json: "payload",
507
- details: ["CLI/admin-token refreshes only observe usage. After quota recovery, a human must click Refresh quotas in the dashboard to authorize model validation. Do not mint a GUI session to work around this consent boundary."],
508
- },
509
- {
510
- command: ["account", "grok-reset-coupons"],
511
- summary: "Inspect or redeem Grok billing reset coupons; redemption is journaled and idempotent.",
512
- routes: [
513
- { method: "GET", path: "/api/grok/reset-coupons" },
514
- { method: "POST", path: "/api/grok/reset-coupons/consume" },
515
- ],
516
- flags: [
517
- { name: "--consume", value: "boolean", summary: "Redeem one reset coupon; requires --yes." },
518
- { name: "--yes", value: "boolean", summary: "Explicit confirmation required by --consume." },
519
- { name: "--token-id", value: "string", summary: "Redeem a specific reset token instead of the default selection." },
520
- { name: "--operation-id", value: "string", summary: "UUIDv4 making a redemption idempotent: retries replay the journaled outcome." },
521
- { name: "--json", value: "boolean", summary: "Emit the coupon list or redemption result as JSON." },
522
- ],
523
- mutates: true,
524
- json: "payload",
525
- details: [
526
- "Without --consume this is a read: remaining coupons and their validity windows.",
527
- "The operation is journaled before the upstream call, so retrying the same --operation-id replays the recorded outcome instead of spending a second coupon.",
528
- ],
529
- },
530
- {
531
- command: ["usage"],
532
- summary: "Token and estimated-cost report over a time range.",
533
- routes: [{ method: "GET", path: "/api/usage" }],
534
- flags: [
535
- { name: "--range", value: "string", summary: "today | 1d | 7d | 30d | all" },
536
- { name: "--since", value: "string", summary: "Inclusive start: epoch milliseconds or full ISO datetime with timezone; requires --until and overrides --range." },
537
- { name: "--until", value: "string", summary: "Inclusive end: epoch milliseconds or full ISO datetime with timezone; requires --since." },
538
- { name: "--provider", value: "string", summary: "Restrict to one provider." },
539
- { name: "--model", value: "string", summary: "Restrict to one model id." },
540
- { name: "--json", value: "boolean", summary: "Emit the usage report as JSON." },
541
- ],
542
- mutates: false,
543
- json: "payload",
544
- details: [
545
- "Per-account totals are withheld under `--provider` or `--model`: account rows cannot be honestly re-partitioned by provider, so the report says so rather than printing an empty table.",
546
- "An `(ambiguous)` account row aggregates several accounts; do not read it as one identity.",
547
- ],
548
- },
549
- {
550
- command: ["account", "pause"],
551
- summary: "Exclude one account in a Codex, Anthropic or supported generic OAuth pool from automatic selection.",
552
- // Resume uses the same endpoints with `paused: false`.
553
- routes: [
554
- { method: "PUT", path: "/api/codex-auth/accounts/pause" },
555
- { method: "GET", path: "/api/oauth/accounts" },
556
- { method: "PUT", path: "/api/oauth/accounts/pause" },
557
- ],
558
- flags: [{ name: "--json", value: "boolean", summary: "Emit the pause result as JSON." }],
559
- mutates: true,
560
- json: "envelope",
561
- details: [
562
- "Codex pause unbinds pinned threads and selects a fallback when possible; with no fallback, a paused-but-selected Codex account still receives requests. Anthropic and generic OAuth pause exclude the account from new requests, failover and refresh, and an all-paused pool answers 403. Credentials and health are preserved; already-sent turns are not cancelled.",
563
- ],
564
- },
565
- {
566
- command: ["account", "resume"],
567
- summary: "Return a paused account to a Codex, Anthropic or supported generic OAuth pool.",
568
- routes: [
569
- { method: "PUT", path: "/api/codex-auth/accounts/pause" },
570
- { method: "GET", path: "/api/oauth/accounts" },
571
- { method: "PUT", path: "/api/oauth/accounts/pause" },
572
- ],
573
- flags: [{ name: "--json", value: "boolean", summary: "Emit the resume result as JSON." }],
574
- mutates: true,
575
- json: "envelope",
576
- },
577
- {
578
- command: ["account", "pause-exhausted"],
579
- summary: "Pause every Codex account whose quota is spent.",
580
- routes: [{ method: "PUT", path: "/api/codex-auth/accounts/pause-exhausted" }],
581
- flags: [{ name: "--json", value: "boolean", summary: "Emit paused ids and the checked/failed counts as JSON." }],
582
- mutates: true,
583
- json: "envelope",
584
- details: [
585
- "The route refreshes quota per account and can partially fail; a non-zero failed count exits 1 and sets ok:false, because silence would read as `none were exhausted`.",
586
- ],
587
- },
588
- {
589
- command: ["account", "strategy"],
590
- summary: "Show or set how an account pool picks the next account.",
591
- // Both pools, because both have the setting. The Codex pool reads its applied values
592
- // from the active payload; the Anthropic pool has its own GET.
593
- routes: [
594
- { method: "GET", path: "/api/pool/settings" },
595
- { method: "PUT", path: "/api/pool/settings" },
596
- { method: "PATCH", path: "/api/pool/settings" },
597
- ],
598
- flags: [{ name: "--json", value: "boolean", summary: "Emit the applied strategy and sticky limit as JSON." }],
599
- mutates: true,
600
- json: "envelope",
601
- details: [
602
- "A bare invocation reads and never writes.",
603
- "The APPLIED value is echoed, not the requested one, so a server-side normalization stays visible.",
604
- "Values are not re-validated in the CLI: the server owns the strategy names and the 1-100 sticky bound.",
605
- "One route answers for every pool kind and declares which fields that kind honours in `supported`, so an unsupported field is a stated null rather than an absence. `anthropic` alone carries `quotaWindow`. Generic-provider settings steer selection only while `pool.kernel` is on. The legacy per-pool paths still work and are unchanged.",
606
- ],
607
- },
608
- {
609
- command: ["account", "sticky"],
610
- summary: "Show or set how many consecutive requests stay on one account.",
611
- routes: [
612
- { method: "GET", path: "/api/pool/settings" },
613
- { method: "PUT", path: "/api/pool/settings" },
614
- { method: "PATCH", path: "/api/pool/settings" },
615
- ],
616
- flags: [{ name: "--json", value: "boolean", summary: "Emit the applied strategy and sticky limit as JSON." }],
617
- mutates: true,
618
- json: "envelope",
619
- details: ["Only meaningful under the sticky-capable strategies; the pool strategy is the other half of this setting."],
620
- },
621
- {
622
- command: ["account", "routes"],
623
- summary: "Read, replace, or clear Anthropic OAuth model account routes.",
624
- routes: [{ method: "GET", path: "/api/pool/settings" }, { method: "PUT", path: "/api/pool/settings" }],
625
- flags: [
626
- { name: "--file", value: "string", summary: "Read a bounded JSON route array from a local file." },
627
- { name: "--clear", value: "boolean", summary: "Remove the stored routes." },
628
- { name: "--json", value: "boolean", summary: "Emit the unified settings response as JSON." },
629
- ],
630
- mutates: true,
631
- json: "envelope",
632
- details: ["Only anthropic is supported. The server validates route names, patterns, and account IDs."],
633
- },
634
- {
635
- command: ["account", "auto-switch"],
636
- summary: "Show or set the usage percentage at which a pool moves to another account.",
637
- // Declared here rather than riding on `account strategy`, which is what it did before the
638
- // unified route existed. `auto-switch` genuinely drives these three: the Codex pool reads
639
- // its applied threshold from the active payload and writes through its own route, and a
640
- // generic OAuth pool reads and writes the per-provider pool settings.
641
- routes: [
642
- { method: "GET", path: "/api/codex-auth/active" },
643
- { method: "PUT", path: "/api/codex-auth/auto-switch" },
644
- { method: "GET", path: "/api/oauth/accounts/pool" },
645
- { method: "PUT", path: "/api/oauth/accounts/pool" },
646
- { method: "GET", path: "/api/oauth/accounts" },
647
- { method: "PUT", path: "/api/oauth/accounts/auto-switch" },
648
- ],
649
- flags: [{ name: "--json", value: "boolean", summary: "Emit the stored threshold and whether it is applied." },
650
- { name: "--account", value: "string", summary: "Anthropic account ID; inherit restores the pool default, off stores zero." }],
651
- mutates: true,
652
- json: "envelope",
653
- details: [
654
- "A bare invocation reads and never writes.",
655
- "`on` stores 80%, `off` stores 0%, and `threshold <n>` accepts 0-100.",
656
- "Anthropic requires --account <id>; inherit sends null to restore its pool default. Manual/affinity precedence and pool-off recovery are unchanged.",
657
- "For a generic OAuth pool, `inert: true` means the threshold is stored but not applied, `inert: false` means the pool is applying it, and an absent `inert` is an unknown capability.",
658
- ],
659
- },
660
-
661
- {
662
- command: ["logs"],
663
- summary: "Recent request log rows, filterable by provider, model, conversation, account, and status.",
664
- routes: [{ method: "GET", path: "/api/logs" }],
665
- flags: [
666
- { name: "--provider", value: "string", summary: "Restrict to one provider, matching failover attempts too." },
667
- { name: "--model", value: "string", summary: "Restrict to one model id, matching failover attempts too." },
668
- { name: "--conversation", value: "string", summary: "Restrict to one conversation id (`--conversationId` is accepted too)." },
669
- { name: "--account", value: "string", summary: "Restrict to one account log label (`main`, `p<hex6>`, `o<hex6>`), matching failover attempts too." },
670
- { name: "--status", value: "string", summary: "An exact code (429) or a class (5xx)." },
671
- { name: "--limit", value: "number", summary: "Row cap; defaults to 200." },
672
- { name: "--follow", value: "boolean", summary: "Poll for new rows; add --jsonl to emit JSONL." },
673
- { name: "--json", value: "boolean", summary: "Emit the server payload as JSON." },
674
- { name: "--jsonl", value: "boolean", summary: "Emit one row per line." },
675
- ],
676
- mutates: false,
677
- json: "payload",
678
- details: [
679
- "`--provider` and `--model` both match a failover attempt, so a request is findable by what actually served it, not only by what was asked for.",
680
- "Rows print `conv=<id>` when the entry carries one, so a conversation filter can be told apart from an empty result.",
681
- "Rows print `acct=<label>` when the account is known, so an `--account` filter can be told apart from an empty result.",
682
- "`--follow` deduplicates by row id and cannot be combined with `--json`.",
683
- ],
684
- },
685
- {
686
- command: ["storage", "report"],
687
- summary: "Disk usage under CODEX_HOME, with the log-guard protection report.",
688
- routes: [{ method: "GET", path: "/api/storage" }],
689
- flags: [{ name: "--json", value: "boolean", summary: "Emit the storage report as JSON." }],
690
- mutates: false,
691
- json: "payload",
692
- bannerLines: ["ocx storage Storage report (default subcommand)"],
693
- },
694
- {
695
- command: ["storage", "cleanup"],
696
- summary: "Preview or delete the oldest archived sessions by percentage.",
697
- // Both routes, because the verb always previews: the mutating route requires the digest the
698
- // preview returns and rejects a stale one, so the two are one operation.
699
- routes: [
700
- { method: "POST", path: "/api/storage/cleanup/preview" },
701
- { method: "POST", path: "/api/storage/cleanup" },
702
- ],
703
- flags: [
704
- { name: "--percent", value: "number", summary: "Portion of the oldest archived sessions to target (0-100)." },
705
- { name: "--mode", value: "string", summary: "quarantine (recoverable from trash) or permanent." },
706
- { name: "--yes", value: "boolean", summary: "Required to actually delete; without it this is a preview." },
707
- { name: "--json", value: "boolean", summary: "Emit the preview or result as JSON." },
708
- ],
709
- mutates: true,
710
- json: "payload",
711
- details: [
712
- "Without `--yes` it prints what WOULD be freed and exits 0 having changed nothing.",
713
- "There is no interactive confirmation: a prompt an agent can answer is not a safety boundary.",
714
- "`--mode quarantine` moves files to trash, so `storage trash restore` can undo it; `permanent` cannot be undone.",
715
- ],
716
- },
717
- {
718
- command: ["storage", "trash"],
719
- summary: "List quarantined cleanup batches, or restore one.",
720
- routes: [
721
- { method: "GET", path: "/api/storage/trash" },
722
- { method: "POST", path: "/api/storage/trash/restore" },
723
- ],
724
- flags: [
725
- { name: "--yes", value: "boolean", summary: "Required for restore, which moves files and reconciles database rows." },
726
- { name: "--json", value: "boolean", summary: "Emit the trash list or restore result as JSON." },
727
- ],
728
- mutates: true,
729
- json: "payload",
730
- details: ["Restore fails with a named 409 when the destination already exists, rather than overwriting it."],
731
- },
732
- {
733
- command: ["storage", "policy"],
734
- summary: "Show, change, or run the automatic archived-session cleanup policy.",
735
- routes: [
736
- { method: "GET", path: "/api/storage/cleanup-policy" },
737
- { method: "PUT", path: "/api/storage/cleanup-policy" },
738
- { method: "POST", path: "/api/storage/cleanup-policy/run" },
739
- ],
740
- flags: [
741
- { name: "--enabled", value: "string", summary: "true or false." },
742
- { name: "--percent", value: "number", summary: "Portion of oldest archived sessions each run targets." },
743
- { name: "--mode", value: "string", summary: "quarantine or permanent." },
744
- { name: "--schedule", value: "string", summary: "startup, daily, weekly, or manual." },
745
- { name: "--yes", value: "boolean", summary: "Required for `policy run`, which deletes immediately." },
746
- { name: "--json", value: "boolean", summary: "Emit the policy or run state as JSON." },
747
- ],
748
- mutates: true,
749
- json: "payload",
750
- details: [
751
- "`policy set` never enables implicitly: omitting `--enabled` keeps the stored value.",
752
- "`policy run` forces a run regardless of schedule, so it needs `--yes`.",
753
- ],
754
- },
755
- {
756
- command: ["inspect", "config"],
757
- summary: "The effective merged configuration the proxy is running.",
758
- routes: [{ method: "GET", path: "/api/config" }],
759
- flags: [{ name: "--json", value: "boolean", summary: "Emit the config as JSON." }],
760
- mutates: false,
761
- json: "payload",
762
- },
763
- {
764
- command: ["inspect", "catalog"],
765
- summary: "The generated model catalog served to clients.",
766
- routes: [{ method: "GET", path: "/api/catalog" }],
767
- flags: [{ name: "--json", value: "boolean", summary: "Emit the catalog as JSON." }],
768
- mutates: false,
769
- json: "payload",
770
- },
771
- {
772
- command: ["inspect", "routing-analytics"],
773
- summary: "Aggregate routing outcomes per provider and model.",
774
- routes: [{ method: "GET", path: "/api/routing-analytics" }],
775
- flags: [{ name: "--json", value: "boolean", summary: "Emit the analytics payload as JSON." }],
776
- mutates: false,
777
- json: "payload",
778
- },
779
- {
780
- command: ["inspect", "pacing"],
781
- summary: "Request-pacing state for one provider or all of them.",
782
- routes: [{ method: "GET", path: "/api/provider-request-pacing" }],
783
- flags: [
784
- { name: "--name", value: "string", summary: "Restrict to one provider; omitted means every provider." },
785
- { name: "--json", value: "boolean", summary: "Emit the pacing state as JSON." },
786
- ],
787
- mutates: false,
788
- json: "payload",
789
- details: ["An unknown provider name is a 404 rather than an empty result."],
790
- },
791
- {
792
- command: ["inspect", "key-providers"],
793
- summary: "Providers that authenticate with an API key rather than OAuth.",
794
- routes: [{ method: "GET", path: "/api/key-providers" }],
795
- flags: [{ name: "--json", value: "boolean", summary: "Emit the provider list as JSON." }],
796
- mutates: false,
797
- json: "payload",
798
- },
799
- {
800
- command: ["inspect", "codex-prompt"],
801
- summary: "The Codex system prompt state, or the prompt text itself.",
802
- routes: [
803
- { method: "GET", path: "/api/codex-prompt" },
804
- { method: "GET", path: "/api/codex-prompt/text" },
805
- ],
806
- flags: [
807
- { name: "--text", value: "boolean", summary: "Print the prompt body verbatim instead of its metadata." },
808
- { name: "--json", value: "boolean", summary: "Emit the prompt metadata as JSON." },
809
- ],
810
- mutates: false,
811
- json: "payload",
812
- details: ["Read-only by design: the six mutating prompt routes require a dashboard session."],
813
- },
814
- {
815
- command: ["inspect", "client-config"],
816
- summary: "The generated configuration snippet for a supported client.",
817
- routes: [{ method: "GET", path: "/api/client-config" }],
818
- flags: [
819
- { name: "--client", value: "string", summary: "Required client id; the route names every accepted value on error." },
820
- { name: "--json", value: "boolean", summary: "Emit the snippet payload as JSON." },
821
- ],
822
- mutates: false,
823
- json: "payload",
824
- },
825
- {
826
- command: ["inspect", "star"],
827
- summary: "Whether this repository is starred by the signed-in GitHub account.",
828
- // GET only, permanently. The POST spends the operator identity and requires a dashboard
829
- // session precisely so an agent cannot answer that question for them.
830
- routes: [{ method: "GET", path: "/api/github/star" }],
831
- flags: [{ name: "--json", value: "boolean", summary: "Emit the star status as JSON." }],
832
- mutates: false,
833
- json: "payload",
834
- details: ["Starring is never available from the CLI; the verb says so rather than offering a flag that cannot work."],
835
- },
836
- {
837
- command: ["inspect", "windows-tray"],
838
- summary: "Windows tray helper state.",
839
- routes: [{ method: "GET", path: "/api/windows-tray" }],
840
- flags: [{ name: "--json", value: "boolean", summary: "Emit the tray state as JSON." }],
841
- mutates: false,
842
- json: "payload",
843
- },
844
- {
845
- command: ["system", "codex-app-server"],
846
- summary: "Codex app-server reachability and process state, as the dashboard sees it.",
847
- routes: [{ method: "GET", path: "/api/system/codex-app-server" }],
848
- flags: [{ name: "--json", value: "boolean", summary: "Emit the app-server state as JSON." }],
849
- mutates: false,
850
- json: "payload",
851
- details: [
852
- "The GUI reads this state directly; without a verb an agent could not tell whether the Codex app-server was reachable at all.",
853
- ],
854
- },
855
- {
856
- command: ["system", "codex-cli-update", "check"],
857
- summary: "Inspect a configured Codex CLI candidate and its ownership provenance.",
858
- routes: [],
859
- flags: [{ name: "--json", value: "boolean", summary: "Emit the redacted provenance report as JSON." }],
860
- mutates: false,
861
- json: "envelope",
862
- details: [
863
- "Proof-bound published-launcher context authenticates the configured candidate snapshot, not successful Codex execution; this check does not attest or admit a selected runtime.",
864
- "On Windows this first slice performs no candidate or configuration filesystem I/O: only a proof-captured absolute environment candidate can receive lexical app-bundle or version-manager labels; every other Windows candidate fails closed.",
865
- "Makes no package-registry request.",
866
- "Does not execute Codex or npm, install or repair software, control a process, or write configuration or cache state.",
867
- ],
868
- },
869
- {
870
- command: ["system", "codex-cli-update", "attest"],
871
- summary: "Observe the selected or explicitly named Windows npm Codex installation files without enabling updates.",
872
- routes: [],
873
- flags: [
874
- { name: "--candidate", value: "string", summary: "Absolute npm codex.cmd or package bin/codex.js path; all four paths are all-or-none." },
875
- { name: "--npm-prefix", value: "string", summary: "Absolute prefix containing node_modules/@openai/codex." },
876
- { name: "--npm-cli", value: "string", summary: "Absolute node_modules/npm/bin/npm-cli.js path." },
877
- { name: "--node", value: "string", summary: "Absolute node.exe path; observed, never executed." },
878
- { name: "--json", value: "boolean", summary: "Emit the path-free installation identity observation." },
879
- ],
880
- mutates: false,
881
- json: "envelope",
882
- details: [
883
- "Opt-in Windows x64 local-volume inspection using held native file handles; refuses reparse points, active writers and unsupported layouts.",
884
- "Without explicit paths, the proof-bound launcher snapshot identifies the selected candidate: the configured CODEX_CLI_PATH or the first codex on the captured PATH, with an OpenCodex wrapper resolving to its codex.opencodex-real backing. Discovery only proposes paths; the held-handle observation remains the authority.",
885
- "Success binds observed file identities and bytes, not selected-runtime admission or installer ownership.",
886
- "selectionAttested, managed and applyAllowed remain false. The digest is an observation, not a durable update permit.",
887
- "Does not run the named Codex/npm/Node files, query a registry, install software, control processes or persist state.",
888
- ],
889
- },
890
- {
891
- command: ["system", "codex-restart"],
892
- summary: "Restart the Codex desktop app and app-servers.",
893
- routes: [{ method: "POST", path: "/api/system/codex-restart" }],
894
- flags: [
895
- { 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." },
896
- { name: "--json", value: "boolean", summary: "Emit the restart result as JSON." },
897
- ],
898
- mutates: true,
899
- json: "payload",
900
- details: [
901
- "`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.",
902
- "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.",
903
- "--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.",
904
- ],
905
- },
906
- {
907
- command: ["claude", "config"],
908
- summary: "Read or update Claude Code settings, including independent CLI first-party routing.",
909
- routes: [{ method: "GET", path: "/api/claude-code" }, { method: "PUT", path: "/api/claude-code" }],
910
- flags: [
911
- { name: "--first-party", value: "string", summary: "For `set`, on or off; route standalone Claude CLI subscription requests through the intercept." },
912
- { name: "--json", value: "boolean", summary: "Emit the management response as JSON." },
913
- ],
914
- mutates: true,
915
- json: "payload",
916
- details: ["`status` reads the route; `set` writes only submitted fields. Enabling first-party requires a running Claude intercept."],
917
- },
918
- {
919
- command: ["claude", "intercept", "start"],
920
- summary: "Start the local Claude interception pair on demand.",
921
- routes: [{ method: "POST", path: "/api/claude-intercept/start" }],
922
- flags: [{ name: "--json", value: "boolean", summary: "Emit the management response as JSON." }],
923
- mutates: true,
924
- json: "payload",
925
- },
926
- {
927
- command: ["claude", "desktop", "status"],
928
- summary: "Applied-vs-desired Claude Desktop state, including staleness, drift, and health.",
929
- routes: [{ method: "GET", path: "/api/claude-desktop/status" }],
930
- flags: [{ name: "--json", value: "boolean", summary: "Emit the live status as JSON." }],
931
- mutates: false,
932
- json: "payload",
933
- details: [
934
- "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.",
935
- ],
936
- },
937
- {
938
- command: ["claude", "desktop", "bind"],
939
- summary: "First-party: serve a Claude Desktop Code tab picker model with an opencodex route.",
940
- routes: [{ method: "PUT", path: "/api/claude-desktop/first-party-bindings" }],
941
- flags: [],
942
- mutates: true,
943
- json: "none",
944
- details: [
945
- "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.",
946
- "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.",
947
- "The Desktop picker keeps Anthropic's label; the binding changes which model answers, starting with the next request.",
948
- ],
949
- },
950
- {
951
- command: ["claude", "desktop", "unbind"],
952
- summary: "Remove a first-party Claude Desktop Code tab picker binding.",
953
- routes: [{ method: "PUT", path: "/api/claude-desktop/first-party-bindings" }],
954
- flags: [],
955
- mutates: true,
956
- json: "none",
957
- details: [
958
- "Removing an id that is not bound is a no-op; the remaining bindings are printed.",
959
- ],
960
- },
961
- {
962
- command: ["claude", "desktop", "picker", "status"],
963
- summary: "First-party picker mode: whether Claude Desktop's Code tab lists opencodex models, and what is missing if not.",
964
- routes: [{ method: "GET", path: "/api/claude-desktop/picker" }],
965
- flags: [],
966
- mutates: false,
967
- json: "none",
968
- details: [
969
- "Reports desired, effective, keychain trust, the Desktop egress profile, the model count and a reason with the next command to run.",
970
- ],
971
- },
972
- {
973
- command: ["claude", "desktop", "picker", "on"],
974
- summary: "Turn first-party picker mode on and remember the choice.",
975
- routes: [{ method: "PUT", path: "/api/claude-desktop/picker" }],
976
- flags: [],
977
- mutates: true,
978
- json: "none",
979
- details: [
980
- "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.",
981
- "Claude Desktop then reaches the network through opencodex; fully quit and reopen Desktop afterwards.",
982
- ],
983
- },
984
- {
985
- command: ["claude", "desktop", "picker", "off"],
986
- summary: "Turn first-party picker mode off, remove its Desktop egress profile and certificate trust, and remember the choice.",
987
- routes: [{ method: "PUT", path: "/api/claude-desktop/picker" }],
988
- flags: [],
989
- mutates: true,
990
- json: "none",
991
- details: [
992
- "Works without a running proxy: the preference is saved and the picker profile and trust are removed locally.",
993
- ],
994
- },
995
- {
996
- command: ["claude", "desktop", "picker", "trust"],
997
- summary: "Run the macOS keychain step for picker mode in this terminal, then ask the server to finish enabling it.",
998
- routes: [{ method: "PUT", path: "/api/claude-desktop/picker" }],
999
- flags: [],
1000
- mutates: true,
1001
- json: "none",
1002
- details: [
1003
- "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.",
1004
- ],
1005
- },
1006
- {
1007
- command: ["integration", "native"],
1008
- 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) and, on request, the Private Inference installer Cursor's update channel advertises.",
1009
- routes: [
1010
- { method: "GET", path: "/api/native-integrations" },
1011
- { method: "PUT", path: "/api/native-integrations/claude" },
1012
- { method: "PUT", path: "/api/native-integrations/claude-desktop" },
1013
- { method: "PUT", path: "/api/native-integrations/codex" },
1014
- { method: "PUT", path: "/api/native-integrations/grok" },
1015
- { method: "GET", path: "/api/native-integrations/cursor" },
1016
- { method: "GET", path: "/api/native-integrations/cursor/local-installer" },
1017
- ],
1018
- flags: [{ name: "--json", value: "boolean", summary: "Emit the client rows or toggle result as JSON." }],
1019
- mutates: true,
1020
- json: "payload",
1021
- details: [
1022
- "The list renders per-client state, installed, and desired columns; a blocked disable is named rather than left silent.",
1023
- "Each client has its own route because a toggle rewrites that client's own config file.",
1024
- ],
1025
- },
1026
- {
1027
- command: ["integration", "client"],
1028
- summary: "Inspect and toggle Aside profile catalogs, read their history, and restore a selected profile operation.",
1029
- routes: [
1030
- { method: "GET", path: "/api/client-integrations/aside/profiles" },
1031
- { method: "PUT", path: "/api/client-integrations/aside/profiles" },
1032
- { method: "GET", path: "/api/client-integrations/aside/profiles/{profileId}" },
1033
- { method: "PUT", path: "/api/client-integrations/aside/profiles/{profileId}" },
1034
- { method: "GET", path: "/api/client-integrations/aside/profiles/journal" },
1035
- { method: "GET", path: "/api/client-integrations/aside/profiles/{profileId}/journal" },
1036
- { method: "POST", path: "/api/client-integrations/aside/profiles/{profileId}/restore" },
1037
- ],
1038
- flags: [
1039
- { name: "--client", value: "string", summary: "Select the file integration; use aside for profile controls." },
1040
- { name: "--profile", value: "number", summary: "Select one registered Aside account; omitted toggles affect all profiles." },
1041
- { name: "--op", value: "string", summary: "Operation ID for restore." },
1042
- { name: "--confirm-drift", value: "boolean", summary: "Explicitly allow restore to replace subsequent edits." },
1043
- { name: "--overwrite-conflict", value: "boolean", summary: "Explicitly allow enable to replace a conflicting provider block." },
1044
- { name: "--json", value: "boolean", summary: "Emit the profile state, history, or mutation result as JSON." },
1045
- ],
1046
- mutates: true,
1047
- json: "payload",
1048
- details: [
1049
- "Use status/show/list, history/journal, enable/disable, or restore after integration client.",
1050
- "These declarations cover the dedicated Aside profile paths; existing generic client routes retain their separate parity inventory.",
1051
- ],
1052
- },
1053
- {
1054
- command: ["sync"],
1055
- summary: "Synchronize client catalogs, including Aside profiles through the running server's mutation owner.",
1056
- routes: [{ method: "POST", path: "/api/client-integrations/aside/sync" }],
1057
- flags: [
1058
- { name: "--restart-codex", value: "boolean", summary: "Restart the Codex app-servers and fully quit and relaunch the Codex desktop app after a catalog or cache write, on macOS, Linux and Windows." },
1059
- { name: "--restart-app-server-only", value: "boolean", summary: "Restart only the Codex app-servers and leave the desktop app running; wins over --restart-codex when both are given." },
1060
- { name: "--restart-desktop-app", value: "boolean", summary: "Deprecated alias of --restart-codex." },
1061
- ],
1062
- mutates: true,
1063
- json: "none",
1064
- details: ["The Aside refresh uses the live server; other catalog synchronization also performs local work."],
1065
- },
1066
- {
1067
- command: ["agent", "subagents", "force"],
1068
- summary: "Force Claude Code subagents onto one exposed model at the next routed launch; - clears.",
1069
- routes: [{ method: "GET", path: "/api/subagent-models" }, { method: "PUT", path: "/api/subagent-models" }],
1070
- flags: [{ name: "--json", value: "boolean", summary: "Emit the saved force setting." }],
1071
- mutates: true,
1072
- json: "payload",
1073
- details: ["Requires Claude Code 2.1.257+. Plain claude, forks, inherit skills, the main model and small-fast sidecars are unaffected."],
1074
- },
1075
- {
1076
- command: ["agent", "request-user-input"],
1077
- summary: "Show or set whether default mode may ask the operator a question mid-task.",
1078
- routes: [
1079
- { method: "GET", path: "/api/codex-auth/features/default-mode-request-user-input" },
1080
- { method: "PUT", path: "/api/codex-auth/features/default-mode-request-user-input" },
1081
- ],
1082
- flags: [{ name: "--json", value: "boolean", summary: "Emit the feature state as JSON." }],
1083
- mutates: true,
1084
- json: "payload",
1085
- details: ["A bare invocation reads and never writes."],
1086
- },
1087
- {
1088
- command: ["agent", "roles"],
1089
- summary: "omo (Codex / LazyCodex): show each Codex agent role's model pin, set one role's model in its TOML and in omo.jsonc, or suggest a model for every role.",
1090
- routes: [
1091
- { method: "GET", path: "/api/codex-agent-roles" },
1092
- { method: "PUT", path: "/api/codex-agent-roles/{role}" },
1093
- { method: "POST", path: "/api/codex-agent-roles/auto-assign" },
1094
- ],
1095
- flags: [
1096
- { name: "--json", value: "boolean", summary: "Emit the role list, the write result or the proposals as JSON." },
1097
- { name: "--model", value: "string", summary: "suggest: size the roles with this model instead of the Codex default model." },
1098
- { name: "--apply", value: "boolean", summary: "suggest: write every proposal through the role model write." },
1099
- ],
1100
- mutates: true,
1101
- json: "payload",
1102
- details: [
1103
- "A bare invocation reads and never writes.",
1104
- "Requires Codex-based omo (LazyCodex): the omo@sisyphuslabs Codex plugin enabled in config.toml and installed; otherwise status lists no roles, and set and suggest are refused.",
1105
- "set rewrites only the root model value of $CODEX_HOME/agents/<role>.toml; omo.jsonc is skipped when absent or when it contains comments.",
1106
- "suggest sizes every role with one model call and prints proposals without writing; --apply writes each proposed model, and its effort when the role file already sets model_reasoning_effort.",
1107
- ],
1108
- },
1109
- {
1110
- command: ["agent", "injection"],
1111
- summary: "Show or set the delegation model and effort, or suggest both for a described piece of delegated work.",
1112
- routes: [
1113
- { method: "GET", path: "/api/injection-model" },
1114
- { method: "PUT", path: "/api/injection-model" },
1115
- { method: "POST", path: "/api/injection-model/suggest" },
1116
- ],
1117
- flags: [
1118
- { name: "--json", value: "boolean", summary: "Emit the delegation settings, the write result or the proposal as JSON." },
1119
- { name: "--model", value: "string", summary: "set: the delegation model, - clears it. suggest: size the work with this model instead of the Codex default model." },
1120
- { name: "--effort", value: "string", summary: "set: the delegation reasoning effort, - clears it." },
1121
- { name: "--prompt", value: "string", summary: "set: a custom guidance prompt, - clears it." },
1122
- { name: "--guidance", value: "string", summary: "set: on or off for OpenCodex delegation guidance." },
1123
- { name: "--apply", value: "boolean", summary: "suggest: write the proposed model and effort through the delegation settings write." },
1124
- ],
1125
- mutates: true,
1126
- json: "payload",
1127
- details: [
1128
- "A bare invocation reads and never writes.",
1129
- "suggest sizes the described work with one model call, picks the cheapest sufficient model the delegation picker offers, and writes nothing unless --apply is given.",
1130
- ],
1131
- },
1132
- {
1133
- command: ["api", "protocols"],
1134
- summary: "Read the protocol contract version, API surfaces, protocol settings and feature vocabulary.",
1135
- routes: [{ method: "GET", path: "/api/protocols" }],
1136
- flags: [
1137
- { name: "--provider", value: "string", summary: "Add one configured provider's upstream wire and who decided it." },
1138
- { name: "--json", value: "boolean", summary: "Emit the GET /api/protocols body." },
1139
- ],
1140
- mutates: false,
1141
- json: "payload",
1142
- },
1143
- {
1144
- command: ["combo", "test"],
1145
- summary: "Run one JEV decision probe through a decision method: TypeSafe, a System One row, or an opencodex model.",
1146
- routes: [{ method: "POST", path: "/api/combos/decision-test" }],
1147
- flags: [
1148
- { name: "--combo", value: "string", summary: "Combo id whose saved decision method is probed and whose recursion rules apply." },
1149
- { name: "--decision-provider", value: "string", summary: "Probe a jev-decision provider row (or jev for TypeSafe) instead of the saved method." },
1150
- { name: "--decision-model", value: "string", summary: "Probe an opencodex-routed model instead of the saved method." },
1151
- { name: "--decision-timeout", value: "number", summary: "Decision deadline in milliseconds (1000-120000)." },
1152
- { name: "--json", value: "boolean", summary: "Emit the probe result." },
1153
- ],
1154
- mutates: true,
1155
- json: "payload",
1156
- details: ["Sends one synthetic two-option decision; it may spend a decision call on the chosen backend."],
1157
- },
1158
- {
1159
- command: ["combo", "discover"],
1160
- summary: "List configured System One decision rows and catalog models that look like decision services.",
1161
- routes: [{ method: "GET", path: "/api/combos/decision-discovery" }],
1162
- flags: [
1163
- { name: "--query", value: "string", summary: "Match catalog rows by this text instead of the built-in decision-model hint." },
1164
- { name: "--json", value: "boolean", summary: "Emit the discovery payload." },
1165
- ],
1166
- mutates: false,
1167
- json: "payload",
1168
- details: ["Read-only: nothing is probed and no provider row is created."],
1169
- },
1170
- {
1171
- command: ["api", "explain"],
1172
- summary: "Preview the request path a model would take from one inbound API, computed from config.",
1173
- routes: [{ method: "POST", path: "/api/protocols/plan" }],
1174
- flags: [
1175
- { name: "--model", value: "string", required: true, summary: "Model selector as a client would send it." },
1176
- { name: "--inbound", value: "string", required: true, summary: "Inbound API: responses, chat or messages." },
1177
- { name: "--feature", value: "string", summary: "Request feature key to judge; repeatable or comma-separated." },
1178
- { name: "--json", value: "boolean", summary: "Emit the ProtocolPlanV1 preview." },
1179
- ],
1180
- mutates: false,
1181
- json: "payload",
1182
- details: ["A read-only POST: nothing is sent upstream, no combo state advances and the input is not logged."],
1183
- },
1184
- {
1185
- command: ["api", "policy"],
1186
- summary: "Read the protocol policy, or change the Messages surface, unrepresentable policy and rollout switches.",
1187
- routes: [
1188
- { method: "GET", path: "/api/protocols" },
1189
- { method: "PATCH", path: "/api/protocols/settings" },
1190
- ],
1191
- flags: [
1192
- { name: "--messages", value: "string", summary: "Open or close the Messages API: on or off. Off also turns the Claude integration off." },
1193
- { name: "--unrepresentable", value: "string", summary: "legacy keeps today's behavior; reject refuses a request its path cannot carry." },
1194
- { name: "--rollout", value: "string", summary: "One switch as name=on or name=off; repeatable. Every switch defaults off." },
1195
- { name: "--json", value: "boolean", summary: "Emit the resulting GET /api/protocols body." },
1196
- ],
1197
- mutates: true,
1198
- json: "payload",
1199
- details: [
1200
- "A bare invocation reads and never writes.",
1201
- "A setting flag changes the operator's config; run it only when the operator asks for that change.",
1202
- ],
1203
- },
18
+ ...BASE_CAPABILITIES,
19
+ ...PROVIDER_MODEL_CAPABILITIES,
20
+ ...ACCOUNT_CAPABILITIES,
21
+ ...AGENT_ROUTING_CAPABILITIES,
22
+ ...INTEGRATION_CAPABILITIES,
23
+ ...OBSERVE_SYSTEM_CAPABILITIES,
24
+ ...ACCESS_REMOTE_CAPABILITIES,
25
+ ...LAB_CAPABILITIES,
1204
26
  ];
1205
27
 
28
+ export { HEAD_CAPABILITIES } from "./capabilities-base";
29
+ export type {
30
+ CapabilityRoute,
31
+ CapabilityFlag,
32
+ CapabilityJsonMode,
33
+ Capability,
34
+ HeadCapability,
35
+ } from "./capability-types";
36
+
1206
37
  /** Capabilities that drive `route`, for `ocx capabilities --route`. */
1207
38
  export function capabilitiesForRoute(path: string): Capability[] {
1208
39
  return CAPABILITIES.filter(cap => cap.routes.some(r => r.path === path));