Dual-Layer Persistence Model
Palyra Desktop utilizes a two-tier storage strategy to balance ease of migration with secure credential handling.1. Unencrypted State (state.json)
General application configuration, window preferences, and non-sensitive status are stored in a versioned JSON file located at <state_root>/desktop-control-center/state.json apps/desktop/src-tauri/src/supervisor.rs#209-210.
- Schema Versioning: The state file includes a
schema_version(currently5) apps/desktop/src-tauri/src/lib.rs#9. - Migrations: Loading the file triggers
load_or_initialize_state_file, which usespalyra_common::config_system::parse_document_with_migrationto apply structural updates apps/desktop/src-tauri/src/snapshot.rs#11-12. - Content: Stores
DesktopOnboardingStep, rollout flags (e.g.,companion_shell_enabled), and bounded collections for notifications and offline drafts apps/desktop/src-tauri/src/desktop_state.rs#90-103.
2. Encrypted Secret Store (palyra-vault)
Sensitive tokens required for daemon orchestration are managed via the DesktopSecretStore, which wraps the palyra-vault crate apps/desktop/src-tauri/src/desktop_state.rs#8.
- Platform Backends: Uses
EncryptedFile, macOS Keychain, or Windows DPAPI depending on the OS apps/desktop/src-tauri/src/desktop_state.rs#8. - Key Credentials:
desktop_admin_token: Used to authenticate the Desktop app against thepalyradadmin API apps/desktop/src-tauri/src/lib.rs#11.desktop_browser_auth_token: Used for securing the bridge topalyra-browserdapps/desktop/src-tauri/src/lib.rs#12.
| Persistence Component | File/Path | Logic Entity |
|---|---|---|
| Public State | state.json | DesktopStateFile |
| Secret Vault | Platform Specific | DesktopSecretStore |
| Profile Catalog | cli/profiles.toml | DesktopProfileCatalog |
Desktop Onboarding State Machine
The onboarding process is managed as a linear state machine defined by theDesktopOnboardingStep enum apps/desktop/src-tauri/src/desktop_state.rs#205-215.
State Transition Flow
TheControlCenter tracks the current step in the persisted state and exposes it via get_onboarding_status apps/desktop/src-tauri/src/commands.rs#84-93.
- Welcome: Initial splash screen acknowledgement apps/desktop/src-tauri/src/desktop_state.rs#206.
- Environment: Validates binary paths for
palyradandpalyra-browserdapps/desktop/src-tauri/src/desktop_state.rs#207. - StateRoot: Operator confirms or overrides the directory for logs, databases, and keys apps/desktop/src-tauri/src/desktop_state.rs#208.
- GatewayInit: Desktop triggers the initial startup of the sidecar daemon apps/desktop/src-tauri/src/desktop_state.rs#209.
- OperatorAuthBootstrap: Generates the initial admin credentials apps/desktop/src-tauri/src/desktop_state.rs#210.
- Provider Connect (OpenAI/Discord): Optional steps for configuring model providers and connectors apps/desktop/src-tauri/src/desktop_state.rs#211-212.
- DashboardHandoff: Final step where the operator is transitioned to the full Web Console apps/desktop/src-tauri/src/desktop_state.rs#213.
Implementation Diagram: Onboarding Logic
Sources: apps/desktop/src-tauri/src/commands.rs#84-150, apps/desktop/src-tauri/src/onboarding.rs#78-112, apps/desktop/src-tauri/src/desktop_state.rs#205-215.Companion Shell and Offline Drafts
The Companion Shell is a React-based UI (apps/desktop/ui) that communicates with the Tauri backend to provide a lightweight interface for chat and approvals.
Offline Draft System
To prevent data loss during daemon restarts or network instability, the desktop app implements an offline draft queue.- Storage: Drafts are stored in
state.jsonwithinDesktopCompanionStateapps/desktop/src-tauri/src/desktop_state.rs#101. - Queue Logic:
queue_offline_draftadds messages to a bounded list (limit 20) when the control plane is unreachable apps/desktop/src-tauri/src/desktop_state.rs#21-62. - Recovery: When the daemon returns to
Healthystatus, the UI prompts the user to resend or discard drafts apps/desktop/ui/src/App.tsx#97-99.
Dashboard Handoff
The Desktop app facilitates a “Handoff” to the more powerful Web Console by generating short-lived tokens.- Handoff URL:
build_companion_handoff_urlcreates a URL containing a session token and target route (e.g.,#/control/chat) apps/desktop/src-tauri/src/commands.rs#7-16. - Token Flow: The app uses the
admin_tokento request a console session frompalyrad, then opens the default system browser to the loopback URL apps/desktop/src-tauri/src/snapshot.rs#200-205.
System Integration Diagram
Sources: apps/desktop/ui/src/App.tsx#21-43, apps/desktop/src-tauri/src/companion.rs#153-176, apps/desktop/src-tauri/src/desktop_state.rs#175-201.Technical Details: Companion Snapshots
The UI is driven by a comprehensive snapshot fetched viaget_desktop_companion_snapshot apps/desktop/src-tauri/src/commands.rs#109-122.
DesktopCompanionSnapshot Structure
This object aggregates data from multiple sources:- Supervisor Status: Process liveness for
palyradandpalyra-browserdapps/desktop/src-tauri/src/companion.rs#82. - Session Catalog: Recent chat sessions from the daemon apps/desktop/src-tauri/src/companion.rs#95.
- Approval Inbox: Pending security decisions apps/desktop/src-tauri/src/companion.rs#97.
- Metrics: Summary counts for unread notifications and pending tasks apps/desktop/src-tauri/src/companion.rs#100.
| Function | Role | File Reference |
|---|---|---|
build_companion_snapshot | Aggregates all data into the snapshot struct | apps/desktop/src-tauri/src/companion.rs#80-101 |
reconcile_companion_snapshot | Updates local preferences based on remote data | apps/desktop/src-tauri/src/supervisor.rs#226-235 |
fetch_companion_transcript | Retrieves the message history for a specific session | apps/desktop/src-tauri/src/companion.rs#9 |