From dbdc959d3e4444b720647a1e3081f5b8bdf9f192 Mon Sep 17 00:00:00 2001 From: P S Kesavan Date: Thu, 2 Jul 2026 16:37:57 +0530 Subject: [PATCH 01/14] =?UTF-8?q?docs(launcher):=20parked=20design=20?= =?UTF-8?q?=E2=80=94=20unified=20launcher=20+=20bare-basic=20launch=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PARKED for a future session. launch_gently as the single entry point that starts/stops the device layer (managed child subprocess; graceful stop + mid-run guard; auto-kill on exit; external device layer detected). Launch gate is BARE BASIC — two questions (microscope hardware on/off, AI agent/API on/off) + Let's go; organism/hardware/port/ SAM/session are defaults behind Advanced/Settings, never on the gate. Boot uses defer-init so a web gate can control boot-level behavior. Dark/sharp/sleek mockup at docs/superpowers/mockups/2026-07-02-launcher-gate.html. Decisions log + phasing included. --- .../mockups/2026-07-02-launcher-gate.html | 82 +++++++++++++++ .../2026-07-02-unified-launcher-design.md | 99 +++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 docs/superpowers/mockups/2026-07-02-launcher-gate.html create mode 100644 docs/superpowers/specs/2026-07-02-unified-launcher-design.md diff --git a/docs/superpowers/mockups/2026-07-02-launcher-gate.html b/docs/superpowers/mockups/2026-07-02-launcher-gate.html new file mode 100644 index 00000000..18879dde --- /dev/null +++ b/docs/superpowers/mockups/2026-07-02-launcher-gate.html @@ -0,0 +1,82 @@ + + + + + +Launch Gently + + + +
+
Gently
+

What do you need today?

+ +
+
+ +
+
+
Microscope hardware
+
Start the device layer & connect to the rig · :60610
+
+ +
+ +
+
+ +
+
+
AI agent
+
Chat, perception & planning — uses your API key
+
+ +
+ + +
Advanced options · remembers your choice
+
+ + diff --git a/docs/superpowers/specs/2026-07-02-unified-launcher-design.md b/docs/superpowers/specs/2026-07-02-unified-launcher-design.md new file mode 100644 index 00000000..3588d3f5 --- /dev/null +++ b/docs/superpowers/specs/2026-07-02-unified-launcher-design.md @@ -0,0 +1,99 @@ +# Unified Launcher — single entry point + device-layer process management — Design + +Date: 2026-07-02 +Status: **Design — PARKED.** Direction agreed + mockup done; implementation deferred to a future session. +Branch: `feature/unified-launcher` (off `development`). + +## Problem + +Starting gently today is two commands in two terminals: `python start_device_layer.py` +(the hardware server) then `python launch_gently.py` (agent + web). gently can't +start or stop the device layer — it only connects to it as an HTTP client — so there's +no in‑app way to bring hardware up/down. Goal: make `launch_gently.py` the **single** +entry point, with a dead‑simple launch gate and the ability to start/stop the device +layer from gently. + +## How the two processes relate (today) + +- `start_device_layer.py` boots the hardware control server (aiohttp) on **port 60610** + (`DEVICE_PORT`) and runs the configured hardware module's `create_device_layer()`. + Independent OS process. +- `launch_gently.py` boots the agent + web/viz server and creates an HTTP client + (`QueueServerClient → http://127.0.0.1:60610`); `client.is_connected` drives the + "Device: ○ offline" banner. The two only talk over HTTP. + +## The launch gate — BARE BASIC (the key decision) + +The launch screen answers exactly two questions, nothing more: + +1. **Microscope hardware — on/off.** On → gently starts + connects the device layer. + Off → software‑only (analysis, planning, reviewing saved data). +2. **AI agent (API) — on/off.** On → chat, perception, planning (uses the API key). + Off → UI‑only. + +Then **Let's go →**. That's the whole screen. Everything else — organism, hardware +module, device port, SAM device, session resume — is a **default** (config / last‑used), +reachable behind a muted **"Advanced options"** disclosure and in **Settings**. It is +NOT on the gate: if you're not using hardware, you should never be asked which hardware. + +Visual reference (dark, sharp, sleek): `docs/superpowers/mockups/2026-07-02-launcher-gate.html` +— two toggle cards (`Microscope hardware`, `AI agent`) + `Let's go →` + `Advanced +options · remembers your choice`. + +## Process model — managed child subprocess + +A **`DeviceLayerSupervisor`** in the gently process spawns `start_device_layer.py` as a +**child** (`subprocess.Popen([sys.executable, "start_device_layer.py", "--port", …, +"--sam-device", …])`), holds its handle, monitors liveness, captures its log, and stops +it. Ownership is what makes start/stop‑from‑UI and no‑orphans work. +- API: `start(config)`, `stop(force=False)`, `status()`, log tail, `atexit`/signal cleanup. +- **External device layer still supported:** if one is already running on 60610, gently + connects and shows it as "external (not managed)" — it just won't stop what it didn't start. +- Rejected alternatives: independent processes + a `/shutdown` endpoint (weaker ownership, + more parts); in‑process device layer (a hardware crash would take down the UI). + +## Boot flow (defer‑init) + +`launch_gently` boots a minimal web server → shows the **launch gate** (prefilled from +last choice) → on **Let's go**, it initializes per the two toggles: start the agent (if +API on) and start the device layer via the supervisor (if hardware on) → then the landing +("Good afternoon…") → dashboard. Deferring heavy init until the gate is submitted is what +lets a web screen control boot‑level behavior (agent on/off). + +## Runtime control + +A **device‑layer panel in the Devices tab** mirrors the gate's hardware block at runtime: +live status (running / stopped / external / crashed), Start / Stop, and a tail of the +device‑layer log — so you can bring hardware up/down without restarting gently. + +## Stop safety (graceful + mid‑run guard) + +Stop → if a plan/acquisition is active, warn + require explicit confirm ("hardware is +active — stop anyway?") → SIGTERM (clean shutdown) → SIGKILL fallback (~5 s). Reuses the +409 + `"blocked"` pattern from the thermalizer work. Startup failure (hardware off) +surfaces the existing plain‑language `_render_startup_failure` diagnosis, not a traceback. + +## Persistence + +`config/launch.local.json` (gitignored) remembers the two toggles (+ any advanced values) +so the gate is prefilled every boot. + +## Non‑goals (YAGNI) + +Auto‑restart‑on‑crash loops; multiple / remote device layers (mesh already covers +cross‑machine); managing an externally‑started device layer's lifecycle; putting +organism/hardware/port/SAM/session on the gate (they're defaults + Advanced/Settings). + +## Phasing (when resumed) + +1. `DeviceLayerSupervisor` + the runtime Devices start/stop panel + the **hardware toggle** + on a minimal gate. Delivers "no more separate `start_device_layer.py`" immediately. +2. Defer‑init boot refactor + the **agent toggle** + persistence + "Advanced options". + +## Decisions log (from brainstorming) + +- Launcher model: **web startup screen + runtime panel**. +- Boot flow: **show the gate every boot, remember last choices** (one click to proceed). +- Stop: **graceful SIGTERM + mid‑run guard + SIGKILL fallback**. +- Scope: **fold in gently's own options** — but as a **bare‑basic 2‑question gate** + (hardware, agent), with the rest behind Advanced/Settings. From 8ad90354f1d54af1860a45188bf87086c7653ab4 Mon Sep 17 00:00:00 2001 From: P S Kesavan Date: Thu, 2 Jul 2026 16:44:06 +0530 Subject: [PATCH 02/14] docs(launcher): credit Magdalena + open questions to fold in (initial work) This is initial/RFC work. Idea credited to Magdalena. Adds open questions: background (non-blocking) device startup after launch; gently usable while the device boots; on-demand device startup-sequence console; shutdown from that same console; guided shutdown housekeeping (e.g. prompt to reset the F drive). --- .../2026-07-02-unified-launcher-design.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/superpowers/specs/2026-07-02-unified-launcher-design.md b/docs/superpowers/specs/2026-07-02-unified-launcher-design.md index 3588d3f5..39adb0be 100644 --- a/docs/superpowers/specs/2026-07-02-unified-launcher-design.md +++ b/docs/superpowers/specs/2026-07-02-unified-launcher-design.md @@ -1,7 +1,9 @@ # Unified Launcher — single entry point + device-layer process management — Design Date: 2026-07-02 -Status: **Design — PARKED.** Direction agreed + mockup done; implementation deferred to a future session. +Status: **Initial design (RFC) — PARKED.** A starting point to build on, not a finished +design; direction + mockup done, implementation deferred to a future session. +Idea credit: **Magdalena** — the single unified launcher. Branch: `feature/unified-launcher` (off `development`). ## Problem @@ -90,6 +92,25 @@ organism/hardware/port/SAM/session on the gate (they're defaults + Advanced/Sett on a minimal gate. Delivers "no more separate `start_device_layer.py`" immediately. 2. Defer‑init boot refactor + the **agent toggle** + persistence + "Advanced options". +## Open questions to fold in (this is initial work) + +This is a starting point — the following must be worked through as it grows: + +- **Background startup.** After "Let's go", the device‑layer startup should run in the + **background (non‑blocking)** while gently proceeds to the dashboard — not block the gate + until the device connects. (To confirm + design the progress signalling.) +- **Usable during startup.** gently must stay **usable while the device layer boots** — + software features (planning, review, analysis) available immediately; hardware‑dependent + actions gated behind a "device starting…" state until connected. +- **On‑demand startup‑sequence screen.** There must be a screen to watch the device + **startup sequence** on demand — a device console (in the Devices panel) streaming the + `start_device_layer` boot log + per‑stage connection progress. +- **Shutdown from that same screen.** That console is also the **shutdown control** — start + the sequence, watch it, and stop the device from one place. +- **Guided shutdown housekeeping.** Shutdown is a **sequence, not just a kill** — e.g. it + can prompt the operator to **reset the F drive** (post‑shutdown drive/housekeeping) as a + step in the flow. + ## Decisions log (from brainstorming) - Launcher model: **web startup screen + runtime panel**. From caa0d57e2d188f0e8be4ca5e99d13bb6780b23e0 Mon Sep 17 00:00:00 2001 From: P S Kesavan Date: Thu, 2 Jul 2026 16:47:01 +0530 Subject: [PATCH 03/14] =?UTF-8?q?docs(launcher):=20future=20direction=20?= =?UTF-8?q?=E2=80=94=20Windows=20desktop=20app=20(Electron=20shell)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold-in to weigh: package the unified launcher as a Windows desktop app (potentially Electron) that owns/spawns the Python backend + device-layer child and renders the web UI natively (launch gate as first screen), with native process lifecycle + installer. Web UI stays the single source of truth; pywebview/Tauri as lighter fallbacks. The managed-child model here is what an Electron shell would take over. --- .../specs/2026-07-02-unified-launcher-design.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/superpowers/specs/2026-07-02-unified-launcher-design.md b/docs/superpowers/specs/2026-07-02-unified-launcher-design.md index 39adb0be..3e24228c 100644 --- a/docs/superpowers/specs/2026-07-02-unified-launcher-design.md +++ b/docs/superpowers/specs/2026-07-02-unified-launcher-design.md @@ -111,6 +111,22 @@ This is a starting point — the following must be worked through as it grows: can prompt the operator to **reset the F drive** (post‑shutdown drive/housekeeping) as a step in the flow. +## Future direction — Windows desktop app (Electron) + +Bigger fold‑in to weigh: package the unified launcher as a **desktop app for Windows**, +potentially **Electron**, so gently is a double‑click application instead of terminal +commands. Electron would *be* the launcher shell — it owns and spawns the Python backend +(`launch_gently`) and the device‑layer child, renders the existing web UI in a native +window (the launch gate is the first screen), and gets native process lifecycle +(children killed on quit), a tray/menu, and a real installer + auto‑update. + +Tradeoffs for later: bundling/shipping the Python environment (embeddable Python / +PyInstaller), app size, auto‑update, and keeping the **web UI the single source of truth** +(Electron stays a thin shell — no UI logic moves into it). A lighter native wrapper +(**pywebview** or **Tauri**) is the fallback if Electron's footprint is too heavy. This is +a packaging/architecture decision, not required for the launcher's first cut — but the +managed‑child process model here is exactly what an Electron shell would take over. + ## Decisions log (from brainstorming) - Launcher model: **web startup screen + runtime panel**. From e2aa54f5df5523f04297b6d8484c670fe62abc67 Mon Sep 17 00:00:00 2001 From: Kesavan Date: Sun, 12 Jul 2026 02:27:31 -0400 Subject: [PATCH 04/14] feat(launcher): scaffold DeviceLayerSupervisor + launch gate (RFC #78) First implementation cut of the parked unified-launcher RFC: gently can now own the device-layer process and start/stop it from the UI, instead of requiring a second terminal running start_device_layer.py. - DeviceLayerSupervisor (gently/app/device_supervisor.py): spawns start_device_layer.py as a managed child, tails its console into a ring buffer, reports running/stopped/crashed/external, stops gracefully with a hard-kill fallback, and atexit-kills the child so it never orphans. Detects and respects an externally-started device layer (won't stop what it didn't start). - Launch gate (/launch + templates/launch.html): the bare two-question start screen (hardware on/off, agent on/off), styled from the RFC mockup, wired to persist choices and start the device layer on "Let's go". - launch_prefs.py: remembers the gate's toggles in config/launch.local.json. - routes/device_layer.py: status/start/stop/log + launch prefs, with start/stop behind require_control and a 409 "blocked" mid-run guard on stop. - Wired the router into register_all_routes and attach a supervisor to the viz server at boot. Deferred (RFC open questions, marked in-code): defer-init boot so the agent toggle gates startup; truly graceful Windows shutdown (needs SIGBREAK handling in start_device_layer.py); background/non-blocking startup with per-stage boot progress; guided shutdown housekeeping. Co-Authored-By: Claude Opus 4.8 (1M context) --- gently/app/device_supervisor.py | 313 +++++++++++++++++++++++++++ gently/ui/web/launch_prefs.py | 81 +++++++ gently/ui/web/routes/__init__.py | 2 + gently/ui/web/routes/device_layer.py | 141 ++++++++++++ gently/ui/web/templates/launch.html | 196 +++++++++++++++++ launch_gently.py | 12 + 6 files changed, 745 insertions(+) create mode 100644 gently/app/device_supervisor.py create mode 100644 gently/ui/web/launch_prefs.py create mode 100644 gently/ui/web/routes/device_layer.py create mode 100644 gently/ui/web/templates/launch.html diff --git a/gently/app/device_supervisor.py b/gently/app/device_supervisor.py new file mode 100644 index 00000000..5f7c01a7 --- /dev/null +++ b/gently/app/device_supervisor.py @@ -0,0 +1,313 @@ +"""Managed child subprocess for the device layer. + +Today gently only connects to ``start_device_layer.py`` as an HTTP client, so +there is no in-app way to bring hardware up or down — you run it yourself in a +second terminal. ``DeviceLayerSupervisor`` gives the gently process *ownership* +of that child: it spawns ``start_device_layer.py``, holds the handle, tails its +console output, reports liveness, and stops it (gracefully, then forcibly). That +ownership is what makes start/stop-from-UI and no-orphans-on-exit possible. + +Design: ``docs/superpowers/specs/2026-07-02-unified-launcher-design.md`` (RFC #78). + +Scope of this scaffold +---------------------- +- Real, working spawn / stop / status / log-tail + atexit cleanup. +- **External device layer is respected:** if something is already listening on + the port, we surface it as ``external`` and never try to manage (or stop) what + we did not start. + +Deliberately deferred (RFC "open questions"): +- Background/non-blocking startup with per-stage boot progress. +- Truly graceful shutdown on Windows — that needs ``start_device_layer.py`` to + handle ``SIGBREAK`` (see ``stop`` below). Until then Windows falls back to a + hard terminate after the grace period. +""" + +from __future__ import annotations + +import atexit +import logging +import signal +import socket +import subprocess +import sys +import threading +import time +from collections import deque +from pathlib import Path + +from gently.settings import settings + +logger = logging.getLogger(__name__) + +# Repo root: gently/app/device_supervisor.py -> parents[2] +_PROJECT_ROOT = Path(__file__).resolve().parents[2] +_DEVICE_SCRIPT = _PROJECT_ROOT / "start_device_layer.py" + +# How many console lines to retain for the log-tail shown in the Devices panel. +_LOG_TAIL_LINES = 500 +# Grace period (seconds) for a clean shutdown before we hard-kill. +_STOP_GRACE_SECONDS = 5.0 + + +class DeviceLayerSupervisor: + """Own the ``start_device_layer.py`` child process for one gently instance. + + Thread-safe: ``start``/``stop`` take an internal lock so overlapping calls + from async route handlers can't race on the process handle. A single reader + thread drains the child's stdout into a bounded ring buffer for the tail. + """ + + def __init__( + self, + port: int = settings.network.device_port, + host: str = settings.network.device_host, + sam_device: str = "cuda", + config_path: str = "config/config.yml", + ): + self.port = port + self.host = host + self.sam_device = sam_device + self.config_path = config_path + + self._proc: subprocess.Popen | None = None + self._lock = threading.Lock() + self._log: deque[str] = deque(maxlen=_LOG_TAIL_LINES) + self._reader: threading.Thread | None = None + self._started_at: float | None = None + # True once *we* asked the child to stop, so a resulting non-zero exit + # reads as "stopped" rather than "crashed". + self._stopping = False + + atexit.register(self._atexit_cleanup) + + # ── lifecycle ──────────────────────────────────────────────────────── + + def start(self, *, sam_device: str | None = None, config_path: str | None = None) -> dict: + """Spawn the device layer child if it isn't already up. + + Idempotent: if we already own a live child, returns its status. If an + *external* (unmanaged) device layer is already listening on the port, + refuses to start a duplicate and returns the external status. + """ + with self._lock: + if self._alive(): + logger.debug("Device layer already managed (pid=%s)", self._proc.pid) + return self._status_locked() + + if self._port_open(): + # Something is already listening we didn't start — don't stomp it. + logger.info( + "Device layer already running externally on %s:%s — not spawning a child", + self.host, + self.port, + ) + return self._status_locked() + + if not _DEVICE_SCRIPT.exists(): + raise FileNotFoundError(f"device layer script not found: {_DEVICE_SCRIPT}") + + if sam_device is not None: + self.sam_device = sam_device + if config_path is not None: + self.config_path = config_path + + cmd = [ + sys.executable, + str(_DEVICE_SCRIPT), + "--port", + str(self.port), + "--sam-device", + self.sam_device, + "--config", + self.config_path, + ] + + # A new process group on Windows is what later lets us send a + # CTRL_BREAK for a (best-effort) clean shutdown instead of only a + # hard TerminateProcess. + creationflags = 0 + if sys.platform == "win32": + creationflags = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore[attr-defined] + + logger.info("Spawning device layer: %s", " ".join(cmd)) + self._log.clear() + self._stopping = False + self._proc = subprocess.Popen( + cmd, + cwd=str(_PROJECT_ROOT), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + encoding="utf-8", + errors="replace", + bufsize=1, + creationflags=creationflags, + ) + self._started_at = time.monotonic() + + self._reader = threading.Thread( + target=self._drain_output, + args=(self._proc,), + name="device-layer-log", + daemon=True, + ) + self._reader.start() + + return self._status_locked() + + def stop(self, *, force: bool = False, timeout: float = _STOP_GRACE_SECONDS) -> dict: + """Stop the managed child. Graceful first, hard-kill fallback. + + We only stop a child *we* spawned — an external device layer is left + alone (you can't cleanly stop what you don't own). + + ``force=True`` skips the grace period and hard-kills immediately. + """ + with self._lock: + if not self._alive(): + # Nothing of ours to stop (may still be external — status says so). + return self._status_locked() + + self._stopping = True + proc = self._proc + assert proc is not None + + if force: + self._hard_kill(proc) + return self._status_locked() + + # Graceful request. + try: + if sys.platform == "win32": + # Best-effort clean stop. NOTE: start_device_layer.py handles + # SIGINT/SIGTERM but not SIGBREAK, so today this usually falls + # through to the hard-kill below. Teaching the device layer to + # handle SIGBREAK (RFC follow-up) makes this a clean shutdown. + proc.send_signal(signal.CTRL_BREAK_EVENT) # type: ignore[attr-defined] + else: + proc.terminate() # SIGTERM -> device layer's clean shutdown path + except (ProcessLookupError, OSError) as e: + logger.debug("Signal to device layer failed (already exiting?): %s", e) + + try: + proc.wait(timeout=timeout) + logger.info("Device layer stopped cleanly (rc=%s)", proc.returncode) + except subprocess.TimeoutExpired: + logger.warning( + "Device layer didn't exit within %.1fs — forcing termination", timeout + ) + self._hard_kill(proc) + + return self._status_locked() + + def restart(self, **kwargs) -> dict: + """Stop (if running) then start — convenience for the Devices panel.""" + self.stop() + return self.start(**kwargs) + + # ── introspection ──────────────────────────────────────────────────── + + def status(self) -> dict: + """Current state of the device layer (see ``_status_locked``).""" + with self._lock: + return self._status_locked() + + def log_tail(self, limit: int = 200) -> list[str]: + """The most recent captured console lines (oldest → newest).""" + lines = list(self._log) + return lines[-limit:] if limit else lines + + # ── internals ──────────────────────────────────────────────────────── + + def _status_locked(self) -> dict: + """Compute status. Caller must hold ``_lock``. + + state: + running — we own a live child + crashed — our child exited non-zero without us asking it to + external — we don't own it, but the port is listening + stopped — nothing running (never started, or cleanly stopped) + """ + managed_alive = self._alive() + port_open = self._port_open() + + if managed_alive: + state = "running" + elif self._proc is not None and self._proc.returncode not in (None, 0) and not self._stopping: + state = "crashed" + elif port_open: + state = "external" + else: + state = "stopped" + + pid = self._proc.pid if (self._proc and managed_alive) else None + rc = self._proc.returncode if self._proc else None + uptime = ( + round(time.monotonic() - self._started_at, 1) + if (managed_alive and self._started_at) + else None + ) + + return { + "state": state, + "managed": managed_alive, + "pid": pid, + "returncode": rc, + "host": self.host, + "port": self.port, + "port_open": port_open, + "sam_device": self.sam_device, + "uptime_seconds": uptime, + "log_tail": self.log_tail(50), + } + + def _alive(self) -> bool: + """True if we own a child that is still running.""" + return self._proc is not None and self._proc.poll() is None + + def _port_open(self, timeout: float = 0.25) -> bool: + """True if anything is accepting connections on the device port. + + Used to detect an externally-started device layer. ``host`` may be a + bind address like ``0.0.0.0``; probe loopback for that case. + """ + probe_host = "127.0.0.1" if self.host in ("0.0.0.0", "", None) else self.host + try: + with socket.create_connection((probe_host, self.port), timeout=timeout): + return True + except OSError: + return False + + def _hard_kill(self, proc: subprocess.Popen) -> None: + """Terminate a process forcibly and reap it. Caller holds ``_lock``.""" + try: + proc.kill() + proc.wait(timeout=3.0) + except subprocess.TimeoutExpired: + logger.error("Device layer pid=%s would not die after kill()", proc.pid) + except (ProcessLookupError, OSError): + pass + + def _drain_output(self, proc: subprocess.Popen) -> None: + """Reader-thread body: copy child stdout into the ring buffer.""" + stream = proc.stdout + if stream is None: + return + try: + for line in iter(stream.readline, ""): + self._log.append(line.rstrip("\n")) + except (ValueError, OSError): + # Stream closed underneath us during shutdown — fine. + pass + + def _atexit_cleanup(self) -> None: + """Kill an orphaned child when the gently process exits.""" + proc = self._proc + if proc is not None and proc.poll() is None: + logger.info("atexit: terminating managed device layer (pid=%s)", proc.pid) + self._stopping = True + try: + proc.kill() + except (ProcessLookupError, OSError): + pass diff --git a/gently/ui/web/launch_prefs.py b/gently/ui/web/launch_prefs.py new file mode 100644 index 00000000..0a5bb905 --- /dev/null +++ b/gently/ui/web/launch_prefs.py @@ -0,0 +1,81 @@ +"""Persistence for the launch gate's two toggles (+ advanced defaults). + +The launch gate answers exactly two questions — *microscope hardware on/off* and +*AI agent on/off* — and everything else (device port, SAM device) is a remembered +default behind "Advanced options". Those choices live in +``config/launch.local.json`` (gitignored) so the gate is prefilled every boot. + +See ``docs/superpowers/specs/2026-07-02-unified-launcher-design.md`` (RFC #78). +""" + +from __future__ import annotations + +import json +import logging +from pathlib import Path + +from gently.settings import settings + +logger = logging.getLogger(__name__) + +# Repo root: gently/ui/web/launch_prefs.py -> parents[3] +_CONFIG_DIR = Path(__file__).resolve().parents[3] / "config" +PREFS_PATH = _CONFIG_DIR / "launch.local.json" + +# Only these keys are read from / written to disk. Advanced values fall back to +# settings so a fresh install has sensible defaults without a prefs file. +_DEFAULTS: dict = { + "hardware": True, # start + connect the device layer + "agent": True, # enable chat / perception / planning (needs API key) + "port": settings.network.device_port, + "sam_device": "cuda", +} +_ALLOWED_KEYS = set(_DEFAULTS) + + +def load_prefs() -> dict: + """Return the persisted launch choices merged over defaults. + + Never raises — a missing or corrupt file just yields the defaults, so the + gate always renders. + """ + prefs = dict(_DEFAULTS) + try: + if PREFS_PATH.exists(): + stored = json.loads(PREFS_PATH.read_text(encoding="utf-8")) + if isinstance(stored, dict): + prefs.update({k: stored[k] for k in _ALLOWED_KEYS if k in stored}) + except (OSError, ValueError) as e: + logger.warning("launch prefs unreadable (%s) — using defaults", e) + return prefs + + +def save_prefs(prefs: dict) -> dict: + """Persist a (partial) set of launch choices; returns the merged result. + + Unknown keys are ignored; known keys are coerced to the expected types. + """ + merged = load_prefs() + for key in _ALLOWED_KEYS & set(prefs): + merged[key] = _coerce(key, prefs[key]) + try: + _CONFIG_DIR.mkdir(parents=True, exist_ok=True) + PREFS_PATH.write_text(json.dumps(merged, indent=2), encoding="utf-8") + except OSError as e: + logger.error("could not persist launch prefs: %s", e) + return merged + + +def _coerce(key: str, value): + """Coerce a JSON-supplied value to the type its default implies.""" + default = _DEFAULTS[key] + if isinstance(default, bool): + if isinstance(value, str): + return value.strip().lower() in ("1", "true", "yes", "on") + return bool(value) + if isinstance(default, int): + try: + return int(value) + except (TypeError, ValueError): + return default + return value diff --git a/gently/ui/web/routes/__init__.py b/gently/ui/web/routes/__init__.py index a881a0bb..ef939435 100644 --- a/gently/ui/web/routes/__init__.py +++ b/gently/ui/web/routes/__init__.py @@ -12,6 +12,7 @@ from .chat import create_router as create_chat_router from .context import create_router as create_context_router from .data import create_router as create_data_router +from .device_layer import create_router as create_device_layer_router from .experiments import create_router as create_experiments_router from .images import create_router as create_images_router from .notebook import create_router as create_notebook_router @@ -30,6 +31,7 @@ def register_all_routes(server): for factory in ( create_pages_router, create_auth_router, + create_device_layer_router, create_sessions_router, create_campaigns_router, create_experiments_router, diff --git a/gently/ui/web/routes/device_layer.py b/gently/ui/web/routes/device_layer.py new file mode 100644 index 00000000..8f8dbf0f --- /dev/null +++ b/gently/ui/web/routes/device_layer.py @@ -0,0 +1,141 @@ +"""Device-layer supervision + launch gate routes. + +Two surfaces, both backed by ``DeviceLayerSupervisor``: + +- **Launch gate** (``GET /launch``) — the bare two-question start screen + (hardware on/off, agent on/off) with its persisted choices. +- **Devices panel** (``/api/device-layer/*``) — runtime status, log tail, and + Start / Stop controls that mirror the gate's hardware block. + +Control-mutating endpoints (start/stop) are gated behind ``require_control``, +matching the rest of the hardware routes. Stop reuses the 409 + ``"blocked"`` +mid-run guard pattern: if hardware looks active, the caller must confirm. + +See ``docs/superpowers/specs/2026-07-02-unified-launcher-design.md`` (RFC #78). +""" + +from __future__ import annotations + +import logging + +from fastapi import APIRouter, Depends, Request +from fastapi.responses import HTMLResponse, JSONResponse + +from gently.ui.web.auth import require_control +from gently.ui.web.launch_prefs import load_prefs, save_prefs + +logger = logging.getLogger(__name__) + + +def get_supervisor(server): + """Return the server's DeviceLayerSupervisor, creating one on first use. + + ``launch_gently`` attaches a supervisor to the viz server at boot, but we + lazily construct one if it's absent so these routes work standalone (and so + the panel degrades gracefully rather than 500-ing). + """ + sup = getattr(server, "device_supervisor", None) + if sup is None: + from gently.app.device_supervisor import DeviceLayerSupervisor + + sup = DeviceLayerSupervisor() + server.device_supervisor = sup + return sup + + +def _hardware_active(server) -> bool: + """Best-effort: is an acquisition / timelapse currently running? + + Used by the stop guard. Conservative — only reports active when we can see a + clearly-running timelapse; unknown state reads as inactive so a stuck flag + can't wedge the Stop button. + """ + tracker = getattr(server, "timelapse_tracker", None) + status = getattr(tracker, "status", None) + return str(status).lower() in ("running", "acquiring", "active") + + +def create_router(server) -> APIRouter: + router = APIRouter() + + # ── Launch gate ────────────────────────────────────────────────────── + + @router.get("/launch", response_class=HTMLResponse) + async def launch_gate(request: Request): + """The bare two-question launch screen (prefilled from last choice).""" + return server.templates.TemplateResponse(request, "launch.html", {}) + + @router.get("/api/launch/prefs") + async def get_launch_prefs(): + """Persisted launch choices (hardware/agent toggles + advanced defaults).""" + return load_prefs() + + @router.post("/api/launch/prefs") + async def set_launch_prefs(request: Request, _=Depends(require_control)): + """Persist launch choices; returns the merged result.""" + body = await request.json() + return save_prefs(body if isinstance(body, dict) else {}) + + # ── Devices panel: device-layer supervision ────────────────────────── + + @router.get("/api/device-layer/status") + async def device_layer_status(): + """Live status: running / stopped / external / crashed (+ short log tail).""" + return get_supervisor(server).status() + + @router.get("/api/device-layer/log") + async def device_layer_log(limit: int = 200): + """Recent captured console output (oldest → newest) for the console view.""" + return {"lines": get_supervisor(server).log_tail(limit)} + + @router.post("/api/device-layer/start") + async def device_layer_start(request: Request, _=Depends(require_control)): + """Spawn (or adopt-if-external) the device layer per the request body. + + Body (all optional): ``{"sam_device": "cuda"|"cpu", "config_path": "..."}``. + """ + body = await _safe_json(request) + sup = get_supervisor(server) + try: + status = sup.start( + sam_device=body.get("sam_device"), + config_path=body.get("config_path"), + ) + except (FileNotFoundError, OSError) as e: + logger.error("device layer start failed: %s", e) + return JSONResponse({"error": str(e)}, status_code=500) + return status + + @router.post("/api/device-layer/stop") + async def device_layer_stop(request: Request, _=Depends(require_control)): + """Stop the managed device layer, with a mid-run confirmation guard. + + If hardware looks active and the body doesn't carry ``{"confirm": true}``, + returns 409 ``{"blocked": true, ...}`` instead of stopping (same shape the + thermalizer stop-guard uses). ``{"force": true}`` skips the grace period. + """ + body = await _safe_json(request) + sup = get_supervisor(server) + + if _hardware_active(server) and not body.get("confirm"): + return JSONResponse( + { + "blocked": True, + "reason": "hardware is active — an acquisition is running", + "hint": "resend with {\"confirm\": true} to stop anyway", + }, + status_code=409, + ) + + return sup.stop(force=bool(body.get("force"))) + + return router + + +async def _safe_json(request: Request) -> dict: + """Parse a JSON body, tolerating an empty/absent one (returns {}).""" + try: + body = await request.json() + except (ValueError, TypeError): + return {} + return body if isinstance(body, dict) else {} diff --git a/gently/ui/web/templates/launch.html b/gently/ui/web/templates/launch.html new file mode 100644 index 00000000..89027014 --- /dev/null +++ b/gently/ui/web/templates/launch.html @@ -0,0 +1,196 @@ + + + + + +Launch Gently + + + + +
+
Gently
+

What do you need today?

+ +
+
+ +
+
+
Microscope hardware
+
Start the device layer & connect to the rig · :60610
+
+ +
+ +
+
+ +
+
+
AI agent
+
Chat, perception & planning — uses your API key
+
+ +
+ + +
+ +
+ · remembers your choice +
+
+
+ + +
+
+ + +
+
+
+ + + + diff --git a/launch_gently.py b/launch_gently.py index 6afcbe86..7ba28534 100644 --- a/launch_gently.py +++ b/launch_gently.py @@ -552,6 +552,18 @@ def _status_provider(): if agent.viz_server is not None: agent.viz_server.agent_bridge = bridge agent.viz_server.set_context_store(context_store) + # Device-layer supervisor (managed child subprocess) — lets the launch + # gate and the Devices panel start/stop start_device_layer.py from the + # UI, and kills it on exit so it never orphans. It auto-detects an + # already-running (external) device layer and leaves it alone. RFC #78. + try: + from gently.app.device_supervisor import DeviceLayerSupervisor + + agent.viz_server.device_supervisor = DeviceLayerSupervisor( + port=settings.network.device_port, + ) + except Exception: + logger.debug("DeviceLayerSupervisor init skipped", exc_info=True) # If launched into an existing session, rehydrate its persisted # imagery so the galleries/filmstrips show data from the start. if session_to_resume: From cdd0eb3592ff41ddea8e921ef635b917a8fb8563 Mon Sep 17 00:00:00 2001 From: Kesavan Date: Sun, 12 Jul 2026 02:59:31 -0400 Subject: [PATCH 05/14] feat(devices+desktop): device-layer supervision panel + Tauri desktop shell (RFC #78) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fold-ins on the unified-launcher RFC. Devices supervision panel (web UI): - gently/ui/web/static/js/device-layer.js — self-contained DeviceLayerCard IIFE in the Devices tab: polls /api/device-layer/status while the tab is visible, renders running/stopped/external/crashed as a status pill, Start/Stop (with the 409 mid-run force-confirm and transparent 403 view-only handling), and a collapsible live log tail. Wired into index.html + main.css using existing devices-* / marking-* / theme-token conventions. - Verified end-to-end in a browser: stopped -> Start -> running (pid/port/uptime, live log) -> Stop -> stopped, server-confirmed, no console errors. Tauri desktop shell (desktop/): - A thin WebView2 window that OWNS the Python backend: spawns launch_gently.py --no-browser, shows a splash, then navigates to the live UI. - Reliable teardown: the spawned Python (and its device-layer grandchild) go in a Windows Job Object with KILL_ON_JOB_CLOSE, so quitting/crashing the shell reaps the whole tree — proven by force-killing only the shell and observing python + device layer die and both ports free. - Built clean against tauri 2.11.5; UI verified rendering inside the native window (incl. the new Devices panel) via WebView2 CDP. - README documents dev-run, build, env config, and the remaining Python-bundling work for a redistributable installer. Supervisor: - device_supervisor.py honours GENTLY_DEVICE_LAYER_SCRIPT to point at an alternate device-layer entry point (also lets tests use a harmless stand-in). Co-Authored-By: Claude Opus 4.8 (1M context) --- desktop/.gitignore | 14 + desktop/README.md | 94 + desktop/icons/source.png | Bin 0 -> 5157 bytes desktop/package-lock.json | 232 + desktop/package.json | 12 + desktop/splash/index.html | 51 + desktop/src-tauri/Cargo.lock | 4433 +++++++++++++++++++ desktop/src-tauri/Cargo.toml | 29 + desktop/src-tauri/build.rs | 3 + desktop/src-tauri/capabilities/default.json | 7 + desktop/src-tauri/icons/128x128.png | Bin 0 -> 8161 bytes desktop/src-tauri/icons/128x128@2x.png | Bin 0 -> 15932 bytes desktop/src-tauri/icons/32x32.png | Bin 0 -> 1623 bytes desktop/src-tauri/icons/64x64.png | Bin 0 -> 3830 bytes desktop/src-tauri/icons/icon.icns | Bin 0 -> 128538 bytes desktop/src-tauri/icons/icon.ico | Bin 0 -> 27566 bytes desktop/src-tauri/icons/icon.png | Bin 0 -> 3887 bytes desktop/src-tauri/src/main.rs | 228 + desktop/src-tauri/tauri.conf.json | 38 + gently/app/device_supervisor.py | 11 +- gently/ui/web/static/css/main.css | 48 + gently/ui/web/static/js/device-layer.js | 242 + gently/ui/web/templates/index.html | 21 + 23 files changed, 5460 insertions(+), 3 deletions(-) create mode 100644 desktop/.gitignore create mode 100644 desktop/README.md create mode 100644 desktop/icons/source.png create mode 100644 desktop/package-lock.json create mode 100644 desktop/package.json create mode 100644 desktop/splash/index.html create mode 100644 desktop/src-tauri/Cargo.lock create mode 100644 desktop/src-tauri/Cargo.toml create mode 100644 desktop/src-tauri/build.rs create mode 100644 desktop/src-tauri/capabilities/default.json create mode 100644 desktop/src-tauri/icons/128x128.png create mode 100644 desktop/src-tauri/icons/128x128@2x.png create mode 100644 desktop/src-tauri/icons/32x32.png create mode 100644 desktop/src-tauri/icons/64x64.png create mode 100644 desktop/src-tauri/icons/icon.icns create mode 100644 desktop/src-tauri/icons/icon.ico create mode 100644 desktop/src-tauri/icons/icon.png create mode 100644 desktop/src-tauri/src/main.rs create mode 100644 desktop/src-tauri/tauri.conf.json create mode 100644 gently/ui/web/static/js/device-layer.js diff --git a/desktop/.gitignore b/desktop/.gitignore new file mode 100644 index 00000000..6b3daa59 --- /dev/null +++ b/desktop/.gitignore @@ -0,0 +1,14 @@ +# Node / Tauri CLI +node_modules/ + +# Rust / Tauri build output +src-tauri/target/ +src-tauri/gen/ + +# Generated mobile / MS-Store icon variants (regenerate with `tauri icon`). +# The desktop icons referenced by tauri.conf.json (32x32, 128x128, 128x128@2x, +# icon.ico, icon.icns, icon.png) ARE committed so a clean checkout builds. +src-tauri/icons/android/ +src-tauri/icons/ios/ +src-tauri/icons/Square*Logo.png +src-tauri/icons/StoreLogo.png diff --git a/desktop/README.md b/desktop/README.md new file mode 100644 index 00000000..f9ad9943 --- /dev/null +++ b/desktop/README.md @@ -0,0 +1,94 @@ +# Gently Desktop (Tauri shell) + +A thin [Tauri](https://v2.tauri.app) desktop wrapper that turns gently into a +double-click Windows app. It **owns** the Python backend: on launch it spawns +`launch_gently.py --no-browser`, shows a splash while the server boots, then +renders the existing web UI in a native WebView2 window. No application logic +lives here — the web UI served by Python stays the single source of truth. + +This is the desktop-packaging fold-in described in RFC #78 +(`docs/superpowers/specs/2026-07-02-unified-launcher-design.md`). + +## Why Tauri (and what it does / doesn't solve) + +- **Tiny footprint** — uses the OS WebView2 (already present on Win 11), not a + bundled Chromium. +- **Robust process ownership** — the shell puts the spawned Python into a + Windows **Job Object** with `KILL_ON_JOB_CLOSE`. Python's own device-layer + grandchild (via `DeviceLayerSupervisor`) inherits the job, so when the app + quits *or crashes* the OS reaps the **entire** process tree — no orphaned + device layer holding COM ports. +- **Not solved here:** bundling the Python environment (torch, anthropic, + perception) into a redistributable installer. This build launches the repo's + existing `.venv`. Shipping a self-contained `.msi`/`.exe` to another machine + needs an embeddable-Python / PyInstaller sidecar — see *Bundling* below. + +## Architecture + +``` +Tauri shell (Rust, WebView2 window) + └─ spawns: python launch_gently.py --no-browser [in a kill-on-close Job] + └─ spawns: start_device_layer.py (DeviceLayerSupervisor) + ├─ shows splash/index.html while uvicorn boots + └─ navigate() → http://localhost:8080 (the live gently UI) +``` + +- `src-tauri/src/main.rs` — spawn + Job Object teardown + wait-for-server + navigate. +- `splash/index.html` — boot splash (Rust updates its status line via `window.__gentlyStatus`). +- `src-tauri/tauri.conf.json` — one window, `frontendDist: ../splash`, NSIS bundle. + +## Prerequisites + +- **Rust** (MSVC toolchain) — `rustup default stable-x86_64-pc-windows-msvc` +- **MSVC C++ build tools** (Visual Studio 2022 / Build Tools) +- **WebView2 runtime** (inbox on Windows 11) +- **Node** (only for the Tauri CLI: `npm install` in this folder) +- A working gently checkout with its Python **`.venv`** at the repo root + +## Run (dev) + +```bash +cd desktop +npm install # once — installs @tauri-apps/cli +# UI-only smoke test (no hardware, no API key, no login): +GENTLY_LAUNCH_ARGS="--no-api --offline --no-auth" npx tauri dev +# Full app (needs ANTHROPIC_API_KEY in the environment / repo .env): +npx tauri dev +``` + +`tauri dev` builds and launches the shell; it spawns the backend for you. + +## Build (installer) + +```bash +cd desktop +npx tauri build # produces an NSIS installer under src-tauri/target/release/bundle/ +``` + +The built app launches the **repo's** `.venv` + `launch_gently.py` (paths baked +at compile time / overridable — see env vars). It is a single-machine build +until Python bundling lands. + +## Configuration (env vars read by the shell) + +| Var | Default | Purpose | +|---|---|---| +| `GENTLY_HOME` | compile-time repo root | Directory to run the backend from | +| `GENTLY_PYTHON` | `/.venv/Scripts/python.exe` | Python interpreter to launch | +| `GENTLY_LAUNCH_ARGS` | *(none)* | Extra args appended to `launch_gently.py --no-browser` | +| `VIZ_PORT` | `8080` | Port the shell waits on and navigates to | +| `GENTLY_DEVICE_LAYER_SCRIPT` | `start_device_layer.py` | Alternate device-layer entry point (read by `DeviceLayerSupervisor`) | + +## Bundling Python (the remaining long pole) + +`tauri build` today does **not** package Python. To make a redistributable app: + +1. Produce a self-contained backend (PyInstaller one-folder of `launch_gently`, + or an embeddable-Python tree with the deps installed). +2. Ship it as a Tauri **sidecar** (or under the app's resource dir) and point + `GENTLY_PYTHON` / `GENTLY_HOME` at it. +3. Expect a multi-GB artifact (torch/CUDA dominate) and plan auto-update + accordingly. + +The Job-Object ownership and boot/navigate flow are unchanged by bundling — only +*where Python comes from* changes. diff --git a/desktop/icons/source.png b/desktop/icons/source.png new file mode 100644 index 0000000000000000000000000000000000000000..8f2af46c523ca4713ffa2ced8024e669a161af1e GIT binary patch literal 5157 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 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.11.4", + "@tauri-apps/cli-darwin-x64": "2.11.4", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.4", + "@tauri-apps/cli-linux-arm64-gnu": "2.11.4", + "@tauri-apps/cli-linux-arm64-musl": "2.11.4", + "@tauri-apps/cli-linux-riscv64-gnu": "2.11.4", + "@tauri-apps/cli-linux-x64-gnu": "2.11.4", + "@tauri-apps/cli-linux-x64-musl": "2.11.4", + "@tauri-apps/cli-win32-arm64-msvc": "2.11.4", + "@tauri-apps/cli-win32-ia32-msvc": "2.11.4", + "@tauri-apps/cli-win32-x64-msvc": "2.11.4" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.4.tgz", + "integrity": "sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.4.tgz", + "integrity": "sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.4.tgz", + "integrity": "sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.4.tgz", + "integrity": "sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.4.tgz", + "integrity": "sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.4.tgz", + "integrity": "sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.4.tgz", + "integrity": "sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.4.tgz", + "integrity": "sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.4.tgz", + "integrity": "sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.4.tgz", + "integrity": "sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.4.tgz", + "integrity": "sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + } + } +} diff --git a/desktop/package.json b/desktop/package.json new file mode 100644 index 00000000..7c30a7fe --- /dev/null +++ b/desktop/package.json @@ -0,0 +1,12 @@ +{ + "name": "gently-desktop", + "version": "0.1.0", + "private": true, + "description": "Tauri desktop shell for gently (owns the Python backend + device layer)", + "scripts": { + "tauri": "tauri" + }, + "devDependencies": { + "@tauri-apps/cli": "^2.11.4" + } +} diff --git a/desktop/splash/index.html b/desktop/splash/index.html new file mode 100644 index 00000000..f7bb3357 --- /dev/null +++ b/desktop/splash/index.html @@ -0,0 +1,51 @@ + + + + + +Gently + + + + +
+
Gently
+
+
Starting the backend…
+
microscopy agent · desktop
+ + + diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock new file mode 100644 index 00000000..27a8fbb4 --- /dev/null +++ b/desktop/src-tauri/Cargo.lock @@ -0,0 +1,4433 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" + +[[package]] +name = "atk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "brotli" +version = "8.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +dependencies = [ + "serde", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.13.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "camino" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2d30e4173c4026932d51d31d6b0613b1fd3014bf3f9f8943d4ba139c437ba0" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link 0.2.1", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" +dependencies = [ + "bitflags 2.13.0", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.13.0", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.118", +] + +[[package]] +name = "ctor" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" +dependencies = [ + "ctor-proc-macro", + "dtor", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "dbus" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab69f03cc8c4340c9c8e315114e1658e6775a9b16a04357973aa21cec22b32e" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.118", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.0", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "dlopen2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "dom_query" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +dependencies = [ + "bit-set", + "cssparser", + "foldhash", + "html5ever", + "precomputed-hash", + "selectors", + "tendril", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +dependencies = [ + "serde", +] + +[[package]] +name = "dtoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dtor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "embed-resource" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbfdaacccebec3b28e4866b8973543c7647797db5ada1bdab552e48fe665fbbd" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 1.1.2+spec-1.1.0", + "vswhom", + "winreg", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gently-desktop" +version = "0.1.0" +dependencies = [ + "tauri", + "tauri-build", + "windows 0.62.2", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.13.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.2", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +dependencies = [ + "log", + "markup5ever", +] + +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" +dependencies = [ + "byteorder", + "png 0.17.16", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "infer" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +dependencies = [ + "cfb", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.118", +] + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.13.0", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "libappindicator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" +dependencies = [ + "libc", +] + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "markup5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +dependencies = [ + "log", + "tendril", + "web_atoms", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "muda" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "once_cell", + "png 0.18.1", + "serde", + "thiserror 2.0.18", + "windows-sys 0.61.2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.0", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.13.0", + "block2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.13.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.13.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.0", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.13.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.13.0", + "block2", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.0", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation", + "objc2-quartz-core", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-web-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" +dependencies = [ + "bitflags 2.13.0", + "block2", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_codegen" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plist" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da1d65da6dd5d1e44199ac0f58712d241c0f439f80adea8924d832384087f85" +dependencies = [ + "base64 0.22.1", + "indexmap 2.14.0", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.13.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.12+spec-1.1.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.0", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "regex" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", + "url", + "uuid", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.118", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +dependencies = [ + "bitflags 2.13.0", + "cssparser", + "derive_more", + "log", + "new_debug_unreachable", + "phf", + "phf_codegen", + "precomputed-hash", + "rustc-hash", + "servo_arc", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_with" +version = "3.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" +dependencies = [ + "base64 0.22.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "servo_arc" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "softbuffer" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" +dependencies = [ + "bytemuck", + "js-sys", + "ndk", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "redox_syscall", + "tracing", + "wasm-bindgen", + "web-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "string_cache" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "string_cache_codegen" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "swift-rs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.35.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" +dependencies = [ + "bitflags 2.13.0", + "block2", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dbus", + "dispatch2", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "jni", + "libc", + "log", + "ndk", + "ndk-sys", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "once_cell", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "tao-macros", + "unicode-segmentation", + "url", + "windows 0.61.3", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tauri" +version = "2.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "667b20e2726d572dea2de7370da16e188eb06008faf9a92fab7cdc46791190b5" +dependencies = [ + "anyhow", + "bytes", + "cookie", + "dirs", + "dunce", + "embed_plist", + "getrandom 0.3.4", + "glob", + "gtk", + "heck 0.5.0", + "http", + "jni", + "libc", + "log", + "mime", + "muda", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "percent-encoding", + "plist", + "raw-window-handle", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "swift-rs", + "tauri-build", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "thiserror 2.0.18", + "tokio", + "tray-icon", + "url", + "webkit2gtk", + "webview2-com", + "window-vibrancy", + "windows 0.61.3", +] + +[[package]] +name = "tauri-build" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9ce40b16101cb6ea63d3e221567affd1c3a9205f95d7bc574941a10636b632" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08279169ff42f8fc45a1dbc9dcae888893ba95288142e5880c59b93a26d2cfc5" +dependencies = [ + "base64 0.22.1", + "brotli", + "ico", + "json-patch", + "plist", + "png 0.17.16", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "sha2", + "syn 2.0.118", + "tauri-utils", + "thiserror 2.0.18", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8b394794f399a421811d06966343e7933fcae92d59f5180b9388d1174497a45" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.118", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-runtime" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b4bc95aed361b0019067d189a1174a603d460d0f6c72606512d59fc9c12ec8" +dependencies = [ + "cookie", + "dpi", + "gtk", + "http", + "jni", + "objc2", + "objc2-ui-kit", + "objc2-web-kit", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 2.0.18", + "url", + "webkit2gtk", + "webview2-com", + "windows 0.61.3", +] + +[[package]] +name = "tauri-runtime-wry" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f" +dependencies = [ + "gtk", + "http", + "jni", + "log", + "objc2", + "objc2-app-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "softbuffer", + "tao", + "tauri-runtime", + "tauri-utils", + "url", + "webkit2gtk", + "webview2-com", + "windows 0.61.3", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "2.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e176a18e67764923c4f1ce66f25ae4abe5f688384d5eb1a0fa6c77f3d90f887" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dom_query", + "dunce", + "glob", + "http", + "infer", + "json-patch", + "log", + "memchr", + "phf", + "plist", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.18", + "toml 1.1.2+spec-1.1.0", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc65d45c68858bfe420dd29e834b5d15dbecf8a07a8a16cf4d532c7b1f69d4b6" +dependencies = [ + "dunce", + "embed-resource", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "tendril" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fed54709c5b3a53d09bb1c113ea4f5ceafd1e772ddcb0030a82e1d56c087b08" +dependencies = [ + "new_debug_unreachable", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "time" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.14.0", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap 2.14.0", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.14.0", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.25.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.3", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.0", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tray-icon" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65ba1e5f6b9ef9fd87e21b9c6f351554dbd717960089168fcfdef854686961dc" +dependencies = [ + "crossbeam-channel", + "dirs", + "libappindicator", + "muda", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "once_cell", + "png 0.18.1", + "serde", + "thiserror 2.0.18", + "windows-sys 0.61.2", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlpattern" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +dependencies = [ + "regex", + "serde", + "unic-ucd-ident", + "url", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.118", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web_atoms" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297" +dependencies = [ + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webview2-com" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.61.3", + "windows-core 0.61.2", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "webview2-com-sys" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" +dependencies = [ + "thiserror 2.0.18", + "windows 0.61.3", + "windows-core 0.61.2", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window-vibrancy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +dependencies = [ + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "windows-sys 0.59.0", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections 0.2.0", + "windows-core 0.61.2", + "windows-future 0.2.1", + "windows-link 0.1.3", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading 0.1.0", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "wry" +version = "0.55.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" +dependencies = [ + "base64 0.22.1", + "block2", + "cookie", + "crossbeam-channel", + "dirs", + "dom_query", + "dpi", + "dunce", + "gdkx11", + "gtk", + "http", + "javascriptcore-rs", + "jni", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 2.0.18", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.61.3", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml new file mode 100644 index 00000000..6d85d560 --- /dev/null +++ b/desktop/src-tauri/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "gently-desktop" +version = "0.1.0" +edition = "2021" +description = "Gently desktop shell — owns the Python backend + device layer" +authors = ["gently"] +default-run = "gently-desktop" + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2" } + +# Windows Job Object: put the spawned Python (and its device-layer grandchild) +# in a kill-on-close job so the whole tree dies when the shell exits or crashes. +[target.'cfg(windows)'.dependencies] +windows = { version = "0.62", features = [ + "Win32_Foundation", + "Win32_System_JobObjects", + "Win32_System_Threading", + "Win32_Security", +] } + +[profile.release] +codegen-units = 1 +lto = true +opt-level = "s" +strip = true diff --git a/desktop/src-tauri/build.rs b/desktop/src-tauri/build.rs new file mode 100644 index 00000000..d860e1e6 --- /dev/null +++ b/desktop/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/desktop/src-tauri/capabilities/default.json b/desktop/src-tauri/capabilities/default.json new file mode 100644 index 00000000..c1da0cbb --- /dev/null +++ b/desktop/src-tauri/capabilities/default.json @@ -0,0 +1,7 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Thin shell — the UI is served by the Python backend and makes no Tauri IPC calls. Navigation is driven from Rust, so no window/shell permissions are needed.", + "windows": ["main"], + "permissions": ["core:default"] +} diff --git a/desktop/src-tauri/icons/128x128.png b/desktop/src-tauri/icons/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..28f09f10c15d3315ce11b14a3da2d0bc054da8ba GIT binary patch literal 8161 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 Hu0mjfyA8== literal 0 HcmV?d00001 diff --git a/desktop/src-tauri/icons/128x128@2x.png b/desktop/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ceff7febcabe0dfb1be7047f8a3500403c37b7e7 GIT binary patch literal 15932 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 literal 0 HcmV?d00001 diff --git a/desktop/src-tauri/icons/32x32.png b/desktop/src-tauri/icons/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..777c4bb931f38aada11883c2b61c1d3b2da27151 GIT binary patch literal 1623 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 literal 0 HcmV?d00001 diff --git a/desktop/src-tauri/icons/icon.icns b/desktop/src-tauri/icons/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..f0a19c15bd28fbd964aee8aa621b1746bb2c27a2 GIT binary patch literal 128538 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

Gb_S>PoI?03P%&BRt zFQdz#a7)ygeKasnBAbr&-b4_ohMwxzm<=GE_2%|1^5rFtLFO8p=V$fY93Lj+`Pn}| zH0Z`Qq$zgOToYBMXCA52Rds{Z%R9@!|5t1quD1ElG}y{ZyabLOLXug*9}F?A`vUXxMPdmvlWNgVMCf(}d_{VBLo(FU5<+>8)& zrf$|RZZu@(!eMWa^vKV;10C7nG>wD54owvvI4dfniD2rCZ+>QrzW%zZirxLS{brDy ze5f?g_46b9zj}=s^XCQ%p#j4s0eI)2$L=tJmzPeR(~7A=k>H&Am{ON=RMvaUku&Jw zb%zJfdE#$Z2c). The whole +// UI is served by Python — this shell holds no application logic. +// +// Process ownership: the Python child spawns its own device-layer grandchild +// (via DeviceLayerSupervisor). To guarantee no orphans, on Windows we put the +// spawned Python into a Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; +// children inherit the job, so when this shell exits or crashes the OS reaps the +// entire tree. See docs/superpowers/specs/2026-07-02-unified-launcher-design.md. +// +// Deferred (documented): bundling the Python environment for a redistributable +// installer (embeddable Python / PyInstaller sidecar), and a graceful backend +// shutdown handshake before the job hard-kills the tree. + +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +use std::path::{Path, PathBuf}; +use std::process::{Child, Command}; +use std::sync::Mutex; +use std::time::{Duration, Instant}; + +use tauri::{Manager, RunEvent}; + +/// Backend process + (Windows) the job that owns its tree, held for the app's +/// whole lifetime as Tauri managed state. +struct Backend { + child: Mutex>, + #[cfg(windows)] + job: jobkill::Job, +} + +fn main() { + #[cfg(windows)] + let job = jobkill::create_kill_on_close().expect("failed to create Job Object"); + + let backend = Backend { + child: Mutex::new(None), + #[cfg(windows)] + job, + }; + + tauri::Builder::default() + .manage(backend) + .setup(|app| { + let handle = app.handle().clone(); + // Boot the backend off the UI thread so the splash paints immediately. + std::thread::spawn(move || boot_backend(handle)); + Ok(()) + }) + .build(tauri::generate_context!()) + .expect("error building the Gently desktop app") + .run(|app_handle, event| { + if let RunEvent::Exit = event { + let b = app_handle.state::(); + // Best-effort direct kill of the child we spawned... + if let Some(mut child) = b.child.lock().unwrap().take() { + let _ = child.kill(); + } + // ...and close the job handle, which kill-on-close uses to reap + // the whole tree (python + device-layer grandchild). Correct even + // if the child kill above missed a grandchild. + #[cfg(windows)] + jobkill::close(&b.job); + } + }); +} + +/// Spawn the Python backend, wait for its server, then navigate the window to it. +fn boot_backend(app: tauri::AppHandle) { + let repo = repo_root(); + let python = python_exe(&repo); + + let mut args: Vec = vec!["launch_gently.py".into(), "--no-browser".into()]; + if let Ok(extra) = std::env::var("GENTLY_LAUNCH_ARGS") { + args.extend(extra.split_whitespace().map(str::to_string)); + } + + set_status(&app, "Starting the backend…"); + eprintln!("[gently-desktop] spawning: {} {:?} (cwd={})", python.display(), args, repo.display()); + + let child = match Command::new(&python).args(&args).current_dir(&repo).spawn() { + Ok(c) => c, + Err(e) => { + set_status(&app, &format!("Failed to start backend: {e}")); + eprintln!("[gently-desktop] spawn failed: {e}"); + return; + } + }; + + // Put the child in our kill-on-close job so its tree can't outlive us. + #[cfg(windows)] + { + let b = app.state::(); + if let Err(e) = jobkill::assign(&b.job, &child) { + eprintln!("[gently-desktop] job assign failed (continuing): {e:?}"); + } + } + *app.state::().child.lock().unwrap() = Some(child); + + let port = viz_port(); + set_status(&app, "Waiting for the server…"); + if wait_for_port("127.0.0.1", port, 120) { + let url = format!("http://localhost:{port}"); + eprintln!("[gently-desktop] backend up — navigating to {url}"); + if let Some(win) = app.get_webview_window("main") { + match url.parse() { + Ok(u) => { let _ = win.navigate(u); } + Err(e) => set_status(&app, &format!("Bad backend URL: {e}")), + } + } + } else { + set_status(&app, "Backend did not become ready in time. Check the terminal log."); + eprintln!("[gently-desktop] timed out waiting for 127.0.0.1:{port}"); + } +} + +/// Repo root: `GENTLY_HOME` override, else the compile-time project root +/// (desktop/src-tauri/../..). The compile-time path is correct for `tauri dev` +/// and for a build run on this machine; a redistributable build should set +/// `GENTLY_HOME` (or bundle Python — see the module header). +fn repo_root() -> PathBuf { + if let Ok(p) = std::env::var("GENTLY_HOME") { + return PathBuf::from(p); + } + let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let root = manifest.join("..").join(".."); + std::fs::canonicalize(&root).unwrap_or(root) +} + +/// Python interpreter: `GENTLY_PYTHON` override, else the repo venv, else PATH. +fn python_exe(repo: &Path) -> PathBuf { + if let Ok(p) = std::env::var("GENTLY_PYTHON") { + return PathBuf::from(p); + } + let venv = repo.join(".venv").join("Scripts").join("python.exe"); + if venv.exists() { + venv + } else { + PathBuf::from("python") + } +} + +/// Viz port — mirrors the backend's `VIZ_PORT` env (default 8080). +fn viz_port() -> u16 { + std::env::var("VIZ_PORT") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(8080) +} + +/// Poll a TCP port until something accepts, or `secs` elapse. +fn wait_for_port(host: &str, port: u16, secs: u64) -> bool { + use std::net::TcpStream; + let addr: std::net::SocketAddr = match format!("{host}:{port}").parse() { + Ok(a) => a, + Err(_) => return false, + }; + let deadline = Instant::now() + Duration::from_secs(secs); + while Instant::now() < deadline { + if TcpStream::connect_timeout(&addr, Duration::from_millis(800)).is_ok() { + return true; + } + std::thread::sleep(Duration::from_millis(700)); + } + false +} + +/// Update the splash status line via the JS hook it exposes. +fn set_status(app: &tauri::AppHandle, msg: &str) { + if let Some(win) = app.get_webview_window("main") { + let safe = msg.replace('\\', "\\\\").replace('\'', "\\'"); + let js = format!("window.__gentlyStatus && window.__gentlyStatus('{safe}')"); + let _ = win.eval(js.as_str()); + } +} + +/// Windows Job Object helper — kill-on-close ownership of the backend tree. +#[cfg(windows)] +mod jobkill { + use std::ffi::c_void; + use std::os::windows::io::AsRawHandle; + use std::process::Child; + + use windows::Win32::Foundation::{CloseHandle, HANDLE}; + use windows::Win32::System::JobObjects::{ + AssignProcessToJobObject, CreateJobObjectW, SetInformationJobObject, + JobObjectExtendedLimitInformation, JOBOBJECT_EXTENDED_LIMIT_INFORMATION, + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, + }; + + /// Owns a job HANDLE. `Send`/`Sync` so it can live in Tauri managed state; + /// the handle is only touched from create/assign/close. + pub struct Job(pub HANDLE); + unsafe impl Send for Job {} + unsafe impl Sync for Job {} + + pub fn create_kill_on_close() -> windows::core::Result { + unsafe { + let job = CreateJobObjectW(None, None)?; + let mut info = JOBOBJECT_EXTENDED_LIMIT_INFORMATION::default(); + info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + SetInformationJobObject( + job, + JobObjectExtendedLimitInformation, + &info as *const _ as *const c_void, + std::mem::size_of::() as u32, + )?; + Ok(Job(job)) + } + } + + /// Assign a freshly-spawned child to the job. Its own children inherit the + /// job (Windows default), so grandchildren are covered too. + pub fn assign(job: &Job, child: &Child) -> windows::core::Result<()> { + unsafe { AssignProcessToJobObject(job.0, HANDLE(child.as_raw_handle())) } + } + + /// Close the job handle. With kill-on-close, this terminates every process + /// still in the job. + pub fn close(job: &Job) { + unsafe { + let _ = CloseHandle(job.0); + } + } +} diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json new file mode 100644 index 00000000..d7dc638e --- /dev/null +++ b/desktop/src-tauri/tauri.conf.json @@ -0,0 +1,38 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "productName": "Gently", + "version": "0.1.0", + "identifier": "org.janelia.gently.desktop", + "build": { + "frontendDist": "../splash" + }, + "app": { + "windows": [ + { + "label": "main", + "title": "Gently", + "width": 1440, + "height": 920, + "minWidth": 900, + "minHeight": 600, + "resizable": true, + "visible": true, + "center": true + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": ["nsis"], + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } +} diff --git a/gently/app/device_supervisor.py b/gently/app/device_supervisor.py index 5f7c01a7..0ec52747 100644 --- a/gently/app/device_supervisor.py +++ b/gently/app/device_supervisor.py @@ -27,6 +27,7 @@ import atexit import logging +import os import signal import socket import subprocess @@ -104,8 +105,12 @@ def start(self, *, sam_device: str | None = None, config_path: str | None = None ) return self._status_locked() - if not _DEVICE_SCRIPT.exists(): - raise FileNotFoundError(f"device layer script not found: {_DEVICE_SCRIPT}") + # GENTLY_DEVICE_LAYER_SCRIPT overrides the launcher — lets an operator + # point at an alternate device-layer entry point (and lets tests point + # at a harmless stand-in instead of touching real hardware). + script = Path(os.environ.get("GENTLY_DEVICE_LAYER_SCRIPT") or _DEVICE_SCRIPT) + if not script.exists(): + raise FileNotFoundError(f"device layer script not found: {script}") if sam_device is not None: self.sam_device = sam_device @@ -114,7 +119,7 @@ def start(self, *, sam_device: str | None = None, config_path: str | None = None cmd = [ sys.executable, - str(_DEVICE_SCRIPT), + str(script), "--port", str(self.port), "--sam-device", diff --git a/gently/ui/web/static/css/main.css b/gently/ui/web/static/css/main.css index 2c7751aa..01115260 100644 --- a/gently/ui/web/static/css/main.css +++ b/gently/ui/web/static/css/main.css @@ -9427,6 +9427,54 @@ body.modal-open { .devices-status-pill.stale { background: rgba(210, 153, 34, 0.2); color: var(--accent-orange, #d29922); } .devices-status-pill.error { background: rgba(248, 81, 73, 0.2); color: #f85149; } +/* Device-layer supervision card (device-layer.js) */ +.devices-layer-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 6px; + padding: 0.6rem 0.9rem; + margin: 0.75rem 0 0.25rem; +} +.devices-layer-head { + display: flex; + align-items: center; + gap: 0.6rem; + flex-wrap: wrap; +} +.devices-layer-head .devices-card-title { margin-bottom: 0; } +.devices-layer-meta { + font-family: 'SF Mono', 'Consolas', monospace; + font-size: 0.72rem; + color: var(--text-muted); + font-variant-numeric: tabular-nums; +} +.devices-layer-hint { + font-size: 0.72rem; + color: var(--text-muted); +} +.devices-layer-actions { + display: flex; + align-items: center; + gap: 0.4rem; + margin-top: 0.55rem; + flex-wrap: wrap; +} +.devices-layer-log { + margin: 0.55rem 0 0; + padding: 0.5rem 0.65rem; + max-height: 220px; + overflow: auto; + background: var(--bg-hover); + border: 1px solid var(--border); + border-radius: 5px; + font-family: 'SF Mono', 'Consolas', monospace; + font-size: 0.7rem; + line-height: 1.5; + color: var(--text-muted); + white-space: pre-wrap; + word-break: break-word; +} + .devices-positions { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); diff --git a/gently/ui/web/static/js/device-layer.js b/gently/ui/web/static/js/device-layer.js new file mode 100644 index 00000000..f3551be3 --- /dev/null +++ b/gently/ui/web/static/js/device-layer.js @@ -0,0 +1,242 @@ +/** + * Device-layer supervision card (Devices tab). + * + * The runtime mirror of the launch gate's hardware block: shows whether the + * device layer is running / stopped / external / crashed, lets an operator + * Start or Stop it from the UI, and tails its console. Consumes the routes + * added in gently/ui/web/routes/device_layer.py: + * + * GET /api/device-layer/status -> {state, managed, pid, port, port_open, + * sam_device, uptime_seconds, log_tail[]} + * GET /api/device-layer/log?limit=N -> {lines: [...]} + * POST /api/device-layer/start (control-gated) body {sam_device?, config_path?} + * POST /api/device-layer/stop (control-gated) body {confirm?, force?} + * -> 409 {blocked:true,...} mid-acquisition + * + * Self-contained IIFE (no devices.js internals). Polls only while the Devices + * tab is visible (ClientEventBus 'TAB_CHANGED'). Control auth is transparent: + * a same-origin fetch carries the gently_session cookie, and control-auth.js + * already toasts on a bare 403, so Start/Stop need no credential code. + */ +const DeviceLayerCard = (function () { + const POLL_MS = 5000; + + // state -> [pill modifier class, label]. Mirrors the header pill states. + const PILL = { + running: ['live', 'running'], + external: ['paused', 'external'], + stopped: ['', 'stopped'], + crashed: ['error', 'crashed'], + }; + + let _card, _pill, _meta, _start, _stop, _logToggle, _log, _hint; + let _timer = null; + let _busy = false; // a start/stop is in flight + let _dom = false; + + function cacheDom() { + if (_dom) return; + _card = document.getElementById('devices-layer-card'); + if (!_card) return; // markup absent -> stay inert + _pill = document.getElementById('devices-layer-pill'); + _meta = document.getElementById('devices-layer-meta'); + _start = document.getElementById('devices-layer-start'); + _stop = document.getElementById('devices-layer-stop'); + _logToggle = document.getElementById('devices-layer-log-toggle'); + _log = document.getElementById('devices-layer-log'); + _hint = document.getElementById('devices-layer-hint'); + _dom = true; + } + + function init() { + cacheDom(); + if (!_card) return; + _start.addEventListener('click', onStart); + _stop.addEventListener('click', onStop); + _logToggle.addEventListener('click', toggleLog); + + // Poll only while the Devices tab is showing. switchTab() emits + // TAB_CHANGED with the *new* tab id (no leave signal), so compare + // against TABS.DEVICES to derive both enter and exit. + if (typeof ClientEventBus !== 'undefined') { + ClientEventBus.on('TAB_CHANGED', (tab) => { + if (tab === TABS.DEVICES) startPoll(); + else stopPoll(); + }); + } + // Seed if Devices is already the active tab (reload / deep link) — + // TAB_CHANGED does not fire for the landing tab. + const content = document.getElementById('devices-content'); + if (content && content.classList.contains('active')) startPoll(); + } + + // ── polling ────────────────────────────────────────────────────────── + + function startPoll() { + loadStatus(); // immediate + if (_timer) clearInterval(_timer); // clear-before-set + _timer = setInterval(loadStatus, POLL_MS); + } + + function stopPoll() { + if (_timer) { clearInterval(_timer); _timer = null; } + } + + async function loadStatus() { + if (!_card) return; + try { + const res = await fetch('/api/device-layer/status'); + if (!res.ok) return; // keep last-known UI + apply(await res.json()); + } catch (e) { + console.debug('device-layer status poll failed', e); + } + } + + // ── render ─────────────────────────────────────────────────────────── + + function apply(d) { + _card.hidden = false; + const [mod, label] = PILL[d.state] || ['stale', d.state || 'unknown']; + _pill.className = 'devices-status-pill' + (mod ? ' ' + mod : ''); + _pill.textContent = label; + + const bits = []; + if (d.pid) bits.push('pid ' + d.pid); + if (d.port) bits.push('port ' + d.port + (d.port_open ? '' : ' · closed')); + if (d.sam_device) bits.push(d.sam_device); + if (typeof d.uptime_seconds === 'number') bits.push('up ' + fmtUptime(d.uptime_seconds)); + _meta.textContent = bits.join(' · '); + + // An external (unmanaged) layer can't be started or stopped by us. + if (d.state === 'external') { + _hint.hidden = false; + _hint.textContent = 'running externally — not managed by gently'; + } else { + _hint.hidden = true; + _hint.textContent = ''; + } + + // Enable/disable by state (a hint only; the server 403/409 is the real + // gate). While a start/stop is in flight, keep both disabled. + const running = d.state === 'running'; + const external = d.state === 'external'; + const stoppedish = d.state === 'stopped' || d.state === 'crashed'; + _start.disabled = _busy || running || external; + _stop.disabled = _busy || stoppedish || external; + + if (Array.isArray(d.log_tail) && d.log_tail.length && !_log.hidden) { + renderLog(d.log_tail); + } + } + + function fmtUptime(s) { + s = Math.max(0, Math.floor(s)); + if (s < 60) return s + 's'; + if (s < 3600) return Math.floor(s / 60) + 'm ' + (s % 60) + 's'; + return Math.floor(s / 3600) + 'h ' + Math.floor((s % 3600) / 60) + 'm'; + } + + // ── start / stop ───────────────────────────────────────────────────── + + async function onStart() { + if (_start.disabled) return; + _busy = true; + _start.disabled = true; + try { + await postJSON('/api/device-layer/start', {}); + toast('Device layer starting…'); + } catch (e) { + // 403 already surfaced by control-auth.js; don't double-toast. + if (e.status !== 403) toast('Start failed: ' + e.message); + } finally { + _busy = false; + // The layer takes a moment to bind its port; re-poll shortly. + setTimeout(loadStatus, 800); + loadStatus(); + } + } + + async function onStop() { + if (_stop.disabled) return; + if (!window.confirm('Stop the device layer?')) return; + _busy = true; + _stop.disabled = true; + try { + await postJSON('/api/device-layer/stop', { confirm: true }); + toast('Device layer stopping…'); + } catch (e) { + if (e.status === 409 && e.payload && e.payload.blocked) { + // Mid-acquisition soft block — offer an explicit force-stop. + if (window.confirm('A run is active. Force-stop the device layer anyway?')) { + try { + await postJSON('/api/device-layer/stop', { confirm: true, force: true }); + toast('Force-stopping…'); + } catch (e2) { + if (e2.status !== 403) toast('Force-stop failed: ' + e2.message); + } + } + } else if (e.status !== 403) { + toast('Stop failed: ' + e.message); + } + } finally { + _busy = false; + setTimeout(loadStatus, 500); + loadStatus(); + } + } + + // POST JSON; on !ok throw an Error carrying .status and parsed .payload so + // callers can branch on 409/403 (mirrors operate.js's postJSON convention). + async function postJSON(url, body) { + const res = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + }); + if (!res.ok) { + let payload = {}; + try { payload = await res.json(); } catch (_) { /* non-JSON */ } + const err = new Error(payload.error || payload.reason || res.statusText); + err.status = res.status; + err.payload = payload; + throw err; + } + return res.json(); + } + + // ── log tail ───────────────────────────────────────────────────────── + + function toggleLog() { + const show = _log.hidden; + _log.hidden = !show; + _logToggle.setAttribute('aria-expanded', String(show)); + _logToggle.classList.toggle('active', show); + if (show) loadFullLog(); + } + + async function loadFullLog() { + try { + const res = await fetch('/api/device-layer/log?limit=200'); + if (!res.ok) return; + const d = await res.json(); + if (Array.isArray(d.lines)) renderLog(d.lines); + } catch (e) { + console.debug('device-layer log fetch failed', e); + } + } + + function renderLog(lines) { + if (!_log) return; + _log.textContent = lines.join('\n'); + _log.scrollTop = _log.scrollHeight; // pin to newest + } + + function toast(msg) { + if (typeof showGentlyToast === 'function') showGentlyToast(msg); + } + + return { init }; +})(); + +document.addEventListener('DOMContentLoaded', () => DeviceLayerCard.init()); diff --git a/gently/ui/web/templates/index.html b/gently/ui/web/templates/index.html index af177670..8ad9cba4 100644 --- a/gently/ui/web/templates/index.html +++ b/gently/ui/web/templates/index.html @@ -484,6 +484,26 @@

Device + + +