Fix duckdb_tables query error after SQLCipher migration
Details
DataPlugin.GetMetricsAsync was querying duckdb_tables() which no longer
exists after the DuckDB → SQLCipher migration. Replaced with
sqlite_master query to find dataset tables (ds_* pattern).
SQLite doesn't expose per-table byte sizes like DuckDB did, so the
method now returns a set of existing table names and the caller uses
the existing row-count × column-count heuristic for all tables.
- Rename QueryDuckDbTableSizesAsync → QueryDatasetTablesAsync
- Return HashSet<string> instead of Dictionary<string, long>
- Query sqlite_master WHERE type='table' AND name LIKE 'ds_%'
- Fix stale DuckDB references in comments
- Bump Data plugin 1.21.1 → 1.21.2
Fix Dashboard plugin toggle not rendering + clean up alloc tracking
Details
The ToggleSwitch for enabling/disabling plugins was invisible because
ToggleSwitch in Avalonia does not have Command/CommandParameter properties.
The XAML parser silently dropped the invalid attributes, preventing the
control from rendering.
- Remove invalid Command/CommandParameter from ToggleSwitch
- Switch to two-way IsChecked binding on IsActivated property
- Add OnActivationChanged callback on DashboardPluginItem that fires
when IsActivated changes from the ToggleSwitch
- Wire callback in PopulateLocalPlugins AFTER setting initial value
to avoid re-entrant enable/disable calls during initialization
- Add OnPluginActivationChanged handler that syncs to plugin registry
Also cleans up SubsystemTracker: removed broken heartbeat approach for
long-running task alloc tracking (GC.GetAllocatedBytesForCurrentThread
cannot be queried cross-thread after await resumes on a different thread).
Fix Subsystems tab: use process-level native memory, improve column layout
Details
The "Native Memory" summary card was showing only Rust allocator-tracked
bytes (~126 B), which is misleading when the process uses ~1.4 GB native.
The Rust GlobalAlloc only tracks Rust heap allocations — C/C++ libraries
(SQLCipher, ONNX, Whisper, LLamaSharp) use their own malloc directly.
- Summary "Native Memory" card now uses WorkingSet64 - GC heap (same
calculation as the Overview tab's memory card)
- Per-subsystem memory column renamed to "Tracked Memory" and widened
to accommodate labels like "126 B native" or "7.0 MB managed"
- Memory display now distinguishes native vs managed with explicit labels
- Column widths adjusted (Category 80, Tasks 60, Memory 180, Rate 100)
- Removed broken heartbeat approach for long-running task alloc tracking
(GC.GetAllocatedBytesForCurrentThread can't be queried cross-thread)
Fix disabled plugins not showing in Settings for re-enable
Details
Root cause: when a plugin is disabled, its assembly is deferred (not
loaded) at startup to save memory. But the Settings plugin list only
iterated over loaded plugins (_plugins), so deferred plugins were
invisible — the user could never re-enable them.
Fix:
- Expose DeferredPluginDirs on IPluginRegistry — maps plugin IDs to
their discovered directory paths for plugins that were skipped
- SettingsViewModel.LoadPluginItems() now appends deferred plugins to
the list with IsEnabled=false, allowing the user to toggle them on
- Toggling on triggers the existing EnablePlugin() deferred path which
dynamically loads the assembly from the saved directory
- HeadlessPluginRegistry implements the new property with an empty dict
Fix fresh-install StorageError and update C# paths for SQLite migration
Details
Root cause: on fresh install (no salt file, no existing DB), init_core()
opened an unencrypted on-disk database at data.privstack.db. When
auth_initialize() then tried to create an encrypted DB at the same path,
SQLCipher failed because the file already existed as unencrypted.
Fix (Rust FFI):
- Fresh install now opens in-memory placeholder (same as encrypted mode)
- Only open unencrypted on-disk for legacy databases that already exist
- auth_initialize detects legacy unencrypted DB and skips SQLCipher
creation, just initializes vault on the existing DB
Fix (C# Desktop):
- WorkspaceService: base path changed from "data.duckdb" to "data"
(Rust derives "data.privstack.db" via with_extension)
- SetupWizardViewModel: same path change
- PrivStackService: updated diagnostics to check .privstack.db,
.datasets.db, .privstack.salt instead of old .duckdb files
- App.axaml.cs: updated orphan cleanup patterns and diagnostics
- DashboardViewModel: updated file size checks and compact display
- SystemMetricsService: updated file paths, WAL suffix (.wal → -wal)
Get notified about new releases