CmdPal: Extract persistence services from SettingsModel and AppStateModel#46312
Merged
michaeljolley merged 8 commits intomainfrom Mar 20, 2026
Merged
CmdPal: Extract persistence services from SettingsModel and AppStateModel#46312michaeljolley merged 8 commits intomainfrom
michaeljolley merged 8 commits intomainfrom
Conversation
- Created orchestration logs for Snake Eyes (Phases 1-4 implementation) - Created orchestration logs for Duke (code review, APPROVED verdict) - Created orchestration logs for Hawk (23 unit tests, 14/14 passing) - Written session log documenting complete persistence service extraction - Merged decision inbox files into decisions.md (2 decisions recorded) - Updated agent history files (snake-eyes, duke, hawk) with session learnings - Cleaned up decision inbox (3 files processed and removed) This session completed the persistence service architecture for CmdPal: - Extracted logic from SettingsModel/AppStateModel into service layer - Created IPersistenceService, ISettingsService, IAppStateService - Updated ~20 consumer files with proper DI injection - Verified migration logic preserved, contracts stable, no ABI breaks - Established test patterns for future service development Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove raw model DI registrations - Inject IApplicationInfoService into persistence services - Update 42+ consumer locations across ~26 files - Build passing, 43/43 tests passing - Code review approved Orchestration logs created for Snake Eyes and Duke. Decision record merged and deduped.
… AppStateModel - Create IPersistenceService, ISettingsService, and IAppStateService interfaces - Implement PersistenceService with generic Load<T>/Save<T> and shallow-merge - Implement SettingsService with migration support and hot-reload events - Implement AppStateService with load/save lifecycle and state change events - Strip all persistence logic from SettingsModel and AppStateModel (pure data models) - Inject IApplicationInfoService for config directory resolution - Remove raw model DI registrations; all consumers use service interfaces - Update 31 consumer files from direct model access to service-based access - Replace Colors.Transparent with struct literal to remove WinUI3 COM dependency - Add 23 unit tests (PersistenceService, SettingsService, AppStateService) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
check-spelling found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace relative namespace references (Services.ISettingsService, Services.IAppStateService) with proper using directives across 7 ViewModel files for consistency with the rest of the codebase. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace underscore-prefixed convenience properties (_settings, _settingsModel, _appStateModel, _dockSettings) with direct service property access (_settingsService.Settings, _appStateService.State). Removes all #pragma warning disable SA1300 suppressions (14 blocks across 12 files, ~192 inline replacements). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jiripolasek
reviewed
Mar 20, 2026
src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/PersistenceService.cs
Show resolved
Hide resolved
src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/PersistenceService.cs
Outdated
Show resolved
Hide resolved
src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/PersistenceService.cs
Outdated
Show resolved
Hide resolved
src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/SettingsService.cs
Outdated
Show resolved
Hide resolved
jiripolasek
requested changes
Mar 20, 2026
src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/PersistenceService.cs
Outdated
Show resolved
Hide resolved
PersistenceService.Save now calls Directory.CreateDirectory before File.WriteAllText to prevent DirectoryNotFoundException on first run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nd Reload - Remove shallow-merge strategy from PersistenceService.Save (direct write replaces read-merge-write) - Remove postProcessMerge callback parameter from IPersistenceService - Remove Reload() from ISettingsService and SettingsService - Consolidate Directory.CreateDirectory into PersistenceService.Save only, removing redundant calls from service path helpers - Update test mocks to match new 3-arg Save signature - Remove tests for dropped features (shallow merge, postProcessMerge, Reload) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.

Summary of the Pull Request
Extracts persistence (load/save) logic from
SettingsModelandAppStateModelinto dedicated service classes, following the single-responsibility principle. Consumers now interact withISettingsServiceandIAppStateServiceinstead of receiving raw model objects through DI.New services introduced:
IPersistenceService/PersistenceService— genericLoad<T>/Save<T>with AOT-compatibleJsonTypeInfo<T>, ensures target directory exists before writingISettingsService/SettingsService— loads settings on construction, runs migrations, exposesSettingsproperty andSettingsChangedeventIAppStateService/AppStateService— loads state on construction, exposesStateproperty andStateChangedeventKey changes:
SettingsModelandAppStateModelare now pure data models — all file I/O, migration, and directory management removedSettingsModelandAppStateModelremoved from DI container; consumers receive the appropriate serviceIApplicationInfoService.ConfigDirectoryinjected into services for config path resolution (no more hardcodedUtilities.BaseSettingsPath)Microsoft.CmdPal.UI.ViewModelsandMicrosoft.CmdPal.UIprojects#pragma warning disable SA1300suppressions removed — convenience accessors replaced with direct_settingsService.Settings/_appStateService.StateaccessServices.ISettingsService) replaced with properusingdirectivesPR Checklist
Detailed Description of the Pull Request / Additional comments
Architecture
Services are registered as singletons in
App.xaml.cs:PersistenceService.Save<T>writes the serialized model directly to disk, creating the target directory if it doesn't exist. It also does not attempt to merge existing and new settings/state.SettingsServiceruns hotkey migrations on load and raisesSettingsChangedafter saves.AppStateServicealways raisesStateChangedafter saves.Files changed (41 files, +1169/−660)
Services/IPersistenceService.cs,PersistenceService.cs,ISettingsService.cs,SettingsService.cs,IAppStateService.cs,AppStateService.csSettingsModel.cs,AppStateModel.csApp.xaml.csDockSettings.csColors.Transparentreplaced with struct literal to avoid WinUI3 COM dependencyPersistenceServiceTests.cs,SettingsServiceTests.cs,AppStateServiceTests.cs.gitignore.squad/,.github/agents/exclusionsValidation Steps Performed
Microsoft.CmdPal.UIwith MSBuild (x64/Debug) — exit code 0, clean buildvstest.console.exe— all passing#pragma warning disable SA1300blocksServices.namespace prefixes