From 43a10fcbb8345b8a7c171692009f69a27520a321 Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:21 +0000 Subject: [PATCH 01/13] feat(desktop): scaffold Tauri desktop shell + slim API sidecar packaging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foundation for packaging OpenKB as a desktop app for non-technical users. The architecture is a thin Tauri (Rust) shell that spawns the openkb-api server (from #150) frozen into a slim, self-contained PyInstaller sidecar, then points the system WebView at it over localhost. desktop/packaging/ — freezes openkb.api:main into a slim onedir binary: - pyi_rthook_magika.py: runtime hook stubbing magika so markitdown converts Office/HTML by file extension, letting the build exclude magika + onnxruntime entirely. - prune_litellm_proxy.py: post-build removal of the unused LiteLLM Proxy Server (static/data assets no client code path imports). - build_sidecar.sh: the PyInstaller recipe wiring both together. - sidecar_entry.py: frozen entry mirroring the openkb-api console script. desktop/src-tauri/ — reference Tauri v2 shell: spawns the sidecar, shows a splash while polling its health, navigates the WebView to it, kills it on exit. PyInstaller onedir output is bundled as a resource directory (not externalBin, which expects a single file). Verified (x86_64 Linux): the frozen slim sidecar boots uvicorn and serves GET /api/v1/kbs -> 200; ≈134 MB compressed / 338 MB on disk. The src-tauri shell is a skeleton, not compiled here (the dev container lacks webkit2gtk); build it where the platform WebView libraries are present. See desktop/README.md. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/.gitignore | 8 ++ desktop/README.md | 90 ++++++++++++++++++++++ desktop/packaging/build_sidecar.sh | 38 ++++++++++ desktop/packaging/prune_litellm_proxy.py | 51 +++++++++++++ desktop/packaging/pyi_rthook_magika.py | 39 ++++++++++ desktop/packaging/sidecar_entry.py | 11 +++ desktop/src-tauri/Cargo.toml | 15 ++++ desktop/src-tauri/build.rs | 3 + desktop/src-tauri/splash/index.html | 32 ++++++++ desktop/src-tauri/src/main.rs | 97 ++++++++++++++++++++++++ desktop/src-tauri/tauri.conf.json | 31 ++++++++ 11 files changed, 415 insertions(+) create mode 100644 desktop/.gitignore create mode 100644 desktop/README.md create mode 100755 desktop/packaging/build_sidecar.sh create mode 100644 desktop/packaging/prune_litellm_proxy.py create mode 100644 desktop/packaging/pyi_rthook_magika.py create mode 100644 desktop/packaging/sidecar_entry.py create mode 100644 desktop/src-tauri/Cargo.toml create mode 100644 desktop/src-tauri/build.rs create mode 100644 desktop/src-tauri/splash/index.html create mode 100644 desktop/src-tauri/src/main.rs create mode 100644 desktop/src-tauri/tauri.conf.json diff --git a/desktop/.gitignore b/desktop/.gitignore new file mode 100644 index 00000000..970032a7 --- /dev/null +++ b/desktop/.gitignore @@ -0,0 +1,8 @@ +# PyInstaller sidecar build artifacts +packaging/build/ +packaging/dist/ +packaging/*.spec + +# Tauri / Rust build artifacts +src-tauri/target/ +src-tauri/gen/ diff --git a/desktop/README.md b/desktop/README.md new file mode 100644 index 00000000..c6d3122d --- /dev/null +++ b/desktop/README.md @@ -0,0 +1,90 @@ +# OpenKB Desktop (Tauri) + +A desktop app that wraps OpenKB for non-technical users: no `pip`, no terminal. +It is a thin [Tauri](https://tauri.app) (Rust) shell around two things OpenKB +already produces: + +1. **The API sidecar** — `openkb-api` (the FastAPI server from the Knowledge + Workbench, `openkb.api:main`) frozen into a self-contained binary with + PyInstaller. It serves both the JSON/SSE API and the built web UI. +2. **The web UI** — the `frontend/` Vite SPA, served by the sidecar at `/`. + +``` +┌─────────────────────────────────────────────┐ +│ Tauri shell (Rust + system WebView) │ +│ │ +│ spawns ──▶ openkb-api-sidecar (frozen) │ +│ ├─ FastAPI /api/v1/* │ +│ └─ web UI / │ +│ WebView ──▶ http://127.0.0.1:/ │ +└─────────────────────────────────────────────┘ +``` + +The user double-clicks the app; the Rust shell starts the sidecar on a +localhost port, waits until it answers, then points the WebView at it. No +browser, no port, no "server" ever surfaces to the user. + +## Why this shape + +- OpenKB's capability lives in a heavy Python stack (litellm, pageindex, + markitdown, pymupdf). Rust can't replace that, so the Python runs as a frozen + sidecar. The Rust shell is glue: window, WebView, process lifecycle, updater. +- Tauri (vs Electron) ships no Chromium — smaller download, less memory — at the + cost of using each platform's system WebView. + +## Layout + +``` +desktop/ + packaging/ # freeze the Python API into a slim sidecar binary + build_sidecar.sh # PyInstaller recipe (slim: no magika/onnxruntime) + sidecar_entry.py # frozen entry -> openkb.api:main + pyi_rthook_magika.py# runtime hook: stub magika (drops onnxruntime) + prune_litellm_proxy.py # post-build: delete the unused LiteLLM proxy server + src-tauri/ # Tauri (Rust) shell — spawns the sidecar, opens the window +``` + +## Build pipeline + +```bash +# 1. Python env with API + PyInstaller +python -m venv .venv && . .venv/bin/activate +pip install -e ".[api]" pyinstaller + +# 2. Build the web UI (its output is what the sidecar serves) +cd frontend && npm install && npm run build && cd .. + +# 3. Freeze the slim API sidecar -> desktop/packaging/dist/openkb-api-sidecar/ +PYTHON=.venv/bin/python desktop/packaging/build_sidecar.sh + +# 4. Build the Tauri app (bundles the sidecar + opens the WebView) +cd desktop/src-tauri && cargo tauri build +``` + +## Slimming (measured, x86_64 Linux) + +The sidecar reuses the packaging work from the CLI slimming (see PR #186 for the +lazy-markitdown source change that makes it possible): + +| stage | compressed | +|---|---| +| full PyInstaller freeze | 147 MB | +| − magika / onnxruntime (stub hook) | 140 MB | +| − LiteLLM proxy server | 133 MB | + +The frozen **API sidecar** (adds FastAPI + uvicorn over the CLI baseline) +measures **≈134 MB compressed / 338 MB on disk**, verified booting uvicorn and +serving `GET /api/v1/kbs` → 200. + +`pymupdf` (PDF engine) and `pandas`/`numpy` (Excel support) are kept +deliberately — they are load-bearing for OpenKB's document formats. + +## Toolchain / status + +Full builds need, per platform: Rust + Cargo, Node + npm, a Python 3.10+ env, +and on **Linux `webkit2gtk`** (`libwebkit2gtk-4.1-dev`) for the WebView. + +**Status:** the API sidecar freeze (`packaging/`) is implemented and verified. +The `src-tauri/` shell is a reference skeleton — it is *not* compiled in the +CI/dev container used so far because `webkit2gtk` is absent there; build it on a +machine (or CI runner) that has the WebView libraries installed. diff --git a/desktop/packaging/build_sidecar.sh b/desktop/packaging/build_sidecar.sh new file mode 100755 index 00000000..0dc11ec7 --- /dev/null +++ b/desktop/packaging/build_sidecar.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# +# Build the OpenKB API sidecar: a self-contained, slimmed PyInstaller binary +# that the Tauri desktop shell spawns and talks to over localhost HTTP. +# +# Slimming (see ../README.md for measured sizes): +# - exclude magika + onnxruntime; a runtime hook stubs magika so markitdown +# still converts Office/HTML by file extension. +# - post-build prune of the unused LiteLLM Proxy Server. +# +# Prerequisites: a Python env with `pip install -e ".[api]"` and `pyinstaller`. +# Set PYTHON to that env's interpreter (default: python3). +# +# Usage: PYTHON=/path/to/venv/bin/python desktop/packaging/build_sidecar.sh +# Output: desktop/packaging/dist/openkb-api-sidecar/ +set -euo pipefail + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PYTHON="${PYTHON:-python3}" +cd "$HERE" + +rm -rf build dist openkb-api-sidecar.spec + +COLLECT=(litellm markitdown pageindex tiktoken agents openai tiktoken_ext uvicorn fastapi) +EXCLUDE=(magika onnxruntime) + +ARGS=(--onedir --name openkb-api-sidecar --noconfirm --clean --log-level=WARN) +ARGS+=(--runtime-hook "$HERE/pyi_rthook_magika.py") +for pkg in "${COLLECT[@]}"; do ARGS+=(--collect-all "$pkg"); done +for pkg in "${EXCLUDE[@]}"; do ARGS+=(--exclude-module "$pkg"); done + +echo ">>> freezing openkb-api sidecar (slim: no magika/onnxruntime)" +"$PYTHON" -m PyInstaller "${ARGS[@]}" sidecar_entry.py + +echo ">>> pruning unused litellm proxy server" +"$PYTHON" prune_litellm_proxy.py "dist/openkb-api-sidecar" + +echo ">>> done: dist/openkb-api-sidecar/openkb-api-sidecar" diff --git a/desktop/packaging/prune_litellm_proxy.py b/desktop/packaging/prune_litellm_proxy.py new file mode 100644 index 00000000..a3f1055b --- /dev/null +++ b/desktop/packaging/prune_litellm_proxy.py @@ -0,0 +1,51 @@ +"""Prune the unused LiteLLM Proxy Server from a frozen build. + +`--collect-all litellm` pulls litellm's entire *Proxy Server* (~44 MB: a +FastAPI gateway with an admin UI, swagger assets and OpenAPI snapshots), but +OpenKB only uses litellm as a client. `import litellm` loads a handful of small +proxy submodules; none of the static/data assets below are reached by any +client code path (verified: not in sys.modules after `import litellm` plus a +completion call). Deleting them from the frozen tree is safe; the sidecar smoke +test (`GET /api/v1/kbs` returns 200) confirms the client path stays intact. + +Usage: python prune_litellm_proxy.py +The frozen app dir is PyInstaller's onedir output (contains `_internal/`). +""" + +from __future__ import annotations + +import sys +from pathlib import Path + +# Static/data dead weight — never imported by a litellm *client*. +_PRUNE_DIRS = ("_experimental", "swagger") +_PRUNE_GLOBS = ("*.jpg", "*.json", "*.yaml", "*.txt", "README.md") + + +def _dir_size_mb(path: Path) -> int: + return sum(f.stat().st_size for f in path.rglob("*") if f.is_file()) // (1024 * 1024) + + +def prune(app_dir: Path) -> None: + proxy = app_dir / "_internal" / "litellm" / "proxy" + if not proxy.is_dir(): + print(f"prune_litellm_proxy: no proxy dir at {proxy}; nothing to do") + return + before = _dir_size_mb(proxy) + import shutil + + for name in _PRUNE_DIRS: + target = proxy / name + if target.exists(): + shutil.rmtree(target) + for pattern in _PRUNE_GLOBS: + for f in proxy.glob(pattern): + f.unlink() + after = _dir_size_mb(proxy) + print(f"prune_litellm_proxy: {before}M -> {after}M") + + +if __name__ == "__main__": + if len(sys.argv) != 2: + raise SystemExit("usage: python prune_litellm_proxy.py ") + prune(Path(sys.argv[1])) diff --git a/desktop/packaging/pyi_rthook_magika.py b/desktop/packaging/pyi_rthook_magika.py new file mode 100644 index 00000000..a47ba9ee --- /dev/null +++ b/desktop/packaging/pyi_rthook_magika.py @@ -0,0 +1,39 @@ +"""PyInstaller runtime hook: stub `magika` so markitdown runs without onnxruntime. + +markitdown hard-depends on magika, which loads an ONNX model via onnxruntime +(tens of MB) purely to sniff a file's type from its content. OpenKB only ever +converts real files with correct extensions, so markitdown's extension/mimetype +based stream-info guessing is sufficient and magika's content sniffing is +redundant. This hook installs a lightweight in-memory `magika` module before +markitdown imports it; `identify_stream` returns a non-"ok" status, which makes +markitdown fall back to the extension guess. Paired with +`--exclude-module magika --exclude-module onnxruntime` at build time, this drops +onnxruntime (and magika's model) from the packaged sidecar entirely. +""" + +import sys +import types + + +class _Result: + # Any status other than "ok" makes markitdown use its extension-based guess. + status = "stub" + + +class Magika: + def __init__(self, *args, **kwargs): + pass + + def identify_stream(self, *args, **kwargs): + return _Result() + + def identify_bytes(self, *args, **kwargs): + return _Result() + + def identify_path(self, *args, **kwargs): + return _Result() + + +_stub = types.ModuleType("magika") +_stub.Magika = Magika +sys.modules.setdefault("magika", _stub) diff --git a/desktop/packaging/sidecar_entry.py b/desktop/packaging/sidecar_entry.py new file mode 100644 index 00000000..13fb11c7 --- /dev/null +++ b/desktop/packaging/sidecar_entry.py @@ -0,0 +1,11 @@ +"""Frozen entry point for the OpenKB API sidecar. + +Mirrors the `openkb-api = openkb.api:main` console script. The Tauri shell +spawns the frozen binary as `openkb-api-sidecar --host 127.0.0.1 --port `; +argparse in `openkb.api.main` reads those args from sys.argv unchanged. +""" + +from openkb.api import main + +if __name__ == "__main__": + main() diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml new file mode 100644 index 00000000..eb093ed1 --- /dev/null +++ b/desktop/src-tauri/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "openkb-desktop" +version = "0.1.0" +edition = "2021" +description = "OpenKB desktop shell (Tauri) — wraps the frozen openkb-api sidecar" +license = "Apache-2.0" + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2", features = [] } +# ureq is a tiny blocking HTTP client used only to poll the sidecar's health +# endpoint during startup. Swap for anything you prefer. +ureq = "2" 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/splash/index.html b/desktop/src-tauri/splash/index.html new file mode 100644 index 00000000..3ec9ee56 --- /dev/null +++ b/desktop/src-tauri/splash/index.html @@ -0,0 +1,32 @@ + + + + + + OpenKB + + + +
+

OpenKB

+

Starting your knowledge base

+
+ + diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs new file mode 100644 index 00000000..2ef1a78b --- /dev/null +++ b/desktop/src-tauri/src/main.rs @@ -0,0 +1,97 @@ +// OpenKB desktop shell. +// +// Reference skeleton (Tauri v2). On launch it: (1) spawns the frozen +// openkb-api sidecar on a localhost port, (2) shows a splash window while +// polling the sidecar's health, (3) navigates the WebView to the sidecar once +// it answers, and (4) kills the sidecar on exit. +// +// NOTE: not compiled in the container used so far (no webkit2gtk). Build on a +// machine with the platform WebView libraries. Treat exact Tauri-v2 API details +// (navigate signature, resource path) as things to confirm against your Tauri +// version. +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +use std::process::{Child, Command}; +use std::sync::Mutex; +use std::time::{Duration, Instant}; + +use tauri::{Manager, RunEvent, Url}; + +/// Held in Tauri state so the sidecar can be killed when the app exits. +struct Sidecar(Mutex>); + +const HOST: &str = "127.0.0.1"; +const PORT: u16 = 8765; + +/// Spawn the bundled PyInstaller onedir sidecar. +/// +/// The sidecar is bundled as a resource *directory* named `sidecar` (see +/// `tauri.conf.json` `bundle.resources`), because PyInstaller onedir output is +/// a folder, not a single executable — so this can't use Tauri's `externalBin` +/// mechanism. +fn spawn_sidecar(app: &tauri::App) -> std::io::Result { + let resource_dir = app + .path() + .resource_dir() + .expect("resource dir should resolve"); + let exe_name = if cfg!(windows) { + "openkb-api-sidecar.exe" + } else { + "openkb-api-sidecar" + }; + let exe = resource_dir + .join("sidecar") + .join("openkb-api-sidecar") + .join(exe_name); + Command::new(exe) + .args(["--host", HOST, "--port", &PORT.to_string()]) + .spawn() +} + +/// Poll `url` until it answers or `timeout` elapses. +fn wait_until_ready(url: &str, timeout: Duration) -> bool { + let deadline = Instant::now() + timeout; + while Instant::now() < deadline { + if ureq::get(url) + .timeout(Duration::from_millis(500)) + .call() + .is_ok() + { + return true; + } + std::thread::sleep(Duration::from_millis(200)); + } + false +} + +fn main() { + tauri::Builder::default() + .manage(Sidecar(Mutex::new(None))) + .setup(|app| { + let child = spawn_sidecar(app)?; + app.state::().0.lock().unwrap().replace(child); + + let url = format!("http://{HOST}:{PORT}/"); + let handle = app.handle().clone(); + // Poll off the main thread so the splash window can paint. + std::thread::spawn(move || { + if wait_until_ready(&url, Duration::from_secs(30)) { + if let (Some(win), Ok(parsed)) = + (handle.get_webview_window("main"), Url::parse(&url)) + { + let _ = win.navigate(parsed); + } + } + }); + Ok(()) + }) + .build(tauri::generate_context!()) + .expect("error while building tauri app") + .run(|app_handle, event| { + if let RunEvent::Exit = event { + if let Some(mut child) = app_handle.state::().0.lock().unwrap().take() { + let _ = child.kill(); + } + } + }); +} diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json new file mode 100644 index 00000000..d03aa40d --- /dev/null +++ b/desktop/src-tauri/tauri.conf.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "OpenKB", + "version": "0.1.0", + "identifier": "ai.pageindex.openkb", + "build": { + "frontendDist": "../splash" + }, + "app": { + "windows": [ + { + "label": "main", + "title": "OpenKB", + "width": 1200, + "height": 800, + "resizable": true, + "url": "index.html" + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "all", + "resources": { + "../packaging/dist/openkb-api-sidecar": "sidecar" + } + } +} From c9b1eea19d2b9bc379d7929d1ecaa42545db0beb Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:21 +0000 Subject: [PATCH 02/13] =?UTF-8?q?fix(desktop):=20make=20the=20Tauri=20shel?= =?UTF-8?q?l=20compile=20=E2=80=94=20frontendDist=20path=20+=20app=20icons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verified by installing libwebkit2gtk-4.1-dev and running `cargo build`, which compiled the full Tauri dependency tree and surfaced two skeleton errors: - `frontendDist` pointed at "../splash" (resolves outside src-tauri) but the splash page lives at src-tauri/splash — corrected to "splash". - `generate_context!` requires a default `icons/icon.png`; added a generated app icon set (png sizes + ico). `cargo build` now finishes cleanly. Running the window still needs a display (headless container has none); the web UI itself was verified rendering end-to-end against the sidecar via headless Chromium. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/README.md | 13 +++++++++---- desktop/src-tauri/icons/128x128.png | Bin 0 -> 3632 bytes desktop/src-tauri/icons/256x256.png | Bin 0 -> 6531 bytes desktop/src-tauri/icons/32x32.png | Bin 0 -> 1062 bytes desktop/src-tauri/icons/icon.ico | Bin 0 -> 19510 bytes desktop/src-tauri/icons/icon.png | Bin 0 -> 4183 bytes desktop/src-tauri/tauri.conf.json | 2 +- 7 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 desktop/src-tauri/icons/128x128.png create mode 100644 desktop/src-tauri/icons/256x256.png create mode 100644 desktop/src-tauri/icons/32x32.png create mode 100644 desktop/src-tauri/icons/icon.ico create mode 100644 desktop/src-tauri/icons/icon.png diff --git a/desktop/README.md b/desktop/README.md index c6d3122d..b7feea05 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -84,7 +84,12 @@ deliberately — they are load-bearing for OpenKB's document formats. Full builds need, per platform: Rust + Cargo, Node + npm, a Python 3.10+ env, and on **Linux `webkit2gtk`** (`libwebkit2gtk-4.1-dev`) for the WebView. -**Status:** the API sidecar freeze (`packaging/`) is implemented and verified. -The `src-tauri/` shell is a reference skeleton — it is *not* compiled in the -CI/dev container used so far because `webkit2gtk` is absent there; build it on a -machine (or CI runner) that has the WebView libraries installed. +**Status:** +- **API sidecar** (`packaging/`) — implemented and verified: the frozen slim + binary boots uvicorn and serves `GET /api/v1/kbs` → 200. +- **Web UI** — builds (`npm run build` → `openkb/web/`) and renders end-to-end + against the sidecar (verified via headless Chromium screenshot). +- **Tauri shell** (`src-tauri/`) — **compiles** (`cargo build`, with + `libwebkit2gtk-4.1-dev` installed). *Running* the window needs a display, so + the end-to-end "double-click → window → sidecar" flow must be exercised on a + desktop machine or a display-equipped CI runner (e.g. via `xvfb`). diff --git a/desktop/src-tauri/icons/128x128.png b/desktop/src-tauri/icons/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..b2922cabfc72cb0dabc8450e181a3ef80f6f9d53 GIT binary patch literal 3632 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 pHddN#MR&2<{O60s{d9JtJM) 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 W{N(j^X*C6e0iApLu;M$m5&s2e!+B`{ 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..33b29cde7c4f5e74333c2fd10f7d5b57e877db48 GIT binary patch literal 1062 zcmV+>1ljwEP)A#kIcGmKG!O#m8Ua%&Xp{;uDiw%VTBIau(0F6~5Bx|(BZ)WlMg<`;@y3|w zjTc4|HPkNxK}kqJ(ugS<5JFojLc7vRrEYi6nVHv%v#j)EmtAS$ce9f@Z|3*RJMTM_ zg_|rj)8rF7ORFq?trlq(@iWHMFAX{v)*?suY)v1l3Gmde@tpO+yTBG5rqkDFJXt<2 z#iCSq92H*KyKTY1G=Pp>%a+w2DF+!Zxm<^u}i*d1=c6? zfw@iq=b>$>CbvM-JLnj`Bo(u}Zqu|Z*5t>8vll)0w-|;ld4|V?dv7-kj(AQDd4d{w zz9xY6uxWL`BXJ3&IIQ8)PzKUL(qbi> z)WS>>fkGq{N>C_)_f_8fvKq?3*T*bp@}6hchK!C2pB##(9l^?+=7Bpiq{}NS1$%of zsVYtlWxyEt=!b}&KF9MLLN?wPP>d(XENW5}bAT1i8j;eS+j7SqCfBX@cW2!Bf`*_XU#H0|DT@Yzx%4U zU|j%4!_hO2Bd3#0nDTDI0DeB}`KdpF(i(Ojv1pwfRewGi*D|jQ0LqKZu+Y@`t2@Hf zSzSq()NIu`k(51k**|}y0hA_R0SJ)8E}C#PFYVd0#@h(IK2!l%{m-qvBECBavvY25 zQdzu<4~!SGhZCH#Hti@ZGfM5#VW!o^6V$xE{+ARcmBq!ya}YoJ)z+qylK=oZ-@4SI zQt9`U(5b`Bte%Ir5hAkR+vvq_UT-?_AJz=oyuHwl*6T!E4w35vF-9~hue?9JW;}bS gt4rO0KOYU~UxDe8$h=vg(*OVf07*qoM6N<$g7ISm9{>OV literal 0 HcmV?d00001 diff --git a/desktop/src-tauri/icons/icon.ico b/desktop/src-tauri/icons/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..de62a5da643bf5c3977fb9d407410b5d3bba4545 GIT binary patch literal 19510 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 Mt0%Yclc3}O0=4!2LjV8( literal 0 HcmV?d00001 diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index d03aa40d..77793d11 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -4,7 +4,7 @@ "version": "0.1.0", "identifier": "ai.pageindex.openkb", "build": { - "frontendDist": "../splash" + "frontendDist": "splash" }, "app": { "windows": [ From 5209878188e8fd8d287bdc0a1ff3574fe55b117f Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:22 +0000 Subject: [PATCH 03/13] chore(desktop): track Cargo.lock for reproducible sidecar-shell builds Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/src-tauri/Cargo.lock | 4492 ++++++++++++++++++++++++++++++++++ 1 file changed, 4492 insertions(+) create mode 100644 desktop/src-tauri/Cargo.lock diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock new file mode 100644 index 00000000..0616e37a --- /dev/null +++ b/desktop/src-tauri/Cargo.lock @@ -0,0 +1,4492 @@ +# 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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +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.1", + "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.1", + "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.1", + "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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.1", + "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.119", +] + +[[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.119", +] + +[[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.3+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.119", +] + +[[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.119", +] + +[[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 = "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.1", + "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.119", +] + +[[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.119", +] + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +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.119", +] + +[[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.1", + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +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.1", + "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.119", +] + +[[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.1", + "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.1", + "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.1", + "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.1", + "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.1", + "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.1", + "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.1", + "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.1", + "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.1", + "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.1", + "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 = "openkb-desktop" +version = "0.1.0" +dependencies = [ + "tauri", + "tauri-build", + "ureq", +] + +[[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.119", +] + +[[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.1", + "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.13+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.1", +] + +[[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.119", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +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 = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[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 = "rustls" +version = "0.23.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[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.119", +] + +[[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.1", + "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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +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 = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[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.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +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.119", +] + +[[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.1", + "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", + "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.119", +] + +[[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", +] + +[[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.119", + "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.119", + "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", +] + +[[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", + "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.3+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.3+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.119", +] + +[[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.119", +] + +[[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.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee" +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.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c" +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.4", +] + +[[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.13+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.4", +] + +[[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.4", +] + +[[package]] +name = "toml_writer" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" + +[[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.1", + "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 = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +dependencies = [ + "base64 0.22.1", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "url", + "webpki-roots 0.26.11", +] + +[[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.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" +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.119", + "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 = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.8", +] + +[[package]] +name = "webpki-roots" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" +dependencies = [ + "rustls-pki-types", +] + +[[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", + "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.119", +] + +[[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", + "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", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[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-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", +] + +[[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.119", +] + +[[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.119", +] + +[[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-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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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-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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +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", + "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.119", + "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.119", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[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.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" From 54bcb05f0aff00f5d274dfc2c6cdb0561317d22a Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:22 +0000 Subject: [PATCH 04/13] feat(desktop): non-fatal sidecar spawn; verified real window renders under xvfb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the sidecar can't start (missing binary, port already in use), log and keep the window on the splash instead of aborting the whole app — better failure UX, and it lets `cargo run` dev attach to an externally-run `openkb-api`. Verified end-to-end: built the web UI, ran openkb-api on :8765, launched the Tauri binary under xvfb (WebKitGTK). The shell polled the server, navigated off the splash, and rendered the real Workbench UI — confirming the full shell → poll → navigate → render flow works. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/src-tauri/src/main.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs index 2ef1a78b..075a6629 100644 --- a/desktop/src-tauri/src/main.rs +++ b/desktop/src-tauri/src/main.rs @@ -68,8 +68,16 @@ fn main() { tauri::Builder::default() .manage(Sidecar(Mutex::new(None))) .setup(|app| { - let child = spawn_sidecar(app)?; - app.state::().0.lock().unwrap().replace(child); + // Non-fatal: if the sidecar can't start (missing binary, port in + // use), keep the window up on the splash rather than crashing the + // app. In `cargo run` dev the bundled sidecar isn't present, so + // this lets the shell attach to an externally-run `openkb-api`. + match spawn_sidecar(app) { + Ok(child) => { + app.state::().0.lock().unwrap().replace(child); + } + Err(e) => eprintln!("openkb: could not spawn sidecar: {e}"), + } let url = format!("http://{HOST}:{PORT}/"); let handle = app.handle().clone(); From b6eb142e967b7294ebd2318b5a6c3865b5ac5b1f Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:22 +0000 Subject: [PATCH 05/13] feat(web): first-launch onboarding on the OpenKB Studio frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-implements the setup wizard natively in the new (#189) React/TS frontend, using its conventions — react-i18next (common namespace, en+zh parity), shadcn Dialog/Button, and the config/kb API clients. Shown when the global config reports no LLM key (has_api_key=false): 1. Welcome. 2. Connect your model — model + API key + optional custom base URL, saved via patchGlobalConfig (RFC 7386 merge-patch; the key is only sent when typed and is never returned by the API). 3. Create your first knowledge base — createKb, then navigates to it. "Skip for now" dismisses it. Wired in App.tsx via a getGlobalConfig() check on mount. Build passes (i18n:check key-parity + no-hardcoded-CJK guard, tsc -b, vite build); verified rendering steps 1–2 via headless Chromium against a freshly-built frontend served by openkb-api. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- frontend/src/App.tsx | 12 ++ frontend/src/components/Onboarding.tsx | 181 +++++++++++++++++++++++++ frontend/src/locales/en/common.json | 21 +++ frontend/src/locales/zh/common.json | 21 +++ 4 files changed, 235 insertions(+) create mode 100644 frontend/src/components/Onboarding.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ff8dbbba..330b4deb 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -19,6 +19,8 @@ import { } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" import { getApiBase, getToken, onUnauthorized, setConnection } from "@/api/client" +import { getGlobalConfig } from "@/api/config" +import Onboarding from "@/components/Onboarding" import Home from "@/pages/Home" import ChatSession from "@/pages/ChatSession" import KbList from "@/pages/KbList" @@ -126,6 +128,7 @@ function ConnectionDialog({ export default function App() { const [authOpen, setAuthOpen] = useState(false) + const [onboardOpen, setOnboardOpen] = useState(false) const isDesktopShell = typeof (window as { __OPENKB_DESKTOP__?: unknown }).__OPENKB_DESKTOP__ !== "undefined" @@ -136,6 +139,14 @@ export default function App() { onUnauthorized(() => setAuthOpen(true)) }, []) + // First-launch onboarding: open the setup wizard when no LLM key is + // configured yet. Silent on failure (e.g. a 401 handles its own prompt). + useEffect(() => { + getGlobalConfig() + .then((c) => setOnboardOpen(!c.has_api_key)) + .catch(() => {}) + }, []) + return (
@@ -180,6 +191,7 @@ export default function App() {
+ setOnboardOpen(false)} />
diff --git a/frontend/src/components/Onboarding.tsx b/frontend/src/components/Onboarding.tsx new file mode 100644 index 00000000..169cb54a --- /dev/null +++ b/frontend/src/components/Onboarding.tsx @@ -0,0 +1,181 @@ +import { useState } from "react" +import { useNavigate } from "react-router" +import { useTranslation } from "react-i18next" +import { toast } from "sonner" +import { Sparkles, KeyRound, FolderPlus, Loader2 } from "lucide-react" +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, + DialogFooter, +} from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { patchGlobalConfig, type GlobalConfigPatch } from "@/api/config" +import { createKb } from "@/api/kb" + +const inputCls = + "mt-1.5 w-full h-9 rounded-md border border-input bg-transparent px-3 text-[13px] font-mono2 outline-none focus-visible:ring-2 focus-visible:ring-ring focus:border-accent-brand" + +/** + * First-launch setup: welcome → connect the model (patchGlobalConfig) → create + * the first knowledge base (createKb). Shown when the global config has no API + * key configured yet. "Skip for now" dismisses it. + */ +export default function Onboarding({ open, onClose }: { open: boolean; onClose: () => void }) { + const { t } = useTranslation("common") + const navigate = useNavigate() + const [step, setStep] = useState(1) + const [model, setModel] = useState("gpt-5.4") + const [apiKey, setApiKey] = useState("") + const [baseUrl, setBaseUrl] = useState("") + const [kbName, setKbName] = useState("my-kb") + const [busy, setBusy] = useState(false) + + const errText = (e: unknown) => (e instanceof Error ? e.message : String(e)) + + const saveConfig = async () => { + setBusy(true) + try { + const patch: GlobalConfigPatch = { config: { model: model.trim() } } + if (apiKey.trim()) patch.api_key = apiKey.trim() + if (baseUrl.trim()) patch.openai_api_base = baseUrl.trim() + await patchGlobalConfig(patch) + setStep(3) + } catch (e) { + toast.error(errText(e)) + } finally { + setBusy(false) + } + } + + const createFirstKb = async () => { + const name = kbName.trim() + if (!name) return + setBusy(true) + try { + await createKb({ kb: name }) + toast.success(t("onboarding.createdToast", { name })) + onClose() + navigate(`/kb/${encodeURIComponent(name)}`) + } catch (e) { + toast.error(errText(e)) + } finally { + setBusy(false) + } + } + + return ( + { + if (!v) onClose() + }} + > + + {step === 1 && ( + <> + + + + {t("onboarding.welcomeTitle")} + + {t("onboarding.welcomeBody")} + + + + + + + )} + + {step === 2 && ( + <> + + + + {t("onboarding.configTitle")} + + {t("onboarding.configBody")} + +
+
+ + setModel(e.target.value)} className={inputCls} /> +
+
+ + setApiKey(e.target.value)} + placeholder={t("onboarding.apiKeyPlaceholder")} + className={inputCls} + /> +
+
+ + setBaseUrl(e.target.value)} + placeholder={t("onboarding.baseUrlPlaceholder")} + className={inputCls} + /> +
+
+ + + + + + )} + + {step === 3 && ( + <> + + + + {t("onboarding.kbTitle")} + + {t("onboarding.kbBody")} + +
+ + setKbName(e.target.value)} + placeholder="my-kb" + className={inputCls} + /> +
+ + + + + + )} +
+
+ ) +} diff --git a/frontend/src/locales/en/common.json b/frontend/src/locales/en/common.json index 88cc7561..f24cae41 100644 --- a/frontend/src/locales/en/common.json +++ b/frontend/src/locales/en/common.json @@ -50,5 +50,26 @@ "connector": { "tooltip": "Cloud sync is in development · vote for it on GitHub", "vote": "Want it? Vote" + }, + "onboarding": { + "welcomeTitle": "Welcome to OpenKB", + "welcomeBody": "Turn your documents into an interlinked, always-current knowledge base. Two quick steps and you're ready.", + "getStarted": "Get started", + "skip": "Skip for now", + "configTitle": "Connect your model", + "configBody": "OpenKB uses an LLM to compile and answer. Paste an API key — it is stored locally and never leaves your machine.", + "modelLabel": "LLM model", + "apiKeyLabel": "LLM API key", + "apiKeyPlaceholder": "Paste your API key", + "baseUrlLabel": "Custom base URL (optional)", + "baseUrlPlaceholder": "e.g. http://localhost:11434 (Ollama, LM Studio)", + "continue": "Continue", + "back": "Back", + "kbTitle": "Create your first knowledge base", + "kbBody": "A knowledge base holds your documents and the compiled wiki. You can add more later.", + "kbNameLabel": "Knowledge base name", + "createFinish": "Create & finish", + "saving": "Saving…", + "createdToast": "Created {{name}}" } } diff --git a/frontend/src/locales/zh/common.json b/frontend/src/locales/zh/common.json index 524e0e0b..f284f4a7 100644 --- a/frontend/src/locales/zh/common.json +++ b/frontend/src/locales/zh/common.json @@ -50,5 +50,26 @@ "connector": { "tooltip": "云端同步开发中 · 去 GitHub 投票表达需求", "vote": "想要它?去投票" + }, + "onboarding": { + "welcomeTitle": "欢迎使用 OpenKB", + "welcomeBody": "把你的文档编译成互联、自动保持更新的知识库。两步即可开始。", + "getStarted": "开始设置", + "skip": "暂时跳过", + "configTitle": "连接你的模型", + "configBody": "OpenKB 用大模型来编译和回答。粘贴一个 API 密钥即可——它只存在本机,不会外传。", + "modelLabel": "模型", + "apiKeyLabel": "LLM API 密钥", + "apiKeyPlaceholder": "粘贴 API 密钥", + "baseUrlLabel": "自定义 Base URL(可选)", + "baseUrlPlaceholder": "如 http://localhost:11434(Ollama、LM Studio)", + "continue": "继续", + "back": "上一步", + "kbTitle": "创建你的第一个知识库", + "kbBody": "知识库存放你的文档和编译出的 wiki。之后可以再建更多。", + "kbNameLabel": "知识库名称", + "createFinish": "创建并完成", + "saving": "保存中…", + "createdToast": "已创建 {{name}}" } } From 22794ffda9504a6fd3101808816530ea2aa7f1f4 Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:22 +0000 Subject: [PATCH 06/13] feat(desktop): inject window.__OPENKB_DESKTOP__ to enable desktop chrome MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The #189 frontend gates desktop-only UI (the in-app TitleBar, offset chrome cluster) on a `window.__OPENKB_DESKTOP__` flag. Set it from the shell so those features light up when the UI runs inside Tauri. The window is now created in setup() via WebviewWindowBuilder with an initialization_script, instead of declaratively in tauri.conf.json — an init script runs before page scripts on every navigation, so the flag is present on the splash and (critically) after we navigate the WebView to the sidecar's served UI. tauri.conf.json's windows[] is emptied accordingly. Verified under xvfb (WebKitGTK): with the sidecar serving the new frontend, the Tauri window renders the desktop TitleBar ("OpenKB Studio — Home", traffic lights, Local badge) — confirming the flag reaches the page. cargo build clean. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/src-tauri/src/main.rs | 16 ++++++++++++++++ desktop/src-tauri/tauri.conf.json | 11 +---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs index 075a6629..33a251bb 100644 --- a/desktop/src-tauri/src/main.rs +++ b/desktop/src-tauri/src/main.rs @@ -68,6 +68,22 @@ fn main() { tauri::Builder::default() .manage(Sidecar(Mutex::new(None))) .setup(|app| { + // Create the main window programmatically so we can inject the + // desktop-shell flag the frontend checks (window.__OPENKB_DESKTOP__). + // It gates the in-app TitleBar and other desktop-only chrome. An + // initialization script runs before page scripts on every + // navigation, so the flag is present on the splash AND after we + // navigate to the sidecar's served UI. + tauri::WebviewWindowBuilder::new( + app, + "main", + tauri::WebviewUrl::App("index.html".into()), + ) + .title("OpenKB") + .inner_size(1200.0, 800.0) + .initialization_script("window.__OPENKB_DESKTOP__ = true;") + .build()?; + // Non-fatal: if the sidecar can't start (missing binary, port in // use), keep the window up on the splash rather than crashing the // app. In `cargo run` dev the bundled sidecar isn't present, so diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index 77793d11..b9d4e0cc 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -7,16 +7,7 @@ "frontendDist": "splash" }, "app": { - "windows": [ - { - "label": "main", - "title": "OpenKB", - "width": 1200, - "height": 800, - "resizable": true, - "url": "index.html" - } - ], + "windows": [], "security": { "csp": null } From 8524a35e9e61c7f950266d4fc5ebe5d5525a72e1 Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:23 +0000 Subject: [PATCH 07/13] fix(desktop): bundle the web UI (and openkb data) into the frozen sidecar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sidecar froze only openkb's Python modules, so `openkb.api`'s static mount of `openkb/web` found nothing and served `/` as 404 — an installed app would open to a blank/error page. Add `openkb` to `--collect-all` so PyInstaller bundles its data files (the built web UI at openkb/web, plus prompt/template assets) and any lazy/dynamically-imported submodules. The web UI must be built (npm run build → openkb/web) before this script runs. Verified: the frozen sidecar now serves `/` → 200 with `OpenKB Studio` and its `/assets/*.js` → 200 (was 404). Size 336M → 343M. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/packaging/build_sidecar.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/desktop/packaging/build_sidecar.sh b/desktop/packaging/build_sidecar.sh index 0dc11ec7..23bc315a 100755 --- a/desktop/packaging/build_sidecar.sh +++ b/desktop/packaging/build_sidecar.sh @@ -21,7 +21,12 @@ cd "$HERE" rm -rf build dist openkb-api-sidecar.spec -COLLECT=(litellm markitdown pageindex tiktoken agents openai tiktoken_ext uvicorn fastapi) +# `openkb` is collected whole so PyInstaller bundles (a) its data files — +# crucially the built web UI at openkb/web that the API serves at `/`, plus +# prompt/template assets — and (b) submodules reached only via lazy/dynamic +# imports (e.g. the deferred `from openkb.converter import ...`). The web UI +# must be built (npm run build → openkb/web) BEFORE this script runs. +COLLECT=(openkb litellm markitdown pageindex tiktoken agents openai tiktoken_ext uvicorn fastapi) EXCLUDE=(magika onnxruntime) ARGS=(--onedir --name openkb-api-sidecar --noconfirm --clean --log-level=WARN) From 1869344642f02c481f7559bdc4e14bce0148c208 Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:23 +0000 Subject: [PATCH 08/13] ci(desktop): add Linux desktop build workflow (Tauri + frozen sidecar) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New workflow that builds the desktop app: install WebView deps → build the web UI → freeze the openkb-api sidecar (PyInstaller) → `cargo tauri build` → upload the installers. Triggered on workflow_dispatch and `desktop-v*` tags. Linux-only for now; the matrix is structured so Windows and macOS (arm64 + intel) entries can be added once the Linux path is proven — each needs its own sidecar freeze since neither PyInstaller nor Tauri cross-compiles. Reuses the existing workflows' pinned action SHAs (checkout/setup-python/ setup-node); upload-artifact is left on a tag with a TODO to SHA-pin. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- .github/workflows/desktop.yml | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 .github/workflows/desktop.yml diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml new file mode 100644 index 00000000..a4b7b7ba --- /dev/null +++ b/.github/workflows/desktop.yml @@ -0,0 +1,104 @@ +name: Desktop build + +# Builds the OpenKB desktop app (Tauri shell + frozen openkb-api sidecar). +# +# Neither half cross-compiles — PyInstaller freezes for the host OS/arch and +# Tauri links the platform WebView — so each target is its own runner. This +# workflow starts with Linux only; add the Windows / macOS(arm+intel) matrix +# entries below once the Linux path is proven (see the commented block). +# +# Ordering within a job matters: build the web UI FIRST (npm run build → +# openkb/web), THEN freeze the sidecar (build_sidecar.sh bundles openkb/web), +# THEN `tauri build` (bundles the sidecar dir as a resource). + +on: + workflow_dispatch: + push: + tags: + - "desktop-v*" + +permissions: + contents: read + +concurrency: + group: desktop-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-22.04 + target: linux + # Added once Linux is proven (each needs its own sidecar freeze): + # - os: windows-latest # -> .msi / .exe (NSIS) + # target: windows + # - os: macos-14 # -> .dmg (aarch64, Apple Silicon) + # target: macos-arm64 + # - os: macos-13 # -> .dmg (x86_64, Intel) + # target: macos-intel + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + persist-credentials: false + + # Tauri's Linux WebView + bundler dependencies (webkit2gtk 4.1, appindicator, + # rsvg for icon rendering). No-op on non-Linux targets. + - name: Install Linux WebView deps + if: matrix.target == 'linux' + run: | + sudo apt-get update + sudo apt-get install -y \ + libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev \ + build-essential curl wget file libxdo-dev libssl-dev + + - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + with: + python-version: "3.12" + + # openkb.api (the sidecar) + PyInstaller. PyInstaller is a build tool, not + # a runtime dep, so it's installed ad-hoc here rather than pinned in + # pyproject. + - name: Install openkb + build tools + run: pip install -e ".[api]" pyinstaller + + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: "20" + + # MUST run before the sidecar freeze — build_sidecar.sh bundles openkb/web. + - name: Build web UI + working-directory: frontend + run: | + npm ci + npm run build + + - name: Freeze API sidecar + run: PYTHON="$(which python)" bash desktop/packaging/build_sidecar.sh + + # ubuntu runners ship a stable Rust toolchain, so no toolchain action is + # needed. tauri-cli is installed from crates.io (locked) rather than via a + # third-party action, to keep the supply chain explicit and pin-friendly. + - name: Install tauri-cli + run: cargo install tauri-cli --version "^2" --locked + + - name: Build Tauri bundle + working-directory: desktop/src-tauri + run: cargo tauri build + + # TODO: pin to a SHA to match the repo's action-pinning policy. + - name: Upload installers + uses: actions/upload-artifact@v4 + with: + name: openkb-desktop-${{ matrix.target }} + path: | + desktop/src-tauri/target/release/bundle/**/*.AppImage + desktop/src-tauri/target/release/bundle/**/*.deb + desktop/src-tauri/target/release/bundle/**/*.rpm + desktop/src-tauri/target/release/bundle/**/*.dmg + desktop/src-tauri/target/release/bundle/**/*.msi + desktop/src-tauri/target/release/bundle/**/*.exe + if-no-files-found: warn From 665afc0596e184e97b90e46d0a0050d3074cf965 Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:23 +0000 Subject: [PATCH 09/13] docs(desktop): record verified Linux installer build + CI workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pipeline (web build → sidecar freeze bundling openkb/web → cargo tauri build) is verified locally end to end: it produces a .deb and .rpm (~175 MB each) containing the app + frozen sidecar, and the shell renders the desktop TitleBar under xvfb. Notes the AppImage target needs network for appimagetool. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- desktop/README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/desktop/README.md b/desktop/README.md index b7feea05..91a01dfa 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -84,12 +84,20 @@ deliberately — they are load-bearing for OpenKB's document formats. Full builds need, per platform: Rust + Cargo, Node + npm, a Python 3.10+ env, and on **Linux `webkit2gtk`** (`libwebkit2gtk-4.1-dev`) for the WebView. +CI: `.github/workflows/desktop.yml` runs this pipeline on `workflow_dispatch` +and `desktop-v*` tags (Linux only for now; the matrix has commented Windows / +macOS entries). + **Status:** - **API sidecar** (`packaging/`) — implemented and verified: the frozen slim - binary boots uvicorn and serves `GET /api/v1/kbs` → 200. -- **Web UI** — builds (`npm run build` → `openkb/web/`) and renders end-to-end - against the sidecar (verified via headless Chromium screenshot). -- **Tauri shell** (`src-tauri/`) — **compiles** (`cargo build`, with - `libwebkit2gtk-4.1-dev` installed). *Running* the window needs a display, so - the end-to-end "double-click → window → sidecar" flow must be exercised on a - desktop machine or a display-equipped CI runner (e.g. via `xvfb`). + binary boots uvicorn and serves both `GET /api/v1/kbs` and the web UI at `/`. +- **Web UI** — builds (`npm run build` → `openkb/web/`), is bundled into the + sidecar freeze, and renders end-to-end (verified via headless Chromium). +- **Tauri shell** (`src-tauri/`) — compiles and runs: verified under `xvfb` + (WebKitGTK) navigating to the sidecar and rendering the desktop TitleBar + (`window.__OPENKB_DESKTOP__` is injected by the shell). +- **Installers** — `cargo tauri build` produces a Linux `.deb` and `.rpm` + (verified locally; each ~175 MB, bundling the app + frozen sidecar). The + `.AppImage` target additionally downloads `appimagetool` at build time, so it + needs unrestricted network (fine on GitHub runners; blocked in a locked-down + sandbox). Windows/macOS installers build once their matrix runners are added. From 491cf5f940e4c618210b7e3643c3925aeb474d36 Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:13:23 +0000 Subject: [PATCH 10/13] ci(desktop): full Win/macOS(arm+intel)/Linux matrix + release on tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the desktop build to all platforms (each freezes its own sidecar and links its own WebView — neither cross-compiles) and adds a release job that attaches every platform's installers to a GitHub Release on a `desktop-v*` tag. The sidecar freeze runs under `shell: bash` (git-bash on Windows) with PYTHON=python. macOS arm64/x86_64 are native builds on macos-14/macos-13. Artifacts are unsigned for now (macOS notarization / Windows signing TBD); a couple of first-party actions still need SHA-pinning (marked TODO). The Linux path is verified locally (.deb/.rpm); Windows/macOS need a real runner. Claude-Session: https://claude.ai/code/session_01KZyUSGAzVL9yxpsWWPv6Y2 --- .github/workflows/desktop.yml | 73 ++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml index a4b7b7ba..2f957b23 100644 --- a/.github/workflows/desktop.yml +++ b/.github/workflows/desktop.yml @@ -1,11 +1,12 @@ name: Desktop build -# Builds the OpenKB desktop app (Tauri shell + frozen openkb-api sidecar). +# Builds the OpenKB desktop app (Tauri shell + frozen openkb-api sidecar) for +# every platform, and — on a `desktop-v*` tag — attaches the installers to a +# GitHub Release. # # Neither half cross-compiles — PyInstaller freezes for the host OS/arch and -# Tauri links the platform WebView — so each target is its own runner. This -# workflow starts with Linux only; add the Windows / macOS(arm+intel) matrix -# entries below once the Linux path is proven (see the commented block). +# Tauri links the platform WebView — so each target is its own runner. macOS +# arm64/x86_64 are separate runners (native builds; no --target needed). # # Ordering within a job matters: build the web UI FIRST (npm run build → # openkb/web), THEN freeze the sidecar (build_sidecar.sh bundles openkb/web), @@ -32,21 +33,20 @@ jobs: include: - os: ubuntu-22.04 target: linux - # Added once Linux is proven (each needs its own sidecar freeze): - # - os: windows-latest # -> .msi / .exe (NSIS) - # target: windows - # - os: macos-14 # -> .dmg (aarch64, Apple Silicon) - # target: macos-arm64 - # - os: macos-13 # -> .dmg (x86_64, Intel) - # target: macos-intel + - os: windows-latest + target: windows + - os: macos-14 # Apple Silicon + target: macos-arm64 + - os: macos-13 # Intel + target: macos-intel runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false - # Tauri's Linux WebView + bundler dependencies (webkit2gtk 4.1, appindicator, - # rsvg for icon rendering). No-op on non-Linux targets. + # Tauri's Linux WebView + bundler dependencies. Windows (WebView2) and + # macOS (WebKit) ship theirs with the OS, so this is Linux-only. - name: Install Linux WebView deps if: matrix.target == 'linux' run: | @@ -55,17 +55,16 @@ jobs: libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev \ build-essential curl wget file libxdo-dev libssl-dev - - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: "3.12" # openkb.api (the sidecar) + PyInstaller. PyInstaller is a build tool, not - # a runtime dep, so it's installed ad-hoc here rather than pinned in - # pyproject. + # a runtime dep, so it's installed ad-hoc rather than pinned in pyproject. - name: Install openkb + build tools run: pip install -e ".[api]" pyinstaller - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "20" @@ -76,12 +75,15 @@ jobs: npm ci npm run build + # `shell: bash` so the same script runs on Windows (git-bash) too. + # PyInstaller emits openkb-api-sidecar(.exe) for the host OS/arch. - name: Freeze API sidecar - run: PYTHON="$(which python)" bash desktop/packaging/build_sidecar.sh + shell: bash + run: PYTHON=python bash desktop/packaging/build_sidecar.sh - # ubuntu runners ship a stable Rust toolchain, so no toolchain action is - # needed. tauri-cli is installed from crates.io (locked) rather than via a - # third-party action, to keep the supply chain explicit and pin-friendly. + # ubuntu/macos/windows runners ship a stable Rust toolchain. tauri-cli is + # installed from crates.io (locked) rather than via a third-party action, + # to keep the supply chain explicit. - name: Install tauri-cli run: cargo install tauri-cli --version "^2" --locked @@ -89,7 +91,7 @@ jobs: working-directory: desktop/src-tauri run: cargo tauri build - # TODO: pin to a SHA to match the repo's action-pinning policy. + # TODO: pin actions/upload-artifact to a SHA to match the repo policy. - name: Upload installers uses: actions/upload-artifact@v4 with: @@ -102,3 +104,28 @@ jobs: desktop/src-tauri/target/release/bundle/**/*.msi desktop/src-tauri/target/release/bundle/**/*.exe if-no-files-found: warn + + # Attach every platform's installers to a GitHub Release, but only for a + # `desktop-v*` tag. Signing/notarization (macOS Gatekeeper, Windows + # SmartScreen) is not configured yet — these are unsigned artifacts. + release: + if: startsWith(github.ref, 'refs/tags/desktop-v') + needs: build + runs-on: ubuntu-latest + permissions: + contents: write + steps: + # TODO: pin actions/download-artifact to a SHA to match the repo policy. + - name: Download all installers + uses: actions/download-artifact@v4 + with: + path: installers + merge-multiple: true + + - name: Create / update the release + uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 + with: + tag_name: ${{ github.ref_name }} + name: ${{ github.ref_name }} + generate_release_notes: true + files: installers/**/* From ed06fba73aa7836bb69665649f9798c22c33728a Mon Sep 17 00:00:00 2001 From: Kylin Date: Mon, 20 Jul 2026 14:26:59 +0000 Subject: [PATCH 11/13] feat(web): let onboarding pick the wiki language (UN quick-picks) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a "Wiki language" field to the onboarding setup step, reusing the existing UnLanguageDatalist (the six official UN languages) as free-text quick-picks — so a non-English user sets their knowledge-base language up front. Saved via patchGlobalConfig config.language. en/zh label added to the common namespace. --- frontend/src/components/Onboarding.tsx | 16 ++++++++++++++++ frontend/src/locales/en/common.json | 1 + frontend/src/locales/zh/common.json | 1 + 3 files changed, 18 insertions(+) diff --git a/frontend/src/components/Onboarding.tsx b/frontend/src/components/Onboarding.tsx index 169cb54a..8b656da9 100644 --- a/frontend/src/components/Onboarding.tsx +++ b/frontend/src/components/Onboarding.tsx @@ -12,6 +12,7 @@ import { DialogFooter, } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" +import { UnLanguageDatalist, UN_LANG_LIST_ID } from "@/components/UnLanguageDatalist" import { patchGlobalConfig, type GlobalConfigPatch } from "@/api/config" import { createKb } from "@/api/kb" @@ -28,6 +29,7 @@ export default function Onboarding({ open, onClose }: { open: boolean; onClose: const navigate = useNavigate() const [step, setStep] = useState(1) const [model, setModel] = useState("gpt-5.4") + const [language, setLanguage] = useState("") const [apiKey, setApiKey] = useState("") const [baseUrl, setBaseUrl] = useState("") const [kbName, setKbName] = useState("my-kb") @@ -39,6 +41,7 @@ export default function Onboarding({ open, onClose }: { open: boolean; onClose: setBusy(true) try { const patch: GlobalConfigPatch = { config: { model: model.trim() } } + if (language.trim()) patch.config!.language = language.trim() if (apiKey.trim()) patch.api_key = apiKey.trim() if (baseUrl.trim()) patch.openai_api_base = baseUrl.trim() await patchGlobalConfig(patch) @@ -108,6 +111,19 @@ export default function Onboarding({ open, onClose }: { open: boolean; onClose: setModel(e.target.value)} className={inputCls} /> +
+ + setLanguage(e.target.value)} + list={UN_LANG_LIST_ID} + placeholder="English" + className={inputCls} + /> + +