Skip to main content

Changelog

Every improvement, automatically tracked from our commit history.

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

Guard BackupService and vault unlock for client mode

Details
  • BackupService: skip scheduled backups in client mode (server handles

its own backups). Previously, SettingsViewModel's DI resolution

triggered BackupService constructor which immediately started the

backup timer — even in client mode.

  • PluginRegistry.EnsurePluginVaultsUnlocked: skip in client mode since

vault state is managed by the server. The NativeLib vault calls would

fail (or succeed silently via catch) since the native runtime isn't

initialized in client mode.

patch Desktop Shell

Register EmbeddingService and IEmbeddingService in Desktop DI

Details

EmbeddingService (ONNX embedding model) and its IEmbeddingService

interface were never registered in Desktop's DI container. The Server

project registered a no-op HeadlessEmbeddingService, but Desktop was

missing the mapping entirely. This caused RagSearchService resolution

to fail when CommandPaletteViewModel built AI commands during

MainWindowViewModel construction.

Pre-existing bug surfaced by client mode startup where the full

DI resolution chain is exercised earlier than in standalone mode.

patch Desktop ShellServices

Fix client mode startup: license check and error handling

Details

In client mode, ShowMainWindow crashed at LicenseExpirationService because

PrivStackService.GetLicenseStatus() requires the native runtime to be

initialized — which it isn't in client mode. The exception was silently

swallowed by the fire-and-forget task, leaving the app with no visible

window.

  • Add license_status field to /api/v1/status endpoint response
  • Parse and store server license status during TryEnterClientMode()
  • Add CheckLicenseStatusFromServer() to LicenseExpirationService for

applying license status from a remote server string

  • Use server-provided license status in client mode ShowMainWindow
  • Add ContinueWith error handler on fire-and-forget EnterClientModeAsync

to log failures instead of silently swallowing them

patch Desktop ShellServerServices

Route entity type registration through SDK transport layer

Details

RegisterEntityType was called directly via NativeLib P/Invoke in both

PluginRegistry (Desktop) and HeadlessPluginRegistry (Server), bypassing

the ISdkTransport abstraction. In client mode, the native runtime isn't

initialized, causing all entity schema registrations to fail with error

code -4.

  • Add RegisterEntityType to ISdkTransport interface
  • Implement in FfiSdkTransport (delegates to NativeLib)
  • Implement in HttpSdkTransport (POSTs to /api/v1/sdk/register-entity-type)
  • Add public RegisterEntityType method on SdkHost
  • Add /sdk/register-entity-type endpoint to LocalApiServer
  • Update PluginRegistry to route through SdkHost instead of NativeLib
  • Update HeadlessPluginRegistry with same fix, remove unused NativeLib import
patch Desktop ShellServices

Add SDK transport abstraction for Desktop client mode

Details

Extract FFI calls from SdkHost into ISdkTransport interface with two

implementations:

  • FfiSdkTransport: wraps NativeLibrary P/Invoke calls with pointer

marshalling (standalone mode, existing behavior)

  • HttpSdkTransport: proxies SDK calls over HTTP to a running headless

server (client mode, new)

When Desktop detects a running headless server at startup (probes

GET /api/v1/status), it switches to client mode: swaps the transport

from FFI to HTTP, skips DuckDB initialization and the unlock screen,

and routes all plugin data operations through the server. This solves

the DuckDB single-process limitation during development — server for

API testing, Desktop for UI verification, both against the same data.

Server-side: LocalApiServer gains SDK passthrough endpoints under

/api/v1/sdk/* (execute, search, vault, blob, db maintenance) so the

HttpSdkTransport has something to call. All endpoints sit behind the

existing API key authentication.

In client mode, server-managed background services (backup, file sync,

snapshot sync, reminders, RAG indexing, API server) are skipped since

the headless server handles them. UI services, plugin discovery, and

IPC still run locally.

SdkHost.SetTransport() follows the same post-build wiring pattern as

SetSyncOutbound() and SetVaultUnlockPrompt(). Pure refactor in

standalone mode — zero behavior change when no server is detected.

← Prev Page 16 of 139 Next →

Get notified about new releases