Skip to main content

Changelog

Every improvement, automatically tracked from our commit history.

Subscribe via Atom feed
← Prev Page 7 of 266 Next →
March 1, 2026
patch Desktop Shell

Throttle Dashboard live metrics: stop per-second ReadList spam

Desktop 1.69.0 | 105a850f
Details

The 1-second live metrics timer was calling GetDataMetricsAsync on every

tick regardless of active tab. This triggered ~33 SDK ReadList/Count

calls per second across all plugins (page, task, event, contact, etc.),

saturating the SDK message bus with unnecessary I/O.

  • Memory metrics (process-level, no SDK calls) still refresh every 1s
  • Data metrics now only run on the Data tab, throttled to every 10s
  • Overview tab DataStorageTotal populated on first load only
  • Subsystems tab refresh unchanged (local counters, no SDK calls)
patch Data

Fix duckdb_tables query error after SQLCipher migration

Data 1.21.1 → 1.21.2 | 6c7d3ffc
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
patch Desktop Shell

Fix Dashboard plugin toggle not rendering + clean up alloc tracking

Desktop 1.69.0 | ee972093
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).

patch Desktop ShellServices

Fix Subsystems tab: use process-level native memory, improve column layout

Desktop 1.69.0 | Services 1.68.6 | 086dcb9a
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)

minor CoreDesktop ShellServices

Add per-subsystem memory tracker and Dashboard Subsystems tab

Core 1.15.3 → 1.15.4 | Desktop 1.68.6 → 1.69.0 | Services 1.68.6 | 7180a425
Details

Adds visibility into which subsystems consume memory across .NET managed

heap, native Rust allocations, and background task activity. Enables

live per-subsystem metrics in the Dashboard.

Rust tracking allocator (Phase 1):

  • New allocator.rs: custom GlobalAlloc with 16-byte header per allocation

storing size + subsystem ID. Per-subsystem atomic counters track bytes

and allocation counts. Thread-local subsystem tag set via with_subsystem()

scope guard.

  • Subsystem IDs: untagged(0), storage(1), sync(2), crypto(3), cloud(4),

plugins(5), ffi(6), reserved(7)

  • New FFI export: privstack_subsystem_memory() returns JSON snapshots
  • Key entry points wrapped: privstack_execute (FFI), auth_initialize/unlock

(Crypto), sync_status (Sync)

C# SubsystemTracker (Phase 2):

  • SubsystemTracker: singleton service with AsyncLocal tagging, RunTagged()

for async/sync task wrapping, EnterScope() for synchronous code blocks,

5-sample rolling allocation rate, native counter merging from Rust FFI

  • SubsystemDefinitions: static table of 16 built-in subsystems across

UI, AI, Core, Services, and Runtime categories

  • Static RunTaggedStatic() convenience for instrumentation without DI

Entry point instrumentation (Phase 3):

  • RagIndexService: consumer + deferred init tagged as ai.rag
  • IntentEngine: signal consumer tagged as ai.intent
  • EmbeddingService: ONNX load + tokenizer tagged as ai.embedding
  • LocalLlamaProvider: model load tagged as ai.llm
  • WhisperService: model load tagged as ai.whisper
  • IpcServer: listener tagged as ipc
  • ReminderSchedulerService: initial poll tagged as reminders
  • FileEventInboundScanner: poll loop tagged as core.sync
  • SyncOutboundService: debounce callback tagged as core.sync
  • CloudSyncSettingsViewModel: push + status loop tagged as core.cloud
  • UpdateViewModel: startup check tagged as updates

Dashboard Subsystems tab (Phase 4):

  • New SubsystemItemViewModel with status dot coloring (active/idle/stopped)
  • DashboardViewModel extended with Subsystems tab, summary cards (threads,

managed heap, native memory, active count), per-subsystem item collection

  • DashboardView.axaml: third tab button, summary stat cards, table-style

subsystem list with status dot, name, category, task count, memory,

alloc rate columns

  • Live refresh on 1-second timer when Subsystems tab is active

Registration wiring (Phase 5):

  • SubsystemTracker registered as singleton in CoreServiceRegistration
  • Static subsystems registered at startup, eagerly resolved in WireCorePostBuild
  • Plugin subsystems registered dynamically in DashboardPlugin.CreateViewModelCore()
  • NativeLibrary P/Invoke added for privstack_subsystem_memory

Version bumps:

  • Rust workspace: 1.15.3 → 1.15.4
  • Desktop app: 1.68.6 → 1.69.0
  • Dashboard plugin: 1.4.0 → 1.5.0
← Prev Page 7 of 266 Next →

Get notified about new releases