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. Wired into ManagedAgentRow expanded section below the log panel.
  • ModelPicker shows provenance label when config surface data is available post-spawn (best-effort, non-blocking).
  • 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
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
@wpfleger96 wpfleger96 force-pushed the wpfleger/phase4-config-bridge branch from 678b871 to c392c34 Compare June 9, 2026 21:09
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