feature: Separate global default settings from per-agent settings, and remember each agent's own - #62
Merged
Merged
Conversation
The rail's Settings page edited the selected agent's config while reading as an app-wide page, and those per-agent settings lived only in memory. Splits the two scopes apart and gives an agent's settings a durable home. - Settings page becomes Default Settings, bound to ConfigCoordinator.Defaults, and no longer requires an open agent. - A gear in the agent header opens that agent's settings in a docked pane. Both surfaces host one SettingsForm behind ISettingsScope rather than duplicating ~250 lines of markup. - AgentConfigStore persists an agent's config by PersistKey on first save, and CreateCloneFor restores it. An agent identical to the defaults keeps no file and goes on inheriting them. - Secrets and mcpServers are stripped from per-agent files; the coordinator injects them from Defaults and fans changes out to live agents. Reordering of the shared MCP dictionary would otherwise read as a user edit and silently drop every open agent out of inheriting. - The form edits a draft and commits on Save; validation stays per-keystroke via ConfigKeySetter. Keys owned elsewhere (endpoint, model, MCP servers) are excluded from the diff and re-sourced on commit, so a long-open pane cannot undo a model switch made from the header. - Fixes the preview pane's open/attach buttons doing nothing on a website: both guarded on a file path that is null there. Only http(s) reaches ShellExecute. 330 Desktop tests pass; new coverage pins the secret-stripping, MCP-churn and identical-to-defaults rules. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Settings are now two clearly separate things, and an agent's own settings survive being closed and reopened.
The rail's Settings page is now "Default Settings." It holds the starting point every new agent is created from. It no longer requires an agent to be open, since setting up defaults before opening anything is a reasonable thing to want to do.
Each agent has its own settings, behind a gear icon in its header (between the snapshot and folder icons). It opens a panel docked beside that agent's conversation, so the conversation narrows rather than being covered while its settings are changed.
An agent now keeps its settings. Previously they existed only while the app was running and were lost on exit. An agent becomes independent the first time its settings are saved, and comes back on those settings whether it is restored by a relaunch or reopened from the History panel. An agent that has never been configured keeps following the defaults, so raising a default still reaches every agent that was never customised.
Settings apply when saved, not as they are typed. A Save button reports how many changes are waiting, and closing the page or panel discards anything unsaved. Values are still checked as they are entered, so an invalid number is refused at the field rather than at save time.
Two actions move settings between the scopes, both on an agent's panel:
Why this was done
The Settings page was already per-agent — it edited whichever agent was selected — but it was presented as an app-wide page. Anyone reading it would reasonably conclude they were changing a global setting when they were changing one agent, and there was no way to edit the defaults directly at all. Separating the two scopes and naming each one removes that ambiguity.
The persistence gap was the more costly half. Configuring an agent and then closing it silently discarded the work, which made per-agent settings not worth using for anything long-lived.
Handling of shared values
Some settings belong to the whole application rather than to one agent, and are deliberately kept out of per-agent storage:
Also fixed
The preview pane's "open externally" and "attach" buttons did nothing when a website was being viewed, with no message explaining why — both only understood project files. Open now hands the page to the system's default browser, and attach puts its address into the prompt. Previewing a project file still opens that file in its default application; the two cases stay distinct because a file preview is served through an address that only resolves inside the app. Only ordinary web addresses are passed to the system.
Risk and testing
Low. The change is confined to the desktop application; the shared engine is untouched.
Not yet exercised by hand: the two preview-pane buttons against a live website.