Skip to content

feat(desktop): harness-agnostic config bridge#887

Draft
wpfleger96 wants to merge 1 commit into
mainfrom
wpfleger/phase4-config-bridge
Draft

feat(desktop): harness-agnostic config bridge#887
wpfleger96 wants to merge 1 commit into
mainfrom
wpfleger/phase4-config-bridge

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Adds a harness-agnostic config bridge that reads agent configuration from all available sources and exposes it to the frontend with full provenance — where each value came from and how it can be written back.

Agent config was fragmented across four uncoordinated mechanisms with no single surface to see what a running agent would actually use. The silent failure mode was concrete: Wes's goose personas failed because active_provider in ~/.config/goose/config.yaml was invisible to Sprout and overrode our injected model. The bridge surfaces that ambient config, establishes a clear precedence order, and routes writes to the cheapest live mechanism.

  • New config_bridge module with per-runtime config file readers: YAML for goose (~/.config/goose/config.yaml), JSON for Claude Code (~/.claude/settings.json + ~/.claude.json), TOML for Codex (~/.codex/config.toml). 25 unit tests covering all formats, malformed files, and missing files.
  • Four-tier precedence: Sprout-explicit > ACP native (reserved for goose post goose#9197) > ACP configOptions from session/new > env vars > config file on disk. Pre-spawn surfaces tier 2 only; post-spawn adds ACP tiers.
  • session_config_captured observer event emitted after session/new; put_agent_session_config Tauri command populates SessionConfigCache in AppState. parse_models handles both the object shape ({currentModelId, availableModels}) and legacy array shape from session/new.
  • get_agent_config_surface and write_agent_config_field Tauri commands. Write mechanism is chosen per runtime and field: session/set_config_option (live, no restart) before env-var respawn. Single lock scope on the write path closes a TOCTOU race.
  • AgentConfigPanel component with origin badges (Sprout/ACP/ConfigFile/Env), collapsible advanced section, and sources footer showing all four tier statuses. Override/strikethrough rendering shows superseded config values inline — the overridden value appears crossed out next to the effective value, with both origin badges visible for at-a-glance provenance. Read-only fields display an info icon with tooltip rather than a lock icon.
  • ModelPicker shows provenance label when config surface data is available post-spawn (best-effort, non-blocking).
  • Playwright E2E screenshot spec covering 7 scenarios (goose, claude-code, codex, pre-spawn, overrides, advanced section, sources footer) for visual review.
  • Fixes codex.provider_locked to false — Codex supports [model_providers.<id>] custom provider tables. Fixes serde enum tagging on ConfigWriteMechanism, ConfigFieldType, and WriteConfigTarget to use #[serde(tag = "type")] matching the TypeScript discriminated union shapes (default external tagging made all write operations and TS type guards silently broken).

Stack: #794 → this PR

@wpfleger96 wpfleger96 force-pushed the wpfleger/phase3b-normalized-config branch 2 times, most recently from 66de98f to 60f95a2 Compare June 6, 2026 01:02
@wpfleger96 wpfleger96 changed the title feat(desktop): phase 4 — harness-agnostic config bridge feat(desktop): harness-agnostic config bridge Jun 6, 2026
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase3b-normalized-config branch 6 times, most recently from de81ed1 to 0c44d4e Compare June 9, 2026 17:57
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase4-config-bridge branch from 44cc07f to 678b871 Compare June 9, 2026 18:02
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase3b-normalized-config branch from 0c44d4e to ba28ea0 Compare June 9, 2026 20:31
Base automatically changed from wpfleger/phase3b-normalized-config to main June 9, 2026 20:42
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase4-config-bridge branch 2 times, most recently from c392c34 to 9939a10 Compare June 11, 2026 19:24
wpfleger96 pushed a commit that referenced this pull request Jun 11, 2026
wpfleger96 pushed a commit that referenced this pull request Jun 11, 2026
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase4-config-bridge branch from 3228e7a to 139ada2 Compare June 11, 2026 20:16
wpfleger96 pushed a commit that referenced this pull request Jun 11, 2026
wpfleger96 pushed a commit that referenced this pull request Jun 11, 2026
@wpfleger96

Copy link
Copy Markdown
Collaborator Author

Config Bridge — AgentConfigPanel Screenshots (v4)

Updated screenshots with inline override rendering: overridden values appear with strikethrough next to the effective value, and overridden origin badges appear next to the effective badge.

1. Goose — Full Config Panel

Mixed-origin badges (Sprout/ACP/ConfigFile/Env), model/provider/mode fields with provenance tracking. Info icon on read-only fields with hover tooltip. Override value inline with strikethrough.

01-goose-full-config

2. Claude Code — ACP Config Options

ACP-sourced values with green badges, demonstrating the "one surface, multiple runtimes" approach.

02-claude-acp-config

3. Pre-Spawn State

Dimmed ACP fields showing "Available after agent starts" — config surface before runtime is active.

03-pre-spawn-state

4. Override Visibility

Effective value shown with overridden default crossed out inline, plus both origin badges side by side.

04-override-visibility

5. Advanced Section Expanded

Collapsible advanced section with runtime-specific extra fields (extensions, output style, etc.).

05-advanced-expanded

6. Sources Footer

Four-tier status indicators showing which config sources are active.

06-sources-footer

7. Codex — Dual-Mode Display

Codex's unique dual-axis mode (approval_policy × sandbox_mode).

07-codex-dual-mode

wpfleger96 pushed a commit that referenced this pull request Jun 11, 2026
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase4-config-bridge branch 3 times, most recently from 85ab849 to 03d4165 Compare June 12, 2026 19:27
Four-tier config bridge that reads agent configuration from config
files (goose YAML, claude JSON, codex TOML), ACP session data, env
vars, and Sprout-explicit overrides — surfacing a unified normalized
config surface to the desktop UI regardless of runtime.

Key changes:
- Config bridge module with per-runtime file readers
- ACP session config caching for post-spawn config visibility
- AgentConfigPanel component with origin badges and tier provenance
- Serde internally-tagged enums matching TypeScript discriminated unions
- TOCTOU-safe write path with single lock scope
- E2E mock handler for get_agent_config_surface with per-runtime
  fixtures and a Playwright screenshot spec covering 7 scenarios
- Info icon + tooltip on read-only fields; override/strikethrough
  rendering for superseded config values
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase4-config-bridge branch from 03d4165 to 69e6bc8 Compare June 12, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant