feat(desktop): harness-agnostic config bridge#887
Conversation
66de98f to
60f95a2
Compare
de81ed1 to
0c44d4e
Compare
44cc07f to
678b871
Compare
0c44d4e to
ba28ea0
Compare
c392c34 to
9939a10
Compare
3228e7a to
139ada2
Compare
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 PanelMixed-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. 2. Claude Code — ACP Config OptionsACP-sourced values with green badges, demonstrating the "one surface, multiple runtimes" approach. 3. Pre-Spawn StateDimmed ACP fields showing "Available after agent starts" — config surface before runtime is active. 4. Override VisibilityEffective value shown with overridden default crossed out inline, plus both origin badges side by side. 5. Advanced Section ExpandedCollapsible advanced section with runtime-specific extra fields (extensions, output style, etc.). 6. Sources FooterFour-tier status indicators showing which config sources are active. 7. Codex — Dual-Mode DisplayCodex's unique dual-axis mode (approval_policy × sandbox_mode). |
69e6bc8 to
fba912f
Compare
2357920 to
ac3a45e
Compare
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 Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…place badges with provenance sentences
Persona-linked agents had their inherited model/prompt/provider invisible
in the config panel, and the source indicators (checkmark/hourglass icons,
colored badges, footer) were undecipherable.
Phase 1: Resolve all three persona fields (prompt, model, provider) in a
single resolve_config_surface helper called by both get_agent_config_surface
(read) and write_agent_config_field (write). The helper injects resolved
values into the record where absent, calls the reader, then re-tags the
injected fields from BuzzExplicit to PersonaDefault. The re-tag is triple-
gated so a value the user set explicitly in Buzz is never re-tagged. Sharing
the helper keeps the read and write surfaces identical, so plan_config_write
never returns "field not available" for a persona-sourced field. Reader stays
untouched (pure tier-merge function).
Phase 2: Add AgentConfigPanel to ProfileSummaryView in the profile pop-out,
gated on isBot && isOwner && managedAgent defined.
Phase 3: Remove SourcesFooter and colored OriginBadge pills. Replace with
gray inline provenance sentences below each value ("Set in Buzz", "Inherited
from persona", "From environment variable", etc). No action clauses.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
ac3a45e to
69d2c4e
Compare







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_providerin~/.config/goose/config.yamlwas 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.config_bridgemodule 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.configOptionsfromsession/new> env vars > config file on disk. Pre-spawn surfaces tier 2 only; post-spawn adds ACP tiers.session_config_capturedobserver event emitted aftersession/new;put_agent_session_configTauri command populatesSessionConfigCacheinAppState.parse_modelshandles both the object shape ({currentModelId, availableModels}) and legacy array shape fromsession/new.get_agent_config_surfaceandwrite_agent_config_fieldTauri 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.AgentConfigPanelcomponent 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.ModelPickershows provenance label when config surface data is available post-spawn (best-effort, non-blocking).codex.provider_lockedtofalse— Codex supports[model_providers.<id>]custom provider tables. Fixes serde enum tagging onConfigWriteMechanism,ConfigFieldType, andWriteConfigTargetto 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