Skip to main content

Changelog

Every improvement, automatically tracked from our commit history.

Subscribe via Atom feed
← Prev Page 12 of 139 Next →
February 28, 2026
patch Desktop ShellServices

Fix Dashboard blocked by slow API health check (5-min timeout)

Desktop 1.68.6 | Services 1.68.6 | 146e4e31
Details

Root cause: RefreshAsync populated AllPlugins AFTER awaiting

IsOnlineAsync(), which used PluginInstallService's 5-minute timeout

HttpClient for a simple health check. When privstack.io was slow or

unreachable, the entire dashboard sat on "Loading..." for minutes

with nothing rendered.

Fix: Split RefreshAsync into three phases:

1. PopulateLocalPlugins() — instant, no network. Builds AllPlugins

from filesystem manifests + IPluginRegistry.Plugins (the actually

loaded plugins). Sets IsLoading=false immediately so plugins render.

2. LoadSystemMetricsAsync() — local metrics (disk sizes, memory).

3. TryFetchRemoteRegistryAsync() — non-blocking enrichment with

server data. If it fails, local plugins are already displayed.

Also added a 5-second CancellationToken timeout to IsOnlineAsync()

so the health check doesn't inherit the 5-minute download timeout.

patch Desktop Shell

Fix Dashboard showing no plugins when registry is offline

Desktop 1.68.6 | 446e7a4c
Details

The previous fix handled the API timeout gracefully but the dashboard

still showed 0 plugins because GetInstalledVersions() only scans

~/.privstack/plugins and bundled plugin directories for manifest.json

files. In dev mode (project references) and when plugins are loaded

from non-standard paths, no manifests exist in those directories.

Added a fallback that populates AllPlugins from IPluginRegistry.Plugins

— the actually loaded/running plugins — for any plugin not already

covered by the server registry or filesystem manifests. This ensures

the dashboard always shows all active plugins with their metadata

regardless of how they were loaded.

patch Desktop ShellServices

Fix Dashboard showing empty when plugin registry API times out

Desktop 1.68.6 | Services 1.68.6 | b964b411
Details

The Dashboard RefreshAsync method called AllPlugins.Clear() before

fetching the remote plugin registry, so when the API call timed out

the entire catch block skipped populating locally installed plugins,

system metrics, and workspace activation state — leaving the UI stuck

showing "0 installed · 0 available" with empty metric cards.

Restructured RefreshAsync to:

  • Fetch local installed versions first (never fails)
  • Wrap the remote registry fetch in its own try/catch so timeouts

are non-fatal — locally installed plugins still appear

  • Always load system metrics regardless of registry availability

Also increased PrivStackApiClient timeout from 15s to 30s since the

plugin registry endpoint can be slow.

patch Services

Remove N+1 individual entity reads from BacklinkService index build

Services 1.68.6 | 1a5400b6
Details

Phase 2 of BuildIndexAsync already calls WikiLinkParser.ExtractContentFromEntity

on each entity from ReadList. The "load individually" block re-fetched entities

without content via individual SdkAction.Read calls, but the individual Read

returns the same JSON shape — ExtractContentFromEntity produces the same empty

result. This caused 21+ unnecessary contact.Read SDK calls at startup.

Removing the block eliminates the N+1 query pattern with no behavioral change,

since entities that genuinely lack parseable text fields won't gain content from

a re-fetch.

patch Desktop ShellServices

Pre-build backlink index at startup

Desktop 1.68.6 | Services 1.68.6 | 068b6e3b
Details

Adds BacklinkService.PreBuildIndexAsync() and calls it during the

deferred background services block in App.axaml.cs. This eliminates

the ~700ms cold-start delay when the user first clicks an item with

the Info Panel open, since the cross-plugin backlink index is already

warm by the time they interact.

The existing SemaphoreSlim guard in EnsureIndexBuiltAsync ensures

concurrent calls (from a user click racing the startup pre-build)

are safe. If the pre-build fails, the index falls back to lazy

initialization on first query (existing behavior).

← Prev Page 12 of 139 Next →

Get notified about new releases