Skip to content

Add a managed Claude Code client config adapter and settings UI #76

Closed

Description

@NOirBRight

Part of #73.

Blocked by: #75, #77 (native dependencies). Configuration follows the working route and the settled model contract — never the reverse.

Objective

Add Claude Code as a managed external Gateway client: a Claude-specific adapter that writes only CodexHub-managed keys into the current user's Claude Code configuration after an explicit, disclosed activation, plus a Clients card with a dedicated settings dialog. No client configuration UI ships ahead of working Messages text, tools, and streaming.

This supersedes the earlier launcher-first default. A generated launcher is not a required deliverable.

Authority

ADR-0014 "Claude Code activation exception" and "Model selection"; the ADR-0004 exception note; the amended Injected Block and new Activation, Claude Model Mapping, and Compatibility Adaptation terms in CONTEXT.md. ADR-0004's backup, atomic publication, conflict detection, and surgical restore requirements remain mandatory.

Scope

1. Managed-client adapter

  • Detect the claude executable, version, and current-user configuration path; report an actionable diagnostic when the CLI is missing, unsupported, or /v1/messages is unavailable.
  • Add a Claude-specific adapter under the existing managed-client coordinator (src-tauri/src/gateway/clients/) implementing metadata() / inspect() / plan() with preview, apply, restore, and block-fingerprint readback. The adapter stays pure; the coordinator owns the write lock, atomic publish, backup, and readback.
  • The Injected Block is the exact managed key set (route, credential, model settings) — not an invented provider entry. Claude Code has no provider map, so do not fabricate one.

2. Managed content and activation

  • Managed keys (exact names and role variables per Spike Claude Code Messages compatibility through CodexHub #74/Expose every Gateway model to Claude Code with fixed-name and role mapping #77 evidence), expected to include the Gateway base URL, the local Gateway credential via ANTHROPIC_AUTH_TOKEN, and the default/role model selections.
  • Explicit activation: Connect discloses that it changes the current user's default route and default-model fields for newly launched Claude Code, and requires confirmation. Ordinary automatic republish must not activate a disconnected client, and must not overwrite a user's conflicting edits.
  • Preserve unrelated configuration. Back up previous values, publish atomically, detect concurrent edits, verify only the owned fields, and preserve subsequent foreign edits. Surface conflicting managed-field edits instead of replacing the whole file.
  • Restore on Disconnect removes or restores only CodexHub-owned fields.
  • Never modify project configuration or Claude login credentials as a side effect. Inspect environment/project overrides and report ineffective configuration without rewriting them.
  • Write the local Gateway credential only. Never write an upstream API key or subscription credential. Mask secrets in previews and protect backups.

3. Clients surface

  • Register Claude Code in the roster: adapter_for, config_present_for, native-apply support, list_gateway_clients, frontend/src/lib/ui-contract.json, GatewayClientId, the card icon map, and gateway.clientKind in both locales.
  • Update the roster-count and adapter-registration tests that pin the current client set, plus the UI-contract and locale-parity tests.
  • Keep the existing connect/disconnect state machine and Toast/restart disclosure; report the accurate restart requirement for Claude Code.
  • Dedicated settings dialog for the Claude Code card only: read-only searchable list of Gateway-exported models, default-model picker, searchable fixed-name/role mapping editor (Expose every Gateway model to Claude Code with fixed-name and role mapping #77's contract), pending changes, conflicts, invalid mapping warnings, and a concise compatibility state sourced from the Gateway diagnostics record.
  • Other Clients receive no Claude-specific controls. Reuse the existing dialog, settings persistence, and Toast lifecycle rather than building a generic client-settings framework.

4. Headless verification path

  • Extend the isolated/managed-client verification seam (ISOLATED_CLIENTS / ISOLATED_MANAGED_CLIENTS) with an entry for Claude Code, or document and implement an equivalent non-destructive verification contract. The current seam is file-oriented; a key-set/env shape needs its InjectionShape decided explicitly rather than forced into a provider-entry shape.

Out of scope

The Messages route (#75), the model/alias contract itself (#77), the release matrix (#78), launcher scripts as a default path, and ACP/AgentProvider work (#85).

Acceptance criteria

  • Preview masks the Gateway key and enumerates every managed key with its before/after value.
  • Connect requires explicit confirmation of its current-user route scope; there is no silent activation path.
  • Apply writes only the managed key set: unrelated keys, project configuration, and Claude login credentials are untouched.
  • Backup, atomic write, concurrent-change detection, owned-field readback, and field-scoped restore are covered by tests.
  • Disconnect restores/removes only CodexHub-owned fields and preserves later foreign edits.
  • No upstream credential can appear in previews, config writes, launcher text, logs, telemetry, or exports.
  • Missing/incompatible Claude Code and unavailable /v1/messages produce actionable diagnostics.
  • Claude Code appears once in the Clients rail with correct i18n in English and Chinese, and no other client gains Claude-specific controls.
  • The settings dialog covers model list, default model, mappings, pending changes, conflicts, invalid mappings, and restart requirements, with keyboard/focus and empty/loading/error states.
  • Catalog changes republish the projection; removed mapping targets render as invalid, never silently substituted.
  • The isolated verification path covers the Claude Code managed key set.
  • Client-rail, adapter, persistence, conflict, and restore tests cover the new client.

Required verification

Risk class: strict — persisted settings, security boundary, client lifecycle. Use the repository launcher; never a bare python/pytest.

Push-Location src-tauri
cargo test --locked
cargo clippy --locked --all-targets -- -D warnings
Pop-Location
Push-Location frontend
npm run build
npm run test:ui-contract
Pop-Location
.\scripts\codexhub-python.cmd -m pytest -q --ignore=tests/test_real_client_e2e.py
.\scripts\codexhub-python.cmd scripts/report_quality_gates.py

Linux: ./scripts/verify-linux.sh (builds the real app and runs the mandatory pointer-input E2E). UI evidence covers model selection, mappings, connect/disconnect, synchronization, and restart feedback without regressing other Clients.

References

  • src-tauri/src/gateway/managed_clients.rs, src-tauri/src/gateway/clients/, src-tauri/src/gateway/isolated.rs, src-tauri/src/injection.rs, src-tauri/src/gateway/readback.rs
  • frontend/src/components/GatewayClientCard.tsx, frontend/src/pages/GatewayPage.tsx, frontend/src/components/workspace/WorkspaceDialog.tsx, frontend/src/components/SettingsDrawer.tsx, frontend/src/lib/clientConnectionState.ts
  • docs/research/2026-09-13-grok-cli-managed-client.md — validated recipe for adding a roster client (note: its provider-entry shape does not apply here)
  • docs/agents/user-feedback.md, docs/ui/020-workspace-implementation.md

Document status

ADR-0014 is committed in draft PR #556 at ed76f0a6e22d3188879504638b2943f5bb855d41, not yet merged to main. The pinned link is readable now; the document is accepted direction, not live protocol evidence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds-triageMaintainer needs to evaluate this issuewayfinder:taskWayfinder implementation task

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions