Add database compaction via COPY FROM DATABASE
Details
DuckDB's CHECKPOINT reclaims WAL space but cannot free allocated-but-empty
blocks after mass deletion. This adds a full compaction step to maintenance
that uses COPY FROM DATABASE to create a fresh, minimal file and atomically
swaps it in place of the bloated original.
Implementation:
- EntityStore.compact() swaps the live connection behind the Mutex so all
Arc<EntityStore> references remain valid after compaction
- compact_duckdb_file() handles standalone DBs (datasets, blobs, events)
with open→copy→close→rename
- FFI: privstack_compact_databases() compacts entities + sibling DBs
(vault excluded — has active VaultManager connection)
- Safety: checkpoint before copy, backup original before swap, restore on
failure, clean up WAL files and backups
- Dashboard maintenance now runs orphan cleanup → checkpoint → compact
and reports before/after sizes
Rust 1.13.3→1.13.4, SDK 1.43.1→1.43.2, Desktop 1.45.3→1.45.4
Fix Expander header hover flash from Fluent theme override
Details
The Expander control's header is internally a ToggleButton#PART_toggle.
Avalonia's Fluent theme overrides its ContentPresenter background on
hover/checked states, causing a visual flash. Added TemplateBinding
overrides for the Expander's internal ToggleButton in all pseudoclass
states (normal, pointerover, checked, checked:pointerover) — same
pattern used for Button, ListBoxItem, and ToggleButton fixes.
Desktop 1.45.2 → 1.45.3
Orphan entity detection + fix VACUUM→CHECKPOINT
Details
DuckDB VACUUM does NOT reclaim space — only CHECKPOINT does. Fixed maintenance
to use CHECKPOINT instead. Also added orphan entity detection: maintenance now
builds a list of all valid (plugin_id, entity_type) pairs from registered
plugins and system types, queries the DB for entities not matching any known
type, and deletes them with cascade cleanup of auxiliary tables.
This fixes the phantom entity problem where wiped data survives because its
entity_type isn't in any plugin's WipeTargets. Maintenance also clears
transient data (cloud_sync_cursors, plugin_fuel_history) that rebuilds on sync.
New FFI functions:
- privstack_find_orphan_entities(valid_types_json) → orphan summaries
- privstack_delete_orphan_entities(valid_types_json) → deletes + checkpoint
Removed force-recreate approach in favor of proper detection-based cleanup.
Increase Data tab bottom padding and fix row count pluralization
Details
Increase ScrollViewer bottom padding from 48px to 80px so the diagnostics
section isn't overlapped by the main window status bar. Fix "1 rows" → "1 row"
by moving pluralization logic into FormattedRowCount property.
Replace ThemeSuccessBrush with ThemePrimaryBrush on shell action buttons
Details
Update SetupWizard checkmark/create icons, SyncPairing Start/Join/Approve
buttons, and SyncPanel toggle button to use ThemePrimaryBrush. Semantic
success indicators (completion icons, status dots) left as ThemeSuccessBrush.
Version bump: 1.45.1 → 1.45.2
Get notified about new releases