Skip to content

Architecture

Stuart Meeks edited this page Jun 8, 2026 · 1 revision

Architecture

For contributors. The authoritative, always-current source is CLAUDE.md in the repo; this page is an orientation.

Stack

  • .NET 10, C#.
  • WinUI 3 (Windows App SDK) for the UI.
  • Unpackaged distribution (no MSIX/Store) — this is load-bearing: it gives normal Win32 file access for the user-chosen storage/backup folders and is what the Velopack updater expects.
  • MVVM via CommunityToolkit.Mvvm; DI via Microsoft.Extensions.DependencyInjection.
  • Windows 11 is the real target (Mica); Windows 10 falls back to a solid colour.

Projects and the dependency rule

graph TD
    App["Snipdeck.App (net10.0-windows, WinUI 3 head)"] --> Core["Snipdeck.Core (net10.0, UI-free)"]
    App --> Exec["Snipdeck.Execution (net10.0, command execution)"]
    Exec --> Core
    Importer["Snipdeck.Importer (net10.0 tool)"] --> Core
    Tests["Snipdeck.Core.Tests / Snipdeck.Execution.Tests"] --> Core
    Tests --> Exec
Loading
  • Snipdeck.Core (net10.0, not net10.0-windows) — completely UI-free. The domain models, the parameter substitution engine, the JSON store, settings, backup, icon resolution, the view models, and every service interface. This is the testable heart of the app.
  • Snipdeck.Execution (net10.0) — the command-execution feature as a self-contained module: a headless VT→plain-text processor, the SQLite history store, a pseudo-terminal (ConPTY) runner via Porta.Pty, and the run/history view models. UI- free; references Core only.
  • Snipdeck.App (net10.0-windows) — the WinUI 3 head: XAML views, app startup, DI wiring, and the Windows/Win32 implementations of Core's (and Execution's) service interfaces. It's the only project allowed to touch WinUI / Windows / Win32 types.
  • Snipdeck.Importer — the cross-platform SnipCommand import tool (see Importing from SnipCommand).

The dependency direction is one-way: App → {Core, Execution} and Execution → Core. Never the reverse.

Dependency inversion

Every platform-bound capability — clipboard, global hotkey, tray, file picker, updates, dispatcher, command execution — is an interface defined in Core (or Execution) and implemented in App, injected via DI. View models reference only these abstractions, never WinUI types (Frame, NavigationView, DispatcherQueue, …). This keeps Core portable and unit-testable, and preserves the option of a future cross-platform (Avalonia) head — though that isn't built.

Persistence boundary

  • The snip store (definitions) is a single human-readable JSON document via System.Text.Json, written crash-safely (temp file + atomic rename). Not SQLite, not LiteDB — definitions are small and JSON is sync-friendly.
  • Execution history is the deliberate exception: run output isn't small, so it lives in a separate SQLite database (history.db). The JSON-only rule still governs the store.

See Data Storage and Backups.

The testable heart

The parameter substitution engine, the JSON store, the VT processor, the shell-command builder and the history store are covered by unit tests (Snipdeck.Core.Tests, Snipdeck.Execution.Tests) that run on any platform — the bits where a silent bug hurts most. See Building Testing and Releasing.

Clone this wiki locally