ADR 0028: User settings - settings.toml, directory %LocalAppData%\CascadeIDE\, secrets separately¶
Status: Accepted · Implemented
Date: 2026-04-08
Updated: 2026-04-13 - LSP presets in settings.toml (0040). Details - § History.
Related ADRs¶
| ADR | Role |
|---|---|
| 0010 | TOML for bundle modes and repository workspace.toml is another layer, not to be confused with the user file |
| 0013 | hotkeys.toml next to settings.toml - intended, not necessarily implemented |
| 0026 | part of the presets in merged workspace.toml; custom placement override - not just settings.toml |
| 0027 | predictable configuration paths |
| 0029 | TOML as canon; UI - facade above the same file |
| 0017 | presentation - first of all settings.toml, not a repo |
| 0040 | C#/Markdown LSP: presets, optional executable/arguments keys, optional environment |
Implementation snapshot¶
| Element | Meaning |
|---|---|
| Service | SettingsService |
| Catalog | %LocalAppData%\CascadeIDE\ |
| Settings | settings.toml (Tomlyn, snake_case) |
| Secrets | ai-keys.toml (separate from settings) |
Summary¶
- Custom canon:
%LocalAppData%\CascadeIDE\settings.toml(Tomlyn). - Secrets -
ai-keys.toml, not in the main settings file. - Separate from the
UiModes/bundle and merge.cascade/workspace.toml(0010). - LSP presets - 0040.
Context¶
The product already has several layers of configuration: spiked UiModes/ bundle, merge with .cascade/workspace.toml in the open repository (0010), global user preferences (AI, MCP, LSP, panel visibility, UI locale, etc.). At the same time, there was no separate ADR that captures user channel (path on disk, format, what we put where) - the links are scattered across 0010, 0015, UX-docs.
We need one canon point: where “my computer” is located, what is in TOML, what cannot be put in TOML, how it relates to the repository layer.
Solution¶
1. CascadeIDE User Data Directory¶
- Base path:
%LocalAppData%\CascadeIDE\(viaEnvironment.SpecialFolder.LocalApplicationData+CascadeIDEsegment). - The directory is created on the first call, if missing (
SettingsService.GetSettingsDirectory()). - This directory is not the solution directory and not
AppContext.BaseDirectory; it is tied to the Windows user and the installation of the application on the machine.
2. Main settings file: settings.toml¶
- Full path:
%LocalAppData%\CascadeIDE\settings.toml. - Model:
CascadeIdeSettingsis the only source of truth for set of fields and meanings (AI providers, MCP, LSP C#/Markdown, Kroki, panel visibility,UiMode, UI locale, etc.). - Serialization: Tomlyn via
CascadeTomlSerializer: keys in file - snake_case, C# properties - PascalCase (TomlSerializerOptionswithJsonNamingPolicy.SnakeCaseLower). - Loading: when starting
SettingsService.Load(); in case of a reading/parsing error - default model from the code, without crashing the IDE. - Saving:
SettingsService.Save(CascadeIdeSettings)- overwriting the entire file; write errors are swallowed (current implementation policy is not to block the UI).
Before public release: do not increase automatic migrations in SettingsService when renaming/transferring TOML keys - see subsection "Before public release" in the root README. After the appearance of mass installations, a separate solution (file version, one-time migrator, changelog).
3. Historically: JSON is no longer supported¶
- Previously, the code had a one-time migration
settings.json→settings.toml; As of this ADR, there are no legacy settings supported, migration branch removed fromSettingsService.Load(). - Canon - only
settings.toml; if there is no file, default values from the code. The customsettings.jsonin%LocalAppData%\CascadeIDE\is not readable (if the file is left manually, you need to transfer it to TOML yourself or delete it).
4. Secrets: not in settings.toml¶
- API keys (Anthropic, OpenAI, DeepSeek, etc.) are stored in
%LocalAppData%\CascadeIDE\ai-keys.toml, separateAiKeysmodel, serialized viaCascadeTomlSerializer(same assettings.toml: keys in the file - snake_case),AiKeysStorage.Load/Save. - Reasons for separation: do not reveal secrets in the same file, which is convenient to copy/display in logs; simpler backup policy and
.gitignorefor the user; corresponds to the direction 0013 (do not mix everything in one “lump”). TOML format rather than separate JSON - single serialization stack with custom settings. - Do not commit
ai-keys.toml; The developer documentation assumes only a local machine. The fileai-keys.jsonis not readable (if it remains manually, move it to TOML or delete it).
5. What this ADR doesn't describe (explicit distinction from 0010)¶
| Layer | Where | Destination |
|---|---|---|
| User | %LocalAppData%\CascadeIDE\settings.toml |
User preferences on this machine (model CascadeIdeSettings). |
| Application bundle | UiModes/ next to exe |
UI modes, index, spike workspace.toml bundle. |
| Repository | <solution>/.cascade/workspace.toml |
Team/project overlay on top of the bundle (merge in 0010). |
Name workspace.toml: one merge contract, not “two meanings” - and where the file is not¶
- Chrome and mode presets (0010): one data model (
UiWorkspaceToml), two sources of one file name - spikedUiModes/workspace.tomland when the solution is open, optionally<repo>/.cascade/workspace.toml. This is a merge chain (bundle → overlay repo), and not two different products with the same name. %LocalAppData%\CascadeIDE\: there is noworkspace.tomlfile and in the current canon not intended - global user settings live insettings.toml. A typical confusion when reading the docs: look for "user workspace" next tosettings.tomlunder the same name.
Renaming workspace.toml in a bundle/repo (for example in ui-workspace.toml) we do not do just for the sake of uniqueness of the name on disk: it will affect the assembly, merge, keys in 0026, examples and expectations “workspace = IDE layout”. If ever needed - separate ADR + migration of paths and bundle versions.
The state tied to a specific solution (for example, the selected startup project for debugging: Services/StartupProjectStore → <directory .sln>/.cascade-ide/startup-project.json) does not lie in %LocalAppData%\CascadeIDE\ - this is a separate channel "next to the repo", not global user settings.
6. Future files in the same directory¶
hotkeys.toml- by intent 0013, next tosettings.toml, overrides only; prior to implementation, this ADR does not obligate their availability.- Layout by physical displays (
presentation/zone_screen_layoutand grammar tokens by 0017) - personal layer, primarily fields insettings.toml, rather than a team commitment via the repositoryworkspace.toml(0017 § storage layer). - Additional user files (for example, window status by 0017) - separate ADR when an agreement appears, with an explicit link to this directory or to a new key in
settings.toml.
Consequences¶
- Documentation and agents: with the word “user settings” - the path to
settings.tomland the modelCascadeIdeSettings; for “API secrets” -ai-keys.toml. - New fields in user settings are added to
CascadeIdeSettings+ if necessary UI/saving; when the meaning of a layer changes, update this ADR or refer to a new one. - Tests can replace loading through existing mechanisms or model instances without writing to disk - without changing the canon of paths.
Rejected alternatives¶
- Keep custom settings in JSON as primary format - rejected: canon - TOML; automatic migration from
settings.jsonis removed from the code in the absence of supported legacy profiles. - Store API keys in
settings.toml- rejected: mixing secrets with portable/editable config and risk of leakage when exchanging files. - Keep secrets in a separate JSON (
ai-keys.json) - rejected in favor ofai-keys.toml: same format withsettings.tomland the sameCascadeTomlSerializer; the separate file still isolates the secrets from the "regular" config. - One ADR for all TOML - rejected: 0010 remains about modes and merge; user file - separate path and content contract.
- Rename
workspace.tomlin the bundle/repo only because the name matches expectations - rejected without separate ADR and migration (see §5.1).
History of changes¶
| Date | Change |
|---|---|
| 2026-04-08 | Canon: settings.toml, LocalAppData directory; workspace.toml in the merge layer (0010). |
| 2026-04-08 | Removed settings.json → TOML migration; legacy is not supported. |
| 2026-04-08 | Secrets: ai-keys.toml instead of JSON; There is no migration from JSON. |
| 2026-04-11 | Before public release - without auto-migrate scheme (README § Before public release). |
| 2026-04-11 | presentation → 0017. |
| 2026-04-13 | LSP in settings.toml → 0040. |