# docs/cli-provider-settings-descriptor.md · lucenx/codexbar-plasma

[View on GitCafe](https://git.cafe/lucenx/codexbar-plasma/blob/refs%2Fheads%2Fcodex%2Frelease-0.2.36/docs/cli-provider-settings-descriptor.md)

Repository: [lucenx/codexbar-plasma](https://git.cafe/lucenx/codexbar-plasma)

Visibility: public

Requested revision: refs/heads/codex/release-0.2.36

Commit: e09c4573cc13e85f00af27a0430b2933755c0f15

Blob: 4b74622429ab38ef75a7561ce2e32c0327ec2146

Size: 8779 bytes

[Immutable source](https://git.cafe/lucenx/codexbar-plasma/blob/e09c4573cc13e85f00af27a0430b2933755c0f15/docs/cli-provider-settings-descriptor.md?format=markdown)

````
# CLI provider settings descriptor

Status: **Proposed, not shipped**. The last full contract verification used the
checksum-verified official Linux CLI 0.56.2 on 2026-09-01. It rejects
`config providers --descriptors` and has no generic `config set` or `config action`.
See the [pinned audit](research/2026-09-01-macos-parity-0.56.2.md). The scoped
[0.57.0 probes](research/2026-09-09-macos-parity-0.57.0.md#scoped-official-linux-probes)
confirm descriptor absence and the unchanged generic-command gap.
Track [settings delivery](../TODO.md#provider-settings) and
[onboarding actions](../TODO.md#provider-onboarding) in TODO.
All command examples and payloads below describe the proposed contract.

This document defines the CLI contract Plasma needs before it can render real
provider settings or onboarding flows without duplicating macOS Swift logic in
QML.

The Plasma widget consumes this contract when the upstream `codexbar` CLI
exposes it. If a descriptor is absent or unsupported, Plasma keeps enable/disable,
supported single-key setup, docs/dashboard/login links, redacted diagnostics, and
CLI command hints available.

## Command

```sh
codexbar config providers --descriptors --format json --json-only
```

The command returns the normal provider list plus a provider-specific
descriptor. The descriptor is declarative: it names fields and actions, but the
CLI remains the only component that knows how to read, validate, write, import,
or redact provider settings.

Descriptor writes use local CLI commands such as
`codexbar config set --provider amp --field sourceMode --value api --json-only`.
Descriptor actions use local CLI commands such as
`codexbar config action --provider openai --action openDashboard --json-only`.

## Top-level shape

```json
[
  {
    "provider": "openrouter",
    "displayName": "OpenRouter",
    "enabled": true,
    "descriptor": {
      "schemaVersion": 1,
      "fields": [],
      "actions": []
    }
  }
]
```

`schemaVersion` must be incremented for incompatible changes. Plasma should
ignore descriptors with an unknown major schema and keep showing CLI command
hints.

## Fields

Fields are settings the frontend can display or edit. Field order is display
order.

```json
{
  "id": "apiKey",
  "kind": "secret",
  "title": "API key",
  "description": "Stored by codexbar. Paste your OpenRouter API key.",
  "redactedValue": "sk-...abcd",
  "required": true,
  "writeCommand": [
    "codexbar",
    "config",
    "set",
    "--provider",
    "openrouter",
    "--field",
    "apiKey",
    "--stdin",
    "--format",
    "json",
    "--json-only"
  ]
}
```

Supported field kinds:

- `"kind": "text"`: short non-secret string, such as a base URL or workspace id.
- `"kind": "secret"`: secret input, always written through stdin.
- `"kind": "enum"`: one of a stable option list.
- `"kind": "boolean"`: checkbox/toggle.
- `"kind": "number"`: bounded numeric setting.

Command-like behavior belongs in the descriptor's `actions` array, not in
`fields`; every field is editable and must provide an allowed `writeCommand`.

Enum fields include `options`:

```json
{
  "id": "sourceMode",
  "kind": "enum",
  "title": "Source",
  "value": "auto",
  "options": [
    { "id": "auto", "title": "Automatic" },
    { "id": "api", "title": "API key" },
    { "id": "web", "title": "Browser cookies" }
  ],
  "writeCommand": [
    "codexbar",
    "config",
    "set",
    "--provider",
    "amp",
    "--field",
    "sourceMode",
    "--value",
    "{value}",
    "--format",
    "json",
    "--json-only"
  ]
}
```

The CLI must validate `{value}`. Plasma must not infer valid enum values from
provider names or config files.

Field, action, and option IDs are machine identifiers. They must match
`[A-Za-z0-9][A-Za-z0-9._-]*` and be no longer than 128 characters. Consumers
reject invalid IDs instead of trimming, truncating, or otherwise rewriting
them.

## Actions

Actions are provider setup flows the CLI knows how to perform.

```json
{
  "id": "refreshCookies",
  "kind": "command",
  "title": "Refresh browser cookies",
  "description": "Import browser cookies for the selected provider.",
  "command": [
    "codexbar",
    "config",
    "action",
    "--provider",
    "codex",
    "--action",
    "refreshCookies",
    "--format",
    "json",
    "--json-only"
  ]
}
```

Useful action categories:

- browser-cookie import
- manual cookie save
- API key save or clear
- OAuth/device-flow handoff
- local app/session probe
- token-account add/edit/remove
- provider diagnostics refresh
- open docs/dashboard/login URL

Actions must report structured JSON with `status`, optional `message`, and
optional refreshed `descriptor`. `status` is `ok` after a completed action,
`error` after a failed action, or `cancelled` when the user abandons an
interactive flow. A failed action may still exit with code zero, so consumers
must inspect the structured status before reporting success.

URL-opening actions should still be local CLI actions. For example,
`codexbar config action --provider openai --action openDashboard --json-only`
can return `{ "status": "ok", "url": "https://..." }`; Plasma opens the URL
only after the CLI reports it.

## Redaction and safety

Do not expose raw secrets.

Rules for the CLI:

- Secret fields must return only `redactedValue`, never raw values.
- Writes for secrets must use stdin, not command-line arguments.
- Descriptors must not include browser cookie values, bearer tokens, API keys,
  account IDs that are not already user-visible, or raw diagnostic responses.
- Error messages should be bounded and safe to store in user config.
- Commands must be local `codexbar` commands, not remote shell snippets.

Rules for Plasma:

- Treat descriptor JSON as a contract, not as raw config.
- Render only supported field kinds.
- Use `writeCommand` and action `command` exactly as arrays of argv-like
  tokens; quote each token when using Plasma's executable data source.
- Reject descriptor commands unless they start with `codexbar config` and use
  an allowed local subcommand: `set`/`set-api-key` for fields, `action` for
  actions.
- Open descriptor-returned URLs only when they are HTTPS URLs.
- Keep secret fields write-only except for `redactedValue`.
- Fall back to current CLI command hints when a descriptor is missing,
  unsupported, or invalid.
- Bound rendering work even for malformed descriptors. Plasma inspects at most
  32 fields and 32 actions per provider, 64 options per field, and 64 command
  tokens of at most 2048 characters each. Fields with text values longer than
  2048 characters are ignored instead of binding or rewriting the value.

## Plasma renderer rules

The first Plasma implementation should be deliberately small:

- Render fields in the Providers page below the redacted diagnostics summary.
- Use native controls: text field, password field, checkbox, combo box, spin box,
  and buttons.
- Disable controls while their command is in flight.
- After a successful write/action, reload `codexbar config providers
  --descriptors --format json --json-only`.
- Keep existing provider enable/disable behavior separate from descriptor
  fields.
- Do not add provider-specific QML branches for individual settings.

## Example descriptor

```json
{
  "provider": "amp",
  "displayName": "Amp",
  "enabled": true,
  "descriptor": {
    "schemaVersion": 1,
    "fields": [
      {
        "id": "sourceMode",
        "kind": "enum",
        "title": "Source",
        "value": "auto",
        "options": [
          { "id": "auto", "title": "Automatic" },
          { "id": "api", "title": "API key" },
          { "id": "web", "title": "Browser cookies" }
        ],
        "writeCommand": [
          "codexbar",
          "config",
          "set",
          "--provider",
          "amp",
          "--field",
          "sourceMode",
          "--value",
          "{value}",
          "--format",
          "json",
          "--json-only"
        ]
      },
      {
        "id": "apiKey",
        "kind": "secret",
        "title": "API key",
        "redactedValue": "amp_...7890",
        "writeCommand": [
          "codexbar",
          "config",
          "set",
          "--provider",
          "amp",
          "--field",
          "apiKey",
          "--stdin",
          "--format",
          "json",
          "--json-only"
        ]
      }
    ],
    "actions": [
      {
        "id": "refreshCookies",
        "kind": "command",
        "title": "Refresh browser cookies",
        "command": [
          "codexbar",
          "config",
          "action",
          "--provider",
          "amp",
          "--action",
          "refreshCookies",
          "--format",
          "json",
          "--json-only"
        ]
      }
    ]
  }
}
```

````
