Describe the current runtime architecture for the desktop app and shared Rust library.
frontend(React + Vite renderer)electron(main process + preload bridge)pumas-rpc(Rust JSON-RPC server sidecar)pumas-library/pumas-core(model/system API)pumas-app-manager(app version + dependency + launcher management)
Renderer code does not access Node APIs directly.
- Renderer calls methods on
window.electronAPI(exposed byelectron/src/preload.ts). - Electron main process handles those calls and forwards backend RPC operations through
api:call. PythonBridge(name retained for compatibility) launches the Rustpumas-rpcbinary and sends JSON-RPC requests to it over HTTP on localhost.pumas-rpcroutes requests topumas-coreandpumas-app-managerservices.
- Starts the Rust sidecar binary (
pumas-rpcorpumas-rpc.exe). - Chooses launcher root based on environment:
- AppImage portable path when running as AppImage
- standard Electron user data for packaged builds
- project root in local dev
- Hosts browser window lifecycle, shell/dialog window controls, and IPC handlers.
- Axum server with:
GET /healthPOST /rpc
- Initializes:
PumasApi(auto_create_dirs(true))- per-app
VersionManagerinstances (currentlycomfyui,ollama,torch) CustomNodesManager,SizeCalculator, andPluginLoader
Primary ownership is now enforced per launcher root through the registry.
- Current
PumasApi::new()andPumasApi::builder(...).build()calls are owner construction paths. They claim primary ownership when possible and return an error when another process already owns that launcher root. - Direct Rust surfaces use explicit roles: an owning
PumasLibraryInstance, an explicit same-devicePumasLocalClient, or a read-onlyPumasReadOnlyLibrary. - UniFFI
FfiPumasApiconstructors are also owner-only. Foreign-language local-client and read-only access should be exposed as separate binding objects instead of hidden behind the owner object. - Watcher startup, reconciliation startup, and download-recovery startup occur only after the winning primary has started IPC and promoted its claim row to
ready.
This keeps a strict single-primary process model without allowing concurrent startup races to create multiple owners for the same shared-resources/models database.
Key paths used by the current implementation:
launcher-data/metadata/- persisted metadatalauncher-data/cache/- runtime cache and download persistencelauncher-data/mapping-configs/- mapping configurationlauncher-data/plugins/- plugin app descriptorsshared-resources/models/- canonical model library rootshared-resources/models/models.db- SQLite model indexshared-resources/cache/search.sqlite- HuggingFace search cache<app>-versions/directories for managed app version installs (comfyui-versions,ollama-versions,torch-versions)
The AppId enum supports multiple app identifiers, while the current sidecar initialization path actively starts managers for:
- ComfyUI
- Ollama
- Torch
Plugin descriptors under launcher-data/plugins/*.json drive UI capability surfaces and app-specific behavior.
- Strongly typed methods exposed by preload and consumed from
frontend/src/api/adapter.ts. - Includes RPC passthrough and Electron-specific window/file/shell helpers.
- JSON-RPC methods implemented in
rust/crates/pumas-rpc/src/handlers. - Wrappers over:
- model library
- version management
- dependency requirement resolution
- mapping/import/download flows
- utility and migration/report operations
- Rust crates built in
rustworkspace. - Electron packaging bundles renderer assets and the
pumas-rpcbinary as extra resources. - CI runs cross-platform build/test/package jobs for Linux, Windows, and macOS runners.
- Detailed endpoint-by-endpoint API contracts
- UI component-level design guidelines
- migration plans for old pre-0.2.0 code paths
Use docs under docs/ and crate-local READMEs for those details.