chore: rename app from ProxmoxDesktop to Clustri

This commit is contained in:
Matt
2026-08-10 00:00:59 +00:00
parent 190fdb2573
commit 27b9aeb45e
26 changed files with 63 additions and 75 deletions
+4 -4
View File
@@ -1,4 +1,4 @@
# ProxmoxDesktop
# Clustri
A cross-platform desktop client for managing Proxmox VE servers and clusters. The backend is Rust on Tauri 2; the UI is React 19 with TypeScript, Vite, and Tailwind CSS v4.
@@ -9,7 +9,7 @@ A cross-platform desktop client for managing Proxmox VE servers and clusters. Th
- Manage multiple simultaneous connections to servers and clusters.
- Authenticate with an API token or with a username and password. Password mode uses ticket-based auth (PVEAuthCookie plus CSRF token).
- Credentials live in the OS keyring. API tokens never touch disk.
- Connections persist to `{app-config-dir}/proxmoxdesktop/connections.json`. The last active connection reconnects on launch.
- Connections persist to `{app-config-dir}/clustri/connections.json`. The last active connection reconnects on launch.
### Cluster support
@@ -171,7 +171,7 @@ source $HOME/.cargo/env
```bash
git clone <repository-url>
cd ProxmoxDesktop
cd clustri
npm install
```
@@ -250,7 +250,7 @@ When adding a connection you need:
## Project Structure
```
ProxmoxDesktop/
clustri/
├── src/ # React frontend
│ ├── components/
│ │ ├── ui/ # base components (buttons, dialogs, toasts)
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ProxmoxDesktop</title>
<title>Clustri</title>
</head>
<body>
<div id="root"></div>
+2 -2
View File
@@ -1,11 +1,11 @@
{
"name": "proxmoxdesktop",
"name": "clustri",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "proxmoxdesktop",
"name": "clustri",
"version": "0.1.0",
"dependencies": {
"@fontsource-variable/geist": "^5.3.0",
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "proxmoxdesktop",
"name": "clustri",
"private": true,
"version": "0.1.0",
"type": "module",
+29 -29
View File
@@ -411,6 +411,35 @@ dependencies = [
"windows-link 0.2.1",
]
[[package]]
name = "clustri"
version = "0.1.0"
dependencies = [
"futures-util",
"hex",
"httpmock",
"keyring",
"percent-encoding",
"rcgen",
"reqwest 0.12.28",
"rustls",
"rustls-pemfile",
"serde",
"serde_json",
"sha2",
"tauri",
"tauri-build",
"tauri-plugin-shell",
"tempfile",
"thiserror 2.0.19",
"tokio",
"tokio-rustls",
"tokio-tungstenite",
"url",
"uuid",
"x509-cert",
]
[[package]]
name = "cmake"
version = "0.1.58"
@@ -2704,35 +2733,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "proxmox-desktop"
version = "0.1.0"
dependencies = [
"futures-util",
"hex",
"httpmock",
"keyring",
"percent-encoding",
"rcgen",
"reqwest 0.12.28",
"rustls",
"rustls-pemfile",
"serde",
"serde_json",
"sha2",
"tauri",
"tauri-build",
"tauri-plugin-shell",
"tempfile",
"thiserror 2.0.19",
"tokio",
"tokio-rustls",
"tokio-tungstenite",
"url",
"uuid",
"x509-cert",
]
[[package]]
name = "quick-xml"
version = "0.41.0"
+1 -1
View File
@@ -1,5 +1,5 @@
[package]
name = "proxmox-desktop"
name = "clustri"
version = "0.1.0"
description = "A cross-platform desktop application for managing Proxmox VE servers"
authors = ["you"]
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"identifier": "default",
"description": "Default capabilities for ProxmoxDesktop",
"description": "Default capabilities for Clustri",
"windows": ["main"],
"permissions": [
"core:default",
+1 -1
View File
@@ -1 +1 @@
{"default":{"identifier":"default","description":"Default capabilities for ProxmoxDesktop","local":true,"windows":["main"],"permissions":["core:default","core:event:default","core:event:allow-listen","core:event:allow-emit","core:event:allow-emit-to","core:window:default","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-focus","core:window:allow-is-visible","shell:allow-execute","shell:default"]}}
{"default":{"identifier":"default","description":"Default capabilities for Clustri","local":true,"windows":["main"],"permissions":["core:default","core:event:default","core:event:allow-listen","core:event:allow-emit","core:event:allow-emit-to","core:window:default","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-focus","core:window:allow-is-visible","shell:allow-execute","shell:default"]}}
+1 -1
View File
@@ -370,7 +370,7 @@ impl Connection {
}
fn keyring_service() -> &'static str {
"proxmox-desktop"
"clustri"
}
fn keyring_entry(connection_id: &str, field: &str) -> crate::Result<keyring::Entry> {
+3 -3
View File
@@ -129,11 +129,11 @@ struct AppState {
/// Returns the path of the persisted connections file.
///
/// Lives at `{app_config_dir}/proxmoxdesktop/connections.json`; the parent
/// Lives at `{app_config_dir}/clustri/connections.json`; the parent
/// directory is created lazily when the file is first written.
fn connections_file(app: &tauri::AppHandle) -> Result<PathBuf> {
let dir = app.path().app_config_dir()?;
Ok(dir.join("proxmoxdesktop").join("connections.json"))
Ok(dir.join("clustri").join("connections.json"))
}
#[tauri::command]
@@ -939,7 +939,7 @@ pub fn run() {
.build()?;
let _tray = TrayIconBuilder::with_id("main-tray")
.tooltip("ProxmoxDesktop")
.tooltip("Clustri")
.icon(app.default_window_icon().cloned().expect("no default icon"))
.menu(&menu)
.on_menu_event(move |app, event| match event.id.as_ref() {
+1 -1
View File
@@ -1,5 +1,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
proxmox_desktop::run()
clustri::run()
}
+3 -3
View File
@@ -1,8 +1,8 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "ProxmoxDesktop",
"productName": "Clustri",
"version": "0.1.0",
"identifier": "com.proxmoxdesktop.app",
"identifier": "dev.clustri.app",
"build": {
"beforeDevCommand": "npm run dev",
"devUrl": "http://localhost:1420",
@@ -12,7 +12,7 @@
"app": {
"windows": [
{
"title": "ProxmoxDesktop",
"title": "Clustri",
"width": 1200,
"height": 800,
"resizable": true,
+1 -1
View File
@@ -5,7 +5,7 @@
//! error mapping, query parameters, and URL construction.
use httpmock::prelude::*;
use proxmox_desktop::{api_request, AuthContext, AuthMode, Error};
use clustri::{api_request, AuthContext, AuthMode, Error};
use reqwest::Client;
use reqwest::Method as RMethod;
+1 -1
View File
@@ -8,7 +8,7 @@
//! called directly on an added connection without `connect()`.
use httpmock::prelude::*;
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
/// Builds a `ConnectionManager` with a single token-mode connection whose
/// primary endpoint points at the mock server. `node` pins the storage node.
+1 -1
View File
@@ -9,7 +9,7 @@
//! directly on an added connection without `connect()`.
use httpmock::prelude::*;
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
/// Builds a `ConnectionManager` with a single token-mode connection whose
/// primary endpoint points at `url`.
+1 -1
View File
@@ -11,7 +11,7 @@
//! `body_includes` assertions use the encoded form (e.g. `:` becomes `%3A`).
use httpmock::prelude::*;
use proxmox_desktop::{
use clustri::{
AddDiskConfig, AddNICConfig, ConnectionConfig, ConnectionManager, EditNICConfig,
EndpointConfig, Error,
};
+1 -1
View File
@@ -7,7 +7,7 @@
//! directly on an added connection without `connect()`.
use httpmock::prelude::*;
use proxmox_desktop::{
use clustri::{
BackupJobConfig, ConnectionConfig, ConnectionManager, CreateSnapshotConfig, EndpointConfig,
Error,
};
+1 -1
View File
@@ -11,7 +11,7 @@
use httpmock::prelude::*;
use httpmock::Mock;
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
const TOKEN: &str = "root@pam!cluster-token";
+1 -1
View File
@@ -8,7 +8,7 @@
use httpmock::prelude::*;
use httpmock::Mock;
use proxmox_desktop::{derive_node_url, ConnectionConfig, ConnectionManager, EndpointConfig};
use clustri::{derive_node_url, ConnectionConfig, ConnectionManager, EndpointConfig};
const TOKEN: &str = "root@pam!discovery-token";
+1 -1
View File
@@ -8,7 +8,7 @@
use httpmock::prelude::*;
use httpmock::Mock;
use proxmox_desktop::{
use clustri::{
api_request, AuthContext, AuthMode, ConnectionConfig, ConnectionManager, EndpointConfig, Error,
};
use reqwest::Client;
+1 -1
View File
@@ -6,7 +6,7 @@
//! request layer falls back to the OS keyring.
use httpmock::prelude::*;
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
/// Builds a token-mode connection config with a real token set.
fn token_config(id: &str, url: &str, token: &str, accept_untrusted: bool) -> ConnectionConfig {
+2 -2
View File
@@ -4,10 +4,10 @@
//! Each test spawns a local TLS server with a freshly generated self-signed
//! certificate and exercises the capture/verify helpers against it.
use proxmox_desktop::tls::{
use clustri::tls::{
capture_fingerprint, fetch_certificate_info, verify_pin, verify_server_certificate,
};
use proxmox_desktop::Error;
use clustri::Error;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use rustls::ServerConfig;
use sha2::{Digest, Sha256};
+1 -1
View File
@@ -100,7 +100,7 @@ export function TerminalConsole({ connectionId, node, vmid, onError, onConnected
if (!isTauriMode && !cancelled) {
// Dev mode mock terminal
terminal.writeln('\x1b[1;32m╔══════════════════════════════════════════╗\x1b[0m')
terminal.writeln('\x1b[1;32m║ ProxmoxDesktop - Terminal Console ║\x1b[0m')
terminal.writeln('\x1b[1;32m║ Clustri - Terminal Console ║\x1b[0m')
terminal.writeln('\x1b[1;32m╚══════════════════════════════════════════╝\x1b[0m')
terminal.writeln('')
terminal.writeln(`\x1b[33mNode: ${node} | VMID: ${vmid} | Type: LXC\x1b[0m`)
+1 -1
View File
@@ -43,7 +43,7 @@ export function Sidebar({ onAddConnection, activeView, onNavigate }: SidebarProp
</div>
<div className="min-w-0 leading-tight">
<h1 className="truncate text-sm font-semibold tracking-tight text-foreground">
ProxmoxDesktop
Clustri
</h1>
<p className="text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground">
Ops Console
-12
View File
@@ -1,7 +1,6 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { ThemeSwitcher } from '@/components/settings/ThemeSwitcher'
import { ConnectionManager } from '@/components/settings/ConnectionManager'
import { ExternalLink } from 'lucide-react'
export function SettingsPage() {
return (
@@ -59,17 +58,6 @@ export function SettingsPage() {
<span className="text-sm text-muted-foreground">Platform</span>
<span className="font-mono text-sm font-medium">Tauri + React</span>
</div>
<div className="pt-2 border-t">
<a
href="https://github.com/proxmoxdesktop"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 text-sm text-primary hover:underline"
>
View on GitHub
<ExternalLink className="h-3.5 w-3.5" />
</a>
</div>
</div>
</CardContent>
</Card>
+2 -2
View File
@@ -25,11 +25,11 @@ function applyTheme(theme: Theme) {
root.classList.add(theme)
}
localStorage.setItem('proxmoxdesktop-theme', theme)
localStorage.setItem('clustri-theme', theme)
}
function getInitialTheme(): Theme {
const stored = localStorage.getItem('proxmoxdesktop-theme')
const stored = localStorage.getItem('clustri-theme')
if (stored === 'light' || stored === 'dark' || stored === 'system') {
return stored
}