Skip to content

feature: Separate global default settings from per-agent settings, and remember each agent's own - #62

Merged
DevMando merged 1 commit into
mainfrom
feature/per-agent-settings
Sep 10, 2026
Merged

feature: Separate global default settings from per-agent settings, and remember each agent's own#62
DevMando merged 1 commit into
mainfrom
feature/per-agent-settings

Conversation

@DevMando

@DevMando DevMando commented Sep 10, 2026

Copy link
Copy Markdown
Owner

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:

Action Effect
Apply Global Defaults Replaces this agent's settings with the current defaults, and lets it follow future changes to them again.
Save to Global Defaults Makes this agent's settings the starting point for new agents. Agents already open keep their own.

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:

  • API keys are never written to a per-agent file. They remain in the shared configuration and are supplied to each agent in memory. Without this, configuring five agents would put five copies of a key on disk.
  • MCP servers stay shared. They are one set of processes owned by the application, so they are re-read from the shared configuration rather than stored per agent.
  • The endpoint and model are not editable on an agent's panel. An agent's endpoint is set when it launches and its model comes from the dropdown in its own header, so repeating them on the panel would be a second place to change the same thing.

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.

  • Full build clean, 330 tests pass (up from 303).
  • New automated coverage pins the three rules a stored agent depends on: that its file never contains an API key, that it is unaffected by shared changes made elsewhere while its panel is open, and that an agent matching the defaults is treated as still following them.
  • Manually exercised end to end: changing a setting shows the pending count and writes nothing; saving stores it; closing without saving discards it; and reopening the agent restores what was saved.

Not yet exercised by hand: the two preview-pane buttons against a live website.

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>
@DevMando
DevMando merged commit e4373b9 into main Sep 10, 2026
1 check passed
@DevMando
DevMando deleted the feature/per-agent-settings branch September 10, 2026 01: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