src/cli/ contains the terminal management interface. Process ownership, startup, stop and service contracts remain in Runtime; this document owns command discovery, help, management-client presentation and the generated operating reference.
Catalog-derived reasoning-level diagnostics are escaped only at the human-output boundary, which src/cli/runtime-api.ts owns alongside the human/JSON print split. Every CLI path that prints a hub-supplied catalog value renders it there: the first-time refusal in src/cli/connect.ts and the connected ocx sync refusal in src/cli/dispatch.ts. C0/C1 controls, DEL, and Unicode line/paragraph separators print as visible hexadecimal escapes; structured status retains the exact reason, and a rendered failure keeps the domain error as its cause. The ready/unverified/incompatible classification and exit policy are unchanged. src/cli/capabilities-command.ts rejects leftover positional arguments, unknown or repeated flags, and blank route filters with exit 64 before emitting a capability index; a valid unmatched route remains exit 4. printData in src/cli/runtime-api.ts escapes each human-output line at the shared renderer, including role and delegation-model suggestion rationale. JSON output retains the exact original values. src/cli/export-command.ts passes native serialized documents as individual lines so their multiline layout is preserved. tests/cli/cli-headless-parity.test.ts checks both suggestion paths independently from their parsed JSON output; tests/cli/cli-export-command.test.ts covers export framing.
src/cli/root.ts, src/cli/help.ts, src/cli/help-navigation.ts
The pure Bun-head parser retains command argv and derives transient help paths before shim preflight or command dispatch. Bare help is recognized only at root or immediately after the root command; nested paths use --help/-h, and exact -- ends head help scanning. Later operand values such as alias set demo help stay commands. runCli exits help and rejects unknown roots before shim/stateful preflight, while preserving parseCliHead and its kinds. Registry names/aliases/hidden entries and the unregistered internal runner remain valid dispatch targets; hidden/internal names stay outside discovery and suggestions. printUsage renders the same compact index for bare ocx, help, --help and -h; static navigation groups reference registry names/summaries and add no configuration reads, width probes or color dependence. printFullUsage preserves the full reference behind ocx help --all and ocx --help --all. This contract concerns the Bun head; the Node launcher's updater interception has its own recognition rules.
src/cli/help-catalog.ts, src/cli/help-models-context.ts, src/cli/help-recovery.ts
Pure help resolution uses src/cli/registry.ts and src/cli/capabilities.ts, preserving exact alias usage/details before canonical family navigation. Entry results carry transient canonical identity, a matching canonical capability when declared, and declared descendants; top-level help supplements registry usage/details with the capability flags and detail lines not already printed; family help lists partial child coverage and links the curated models-context topic separately. Hidden entries remain explicitly callable but absent from discovery. Declared capabilities render summaries, known flags/details and parent pointers without inventing operand grammar; declared-prefix groups mark incomplete coverage. Unknown roots and unavailable explicit ocx help <path> detail use concise stderr-only diagnostics/navigation, empty stdout and exit 1, without a full banner. Missing detail never establishes unsupported runtime grammar. Successful appended flag-help parent fallback runs before recovery and preserves its write sink; unresolved explicit help uses stderr regardless of sink. The resolver does not validate runtime command execution. The curated models-context topic shares MODELS_CONTEXT_USAGE with src/cli/models-runtime.ts, preserving its status/value/provider/all grammar and read-only status example. The catalog projects pure transient recovery candidates from visible registry names/aliases, immediate declared children and curated topics, deduplicated by canonical destination. The pure recovery formatter bounds input/depth/work, matches conservative edit distances including adjacent transpositions and sorts by distance/name; at most three metadata-derived destinations are suggested, never executed or extended with trailing argv. Distant/control/oversized input gets no guess. Root diagnostics echo only a bounded command-shaped first token accepted by src/lib/redact.ts; nested diagnostics never echo arbitrary operands. src/cli/dispatch.ts reuses the formatter for direct unknown-root dispatch. Capability JSON preserves its existing schema and adds exact usage only for declarations that supply it; provider-specific error semantics remain unchanged. Provider syntax/examples live in registry details; src/cli/provider.ts uses the shared renderer for bare/help success (stdout, exit 0) and unknown-action diagnostics/help (stderr, exit 1, no stdout). The transient optional write sink defaults to console.log, accepts console.error for that error path and propagates through parent fallback. Bare provider retains ordinary preflight; only head-help forms bypass it.
Runnable capability parents also expose their declared descendants. Nested help canonicalizes the supported access-key spellings (api-key, access keys, and key-action delete) while preserving exact root alias usage; recovery indexes the canonical path so prefix expansion cannot select an absent token. These are help-only mappings and never rewrite execution argv.
src/cli/capability-types.ts owns the type-only contract. src/cli/capabilities-base.ts retains the original declarations. Seven domain leaves (src/cli/capabilities-provider-models.ts, src/cli/capabilities-accounts.ts, src/cli/capabilities-agents-routing.ts, src/cli/capabilities-integrations.ts, src/cli/capabilities-observe-system.ts, src/cli/capabilities-access-remote.ts, src/cli/capabilities-lab.ts) append verified existing workflows in a fixed order. Each leaf imports types only. The aggregate preserves baseline row identity and order; duplicate canonical paths fail validation. src/cli/capabilities.ts is the stable public facade for arrays, types and pure query helpers. Consumers continue to import the facade; metadata never imports command handlers, config, registry execution or Lab code. The explicit transitive boundary and cycle/forbidden-edge fixtures live in tests/cli/cli-capability-data.test.ts. Computed-member access, division/ambiguous-regex expressions and ambient host/loader identifiers are outside the admitted metadata grammar and fail closed, including benign shadowing or unquoted properties with reserved names. Quoted data remains supported. This is a checked dependency boundary, not an arbitrary-code sandbox.
A declaration may carry usage, the exact synopsis for a verified leaf. capabilityInvocation and matching still use canonical command tokens. src/cli/capabilities-command.ts projects usage only when present, preserving the previous JSON object shape otherwise. The help renderer then uses the exact Usage line and omits that leaf's incomplete-grammar disclaimer. A declaration without usage keeps the prior Command/partial-grammar presentation. Root aliases, hidden entries, head-only invocations and the models-context special topic retain their existing semantics.
The agents/routing leaf also declares local message sessions and message send; their command-local transport and receipt contract belongs to local messaging. These declarations import no messaging handlers and preserve baseline capability order. The operating-reference generator places the two verbs in the agents/routing chapter.
scripts/generate-ocx-skill-surface.ts renders the compact skills/ocx/references/01_management_surface.md index and eight flat domain chapters from the same capability data. The index retains canonical fragment forwarders and links to complete chapter entries. Counts derive from declarations; grouping does not choose runtime dispatch or grant authority. Unknown roots and duplicate anchors are rejected rather than silently omitted.
Generated flag-table cells escape literal pipes, backslashes and line breaks, and absent value types render as empty cells. Rendered Markdown regressions verify that enum choices stay in the meaning cell.
The generator checks its closed expected file map and exact contents, including missing or stale owner-marked chapters. It writes expected outputs only and does not automatically delete unrelated/stale documents. tests/ci-workflows/skill-ocx.test.ts and the generator-focused tests check regeneration, reachable reference links, actual shipped Markdown and the preserved consent/secret-bearing command rules. Generated status grants no exemption from repository file-size limits.
skills/ocx/SKILL.md is the operating guide, distinct from development instructions and installation consent. The index describes declared capabilities; it does not establish full runtime grammar, target-version compatibility, safe autonomous permission or free upstream execution. Handwritten task recipes provide target/readiness checks, command-level authority and read-back guidance.
Management route declarations describe actual HTTP calls only; local Lab automation, config and data-plane probes retain empty management routes with explicit transport and side-effect notes. Task-family metadata preserves confirmation, human-only secret handoffs and per-handler JSON support. Leaf usage is derived from the existing parser; an indexed command does not gain new runtime behavior.
src/cli/provider.ts selects explicit --live lifecycle operations before local configuration calls. src/cli/provider-lifecycle-runtime.ts pins the management target for roster/preset reads and one add/default/remove mutation, refuses redirects and never falls back to local state. Add is an upsert with an observed no-force check, not atomic create-only protection. Default is a standalone patch; live removal requires --yes and leaves dependency/default/account cleanup to the server. Local add keeps its default target and actually performs requested --sync before JSON output; configApplied and catalog convergence are separate, and an unchanged existing catalog can converge without new writes; saved-but-unavailable/refused/failed sync is nonzero, while policy skips retain truthful needsSync. Known catalog ownership and saved-config removal warnings reach human output and the local sync.warning receipt; only the owner's fixed path-free guidance and namespace count are projected, so appended arbitrary diagnostics remain private. Explicit local authentication/path overrides pass the management owner's completed-candidate validation before registration, saving, discovery or sync; unflagged local behavior is unchanged.
src/cli/provider-settings.ts consumes only the three additional edit fields and owns pacing rules/status. Configured rules come from config, observations from the separate pacing endpoint. Scalar writes preserve observed model rules but replace the entire block without CAS; numeric changes do not implicitly enable pacing. Complete-file replacement is exclusive with scalar flags and uses the canonical pacing validator. src/cli/provider-runtime.ts propagates the safe provider edit result's numeric outcome and the connectivity test outcome. Failed connectivity remains exit 1 through the outer provider dispatcher; successful and non-applicable static-catalog observations remain exit 0.
src/cli/provider-batch.ts reuses the authoritative named editor parser from src/server/auth-cors.ts. Snapshot strips only four GUI decorations, validates, then emits exactly defaultProvider/providers. Supplied baseline/next documents are not stripped or normalized; removals require --yes, the wire body is one exact PUT, and stale baselines are not automatically refreshed or retried. Batch removal does not claim single-DELETE OAuth account cleanup. Neither the snapshot nor address pinning supplies a cross-invocation process identity guarantee.
src/cli/json-input.ts shares the server's 4 MiB limit and also checks the serialized composite body. Explicit stdin and regular files have a 30-second default input deadline, strict UTF-8 decoding, static errors and owned-resource cleanup. At most one batch input can use stdin. Mutable buffers are wiped; immutable parsed strings are not claimed erased. src/cli/provider-result.ts projects only the known receipt/catalog fields, emits fixed known-code/status errors without raw response bodies, and returns saved-but-unconverged failures numerically. Existing global CLI error behavior remains separate. Provider workflow regressions bind these contracts to injected transports, owned homes, actual CLI subprocesses and isolated server editor handlers.
src/cli/models.ts keeps local custom-model authoring as default and selects explicit live operations before local state. src/cli/models-custom-runtime.ts resolves deletion against the complete target roster through the shared slug contract and addresses an exact stored id, refusing ambiguous or malformed identities. src/cli/models-custom-input.ts owns the shared pure reasoning grammar, re-exported from the original module. Local JSON writes report saved state and opportunistic sync: no proxy is pending success; attempted failure is nonzero. src/cli/local-sync-result.ts is the pure safe projection shared with provider writes; caller-specific required/opportunistic policies remain separate.
src/cli/models-order.ts owns raw upstream display-name addressing and routed picker operations. Status preserves saved native identities, while manual/preset replacement requires explicit reset of native-inclusive order. Manual input is a full unique routed permutation with the observed featured prefix; settings/identity rereads reject observable drift without claiming CAS. src/cli/model-picker-ordering.ts mirrors the GUI's pure identity/sort projection without importing GUI code into the CLI. Independent ordering fixtures and test-only GUI conformance exercise the deliberate shared contract. Most-used consumes complete all/all requested-model usage, not representative resolved-model attribution. The registry declares the existing display-name PUT; its handler remains authoritative, including saved-but-failed HTTP503.
src/cli/route-policy-write.ts accepts editable-only documents, requires the caller's update revision and uses fixed create/update/delete requests. Strict nested field ownership is local; provider/alias/routing validation stays on the server, without fabricated config context. Profile writes may activate already-enabled Lab automation. src/cli/combo-input.ts preserves target metadata and explicit false/default options before transport; src/cli/combo.ts applies them through its existing merge stages, retaining a carried force policy's omitted default effort. These combo upserts are not revision CAS. src/cli/combo-stats.ts reports actual JEV decision/token/coverage facts and nullable/incomplete observations without a savings estimate or decision probe.
src/cli/catalog-command-result.ts owns fixed safe errors and shared catalog evidence only; callers validate their distinct public DTOs. src/cli/combo-result.ts rebuilds the combo write receipt and verifies the requested identity. Numeric partial outcomes reach the original root dispatch, and read-back is required before any caller retry. The helpers do not select endpoints, grant authority, perform writes or execute generic CRUD. Existing provider receipt semantics remain separate. Local discovery refusals raised by runtimeBaseUrl before any request carry a typed RuntimeApiError.code (proxy_not_running, client_role_management_unavailable) and render a fixed "No request was sent" message instead of uncertain-write wording; integration-route errors (normalized, unredirected path) may append a fixed recovery line keyed on the closed reason set; the writer's message prose is never echoed.
src/cli/account-policy.ts and src/cli/account-policy-dto.ts use the selected runtime's supported pool fields and validated roster. src/cli/account-target.ts shares pure selection precedence with the existing async helper; new policy writers never use the legacy transport fallback. Per-account threshold, one/all paid-credit permission, display preference and quota-window activation remain distinct operations. Reset-grant status is a typed GET with possible upstream status work; consumption/session acquisition is not exposed.
src/cli/account-auth.ts validates branch-specific login options before code input and pins its login flow requests. Public handoff/state fields are rebuilt without tokens or arbitrary backend text. src/cli/logout-command.ts owns target parsing before credential access: local atomic removed/not-found behavior and live OAuth success remain different receipts, with no cross-target fallback. Native main signout is not an OAuth logout synonym.
src/cli/agent-settings.ts writes strict full memory/compaction override blocks via their canonical schemas. Empty memory blocks and null clears restore existing/default routing rather than disabling pipelines. src/cli/system-settings-parity.ts projects new settings observations; ultraFastTier is read back because its mutation receipt omits it. src/cli/agent-runtime-settings.ts keeps supported injection/guidance and sidecar field ownership, including web reasoning persistence despite reply omission. The actual window spellings and sidecar limits come from their owners, not similar flag names.
src/cli/settings-result.ts handles the settings pending boolean and shared native apply report without private detail; it never treats that flag as a full catalog disposition. Missing confirmation stays unverified/nonzero, while the accepted state remains visible. Existing no-new-option settings output remains compatible. Shared static usage text retains authored line breaks while each displayed line is terminal-safe.
src/cli/v2-input.ts parses target/output/acknowledgment before effects and protects literal hint text after the terminator. src/cli/v2-runtime.ts has no parent-local-writer import and validates the management state/advisory/catalog contract. src/cli/v2-local-output.ts reads actual local state and validates unknown injected sync results before projection. Local mode/keep and changed feature toggles retain their sync call even without a discovered port; other verbs do not gain new synchronization. Live failure never invokes local writers, and partial native state never becomes an implicit rollback claim.
src/cli/capabilities-integrations.ts declares commandcode restore and its dedicated restore/preview routes separately from generic integration restore. Its generated operating reference preserves the client-bound command, supported flags, and refusal on older proxies without those routes.
src/cli/integration-input.ts shares pure profile paths/validation and owns exact optional Droid-map/fingerprint grammar. src/cli/integration-preview.ts handles explicit preview and new-option writes; src/cli/integration-plan-dto.ts validates value-free plans without runtime imports from GUI/planner/writer code. The original direct mutation bodies remain when new options are absent. Refused and no-op previews are completed observations; stale commits return a re-preview instruction without adopting a replacement token. The server owns coordinated binding and writes.
src/cli/integration-journal.ts addresses exact global/Aside/profile history with an explicit confirmation. It reports retired records separately from incomplete snapshot cleanup. src/cli/integration-aside-sync.ts retains the existing attested helper and its original dependency object rather than selecting a different transport through synthesized baseUrl. Empty, malformed and partial outcomes remain distinct. New fixed runtime requests reject redirects; this is not a global legacy transport rewrite.
src/cli/claude-desktop-profile.ts saves runtime profiles through the canonical parser and management owner, without applying or falling back to local state. src/cli/integration-cursor.ts exposes installation/capability and installer-link observations only. src/cli/remote-workspace-hub.ts selects Hub reads before executor storage: available empty results succeed, outer available:false observations remain unavailable/nonzero, and runtime availability retains its named object shape. These observations can trigger the existing inventory/probe work and are not advertised as offline.
Storage policy flags in src/cli/storage.ts preserve omitted enable/settings and submit exclusive byte or percentage targets without running cleanup. Explicit forced revoke in src/cli/link.ts requires --yes and labels remote cleanup from invocation intent: skipped on observed retirement, unverified on an already-missing link. Ordinary revoke retains its existing body and idempotency contract.
src/cli/access-data-client.ts owns explicit-key input, selected enrollment/runtime origin, observable identity rechecks, bounded JSON reads and invocation signals. It never substitutes a management or enrolled credential. src/cli/runtime-api.ts adds optional stdinSignal only to its byte reader; absent that signal, existing input behavior remains. Accepted input is bounded, fatal-decoded and restricted to the printable ASCII carrier supported by issued keys; owned mutable bytes are wiped, not all runtime string copies.
src/cli/access-data-plane.ts preserves the literal credentialless malformed-body control before one fixed small model request. Native key-required401 is an observation of that request, not a lease on later admission policy. src/cli/access-data-response.ts emits only validated assistant text, completion and optional token counts with exact supplied-key replacement. Selected-key reports are versioned; unkeyed legacy results retain their shape. Rename in src/cli/access.ts checks duplicate-ID ambiguity before its existing resolver and sends only id/name, preserving scopes and avoiding plaintext output.
src/cli/access-audio-input.ts bounds regular file reads and late descriptor cleanup. src/cli/access-audio.ts sends the existing multipart operation and returns only transcript text; errors have empty stdout and fixed diagnostics. src/cli/access-audio-live.ts uses native Bun WebSocket, the existing key carrier and fixed session update, then observes native readiness and requests normal closure. Its ready/close report distinguishes partial closure; it claims neither full voice inference nor server lease release. No microphone, delegation execution or retry is introduced.
src/cli/observe-stream.ts owns fixed management GETs, pinned available identity, bounded fetch/body deadlines and serial abortable polling for src/cli/log-follow.ts and src/cli/injection-follow.ts. Management and data-key authorities remain separate. Invocation signal handlers and timers are removed; SIGINT130 and SIGTERM143 reach root dispatch. Log events preserve observed ordered windows, repeated IDs and reset/removal snapshots; legacy row streams preserve amendments but cannot encode removals. Injection's numeric after has no epoch/gap guarantee, and following does not enable capture.
src/cli/companion-timeline.ts uses the existing timeline parser, model selection and provider exclusion vocabulary, preserving seconds, incomplete measurements and filter acknowledgment. The returned end must match the request-time accumulator bucket, or its immediate successor after an observed rollover; aligned stale windows are rejected. System health reports the endpoint and spend-ledger observations separately from root liveness. Key-scoped usage requires echoed scope and is refused on connected clients before enrolled-key access; src/cli/usage-report.ts names the scope in both populated and empty reports. New fixed management requests reject redirects without changing legacy unflagged transport globally.
src/cli/log-view-filter.ts owns the additive logs-filter snapshot, separate from existing follow/event transport. It fetches only the fixed log endpoint with a scan limit of at most 2000, applies GUI-equivalent local selectors, then returns the newest matches in source order without deduplicating. Model/provider matching covers resolved/served/attempt identities; protocol and conversation matching reuse their actual owners. Speed bounds accept observed value-kind metrics only. The versioned JSON view separates loaded, matched and returned counts from configured scan/output limits; JSONL is rows only. Neither a match count nor a cursor claims historical completeness or resumable search. Invalid options fail before discovery; malformed windows never become empty success.
src/cli/usage-model-search.ts applies optional substring search only after the existing usage target/scope acknowledgment. A copied model list sorts stably by total tokens, searches model/provider/resolvedModel and caps at 100. The report's other fields remain intact; explicit modelView metadata distinguishes a view miss from no usage. src/cli/usage-report.ts retains the legacy renderer when no view is supplied and renders up to the selected 100 rows when one is supplied. Search never becomes a server attribution query or widens connected-client/key scope.
src/cli/companion-usage.ts reads settings and two usage ranges sequentially on a pinned management target through src/cli/observe-stream.ts. Its safe projection follows the saved model/provider filters and measured-totals rules in gui/src/pages/tray-data.ts without importing GUI runtime code. It retains unknown/incomplete metrics, valid server defaults with null update time, and explicit corrupt/fallback flags. Malformed settings stop before usage reads. Range failure retains the other observed range, labels unavailable data, and returns partial/nonzero; signal cancellation emits no late report. The observation owner supplies a separate 10-second fetch/body deadline after discovery and 32 MiB cap for each fixed GET, not a command-wide budget. Snapshot context supplies truthful retry wording without altering default follow behavior.
src/cli/account-api.ts forwards explicit quota/refresh intent to the existing per-key owner; ordinary key listing omits both. Opt-in requests reject redirects. src/cli/account-key-quota.ts rebuilds the public ProviderQuota projection, including custom windows and credits, with finite-field validation and no credential or private publication fields. Missing mode evidence is unverified/nonzero. Human rendering separates probe/passive/unsupported, unavailable and unmeasured from actual zero; Codex/OAuth rendering remains separate. This read can invoke upstream quota work but does not change key selection or provider aggregate caches. Account list/current rows additionally project, through src/cli/account-next-actions.ts, only an allow-listed server health label, a locally generated recovery command built from shell-safe selectors (never server summary/action text), and the Codex boolean creditsAfterLimit as read-only consent readback; empty listings add a fixed next-action note to human output and JSON notes.
The operating guide's eight-domain workflow table is navigation rather than parity measurement. Handwritten JSON, recipe, recovery and target docs qualify bounded windows, model-only search, partial/default results and human-only/session actions. Generated chapter counts still derive exclusively from capability declarations.