Remove bottom status bar, move AI + storage state into sidebar
Details
Delete the bottom status bar (~30px) to give plugin content full window
height. The bar contained: status message (removed — no value), active
timer indicator (already in sidebar footer), update status (in Dashboard),
subscription badge (in Settings > About), AI persona button (moved to
sidebar), and storage state pill (moved to sidebar Sync row).
Sidebar expanded footer gains:
- AI Persona button (star icon + gold dot for unseen insights) between
Search and Sync rows
- Storage state label ("Local"/"Cloud") appended to the Sync row
Sidebar collapsed footer gains:
- AI Persona icon with gold dot indicator
- Sync tooltip now includes storage state text
AI balloon repositioned from bottom-right to bottom-left to align with
the sidebar star icon. Balloon positioning code updated to search the
visual tree (star icon is now in NavigationSidebar's name scope).
Removed unused timer-pulse animation style from MainWindow.
Version: 1.69.0 → 1.70.0
Fix Subsystems tab scroll: match Overview tab layout pattern
Details
The Subsystems tab used Border > ScrollViewer which broke scrolling.
The Overview tab uses a bare ScrollViewer directly in Grid.Row="2"
which works correctly. Matched that pattern:
- Removed Border wrapper around ScrollViewer
- ScrollViewer directly in Grid.Row="2" with IsVisible binding
- Padding="24,0,24,32" matching Overview tab exactly
Fix Unknown subsystem entries and scroll cutoff at bottom
Details
Two issues:
1. "Unknown" group with 5 entries: Plugin SDK calls via TrackedSdkProxy
triggered GetOrCreateState() before DashboardPlugin.CreateViewModelCore
registered the plugin subsystems. The fallback created entries with
DisplayName="Unknown", Category="Unknown".
Fix: GetOrCreateState now infers display name and category from the
subsystem ID pattern. "plugin.privstack.notes" → DisplayName="Notes",
Category="Plugin". Non-plugin IDs get Category="Other" with the raw
ID as name. Register() now uses AddOrUpdate so explicit registration
from DashboardPlugin overwrites auto-created entries with the
authoritative PluginMetadata.Name.
2. Bottom scroll cutoff: Increased ScrollViewer bottom padding from 80
to 120 to clear the macOS dock + app status bar.
Add Auto-Check for Updates toggle in Settings > About
Details
The AutoCheckForUpdates setting existed in AppSettings and was wired in
the ViewModel but had no UI toggle — users couldn't disable it. Added a
ToggleSwitch in the About section (same card pattern as Notifications).
Track plugin SDK activity, fix status dots, guard reminders on setting
Details
Three issues with Subsystems tab accuracy:
1. Status dots: Green only showed for active tasks (task count > 0), so
subsystems with tracked memory but no running task (Crypto/Vault,
Auto-Update, Reminders) showed gray. Now green if tasks > 0 OR
native bytes > 0 OR managed alloc bytes > 0.
2. Plugin activity invisible: Plugins make all data calls through
Host.Sdk.SendAsync, but the shared SdkHost had no subsystem tracking.
Added TrackedSdkProxy that wraps IPrivStackSdk per-plugin — each
PluginHost now gets a scoped proxy tagged with "plugin.<id>". SDK
calls (SendAsync, CountAsync, SearchAsync) enter a subsystem scope,
so navigating to a plugin and loading data shows tracked memory.
3. Reminders allocating with notifications off: The scheduler started
its timer and initial poll unconditionally — PollAsync checked
NotificationsEnabled but already allocated before returning early.
Now guards in Start() itself: if notifications disabled, don't
create the timer or fire the initial poll at all.
Get notified about new releases