ci: add multi-OS release workflow with auto-updater
- GitHub Action builds for Linux, Windows, macOS on v* tag push - macOS universal binary (Intel + Apple Silicon) - Draft release with all installers + updater signatures - tauri-plugin-updater for built-in auto-update support
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
name: Build & Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: ubuntu-22.04
|
||||||
|
args: ""
|
||||||
|
- platform: windows-latest
|
||||||
|
args: ""
|
||||||
|
- platform: macos-latest
|
||||||
|
args: "--target universal-apple-darwin"
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Setup Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
||||||
|
|
||||||
|
- name: Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: src-tauri
|
||||||
|
|
||||||
|
- name: Install Linux dependencies
|
||||||
|
if: matrix.platform == 'ubuntu-22.04'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
||||||
|
|
||||||
|
- name: Build and release
|
||||||
|
uses: tauri-apps/tauri-action@v0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tagName: ${{ github.ref_name }}
|
||||||
|
releaseName: "Clustri ${{ github.ref_name }}"
|
||||||
|
releaseBody: "See the assets below to download and install."
|
||||||
|
releaseDraft: true
|
||||||
|
prerelease: false
|
||||||
|
updaterJsonPreferNsis: true
|
||||||
|
args: ${{ matrix.args }}
|
||||||
@@ -4,7 +4,7 @@ const navItems = [
|
|||||||
{ label: 'Dashboard', icon: 'grid', active: true },
|
{ label: 'Dashboard', icon: 'grid', active: true },
|
||||||
{ label: 'Nodes', icon: 'server', active: false },
|
{ label: 'Nodes', icon: 'server', active: false },
|
||||||
{ label: 'VMs', icon: 'box', active: false },
|
{ label: 'VMs', icon: 'box', active: false },
|
||||||
{ label: 'Containers', icon: 'box', active: false },
|
{ label: 'CTs', icon: 'box', active: false },
|
||||||
{ label: 'Storage', icon: 'hdd', active: false },
|
{ label: 'Storage', icon: 'hdd', active: false },
|
||||||
{ label: 'Tasks', icon: 'todo', active: false },
|
{ label: 'Tasks', icon: 'todo', active: false },
|
||||||
{ label: 'Backups', icon: 'shield', active: false },
|
{ label: 'Backups', icon: 'shield', active: false },
|
||||||
@@ -110,7 +110,7 @@ const quickActions = [
|
|||||||
|
|
||||||
<div class="flex items-center gap-2 border-b border-warning/25 bg-warning/10 px-4 py-1.5">
|
<div class="flex items-center gap-2 border-b border-warning/25 bg-warning/10 px-4 py-1.5">
|
||||||
<span class="h-1.5 w-1.5 shrink-0 rounded-full bg-warning" aria-hidden="true"></span>
|
<span class="h-1.5 w-1.5 shrink-0 rounded-full bg-warning" aria-hidden="true"></span>
|
||||||
<p class="shrink-0 font-mono text-[10px] text-warning">Operating on a fallback node</p>
|
<p class="shrink-0 font-mono text-[10px] text-warning">Using a fallback node</p>
|
||||||
<p class="ml-auto min-w-0 truncate font-mono text-[10px] tabular-nums text-warning/80">https://192.168.1.12:8006</p>
|
<p class="ml-auto min-w-0 truncate font-mono text-[10px] tabular-nums text-warning/80">https://192.168.1.12:8006</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ const quickActions = [
|
|||||||
</div>
|
</div>
|
||||||
<p class="ml-7 font-mono text-[10px] text-muted-foreground">Offline</p>
|
<p class="ml-7 font-mono text-[10px] text-muted-foreground">Offline</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3 pb-1 pt-3"><DotMatrixText text="CLUSTER NODES" size="xs" dotClass="text-muted-foreground" /></div>
|
<div class="px-3 pb-1 pt-3"><DotMatrixText text="NODES IN CLUSTER" size="xs" dotClass="text-muted-foreground" /></div>
|
||||||
<div class="space-y-0.5">
|
<div class="space-y-0.5">
|
||||||
{clusterNodes.map((n) => (
|
{clusterNodes.map((n) => (
|
||||||
<div class="flex w-full items-center gap-2.5 rounded-md px-3 py-1.5">
|
<div class="flex w-full items-center gap-2.5 rounded-md px-3 py-1.5">
|
||||||
@@ -219,7 +219,7 @@ const quickActions = [
|
|||||||
<section class="rounded-md border border-dotted border-white/10 bg-card sm:col-span-3">
|
<section class="rounded-md border border-dotted border-white/10 bg-card sm:col-span-3">
|
||||||
<header class="flex items-center gap-2 border-b border-dotted border-white/10 px-3 py-2">
|
<header class="flex items-center gap-2 border-b border-dotted border-white/10 px-3 py-2">
|
||||||
<svg class="h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true"><use href="#i-activity" /></svg>
|
<svg class="h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true"><use href="#i-activity" /></svg>
|
||||||
<h3 class="font-mono text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground">Task activity</h3>
|
<h3 class="font-mono text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground">Recent tasks</h3>
|
||||||
<span class="ml-auto h-1.5 w-1.5 animate-pulse rounded-full bg-success" aria-hidden="true"></span>
|
<span class="ml-auto h-1.5 w-1.5 animate-pulse rounded-full bg-success" aria-hidden="true"></span>
|
||||||
</header>
|
</header>
|
||||||
<div class="divide-y divide-border" data-live-tasks>
|
<div class="divide-y divide-border" data-live-tasks>
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="mx-auto max-w-7xl px-6 lg:px-8">
|
<div class="mx-auto max-w-7xl px-6 lg:px-8">
|
||||||
<div class="max-w-2xl" data-reveal>
|
<div class="max-w-2xl" data-reveal>
|
||||||
<DotMatrixText text="ARCHITECTURE" size="xs" dotClass="text-primary" />
|
<DotMatrixText text="ARCHITECTURE" size="xs" dotClass="text-primary" />
|
||||||
<h2 id="arch-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">One proxy between you and the API.</h2>
|
<h2 id="arch-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">How Clustri reaches Proxmox.</h2>
|
||||||
<p class="mt-4 text-[15px] leading-relaxed text-muted-foreground">The frontend calls Rust commands over Tauri IPC. The backend proxies them to the Proxmox API over HTTPS.</p>
|
<p class="mt-4 text-[15px] leading-relaxed text-muted-foreground">The React frontend calls Rust commands through Tauri IPC. The Rust backend sends each request to Proxmox over HTTPS.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-10 grid gap-3 lg:grid-cols-[1fr_auto_1fr_auto_1fr] lg:items-stretch" data-stagger>
|
<div class="mt-10 grid gap-3 lg:grid-cols-[1fr_auto_1fr_auto_1fr] lg:items-stretch" data-stagger>
|
||||||
@@ -43,7 +43,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
</div>
|
</div>
|
||||||
<div class="py-2" data-reveal data-reveal-delay="100">
|
<div class="py-2" data-reveal data-reveal-delay="100">
|
||||||
<DotMatrixText text="FAILOVER MODEL" size="xs" dotClass="text-muted-foreground" />
|
<DotMatrixText text="FAILOVER MODEL" size="xs" dotClass="text-muted-foreground" />
|
||||||
<p class="mt-3 text-sm leading-relaxed text-muted-foreground">Ordered, deduped endpoints: primary → fallbacks → discovered nodes. Connect / timeout / DNS / transport failure → retry next endpoint.</p>
|
<p class="mt-3 text-sm leading-relaxed text-muted-foreground">Clustri keeps an ordered list of unique endpoints: primary, fallbacks, then discovered nodes. Connection, timeout, DNS, or transport errors trigger the next attempt.</p>
|
||||||
<div class="mt-4 flex gap-4 font-mono text-[10px]">
|
<div class="mt-4 flex gap-4 font-mono text-[10px]">
|
||||||
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-success"></span> connected</span>
|
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-success"></span> connected</span>
|
||||||
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-warning"></span> failover</span>
|
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-warning"></span> failover</span>
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div id="cmdk-panel" class="cmdk-panel w-full max-w-[520px] overflow-hidden rounded-xl border border-dotted border-white/10 bg-card dot-grid">
|
<div id="cmdk-panel" class="cmdk-panel w-full max-w-[520px] overflow-hidden rounded-xl border border-dotted border-white/10 bg-card dot-grid">
|
||||||
<div class="flex items-center gap-3 border-b border-dotted border-white/10 px-4">
|
<div class="flex items-center gap-3 border-b border-dotted border-white/10 px-4">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-4 w-4 shrink-0 text-muted-foreground" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-4 w-4 shrink-0 text-muted-foreground" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
|
||||||
<input id="cmdk-input" type="text" placeholder="Type a command…" autocomplete="off" spellcheck="false" class="h-12 w-full bg-transparent font-mono text-sm text-foreground placeholder:text-muted-foreground/60 focus:outline-none" />
|
<input id="cmdk-input" type="text" placeholder="Search commands" autocomplete="off" spellcheck="false" class="h-12 w-full bg-transparent font-mono text-sm text-foreground placeholder:text-muted-foreground/60 focus:outline-none" />
|
||||||
<kbd class="hidden rounded border border-dotted border-white/10 bg-white/[0.04] px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground sm:inline">ESC</kbd>
|
<kbd class="hidden rounded border border-dotted border-white/10 bg-white/[0.04] px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground sm:inline">ESC</kbd>
|
||||||
</div>
|
</div>
|
||||||
<div id="cmdk-list" class="max-h-[320px] overflow-auto p-2"></div>
|
<div id="cmdk-list" class="max-h-[320px] overflow-auto p-2"></div>
|
||||||
<div class="border-t border-dotted border-white/10 px-3 py-2 flex items-center justify-between">
|
<div class="border-t border-dotted border-white/10 px-3 py-2 flex items-center justify-between">
|
||||||
<DotMatrixText text="UP/DN NAVIGATE / ENTER SELECT / ESC CLOSE" size="xs" dotClass="text-muted-foreground" />
|
<DotMatrixText text="ARROWS MOVE / ENTER SELECT / ESC CLOSE" size="xs" dotClass="text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<section id="download" class="scroll-mt-24 border-t border-dotted border-white/10 py-20 sm:py-28">
|
<section id="download" class="scroll-mt-24 border-t border-dotted border-white/10 py-20 sm:py-28">
|
||||||
<div class="mx-auto max-w-3xl px-6 text-center">
|
<div class="mx-auto max-w-3xl px-6 text-center">
|
||||||
<div data-reveal><DotMatrixText text="RELEASES" size="xs" dotClass="text-primary" /></div>
|
<div data-reveal><DotMatrixText text="RELEASES" size="xs" dotClass="text-primary" /></div>
|
||||||
<h2 class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl" data-reveal data-reveal-delay="80">Coming soon.</h2>
|
<h2 class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl" data-reveal data-reveal-delay="80">Packages are not published yet.</h2>
|
||||||
<p class="mx-auto mt-4 max-w-[46ch] text-[15px] leading-relaxed text-muted-foreground" data-reveal data-reveal-delay="140">
|
<p class="mx-auto mt-4 max-w-[46ch] text-[15px] leading-relaxed text-muted-foreground" data-reveal data-reveal-delay="140">
|
||||||
Clustri is in active development. Packages for Linux, macOS, and Windows are on the way.
|
Clustri is under active development. Linux, macOS, and Windows packages are next.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="relative mt-10 overflow-hidden rounded-xl border border-dotted border-white/10 bg-card p-6 sm:p-8 shadow-card dot-grid" data-reveal data-reveal-delay="200">
|
<div class="relative mt-10 overflow-hidden rounded-xl border border-dotted border-white/10 bg-card p-6 sm:p-8 shadow-card dot-grid" data-reveal data-reveal-delay="200">
|
||||||
@@ -15,8 +15,8 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
|
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="flex flex-wrap items-center justify-center gap-3">
|
<div class="flex flex-wrap items-center justify-center gap-3">
|
||||||
<a href="#" class="rounded-[10px] bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:bg-primary/90 active:scale-[0.98]">Get Clustri</a>
|
<a href="https://github.com/Factor-scd/clustri/releases/latest" class="rounded-[10px] bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:bg-primary/90 active:scale-[0.98]">Download from GitHub</a>
|
||||||
<a href="#" class="rounded-[10px] border border-dotted border-white/10 bg-white/[0.03] px-6 py-3 text-sm font-semibold text-muted-foreground transition hover:border-white/15 hover:text-foreground active:scale-[0.98]">Build from source</a>
|
<a href="https://github.com/Factor-scd/clustri" class="rounded-[10px] border border-dotted border-white/10 bg-white/[0.03] px-6 py-3 text-sm font-semibold text-muted-foreground transition hover:border-white/15 hover:text-foreground active:scale-[0.98]">Build from source</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 flex flex-wrap items-center justify-center gap-2">
|
<div class="mt-6 flex flex-wrap items-center justify-center gap-2">
|
||||||
<span class="rounded-md border border-dotted border-white/10 bg-background px-2.5 py-1 font-mono text-[11px] text-muted-foreground">Linux</span>
|
<span class="rounded-md border border-dotted border-white/10 bg-background px-2.5 py-1 font-mono text-[11px] text-muted-foreground">Linux</span>
|
||||||
|
|||||||
@@ -9,28 +9,28 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="lg:col-span-5">
|
<div class="lg:col-span-5">
|
||||||
<div data-reveal><DotMatrixText text="FAILOVER / TRY IT" size="xs" dotClass="text-primary" /></div>
|
<div data-reveal><DotMatrixText text="FAILOVER / TRY IT" size="xs" dotClass="text-primary" /></div>
|
||||||
<h2 id="fp-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl" data-reveal data-reveal-delay="80">
|
<h2 id="fp-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl" data-reveal data-reveal-delay="80">
|
||||||
One node dies.<br /><span class="text-muted-foreground">You don't notice.</span>
|
When a node drops,<br /><span class="text-muted-foreground">requests keep moving.</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-4 max-w-[42ch] text-[15px] leading-relaxed text-muted-foreground" data-reveal data-reveal-delay="140">
|
<p class="mt-4 max-w-[42ch] text-[15px] leading-relaxed text-muted-foreground" data-reveal data-reveal-delay="140">
|
||||||
Requests ride an ordered endpoint list: primary, fallbacks, then discovered cluster nodes. Kill a node on the right — watch the packets reroute and the status flip.
|
Clustri tries the primary endpoint, then configured fallbacks and discovered cluster nodes. Stop a node on the right to watch the request move.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="mt-8 flex flex-wrap gap-2" data-reveal data-reveal-delay="180">
|
<div class="mt-8 flex flex-wrap gap-2" data-reveal data-reveal-delay="180">
|
||||||
<button id="fp-kill-pve1" type="button" class="rounded-md border border-dotted border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-[11px] font-medium text-foreground transition hover:border-white/15 hover:bg-white/[0.07]">Kill pve1</button>
|
<button id="fp-kill-pve1" type="button" class="rounded-md border border-dotted border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-[11px] font-medium text-foreground transition hover:border-white/15 hover:bg-white/[0.07]">Stop pve1</button>
|
||||||
<button id="fp-kill-pve2" type="button" class="rounded-md border border-dotted border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-[11px] font-medium text-foreground transition hover:border-white/15 hover:bg-white/[0.07]">Kill pve2</button>
|
<button id="fp-kill-pve2" type="button" class="rounded-md border border-dotted border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-[11px] font-medium text-foreground transition hover:border-white/15 hover:bg-white/[0.07]">Stop pve2</button>
|
||||||
<button id="fp-kill-pve3" type="button" class="rounded-md border border-dotted border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-[11px] font-medium text-foreground transition hover:border-white/15 hover:bg-white/[0.07]">Kill pve3</button>
|
<button id="fp-kill-pve3" type="button" class="rounded-md border border-dotted border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-[11px] font-medium text-foreground transition hover:border-white/15 hover:bg-white/[0.07]">Stop pve3</button>
|
||||||
<button id="fp-heal" type="button" class="rounded-md bg-primary px-3 py-2 font-mono text-[11px] font-semibold text-primary-foreground transition hover:bg-primary/90">Heal all</button>
|
<button id="fp-heal" type="button" class="rounded-md bg-primary px-3 py-2 font-mono text-[11px] font-semibold text-primary-foreground transition hover:bg-primary/90">Restore nodes</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 flex flex-wrap gap-3 font-mono text-[10px]" data-reveal data-reveal-delay="220">
|
<div class="mt-6 flex flex-wrap gap-3 font-mono text-[10px]" data-reveal data-reveal-delay="220">
|
||||||
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-success"></span> connected</span>
|
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-success"></span> connected</span>
|
||||||
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-warning"></span> failover</span>
|
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-warning"></span> failover</span>
|
||||||
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-destructive"></span> failed</span>
|
<span class="inline-flex items-center gap-1.5"><span class="h-1.5 w-1.5 rounded-full bg-destructive"></span> failed</span>
|
||||||
<span class="ml-1 text-muted-foreground">— tap a node or use the buttons</span>
|
<span class="ml-1 text-muted-foreground">Click a node or use a button</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 rounded-md border border-dotted border-white/10 bg-background px-3 py-2.5 font-mono text-[11px] leading-relaxed text-muted-foreground" data-reveal data-reveal-delay="260">
|
<div class="mt-6 rounded-md border border-dotted border-white/10 bg-background px-3 py-2.5 font-mono text-[11px] leading-relaxed text-muted-foreground" data-reveal data-reveal-delay="260">
|
||||||
<span class="text-foreground">How it works:</span> deduped order <span class="text-foreground">primary → fallbacks → discovered</span>. On connect / timeout / DNS / transport failure, retry the next endpoint. Status reflects which endpoint actually answered.
|
<span class="text-foreground">Request order:</span> <span class="text-foreground">primary → fallbacks → discovered</span>. A connection, timeout, DNS, or transport failure moves the request to the next endpoint.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
|
|
||||||
<!-- header -->
|
<!-- header -->
|
||||||
<div class="flex items-center justify-between gap-3 border-b border-dotted border-white/10 px-4 py-3">
|
<div class="flex items-center justify-between gap-3 border-b border-dotted border-white/10 px-4 py-3">
|
||||||
<p class="font-mono text-[10px] tracking-[0.06em] text-muted-foreground">request → endpoints[0] → retry on failure</p>
|
<p class="font-mono text-[10px] tracking-[0.06em] text-muted-foreground">request → primary endpoint → retry if needed</p>
|
||||||
<span id="fp-status-chip" class="rounded border border-success/25 bg-success/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-success">Connected</span>
|
<span id="fp-status-chip" class="rounded border border-success/25 bg-success/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-success">Connected</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<!-- status bar -->
|
<!-- status bar -->
|
||||||
<div class="border-t border-dotted border-white/10 bg-background px-4 py-3">
|
<div class="border-t border-dotted border-white/10 bg-background px-4 py-3">
|
||||||
<div class="flex items-center justify-between gap-3">
|
<div class="flex items-center justify-between gap-3">
|
||||||
<span id="fp-status-text" class="font-mono text-[11px] tabular-nums text-muted-foreground">status: connected — pve1 answered</span>
|
<span id="fp-status-text" class="font-mono text-[11px] tabular-nums text-muted-foreground">status: connected, pve1 answered</span>
|
||||||
<span id="fp-latency" class="font-mono text-[10px] tabular-nums text-muted-foreground">~18 ms</span>
|
<span id="fp-latency" class="font-mono text-[10px] tabular-nums text-muted-foreground">~18 ms</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 h-1 overflow-hidden rounded-full bg-muted">
|
<div class="mt-2 h-1 overflow-hidden rounded-full bg-muted">
|
||||||
@@ -103,7 +103,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="mt-3 text-center font-mono text-[10px] text-muted-foreground/60">Click a node row to kill / heal it. Packets reroute automatically.</p>
|
<p class="mt-3 text-center font-mono text-[10px] text-muted-foreground/60">Click a node row to stop or restore it. Requests move to the next endpoint.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -172,7 +172,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
if (failed) {
|
if (failed) {
|
||||||
chip.textContent = 'Failed'
|
chip.textContent = 'Failed'
|
||||||
chip.className = 'rounded border border-destructive/30 bg-destructive/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-destructive'
|
chip.className = 'rounded border border-destructive/30 bg-destructive/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-destructive'
|
||||||
statusText.textContent = 'status: failed — no endpoint reachable'
|
statusText.textContent = 'status: failed, no endpoint reachable'
|
||||||
statusText.className = 'font-mono text-[11px] tabular-nums text-destructive'
|
statusText.className = 'font-mono text-[11px] tabular-nums text-destructive'
|
||||||
topRule.className = 'h-px w-full bg-destructive/40'
|
topRule.className = 'h-px w-full bg-destructive/40'
|
||||||
bar.style.width = '100%'
|
bar.style.width = '100%'
|
||||||
@@ -181,7 +181,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
} else if (failover) {
|
} else if (failover) {
|
||||||
chip.textContent = 'Failover'
|
chip.textContent = 'Failover'
|
||||||
chip.className = 'rounded border border-warning/30 bg-warning/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-warning'
|
chip.className = 'rounded border border-warning/30 bg-warning/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-warning'
|
||||||
statusText.textContent = `status: failover — ${names[ai]} answered (${addrs[ai]})`
|
statusText.textContent = `status: failover, ${names[ai]} answered (${addrs[ai]})`
|
||||||
statusText.className = 'font-mono text-[11px] tabular-nums text-warning'
|
statusText.className = 'font-mono text-[11px] tabular-nums text-warning'
|
||||||
topRule.className = 'h-px w-full bg-warning/40'
|
topRule.className = 'h-px w-full bg-warning/40'
|
||||||
bar.style.width = ai === 1 ? '56%' : '88%'
|
bar.style.width = ai === 1 ? '56%' : '88%'
|
||||||
@@ -190,7 +190,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
} else {
|
} else {
|
||||||
chip.textContent = 'Connected'
|
chip.textContent = 'Connected'
|
||||||
chip.className = 'rounded border border-success/25 bg-success/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-success'
|
chip.className = 'rounded border border-success/25 bg-success/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-success'
|
||||||
statusText.textContent = `status: connected — ${names[0]} answered`
|
statusText.textContent = `status: connected, ${names[0]} answered`
|
||||||
statusText.className = 'font-mono text-[11px] tabular-nums text-success'
|
statusText.className = 'font-mono text-[11px] tabular-nums text-success'
|
||||||
topRule.className = 'h-px w-full bg-primary/30'
|
topRule.className = 'h-px w-full bg-primary/30'
|
||||||
bar.style.width = '18%'
|
bar.style.width = '18%'
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="lg:col-span-6" data-reveal>
|
<div class="lg:col-span-6" data-reveal>
|
||||||
<DotMatrixText text="SECURITY" size="xs" dotClass="text-primary" />
|
<DotMatrixText text="SECURITY" size="xs" dotClass="text-primary" />
|
||||||
<h2 id="sec-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">
|
<h2 id="sec-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">
|
||||||
Your keys stay<br /><span class="text-muted-foreground">in your pocket.</span>
|
Keep credentials<br /><span class="text-muted-foreground">on your machine.</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-4 max-w-[44ch] text-[15px] leading-relaxed text-muted-foreground">
|
<p class="mt-4 max-w-[44ch] text-[15px] leading-relaxed text-muted-foreground">
|
||||||
API tokens live in the OS keyring — never on disk. Self-signed certs are pinned by SHA-256 on first connect and verified every time after.
|
Clustri stores API tokens in the OS keyring, not in a file. It pins self-signed certificates by SHA-256 on first connect and checks them on later connections.
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6 space-y-3 font-mono text-[11px] leading-relaxed">
|
<div class="mt-6 space-y-3 font-mono text-[11px] leading-relaxed">
|
||||||
<div class="flex gap-2"><span class="text-primary">—</span><span class="text-muted-foreground">Token mode: <span class="text-foreground">PVEAPIToken / PBSAPIToken</span> header</span></div>
|
<div class="flex gap-2"><span class="text-primary">•</span><span class="text-muted-foreground">Token mode: <span class="text-foreground">PVEAPIToken / PBSAPIToken</span> header</span></div>
|
||||||
<div class="flex gap-2"><span class="text-primary">—</span><span class="text-muted-foreground">Password mode: ticket auth + <span class="text-foreground">CSRFPreventionToken</span></span></div>
|
<div class="flex gap-2"><span class="text-primary">•</span><span class="text-muted-foreground">Password mode: ticket auth + <span class="text-foreground">CSRFPreventionToken</span></span></div>
|
||||||
<div class="flex gap-2"><span class="text-primary">—</span><span class="text-muted-foreground">Fallbacks skip TOFU — intentional for home-lab failover; primary is always pinned.</span></div>
|
<div class="flex gap-2"><span class="text-primary">•</span><span class="text-muted-foreground">Fallbacks skip TOFU during home-lab failover; the primary endpoint stays pinned.</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="rounded-xl border border-dotted border-white/10 bg-card p-5 shadow-card">
|
<div class="rounded-xl border border-dotted border-white/10 bg-card p-5 shadow-card">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="h-2 w-2 rounded-full bg-success shadow-[0_0_6px] shadow-success/60" aria-hidden="true"></span>
|
<span class="h-2 w-2 rounded-full bg-success shadow-[0_0_6px] shadow-success/60" aria-hidden="true"></span>
|
||||||
<span class="font-mono text-[10px] uppercase tracking-[0.08em] text-muted-foreground">SHA-256 fingerprint — pinned</span>
|
<span class="font-mono text-[10px] uppercase tracking-[0.08em] text-muted-foreground">SHA-256 fingerprint: pinned</span>
|
||||||
<span class="ml-auto rounded border border-success/20 bg-success/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-success">Pinned</span>
|
<span class="ml-auto rounded border border-success/20 bg-success/10 px-1.5 py-0.5 font-mono text-[10px] uppercase text-success">Pinned</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-4 overflow-x-auto whitespace-nowrap font-mono text-[13px] tracking-[0.12em] text-foreground">A3:0F:71:C9:52:B8:4D:E0:11:2A:7F:9C:63:D4:18:0B</p>
|
<p class="mt-4 overflow-x-auto whitespace-nowrap font-mono text-[13px] tracking-[0.12em] text-foreground">A3:0F:71:C9:52:B8:4D:E0:11:2A:7F:9C:63:D4:18:0B</p>
|
||||||
@@ -33,7 +33,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<span class="rounded bg-white/[0.04] px-2 py-1 text-muted-foreground">rustls · sha2 · x509-cert</span>
|
<span class="rounded bg-white/[0.04] px-2 py-1 text-muted-foreground">rustls · sha2 · x509-cert</span>
|
||||||
<span class="rounded bg-white/[0.04] px-2 py-1 text-muted-foreground">no telemetry</span>
|
<span class="rounded bg-white/[0.04] px-2 py-1 text-muted-foreground">no telemetry</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-3 font-mono text-[10px] text-muted-foreground">Captured on first connect. Verified on every connect after. “Accept anyway” per-connection when you rotate certs.</p>
|
<p class="mt-3 font-mono text-[10px] text-muted-foreground">Clustri captures the fingerprint on first connect and checks it later. Accept a rotated certificate for one connection.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 grid grid-cols-3 gap-3">
|
<div class="mt-4 grid grid-cols-3 gap-3">
|
||||||
@@ -55,18 +55,18 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Bold statement — full bleed -->
|
<!-- Bold statement: full bleed -->
|
||||||
<section class="relative overflow-hidden border-y border-dotted border-white/10 bg-[#08080a]">
|
<section class="relative overflow-hidden border-y border-dotted border-white/10 bg-[#08080a]">
|
||||||
<div class="pointer-events-none absolute inset-0 grid-bg opacity-[0.22]" aria-hidden="true"></div>
|
<div class="pointer-events-none absolute inset-0 grid-bg opacity-[0.22]" aria-hidden="true"></div>
|
||||||
<div class="relative mx-auto max-w-7xl px-6 py-20 sm:py-28 lg:px-8">
|
<div class="relative mx-auto max-w-7xl px-6 py-20 sm:py-28 lg:px-8">
|
||||||
<div class="max-w-4xl" data-reveal>
|
<div class="max-w-4xl" data-reveal>
|
||||||
<DotMatrixText text="THE IDEA" size="xs" dotClass="text-primary" />
|
<DotMatrixText text="THE IDEA" size="xs" dotClass="text-primary" />
|
||||||
<p class="mt-6 text-3xl font-semibold leading-[0.95] tracking-[-0.04em] text-foreground sm:text-5xl lg:text-[3.4rem]">
|
<p class="mt-6 text-3xl font-semibold leading-[0.95] tracking-[-0.04em] text-foreground sm:text-5xl lg:text-[3.4rem]">
|
||||||
Proxmox is powerful.<br />
|
The cluster keeps running.<br />
|
||||||
<span class="text-muted-foreground">The web UI is not the point of failure.</span>
|
<span class="text-muted-foreground">Your management session should stay with it.</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-6 max-w-[52ch] text-[15px] leading-relaxed text-muted-foreground sm:text-[16px]">
|
<p class="mt-6 max-w-[52ch] text-[15px] leading-relaxed text-muted-foreground sm:text-[16px]">
|
||||||
Clustri sits between you and the API. When a node drops, the app retries the next one. You keep working. The cluster keeps running.
|
Clustri sends requests through the Proxmox API. If a node stops answering, it tries the next endpoint and shows you which node answered.
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-8 h-px w-12 bg-primary/60" aria-hidden="true"></div>
|
<div class="mt-8 h-px w-12 bg-primary/60" aria-hidden="true"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,9 +79,9 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="grid gap-10 lg:grid-cols-12">
|
<div class="grid gap-10 lg:grid-cols-12">
|
||||||
<div class="lg:col-span-5" data-reveal>
|
<div class="lg:col-span-5" data-reveal>
|
||||||
<DotMatrixText text="CONSOLE" size="xs" dotClass="text-primary" />
|
<DotMatrixText text="CONSOLE" size="xs" dotClass="text-primary" />
|
||||||
<h2 id="console-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">Type like you're there.</h2>
|
<h2 id="console-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">Open a console on any guest.</h2>
|
||||||
<p class="mt-4 max-w-[44ch] text-[15px] leading-relaxed text-muted-foreground">
|
<p class="mt-4 max-w-[44ch] text-[15px] leading-relaxed text-muted-foreground">
|
||||||
noVNC for VMs, xterm.js for containers. Fullscreen, keyboard passthrough, and Ctrl+Alt+Del where you expect it.
|
Use noVNC for VMs and xterm.js for containers. Fullscreen mode and keyboard passthrough keep the session in the app.
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6 inline-flex gap-2">
|
<div class="mt-6 inline-flex gap-2">
|
||||||
<span class="rounded border border-dotted border-white/10 bg-card px-2.5 py-1 font-mono text-[11px] text-muted-foreground">Fullscreen</span>
|
<span class="rounded border border-dotted border-white/10 bg-card px-2.5 py-1 font-mono text-[11px] text-muted-foreground">Fullscreen</span>
|
||||||
@@ -118,10 +118,10 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="flex flex-wrap items-end justify-between gap-6" data-reveal>
|
<div class="flex flex-wrap items-end justify-between gap-6" data-reveal>
|
||||||
<div>
|
<div>
|
||||||
<DotMatrixText text="POWER USER" size="xs" dotClass="text-primary" />
|
<DotMatrixText text="POWER USER" size="xs" dotClass="text-primary" />
|
||||||
<h2 id="power-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">Built for the people who keep the lights on.</h2>
|
<h2 id="power-title" class="mt-4 text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">Controls for the work you repeat.</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="max-w-[44ch] text-[15px] leading-relaxed text-muted-foreground">
|
<p class="max-w-[44ch] text-[15px] leading-relaxed text-muted-foreground">
|
||||||
Tasks stream over WebSocket with polling fallback. <button data-cmdk-trigger class="underline decoration-white/15 underline-offset-4 hover:text-foreground">⌘K</button> opens the palette. The tray keeps one-click actions one click away.
|
WebSocket events update task status. If events stop, polling takes over. Press <button data-cmdk-trigger class="underline decoration-white/15 underline-offset-4 hover:text-foreground">⌘K</button> to find a command. The tray keeps common actions close.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-4 border-b border-dotted border-white/10 px-1 py-4 sm:px-4" data-stagger-child>
|
<div class="flex items-center justify-between gap-4 border-b border-dotted border-white/10 px-1 py-4 sm:px-4" data-stagger-child>
|
||||||
<span class="font-mono text-[11px] font-medium text-primary">WebSocket</span>
|
<span class="font-mono text-[11px] font-medium text-primary">WebSocket</span>
|
||||||
<span class="text-sm text-muted-foreground">Live task & event stream</span>
|
<span class="text-sm text-muted-foreground">Live task and event updates</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-4 border-b border-dotted border-white/10 px-1 py-4 sm:border-r sm:px-4 sm:border-b-0" data-stagger-child>
|
<div class="flex items-center justify-between gap-4 border-b border-dotted border-white/10 px-1 py-4 sm:border-r sm:px-4 sm:border-b-0" data-stagger-child>
|
||||||
<span class="font-mono text-[11px] font-medium text-primary">Tray menu</span>
|
<span class="font-mono text-[11px] font-medium text-primary">Tray menu</span>
|
||||||
|
|||||||
@@ -14,26 +14,26 @@ const year = new Date().getFullYear()
|
|||||||
<DotMatrixText text="CLUSTRI" size="xs" dotClass="text-foreground" />
|
<DotMatrixText text="CLUSTRI" size="xs" dotClass="text-foreground" />
|
||||||
<span class="hidden sm:inline"><DotMatrixText text="OPS CONSOLE" size="xs" dotClass="text-muted-foreground opacity-70" /></span>
|
<span class="hidden sm:inline"><DotMatrixText text="OPS CONSOLE" size="xs" dotClass="text-muted-foreground opacity-70" /></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-3 font-mono text-[11px] text-muted-foreground">v0.1.0 · MIT · Not affiliated with Proxmox.</p>
|
<p class="mt-3 font-mono text-[11px] text-muted-foreground">v0.1.0 · MIT · Desktop client for Proxmox.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-8 sm:flex-row sm:gap-16">
|
<div class="flex flex-col gap-8 sm:flex-row sm:gap-16">
|
||||||
<nav aria-label="Navigate" class="space-y-2">
|
<nav aria-label="Navigate" class="space-y-2">
|
||||||
<DotMatrixText text="NAVIGATE" size="xs" dotClass="text-muted-foreground" />
|
<DotMatrixText text="NAVIGATE" size="xs" dotClass="text-muted-foreground" />
|
||||||
<div class="mt-2 space-y-1">
|
<div class="mt-2 space-y-1">
|
||||||
<a href="#failover-playground" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Failover demo</a>
|
<a href="#failover-playground" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Test failover</a>
|
||||||
<a href="#security" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Security</a>
|
<a href="#security" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Security</a>
|
||||||
<a href="#tour" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Tour</a>
|
<a href="#tour" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Tour</a>
|
||||||
<a href="#console" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Console</a>
|
<a href="#console" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Console</a>
|
||||||
<a href="#architecture" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Architecture</a>
|
<a href="#architecture" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Architecture</a>
|
||||||
<a href="#download" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Download</a>
|
<a href="#download" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">See releases</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<nav aria-label="Source" class="space-y-2">
|
<nav aria-label="Source" class="space-y-2">
|
||||||
<DotMatrixText text="SOURCE" size="xs" dotClass="text-muted-foreground" />
|
<DotMatrixText text="SOURCE" size="xs" dotClass="text-muted-foreground" />
|
||||||
<div class="mt-2 space-y-1">
|
<div class="mt-2 space-y-1">
|
||||||
<a href="#" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">GitHub</a>
|
<a href="https://github.com/Factor-scd/clustri" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">GitHub</a>
|
||||||
<a href="#" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Build from source</a>
|
<a href="https://github.com/Factor-scd/clustri" class="block font-mono text-[12px] text-muted-foreground transition-colors hover:text-foreground">Build from source</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,7 +41,7 @@ const year = new Date().getFullYear()
|
|||||||
|
|
||||||
<div class="mt-10 flex flex-col gap-2 border-t border-dotted border-white/10 pt-6 font-mono text-[11px] text-muted-foreground/60 md:flex-row md:items-center md:justify-between">
|
<div class="mt-10 flex flex-col gap-2 border-t border-dotted border-white/10 pt-6 font-mono text-[11px] text-muted-foreground/60 md:flex-row md:items-center md:justify-between">
|
||||||
<p>© {year} Clustri. MIT license.</p>
|
<p>© {year} Clustri. MIT license.</p>
|
||||||
<p class="flex items-center gap-2">Press <kbd class="rounded border border-dotted border-white/15 bg-white/[0.04] px-1.5 py-0.5 text-[10px]">⌘K</kbd> anywhere</p>
|
<p class="flex items-center gap-2">Press <kbd class="rounded border border-dotted border-white/15 bg-white/[0.04] px-1.5 py-0.5 text-[10px]">⌘K</kbd> to search</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="relative mx-auto max-w-7xl px-6 lg:px-8">
|
<div class="relative mx-auto max-w-7xl px-6 lg:px-8">
|
||||||
<div class="pt-28 sm:pt-36 lg:pt-40">
|
<div class="pt-28 sm:pt-36 lg:pt-40">
|
||||||
<h1 class="mt-6 max-w-[14ch] text-[2.6rem] font-semibold leading-[0.92] tracking-[-0.04em] text-foreground sm:text-[3.5rem] lg:text-[4.6rem]">
|
<h1 class="mt-6 max-w-[14ch] text-[2.6rem] font-semibold leading-[0.92] tracking-[-0.04em] text-foreground sm:text-[3.5rem] lg:text-[4.6rem]">
|
||||||
Your cluster,<br />
|
Manage your cluster,<br />
|
||||||
<span class="text-muted-foreground">not your problem.</span>
|
<span class="text-muted-foreground">from one desktop app.</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p class="mt-5 max-w-[52ch] text-[15px] leading-relaxed text-muted-foreground sm:text-[16px]">
|
<p class="mt-5 max-w-[52ch] text-[15px] leading-relaxed text-muted-foreground sm:text-[16px]">
|
||||||
Clustri is a cross-platform desktop console for Proxmox VE. Manage nodes, VMs, storage and backups — and keep working when a node goes down.
|
Clustri connects to Proxmox VE and PBS so you can manage nodes, VMs, containers, storage, backups, and consoles without keeping a browser tab open.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="mt-8 flex flex-wrap items-center gap-3">
|
<div class="mt-8 flex flex-wrap items-center gap-3">
|
||||||
<a href="#download" class="rounded-[10px] bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:bg-primary/90 active:scale-[0.98]">Get Clustri</a>
|
<a href="#download" class="rounded-[10px] bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:bg-primary/90 active:scale-[0.98]">See releases</a>
|
||||||
<a href="#failover-playground" class="rounded-[10px] border border-dotted border-white/15 bg-white/[0.04] px-6 py-3 text-sm font-semibold text-foreground transition hover:border-white/20 hover:bg-white/[0.06] active:scale-[0.98]">Try the failover demo ↓</a>
|
<a href="#failover-playground" class="rounded-[10px] border border-dotted border-white/15 bg-white/[0.04] px-6 py-3 text-sm font-semibold text-foreground transition hover:border-white/20 hover:bg-white/[0.06] active:scale-[0.98]">Try failover</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 flex flex-wrap gap-x-4 gap-y-1 font-mono text-[11px] uppercase tracking-[0.08em] text-muted-foreground">
|
<div class="mt-6 flex flex-wrap gap-x-4 gap-y-1 font-mono text-[11px] uppercase tracking-[0.08em] text-muted-foreground">
|
||||||
@@ -42,7 +42,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<AppWindowMockup />
|
<AppWindowMockup />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-3 text-center font-mono text-[10px] text-muted-foreground">Live demo — values tick, tasks stream. The real app looks like this.</p>
|
<p class="mt-3 text-center font-mono text-[10px] text-muted-foreground">Dashboard preview with live metrics and task updates.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex shrink-0 items-center gap-3">
|
<div class="flex shrink-0 items-center gap-3">
|
||||||
<button data-cmdk-trigger class="hidden sm:flex items-center gap-1.5 rounded-md border border-dotted border-white/10 bg-white/[0.04] px-2.5 py-1.5 font-mono text-[11px] text-muted-foreground transition-colors hover:border-white/15 hover:text-foreground" aria-label="Open command palette">
|
<button data-cmdk-trigger class="hidden sm:flex items-center gap-1.5 rounded-md border border-dotted border-white/10 bg-white/[0.04] px-2.5 py-1.5 font-mono text-[11px] text-muted-foreground transition-colors hover:border-white/15 hover:text-foreground" aria-label="Open commands">
|
||||||
<span>⌘K</span>
|
<span>⌘K</span>
|
||||||
</button>
|
</button>
|
||||||
<a href="#download" class="rounded-[10px] border border-dotted border-primary/30 bg-primary px-4 py-2 text-[13px] font-semibold text-primary-foreground transition-all hover:bg-primary/90 active:scale-[0.98]">Get Clustri</a>
|
<a href="#download" class="rounded-[10px] border border-dotted border-primary/30 bg-primary px-4 py-2 text-[13px] font-semibold text-primary-foreground transition-all hover:bg-primary/90 active:scale-[0.98]">See releases</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div data-reveal>
|
<div data-reveal>
|
||||||
<DotMatrixText text="TOUR" size="xs" dotClass="text-primary" />
|
<DotMatrixText text="TOUR" size="xs" dotClass="text-primary" />
|
||||||
<h2 id="tour-title" class="mt-4 max-w-[14ch] text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">
|
<h2 id="tour-title" class="mt-4 max-w-[14ch] text-3xl font-semibold tracking-[-0.03em] text-foreground sm:text-4xl">
|
||||||
Feels like the Proxmox UI,<br /><span class="text-muted-foreground">without the browser.</span>
|
Manage Proxmox resources,<br /><span class="text-muted-foreground">in a desktop window.</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-4 max-w-[48ch] text-[15px] leading-relaxed text-muted-foreground">
|
<p class="mt-4 max-w-[48ch] text-[15px] leading-relaxed text-muted-foreground">
|
||||||
Native window, keyboard-first, no electron bloat. Tabs switch instantly — the data underneath stays live via WebSocket or 10s polling.
|
Clustri runs as a native Tauri app. Switch between VMs, consoles, and backups while WebSocket events or 10-second polling refreshes the data.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<span class="h-2.5 w-2.5 rounded-full border border-dotted border-white/10 bg-white/10"></span>
|
<span class="h-2.5 w-2.5 rounded-full border border-dotted border-white/10 bg-white/10"></span>
|
||||||
<span class="h-2.5 w-2.5 rounded-full border border-dotted border-white/10 bg-white/10"></span>
|
<span class="h-2.5 w-2.5 rounded-full border border-dotted border-white/10 bg-white/10"></span>
|
||||||
</div>
|
</div>
|
||||||
<p id="tour-frame-label" class="font-mono text-[10px] tabular-nums text-muted-foreground">Virtual Machines — 4 VMs across the cluster</p>
|
<p id="tour-frame-label" class="font-mono text-[10px] tabular-nums text-muted-foreground">Virtual Machines: 4 VMs across the cluster</p>
|
||||||
<span class="hidden font-mono text-[10px] text-success sm:inline">● live</span>
|
<span class="hidden font-mono text-[10px] text-success sm:inline">● live</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative bg-[#0e0e12]">
|
<div class="relative bg-[#0e0e12]">
|
||||||
@@ -41,15 +41,15 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
<div class="mt-4 grid gap-3 sm:grid-cols-3">
|
<div class="mt-4 grid gap-3 sm:grid-cols-3">
|
||||||
<div class="rounded-lg border border-dotted border-white/10 bg-card p-4 dot-grid" data-reveal>
|
<div class="rounded-lg border border-dotted border-white/10 bg-card p-4 dot-grid" data-reveal>
|
||||||
<DotMatrixText text="VMS + CONTAINERS" size="xs" dotClass="text-foreground" />
|
<DotMatrixText text="VMS + CONTAINERS" size="xs" dotClass="text-foreground" />
|
||||||
<p class="mt-2 text-[13px] leading-relaxed text-muted-foreground">Filter by node, type, status. Start / stop / migrate / console in one click. QEMU and LXC.</p>
|
<p class="mt-2 text-[13px] leading-relaxed text-muted-foreground">Filter by node, type, or status. Start, stop, migrate, or open a console for QEMU and LXC guests.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-lg border border-dotted border-white/10 bg-card p-4 dot-grid" data-reveal data-reveal-delay="80">
|
<div class="rounded-lg border border-dotted border-white/10 bg-card p-4 dot-grid" data-reveal data-reveal-delay="80">
|
||||||
<DotMatrixText text="CONSOLE" size="xs" dotClass="text-foreground" />
|
<DotMatrixText text="CONSOLE" size="xs" dotClass="text-foreground" />
|
||||||
<p class="mt-2 text-[13px] leading-relaxed text-muted-foreground">noVNC for VMs, xterm.js for CTs. Fullscreen, resize, Ctrl+Alt+Del passthrough.</p>
|
<p class="mt-2 text-[13px] leading-relaxed text-muted-foreground">Use noVNC for VMs and xterm.js for CTs, with fullscreen, resize, and Ctrl+Alt+Del passthrough.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="rounded-lg border border-dotted border-white/10 bg-card p-4 dot-grid" data-reveal data-reveal-delay="160">
|
<div class="rounded-lg border border-dotted border-white/10 bg-card p-4 dot-grid" data-reveal data-reveal-delay="160">
|
||||||
<DotMatrixText text="BACKUPS" size="xs" dotClass="text-foreground" />
|
<DotMatrixText text="BACKUPS" size="xs" dotClass="text-foreground" />
|
||||||
<p class="mt-1.5 text-[13px] leading-relaxed text-muted-foreground">Jobs, groups, snapshots. Verify, prune (dry-run), GC, archive download via OS dialog.</p>
|
<p class="mt-1.5 text-[13px] leading-relaxed text-muted-foreground">Review jobs, groups, and snapshots. Verify archives, preview prune, run GC, or download through the OS dialog.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,9 +60,9 @@ import DotMatrixText from './DotMatrixText.astro'
|
|||||||
const label = document.getElementById('tour-frame-label')
|
const label = document.getElementById('tour-frame-label')
|
||||||
const tabs = document.querySelectorAll<HTMLButtonElement>('[data-tour-tab]')
|
const tabs = document.querySelectorAll<HTMLButtonElement>('[data-tour-tab]')
|
||||||
const sources: Record<string, { src: string; label: string; alt: string }> = {
|
const sources: Record<string, { src: string; label: string; alt: string }> = {
|
||||||
vms: { src: '/screenshots/vms.png', label: 'Virtual Machines — 4 VMs across the cluster', alt: 'Clustri VM list showing running and stopped VMs' },
|
vms: { src: '/screenshots/vms.png', label: 'Virtual Machines: 4 VMs across the cluster', alt: 'Clustri VM list showing running and stopped VMs' },
|
||||||
console: { src: '/screenshots/console.png', label: 'VNC Console — web-01 (QEMU) on pve1', alt: 'Clustri console view with VNC viewer' },
|
console: { src: '/screenshots/console.png', label: 'VNC Console: web-01 (QEMU) on pve1', alt: 'Clustri console view with VNC viewer' },
|
||||||
backups: { src: '/screenshots/backups.png', label: 'Backups — datastores, groups and snapshots', alt: 'Clustri backups view with datastores and prune controls' },
|
backups: { src: '/screenshots/backups.png', label: 'Backups: datastores, groups, and snapshots', alt: 'Clustri backups view with datastores and prune controls' },
|
||||||
}
|
}
|
||||||
tabs.forEach((btn) => {
|
tabs.forEach((btn) => {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
---
|
---
|
||||||
import DotMatrixText from './DotMatrixText.astro'
|
import DotMatrixText from './DotMatrixText.astro'
|
||||||
---
|
---
|
||||||
<section aria-label="Facts" class="border-y border-dotted border-white/10 bg-[#08080a] dot-grid">
|
<section aria-label="Project details" class="border-y border-dotted border-white/10 bg-[#08080a] dot-grid">
|
||||||
<div class="mx-auto max-w-7xl px-6 lg:px-8">
|
<div class="mx-auto max-w-7xl px-6 lg:px-8">
|
||||||
<div class="grid grid-cols-2 gap-0 py-8 sm:grid-cols-4" data-stagger>
|
<div class="grid grid-cols-2 gap-0 py-8 sm:grid-cols-4" data-stagger>
|
||||||
<div class="flex flex-col items-center gap-2 border-r border-dotted border-white/10 px-2 py-6" data-stagger-child>
|
<div class="flex flex-col items-center gap-2 border-r border-dotted border-white/10 px-2 py-6" data-stagger-child>
|
||||||
<span class="font-mono text-3xl font-semibold tracking-[-0.03em] tabular-nums text-foreground sm:text-4xl" data-countup="0">0</span>
|
<span class="font-mono text-3xl font-semibold tracking-[-0.03em] tabular-nums text-foreground sm:text-4xl" data-countup="0">0</span>
|
||||||
<DotMatrixText text="TELEMETRY" size="xs" dotClass="text-muted-foreground" />
|
<DotMatrixText text="TELEMETRY" size="xs" dotClass="text-muted-foreground" />
|
||||||
<span class="font-mono text-[11px] text-muted-foreground">ships with the app</span>
|
<span class="font-mono text-[11px] text-muted-foreground">telemetry disabled</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center gap-2 border-r border-dotted border-white/10 px-2 py-6 sm:border-r" data-stagger-child>
|
<div class="flex flex-col items-center gap-2 border-r border-dotted border-white/10 px-2 py-6 sm:border-r" data-stagger-child>
|
||||||
<span class="font-mono text-3xl font-semibold tracking-[-0.03em] tabular-nums text-foreground sm:text-4xl" data-countup="0">0</span>
|
<span class="font-mono text-3xl font-semibold tracking-[-0.03em] tabular-nums text-foreground sm:text-4xl" data-countup="0">0</span>
|
||||||
<DotMatrixText text="CLOUD" size="xs" dotClass="text-muted-foreground" />
|
<DotMatrixText text="CLOUD" size="xs" dotClass="text-muted-foreground" />
|
||||||
<span class="font-mono text-[11px] text-muted-foreground">talks to your nodes</span>
|
<span class="font-mono text-[11px] text-muted-foreground">runs against your infrastructure</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center gap-2 border-r border-dotted border-white/10 px-2 py-6 max-sm:border-r-0" data-stagger-child>
|
<div class="flex flex-col items-center gap-2 border-r border-dotted border-white/10 px-2 py-6 max-sm:border-r-0" data-stagger-child>
|
||||||
<span class="font-mono text-3xl font-semibold tracking-[-0.03em] tabular-nums text-primary sm:text-4xl" data-countup="64">0</span>
|
<span class="font-mono text-3xl font-semibold tracking-[-0.03em] tabular-nums text-primary sm:text-4xl" data-countup="64">0</span>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import '@fontsource-variable/jetbrains-mono'
|
|||||||
import '../styles/global.css'
|
import '../styles/global.css'
|
||||||
|
|
||||||
interface Props { title?: string; description?: string }
|
interface Props { title?: string; description?: string }
|
||||||
const { title = 'Clustri', description = 'A desktop client for managing Proxmox VE servers and clusters.' } = Astro.props
|
const { title = 'Clustri', description = 'A cross-platform desktop client for managing Proxmox VE and PBS servers and clusters.' } = Astro.props
|
||||||
---
|
---
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import CommandPalette from '../components/CommandPalette.astro'
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Base
|
<Base
|
||||||
title="Clustri — Ops Console for Proxmox VE"
|
title="Clustri | Proxmox VE desktop client"
|
||||||
description="Clustri is a cross-platform desktop client for managing Proxmox VE servers and clusters. Failover, security, VMs, storage, backups, and consoles in one app."
|
description="Manage Proxmox VE and PBS from a cross-platform desktop client with failover, keyring storage, VM and container controls, backups, and consoles."
|
||||||
>
|
>
|
||||||
<Nav />
|
<Nav />
|
||||||
<main>
|
<main>
|
||||||
|
|||||||
+11
-11
@@ -159,11 +159,11 @@ function initLiveDashboard() {
|
|||||||
const taskList = root.querySelector<HTMLElement>('[data-live-tasks]')
|
const taskList = root.querySelector<HTMLElement>('[data-live-tasks]')
|
||||||
|
|
||||||
const pool = [
|
const pool = [
|
||||||
{ chip: 'RUNNING', cls: 'border-warning/30 bg-warning/10 text-warning', text: 'start VM 104', node: 'pve3', time: 'now' },
|
{ chip: 'RUNNING', cls: 'border-warning/30 bg-warning/10 text-warning', text: 'Start VM 104', node: 'pve3', time: 'now' },
|
||||||
{ chip: 'OK', cls: 'border-success/25 bg-success/10 text-success', text: 'snapshot vm-100', node: 'pve1', time: 'now' },
|
{ chip: 'OK', cls: 'border-success/25 bg-success/10 text-success', text: 'Snapshot vm-100', node: 'pve1', time: 'now' },
|
||||||
{ chip: 'RUNNING', cls: 'border-warning/30 bg-warning/10 text-warning', text: 'migrate VM 102 → pve3', node: 'pve1 → pve3', time: 'now' },
|
{ chip: 'RUNNING', cls: 'border-warning/30 bg-warning/10 text-warning', text: 'Move VM 102 to pve3', node: 'pve1 → pve3', time: 'now' },
|
||||||
{ chip: 'OK', cls: 'border-success/25 bg-success/10 text-success', text: 'backup ct-201 → pbs', node: 'pve2', time: 'now' },
|
{ chip: 'OK', cls: 'border-success/25 bg-success/10 text-success', text: 'Back up ct-201 to PBS', node: 'pve2', time: 'now' },
|
||||||
{ chip: 'DONE', cls: 'border-white/10 bg-white/[0.04] text-muted-foreground', text: 'prune datastore main', node: 'pbs', time: 'now' },
|
{ chip: 'DONE', cls: 'border-white/10 bg-white/[0.04] text-muted-foreground', text: 'Prune main datastore', node: 'pbs', time: 'now' },
|
||||||
]
|
]
|
||||||
let poolIdx = 0
|
let poolIdx = 0
|
||||||
|
|
||||||
@@ -221,12 +221,12 @@ function initCommandPalette() {
|
|||||||
if (!overlay || !panel || !input || !list) return
|
if (!overlay || !panel || !input || !list) return
|
||||||
|
|
||||||
const commands = [
|
const commands = [
|
||||||
{ label: 'Go to Features', desc: 'Failover, security, VMs', action: () => scrollToId('features') },
|
{ label: 'See features', desc: 'Failover, credentials, guests', action: () => scrollToId('features') },
|
||||||
{ label: 'Go to Console', desc: 'noVNC · xterm.js', action: () => scrollToId('console') },
|
{ label: 'Open console', desc: 'VM and container consoles', action: () => scrollToId('console') },
|
||||||
{ label: 'Go to Architecture', desc: 'Request path diagram', action: () => scrollToId('architecture') },
|
{ label: 'See architecture', desc: 'Watch requests move', action: () => scrollToId('architecture') },
|
||||||
{ label: 'Go to Download', desc: 'Releases · coming soon', action: () => scrollToId('download') },
|
{ label: 'See releases', desc: 'Packages are not published yet', action: () => scrollToId('download') },
|
||||||
{ label: 'Kill pve1 (demo)', desc: 'Trigger the failover playground', action: () => { scrollToId('failover-playground'); setTimeout(() => document.getElementById('fp-kill-pve1')?.click(), 600) } },
|
{ label: 'Stop pve1 (demo)', desc: 'Stop pve1 and watch failover', action: () => { scrollToId('failover-playground'); setTimeout(() => document.getElementById('fp-kill-pve1')?.click(), 600) } },
|
||||||
{ label: 'Copy install command', desc: 'npm run tauri dev', action: () => navigator.clipboard.writeText('npm run tauri dev') },
|
{ label: 'Copy install command', desc: 'Copy npm run tauri dev', action: () => navigator.clipboard.writeText('npm run tauri dev') },
|
||||||
]
|
]
|
||||||
|
|
||||||
let filtered = [...commands]
|
let filtered = [...commands]
|
||||||
|
|||||||
Generated
+248
-5
@@ -58,6 +58,15 @@ dependencies = [
|
|||||||
"security-framework",
|
"security-framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arbitrary"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
||||||
|
dependencies = [
|
||||||
|
"derive_arbitrary",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assert-json-diff"
|
name = "assert-json-diff"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
@@ -445,6 +454,7 @@ dependencies = [
|
|||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
"tauri-plugin-dialog",
|
"tauri-plugin-dialog",
|
||||||
|
"tauri-plugin-updater",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -706,6 +716,17 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_arbitrary"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@@ -962,6 +983,16 @@ dependencies = [
|
|||||||
"rustc_version",
|
"rustc_version",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filetime"
|
||||||
|
version = "0.2.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@@ -1860,6 +1891,36 @@ dependencies = [
|
|||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jni"
|
||||||
|
version = "0.22.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"combine",
|
||||||
|
"jni-macros",
|
||||||
|
"jni-sys 0.4.1",
|
||||||
|
"log",
|
||||||
|
"simd_cesu8",
|
||||||
|
"thiserror 2.0.19",
|
||||||
|
"walkdir",
|
||||||
|
"windows-link 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jni-macros"
|
||||||
|
version = "0.22.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustc_version",
|
||||||
|
"simd_cesu8",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jni-sys"
|
name = "jni-sys"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -2094,6 +2155,12 @@ version = "0.3.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minisign-verify"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.9"
|
version = "0.8.9"
|
||||||
@@ -2342,6 +2409,18 @@ dependencies = [
|
|||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-osa-kit"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.13.1",
|
||||||
|
"objc2",
|
||||||
|
"objc2-app-kit",
|
||||||
|
"objc2-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-quartz-core"
|
name = "objc2-quartz-core"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -2405,12 +2484,32 @@ version = "1.21.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-probe"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-ext"
|
name = "option-ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "osakit"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b"
|
||||||
|
dependencies = [
|
||||||
|
"objc2",
|
||||||
|
"objc2-foundation",
|
||||||
|
"objc2-osa-kit",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 2.0.19",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pango"
|
name = "pango"
|
||||||
version = "0.18.3"
|
version = "0.18.3"
|
||||||
@@ -2977,15 +3076,20 @@ dependencies = [
|
|||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"hyper-rustls",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-platform-verifier",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sync_wrapper",
|
"sync_wrapper",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-rustls",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
@@ -3079,6 +3183,18 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-native-certs"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d"
|
||||||
|
dependencies = [
|
||||||
|
"openssl-probe",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
@@ -3098,6 +3214,33 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-platform-verifier"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"jni 0.22.4",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"rustls",
|
||||||
|
"rustls-native-certs",
|
||||||
|
"rustls-platform-verifier-android",
|
||||||
|
"rustls-webpki",
|
||||||
|
"security-framework",
|
||||||
|
"security-framework-sys",
|
||||||
|
"webpki-root-certs",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-platform-verifier-android"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.103.13"
|
version = "0.103.13"
|
||||||
@@ -3131,6 +3274,15 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "schannel"
|
||||||
|
version = "0.1.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars"
|
name = "schemars"
|
||||||
version = "0.8.22"
|
version = "0.8.22"
|
||||||
@@ -3464,6 +3616,22 @@ version = "0.3.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
|
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd_cesu8"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version",
|
||||||
|
"simdutf8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simdutf8"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "similar"
|
name = "similar"
|
||||||
version = "2.7.0"
|
version = "2.7.0"
|
||||||
@@ -3707,7 +3875,7 @@ dependencies = [
|
|||||||
"gdkwayland-sys",
|
"gdkwayland-sys",
|
||||||
"gdkx11-sys",
|
"gdkx11-sys",
|
||||||
"gtk",
|
"gtk",
|
||||||
"jni",
|
"jni 0.21.1",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"ndk",
|
"ndk",
|
||||||
@@ -3740,6 +3908,17 @@ dependencies = [
|
|||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tar"
|
||||||
|
version = "0.4.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840"
|
||||||
|
dependencies = [
|
||||||
|
"filetime",
|
||||||
|
"libc",
|
||||||
|
"xattr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.16"
|
version = "0.12.16"
|
||||||
@@ -3763,7 +3942,7 @@ dependencies = [
|
|||||||
"gtk",
|
"gtk",
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"http",
|
"http",
|
||||||
"jni",
|
"jni 0.21.1",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
@@ -3917,6 +4096,39 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-updater"
|
||||||
|
version = "2.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "806d9dac662c2e4594ff03c647a552f2c9bd544e7d0f683ec58f872f952ce4af"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"dirs",
|
||||||
|
"flate2",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"infer",
|
||||||
|
"log",
|
||||||
|
"minisign-verify",
|
||||||
|
"osakit",
|
||||||
|
"percent-encoding",
|
||||||
|
"reqwest 0.13.4",
|
||||||
|
"rustls",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tar",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror 2.0.19",
|
||||||
|
"time",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
"zip",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime"
|
name = "tauri-runtime"
|
||||||
version = "2.11.3"
|
version = "2.11.3"
|
||||||
@@ -3927,7 +4139,7 @@ dependencies = [
|
|||||||
"dpi",
|
"dpi",
|
||||||
"gtk",
|
"gtk",
|
||||||
"http",
|
"http",
|
||||||
"jni",
|
"jni 0.21.1",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-ui-kit",
|
"objc2-ui-kit",
|
||||||
"objc2-web-kit",
|
"objc2-web-kit",
|
||||||
@@ -3950,7 +4162,7 @@ checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"gtk",
|
"gtk",
|
||||||
"http",
|
"http",
|
||||||
"jni",
|
"jni 0.21.1",
|
||||||
"log",
|
"log",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
@@ -4804,6 +5016,15 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-root-certs"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.26.11"
|
version = "0.26.11"
|
||||||
@@ -5369,7 +5590,7 @@ dependencies = [
|
|||||||
"gtk",
|
"gtk",
|
||||||
"http",
|
"http",
|
||||||
"javascriptcore-rs",
|
"javascriptcore-rs",
|
||||||
"jni",
|
"jni 0.21.1",
|
||||||
"libc",
|
"libc",
|
||||||
"ndk",
|
"ndk",
|
||||||
"objc2",
|
"objc2",
|
||||||
@@ -5428,6 +5649,16 @@ dependencies = [
|
|||||||
"tls_codec",
|
"tls_codec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xattr"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yasna"
|
name = "yasna"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -5554,6 +5785,18 @@ dependencies = [
|
|||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zip"
|
||||||
|
version = "4.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1"
|
||||||
|
dependencies = [
|
||||||
|
"arbitrary",
|
||||||
|
"crc32fast",
|
||||||
|
"indexmap 2.14.0",
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zmij"
|
name = "zmij"
|
||||||
version = "1.0.23"
|
version = "1.0.23"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ tauri-build = { version = "2", features = [] }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "2", features = ["tray-icon"] }
|
tauri = { version = "2", features = ["tray-icon"] }
|
||||||
tauri-plugin-dialog = "2"
|
tauri-plugin-dialog = "2"
|
||||||
|
tauri-plugin-updater = "2"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
|
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -2257,6 +2257,60 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "dialog:deny-save",
|
"const": "dialog:deny-save",
|
||||||
"markdownDescription": "Denies the save command without any pre-configured scope."
|
"markdownDescription": "Denies the save command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n\n#### This default permission set includes:\n\n- `allow-check`\n- `allow-download`\n- `allow-install`\n- `allow-download-and-install`",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:default",
|
||||||
|
"markdownDescription": "This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n\n#### This default permission set includes:\n\n- `allow-check`\n- `allow-download`\n- `allow-install`\n- `allow-download-and-install`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-check",
|
||||||
|
"markdownDescription": "Enables the check command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-download",
|
||||||
|
"markdownDescription": "Enables the download command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-download-and-install",
|
||||||
|
"markdownDescription": "Enables the download_and_install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-install",
|
||||||
|
"markdownDescription": "Enables the install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-check",
|
||||||
|
"markdownDescription": "Denies the check command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-download",
|
||||||
|
"markdownDescription": "Denies the download command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-download-and-install",
|
||||||
|
"markdownDescription": "Denies the download_and_install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-install",
|
||||||
|
"markdownDescription": "Denies the install command without any pre-configured scope."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2257,6 +2257,60 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "dialog:deny-save",
|
"const": "dialog:deny-save",
|
||||||
"markdownDescription": "Denies the save command without any pre-configured scope."
|
"markdownDescription": "Denies the save command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n\n#### This default permission set includes:\n\n- `allow-check`\n- `allow-download`\n- `allow-install`\n- `allow-download-and-install`",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:default",
|
||||||
|
"markdownDescription": "This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n\n#### This default permission set includes:\n\n- `allow-check`\n- `allow-download`\n- `allow-install`\n- `allow-download-and-install`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-check",
|
||||||
|
"markdownDescription": "Enables the check command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-download",
|
||||||
|
"markdownDescription": "Enables the download command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-download-and-install",
|
||||||
|
"markdownDescription": "Enables the download_and_install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:allow-install",
|
||||||
|
"markdownDescription": "Enables the install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-check",
|
||||||
|
"markdownDescription": "Denies the check command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-download",
|
||||||
|
"markdownDescription": "Denies the download command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-download-and-install",
|
||||||
|
"markdownDescription": "Denies the download_and_install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "updater:deny-install",
|
||||||
|
"markdownDescription": "Denies the install command without any pre-configured scope."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1249,6 +1249,7 @@ pub fn run() {
|
|||||||
update_tray_menu,
|
update_tray_menu,
|
||||||
])
|
])
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
// Build the system tray menu
|
// Build the system tray menu
|
||||||
let show_hide = MenuItemBuilder::new("Show / Hide")
|
let show_hide = MenuItemBuilder::new("Show / Hide")
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"rustc_fingerprint":6524788087311550793,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.95.0 (59807616e 2026-04-14)\nbinary: rustc\ncommit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860\ncommit-date: 2026-04-14\nhost: aarch64-apple-darwin\nrelease: 1.95.0\nLLVM version: 22.1.2\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/matt/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""}},"successes":{}}
|
{"rustc_fingerprint":9200552825474144316,"outputs":{"7752308220390268658":{"success":true,"status":"","code":0,"stdout":"rustc 1.97.1 (8bab26f4f 2026-07-14)\nbinary: rustc\ncommit-hash: 8bab26f4f68e0e26f0bb7960be334d5b520ea452\ncommit-date: 2026-07-14\nhost: x86_64-unknown-linux-gnu\nrelease: 1.97.1\nLLVM version: 22.1.6\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_primitive_alignment=\"16\"\ntarget_has_atomic_primitive_alignment=\"32\"\ntarget_has_atomic_primitive_alignment=\"64\"\ntarget_has_atomic_primitive_alignment=\"8\"\ntarget_has_atomic_primitive_alignment=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
|
||||||
@@ -34,5 +34,13 @@
|
|||||||
"icons/icon.icns",
|
"icons/icon.icns",
|
||||||
"icons/icon.ico"
|
"icons/icon.ico"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
"updater": {
|
||||||
|
"enabled": true,
|
||||||
|
"endpoints": [
|
||||||
|
"https://github.com/Factor-scd/clustri/releases/latest/download/latest.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user