From b199af182e85fdb7e8993775b9f3b8a36ef7e1e3 Mon Sep 17 00:00:00 2001 From: iamtoruk Date: Tue, 18 Aug 2026 04:00:59 -0700 Subject: [PATCH] windows: import the Tauri tray app as the Windows menubar Brings the Tauri 2.x tray popover from #1022 onto main as windows/, mirroring mac/. Product name, bundle identifier, and version line up with the macOS menubar (org.agentseal.codeburn-menubar, 0.9.20); the crate is renamed off "desktop" so it no longer collides with the Electron app in app/. Linux (ksni) stays compiled and dev-usable but is documented as experimental: gnome/ is the shipping Linux surface. The five src/ CLI commits on that branch are dropped - they re-implement a daily-bucketing fix main already carries. --- windows/.gitignore | 10 + windows/DEVELOPMENT.md | 169 + windows/Scripts/autoinstall/README.md | 38 + windows/Scripts/autoinstall/meta-data | 2 + windows/Scripts/autoinstall/user-data | 57 + windows/Scripts/provision-linux.sh | 89 + windows/dist/index.html | 4 + windows/index.html | 12 + windows/package-lock.json | 2069 ++++++ windows/package.json | 28 + windows/src-tauri/Cargo.lock | 6066 +++++++++++++++++ windows/src-tauri/Cargo.toml | 40 + windows/src-tauri/build.rs | 3 + windows/src-tauri/capabilities/default.json | 20 + windows/src-tauri/icons/128x128.png | Bin 0 -> 16212 bytes windows/src-tauri/icons/128x128@2x.png | Bin 0 -> 60726 bytes windows/src-tauri/icons/32x32.png | Bin 0 -> 1455 bytes windows/src-tauri/icons/icon.ico | Bin 0 -> 88060 bytes windows/src-tauri/icons/icon.png | Bin 0 -> 227446 bytes windows/src-tauri/icons/tray.png | Bin 0 -> 2381 bytes windows/src-tauri/src/autostart.rs | 88 + windows/src-tauri/src/cli.rs | 499 ++ windows/src-tauri/src/config.rs | 161 + windows/src-tauri/src/fx.rs | 152 + windows/src-tauri/src/lib.rs | 509 ++ windows/src-tauri/src/main.rs | 6 + windows/src-tauri/src/plan.rs | 484 ++ windows/src-tauri/src/tray_badge.rs | 246 + windows/src-tauri/src/tray_linux.rs | 139 + windows/src-tauri/tauri.conf.json | 64 + windows/src/App.tsx | 352 + windows/src/components/ActivitySection.tsx | 52 + windows/src/components/AgentTabStrip.tsx | 116 + windows/src/components/CollapsibleSection.tsx | 44 + windows/src/components/DropMenu.tsx | 93 + windows/src/components/EmptyProviderState.tsx | 19 + windows/src/components/ErrorToast.tsx | 29 + windows/src/components/FindingsSection.tsx | 72 + windows/src/components/FooterBar.tsx | 81 + windows/src/components/ForecastInsight.tsx | 59 + windows/src/components/HeroSection.tsx | 43 + windows/src/components/Icons.tsx | 195 + windows/src/components/InsightPills.tsx | 41 + windows/src/components/LoadingOverlay.tsx | 44 + windows/src/components/ModelsSection.tsx | 47 + windows/src/components/NoDataState.tsx | 35 + windows/src/components/PeriodTabs.tsx | 41 + windows/src/components/PlanInsight.tsx | 147 + windows/src/components/PulseInsight.tsx | 32 + windows/src/components/SettingsPanel.tsx | 156 + windows/src/components/SetupState.tsx | 71 + windows/src/components/StarBanner.tsx | 29 + windows/src/components/StatsInsight.tsx | 63 + windows/src/components/TrendInsight.tsx | 153 + windows/src/lib/cache.ts | 43 + windows/src/lib/currency.ts | 70 + windows/src/lib/dates.ts | 89 + windows/src/lib/history.ts | 99 + windows/src/lib/payload.ts | 57 + windows/src/lib/plan.ts | 73 + windows/src/lib/platform.ts | 10 + windows/src/lib/settings.ts | 42 + windows/src/lib/tips.ts | 48 + windows/src/main.tsx | 10 + windows/src/styles.css | 1153 ++++ windows/tokens.json | 75 + windows/tsconfig.json | 24 + windows/vite.config.ts | 29 + 68 files changed, 14791 insertions(+) create mode 100644 windows/.gitignore create mode 100644 windows/DEVELOPMENT.md create mode 100644 windows/Scripts/autoinstall/README.md create mode 100644 windows/Scripts/autoinstall/meta-data create mode 100644 windows/Scripts/autoinstall/user-data create mode 100755 windows/Scripts/provision-linux.sh create mode 100644 windows/dist/index.html create mode 100644 windows/index.html create mode 100644 windows/package-lock.json create mode 100644 windows/package.json create mode 100644 windows/src-tauri/Cargo.lock create mode 100644 windows/src-tauri/Cargo.toml create mode 100644 windows/src-tauri/build.rs create mode 100644 windows/src-tauri/capabilities/default.json create mode 100644 windows/src-tauri/icons/128x128.png create mode 100644 windows/src-tauri/icons/128x128@2x.png create mode 100644 windows/src-tauri/icons/32x32.png create mode 100644 windows/src-tauri/icons/icon.ico create mode 100644 windows/src-tauri/icons/icon.png create mode 100644 windows/src-tauri/icons/tray.png create mode 100644 windows/src-tauri/src/autostart.rs create mode 100644 windows/src-tauri/src/cli.rs create mode 100644 windows/src-tauri/src/config.rs create mode 100644 windows/src-tauri/src/fx.rs create mode 100644 windows/src-tauri/src/lib.rs create mode 100644 windows/src-tauri/src/main.rs create mode 100644 windows/src-tauri/src/plan.rs create mode 100644 windows/src-tauri/src/tray_badge.rs create mode 100644 windows/src-tauri/src/tray_linux.rs create mode 100644 windows/src-tauri/tauri.conf.json create mode 100644 windows/src/App.tsx create mode 100644 windows/src/components/ActivitySection.tsx create mode 100644 windows/src/components/AgentTabStrip.tsx create mode 100644 windows/src/components/CollapsibleSection.tsx create mode 100644 windows/src/components/DropMenu.tsx create mode 100644 windows/src/components/EmptyProviderState.tsx create mode 100644 windows/src/components/ErrorToast.tsx create mode 100644 windows/src/components/FindingsSection.tsx create mode 100644 windows/src/components/FooterBar.tsx create mode 100644 windows/src/components/ForecastInsight.tsx create mode 100644 windows/src/components/HeroSection.tsx create mode 100644 windows/src/components/Icons.tsx create mode 100644 windows/src/components/InsightPills.tsx create mode 100644 windows/src/components/LoadingOverlay.tsx create mode 100644 windows/src/components/ModelsSection.tsx create mode 100644 windows/src/components/NoDataState.tsx create mode 100644 windows/src/components/PeriodTabs.tsx create mode 100644 windows/src/components/PlanInsight.tsx create mode 100644 windows/src/components/PulseInsight.tsx create mode 100644 windows/src/components/SettingsPanel.tsx create mode 100644 windows/src/components/SetupState.tsx create mode 100644 windows/src/components/StarBanner.tsx create mode 100644 windows/src/components/StatsInsight.tsx create mode 100644 windows/src/components/TrendInsight.tsx create mode 100644 windows/src/lib/cache.ts create mode 100644 windows/src/lib/currency.ts create mode 100644 windows/src/lib/dates.ts create mode 100644 windows/src/lib/history.ts create mode 100644 windows/src/lib/payload.ts create mode 100644 windows/src/lib/plan.ts create mode 100644 windows/src/lib/platform.ts create mode 100644 windows/src/lib/settings.ts create mode 100644 windows/src/lib/tips.ts create mode 100644 windows/src/main.tsx create mode 100644 windows/src/styles.css create mode 100644 windows/tokens.json create mode 100644 windows/tsconfig.json create mode 100644 windows/vite.config.ts diff --git a/windows/.gitignore b/windows/.gitignore new file mode 100644 index 00000000..2e4d499b --- /dev/null +++ b/windows/.gitignore @@ -0,0 +1,10 @@ +node_modules/ +# dist/ is a Vite build output; we gitignore its contents but keep a tracked placeholder +# index.html so Tauri's compile-time `frontendDist` validation passes on fresh clones before +# anyone has run `npm run build`. Real build output replaces the placeholder locally. +dist/* +!dist/index.html +src-tauri/target/ +src-tauri/gen/ +.DS_Store +*.log diff --git a/windows/DEVELOPMENT.md b/windows/DEVELOPMENT.md new file mode 100644 index 00000000..6b90bcdc --- /dev/null +++ b/windows/DEVELOPMENT.md @@ -0,0 +1,169 @@ +# CodeBurn Menubar (Windows) + +Tauri 2.x tray app that surfaces CodeBurn in the Windows notification area. It is the Windows +mirror of the native macOS menubar in `../mac/`, which stays the authoritative look and feel; +this project mirrors its layout, colors, and data via the shared `tokens.json`. + +Linux (ksni / AppIndicator) support is compiled and kept working for dev, but it is +**experimental and unreleased** - Linux users should use the GNOME extension in `../gnome/`. +The releases this repo cuts from here are Windows only. + +## Architecture + +``` +windows/ +├── src/ React + TypeScript popover UI (runs inside the Tauri webview) +├── src-tauri/ +│ ├── src/ +│ │ ├── main.rs binary entry +│ │ ├── lib.rs tray, window lifecycle, state wiring +│ │ ├── cli.rs argv-validated spawn of the codeburn CLI +│ │ ├── config.rs ~/.config/codeburn/config.json read/write under a lock +│ │ ├── plan.rs Claude OAuth quota (port of mac/.../ClaudeSubscriptionService.swift) +│ │ └── fx.rs Frankfurter fetch + 24h disk cache + [0.0001, 1e6] clamp +│ ├── capabilities/ Tauri v2 permission manifests +│ └── icons/ tray + bundle icons +└── tokens.json shared design tokens (also consumed by mac/ at build time) +``` + +## Prerequisites (Windows) + +```powershell +# Rust +winget install Rustlang.Rustup +rustup target add x86_64-pc-windows-msvc + +# WebView2 Runtime +winget install Microsoft.EdgeWebView2Runtime + +# Microsoft C++ Build Tools (ships with Visual Studio Installer; pick "Desktop development with C++") +``` + +## Prerequisites (macOS / Linux, dev only) + +Tauri builds on macOS and Linux for inner-loop UI iteration. The shipping macOS product is the +Swift app in `../mac/`, so we don't cut a Tauri Mac release. + +```bash +# macOS +brew install rust node + +# Ubuntu / Debian +sudo apt update +sudo apt install -y \ + build-essential curl wget file \ + libwebkit2gtk-4.1-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + libssl-dev \ + libxdo-dev \ + libgtk-3-dev +``` + +## Run the dev server + +```bash +cd windows +npm install +npm run tauri dev +``` + +Under the hood this starts Vite on `localhost:1420`, builds `src-tauri/target/debug/codeburn-menubar`, +and opens a window wired to the dev server with hot reload for the React code. The tray icon +appears at the same time. + +If the codeburn CLI isn't on PATH (dev builds from this monorepo), point the app at your local build: + +```bash +npm --prefix .. run build +CODEBURN_BIN="node $(pwd)/../dist/cli.js" npm run tauri dev +``` + +`CODEBURN_BIN` is validated against a strict allowlist (alphanumerics plus `._/-` and space; +`\ : ( )` also allowed on Windows) before use; anything else falls back to auto-resolution. + +Without `CODEBURN_BIN` the app looks for `codeburn` (`codeburn.cmd` / `codeburn.exe` on Windows) +on the inherited `PATH`, then in the usual npm and node prefixes (`%APPDATA%\npm`, +`%LOCALAPPDATA%\Programs\nodejs`, pnpm, Volta, scoop, `/opt/homebrew/bin`, `~/.npm-global/bin`), +and finally on Windows in the live user and machine `PATH` read from the registry, so a CLI +installed after the tray app was launched is still found. Only absolute directory entries are +considered - empty or relative `PATH` entries are skipped so nothing is ever resolved out of the +current working directory. + +If nothing is found, or `codeburn --version` is older than `MIN_CLI_VERSION` +(`src-tauri/src/cli.rs`), the popover shows a setup screen with the install command and a +"Check again" button. That gate is probed once on mount, before the first payload fetch. + +`MIN_CLI_VERSION` is **0.9.9**: the first release whose `codeburn status --format menubar-json` +accepts `--no-optimize`, which the app's quiet background refreshes always pass. Every payload +field the popover reads (`current.providers`, `current.cacheHitPercent`, `history.daily[].topModels`) +also exists at that version. + +## Refresh policy + +Mirrors `mac/Sources/CodeBurnMenubar/RefreshCadence.swift`: each CLI fetch is a full Node +process, so the cadence follows popover visibility. + +- popover visible: 60 s tick, full fetch (optimize findings included) +- popover hidden: 120 s tick, `today`/`all` only, `--no-optimize` +- on show: immediate refresh when the visible key is older than 60 s + +## Plan / quota + +The Plan pill (visible on the Claude tab, or when Claude is the only detected provider) reads +Claude Code's OAuth credentials from `~/.claude/.credentials.json`, calls +`https://api.anthropic.com/api/oauth/usage`, refreshes the token once on 401, and stores one +snapshot per window under `~/.cache/codeburn/subscription-snapshots.json` (`CODEBURN_CACHE_DIR` +override) so a freshly reset window can still show last cycle's final. This is the same file +format the macOS app writes. Nothing is logged: the credential blob never leaves the Rust side. + +## Build a production package + +```bash +# Windows (.msi + NSIS .exe): run from a Windows host +npm run tauri build + +# Linux (experimental): produces .deb, .rpm, .AppImage under src-tauri/target/release/bundle/ +npm run tauri build +``` + +## Security model + +- **Process spawn**: every call into the codeburn CLI goes through `CodeburnCli::fetch_menubar_payload`, + which builds argv explicitly and runs the binary directly (no `sh -c`). `CODEBURN_BIN` is + allowlisted before use. Windows system tools (`reg.exe`, `cmd.exe`) are invoked by absolute + path under `%SystemRoot%\System32` so `CreateProcess`'s current-directory search can never + pick up a planted binary; `claude` is resolved from absolute `PATH` directories the same way. +- **Pipes**: stdout is capped at 20 MB, stderr at 256 KB, total wall time at 60 s. A hung CLI + cannot pin file descriptors or memory. +- **Config writes**: `~/.config/codeburn/config.json` writes run under a POSIX `flock` on + `~/.config/codeburn/.config.lock`. On Windows the same path uses a create-new lock file. Note + that this lock is advisory *between instances of this app only* - the codeburn CLI does not + take it - so it narrows, but does not eliminate, a concurrent-write race. A lock left behind + by a crash is never deleted by another process; it expires after 30 s of inactivity and the + next writer retries. +- **Snapshot writes**: `subscription-snapshots.json` refuses a symlinked target and is written + 0600 on unix, mirroring `mac/Sources/CodeBurnMenubar/Security/SafeFile.swift`. +- **Credentials**: the Plan view reads `~/.claude/.credentials.json` with a 64 KB cap and refuses + symlinks; tokens are only ever sent to the Anthropic usage and token endpoints over TLS. +- **FX fetches**: Frankfurter response is parsed as JSON and the rate is clamped to + `[0.0001, 1_000_000]` before it touches displayed numbers. Stale cache preferred over poisoned + fresh data. +- **CSP**: `connect-src` restricted to `self`, `ipc:`, and `https://api.frankfurter.app`. No + inline scripts. + +## CI and release tags + +- `.github/workflows/windows-menubar-ci.yml` runs on any `windows/**` change: `tsc --noEmit`, + `cargo clippy -D warnings` and `cargo test` on windows-latest + ubuntu-latest, plus a release + build smoke on Windows. +- `windows-v*` tag (e.g. `windows-v0.9.20`) triggers + `.github/workflows/release-menubar-windows.yml`; publishes the `.msi` and NSIS `.exe` to a + "Windows Menubar vX" release. Unsigned for now, so Windows SmartScreen prompts on first run + until a signing cert is in place. + +## Pending work + +1. Code signing for the Windows `.msi` to remove the SmartScreen warning. +2. Linux: decide whether to ship at all (the GNOME extension in `../gnome/` covers that + surface today) or promote the ksni tray out of experimental. diff --git a/windows/Scripts/autoinstall/README.md b/windows/Scripts/autoinstall/README.md new file mode 100644 index 00000000..5e81424a --- /dev/null +++ b/windows/Scripts/autoinstall/README.md @@ -0,0 +1,38 @@ +# Unattended Ubuntu install for the CodeBurn dev VM + +This directory contains a cloud-init `user-data` + `meta-data` pair that tells the Ubuntu 24.04 Server installer to configure itself without any user prompts. After it finishes, you reboot into GNOME and run the one-line provisioner. + +Default credentials in `user-data`: **`codeburn` / `codeburn`**. Change them before using anywhere that matters. + +## Build the CIDATA ISO (on your Mac) + +```bash +cd windows/Scripts/autoinstall +hdiutil makehybrid -o codeburn-cidata.iso \ + -hfs -joliet -iso -default-volume-name CIDATA . +``` + +That produces `codeburn-cidata.iso` (around 2 KB) with the two YAML files at the root, labelled `CIDATA`. + +## Hook it into UTM + +1. Create the VM as usual (Virtualize → Linux → Ubuntu Server arm64 ISO). +2. Before first boot, open the VM's Settings → **Drives** → **New Drive** → pick **Removable** → **Import**, and select `codeburn-cidata.iso`. +3. Boot. The Ubuntu installer auto-detects the CIDATA volume, reads the autoinstall config, and runs the install without prompts. Takes 15-20 minutes depending on disk speed. +4. Reboot into the installed system, log in as `codeburn`, then: + + ```bash + bash ~/provision.sh + ``` + + (The autoinstall drops the script to `~/provision.sh`. It installs Rust + Node + the codeburn CLI, clones the repo, and sets up the windows/ npm deps.) + +5. `cd ~/codeburn/windows && npm run tauri dev`. + +## Why not automate the provisioner run too + +cloud-init's `late-commands` runs in the installer environment, which doesn't have a GNOME session for the tray icon to land in. We deliberately stop short of running `npm run tauri dev` from within autoinstall so the tray shows up on your first real login instead of a detached systemd unit. + +## Skipping autoinstall + +If you'd rather click through the Ubuntu installer normally, ignore this directory entirely. The `provision-linux.sh` script in the parent directory works the same way whether the OS was installed unattended or by hand. diff --git a/windows/Scripts/autoinstall/meta-data b/windows/Scripts/autoinstall/meta-data new file mode 100644 index 00000000..576f5acd --- /dev/null +++ b/windows/Scripts/autoinstall/meta-data @@ -0,0 +1,2 @@ +instance-id: codeburn-linux-01 +local-hostname: codeburn-linux diff --git a/windows/Scripts/autoinstall/user-data b/windows/Scripts/autoinstall/user-data new file mode 100644 index 00000000..f4050494 --- /dev/null +++ b/windows/Scripts/autoinstall/user-data @@ -0,0 +1,57 @@ +#cloud-config +# Ubuntu 24.04 LTS Server autoinstall configuration for a CodeBurn desktop dev VM. Mount this +# file as a second virtual disk (CIDATA volume) alongside the Ubuntu Server ISO in UTM and +# the installer runs unattended end to end. Default login: codeburn / codeburn. Change the +# identity block before running in any environment that matters. +autoinstall: + version: 1 + + # Accept the EULA-style prompts without user input. + refresh-installer: + update: yes + + locale: en_US.UTF-8 + keyboard: + layout: us + + # Wire up a default user. Password is `codeburn`; hash generated with `openssl passwd -6`. + # Regenerate the hash if you care about the credentials outside of a throwaway VM. + identity: + hostname: codeburn-linux + username: codeburn + password: "$6$rounds=4096$JrKVZcJ2$F93p8IWyTlZR5p1Trmno/qCnhYI1BnbUUYdf6HsiD.XW4T0I3JtvzH40nWNy9Z1CcJ2X5C6RuzK0bj9WM3x/n." + + ssh: + install-server: yes + allow-pw: yes + + # Install GNOME + the build dependencies Tauri needs so the first login is already ready + # to run `npm run tauri dev` without another apt round trip. + packages: + - ubuntu-desktop-minimal + - build-essential + - curl + - wget + - file + - git + - libwebkit2gtk-4.1-dev + - libayatana-appindicator3-dev + - librsvg2-dev + - libssl-dev + - libxdo-dev + - libgtk-3-dev + - pkg-config + + # Run the provisioner as the new user on first boot. It installs Node + Rust, pulls the + # repo, and runs `npm install` for the desktop app. After the script finishes, logging in + # to GNOME and running `cd ~/codeburn/windows && npm run tauri dev` brings the tray up. + late-commands: + - curtin in-target --target=/target -- bash -lc ' + sudo -iu codeburn bash -lc " + curl -fsSL https://raw.githubusercontent.com/getagentseal/codeburn/main/windows/Scripts/provision-linux.sh \ + -o /home/codeburn/provision.sh + chmod +x /home/codeburn/provision.sh + " + ' + + shutdown: reboot diff --git a/windows/Scripts/provision-linux.sh b/windows/Scripts/provision-linux.sh new file mode 100755 index 00000000..23ba9991 --- /dev/null +++ b/windows/Scripts/provision-linux.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# One-shot Ubuntu provisioning for the CodeBurn desktop (Tauri) dev environment. +# +# Usage inside a fresh Ubuntu 24.04 LTS Server VM (after `sudo apt install +# ubuntu-desktop-minimal && sudo reboot`, and logging into GNOME): +# +# curl -fsSL https://raw.githubusercontent.com/getagentseal/codeburn/main/windows/Scripts/provision-linux.sh | bash +# +# Or if you cloned the repo manually: `bash windows/Scripts/provision-linux.sh`. +# +# Installs: build toolchain, webkit + appindicator headers, Node 20 LTS, Rust stable, +# the codeburn npm CLI, and this repo. Leaves you one command away from `npm run tauri dev`. + +set -euo pipefail + +REPO_URL="https://github.com/getagentseal/codeburn.git" +BRANCH="feat/tauri-menubar-win-linux" +CHECKOUT="${HOME}/codeburn" + +log() { printf '\033[1;34m▸\033[0m %s\n' "$*"; } +fail() { printf '\033[1;31m✗\033[0m %s\n' "$*" >&2; exit 1; } + +# 1. Platform sanity +[[ "$(uname -s)" == "Linux" ]] || fail "Run me on Linux (detected: $(uname -s))." +if ! command -v apt-get >/dev/null; then + fail "Only apt-based distros supported by this provisioner (Ubuntu, Debian)." +fi + +log "apt update + system build deps" +sudo apt-get update -qq +sudo apt-get install -y \ + build-essential curl wget file git \ + libwebkit2gtk-4.1-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + libssl-dev \ + libxdo-dev \ + libgtk-3-dev \ + pkg-config + +# 2. Node 20 LTS via NodeSource if the distro version is too old. Tauri CLI needs >= 18. +if ! command -v node >/dev/null || [[ "$(node -v | sed 's/v\([0-9]*\).*/\1/')" -lt 18 ]]; then + log "installing Node 20 LTS" + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get install -y nodejs +fi + +# 3. Rust via rustup if not present +if ! command -v cargo >/dev/null; then + log "installing Rust via rustup" + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal + # shellcheck disable=SC1091 + source "$HOME/.cargo/env" +fi + +# 4. codeburn CLI (the Tauri app shells out to this for data) +if ! command -v codeburn >/dev/null; then + log "installing codeburn CLI from npm" + sudo npm install -g codeburn +fi + +# 5. Repo +if [[ -d "${CHECKOUT}/.git" ]]; then + log "updating existing checkout at ${CHECKOUT}" + git -C "${CHECKOUT}" fetch origin + git -C "${CHECKOUT}" checkout "${BRANCH}" + git -C "${CHECKOUT}" pull --ff-only origin "${BRANCH}" +else + log "cloning ${REPO_URL} into ${CHECKOUT}" + git clone --branch "${BRANCH}" "${REPO_URL}" "${CHECKOUT}" +fi + +# 6. npm deps for the desktop app +log "npm install for windows/" +(cd "${CHECKOUT}/windows" && npm install --no-audit --no-fund) + +# 7. Summary + next step +cat <CodeBurn + +

Run npm install && npm run tauri dev from windows/.

+ diff --git a/windows/index.html b/windows/index.html new file mode 100644 index 00000000..44d28a31 --- /dev/null +++ b/windows/index.html @@ -0,0 +1,12 @@ + + + + + + CodeBurn + + +
+ + + diff --git a/windows/package-lock.json b/windows/package-lock.json new file mode 100644 index 00000000..9694bd7c --- /dev/null +++ b/windows/package-lock.json @@ -0,0 +1,2069 @@ +{ + "name": "codeburn-menubar", + "version": "0.9.20", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "codeburn-menubar", + "version": "0.9.20", + "dependencies": { + "@tauri-apps/api": "^2.0.0", + "@tauri-apps/plugin-opener": "^2.0.0", + "@tauri-apps/plugin-shell": "^2.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@tauri-apps/cli": "^2.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@vitejs/plugin-react": "^4.3.0", + "typescript": "^5.6.0", + "vite": "^6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", + "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", + "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", + "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", + "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", + "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", + "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", + "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", + "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", + "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", + "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", + "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", + "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", + "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", + "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", + "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", + "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", + "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", + "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", + "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", + "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", + "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", + "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", + "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", + "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", + "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tauri-apps/api": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.10.1.tgz", + "integrity": "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.10.1.tgz", + "integrity": "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.10.1", + "@tauri-apps/cli-darwin-x64": "2.10.1", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1", + "@tauri-apps/cli-linux-arm64-gnu": "2.10.1", + "@tauri-apps/cli-linux-arm64-musl": "2.10.1", + "@tauri-apps/cli-linux-riscv64-gnu": "2.10.1", + "@tauri-apps/cli-linux-x64-gnu": "2.10.1", + "@tauri-apps/cli-linux-x64-musl": "2.10.1", + "@tauri-apps/cli-win32-arm64-msvc": "2.10.1", + "@tauri-apps/cli-win32-ia32-msvc": "2.10.1", + "@tauri-apps/cli-win32-x64-msvc": "2.10.1" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.1.tgz", + "integrity": "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.1.tgz", + "integrity": "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.1.tgz", + "integrity": "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.1.tgz", + "integrity": "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.1.tgz", + "integrity": "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.1.tgz", + "integrity": "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.1.tgz", + "integrity": "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.1.tgz", + "integrity": "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.1.tgz", + "integrity": "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.1.tgz", + "integrity": "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.1.tgz", + "integrity": "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/plugin-opener": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz", + "integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-shell": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.5.tgz", + "integrity": "sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.19.tgz", + "integrity": "sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001788", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz", + "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.340", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.340.tgz", + "integrity": "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", + "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.5" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", + "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.1", + "@rollup/rollup-android-arm64": "4.60.1", + "@rollup/rollup-darwin-arm64": "4.60.1", + "@rollup/rollup-darwin-x64": "4.60.1", + "@rollup/rollup-freebsd-arm64": "4.60.1", + "@rollup/rollup-freebsd-x64": "4.60.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", + "@rollup/rollup-linux-arm-musleabihf": "4.60.1", + "@rollup/rollup-linux-arm64-gnu": "4.60.1", + "@rollup/rollup-linux-arm64-musl": "4.60.1", + "@rollup/rollup-linux-loong64-gnu": "4.60.1", + "@rollup/rollup-linux-loong64-musl": "4.60.1", + "@rollup/rollup-linux-ppc64-gnu": "4.60.1", + "@rollup/rollup-linux-ppc64-musl": "4.60.1", + "@rollup/rollup-linux-riscv64-gnu": "4.60.1", + "@rollup/rollup-linux-riscv64-musl": "4.60.1", + "@rollup/rollup-linux-s390x-gnu": "4.60.1", + "@rollup/rollup-linux-x64-gnu": "4.60.1", + "@rollup/rollup-linux-x64-musl": "4.60.1", + "@rollup/rollup-openbsd-x64": "4.60.1", + "@rollup/rollup-openharmony-arm64": "4.60.1", + "@rollup/rollup-win32-arm64-msvc": "4.60.1", + "@rollup/rollup-win32-ia32-msvc": "4.60.1", + "@rollup/rollup-win32-x64-gnu": "4.60.1", + "@rollup/rollup-win32-x64-msvc": "4.60.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", + "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/windows/package.json b/windows/package.json new file mode 100644 index 00000000..bbf2b50d --- /dev/null +++ b/windows/package.json @@ -0,0 +1,28 @@ +{ + "name": "codeburn-menubar", + "private": true, + "version": "0.9.20", + "description": "CodeBurn menubar (tray) app for Windows, with experimental Linux support. Shares design tokens with the native macOS app under mac/.", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "preview": "vite preview", + "tauri": "tauri" + }, + "dependencies": { + "@tauri-apps/api": "^2.0.0", + "@tauri-apps/plugin-opener": "^2.0.0", + "@tauri-apps/plugin-shell": "^2.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@tauri-apps/cli": "^2.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@vitejs/plugin-react": "^4.3.0", + "typescript": "^5.6.0", + "vite": "^6.0.0" + } +} diff --git a/windows/src-tauri/Cargo.lock b/windows/src-tauri/Cargo.lock new file mode 100644 index 00000000..18765ad9 --- /dev/null +++ b/windows/src-tauri/Cargo.lock @@ -0,0 +1,6066 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[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.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "async-signal" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[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.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +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 = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +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.11.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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +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.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +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 = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link 0.2.1", +] + +[[package]] +name = "codeburn-menubar" +version = "0.9.20" +dependencies = [ + "anyhow", + "dirs 5.0.1", + "fontdue", + "ksni", + "png 0.17.16", + "reqwest 0.12.28", + "serde", + "serde_json", + "tauri", + "tauri-build", + "tauri-plugin-opener", + "tauri-plugin-shell", + "thiserror 1.0.69", + "tokio", + "windows-sys 0.59.0", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[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.11.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.11.1", + "core-foundation", + "libc", +] + +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[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.29.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "matches", + "phf 0.10.1", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[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 0.13.1", + "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.117", +] + +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[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.117", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.117", +] + +[[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.117", +] + +[[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 = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.6", + "windows-sys 0.48.0", +] + +[[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 0.5.2", + "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.11.1", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "dom_query" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +dependencies = [ + "bit-set", + "cssparser 0.36.0", + "foldhash 0.2.0", + "html5ever 0.38.0", + "precomputed-hash", + "selectors 0.36.1", + "tendril 0.5.0", +] + +[[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 = "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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63a1d0de4f2249aa0ff5884d7080814f446bb241a559af6c170a41e878ed2d45" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.9.12+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 = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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 = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[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.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "fontdue" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7894823fa221401399e2598f8b63f81ac77ff5c63248b7656779bff1632d7d3d" +dependencies = [ + "hashbrown 0.15.5", + "ttf-parser", +] + +[[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.117", +] + +[[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 = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[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-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[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.117", +] + +[[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 = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[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.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[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.11.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.117", +] + +[[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.117", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + +[[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 = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +dependencies = [ + "log", + "mac", + "markup5ever 0.14.1", + "match_token", +] + +[[package]] +name = "html5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +dependencies = [ + "log", + "markup5ever 0.38.0", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[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 = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png 0.18.1", +] + +[[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.0", + "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 = "iri-string" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[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.117", +] + +[[package]] +name = "js-sys" +version = "0.3.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "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.11.1", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "ksni" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ca513d0be42df5edb485af9f44a12b2cb85af773d91c27dc796d1c58b78edc" +dependencies = [ + "futures-util", + "pastey", + "serde", + "tokio", + "zbus", +] + +[[package]] +name = "kuchikiki" +version = "0.8.8-speedreader" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" +dependencies = [ + "cssparser 0.29.6", + "html5ever 0.29.1", + "indexmap 2.14.0", + "selectors 0.24.0", +] + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[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.185" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" + +[[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 = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +dependencies = [ + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[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.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "markup5ever" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +dependencies = [ + "log", + "phf 0.11.3", + "phf_codegen 0.11.3", + "string_cache 0.8.9", + "string_cache_codegen 0.5.4", + "tendril 0.4.3", +] + +[[package]] +name = "markup5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +dependencies = [ + "log", + "tendril 0.5.0", + "web_atoms", +] + +[[package]] +name = "match_token" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "muda" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9fec5a4e89860383d778d10563a605838f8f0b2f9303868937e5ff32e86177" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "once_cell", + "png 0.17.16", + "serde", + "thiserror 2.0.18", + "windows-sys 0.60.2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.11.1", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[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 = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-conv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" + +[[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.117", +] + +[[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.11.1", + "block2", + "objc2", + "objc2-core-foundation", + "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.11.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.11.1", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[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.11.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.11.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.11.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.11.1", + "objc2", + "objc2-core-foundation", + "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.11.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 = "open" +version = "5.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" +dependencies = [ + "dunce", + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "os_pipe" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[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" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[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 = "pastey" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared 0.8.0", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros 0.13.1", + "phf_shared 0.13.1", + "serde", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_codegen" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.6", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.6", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared 0.13.1", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.2", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.2", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" +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.11.1", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + +[[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 = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[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.11+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-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[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 = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.4", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +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 = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[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.11.1", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[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.117", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.11.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[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.117", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" +dependencies = [ + "bitflags 1.3.2", + "cssparser 0.29.6", + "derive_more 0.99.20", + "fxhash", + "log", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc 0.2.0", + "smallvec", +] + +[[package]] +name = "selectors" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +dependencies = [ + "bitflags 2.11.1", + "cssparser 0.36.0", + "derive_more 2.1.1", + "log", + "new_debug_unreachable", + "phf 0.13.1", + "phf_codegen 0.13.1", + "precomputed-hash", + "rustc-hash", + "servo_arc 0.4.3", + "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.117", +] + +[[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.117", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +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.117", +] + +[[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_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" +dependencies = [ + "base64 0.22.1", + "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.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "servo_arc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[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 = "shared_child" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" +dependencies = [ + "libc", + "sigchld", + "windows-sys 0.60.2", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sigchld" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" +dependencies = [ + "libc", + "os_pipe", + "signal-hook", +] + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +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.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[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 0.13.1", + "precomputed-hash", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "string_cache_codegen" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", + "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", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +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.117", +] + +[[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.34.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9103edf55f2da3c82aea4c7fab7c4241032bfeea0e71fa557d98e00e7ce7cc20" +dependencies = [ + "bitflags 2.11.1", + "block2", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch2", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "jni", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "parking_lot", + "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.117", +] + +[[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.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da77cc00fb9028caf5b5d4650f75e31f1ef3693459dfca7f7e506d1ecef0ba2d" +dependencies = [ + "anyhow", + "bytes", + "cookie", + "dirs 6.0.0", + "dunce", + "embed_plist", + "getrandom 0.3.4", + "glob", + "gtk", + "heck 0.5.0", + "http", + "image", + "jni", + "libc", + "log", + "mime", + "muda", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "percent-encoding", + "plist", + "raw-window-handle", + "reqwest 0.13.2", + "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.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bbc990d1dbf57a8e1c7fa2327f2a614d8b757805603c1b9ba5c81bade09fd4d" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs 6.0.0", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "toml 0.9.12+spec-1.1.0", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a24476afd977c5d5d169f72425868613d82747916dd29e0a357c84c4bd6d29" +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.117", + "tauri-utils", + "thiserror 2.0.18", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d39b349a98dadaffebb73f0a40dcd1f23c999211e5a2e744403db384d0c33de7" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-plugin" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddde7d51c907b940fb573006cdda9a642d6a7c8153657e88f8a5c3c9290cd4aa" +dependencies = [ + "anyhow", + "glob", + "plist", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri-utils", + "toml 0.9.12+spec-1.1.0", + "walkdir", +] + +[[package]] +name = "tauri-plugin-opener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc624469b06f59f5a29f874bbc61a2ed737c0f9c23ef09855a292c389c42e83f" +dependencies = [ + "dunce", + "glob", + "objc2-app-kit", + "objc2-foundation", + "open", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror 2.0.18", + "url", + "windows", + "zbus", +] + +[[package]] +name = "tauri-plugin-shell" +version = "2.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8457dbf9e2bab1edd8df22bb2c20857a59a9868e79cb3eac5ed639eec4d0c73b" +dependencies = [ + "encoding_rs", + "log", + "open", + "os_pipe", + "regex", + "schemars 0.8.22", + "serde", + "serde_json", + "shared_child", + "tauri", + "tauri-plugin", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "tauri-runtime" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2826d79a3297ed08cd6ea7f412644ef58e32969504bc4fbd8d7dbeabc4445ea2" +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.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" +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.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219a1f983a2af3653f75b5747f76733b0da7ff03069c7a41901a5eb3ace4557d" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dunce", + "glob", + "html5ever 0.29.1", + "http", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.18", + "toml 0.9.12+spec-1.1.0", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1087b111fe2b005e42dbdc1990fc18593234238d47453b0c99b7de1c9ab2c1e0" +dependencies = [ + "dunce", + "embed-resource", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "tendril" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" +dependencies = [ + "new_debug_unreachable", + "utf-8", +] + +[[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.117", +] + +[[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.117", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +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.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.52.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[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_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.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.1", +] + +[[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.1", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.11.1", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[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-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e85aa143ceb072062fc4d6356c1b520a51d636e7bc8e77ec94be3608e5e80c" +dependencies = [ + "crossbeam-channel", + "dirs 6.0.0", + "libappindicator", + "muda", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "once_cell", + "png 0.17.16", + "serde", + "thiserror 2.0.18", + "windows-sys 0.60.2", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "uds_windows" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" +dependencies = [ + "memoffset", + "tempfile", + "windows-sys 0.61.2", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[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 = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +dependencies = [ + "getrandom 0.4.2", + "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.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[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.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.14.0", + "wasm-encoder", + "wasmparser", +] + +[[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 = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.1", + "hashbrown 0.15.5", + "indexmap 2.14.0", + "semver", +] + +[[package]] +name = "web-sys" +version = "0.3.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web_atoms" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a9779e9f04d2ac1ce317aee707aa2f6b773afba7b931222bff6983843b1576" +dependencies = [ + "phf 0.13.1", + "phf_codegen 0.13.1", + "string_cache 0.9.0", + "string_cache_codegen 0.6.1", +] + +[[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 = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +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.117", +] + +[[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.117", +] + +[[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.117", +] + +[[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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[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.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[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 0.52.6", + "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-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[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_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[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_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[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" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +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.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.14.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.1", + "indexmap 2.14.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.14.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "wry" +version = "0.54.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a8135d8676225e5744de000d4dff5a082501bf7db6a1c1495034f8c314edbc" +dependencies = [ + "base64 0.22.1", + "block2", + "cookie", + "crossbeam-channel", + "dirs 6.0.0", + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +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.117", + "synstructure", +] + +[[package]] +name = "zbus" +version = "5.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix", + "serde", + "serde_repr", + "tokio", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow 0.7.15", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +dependencies = [ + "serde", + "winnow 0.7.15", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zerofrom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +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.117", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[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.117", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zvariant" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow 0.7.15", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.117", + "winnow 0.7.15", +] diff --git a/windows/src-tauri/Cargo.toml b/windows/src-tauri/Cargo.toml new file mode 100644 index 00000000..548afcba --- /dev/null +++ b/windows/src-tauri/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "codeburn-menubar" +version = "0.9.20" +description = "CodeBurn menubar (tray) app for Windows and Linux" +authors = ["AgentSeal"] +edition = "2021" +rust-version = "1.80" + +[lib] +name = "codeburn_menubar_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2", features = ["tray-icon", "image-png"] } +tauri-plugin-opener = "2" +tauri-plugin-shell = "2" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +tokio = { version = "1", features = ["process", "io-util", "rt-multi-thread", "macros", "time", "sync"] } +thiserror = "1" +anyhow = "1" +dirs = "5" +reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } +fontdue = "0.9" + +[target.'cfg(target_os = "windows")'.dependencies] +windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_Graphics_Dwm", "Win32_UI_WindowsAndMessaging"] } + +[target.'cfg(target_os = "linux")'.dependencies] +ksni = "0.3" +png = "0.17" + +[features] +default = ["custom-protocol"] +# This feature is used for production builds or when a dev server is not specified. Don't +# change it unless you know what you're doing. +custom-protocol = ["tauri/custom-protocol"] diff --git a/windows/src-tauri/build.rs b/windows/src-tauri/build.rs new file mode 100644 index 00000000..d860e1e6 --- /dev/null +++ b/windows/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/windows/src-tauri/capabilities/default.json b/windows/src-tauri/capabilities/default.json new file mode 100644 index 00000000..e227dc18 --- /dev/null +++ b/windows/src-tauri/capabilities/default.json @@ -0,0 +1,20 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Default permissions for the CodeBurn tray app window", + "windows": ["popover"], + "permissions": [ + "core:default", + "core:window:allow-close", + "core:window:allow-hide", + "core:window:allow-show", + "core:window:allow-set-focus", + "core:window:allow-set-position", + "core:window:allow-set-size", + "core:tray:default", + "core:event:allow-listen", + "core:event:allow-emit", + "opener:default", + "shell:default" + ] +} diff --git a/windows/src-tauri/icons/128x128.png b/windows/src-tauri/icons/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..2682d60672f81a8f0cbe4b1a5bc3a1eadddbd63e GIT binary patch literal 16212 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 QPIwp@NuWfPm{H*W1B0}V!2kdN literal 0 HcmV?d00001 diff --git a/windows/src-tauri/icons/128x128@2x.png b/windows/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4942be53c2c6a89ba09f59b4c79ff6cf0142afd0 GIT binary patch literal 60726 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 z

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⁡FWLVi6q~U0V zox9U=Ib0FI)({gr@T_lspynvq2|9osVO zobQ*+nQloe2{p3FE^(w`1lNaUvN28kJw~<&(r;8Yr<#SaE<|FZC`Go6;M$NRwkGOX zYuB?s+sv&oX&i49%xZ_0b>T)Xbc*NZ=q&aY2C_0h;=Rg1ZcIw&QqMScMi|&0t>aRQ zXjUca$aQs-N2>`Rgi%%{Ep>jfF-x@T3m=AIR*fwBNv!5dHzF&t?dPIq57 ziap$Er}bi9l!e;9?(*gqr+!zxf^NDOiZo&PA*T0;5mxaoRS6Tu6z-n%wP|Rj@}`$g z#pVb-r)$`_H9DO`d3rVnY1kgF;!>Abu5^iESEPnb!FmoB*!XBjD(`07SRZ6$OT3xO zJ<@qM+s^VpJxhbN9IF|{<<@bmbm&+RAWCp%&UZ{=ONxbgb{%sZI(8NYalUghYvPP7 zup3wzs^dcI7!FkiG21RN%PO(IGLjQbqM2`#m}NJxG1bPomI6ymCiXc`7s#z5*ak^;)m%AsjK0?Pbn~uF%b}n~}XG63}CO?-4 z={V6af{X29*%GB=b&#I@1p!>?naIv~Bb!2uY>zc@xl;yHg4Lvm$-wSj)b#UWq)kVu zhX=u~)ktu0VTe`BKyhbxbs^EEDxJ+r<|i4c=UI)~KA!Ycy0X7%5Xakvve@dv{V6T^ z%jI=^y>AttzPp}XQ%2LXJdH9j2hgUH<-e)s7wmtG2mrdjevaNo{2~H?xX+0!K$Lex zNl*-Z5Pjdm1FmVjo=s!=adGK<9<7+px7#N1$896HH7tkESLE`=oHSOH*l1Ao9eGO7 zx+oK?;{u4P>Pic(FY_G|3&YH`&?>RM<3epeAGRk2ljkLde2PJqu1pOvGQ**xkECLA zjDe?1s&jWzHcu9mu+i?%=_V08nv=uhg(aM77R`E_Klf*sacguocPAFG)TUxpsDXR4 z%Xq&_Jo8MFym|N4iRRO#HCYj5V7f)e;&3ew=ho&#n{wJeD=@o-8pAN5V=YX2Oj zsQfwEG=}T_Q@A%gpH*pgChE1kTR)D+vn%8)%0!ca#W6-6&#TSu%5cU=8YY_c9B!V# zDita#FGhyJQ|nF`|T50VwBjGYvYTpH8@Zn%<2F=8)D4d>Y2^@6f@~n-AHnEXJ)98 zNj5DrLQRCcQ;oKgf~8?b*2dZBYE%*0)H0`ddY zlsR5Zf|=f-Hs=@5;`0r&`Q84h{BU>@Kc4H)odFIW_HnSMT@>xzt8pyPK_5Riwx`%h za&@7vSM;9_lt>8+JWcHT? zaIJGH+si^3E$NvXDRF&Z3Nr(>jIo;;ukqzluOzlt4`QTF!x*EEMX@?=jmlzHfQHFt z9XEz$u{+<$-J#-I;NU=waBdGy;Z!XPH-~02-JoNZ-j`d06WCD{z$}BFgLR|0*)xfA z4TJe`a0Uy_dRADJ+@6rezVZN8J4~z$F>)x$z|sgkY1Q1w@bq9|go!4et}KkO5F;3W ztCpdXKa(92ql0uLRCA&5ohlrv45p{Si$>L4IMhCzyZyqr+||qXc1HfAZk9{dEgU{BMabr|EYph!KmN#?V9 z3}f^f7RH)*Jg*iXPp-~%ahhAyd^j+R$J5I=);f`q{wlVWh4Nr@A$JGnFf-D~P`$*y z28ldhRD*SeVGNQqER47Cbbc*9=$Fe#i-zGw4ezx`=K1=DtS<^?lt#<`#xXpcT+Gek z*~|zsurS)h{qY$*on6Gcbs`umX;_~V$n%voINvLqnKmOU;>>(9E}u{5Rq}4F2xjOd z_LPM1e0OcG4oPE0fQ~g$W^N75XJ=6$CGMWYxVSLVp<_*?jS+S&AyunUTj9;>XbW4C z18Ac5B}sS$hU>ULIF+>}0kn2^WmT4uPuG?4<+~O9<=iBGdvFcEIkuiBdpB}&@eIba zu1kZ&0P<|gpVWVe=9l+>otiLb8Sw3ah~__K0WT{8IYJj8j6&>61~n{V$Mn%$TDy!- zcCO>|T`T$ByR-Q9mKL0@)G=Glr0(O47VXO2NsN4mL!oSrKGoWssgDb#1&`>0oxC z#EbwV%OZ6gtQX3HFdY-DMrH&X*j`{^bAABRg7l0tX<3$NWLISXi{dPdwHlZjq-Rr6 zAZv4Ma(}`Iy^dKCI(F9zW`ae*D3ggXMm?MJZ7fPKGsvi8kXd3;l7+2h0ZflHF~p>2 zVxXRlg?5&t+2p~ZBTPD0rrFq8GnhHiRz{l4jJHZ`E^)9R&cY~@k NtAtFrhMfr( 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 Result { + use std::os::windows::process::CommandExt; + const CREATE_NO_WINDOW: u32 = 0x08000000; + std::process::Command::new("reg") + .args(args) + .creation_flags(CREATE_NO_WINDOW) + .output() + .with_context(|| "failed to run reg.exe") +} + +#[cfg(target_os = "windows")] +pub fn is_enabled() -> bool { + reg(&["query", RUN_KEY, "/v", APP_NAME]) + .map(|out| out.status.success()) + .unwrap_or(false) +} + +#[cfg(target_os = "windows")] +pub fn set_enabled(enabled: bool) -> Result<()> { + if enabled { + let exe = std::env::current_exe().with_context(|| "cannot resolve current exe")?; + let value = format!("\"{}\"", exe.display()); + let out = reg(&["add", RUN_KEY, "/v", APP_NAME, "/t", "REG_SZ", "/d", &value, "/f"])?; + if !out.status.success() { + return Err(anyhow!(String::from_utf8_lossy(&out.stderr).trim().to_string())); + } + } else { + let out = reg(&["delete", RUN_KEY, "/v", APP_NAME, "/f"])?; + // Deleting a value that does not exist is the state we want anyway. + if !out.status.success() && is_enabled() { + return Err(anyhow!(String::from_utf8_lossy(&out.stderr).trim().to_string())); + } + } + Ok(()) +} + +#[cfg(target_os = "linux")] +fn desktop_file() -> Option { + dirs::config_dir().map(|d| d.join("autostart").join("codeburn-menubar.desktop")) +} + +#[cfg(target_os = "linux")] +pub fn is_enabled() -> bool { + desktop_file().map(|p| p.is_file()).unwrap_or(false) +} + +#[cfg(target_os = "linux")] +pub fn set_enabled(enabled: bool) -> Result<()> { + let path = desktop_file().ok_or_else(|| anyhow!("no config dir"))?; + if enabled { + let exe = std::env::current_exe().with_context(|| "cannot resolve current exe")?; + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent)?; + } + std::fs::write( + &path, + format!( + "[Desktop Entry]\nType=Application\nName={APP_NAME}\nExec=\"{}\"\nX-GNOME-Autostart-enabled=true\n", + exe.display() + ), + )?; + } else if path.exists() { + std::fs::remove_file(&path)?; + } + Ok(()) +} + +#[cfg(target_os = "macos")] +pub fn is_enabled() -> bool { + false +} + +#[cfg(target_os = "macos")] +pub fn set_enabled(_enabled: bool) -> Result<()> { + Err(anyhow!("launch at login is handled by the native macOS app")) +} diff --git a/windows/src-tauri/src/cli.rs b/windows/src-tauri/src/cli.rs new file mode 100644 index 00000000..84f2b358 --- /dev/null +++ b/windows/src-tauri/src/cli.rs @@ -0,0 +1,499 @@ +use std::env; +use std::path::PathBuf; +use std::process::Stdio; + +use anyhow::{anyhow, bail, Context, Result}; +use serde::Serialize; +use serde_json::Value; +use tauri::AppHandle; +use tokio::io::AsyncReadExt; +use tokio::process::Command; +use tokio::time::{timeout, Duration}; + +/// Hard bounds mirror the macOS CodeburnCLI / DataClient design. A malicious or stuck CLI +/// cannot pin the Tauri process: stdout is capped, stderr is bounded, total wall time is +/// 60s. A hostile CODEBURN_BIN is rejected before any shell-resembling path is taken. +const MAX_PAYLOAD_BYTES: usize = 20 * 1024 * 1024; +const MAX_STDERR_BYTES: usize = 256 * 1024; +const FETCH_TIMEOUT_SECS: u64 = 60; +const VERSION_TIMEOUT_SECS: u64 = 20; + +/// Oldest CLI that emits the `menubar-json` shape this app renders (history.daily with +/// per-day model breakdown, providers map). Older CLIs get the setup screen instead of a +/// half-rendered popover. +pub const MIN_CLI_VERSION: (u32, u32, u32) = (0, 7, 0); + +#[cfg(windows)] +const WINDOWS_CLI_NAMES: [&str; 2] = ["codeburn.cmd", "codeburn.exe"]; + +/// Alphanumerics plus `._/-` and space, with `\`, `:`, `(`, `)` also allowed on Windows +/// so a user-supplied `CODEBURN_BIN` path like `C:\Users\...\codeburn.cmd` is accepted. +/// None of these are shell metacharacters in a direct-argv spawn (we never invoke `sh -c`). +fn is_safe_arg(value: &str) -> bool { + !value.is_empty() + && value.chars().all(|c| { + c.is_ascii_alphanumeric() + || matches!(c, '.' | '_' | '/' | '-' | ' ') + || (cfg!(windows) && matches!(c, '\\' | ':' | '(' | ')')) + }) +} + +#[derive(Clone, Debug)] +pub struct CodeburnCli { + program: String, + extra_args: Vec, +} + +/// What the setup screen needs to know about the CLI on this machine. +#[derive(Clone, Debug, Serialize)] +pub struct CliStatus { + pub found: bool, + pub program: String, + pub version: Option, + pub min_version: String, + pub compatible: bool, + pub error: Option, +} + +impl CodeburnCli { + /// Honours `CODEBURN_BIN` only when every whitespace-delimited token passes the + /// allowlist. Otherwise resolves `codeburn` from PATH and the usual npm locations. + pub fn resolve() -> Self { + let raw = env::var("CODEBURN_BIN").unwrap_or_default(); + if raw.is_empty() { + return Self::default_program(); + } + // A bare path (which may contain spaces, e.g. under Program Files) is used whole; + // only otherwise is the value split into program + leading arguments. + if is_safe_arg(&raw) && std::path::Path::new(&raw).is_file() { + return CodeburnCli { + program: raw, + extra_args: vec![], + }; + } + let parts: Vec = raw.split_whitespace().map(String::from).collect(); + if parts.iter().all(|p| is_safe_arg(p)) { + if let Some((first, rest)) = parts.split_first() { + return CodeburnCli { + program: first.clone(), + extra_args: rest.to_vec(), + }; + } + } + eprintln!("codeburn-menubar: refusing unsafe CODEBURN_BIN; falling back to `codeburn`"); + Self::default_program() + } + + fn default_program() -> Self { + CodeburnCli { + program: locate_cli().unwrap_or_else(default_program_name), + extra_args: vec![], + } + } + + pub fn program(&self) -> &str { + &self.program + } + + /// Runs `codeburn --version` and reports whether the CLI is present and new enough. + pub async fn status(&self) -> CliStatus { + let min_version = format!( + "{}.{}.{}", + MIN_CLI_VERSION.0, MIN_CLI_VERSION.1, MIN_CLI_VERSION.2 + ); + let mut status = CliStatus { + found: false, + program: self.program.clone(), + version: None, + min_version, + compatible: false, + error: None, + }; + match self.run_capture(&["--version"], VERSION_TIMEOUT_SECS).await { + Ok(out) => { + let version = out.trim().to_string(); + status.found = true; + status.compatible = parse_version(&version) + .map(|v| v >= MIN_CLI_VERSION) + .unwrap_or(false); + status.version = Some(version); + } + Err(err) => { + status.error = Some(err.to_string()); + } + } + status + } + + /// Spawns `codeburn status --format menubar-json --period X --provider Y` and decodes the + /// output. Pipes are drained concurrently so a chatty stderr cannot deadlock stdout. + pub async fn fetch_menubar_payload( + &self, + period: &str, + provider: &str, + include_optimize: bool, + ) -> Result { + if !is_safe_arg(period) || !is_safe_arg(provider) { + bail!("invalid period/provider argument"); + } + + let mut args = vec![ + "status", + "--format", + "menubar-json", + "--period", + period, + "--provider", + provider, + ]; + if !include_optimize { + args.push("--no-optimize"); + } + + let stdout = self.run_capture(&args, FETCH_TIMEOUT_SECS).await?; + let payload: Value = + serde_json::from_str(&stdout).with_context(|| "CLI returned invalid JSON")?; + Ok(payload) + } + + async fn run_capture(&self, args: &[&str], timeout_secs: u64) -> Result { + let mut full_args = self.extra_args.clone(); + full_args.extend(args.iter().map(|s| s.to_string())); + + let mut cmd = Command::new(&self.program); + cmd.args(&full_args) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .kill_on_drop(true); + #[cfg(windows)] + { + const CREATE_NO_WINDOW: u32 = 0x08000000; + cmd.creation_flags(CREATE_NO_WINDOW); + } + let mut child = cmd.spawn().map_err(|err| { + anyhow!( + "CodeBurn CLI not found ({}). Install it with `npm install -g codeburn`.", + spawn_error_summary(&self.program, &err) + ) + })?; + + let mut stdout = child.stdout.take().ok_or_else(|| anyhow!("no stdout"))?; + let mut stderr = child.stderr.take().ok_or_else(|| anyhow!("no stderr"))?; + + let stdout_task = tokio::spawn(async move { + let mut buf = Vec::with_capacity(64 * 1024); + let mut limited = (&mut stdout).take(MAX_PAYLOAD_BYTES as u64); + limited.read_to_end(&mut buf).await.ok(); + buf + }); + let stderr_task = tokio::spawn(async move { + let mut buf = Vec::with_capacity(4 * 1024); + let mut limited = (&mut stderr).take(MAX_STDERR_BYTES as u64); + limited.read_to_end(&mut buf).await.ok(); + buf + }); + + let status = timeout(Duration::from_secs(timeout_secs), child.wait()) + .await + .map_err(|_| anyhow!("codeburn CLI timed out after {}s", timeout_secs))??; + + let stdout_bytes = stdout_task.await.unwrap_or_default(); + let stderr_bytes = stderr_task.await.unwrap_or_default(); + + if !status.success() { + let msg = String::from_utf8_lossy(&stderr_bytes); + bail!("codeburn CLI exited {}: {}", status, msg.trim()); + } + Ok(String::from_utf8_lossy(&stdout_bytes).into_owned()) + } +} + +fn spawn_error_summary(program: &str, err: &std::io::Error) -> String { + match err.kind() { + std::io::ErrorKind::NotFound => format!("{} is not on PATH", program), + _ => format!("{}: {}", program, err), + } +} + +fn default_program_name() -> String { + #[cfg(windows)] + { + "codeburn.cmd".to_string() + } + #[cfg(not(windows))] + { + "codeburn".to_string() + } +} + +/// Parses "0.7.3" or "codeburn 0.7.3" into a comparable tuple. +pub fn parse_version(text: &str) -> Option<(u32, u32, u32)> { + let token = text + .split_whitespace() + .find(|t| t.chars().next().map(|c| c.is_ascii_digit()).unwrap_or(false))?; + let mut parts = token.split('.').map(|p| { + p.chars() + .take_while(|c| c.is_ascii_digit()) + .collect::() + .parse::() + .ok() + }); + Some((parts.next()??, parts.next()??, parts.next().flatten().unwrap_or(0))) +} + +/// Locates the CLI without relying on the inherited PATH being fresh. A tray app is often +/// launched from Explorer or at login, before (or long after) `npm install -g codeburn` +/// changed the user's PATH, so we also read the live PATH from the registry on Windows and +/// probe the standard npm / node install prefixes. +fn locate_cli() -> Option { + let mut dirs: Vec = Vec::new(); + if let Some(path) = env::var_os("PATH") { + dirs.extend(env::split_paths(&path)); + } + dirs.extend(extra_search_dirs()); + + for dir in dirs { + for name in candidate_names() { + let candidate = dir.join(name); + if candidate.is_file() { + return Some(candidate.to_string_lossy().into_owned()); + } + } + } + None +} + +fn candidate_names() -> Vec<&'static str> { + #[cfg(windows)] + { + WINDOWS_CLI_NAMES.to_vec() + } + #[cfg(not(windows))] + { + vec!["codeburn"] + } +} + +#[cfg(windows)] +fn extra_search_dirs() -> Vec { + let mut out = Vec::new(); + for var in ["APPDATA", "LOCALAPPDATA", "ProgramFiles", "ProgramFiles(x86)"] { + if let Some(base) = env::var_os(var).map(PathBuf::from) { + match var { + "APPDATA" => out.push(base.join("npm")), + "LOCALAPPDATA" => { + out.push(base.join("Programs").join("nodejs")); + out.push(base.join("pnpm")); + out.push(base.join("Volta").join("bin")); + out.push(base.join("fnm_multishells")); + } + _ => out.push(base.join("nodejs")), + } + } + } + if let Some(home) = dirs::home_dir() { + out.push(home.join("scoop").join("shims")); + out.push(home.join(".bun").join("bin")); + } + out.extend(registry_path_dirs()); + out +} + +#[cfg(not(windows))] +fn extra_search_dirs() -> Vec { + let mut out = vec![ + PathBuf::from("/opt/homebrew/bin"), + PathBuf::from("/usr/local/bin"), + ]; + if let Some(home) = dirs::home_dir() { + out.push(home.join(".npm-global").join("bin")); + out.push(home.join(".local").join("bin")); + } + out +} + +/// Reads the user and machine PATH values from the registry via `reg.exe` so a PATH edit +/// made after this process started (npm install adds `%APPDATA%\npm`) is still honoured. +#[cfg(windows)] +fn registry_path_dirs() -> Vec { + use std::os::windows::process::CommandExt; + const CREATE_NO_WINDOW: u32 = 0x08000000; + let mut out = Vec::new(); + let keys = [ + r"HKCU\Environment", + r"HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", + ]; + for key in keys { + let output = std::process::Command::new("reg") + .args(["query", key, "/v", "Path"]) + .creation_flags(CREATE_NO_WINDOW) + .output(); + let Ok(output) = output else { continue }; + let text = String::from_utf8_lossy(&output.stdout); + for line in text.lines() { + let trimmed = line.trim(); + if !trimmed.starts_with("Path") { + continue; + } + let Some(idx) = trimmed.find("REG_") else { continue }; + let rest = &trimmed[idx..]; + let Some(space) = rest.find(char::is_whitespace) else { continue }; + let value = rest[space..].trim(); + for part in value.split(';') { + let expanded = expand_env(part.trim()); + if !expanded.is_empty() { + out.push(PathBuf::from(expanded)); + } + } + } + } + out +} + +#[cfg(windows)] +fn expand_env(value: &str) -> String { + let mut result = String::with_capacity(value.len()); + let mut rest = value; + while let Some(start) = rest.find('%') { + result.push_str(&rest[..start]); + let after = &rest[start + 1..]; + match after.find('%') { + Some(end) => { + let name = &after[..end]; + match env::var(name) { + Ok(v) => result.push_str(&v), + Err(_) => { + result.push('%'); + result.push_str(name); + result.push('%'); + } + } + rest = &after[end + 1..]; + } + None => { + result.push_str(&rest[start..]); + rest = ""; + } + } + } + result.push_str(rest); + result +} + +/// Runs a codeburn subcommand in the user's terminal emulator so they can see the output. +/// Linux: tries `x-terminal-emulator`, `gnome-terminal`, `konsole`, then falls back to a +/// detached headless spawn. Windows: opens a console via `cmd /C start`. Never +/// interpolates through a shell -- argv throughout. +pub fn spawn_in_terminal(app: &AppHandle, subcommand: &[&str]) -> Result<()> { + let cli = CodeburnCli::resolve(); + spawn_program_in_terminal(app, &cli, subcommand) +} + +/// The Plan view's "Connect Claude" runs Claude Code's own login flow, not codeburn. The +/// bare name is deliberate: on Windows the console shell resolves `claude.exe` (native +/// installer) or `claude.cmd` (npm) through PATHEXT. +pub fn spawn_claude_login(app: &AppHandle) -> Result<()> { + let cli = CodeburnCli { + program: "claude".to_string(), + extra_args: vec![], + }; + spawn_program_in_terminal(app, &cli, &["login"]) +} + +fn spawn_program_in_terminal(_app: &AppHandle, cli: &CodeburnCli, subcommand: &[&str]) -> Result<()> { + if !subcommand.iter().all(|s| is_safe_arg(s)) { + bail!("unsafe subcommand argument"); + } + + #[cfg(target_os = "linux")] + { + let terminals: [&[&str]; 4] = [ + &["x-terminal-emulator", "-e"], + &["gnome-terminal", "--", "bash", "-lc"], + &["konsole", "-e"], + &["xterm", "-e"], + ]; + for term in &terminals { + let program = term[0]; + let extras = &term[1..]; + if which::which(program).is_ok() { + let mut command_parts: Vec = vec![cli.program.clone()]; + command_parts.extend(cli.extra_args.clone()); + command_parts.extend(subcommand.iter().map(|s| s.to_string())); + // gnome-terminal wants the whole command as a single argv after `--` + // followed by `bash -lc`. The allowlist guarantees no quoting is needed. + let composite = command_parts.join(" "); + let mut cmd = std::process::Command::new(program); + cmd.args(extras); + cmd.arg(&composite); + cmd.spawn().with_context(|| format!("failed to launch {}", program))?; + return Ok(()); + } + } + // Fallback: run detached, output lost -- better than silently doing nothing. + std::process::Command::new(&cli.program) + .args(&cli.extra_args) + .args(subcommand) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .with_context(|| "no terminal emulator found, detached spawn also failed")?; + } + + #[cfg(target_os = "windows")] + { + // `start` treats the first quoted argument as the window title, so we pass an + // explicit empty title. `/K` keeps the console open for non-interactive commands + // (export) so the user can read where the file went; the TUI (report/optimize) + // owns the window until the user quits it either way. + let is_codeburn = cli.program.starts_with("codeburn"); + let program = if std::path::Path::new(&cli.program).is_absolute() || !is_codeburn { + cli.program.clone() + } else { + locate_cli().unwrap_or_else(|| cli.program.clone()) + }; + let mut cmd = std::process::Command::new("cmd"); + cmd.arg("/C").arg("start").arg("").arg("cmd").arg("/K").arg(&program); + for a in &cli.extra_args { + cmd.arg(a); + } + for a in subcommand { + cmd.arg(a); + } + cmd.spawn().with_context(|| "failed to open cmd.exe")?; + } + + #[cfg(target_os = "macos")] + { + // macOS isn't our target for this app (Swift handles Mac), but keep dev-on-Mac working. + std::process::Command::new(&cli.program) + .args(&cli.extra_args) + .args(subcommand) + .spawn() + .with_context(|| format!("failed to spawn {}", cli.program))?; + } + + Ok(()) +} + +/// Minimal dependency: we only use `which` inside spawn_in_terminal on Linux. Vendored here +/// so the crate graph stays tiny. Gated so the unused-function warning doesn't fire on Mac +/// or Windows builds. +#[cfg(target_os = "linux")] +mod which { + use std::env; + use std::path::PathBuf; + + pub fn which(program: &str) -> Result { + let path = env::var_os("PATH").ok_or(())?; + for dir in env::split_paths(&path) { + let candidate = dir.join(program); + if candidate.is_file() { + return Ok(candidate); + } + } + Err(()) + } +} diff --git a/windows/src-tauri/src/config.rs b/windows/src-tauri/src/config.rs new file mode 100644 index 00000000..29787ff1 --- /dev/null +++ b/windows/src-tauri/src/config.rs @@ -0,0 +1,161 @@ +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +use anyhow::{Context, Result}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct CurrencyConfig { + #[serde(default, flatten)] + extra: serde_json::Map, +} + +fn codeburn_config_dir() -> PathBuf { + dirs::home_dir() + .map(|h| h.join(".config/codeburn")) + .unwrap_or_else(|| PathBuf::from(".codeburn")) +} + +fn config_path() -> PathBuf { + codeburn_config_dir().join("config.json") +} + +fn lock_path() -> PathBuf { + codeburn_config_dir().join(".config.lock") +} + +impl CurrencyConfig { + pub fn load_or_default() -> Self { + match fs::read(config_path()) { + Ok(bytes) => serde_json::from_slice(&bytes).unwrap_or_default(), + Err(_) => Self::default(), + } + } + + pub fn set_currency(&mut self, code: &str, symbol: &str) -> Result<()> { + fs::create_dir_all(codeburn_config_dir()) + .with_context(|| "failed to create ~/.config/codeburn")?; + + #[cfg(unix)] + let _lock = unix_lock::acquire()?; + #[cfg(windows)] + let _lock = windows_lock::acquire()?; + + let mut disk: serde_json::Value = match fs::read(config_path()) { + Ok(bytes) => serde_json::from_slice(&bytes).unwrap_or_else(|_| serde_json::json!({})), + Err(_) => serde_json::json!({}), + }; + + if code == "USD" { + if let Some(obj) = disk.as_object_mut() { + obj.remove("currency"); + } + } else if let Some(obj) = disk.as_object_mut() { + obj.insert( + "currency".into(), + serde_json::json!({ "code": code, "symbol": symbol }), + ); + } + + let serialized = serde_json::to_vec_pretty(&disk)?; + let tmp = config_path().with_extension("tmp"); + { + let mut file = fs::OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(&tmp)?; + file.write_all(&serialized)?; + file.flush()?; + } + fs::rename(&tmp, config_path())?; + + *self = serde_json::from_value(disk).unwrap_or_default(); + Ok(()) + } +} + +#[cfg(unix)] +mod unix_lock { + use std::fs; + use std::os::fd::AsRawFd; + use anyhow::{anyhow, Context, Result}; + + pub struct Guard { + _file: fs::File, + } + + pub fn acquire() -> Result { + let file = fs::OpenOptions::new() + .create(true) + .read(true) + .write(true) + .open(super::lock_path()) + .with_context(|| "failed to open config lock")?; + + let fd = file.as_raw_fd(); + let ret = unsafe { flock(fd, 2) }; + if ret != 0 { + return Err(anyhow!("flock failed: {}", std::io::Error::last_os_error())); + } + Ok(Guard { _file: file }) + } + + extern "C" { + fn flock(fd: i32, operation: i32) -> i32; + } +} + +/// Windows has no flock; a create-new lock file gives the same mutual exclusion against +/// the CLI's own writer. Stale locks (crash mid-write) are ignored once older than +/// STALE_LOCK_SECS so a single crash can never wedge currency changes forever. +#[cfg(windows)] +mod windows_lock { + use std::fs; + use std::path::PathBuf; + use std::thread::sleep; + use std::time::{Duration, SystemTime}; + use anyhow::{anyhow, Result}; + + const RETRY_INTERVAL: Duration = Duration::from_millis(40); + const MAX_RETRIES: u32 = 50; + const STALE_LOCK_SECS: u64 = 30; + + pub struct Guard { + path: PathBuf, + } + + impl Drop for Guard { + fn drop(&mut self) { + let _ = fs::remove_file(&self.path); + } + } + + pub fn acquire() -> Result { + let path = super::lock_path(); + for _ in 0..MAX_RETRIES { + match fs::OpenOptions::new().write(true).create_new(true).open(&path) { + Ok(_) => return Ok(Guard { path }), + Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => { + if is_stale(&path) { + let _ = fs::remove_file(&path); + continue; + } + sleep(RETRY_INTERVAL); + } + Err(err) => return Err(anyhow!("failed to open config lock: {err}")), + } + } + Err(anyhow!("config lock is held by another process")) + } + + fn is_stale(path: &PathBuf) -> bool { + fs::metadata(path) + .and_then(|m| m.modified()) + .ok() + .and_then(|t| SystemTime::now().duration_since(t).ok()) + .map(|age| age.as_secs() > STALE_LOCK_SECS) + .unwrap_or(false) + } +} diff --git a/windows/src-tauri/src/fx.rs b/windows/src-tauri/src/fx.rs new file mode 100644 index 00000000..5eb63be1 --- /dev/null +++ b/windows/src-tauri/src/fx.rs @@ -0,0 +1,152 @@ +use std::collections::HashMap; +use std::fs; +use std::path::PathBuf; +use std::sync::Mutex; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use serde::{Deserialize, Serialize}; + +const FRANKFURTER_URL: &str = "https://api.frankfurter.app/latest?from=USD&to="; +const CACHE_TTL_SECS: u64 = 24 * 3600; +const FETCH_TIMEOUT: Duration = Duration::from_secs(10); +/// Defensive bounds on any fetched FX rate. Outside [0.0001, 1_000_000] the rate is either +/// a parser bug or a tampered response; we refuse it so the UI never multiplies a NaN or +/// wild value into displayed costs. +const MIN_VALID_FX_RATE: f64 = 0.0001; +const MAX_VALID_FX_RATE: f64 = 1_000_000.0; + +/// Currency metadata the frontend renders against. `rate` is USD -> target; the UI +/// multiplies each raw USD number by `rate` and prefixes `symbol` for display. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CurrencyApplied { + pub code: String, + pub symbol: String, + pub rate: f64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct Entry { + rate: f64, + saved_at: u64, +} + +pub struct FxCache { + entries: Mutex>, +} + +impl FxCache { + pub fn new() -> Self { + let entries = load_from_disk().unwrap_or_default(); + FxCache { + entries: Mutex::new(entries), + } + } + + /// Returns a cached-or-fresh rate. Tries cache first, then Frankfurter if stale. Any + /// response that fails the sanity bounds is dropped and the cached (possibly stale) + /// value is returned instead. + pub async fn rate_for(&self, code: &str) -> Option { + if code == "USD" { + return Some(1.0); + } + + { + let guard = self.entries.lock().ok()?; + if let Some(entry) = guard.get(code) { + if now_secs().saturating_sub(entry.saved_at) < CACHE_TTL_SECS { + return Some(entry.rate); + } + } + } + + match fetch_rate(code).await { + Some(fresh) if is_valid(fresh) => { + if let Ok(mut guard) = self.entries.lock() { + guard.insert( + code.to_string(), + Entry { + rate: fresh, + saved_at: now_secs(), + }, + ); + let _ = save_to_disk(&guard); + } + Some(fresh) + } + _ => { + // Fetch failed or out-of-band; serve stale cached value if any. + let guard = self.entries.lock().ok()?; + guard.get(code).map(|e| e.rate) + } + } + } +} + +fn is_valid(rate: f64) -> bool { + rate.is_finite() && (MIN_VALID_FX_RATE..=MAX_VALID_FX_RATE).contains(&rate) +} + +fn now_secs() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|d| d.as_secs()) + .unwrap_or(0) +} + +fn cache_path() -> PathBuf { + dirs::cache_dir() + .unwrap_or_else(|| PathBuf::from(".")) + .join("codeburn-menubar") + .join("fx-rates.json") +} + +fn load_from_disk() -> Option> { + let bytes = fs::read(cache_path()).ok()?; + let parsed: HashMap = serde_json::from_slice(&bytes).ok()?; + Some(parsed.into_iter().filter(|(_, e)| is_valid(e.rate)).collect()) +} + +fn save_to_disk(entries: &HashMap) -> Option<()> { + let path = cache_path(); + let parent = path.parent()?; + fs::create_dir_all(parent).ok()?; + let serialized = serde_json::to_vec(entries).ok()?; + let tmp = path.with_extension("tmp"); + fs::write(&tmp, serialized).ok()?; + fs::rename(&tmp, path).ok()?; + Some(()) +} + +async fn fetch_rate(code: &str) -> Option { + let client = reqwest::Client::builder() + .timeout(FETCH_TIMEOUT) + .https_only(true) + .build() + .ok()?; + let url = format!("{}{}", FRANKFURTER_URL, code); + let response = client.get(&url).send().await.ok()?; + if !response.status().is_success() { + return None; + } + let body: serde_json::Value = response.json().await.ok()?; + body.get("rates")?.get(code)?.as_f64() +} + +/// Prefers a handwritten glyph over whatever Intl returns for a given code, since some +/// locales produce "US$" / "CA$" which reads as noise. Mirrors the Swift symbol override +/// table so both apps display identical strings for the same code. +pub fn symbol_for(code: &str) -> String { + match code { + "USD" | "CAD" | "AUD" | "NZD" | "HKD" | "SGD" | "MXN" => "$".into(), + "EUR" => "\u{20AC}".into(), + "GBP" => "\u{00A3}".into(), + "JPY" | "CNY" => "\u{00A5}".into(), + "KRW" => "\u{20A9}".into(), + "INR" => "\u{20B9}".into(), + "BRL" => "R$".into(), + "CHF" => "CHF".into(), + "SEK" | "DKK" => "kr".into(), + "ZAR" => "R".into(), + _ => code.into(), + } +} diff --git a/windows/src-tauri/src/lib.rs b/windows/src-tauri/src/lib.rs new file mode 100644 index 00000000..d040f399 --- /dev/null +++ b/windows/src-tauri/src/lib.rs @@ -0,0 +1,509 @@ +mod autostart; +mod cli; +mod config; +mod fx; +mod plan; +mod tray_badge; +#[cfg(target_os = "linux")] +mod tray_linux; + +use std::sync::Mutex; +use std::sync::atomic::{AtomicI64, Ordering}; + +static LAST_HIDDEN_MS: AtomicI64 = AtomicI64::new(0); + +use tauri::{AppHandle, Emitter, Manager, WindowEvent}; +#[cfg(target_os = "linux")] +use tauri::Listener; + +#[cfg(not(target_os = "linux"))] +use tauri::{ + menu::{Menu, MenuItem, PredefinedMenuItem}, + tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}, +}; + +use crate::cli::CodeburnCli; +use crate::config::CurrencyConfig; +use crate::fx::FxCache; + +const TRAY_ID: &str = "codeburn-tray"; +/// Second tray icon that carries today's spend as text, sitting next to the logo. The +/// closest Windows and Linux panels get to the macOS menubar title. +const BADGE_TRAY_ID: &str = "codeburn-badge"; +const POPOVER_LABEL: &str = "popover"; + +/// Shared application state. Wraps the CLI handle + currency config + FX cache so every +/// Tauri command sees the same instances. Interior Mutex keeps things simple; the state is +/// touched from the main thread (UI) and the Tokio runtime (CLI spawn, HTTP), both of +/// which go through `#[tauri::command]` async functions that acquire the lock briefly. +pub struct AppState { + pub cli: Mutex, + pub config: Mutex, + pub fx: FxCache, + pub plan: plan::PlanClient, + #[cfg(target_os = "linux")] + pub linux_tray: tray_linux::LinuxTrayHandle, +} + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_opener::init()) + .setup(|app| { + #[cfg(target_os = "linux")] + let linux_tray = tray_linux::LinuxTrayHandle::empty(); + + let state = AppState { + cli: Mutex::new(CodeburnCli::resolve()), + config: Mutex::new(CurrencyConfig::load_or_default()), + fx: FxCache::new(), + plan: plan::PlanClient::new(), + #[cfg(target_os = "linux")] + linux_tray: linux_tray.clone(), + }; + app.manage(state); + + #[cfg(not(target_os = "linux"))] + build_tray_tauri(app.handle())?; + + #[cfg(target_os = "linux")] + init_tray_linux(app.handle().clone(), linux_tray); + + if let Some(window) = app.get_webview_window(POPOVER_LABEL) { + let _ = window.hide(); + #[cfg(target_os = "windows")] + round_window_corners(&window); + } + + Ok(()) + }) + .on_window_event(|window, event| { + match event { + WindowEvent::CloseRequested { api, .. } => { + api.prevent_close(); + let _ = window.hide(); + } + WindowEvent::Focused(false) => { + LAST_HIDDEN_MS.store(now_ms(), Ordering::Relaxed); + let _ = window.hide(); + } + _ => {} + } + }) + .invoke_handler(tauri::generate_handler![ + commands::fetch_payload, + commands::cli_status, + commands::set_currency, + commands::open_terminal_command, + commands::open_claude_login, + commands::quit_app, + commands::hide_popover, + commands::set_tray_tooltip, + commands::set_tray_badge, + commands::app_version, + commands::plan_usage, + commands::launch_at_login, + commands::set_launch_at_login, + ]) + .build(tauri::generate_context!()) + .expect("error while running tauri application") + .run(|_app, event| { + if let tauri::RunEvent::ExitRequested { api, .. } = event { + api.prevent_exit(); + } + }); +} + +#[cfg(not(target_os = "linux"))] +fn build_tray_tauri(app: &AppHandle) -> tauri::Result<()> { + let Some(tray) = app.tray_by_id(TRAY_ID) else { + return Ok(()); + }; + + let open = MenuItem::with_id(app, "open", "Open CodeBurn", true, None::<&str>)?; + let refresh = MenuItem::with_id(app, "refresh", "Refresh", true, None::<&str>)?; + let theme = MenuItem::with_id(app, "toggle_theme", "Toggle Dark/Light", true, None::<&str>)?; + let report = MenuItem::with_id(app, "report", "Open Full Report", true, None::<&str>)?; + let quit = MenuItem::with_id(app, "quit", "Quit CodeBurn", true, None::<&str>)?; + let menu = Menu::with_items( + app, + &[ + &open, + &refresh, + &theme, + &report, + &PredefinedMenuItem::separator(app)?, + &quit, + ], + )?; + + tray.set_menu(Some(menu.clone()))?; + tray.set_show_menu_on_left_click(false)?; + let _ = tray.set_tooltip(Some("CodeBurn")); + tray.on_menu_event(on_tray_menu_event); + tray.on_tray_icon_event(on_tray_icon_event); + + // The badge icon starts fully transparent and hidden; the frontend shows it once it has + // today's spend. Registering it right after the logo puts it beside the logo in the tray. + let blank = tauri::image::Image::new_owned( + vec![0u8; (BLANK_ICON_SIZE * BLANK_ICON_SIZE * 4) as usize], + BLANK_ICON_SIZE, + BLANK_ICON_SIZE, + ); + TrayIconBuilder::with_id(BADGE_TRAY_ID) + .icon(blank) + .tooltip("CodeBurn") + .menu(&menu) + .show_menu_on_left_click(false) + .on_menu_event(on_tray_menu_event) + .on_tray_icon_event(on_tray_icon_event) + .build(app)? + .set_visible(false)?; + + Ok(()) +} + +#[cfg(not(target_os = "linux"))] +const BLANK_ICON_SIZE: u32 = 16; + +#[cfg(not(target_os = "linux"))] +fn on_tray_menu_event(app: &AppHandle, event: tauri::menu::MenuEvent) { + match event.id.as_ref() { + "quit" => app.exit(0), + "open" => show_popover(app, None), + "refresh" => { + if let Some(window) = app.get_webview_window(POPOVER_LABEL) { + let _ = window.emit("codeburn://refresh", ()); + } + } + "toggle_theme" => { + if let Some(window) = app.get_webview_window(POPOVER_LABEL) { + let _ = window.emit("codeburn://toggle-theme", ()); + } + } + "report" => { + let _ = cli::spawn_in_terminal(app, &["report"]); + } + _ => {} + } +} + +#[cfg(not(target_os = "linux"))] +fn on_tray_icon_event(tray: &tauri::tray::TrayIcon, event: TrayIconEvent) { + match event { + TrayIconEvent::Click { + button: MouseButton::Left, + button_state: MouseButtonState::Up, + position, + .. + } + | TrayIconEvent::DoubleClick { + button: MouseButton::Left, + position, + .. + } => { + toggle_popover(tray.app_handle(), Some((position.x as i32, position.y as i32))); + } + _ => {} + } +} + +#[cfg(target_os = "linux")] +fn init_tray_linux(app: AppHandle, handle: tray_linux::LinuxTrayHandle) { + // Spawn the SNI tray on the Tokio runtime that Tauri already owns. + let spawn_app = app.clone(); + let spawn_handle = handle.clone(); + tauri::async_runtime::spawn(async move { + if let Err(err) = tray_linux::spawn(spawn_app, spawn_handle).await { + eprintln!("codeburn: failed to spawn Linux tray: {err}"); + } + }); + + // Left-click on the tray: show popover anchored to the click coordinates. + let activate_app = app.clone(); + app.listen_any("codeburn://tray-activate", move |event| { + let anchor = parse_click(event.payload()); + toggle_popover(&activate_app, anchor); + }); + + // Right-click / middle-click: same as left for now. Quit lives in the popover footer. + let secondary_app = app.clone(); + app.listen_any("codeburn://tray-secondary", move |event| { + let anchor = parse_click(event.payload()); + toggle_popover(&secondary_app, anchor); + }); +} + +#[cfg(target_os = "linux")] +fn parse_click(payload: &str) -> Option<(i32, i32)> { + let value: serde_json::Value = serde_json::from_str(payload).ok()?; + let x = value.get("x")?.as_i64()? as i32; + let y = value.get("y")?.as_i64()? as i32; + Some((x, y)) +} + +/// Undecorated windows are square by default; ask DWM for the Windows 11 rounded corner so +/// the acrylic backdrop is clipped to the same shape as the popover card. Silently ignored +/// on Windows 10, where the corners stay square. +#[cfg(target_os = "windows")] +fn round_window_corners(window: &tauri::WebviewWindow) { + use windows_sys::Win32::Graphics::Dwm::{ + DwmSetWindowAttribute, DWMWA_WINDOW_CORNER_PREFERENCE, DWMWCP_ROUND, + }; + let Ok(hwnd) = window.hwnd() else { return }; + let preference: u32 = DWMWCP_ROUND as u32; + unsafe { + DwmSetWindowAttribute( + hwnd.0 as _, + DWMWA_WINDOW_CORNER_PREFERENCE as u32, + &preference as *const u32 as *const std::ffi::c_void, + std::mem::size_of::() as u32, + ); + } +} + +/// A blur immediately followed by the tray click that caused it would re-open the popover; +/// ignore show requests inside this window after a hide. +const TOGGLE_DEBOUNCE_MS: i64 = 300; + +fn now_ms() -> i64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_millis() as i64 +} + +fn toggle_popover(app: &AppHandle, anchor: Option<(i32, i32)>) { + let Some(window) = app.get_webview_window(POPOVER_LABEL) else { + return; + }; + if window.is_visible().unwrap_or(false) { + LAST_HIDDEN_MS.store(now_ms(), Ordering::Relaxed); + let _ = window.hide(); + return; + } + let last = LAST_HIDDEN_MS.load(Ordering::Relaxed); + if now_ms() - last < TOGGLE_DEBOUNCE_MS { + return; + } + show_popover(app, anchor); +} + +fn show_popover(app: &AppHandle, anchor: Option<(i32, i32)>) { + let Some(window) = app.get_webview_window(POPOVER_LABEL) else { + return; + }; + // Position before showing so the first frame is already in place (no jump). + position_popover(&window, anchor); + let _ = window.show(); + let _ = window.unminimize(); + position_popover(&window, anchor); + let _ = window.set_focus(); + let _ = window.emit("codeburn://shown", ()); +} + +/// Places the popover against the taskbar / panel edge of the monitor that owns the click +/// (or the cursor, when the request came from a menu). The work area already excludes the +/// taskbar on Windows and panels on Linux, so we never need to guess their heights: the +/// popover sits `MARGIN` inside the work area, horizontally centred on the anchor and +/// clamped to the screen. +fn position_popover(window: &tauri::WebviewWindow, anchor: Option<(i32, i32)>) { + const POPOVER_WIDTH_LOGICAL: f64 = 360.0; + const POPOVER_HEIGHT_LOGICAL: f64 = 660.0; + const MARGIN_LOGICAL: f64 = 8.0; + + let point = anchor + .filter(|(x, y)| *x > 0 || *y > 0) + .map(|(x, y)| (x as f64, y as f64)) + .or_else(|| window.cursor_position().ok().map(|p| (p.x, p.y))); + + let monitor = point + .and_then(|(x, y)| window.monitor_from_point(x, y).ok().flatten()) + .or_else(|| window.primary_monitor().ok().flatten()); + let Some(monitor) = monitor else { + return; + }; + + let scale = monitor.scale_factor(); + let pop_w = (POPOVER_WIDTH_LOGICAL * scale).round() as i32; + let pop_h = (POPOVER_HEIGHT_LOGICAL * scale).round() as i32; + let margin = (MARGIN_LOGICAL * scale).round() as i32; + + let area = monitor.work_area(); + let area_x = area.position.x; + let area_y = area.position.y; + let area_w = area.size.width as i32; + let area_h = area.size.height as i32; + let screen = monitor.size(); + let screen_pos = monitor.position(); + + let (anchor_x, anchor_y) = point + .map(|(x, y)| (x as i32, y as i32)) + .unwrap_or((area_x + area_w - pop_w / 2 - margin, area_y + area_h)); + + let min_x = area_x + margin; + let max_x = (area_x + area_w - pop_w - margin).max(min_x); + let x = (anchor_x - pop_w / 2).clamp(min_x, max_x); + + // Which edge holds the taskbar? Whichever side the work area was trimmed on. If the + // taskbar is at the top (or the anchor is in the top half with no bottom taskbar) the + // popover drops down from the top edge; otherwise it rises from the bottom edge. + let trimmed_top = area_y > screen_pos.y; + let trimmed_bottom = (area_y + area_h) < (screen_pos.y + screen.height as i32); + let anchor_in_top_half = anchor_y < screen_pos.y + (screen.height as i32) / 2; + let open_downward = trimmed_top || (!trimmed_bottom && anchor_in_top_half); + + let y = if open_downward { + area_y + margin + } else { + (area_y + area_h - pop_h - margin).max(area_y + margin) + }; + + let _ = window.set_position(tauri::PhysicalPosition::new(x, y)); +} + +mod commands { + use super::{AppState, POPOVER_LABEL}; + use serde_json::Value; + use tauri::{AppHandle, Manager, State}; + + #[tauri::command] + pub async fn fetch_payload( + period: String, + provider: String, + include_optimize: bool, + state: State<'_, AppState>, + ) -> Result { + let cli = state.cli.lock().map_err(|e| e.to_string())?.clone(); + cli.fetch_menubar_payload(&period, &provider, include_optimize) + .await + .map_err(|e| e.to_string()) + } + + /// Re-resolves the CLI each call so a freshly installed `codeburn` is picked up + /// without restarting the tray app. + #[tauri::command] + pub async fn cli_status(state: State<'_, AppState>) -> Result { + let fresh = crate::cli::CodeburnCli::resolve(); + let status = fresh.status().await; + if status.found { + if let Ok(mut guard) = state.cli.lock() { + *guard = fresh; + } + } + Ok(status) + } + + #[tauri::command] + pub async fn set_currency( + code: String, + state: State<'_, AppState>, + ) -> Result { + let symbol = crate::fx::symbol_for(&code); + let rate = state + .fx + .rate_for(&code) + .await + .ok_or_else(|| format!("Exchange rate for {code} is unavailable right now"))?; + state + .config + .lock() + .map_err(|e| e.to_string())? + .set_currency(&code, &symbol) + .map_err(|e| e.to_string())?; + Ok(crate::fx::CurrencyApplied { code, symbol, rate }) + } + + #[tauri::command] + pub fn open_terminal_command(app: AppHandle, args: Vec) -> Result<(), String> { + let args: Vec<&str> = args.iter().map(String::as_str).collect(); + crate::cli::spawn_in_terminal(&app, &args).map_err(|e| e.to_string()) + } + + #[tauri::command] + pub fn open_claude_login(app: AppHandle) -> Result<(), String> { + crate::cli::spawn_claude_login(&app).map_err(|e| e.to_string()) + } + + #[tauri::command] + pub fn quit_app(app: AppHandle) { + app.exit(0); + } + + #[tauri::command] + pub fn hide_popover(app: AppHandle) { + if let Some(window) = app.get_webview_window(POPOVER_LABEL) { + super::LAST_HIDDEN_MS.store(super::now_ms(), std::sync::atomic::Ordering::Relaxed); + let _ = window.hide(); + } + } + + /// The tray cannot render text on Windows, so today's spend lives in the tooltip. + #[tauri::command] + pub fn set_tray_tooltip(app: AppHandle, text: String) { + #[cfg(not(target_os = "linux"))] + for id in [super::TRAY_ID, super::BADGE_TRAY_ID] { + if let Some(tray) = app.tray_by_id(id) { + let _ = tray.set_tooltip(Some(text.as_str())); + } + } + #[cfg(target_os = "linux")] + { + let _ = (app, text); + } + } + + /// `text` is a short spend string ("$87", "142", "1.2K"); `None` hides the badge icon. + #[tauri::command] + pub fn set_tray_badge(app: AppHandle, text: Option) -> Result<(), String> { + #[cfg(not(target_os = "linux"))] + { + let Some(badge) = app.tray_by_id(super::BADGE_TRAY_ID) else { + return Ok(()); + }; + match text.as_deref().map(str::trim).filter(|t| !t.is_empty()) { + Some(t) => { + let icon = crate::tray_badge::render( + t, + crate::tray_badge::small_icon_size(), + crate::tray_badge::taskbar_is_dark(), + ); + // Windows can only modify an icon that is currently shown, so show + // first (re-adds the previous bitmap) and then swap the bitmap. + badge.set_visible(true).map_err(|e| e.to_string())?; + badge.set_icon(Some(icon)).map_err(|e| e.to_string())?; + } + None => { + badge.set_visible(false).map_err(|e| e.to_string())?; + } + } + } + #[cfg(target_os = "linux")] + { + let _ = (app, text); + } + Ok(()) + } + + #[tauri::command] + pub fn app_version(app: AppHandle) -> String { + app.package_info().version.to_string() + } + + #[tauri::command] + pub fn launch_at_login() -> bool { + crate::autostart::is_enabled() + } + + #[tauri::command] + pub fn set_launch_at_login(enabled: bool) -> Result { + crate::autostart::set_enabled(enabled).map_err(|e| e.to_string())?; + Ok(crate::autostart::is_enabled()) + } + + #[tauri::command] + pub async fn plan_usage(state: State<'_, AppState>) -> Result { + state.plan.fetch().await.map_err(|e| e.to_string()) + } +} diff --git a/windows/src-tauri/src/main.rs b/windows/src-tauri/src/main.rs new file mode 100644 index 00000000..b79df4b0 --- /dev/null +++ b/windows/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Stops an extra console window appearing on Windows in release builds. +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + codeburn_menubar_lib::run() +} diff --git a/windows/src-tauri/src/plan.rs b/windows/src-tauri/src/plan.rs new file mode 100644 index 00000000..165c1b33 --- /dev/null +++ b/windows/src-tauri/src/plan.rs @@ -0,0 +1,484 @@ +//! Claude subscription usage (the "Plan" insight). Mirrors the macOS SubscriptionClient: +//! read Claude Code's OAuth credentials, call the usage endpoint, refresh once on 401, and +//! keep a rolling snapshot file so a freshly reset window can still show last cycle's final. + +use std::fs; +use std::path::PathBuf; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use anyhow::{anyhow, bail, Context, Result}; +use serde::{Deserialize, Serialize}; +use tokio::sync::Mutex; + +const CREDENTIALS_RELATIVE_PATH: &str = ".claude/.credentials.json"; +const OAUTH_CLIENT_ID: &str = "9d1c250a-e61b-44d9-88ed-5944d1962f5e"; +const REFRESH_URL: &str = "https://platform.claude.com/v1/oauth/token"; +const USAGE_URL: &str = "https://api.anthropic.com/api/oauth/usage"; +const BETA_HEADER: &str = "oauth-2025-04-20"; +const USER_AGENT: &str = "claude-code/2.1.0"; +const REQUEST_TIMEOUT: Duration = Duration::from_secs(30); +const MAX_CREDENTIAL_BYTES: u64 = 64 * 1024; +const SNAPSHOT_FILENAME: &str = "subscription-snapshots.json"; +const SNAPSHOT_RETENTION: Duration = Duration::from_secs(30 * 24 * 3600); +const WINDOW_KEYS: [(&str, &str); 4] = [ + ("five_hour", "5-hour window"), + ("seven_day", "7-day total"), + ("seven_day_opus", "7-day Opus"), + ("seven_day_sonnet", "7-day Sonnet"), +]; + +#[derive(Debug, Clone, Serialize)] +pub struct PlanWindow { + pub key: String, + pub label: String, + /// 0..100 + pub percent: f64, + /// RFC 3339 timestamp of the next reset, when the API supplied one. + pub resets_at: Option, + /// Final percent reached in the immediately prior cycle, from the snapshot store. + pub previous_final: Option, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(tag = "state", rename_all = "snake_case")] +pub enum PlanUsage { + Ok { + tier: String, + raw_tier: Option, + windows: Vec, + fetched_at: String, + }, + NoCredentials, + Failed { + message: String, + }, +} + +pub struct PlanClient { + snapshot_lock: Mutex<()>, +} + +impl PlanClient { + pub fn new() -> Self { + PlanClient { + snapshot_lock: Mutex::new(()), + } + } + + pub async fn fetch(&self) -> Result { + let creds = match load_credentials() { + Ok(Some(c)) => c, + Ok(None) => return Ok(PlanUsage::NoCredentials), + Err(err) => { + return Ok(PlanUsage::Failed { + message: err.to_string(), + }) + } + }; + + let response = match fetch_usage(&creds.access_token).await { + Ok(r) => r, + Err(FetchError::Unauthorized) => { + let Some(refresh) = creds.refresh_token.as_deref().filter(|t| !t.is_empty()) else { + return Ok(PlanUsage::Failed { + message: "Claude session expired and no refresh token is available. Run `claude login`.".into(), + }); + }; + match refresh_access_token(refresh).await { + Ok(token) => match fetch_usage(&token).await { + Ok(r) => r, + Err(err) => { + return Ok(PlanUsage::Failed { + message: err.to_string(), + }) + } + }, + Err(err) => { + return Ok(PlanUsage::Failed { + message: format!("Token refresh failed: {err}"), + }) + } + } + } + Err(err) => { + return Ok(PlanUsage::Failed { + message: err.to_string(), + }) + } + }; + + let now = SystemTime::now(); + let mut windows = Vec::new(); + for (key, label) in WINDOW_KEYS { + let Some(window) = response.window(key) else { continue }; + let Some(percent) = window.utilization else { continue }; + let resets_at = window.resets_at.clone().filter(|s| !s.is_empty()); + let previous_final = { + let _guard = self.snapshot_lock.lock().await; + if let Some(reset) = resets_at.as_deref() { + record_snapshot(key, percent, reset, now); + previous_window_final(key, reset) + } else { + None + } + }; + windows.push(PlanWindow { + key: key.to_string(), + label: label.to_string(), + percent: percent.clamp(0.0, 100.0), + resets_at, + previous_final, + }); + } + + Ok(PlanUsage::Ok { + tier: tier_display(creds.rate_limit_tier.as_deref()), + raw_tier: creds.rate_limit_tier, + windows, + fetched_at: to_rfc3339(now), + }) + } +} + +// ---- credentials ----------------------------------------------------------------------- + +struct StoredCredentials { + access_token: String, + refresh_token: Option, + rate_limit_tier: Option, +} + +#[derive(Deserialize)] +struct CredentialsRoot { + #[serde(rename = "claudeAiOauth")] + claude_ai_oauth: Option, +} + +#[derive(Deserialize)] +struct OAuthBlock { + #[serde(rename = "accessToken")] + access_token: Option, + #[serde(rename = "refreshToken")] + refresh_token: Option, + #[serde(rename = "rateLimitTier")] + rate_limit_tier: Option, +} + +fn credentials_path() -> Option { + dirs::home_dir().map(|h| h.join(CREDENTIALS_RELATIVE_PATH)) +} + +/// Ok(None) when the file does not exist (user never logged in); Err for malformed data. +fn load_credentials() -> Result> { + let Some(path) = credentials_path() else { + return Ok(None); + }; + let meta = match fs::symlink_metadata(&path) { + Ok(m) => m, + Err(_) => return Ok(None), + }; + if meta.file_type().is_symlink() { + bail!("credentials file is a symlink; refusing to read it"); + } + if meta.len() > MAX_CREDENTIAL_BYTES { + bail!("credentials file is unexpectedly large"); + } + let bytes = fs::read(&path).with_context(|| "failed to read Claude credentials")?; + let root: CredentialsRoot = + serde_json::from_slice(&bytes).with_context(|| "Claude credentials are malformed")?; + let Some(oauth) = root.claude_ai_oauth else { + return Ok(None); + }; + let token = oauth.access_token.unwrap_or_default().trim().to_string(); + if token.is_empty() { + return Ok(None); + } + Ok(Some(StoredCredentials { + access_token: token, + refresh_token: oauth.refresh_token, + rate_limit_tier: oauth.rate_limit_tier, + })) +} + +fn tier_display(raw: Option<&str>) -> String { + let Some(raw) = raw.map(|r| r.to_lowercase()) else { + return "Subscription".into(); + }; + if raw.contains("max_20x") || raw.contains("max20x") || raw.contains("max-20x") { + return "Max 20x".into(); + } + if raw.contains("max_5x") || raw.contains("max5x") || raw.contains("max-5x") { + return "Max 5x".into(); + } + if raw.contains("max") { + return "Max 5x".into(); + } + if raw.contains("pro") { + return "Pro".into(); + } + if raw.contains("team") { + return "Team".into(); + } + if raw.contains("enterprise") { + return "Enterprise".into(); + } + "Subscription".into() +} + +// ---- HTTP ------------------------------------------------------------------------------ + +#[derive(Debug, Deserialize)] +struct UsageResponse { + five_hour: Option, + seven_day: Option, + seven_day_opus: Option, + seven_day_sonnet: Option, +} + +impl UsageResponse { + fn window(&self, key: &str) -> Option<&Window> { + match key { + "five_hour" => self.five_hour.as_ref(), + "seven_day" => self.seven_day.as_ref(), + "seven_day_opus" => self.seven_day_opus.as_ref(), + "seven_day_sonnet" => self.seven_day_sonnet.as_ref(), + _ => None, + } + } +} + +#[derive(Debug, Deserialize)] +struct Window { + utilization: Option, + resets_at: Option, +} + +#[derive(Debug, Deserialize)] +struct TokenRefreshResponse { + access_token: String, +} + +#[derive(Debug, thiserror::Error)] +enum FetchError { + #[error("Claude session is no longer authorized")] + Unauthorized, + #[error("Usage fetch failed ({0}){1}")] + Http(u16, String), + #[error("{0}")] + Other(String), +} + +fn client() -> Result { + reqwest::Client::builder() + .timeout(REQUEST_TIMEOUT) + .https_only(true) + .build() + .map_err(|e| FetchError::Other(e.to_string())) +} + +async fn fetch_usage(token: &str) -> Result { + let response = client()? + .get(USAGE_URL) + .bearer_auth(token) + .header("Accept", "application/json") + .header("anthropic-beta", BETA_HEADER) + .header("User-Agent", USER_AGENT) + .send() + .await + .map_err(|e| FetchError::Other(e.to_string()))?; + let status = response.status(); + if status.as_u16() == 401 { + return Err(FetchError::Unauthorized); + } + if !status.is_success() { + let body = response.text().await.unwrap_or_default(); + let detail = if body.is_empty() { String::new() } else { format!(": {}", truncate(&body, 200)) }; + return Err(FetchError::Http(status.as_u16(), detail)); + } + response + .json::() + .await + .map_err(|e| FetchError::Other(format!("Decode failed: {e}"))) +} + +async fn refresh_access_token(refresh_token: &str) -> Result { + let response = client() + .map_err(|e| anyhow!(e.to_string()))? + .post(REFRESH_URL) + .header("Accept", "application/json") + .form(&[ + ("grant_type", "refresh_token"), + ("refresh_token", refresh_token), + ("client_id", OAUTH_CLIENT_ID), + ]) + .send() + .await?; + let status = response.status(); + if !status.is_success() { + let body = response.text().await.unwrap_or_default(); + bail!("{} {}", status.as_u16(), truncate(&body, 200)); + } + let decoded: TokenRefreshResponse = response.json().await?; + Ok(decoded.access_token) +} + +fn truncate(text: &str, max: usize) -> String { + let mut out: String = text.chars().take(max).collect(); + if text.chars().count() > max { + out.push_str("..."); + } + out +} + +// ---- snapshots ------------------------------------------------------------------------- + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct Snapshot { + #[serde(rename = "windowKey")] + window_key: String, + percent: f64, + #[serde(rename = "resetsAt")] + resets_at: String, + #[serde(rename = "capturedAt")] + captured_at: String, + #[serde(rename = "effectiveTokens")] + effective_tokens: Option, +} + +fn snapshots_path() -> PathBuf { + let dir = std::env::var_os("CODEBURN_CACHE_DIR") + .map(PathBuf::from) + .or_else(|| dirs::home_dir().map(|h| h.join(".cache").join("codeburn"))) + .unwrap_or_else(|| PathBuf::from(".")); + dir.join(SNAPSHOT_FILENAME) +} + +fn load_snapshots() -> Vec { + fs::read(snapshots_path()) + .ok() + .and_then(|bytes| serde_json::from_slice(&bytes).ok()) + .unwrap_or_default() +} + +fn save_snapshots(all: &[Snapshot]) { + let path = snapshots_path(); + if let Some(parent) = path.parent() { + let _ = fs::create_dir_all(parent); + } + if let Ok(bytes) = serde_json::to_vec_pretty(all) { + let tmp = path.with_extension("tmp"); + if fs::write(&tmp, bytes).is_ok() { + let _ = fs::rename(&tmp, &path); + } + } +} + +fn record_snapshot(window_key: &str, percent: f64, resets_at: &str, now: SystemTime) { + let mut all = load_snapshots(); + match all + .iter_mut() + .find(|s| s.window_key == window_key && s.resets_at == resets_at) + { + Some(existing) => { + if percent > existing.percent { + existing.percent = percent; + existing.captured_at = to_rfc3339(now); + } + } + None => all.push(Snapshot { + window_key: window_key.to_string(), + percent, + resets_at: resets_at.to_string(), + captured_at: to_rfc3339(now), + effective_tokens: None, + }), + } + let cutoff = now.checked_sub(SNAPSHOT_RETENTION).unwrap_or(UNIX_EPOCH); + all.retain(|s| parse_rfc3339(&s.captured_at).map(|t| t >= cutoff).unwrap_or(true)); + save_snapshots(&all); +} + +fn previous_window_final(window_key: &str, current_resets_at: &str) -> Option { + let current = parse_rfc3339(current_resets_at)?; + let all = load_snapshots(); + let priors: Vec<(SystemTime, f64)> = all + .iter() + .filter(|s| s.window_key == window_key) + .filter_map(|s| parse_rfc3339(&s.resets_at).map(|t| (t, s.percent))) + .filter(|(t, _)| *t < current) + .collect(); + let latest = priors.iter().map(|(t, _)| *t).max()?; + priors + .iter() + .filter(|(t, _)| *t == latest) + .map(|(_, p)| *p) + .fold(None, |acc: Option, p| Some(acc.map_or(p, |a| a.max(p)))) +} + +// ---- time helpers (RFC 3339 without pulling in chrono) -------------------------------- + +fn to_rfc3339(t: SystemTime) -> String { + let secs = t.duration_since(UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(0) as i64; + let (y, m, d, hh, mm, ss) = civil_from_unix(secs); + format!("{y:04}-{m:02}-{d:02}T{hh:02}:{mm:02}:{ss:02}Z") +} + +/// Accepts `2026-08-18T10:00:00Z`, with optional fractional seconds and `+hh:mm` offsets. +fn parse_rfc3339(text: &str) -> Option { + let bytes = text.as_bytes(); + if bytes.len() < 19 { + return None; + } + let num = |a: usize, b: usize| text.get(a..b)?.parse::().ok(); + let (y, mo, d) = (num(0, 4)?, num(5, 7)?, num(8, 10)?); + let (h, mi, s) = (num(11, 13)?, num(14, 16)?, num(17, 19)?); + let mut rest = &text[19..]; + if rest.starts_with('.') { + let end = rest[1..] + .find(|c: char| !c.is_ascii_digit()) + .map(|i| i + 1) + .unwrap_or(rest.len()); + rest = &rest[end..]; + } + let offset_secs = match rest { + "" | "Z" | "z" => 0, + _ => { + let sign = if rest.starts_with('-') { -1 } else { 1 }; + let oh = rest.get(1..3)?.parse::().ok()?; + let om = rest.get(4..6)?.parse::().ok()?; + sign * (oh * 3600 + om * 60) + } + }; + let unix = unix_from_civil(y, mo, d) + h * 3600 + mi * 60 + s - offset_secs; + if unix < 0 { + return None; + } + Some(UNIX_EPOCH + Duration::from_secs(unix as u64)) +} + +fn unix_from_civil(y: i64, m: i64, d: i64) -> i64 { + // Howard Hinnant's days_from_civil. + let y = if m <= 2 { y - 1 } else { y }; + let era = if y >= 0 { y } else { y - 399 } / 400; + let yoe = y - era * 400; + let mp = (m + 9) % 12; + let doy = (153 * mp + 2) / 5 + d - 1; + let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; + (era * 146_097 + doe - 719_468) * 86_400 +} + +fn civil_from_unix(secs: i64) -> (i64, i64, i64, i64, i64, i64) { + let days = secs.div_euclid(86_400); + let rem = secs.rem_euclid(86_400); + let z = days + 719_468; + let era = if z >= 0 { z } else { z - 146_096 } / 146_097; + let doe = z - era * 146_097; + let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365; + let y = yoe + era * 400; + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + let mp = (5 * doy + 2) / 153; + let d = doy - (153 * mp + 2) / 5 + 1; + let m = if mp < 10 { mp + 3 } else { mp - 9 }; + let y = if m <= 2 { y + 1 } else { y }; + (y, m, d, rem / 3600, (rem % 3600) / 60, rem % 60) +} diff --git a/windows/src-tauri/src/tray_badge.rs b/windows/src-tauri/src/tray_badge.rs new file mode 100644 index 00000000..a372b858 --- /dev/null +++ b/windows/src-tauri/src/tray_badge.rs @@ -0,0 +1,246 @@ +//! Renders today's spend into the tray icon. Windows and most Linux panels cannot place a +//! title next to a tray icon the way the macOS menubar does, so the number becomes the icon: +//! a 4x7 pixel font drawn at the panel's native small-icon size, so it stays crisp instead +//! of being a scaled-down bitmap. + +use tauri::image::Image; + +const GLYPH_HEIGHT: usize = 7; +const BASE_ICON_SIZE: u32 = 16; +const GLYPH_GAP: usize = 1; +/// Brand accent on a light taskbar, the lighter ember on a dark one. +const ACCENT_LIGHT_TASKBAR: [u8; 3] = [0xC9, 0x52, 0x1D]; +const ACCENT_DARK_TASKBAR: [u8; 3] = [0xF0, 0x8A, 0x55]; + +struct Glyph { + width: usize, + rows: [&'static str; GLYPH_HEIGHT], +} + +fn glyph(c: char) -> Option { + let g = |width: usize, rows: [&'static str; GLYPH_HEIGHT]| Some(Glyph { width, rows }); + match c { + '0' => g(4, [".##.", "#..#", "#..#", "#..#", "#..#", "#..#", ".##."]), + '1' => g(3, [".#.", "##.", ".#.", ".#.", ".#.", ".#.", "###"]), + '2' => g(4, [".##.", "#..#", "...#", "..#.", ".#..", "#...", "####"]), + '3' => g(4, ["###.", "...#", "...#", ".##.", "...#", "...#", "###."]), + '4' => g(4, ["#..#", "#..#", "#..#", "####", "...#", "...#", "...#"]), + '5' => g(4, ["####", "#...", "#...", "###.", "...#", "...#", "###."]), + '6' => g(4, [".##.", "#...", "#...", "###.", "#..#", "#..#", ".##."]), + '7' => g(4, ["####", "...#", "..#.", "..#.", ".#..", ".#..", ".#.."]), + '8' => g(4, [".##.", "#..#", "#..#", ".##.", "#..#", "#..#", ".##."]), + '9' => g(4, [".##.", "#..#", "#..#", ".###", "...#", "...#", ".##."]), + '$' => g(4, ["..#.", ".###", "#.#.", ".##.", ".#.#", "###.", "..#."]), + 'K' => g(4, ["#..#", "#.#.", "##..", "#...", "##..", "#.#.", "#..#"]), + 'M' => g(4, ["#..#", "####", "####", "#..#", "#..#", "#..#", "#..#"]), + '.' => g(1, [".", ".", ".", ".", ".", ".", "#"]), + _ => None, + } +} + +fn text_width(text: &str) -> usize { + let glyphs: Vec = text.chars().filter_map(glyph).collect(); + if glyphs.is_empty() { + return 0; + } + glyphs.iter().map(|g| g.width).sum::() + GLYPH_GAP * (glyphs.len() - 1) +} + +/// Draws `text` centred in a `size` x `size` RGBA icon. Prefers anti-aliased bold system +/// text (far more legible at 16px than 1px pixel strokes); falls back to the pixel font +/// when no usable font file is present. +pub fn render(text: &str, size: u32, dark_taskbar: bool) -> Image<'static> { + let color = if dark_taskbar { ACCENT_DARK_TASKBAR } else { ACCENT_LIGHT_TASKBAR }; + if let Some(image) = render_with_font(text, size, color) { + return image; + } + // The pixel font cannot shrink, so trim from the right until the string fits. + let mut trimmed: String = text.to_string(); + while !fits(&trimmed) && trimmed.pop().is_some() {} + render_pixel_font(&trimmed, size, dark_taskbar) +} + +/// Bold sans faces shipped with Windows, best first. Bahnschrift's condensed numerals fit +/// four glyphs into 16px at a larger size than Segoe UI Bold does. +#[cfg(target_os = "windows")] +const FONT_CANDIDATES: [&str; 3] = [ + r"C:\Windows\Fonts\bahnschrift.ttf", + r"C:\Windows\Fonts\segoeuib.ttf", + r"C:\Windows\Fonts\arialbd.ttf", +]; +#[cfg(not(target_os = "windows"))] +const FONT_CANDIDATES: [&str; 3] = [ + "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", + "/usr/share/fonts/TTF/DejaVuSans-Bold.ttf", + "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", +]; + +/// Largest and smallest text sizes tried, as a fraction of the icon size. +const FONT_MAX_FRACTION: f32 = 0.95; +const FONT_MIN_FRACTION: f32 = 0.5; +const FONT_STEP_PX: f32 = 0.5; + +fn load_font() -> Option { + for path in FONT_CANDIDATES { + if let Ok(bytes) = std::fs::read(path) { + if let Ok(font) = fontdue::Font::from_bytes(bytes, fontdue::FontSettings::default()) { + return Some(font); + } + } + } + None +} + +struct Raster { + metrics: fontdue::Metrics, + bitmap: Vec, +} + +fn layout(font: &fontdue::Font, text: &str, px: f32) -> (Vec, f32, i32, i32) { + let glyphs: Vec = text + .chars() + .map(|c| { + let (metrics, bitmap) = font.rasterize(c, px); + Raster { metrics, bitmap } + }) + .collect(); + let width: f32 = glyphs.iter().map(|g| g.metrics.advance_width).sum(); + let top = glyphs.iter().map(|g| g.metrics.height as i32 + g.metrics.ymin).max().unwrap_or(0); + let bottom = glyphs.iter().map(|g| g.metrics.ymin).min().unwrap_or(0); + (glyphs, width, top, bottom) +} + +fn render_with_font(text: &str, size: u32, color: [u8; 3]) -> Option> { + let font = load_font()?; + let limit = size as f32; + let mut px = limit * FONT_MAX_FRACTION; + let mut chosen = None; + while px >= limit * FONT_MIN_FRACTION { + let (glyphs, width, top, bottom) = layout(&font, text, px); + let height = (top - bottom) as f32; + if width <= limit && height <= limit { + chosen = Some((glyphs, width, top, bottom)); + break; + } + px -= FONT_STEP_PX; + } + let (glyphs, width, top, bottom) = chosen?; + + let mut rgba = vec![0u8; (size * size * 4) as usize]; + let height = top - bottom; + let x0 = ((limit - width) / 2.0).round(); + let baseline = ((size as i32 - height) / 2) + top; + let mut pen = x0; + for g in &glyphs { + let gx = pen.round() as i32 + g.metrics.xmin; + let gy = baseline - g.metrics.height as i32 - g.metrics.ymin; + for row in 0..g.metrics.height { + for col in 0..g.metrics.width { + let alpha = g.bitmap[row * g.metrics.width + col]; + if alpha == 0 { + continue; + } + let px_x = gx + col as i32; + let px_y = gy + row as i32; + if px_x < 0 || px_y < 0 || px_x >= size as i32 || px_y >= size as i32 { + continue; + } + let i = ((px_y as u32 * size + px_x as u32) * 4) as usize; + let existing = rgba[i + 3]; + let merged = existing.max(alpha); + rgba[i] = color[0]; + rgba[i + 1] = color[1]; + rgba[i + 2] = color[2]; + rgba[i + 3] = merged; + } + } + pen += g.metrics.advance_width; + } + Some(Image::new_owned(rgba, size, size)) +} + +fn render_pixel_font(text: &str, size: u32, dark_taskbar: bool) -> Image<'static> { + let size = size.max(BASE_ICON_SIZE); + let scale = (size / BASE_ICON_SIZE).max(1) as usize; + let mut rgba = vec![0u8; (size * size * 4) as usize]; + let color = if dark_taskbar { ACCENT_DARK_TASKBAR } else { ACCENT_LIGHT_TASKBAR }; + + let width = text_width(text) * scale; + let height = GLYPH_HEIGHT * scale; + let mut x = (size as usize).saturating_sub(width) / 2; + let y0 = (size as usize).saturating_sub(height) / 2; + + for g in text.chars().filter_map(glyph) { + for (row, bits) in g.rows.iter().enumerate() { + for (col, ch) in bits.chars().enumerate() { + if ch != '#' { + continue; + } + for dy in 0..scale { + for dx in 0..scale { + let px = x + col * scale + dx; + let py = y0 + row * scale + dy; + if px < size as usize && py < size as usize { + let i = (py * size as usize + px) * 4; + rgba[i] = color[0]; + rgba[i + 1] = color[1]; + rgba[i + 2] = color[2]; + rgba[i + 3] = 0xFF; + } + } + } + } + } + x += (g.width + GLYPH_GAP) * scale; + } + + Image::new_owned(rgba, size, size) +} + +/// Whether the text fits the 16px pixel-font grid (the font path scales itself to fit). +fn fits(text: &str) -> bool { + text_width(text) <= BASE_ICON_SIZE as usize +} + +/// The panel's small-icon size in physical pixels (16 at 100%, 20 at 125%, 24 at 150%). +#[cfg(target_os = "windows")] +pub fn small_icon_size() -> u32 { + use windows_sys::Win32::UI::WindowsAndMessaging::{GetSystemMetrics, SM_CXSMICON}; + let px = unsafe { GetSystemMetrics(SM_CXSMICON) }; + if px > 0 { px as u32 } else { BASE_ICON_SIZE } +} + +#[cfg(not(target_os = "windows"))] +pub fn small_icon_size() -> u32 { + 22 +} + +/// Windows keeps the taskbar theme separate from the app theme; the number must contrast +/// with the taskbar, not the popover. +#[cfg(target_os = "windows")] +pub fn taskbar_is_dark() -> bool { + use std::os::windows::process::CommandExt; + const CREATE_NO_WINDOW: u32 = 0x08000000; + let output = std::process::Command::new("reg") + .args([ + "query", + r"HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", + "/v", + "SystemUsesLightTheme", + ]) + .creation_flags(CREATE_NO_WINDOW) + .output(); + match output { + Ok(out) => { + let text = String::from_utf8_lossy(&out.stdout); + // "0x0" means the system (taskbar) uses the dark theme. + text.lines().any(|l| l.contains("SystemUsesLightTheme") && l.trim_end().ends_with("0x0")) + } + Err(_) => true, + } +} + +#[cfg(not(target_os = "windows"))] +pub fn taskbar_is_dark() -> bool { + true +} diff --git a/windows/src-tauri/src/tray_linux.rs b/windows/src-tauri/src/tray_linux.rs new file mode 100644 index 00000000..c57cb5c2 --- /dev/null +++ b/windows/src-tauri/src/tray_linux.rs @@ -0,0 +1,139 @@ +use std::sync::{Arc, Mutex}; + +use ksni::{Category, Icon, Status, ToolTip, Tray, TrayMethods}; +use tauri::{AppHandle, Emitter}; + +/// StatusNotifierItem-backed tray for Linux. Bypasses libappindicator so left-click +/// fires `activate(x, y)` with real screen coordinates, which is what Tauri's Linux +/// tray path cannot deliver. See tauri-apps/tauri#7283 for the upstream gap. +/// +/// No menu() is exported. Exporting a menu causes most SNI hosts (notably +/// gnome-shell-extension-appindicator) to swallow left-click as a menu-open and +/// never fire Activate. Quit/Refresh/Open Full Report live in the popover footer. +pub struct CodeburnTray { + app: AppHandle, + title: String, + icon: Vec, +} + +impl CodeburnTray { + fn new(app: AppHandle, icon: Vec) -> Self { + Self { + app, + title: "CodeBurn".to_string(), + icon, + } + } +} + +impl Tray for CodeburnTray { + fn id(&self) -> String { + "org.agentseal.codeburn".to_string() + } + + fn title(&self) -> String { + self.title.clone() + } + + fn category(&self) -> Category { + Category::ApplicationStatus + } + + fn status(&self) -> Status { + Status::Active + } + + fn icon_pixmap(&self) -> Vec { + self.icon.clone() + } + + fn tool_tip(&self) -> ToolTip { + ToolTip { + icon_name: String::new(), + icon_pixmap: Vec::new(), + title: "CodeBurn".to_string(), + description: self.title.clone(), + } + } + + fn activate(&mut self, x: i32, y: i32) { + let _ = self + .app + .emit("codeburn://tray-activate", TrayClick { x, y }); + } + + fn secondary_activate(&mut self, x: i32, y: i32) { + let _ = self + .app + .emit("codeburn://tray-secondary", TrayClick { x, y }); + } +} + +#[derive(Clone, serde::Serialize)] +struct TrayClick { + x: i32, + y: i32, +} + +/// Type-erased handle for the Linux tray so callers can push title updates without +/// naming the `ksni::Handle` generic parameter across module boundaries. +#[derive(Clone)] +pub struct LinuxTrayHandle { + inner: Arc>>>, +} + +impl LinuxTrayHandle { + pub fn empty() -> Self { + Self { + inner: Arc::new(Mutex::new(None)), + } + } + + fn set(&self, handle: ksni::Handle) { + if let Ok(mut guard) = self.inner.lock() { + *guard = Some(handle); + } + } + +} + +/// Decode the bundled tray.png into ARGB32 pixels that the SNI spec expects. +/// Falls back to an empty icon list (host shows a broken-icon placeholder) if the +/// asset can't be decoded. We'd rather render a blank icon than crash the tray. +fn load_icon() -> Vec { + // Embedded at build time so the binary is self-contained. + let bytes = include_bytes!("../icons/tray.png"); + let Ok(decoder) = png::Decoder::new(bytes.as_slice()).read_info().map_err(|_| ()) else { + return Vec::new(); + }; + decode_png(decoder) +} + +fn decode_png(mut reader: png::Reader<&[u8]>) -> Vec { + let info = reader.info().clone(); + let width = info.width as i32; + let height = info.height as i32; + let mut buf = vec![0u8; reader.output_buffer_size()]; + if reader.next_frame(&mut buf).is_err() { + return Vec::new(); + } + // SNI expects ARGB32 in network byte order. PNG decoder gives RGBA8. + let pixel_count = (width as usize) * (height as usize); + let mut argb = Vec::with_capacity(pixel_count * 4); + for chunk in buf.chunks_exact(4) { + let (r, g, b, a) = (chunk[0], chunk[1], chunk[2], chunk[3]); + argb.extend_from_slice(&[a, r, g, b]); + } + vec![Icon { + width, + height, + data: argb, + }] +} + +pub async fn spawn(app: AppHandle, handle_out: LinuxTrayHandle) -> anyhow::Result<()> { + let tray = CodeburnTray::new(app, load_icon()); + let handle = tray.spawn().await?; + handle_out.set(handle); + Ok(()) +} diff --git a/windows/src-tauri/tauri.conf.json b/windows/src-tauri/tauri.conf.json new file mode 100644 index 00000000..a063413f --- /dev/null +++ b/windows/src-tauri/tauri.conf.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "CodeBurn Menubar", + "version": "0.9.20", + "identifier": "org.agentseal.codeburn-menubar", + "build": { + "beforeDevCommand": "npm run dev", + "devUrl": "http://localhost:1420", + "beforeBuildCommand": "npm run build", + "frontendDist": "../dist" + }, + "app": { + "windows": [ + { + "label": "popover", + "title": "CodeBurn", + "width": 360, + "height": 660, + "decorations": false, + "transparent": true, + "resizable": false, + "alwaysOnTop": true, + "skipTaskbar": true, + "visible": false, + "focus": false, + "shadow": true, + "windowEffects": { + "effects": ["acrylic"], + "state": "active" + } + } + ], + "security": { + "csp": "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self' ipc: https://api.frankfurter.app" + }, + "trayIcon": { + "id": "codeburn-tray", + "iconPath": "icons/tray.png", + "iconAsTemplate": false, + "tooltip": "CodeBurn" + } + }, + "bundle": { + "active": true, + "category": "Utility", + "shortDescription": "AI coding cost tracker", + "longDescription": "Shows today's AI coding spend in your system tray. Popover breaks down cost by activity, model, and provider across Claude Code, Cursor, Codex, and more.", + "publisher": "AgentSeal", + "homepage": "https://github.com/getagentseal/codeburn", + "targets": ["deb", "rpm", "appimage", "msi"], + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.png", + "icons/icon.ico" + ], + "linux": { + "deb": { + "depends": ["libwebkit2gtk-4.1-0", "libayatana-appindicator3-1"] + } + } + } +} diff --git a/windows/src/App.tsx b/windows/src/App.tsx new file mode 100644 index 00000000..4a4408f8 --- /dev/null +++ b/windows/src/App.tsx @@ -0,0 +1,352 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { invoke } from '@tauri-apps/api/core' +import { listen } from '@tauri-apps/api/event' + +import type { MenubarPayload } from './lib/payload' +import type { CurrencyState } from './lib/currency' +import { USD, formatCurrency, trayBadgeText } from './lib/currency' +import { PayloadCache } from './lib/cache' +import { relativePast } from './lib/dates' +import { applyTheme, currentTheme, readSetting, writeSetting } from './lib/settings' +import { AgentTabStrip, detectedProviders } from './components/AgentTabStrip' +import type { Provider } from './components/AgentTabStrip' +import { ModelsSection } from './components/ModelsSection' +import { InsightPills, INSIGHT_ORDER, isInsightMode, type InsightMode } from './components/InsightPills' +import { TrendInsight } from './components/TrendInsight' +import { ForecastInsight } from './components/ForecastInsight' +import { PulseInsight } from './components/PulseInsight' +import { StatsInsight } from './components/StatsInsight' +import { PlanInsight } from './components/PlanInsight' +import { FindingsSection } from './components/FindingsSection' +import { ActivitySection } from './components/ActivitySection' +import { LoadingOverlay } from './components/LoadingOverlay' +import { EmptyProviderState } from './components/EmptyProviderState' +import { NoDataState } from './components/NoDataState' +import { SetupState, type CliStatus } from './components/SetupState' +import { StarBanner } from './components/StarBanner' +import { HeroSection } from './components/HeroSection' +import { PeriodTabs, PERIOD_LABELS } from './components/PeriodTabs' +import type { Period } from './components/PeriodTabs' +import { FooterBar } from './components/FooterBar' +import { ErrorToast } from './components/ErrorToast' +import { SettingsPanel, type ThemeChoice } from './components/SettingsPanel' + +const payloadCache = new PayloadCache() + +/// Background cadence. Every tick refreshes today/all (tray tooltip, provider badges) and +/// the visible period/provider; entries younger than STALE_MS are left alone when the +/// popover is re-opened. +const REFRESH_INTERVAL_MS = 60_000 +const STALE_MS = 60_000 + +type FetchOptions = { + includeOptimize: boolean + showOverlay: boolean +} + +export function App() { + const [period, setPeriod] = useState('today') + const [provider, setProvider] = useState('all') + const [payload, setPayload] = useState(null) + const [todayPayload, setTodayPayload] = useState(null) + const [currency, setCurrency] = useState(USD) + const [overlay, setOverlay] = useState(false) + const [error, setError] = useState(null) + const [insight, setInsight] = useState(() => { + const saved = readSetting('insight') + return isInsightMode(saved) ? saved : 'trend' + }) + const [cliStatus, setCliStatus] = useState(null) + const [cliChecking, setCliChecking] = useState(false) + const [version, setVersion] = useState('') + const [lastUpdated, setLastUpdated] = useState(null) + const [theme, setTheme] = useState(() => currentTheme()) + const [trayBadge, setTrayBadge] = useState(() => readSetting('trayBadge') !== 'off') + const [showSettings, setShowSettings] = useState(false) + const [themeChoice, setThemeChoice] = useState(() => { + const saved = readSetting('theme') + return saved === 'dark' || saved === 'light' ? saved : 'system' + }) + + const selection = useRef({ period, provider }) + selection.current = { period, provider } + + const fetchKey = useCallback(async (p: Period, prov: Provider, opts: FetchOptions) => { + if (payloadCache.isInFlight(p, prov)) return + payloadCache.markInFlight(p, prov) + const isSelected = () => selection.current.period === p && selection.current.provider === prov + if (opts.showOverlay && isSelected()) setOverlay(true) + try { + const json = await invoke('fetch_payload', { + period: p, + provider: prov, + includeOptimize: opts.includeOptimize, + }) + // A quiet (no-optimize) refresh must not wipe findings a previous full fetch had. + if (!opts.includeOptimize) { + const previous = payloadCache.get(p, prov) + if (previous) json.optimize = previous.optimize + } + payloadCache.set(p, prov, json) + if (isSelected()) setPayload(json) + if (p === 'today' && prov === 'all') setTodayPayload(json) + setLastUpdated(new Date()) + setCliStatus(prev => (prev && !(prev.found && prev.compatible) ? { ...prev, found: true, compatible: true, error: null } : prev)) + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + if (message.includes('CLI not found')) { + const status = await invoke('cli_status').catch(() => null) + if (status) setCliStatus(status) + } else if (isSelected()) { + setError(message) + } + } finally { + payloadCache.clearInFlight(p, prov) + if (isSelected()) setOverlay(false) + } + }, []) + + const refreshAll = useCallback(async (opts: FetchOptions) => { + const { period: p, provider: prov } = selection.current + if (!(p === 'today' && prov === 'all')) { + fetchKey('today', 'all', { includeOptimize: false, showOverlay: false }) + } + await fetchKey(p, prov, opts) + }, [fetchKey]) + + const probeCli = useCallback(async () => { + setCliChecking(true) + try { + setCliStatus(await invoke('cli_status')) + } catch { + // Leave the status unknown; the data views already tell the user if fetches fail. + } finally { + setCliChecking(false) + } + }, []) + + const checkCli = useCallback(async () => { + setCliChecking(true) + try { + const status = await invoke('cli_status') + setCliStatus(status) + if (status.found && status.compatible) { + refreshAll({ includeOptimize: true, showOverlay: true }) + } + } catch (err) { + setError(err instanceof Error ? err.message : String(err)) + } finally { + setCliChecking(false) + } + }, [refreshAll]) + + useEffect(() => { + invoke('app_version').then(setVersion).catch(() => {}) + refreshAll({ includeOptimize: true, showOverlay: true }) + const id = setInterval(() => refreshAll({ includeOptimize: true, showOverlay: false }), REFRESH_INTERVAL_MS) + return () => clearInterval(id) + }, [refreshAll]) + + useEffect(() => { + const cached = payloadCache.get(period, provider) + setPayload(cached) + if (!cached) { + fetchKey(period, provider, { includeOptimize: true, showOverlay: true }) + } else if (payloadCache.age(period, provider) > STALE_MS) { + fetchKey(period, provider, { includeOptimize: true, showOverlay: false }) + } + }, [period, provider, fetchKey]) + + useEffect(() => { + const unlistenRefresh = listen('codeburn://refresh', () => refreshAll({ includeOptimize: true, showOverlay: true })) + const unlistenShown = listen('codeburn://shown', () => { + const { period: p, provider: prov } = selection.current + if (payloadCache.age(p, prov) > STALE_MS) refreshAll({ includeOptimize: true, showOverlay: false }) + }) + const unlistenTheme = listen('codeburn://toggle-theme', () => toggleTheme()) + return () => { + unlistenRefresh.then(fn => fn()) + unlistenShown.then(fn => fn()) + unlistenTheme.then(fn => fn()) + } + }, [refreshAll]) + + useEffect(() => { + const saved = readSetting('theme') + if (saved === 'dark' || saved === 'light') applyTheme(saved) + setTheme(currentTheme()) + const media = window.matchMedia('(prefers-color-scheme: dark)') + const onChange = () => setTheme(currentTheme()) + media.addEventListener('change', onChange) + return () => media.removeEventListener('change', onChange) + }, []) + + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if (e.key === 'Escape') invoke('hide_popover').catch(() => {}) + } + window.addEventListener('keydown', onKey) + return () => window.removeEventListener('keydown', onKey) + }, []) + + useEffect(() => { + if (!todayPayload) return + const text = `CodeBurn · ${formatCurrency(todayPayload.current.cost, currency)} today` + invoke('set_tray_tooltip', { text }).catch(() => {}) + }, [todayPayload, currency]) + + useEffect(() => { + const text = trayBadge && todayPayload ? trayBadgeText(todayPayload.current.cost, currency) : null + invoke('set_tray_badge', { text }).catch(err => setError(`Tray badge: ${String(err)}`)) + }, [todayPayload, currency, trayBadge]) + + + const chooseTheme = (choice: ThemeChoice) => { + applyTheme(choice === 'system' ? null : choice) + setThemeChoice(choice) + setTheme(currentTheme()) + } + + const toggleTheme = () => { + chooseTheme(currentTheme() === 'dark' ? 'light' : 'dark') + } + + const setTrayBadgePref = (on: boolean) => { + setTrayBadge(on) + writeSetting('trayBadge', on ? 'on' : 'off') + } + + const applyCurrency = async (code: string) => { + try { + setCurrency(await invoke('set_currency', { code })) + } catch (err) { + setError(err instanceof Error ? err.message : String(err)) + } + } + + const openTerminal = (args: string[]) => { + invoke('open_terminal_command', { args }).catch(err => setError(String(err))) + } + const connectClaude = () => { + invoke('open_claude_login').catch(err => setError(String(err))) + } + + const selectInsight = (mode: InsightMode) => { + setInsight(mode) + writeSetting('insight', mode) + } + + const providers = detectedProviders(todayPayload) + const planVisible = provider === 'claude' || (provider === 'all' && providers.length === 1 && providers[0] === 'claude') + const visibleModes = useMemo( + () => INSIGHT_ORDER.filter(m => m !== 'plan' || planVisible), + [planVisible], + ) + const activeInsight = visibleModes.includes(insight) ? insight : 'trend' + + const cliBlocked = cliStatus !== null && (!cliStatus.found || !cliStatus.compatible) + const isFilteredEmpty = payload !== null && provider !== 'all' && payload.current.cost <= 0 && payload.current.calls === 0 + const neverAnyData = payload !== null && provider === 'all' + && payload.current.calls === 0 && payload.current.sessions === 0 && payload.history.daily.length === 0 + + const footnote = [version ? `CodeBurn v${version}` : 'CodeBurn', lastUpdated ? `updated ${relativePast(lastUpdated)}` : null] + .filter(Boolean) + .join(' · ') + + return ( +

+
+
+ Code + Burn +
+
AI Coding Cost Tracker
+
+ + {!cliBlocked && !showSettings && ( + + )} + +
+ {showSettings ? ( + setShowSettings(false)} + version={version} + currency={currency} + onCurrency={applyCurrency} + themeChoice={themeChoice} + onThemeChoice={chooseTheme} + trayBadge={trayBadge} + onTrayBadge={setTrayBadgePref} + cliStatus={cliStatus} + onCheckCli={checkCli} + onProbeCli={probeCli} + cliChecking={cliChecking} + onQuit={() => invoke('quit_app').catch(() => {})} + /> + ) : cliBlocked && cliStatus ? ( + + ) : ( + <> + + + + {isFilteredEmpty ? ( + + ) : neverAnyData ? ( + refreshAll({ includeOptimize: true, showOverlay: true })} /> + ) : ( + <> +
+ + {activeInsight === 'plan' && ( + + )} + {activeInsight === 'trend' && } + {activeInsight === 'forecast' && } + {activeInsight === 'pulse' && payload && } + {activeInsight === 'stats' && payload && } +
+ {payload && ( + <> + + + + + )} + + )} + {overlay && } + + )} +
+ + refreshAll({ includeOptimize: true, showOverlay: true })} + onExport={format => openTerminal(['export', '-f', format])} + onOpenReport={() => openTerminal(['report'])} + onToggleTheme={toggleTheme} + onQuit={() => invoke('quit_app').catch(() => {})} + themeLabel={theme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'} + trayBadge={trayBadge} + onToggleTrayBadge={() => setTrayBadgePref(!trayBadge)} + onOpenSettings={() => setShowSettings(s => !s)} + settingsOpen={showSettings} + footnote={footnote} + /> + + + + {error && setError(null)} />} +
+ ) +} diff --git a/windows/src/components/ActivitySection.tsx b/windows/src/components/ActivitySection.tsx new file mode 100644 index 00000000..f7becd1b --- /dev/null +++ b/windows/src/components/ActivitySection.tsx @@ -0,0 +1,52 @@ +import type { MenubarPayload } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCompactCurrency } from '../lib/currency' +import { CollapsibleSection } from './CollapsibleSection' + +/// Column widths shared with the header captions (mac: Cost 54 / Turns 52 / 1-shot 44). +export const COL_COST = 54 +export const COL_COUNT = 52 +export const COL_ONESHOT = 44 + +type Props = { + payload: MenubarPayload + currency: CurrencyState +} + +export function ActivitySection({ payload, currency }: Props) { + const activities = payload.current.topActivities + if (activities.length === 0) return null + const maxCost = Math.max(...activities.map(a => a.cost), 0.01) + + return ( + + {activities.map(a => ( +
+ + {a.name} + {formatCompactCurrency(a.cost, currency)} + {a.turns} + + {a.oneShotRate == null ? '-' : `${Math.round(a.oneShotRate * 100)}%`} + +
+ ))} +
+ ) +} + +export function FixedBar({ fraction }: { fraction: number }) { + const pct = Math.min(Math.max(fraction, 0), 1) * 100 + return ( +
+ + {open && ( +
1 ? 'dropmenu-grid' : ''}`} + role="menu" + style={columns > 1 ? { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` } : undefined} + > + {items.map(item => ( +
+ {item.separatorBefore &&
} + +
+ ))} + {footnote &&
{footnote}
} +
+ )} +
+ ) +} diff --git a/windows/src/components/EmptyProviderState.tsx b/windows/src/components/EmptyProviderState.tsx new file mode 100644 index 00000000..e0843807 --- /dev/null +++ b/windows/src/components/EmptyProviderState.tsx @@ -0,0 +1,19 @@ +import type { Provider } from './AgentTabStrip' +import { PROVIDER_LABELS } from './AgentTabStrip' +import type { Period } from './PeriodTabs' +import { PERIOD_PHRASES } from './PeriodTabs' +import { TrayIcon } from './Icons' + +type Props = { + provider: Provider + period: Period +} + +export function EmptyProviderState({ provider, period }: Props) { + return ( +
+ +
No {PROVIDER_LABELS[provider]} data for {PERIOD_PHRASES[period]}
+
+ ) +} diff --git a/windows/src/components/ErrorToast.tsx b/windows/src/components/ErrorToast.tsx new file mode 100644 index 00000000..7855f369 --- /dev/null +++ b/windows/src/components/ErrorToast.tsx @@ -0,0 +1,29 @@ +import { useEffect, useRef } from 'react' +import { XIcon } from './Icons' + +const AUTO_DISMISS_MS = 8_000 + +type Props = { + message: string + onDismiss: () => void +} + +export function ErrorToast({ message, onDismiss }: Props) { + // Keep the latest handler in a ref so re-renders of the parent do not restart the timer. + const dismissRef = useRef(onDismiss) + dismissRef.current = onDismiss + + useEffect(() => { + const id = setTimeout(() => dismissRef.current(), AUTO_DISMISS_MS) + return () => clearTimeout(id) + }, [message]) + + return ( +
+ {message} + +
+ ) +} diff --git a/windows/src/components/FindingsSection.tsx b/windows/src/components/FindingsSection.tsx new file mode 100644 index 00000000..3745e021 --- /dev/null +++ b/windows/src/components/FindingsSection.tsx @@ -0,0 +1,72 @@ +import { useState } from 'react' +import type { MenubarPayload } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { computeTipGroups, type TipGroup } from '../lib/tips' +import { plural } from '../lib/currency' +import { ArrowForward, ArrowUpRightCircleIcon, BulbIcon, CheckCircleIcon, ChevronRight, WarningIcon } from './Icons' + +type Props = { + payload: MenubarPayload + currency: CurrencyState + onOpenTerminal: (args: string[]) => void +} + +export function FindingsSection({ payload, currency, onOpenTerminal }: Props) { + const [expanded, setExpanded] = useState(true) + const groups = computeTipGroups(payload, currency) + const totalSignals = groups.reduce((s, g) => s + g.items.length, 0) + if (totalSignals === 0) return null + + return ( +
+
+ + + {expanded && ( +
+ {groups.map(g => g.items.length > 0 && )} + {payload.optimize.findingCount > 0 && ( + + )} +
+ )} +
+
+ ) +} + +function GroupIcon({ icon }: { icon: string }) { + if (icon === 'check') return + if (icon === 'up') return + return +} + +function TipsGroupView({ group }: { group: TipGroup }) { + return ( +
+
+ + {group.label} +
+ {group.items.map((item, i) => ( +
+ + {item.text} + {item.trailing && {item.trailing}} +
+ ))} +
+ ) +} diff --git a/windows/src/components/FooterBar.tsx b/windows/src/components/FooterBar.tsx new file mode 100644 index 00000000..68490006 --- /dev/null +++ b/windows/src/components/FooterBar.tsx @@ -0,0 +1,81 @@ +import type { CurrencyState } from '../lib/currency' +import { CURRENCY_CODES } from '../lib/currency' +import { DropMenu } from './DropMenu' +import { CoinIcon, DownloadIcon, EllipsisIcon, RefreshIcon, TerminalIcon } from './Icons' + +type Props = { + currency: CurrencyState + onCurrency: (code: string) => void + loading: boolean + onRefresh: () => void + onExport: (format: 'csv' | 'json') => void + onOpenReport: () => void + onToggleTheme: () => void + onQuit: () => void + themeLabel: string + footnote: string + trayBadge: boolean + onToggleTrayBadge: () => void + onOpenSettings: () => void + settingsOpen: boolean +} + +export function FooterBar({ + currency, onCurrency, loading, onRefresh, onExport, onOpenReport, onToggleTheme, onQuit, themeLabel, footnote, + trayBadge, onToggleTrayBadge, onOpenSettings, settingsOpen, +}: Props) { + return ( +
+ {currency.code}} + items={CURRENCY_CODES.map(c => ({ id: c, label: c, checked: c === currency.code }))} + columns={3} + onSelect={onCurrency} + /> + + Export} + items={[ + { id: 'csv', label: 'CSV (folder)' }, + { id: 'json', label: 'JSON' }, + ]} + onSelect={id => onExport(id as 'csv' | 'json')} + /> + + + } + className="dropmenu-more" + items={[ + { id: 'settings', label: settingsOpen ? 'Back to overview' : 'Settings…' }, + { id: 'badge', label: "Show today's cost in tray", checked: trayBadge, separatorBefore: true }, + { id: 'theme', label: themeLabel }, + { id: 'quit', label: 'Quit CodeBurn', separatorBefore: true }, + ]} + footnote={footnote} + onSelect={id => { + if (id === 'settings') onOpenSettings() + if (id === 'badge') onToggleTrayBadge() + if (id === 'theme') onToggleTheme() + if (id === 'quit') onQuit() + }} + /> +
+ ) +} diff --git a/windows/src/components/ForecastInsight.tsx b/windows/src/components/ForecastInsight.tsx new file mode 100644 index 00000000..3ac30329 --- /dev/null +++ b/windows/src/components/ForecastInsight.tsx @@ -0,0 +1,59 @@ +import type { DailyEntry } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCurrency, formatCompactCurrency } from '../lib/currency' +import { computeHistoryStats } from '../lib/history' +import { ArrowUpRight, ArrowDownRight } from './Icons' + +const WEEK_DAYS = 7 + +type Props = { + days: DailyEntry[] + currency: CurrencyState +} + +export function ForecastInsight({ days, currency }: Props) { + const s = computeHistoryStats(days) + const prevDelta = s.previousMonthTotal && s.previousMonthTotal > 0 + ? ((s.monthProjection - s.previousMonthTotal) / s.previousMonthTotal) * 100 + : null + + return ( +
+
+
+
Month-to-date
+
{formatCurrency(s.monthToDate, currency)}
+
+
+
On pace for
+
{formatCurrency(s.monthProjection, currency)}
+
+
+ +
+
+
Avg/day (this wk)
+
{formatCompactCurrency(s.weekTotal / WEEK_DAYS, currency)}
+
+
+
Yesterday
+
{formatCompactCurrency(s.yesterday, currency)}
+
+
+
Last 7d
+
{formatCompactCurrency(s.weekTotal, currency)}
+
+
+ + {prevDelta !== null && s.previousMonthTotal !== null && ( +
+ {prevDelta >= 0 ? : } + + {prevDelta >= 0 ? '+' : ''}{Math.round(prevDelta)}% vs last month + ({formatCompactCurrency(s.previousMonthTotal, currency)}) + +
+ )} +
+ ) +} diff --git a/windows/src/components/HeroSection.tsx b/windows/src/components/HeroSection.tsx new file mode 100644 index 00000000..706a9991 --- /dev/null +++ b/windows/src/components/HeroSection.tsx @@ -0,0 +1,43 @@ +import type { MenubarPayload } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCurrency, plural } from '../lib/currency' +import { prettyDate, todayKey } from '../lib/dates' +import { SectionCaption } from './CollapsibleSection' + +type Props = { + payload: MenubarPayload | null + currency: CurrencyState + periodLabel: string + isToday: boolean +} + +export function HeroSection({ payload, currency, periodLabel, isToday }: Props) { + const todayLabel = prettyDate(todayKey()) + const caption = isToday ? `Today · ${todayLabel}` : (payload?.current.label || periodLabel) + + return ( +
+ +
+ {payload ? ( +
{formatCurrency(payload.current.cost, currency)}
+ ) : ( +
+ )} +
+ {payload ? ( + <> + {payload.current.calls.toLocaleString()} {payload.current.calls === 1 ? 'call' : 'calls'} + {plural(payload.current.sessions, 'session')} + + ) : ( + <> + + + + )} +
+
+
+ ) +} diff --git a/windows/src/components/Icons.tsx b/windows/src/components/Icons.tsx new file mode 100644 index 00000000..ae433822 --- /dev/null +++ b/windows/src/components/Icons.tsx @@ -0,0 +1,195 @@ +import type { SVGProps } from 'react' + +/// Small stroke icons standing in for the SF Symbols the macOS app uses. All are drawn on +/// a 16x16 grid at 1.5px stroke so they sit on the same optical baseline as 11px text. + +type IconProps = SVGProps & { size?: number } + +function Svg({ size = 12, children, ...rest }: IconProps) { + return ( + + ) +} + +export const FLAME_PATH = 'M8 1.5c.4 2.2 1.9 3.3 3.1 4.6C12.4 7.5 13 8.9 13 10.3 13 13 10.8 15 8 15s-5-2-5-4.7c0-1.6.7-2.8 1.5-3.7.2 1 .8 1.8 1.6 2.2C6 7 6.6 4.5 8 1.5z' + +export function FlameIcon({ filled = false, ...p }: IconProps & { filled?: boolean }) { + return +} + +export function ChevronRight(p: IconProps) { + return +} + +export function ChevronDown(p: IconProps) { + return +} + +export function RefreshIcon(p: IconProps) { + return ( + + + + + ) +} + +export function DownloadIcon(p: IconProps) { + return ( + + + + + ) +} + +export function TerminalIcon(p: IconProps) { + return ( + + + + + ) +} + +export function CoinIcon(p: IconProps) { + return ( + + + + + ) +} + +export function StarIcon(p: IconProps) { + return ( + + + + ) +} + +export function XIcon(p: IconProps) { + return +} + +export function BulbIcon(p: IconProps) { + return ( + + + + + ) +} + +export function CheckCircleIcon(p: IconProps) { + return ( + + + + + ) +} + +export function ArrowUpRightCircleIcon(p: IconProps) { + return ( + + + + + ) +} + +export function WarningIcon({ filled = true, ...p }: IconProps & { filled?: boolean }) { + return ( + + + + + ) +} + +export function ArrowUpRight(p: IconProps) { + return +} + +export function ArrowDownRight(p: IconProps) { + return +} + +export function ArrowForward(p: IconProps) { + return +} + +export function KeySlashIcon(p: IconProps) { + return ( + + + + + ) +} + +export function PersonDashedIcon(p: IconProps) { + return ( + + + + + + ) +} + +export function TrayIcon(p: IconProps) { + return ( + + + + + ) +} + +export function EllipsisIcon(p: IconProps) { + return ( + + + + + + ) +} + +export function CheckIcon(p: IconProps) { + return +} + +export function SunMoonIcon(p: IconProps) { + return ( + + + + + ) +} + +export function PowerIcon(p: IconProps) { + return ( + + + + + ) +} diff --git a/windows/src/components/InsightPills.tsx b/windows/src/components/InsightPills.tsx new file mode 100644 index 00000000..abd71a5d --- /dev/null +++ b/windows/src/components/InsightPills.tsx @@ -0,0 +1,41 @@ +export type InsightMode = 'plan' | 'trend' | 'forecast' | 'pulse' | 'stats' + +export const INSIGHT_LABELS: Record = { + plan: 'Plan', + trend: 'Trend', + forecast: 'Forecast', + pulse: 'Pulse', + stats: 'Stats', +} + +/// Same order as the macOS InsightMode enum: Plan first when it is visible. +export const INSIGHT_ORDER: InsightMode[] = ['plan', 'trend', 'forecast', 'pulse', 'stats'] + +export function isInsightMode(value: string | null): value is InsightMode { + return value !== null && value in INSIGHT_LABELS +} + +type Props = { + selected: InsightMode + onSelect: (m: InsightMode) => void + modes: InsightMode[] +} + +export function InsightPills({ selected, onSelect, modes }: Props) { + return ( +
+ {modes.map(m => ( + + ))} +
+ ) +} diff --git a/windows/src/components/LoadingOverlay.tsx b/windows/src/components/LoadingOverlay.tsx new file mode 100644 index 00000000..3d81276c --- /dev/null +++ b/windows/src/components/LoadingOverlay.tsx @@ -0,0 +1,44 @@ +import { FLAME_PATH } from './Icons' + +/// The macOS BurnLoadingOverlay: a blurred sheet over the scroll area with a flame that +/// fills bottom-to-top on a 1.4s loop while a soft glow pulses behind it. + +type Props = { periodLabel: string } + +export function LoadingOverlay({ periodLabel }: Props) { + return ( +
+
+ +
Loading {periodLabel}…
+
+
+ ) +} + +export function BurnFlame({ size = 64 }: { size?: number }) { + return ( +
+ + + +
+ ) +} diff --git a/windows/src/components/ModelsSection.tsx b/windows/src/components/ModelsSection.tsx new file mode 100644 index 00000000..9e61bf09 --- /dev/null +++ b/windows/src/components/ModelsSection.tsx @@ -0,0 +1,47 @@ +import type { Model } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCompactCurrency, formatTokens } from '../lib/currency' +import { CollapsibleSection } from './CollapsibleSection' +import { FixedBar, COL_COST, COL_COUNT } from './ActivitySection' + +type Props = { + models: Model[] + inputTokens: number + outputTokens: number + cacheHitPercent: number + currency: CurrencyState +} + +export function ModelsSection({ models, inputTokens, outputTokens, cacheHitPercent, currency }: Props) { + if (models.length === 0) return null + const maxCost = Math.max(...models.map(m => m.cost), 0.01) + + return ( + + {models.map(m => ( +
+ + {m.name} + {formatCompactCurrency(m.cost, currency)} + {m.calls} +
+ ))} + {(inputTokens > 0 || outputTokens > 0) && ( +
+ Tokens + {formatTokens(inputTokens)} in + · + {formatTokens(outputTokens)} out + · + {Math.round(cacheHitPercent)}% cache hit +
+ )} +
+ ) +} diff --git a/windows/src/components/NoDataState.tsx b/windows/src/components/NoDataState.tsx new file mode 100644 index 00000000..cfd31a36 --- /dev/null +++ b/windows/src/components/NoDataState.tsx @@ -0,0 +1,35 @@ +/// First-run copy for a machine where the CLI ran fine but found no sessions. Paths are +/// shown the way the reader's own OS spells them. + +import { homePath } from '../lib/platform' + +const SOURCES: Array<{ path: string | null; tool: string }> = [ + { path: homePath('.claude', 'projects'), tool: 'Claude Code' }, + { path: homePath('.codex', 'sessions'), tool: 'Codex CLI' }, + { path: null, tool: 'Cursor local database' }, + { path: null, tool: 'GitHub Copilot session events' }, + { path: homePath('.local', 'share', 'opencode'), tool: 'OpenCode' }, + { path: homePath('.pi'), tool: 'Pi' }, +] + +export function NoDataState({ onRefresh }: { onRefresh: () => void }) { + return ( +
+

No session data yet

+

+ CodeBurn reads local session logs written by your AI coding tools. None of the + supported tools have recorded a session on this machine yet. +

+

Watched locations

+
    + {SOURCES.map(s => ( +
  • + {s.path ? <>{s.path} {s.tool} : s.tool} +
  • + ))} +
+

Run one of those tools for a session, then refresh.

+ +
+ ) +} diff --git a/windows/src/components/PeriodTabs.tsx b/windows/src/components/PeriodTabs.tsx new file mode 100644 index 00000000..38d3cce9 --- /dev/null +++ b/windows/src/components/PeriodTabs.tsx @@ -0,0 +1,41 @@ +export type Period = 'today' | 'week' | '30days' | 'month' | 'all' + +export const PERIOD_LABELS: Record = { + today: 'Today', week: '7 Days', '30days': '30 Days', month: 'Month', all: 'All', +} + +/// Short phrase used in sentences ("Sessions (7 days)", "No Claude data for this month"). +export const PERIOD_PHRASES: Record = { + today: 'today', + week: 'the last 7 days', + '30days': 'the last 30 days', + month: 'this month', + all: 'all time', +} + +const PERIODS = Object.keys(PERIOD_LABELS) as Period[] + +type Props = { + selected: Period + onSelect: (p: Period) => void +} + +export function PeriodTabs({ selected, onSelect }: Props) { + return ( +
+ +
+ ) +} diff --git a/windows/src/components/PlanInsight.tsx b/windows/src/components/PlanInsight.tsx new file mode 100644 index 00000000..76788e1f --- /dev/null +++ b/windows/src/components/PlanInsight.tsx @@ -0,0 +1,147 @@ +import { useEffect, useState } from 'react' +import { invoke } from '@tauri-apps/api/core' +import type { MenubarPayload } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCompactCurrency, formatTokens, plural } from '../lib/currency' +import { relativeFuture } from '../lib/dates' +import type { PlanUsage, PlanWindow } from '../lib/plan' +import { projectWindow, earliestReset } from '../lib/plan' +import { BulbIcon, ChevronRight, KeySlashIcon, PersonDashedIcon, WarningIcon, ArrowUpRight } from './Icons' + +/// Sonnet-weighted approximation the mac app uses to turn a dollar saving into tokens. +const USD_PER_MILLION_EFFECTIVE_TOKENS = 9 +const MILLION = 1_000_000 +const PLAN_REFRESH_MS = 5 * 60_000 + +type LoadState = + | { kind: 'idle' } + | { kind: 'loading' } + | { kind: 'loaded'; usage: Extract } + | { kind: 'no_credentials' } + | { kind: 'failed'; message: string } + +type Props = { + payload: MenubarPayload | null + currency: CurrencyState + onOpenTerminal: (args: string[]) => void + onConnectClaude: () => void +} + +export function PlanInsight({ payload, currency, onOpenTerminal, onConnectClaude }: Props) { + const [state, setState] = useState({ kind: 'idle' }) + const [now, setNow] = useState(() => new Date()) + + const load = async () => { + setState(prev => (prev.kind === 'loaded' ? prev : { kind: 'loading' })) + try { + const usage = await invoke('plan_usage') + if (usage.state === 'ok') setState({ kind: 'loaded', usage }) + else if (usage.state === 'no_credentials') setState({ kind: 'no_credentials' }) + else setState({ kind: 'failed', message: usage.message }) + } catch (err) { + setState({ kind: 'failed', message: err instanceof Error ? err.message : String(err) }) + } + setNow(new Date()) + } + + useEffect(() => { + load() + const id = setInterval(load, PLAN_REFRESH_MS) + return () => clearInterval(id) + }, []) + + switch (state.kind) { + case 'idle': + case 'loading': + return ( +
+ +
Loading your plan...
+
Reading Claude Code credentials from this machine.
+
+ ) + case 'no_credentials': + return ( +
+ +
No Claude subscription connected
+
Click Connect to sign in with Claude in a terminal, then return here.
+
+ + +
+
+ ) + case 'failed': + return ( +
+ +
Couldn't load plan data
+
{state.message}
+
+ + +
+
+ ) + case 'loaded': { + const { usage } = state + const reset = earliestReset(usage.windows) + return ( +
+
+ {usage.tier} + {reset && Resets {relativeFuture(reset, now)}} +
+
+ {usage.windows.map(w => )} +
+ {payload && payload.optimize.findingCount > 0 && payload.optimize.savingsUSD > 0 && ( + + )} +
+ ) + } + } +} + +function UtilizationRow({ window, now }: { window: PlanWindow; now: Date }) { + const projection = projectWindow(window, now) + const clamped = Math.min(Math.max(window.percent, 0), 100) + const marker = projection ? Math.min(Math.max(projection.percent, 0), 100) : null + + let caption: string | null = null + if (projection) { + const pct = Math.round(projection.percent) + if (projection.source === 'historical') caption = `Based on last cycle: ${pct}%` + else if (projection.willOverflow && projection.hitsLimitAt) caption = `On pace: ${pct}% at reset · hits 100% ${relativeFuture(projection.hitsLimitAt, now)}` + else caption = `On pace: ${pct}% at reset` + } + + return ( +
+
+ {window.label} + {Math.round(clamped)}% +
+
+
+ {marker !== null &&
} +
+ {caption && ( +
+ {projection?.willOverflow ? : } + {caption} +
+ )} +
+ ) +} diff --git a/windows/src/components/PulseInsight.tsx b/windows/src/components/PulseInsight.tsx new file mode 100644 index 00000000..1668e8c8 --- /dev/null +++ b/windows/src/components/PulseInsight.tsx @@ -0,0 +1,32 @@ +import type { MenubarPayload } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCompactCurrency } from '../lib/currency' + +type Props = { + payload: MenubarPayload + currency: CurrencyState +} + +export function PulseInsight({ payload, currency }: Props) { + const { cacheHitPercent, oneShotRate, cost, sessions } = payload.current + const cacheText = cacheHitPercent <= 0 ? '-' : `${Math.round(cacheHitPercent)}%` + const oneShotText = oneShotRate == null ? '-' : `${Math.round(oneShotRate * 100)}%` + const costPerSession = sessions > 0 ? formatCompactCurrency(cost / sessions, currency) : '-' + + return ( +
+
+
Cache hit
+
{cacheText}
+
+
+
1-shot
+
{oneShotText}
+
+
+
Cost / session
+
{costPerSession}
+
+
+ ) +} diff --git a/windows/src/components/SettingsPanel.tsx b/windows/src/components/SettingsPanel.tsx new file mode 100644 index 00000000..00f8b04b --- /dev/null +++ b/windows/src/components/SettingsPanel.tsx @@ -0,0 +1,156 @@ +import { useEffect, useState, type ReactNode } from 'react' +import { invoke } from '@tauri-apps/api/core' +import type { CurrencyState } from '../lib/currency' +import { CURRENCY_CODES } from '../lib/currency' +import { homePath } from '../lib/platform' +import type { CliStatus } from './SetupState' +import { DropMenu } from './DropMenu' +import { ChevronDown, ChevronRight } from './Icons' + +/// Preferences that have no home in the popover proper. Deliberately small: the mac app has +/// no settings window at all, so everything here is a Windows/Linux need (login item, tray +/// text) or a convenience the footer already offers in a smaller form. + +export type ThemeChoice = 'system' | 'light' | 'dark' + +const GITHUB_URL = 'https://github.com/getagentseal/codeburn' + +type Props = { + onBack: () => void + version: string + currency: CurrencyState + onCurrency: (code: string) => void + themeChoice: ThemeChoice + onThemeChoice: (t: ThemeChoice) => void + trayBadge: boolean + onTrayBadge: (on: boolean) => void + cliStatus: CliStatus | null + onCheckCli: () => void + onProbeCli: () => void + cliChecking: boolean + onQuit: () => void +} + +export function SettingsPanel({ + onBack, version, currency, onCurrency, themeChoice, onThemeChoice, trayBadge, onTrayBadge, + cliStatus, onCheckCli, onProbeCli, cliChecking, onQuit, +}: Props) { + const [loginItem, setLoginItem] = useState(null) + const [loginError, setLoginError] = useState(null) + + useEffect(() => { + invoke('launch_at_login').then(setLoginItem).catch(() => setLoginItem(false)) + if (!cliStatus) onProbeCli() + // Probe once when the panel opens; cliStatus arriving later must not re-trigger it. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const toggleLogin = async () => { + if (loginItem === null) return + setLoginError(null) + try { + setLoginItem(await invoke('set_launch_at_login', { enabled: !loginItem })) + } catch (err) { + setLoginError(err instanceof Error ? err.message : String(err)) + } + } + + return ( +
+
+ + Settings +
+ +
+
General
+ + + + {loginError &&
{loginError}
} + + onTrayBadge(!trayBadge)} /> + +
+ +
+
Appearance
+ +
+ {(['system', 'light', 'dark'] as ThemeChoice[]).map(t => ( + + ))} +
+
+ + {currency.code}} + items={CURRENCY_CODES.map(c => ({ id: c, label: c, checked: c === currency.code }))} + columns={3} + align="right" + onSelect={onCurrency} + /> + +
+ +
+
Data source
+ + + +
+ +
+
About
+ +
GitHub + + + + +
+
+ ) +} + +function Row({ label, hint, children }: { label: string; hint?: string; children: ReactNode }) { + return ( +
+
+
{label}
+ {hint &&
{hint}
} +
+
{children}
+
+ ) +} + +function Toggle({ on, disabled = false, onToggle }: { on: boolean; disabled?: boolean; onToggle: () => void }) { + return ( + + ) +} diff --git a/windows/src/components/SetupState.tsx b/windows/src/components/SetupState.tsx new file mode 100644 index 00000000..9c392e93 --- /dev/null +++ b/windows/src/components/SetupState.tsx @@ -0,0 +1,71 @@ +import { useState } from 'react' +import { BurnFlame } from './LoadingOverlay' +import { WarningIcon } from './Icons' + +/// Shown instead of the data views when the CLI is missing or too old. This is what a +/// brand-new Windows user sees, so it has to explain the one thing they need to do. + +export type CliStatus = { + found: boolean + program: string + version: string | null + min_version: string + compatible: boolean + error: string | null +} + +const INSTALL_COMMAND = 'npm install -g codeburn' + +type Props = { + status: CliStatus + checking: boolean + onCheckAgain: () => void +} + +export function SetupState({ status, checking, onCheckAgain }: Props) { + const [copied, setCopied] = useState(false) + const outdated = status.found && !status.compatible + + const copy = async () => { + try { + await navigator.clipboard.writeText(INSTALL_COMMAND) + setCopied(true) + setTimeout(() => setCopied(false), 1500) + } catch { + setCopied(false) + } + } + + return ( +
+ +

+ {outdated ? 'Update the CodeBurn CLI' : 'Install the CodeBurn CLI'} +

+

+ {outdated + ? `This app needs codeburn ${status.min_version} or newer; version ${status.version} was found.` + : 'The tray app reads everything through the codeburn command line tool, which is not installed on this machine yet.'} +

+
+ {INSTALL_COMMAND} + +
+

+ Requires Node.js 22 or newer. After installing, click Check again; no restart needed. +

+
+ +
+ {status.error && ( +
+ Details +
{status.error}
+
Looked for: {status.program}
+
+ )} +
+ ) +} diff --git a/windows/src/components/StarBanner.tsx b/windows/src/components/StarBanner.tsx new file mode 100644 index 00000000..ca359deb --- /dev/null +++ b/windows/src/components/StarBanner.tsx @@ -0,0 +1,29 @@ +import { useState } from 'react' +import { readSetting, writeSetting } from '../lib/settings' +import { StarIcon, XIcon } from './Icons' + +const GITHUB_URL = 'https://github.com/getagentseal/codeburn' + +export function StarBanner() { + const [dismissed, setDismissed] = useState(() => readSetting('starBannerDismissed') === 'true') + if (dismissed) return null + + const dismiss = () => { + writeSetting('starBannerDismissed', 'true') + setDismissed(true) + } + + return ( + + ) +} diff --git a/windows/src/components/StatsInsight.tsx b/windows/src/components/StatsInsight.tsx new file mode 100644 index 00000000..8ba13f5e --- /dev/null +++ b/windows/src/components/StatsInsight.tsx @@ -0,0 +1,63 @@ +import type { MenubarPayload } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCurrency, formatCompactCurrency, plural } from '../lib/currency' +import { daysInMonth, monthDay } from '../lib/dates' +import { computeHistoryStats } from '../lib/history' +import type { Period } from './PeriodTabs' + +type Props = { + payload: MenubarPayload + currency: CurrencyState + period: Period +} + +const PERIOD_SUFFIX: Record = { + today: 'today', + week: '(7 days)', + '30days': '(30 days)', + month: '(month)', + all: '(all time)', +} + +export function StatsInsight({ payload, currency, period }: Props) { + const s = computeHistoryStats(payload.history.daily) + const suffix = PERIOD_SUFFIX[period] + + return ( +
+
+
+ + + + +
+
+ + + 0 ? plural(s.currentStreak, 'day') : '-'} /> + 0 ? plural(s.longestStreak, 'day') : '-'} /> +
+
+ {s.trackedDays > 0 && ( +
+ + Tracked spend (last {plural(s.trackedDays, 'day')}) + + + {formatCurrency(s.trackedTotal, currency)} + +
+ )} +
+ ) +} + +function StatRow({ label, value }: { label: string; value: string }) { + return ( +
+
{label}
+
{value}
+
+ ) +} diff --git a/windows/src/components/TrendInsight.tsx b/windows/src/components/TrendInsight.tsx new file mode 100644 index 00000000..9a8e1d85 --- /dev/null +++ b/windows/src/components/TrendInsight.tsx @@ -0,0 +1,153 @@ +import { useState } from 'react' +import type { DailyEntry, DailyModel } from '../lib/payload' +import type { CurrencyState } from '../lib/currency' +import { formatCompactCurrency, formatCurrency, formatTokens } from '../lib/currency' +import { todayKey, formatDateKey, addDays, startOfDay, prettyDate, shortDate } from '../lib/dates' +import { ArrowUpRight, ArrowDownRight } from './Icons' + +/// 19 columns of 13px bars with 4px gaps = 319px, the widest chart that fits the 332px +/// content width of a 360px popover (mirrors mac trendDays / trendBarWidth / trendBarGap). +export const TREND_DAYS = 19 +const MAX_TOOLTIP_MODELS = 4 +const MIN_BAR_PCT = 2 + +type TrendBar = { + date: string + cost: number + tokens: number + isToday: boolean + topModels: DailyModel[] +} + +function buildBars(days: DailyEntry[]): TrendBar[] { + const byDate = new Map(days.map(d => [d.date, d])) + const today = startOfDay(new Date()) + const tk = todayKey() + const bars: TrendBar[] = [] + for (let i = TREND_DAYS - 1; i >= 0; i--) { + const key = formatDateKey(addDays(today, -i)) + const entry = byDate.get(key) + bars.push({ + date: key, + cost: entry?.cost ?? 0, + tokens: (entry?.inputTokens ?? 0) + (entry?.outputTokens ?? 0), + isToday: key === tk, + topModels: entry?.topModels ?? [], + }) + } + return bars +} + +function computeDelta(bars: TrendBar[], allDays: DailyEntry[]): number | null { + const thisTotal = bars.reduce((s, b) => s + b.cost, 0) + const today = startOfDay(new Date()) + const priorStart = formatDateKey(addDays(today, -(2 * TREND_DAYS - 1))) + const thisStart = formatDateKey(addDays(today, -(TREND_DAYS - 1))) + const priorTotal = allDays + .filter(d => d.date >= priorStart && d.date < thisStart) + .reduce((s, d) => s + d.cost, 0) + if (priorTotal <= 0) return null + return ((thisTotal - priorTotal) / priorTotal) * 100 +} + +type Props = { + days: DailyEntry[] + currency: CurrencyState +} + +export function TrendInsight({ days, currency }: Props) { + const [hoveredIdx, setHoveredIdx] = useState(null) + const bars = buildBars(days) + const totalTokens = bars.reduce((s, b) => s + b.tokens, 0) + const useTokens = totalTokens > 0 + const metric = (b: TrendBar) => useTokens ? b.tokens : b.cost + const maxVal = Math.max(...bars.map(metric), 0.01) + const avgVal = bars.reduce((s, b) => s + metric(b), 0) / bars.length + const totalCost = bars.reduce((s, b) => s + b.cost, 0) + const peak = bars.filter(b => metric(b) > 0).sort((a, b) => metric(b) - metric(a))[0] + const yd = formatDateKey(addDays(startOfDay(new Date()), -1)) + const yesterday = bars.find(b => b.date === yd) + const delta = computeDelta(bars, days) + + const fmtVal = (v: number) => useTokens ? `${formatTokens(v)} tok` : formatCompactCurrency(v, currency) + const heroText = useTokens ? `${formatTokens(totalTokens)} tokens` : formatCurrency(totalCost, currency) + const hovered = hoveredIdx !== null ? bars[hoveredIdx] : null + + return ( +
+
+
+
Last {TREND_DAYS} days
+
{heroText}
+
+ {delta !== null && ( +
+ {delta >= 0 ? : } + {delta >= 0 ? '+' : ''}{Math.round(delta)}% vs prior {TREND_DAYS}d +
+ )} +
+ +
setHoveredIdx(null)}> +
+ {bars.map((bar, i) => { + const val = metric(bar) + const pct = (val / maxVal) * 100 + const cls = [ + 'trend-bar', + bar.isToday ? 'trend-bar-today' : '', + val <= 0 ? 'trend-bar-empty' : '', + hoveredIdx === i ? 'trend-bar-hovered' : '', + ].join(' ') + return ( +
setHoveredIdx(i)} + > +
+
+ ) + })} +
+
+ {hovered && ( +
+
+ {prettyDate(hovered.date)} + {fmtVal(metric(hovered))} +
+ {hovered.topModels.slice(0, MAX_TOOLTIP_MODELS).map(m => ( +
+ + {m.name} + {formatTokens(m.inputTokens + m.outputTokens)} tok + ({formatTokens(m.inputTokens)}/{formatTokens(m.outputTokens)}) +
+ ))} +
+ )} +
+ +
+
+
Avg/day
+
{fmtVal(avgVal)}
+
+
+
Peak
+
+ {peak ? `${fmtVal(metric(peak))} on ${shortDate(peak.date)}` : '-'} +
+
+
+
Yesterday
+
{yesterday ? fmtVal(metric(yesterday)) : '-'}
+
+
+
+ ) +} diff --git a/windows/src/lib/cache.ts b/windows/src/lib/cache.ts new file mode 100644 index 00000000..77cb04aa --- /dev/null +++ b/windows/src/lib/cache.ts @@ -0,0 +1,43 @@ +/// Per (period, provider) payload cache. Entries are served instantly on tab switches and +/// refreshed in the background (stale-while-revalidate); `age` lets the caller decide +/// whether a background refresh is due. + +interface CacheEntry { + data: T + ts: number +} + +export class PayloadCache { + private store = new Map>() + private flights = new Set() + + private key(period: string, provider: string): string { + return `${period}:${provider}` + } + + get(period: string, provider: string): T | null { + return this.store.get(this.key(period, provider))?.data ?? null + } + + /// Milliseconds since the entry was stored, or Infinity when absent. + age(period: string, provider: string): number { + const entry = this.store.get(this.key(period, provider)) + return entry ? Date.now() - entry.ts : Number.POSITIVE_INFINITY + } + + set(period: string, provider: string, data: T): void { + this.store.set(this.key(period, provider), { data, ts: Date.now() }) + } + + isInFlight(period: string, provider: string): boolean { + return this.flights.has(this.key(period, provider)) + } + + markInFlight(period: string, provider: string): void { + this.flights.add(this.key(period, provider)) + } + + clearInFlight(period: string, provider: string): void { + this.flights.delete(this.key(period, provider)) + } +} diff --git a/windows/src/lib/currency.ts b/windows/src/lib/currency.ts new file mode 100644 index 00000000..c334af90 --- /dev/null +++ b/windows/src/lib/currency.ts @@ -0,0 +1,70 @@ +/// Currency formatting that mirrors the macOS app's Double.asCurrency / asCompactCurrency. +/// The Rust backend hands us { code, symbol, rate } so the frontend stays dumb about FX -- +/// it just multiplies and renders. + +export type CurrencyState = { + code: string + symbol: string + rate: number +} + +export const USD: CurrencyState = { code: 'USD', symbol: '$', rate: 1 } + +export const CURRENCY_CODES = [ + 'USD', 'GBP', 'EUR', 'AUD', 'CAD', 'NZD', 'JPY', 'CHF', 'INR', + 'BRL', 'SEK', 'SGD', 'HKD', 'KRW', 'MXN', 'ZAR', 'DKK', +] as const + +const SUB_CENT = 0.005 + +/// Wider format with thousands separators. Used for the hero value. +export function formatCurrency(usdAmount: number, currency: CurrencyState): string { + const converted = usdAmount * currency.rate + const parts = converted.toFixed(2).split('.') + const whole = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',') + return `${currency.symbol}${whole}.${parts[1]}` +} + +/// Compact form (no thousands separators) used in dense tables where the monospace font +/// already gives visual grouping. +export function formatCompactCurrency(usdAmount: number, currency: CurrencyState): string { + const converted = usdAmount * currency.rate + return `${currency.symbol}${converted.toFixed(2)}` +} + +/// For savings and other tiny amounts: never print a misleading "$0.00". +export function formatSmallCurrency(usdAmount: number, currency: CurrencyState): string { + const converted = usdAmount * currency.rate + if (converted > 0 && converted < SUB_CENT) return `<${currency.symbol}0.01` + return formatCompactCurrency(usdAmount, currency) +} + +/// Token compaction shared by every surface (the mac app rounds K to whole numbers). +export function formatTokens(n: number): string { + if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M` + if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K` + return `${Math.round(n)}` +} + +const BADGE_THOUSAND = 1_000 +const BADGE_MILLION = 1_000_000 + +/// The spend string drawn into the tray icon. Budget is a 16px-wide pixel grid, so at most +/// four glyph slots: "$9.5", "$87", "142", "1.2K", "12K", "0.1M". The `$` only fits when +/// there are two digits or fewer, and only USD has a glyph in the icon font. +export function trayBadgeText(usdAmount: number, currency: CurrencyState): string { + const v = Math.max(0, usdAmount * currency.rate) + const symbol = currency.code === 'USD' ? '$' : '' + // Thresholds sit at the rounding boundary of the format above them, so "9.96" becomes + // "$10" rather than "$10.0" and "999.7" becomes "1.0K" rather than "1000". + if (v < 9.95) return `${symbol}${v.toFixed(1)}` + if (v < 99.5) return `${symbol}${Math.round(v)}` + if (v < 999.5) return `${Math.round(v)}` + if (v < 9_950) return `${(v / BADGE_THOUSAND).toFixed(1)}K` + if (v < 999_500) return `${Math.round(v / BADGE_THOUSAND)}K` + return `${(v / BADGE_MILLION).toFixed(1)}M` +} + +export function plural(n: number, singular: string, pluralForm = `${singular}s`): string { + return `${n} ${n === 1 ? singular : pluralForm}` +} diff --git a/windows/src/lib/dates.ts b/windows/src/lib/dates.ts new file mode 100644 index 00000000..273afbdc --- /dev/null +++ b/windows/src/lib/dates.ts @@ -0,0 +1,89 @@ +/// All calendar math is in the machine's local time zone. The CLI buckets `history.daily` +/// by local date, so "today" here must be the same local day or the trend chart and the +/// hero disagree around midnight. + +const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] +const MONTH_NAMES = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', +] + +export const MS_PER_DAY = 86_400_000 + +function pad2(n: number): string { + return n < 10 ? `0${n}` : String(n) +} + +export function todayKey(): string { + return formatDateKey(new Date()) +} + +export function formatDateKey(d: Date): string { + return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}` +} + +export function parseDateKey(ymd: string): Date { + const [y, m, d] = ymd.split('-').map(Number) + return new Date(y, m - 1, d) +} + +export function addDays(d: Date, n: number): Date { + const r = new Date(d.getTime()) + r.setDate(r.getDate() + n) + return r +} + +export function startOfDay(d: Date): Date { + return new Date(d.getFullYear(), d.getMonth(), d.getDate()) +} + +export function prettyDate(ymd: string): string { + const dt = parseDateKey(ymd) + return `${DAY_NAMES[dt.getDay()]} ${MONTH_NAMES[dt.getMonth()]} ${dt.getDate()}` +} + +export function monthDay(ymd: string): string { + const dt = parseDateKey(ymd) + return `${MONTH_NAMES[dt.getMonth()]} ${dt.getDate()}` +} + +export function shortDate(ymd: string): string { + const parts = ymd.split('-') + return `${parts[1]}/${parts[2]}` +} + +export function firstOfMonth(d: Date): Date { + return new Date(d.getFullYear(), d.getMonth(), 1) +} + +export function daysInMonth(d: Date): number { + return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate() +} + +export function dayOfMonth(d: Date): number { + return d.getDate() +} + +export function previousMonthRange(d: Date): { first: string; last: string } { + const first = new Date(d.getFullYear(), d.getMonth() - 1, 1) + const last = new Date(d.getFullYear(), d.getMonth(), 0) + return { first: formatDateKey(first), last: formatDateKey(last) } +} + +/// "in 42m", "in 3h", "in 2d", or "now". +export function relativeFuture(target: Date, now = new Date()): string { + const secs = (target.getTime() - now.getTime()) / 1000 + if (secs <= 0) return 'now' + if (secs < 3600) return `in ${Math.ceil(secs / 60)}m` + if (secs < 86_400) return `in ${Math.ceil(secs / 3600)}h` + return `in ${Math.ceil(secs / 86_400)}d` +} + +/// "just now", "2 min ago", "1 h ago". +export function relativePast(target: Date, now = new Date()): string { + const secs = Math.max(0, (now.getTime() - target.getTime()) / 1000) + if (secs < 45) return 'just now' + if (secs < 3600) return `${Math.round(secs / 60)} min ago` + if (secs < 86_400) return `${Math.round(secs / 3600)} h ago` + return `${Math.round(secs / 86_400)} d ago` +} diff --git a/windows/src/lib/history.ts b/windows/src/lib/history.ts new file mode 100644 index 00000000..ef532bf5 --- /dev/null +++ b/windows/src/lib/history.ts @@ -0,0 +1,99 @@ +import type { DailyEntry } from './payload' +import { + formatDateKey, addDays, startOfDay, firstOfMonth, daysInMonth, dayOfMonth, + previousMonthRange, parseDateKey, MS_PER_DAY, +} from './dates' + +/// Derived numbers over `history.daily` that several insights share (Trend, Forecast, +/// Stats, Tips). One implementation so the streak in Tips and the streak in Stats agree. + +const MAX_STREAK_LOOKBACK_DAYS = 400 +const WEEK_DAYS = 7 + +export type HistoryStats = { + weekTotal: number + priorWeekTotal: number + weekDelta: number | null + yesterday: number + monthToDate: number + monthProjection: number + previousMonthTotal: number | null + activeDaysThisMonth: number + currentStreak: number + longestStreak: number + peak: DailyEntry | null + trackedTotal: number + trackedDays: number +} + +export function computeHistoryStats(history: DailyEntry[], now = new Date()): HistoryStats { + const today = startOfDay(now) + const costByDate = new Map(history.map(d => [d.date, d.cost])) + const sum = (from: string, to: string) => + history.filter(d => d.date >= from && d.date <= to).reduce((s, d) => s + d.cost, 0) + + const todayKey = formatDateKey(today) + const weekStart = formatDateKey(addDays(today, -(WEEK_DAYS - 1))) + const priorWeekStart = formatDateKey(addDays(today, -(2 * WEEK_DAYS - 1))) + const priorWeekEnd = formatDateKey(addDays(today, -WEEK_DAYS)) + const weekTotal = sum(weekStart, todayKey) + const priorWeekTotal = sum(priorWeekStart, priorWeekEnd) + const weekDelta = priorWeekTotal > 0 ? ((weekTotal - priorWeekTotal) / priorWeekTotal) * 100 : null + + const yesterday = costByDate.get(formatDateKey(addDays(today, -1))) ?? 0 + + const fomKey = formatDateKey(firstOfMonth(now)) + const monthToDate = sum(fomKey, todayKey) + const dom = dayOfMonth(now) + const monthProjection = dom > 0 ? (monthToDate / dom) * daysInMonth(now) : 0 + const prev = previousMonthRange(now) + const prevEntries = history.filter(d => d.date >= prev.first && d.date <= prev.last) + const previousMonthTotal = prevEntries.length > 0 ? prevEntries.reduce((s, d) => s + d.cost, 0) : null + + const activeDaysThisMonth = history.filter(d => d.date >= fomKey && d.cost > 0).length + + let currentStreak = 0 + for (let i = 0; i < MAX_STREAK_LOOKBACK_DAYS; i++) { + if ((costByDate.get(formatDateKey(addDays(today, -i))) ?? 0) > 0) currentStreak++ + else break + } + + let longestStreak = 0 + if (history.length > 0) { + const first = parseDateKey([...history].sort((a, b) => a.date.localeCompare(b.date))[0].date) + const totalDays = Math.min( + MAX_STREAK_LOOKBACK_DAYS, + Math.round((today.getTime() - first.getTime()) / MS_PER_DAY) + 1, + ) + const start = addDays(today, -(totalDays - 1)) + let running = 0 + for (let i = 0; i < totalDays; i++) { + if ((costByDate.get(formatDateKey(addDays(start, i))) ?? 0) > 0) { + running++ + longestStreak = Math.max(longestStreak, running) + } else { + running = 0 + } + } + } + + const peak = history.reduce( + (best, d) => (!best || d.cost > best.cost) ? d : best, null, + ) + + return { + weekTotal, + priorWeekTotal, + weekDelta, + yesterday, + monthToDate, + monthProjection, + previousMonthTotal, + activeDaysThisMonth, + currentStreak, + longestStreak, + peak: peak && peak.cost > 0 ? peak : null, + trackedTotal: history.reduce((s, d) => s + d.cost, 0), + trackedDays: history.length, + } +} diff --git a/windows/src/lib/payload.ts b/windows/src/lib/payload.ts new file mode 100644 index 00000000..e4d34755 --- /dev/null +++ b/windows/src/lib/payload.ts @@ -0,0 +1,57 @@ +/// Shape of the JSON returned by `codeburn status --format menubar-json`. Kept in sync with +/// `src/menubar-json.ts` (CLI) and `mac/Sources/CodeBurnMenubar/Data/MenubarPayload.swift` +/// (macOS app). Any field change there must land here too or the frontend silently drops it. +export type MenubarPayload = { + generated: string + current: { + label: string + cost: number + calls: number + sessions: number + oneShotRate: number | null + inputTokens: number + outputTokens: number + cacheHitPercent: number + topActivities: Activity[] + topModels: Model[] + providers: Record + } + optimize: { + findingCount: number + savingsUSD: number + topFindings: Array<{ title: string; impact: 'high' | 'medium' | 'low'; savingsUSD: number }> + } + history: { daily: DailyEntry[] } +} + +export type Activity = { + name: string + cost: number + turns: number + oneShotRate: number | null +} + +export type Model = { + name: string + cost: number + calls: number +} + +export type DailyModel = { + name: string + cost: number + calls: number + inputTokens: number + outputTokens: number +} + +export type DailyEntry = { + date: string + cost: number + calls: number + inputTokens: number + outputTokens: number + cacheReadTokens: number + cacheWriteTokens: number + topModels?: DailyModel[] +} diff --git a/windows/src/lib/plan.ts b/windows/src/lib/plan.ts new file mode 100644 index 00000000..72ccc6ce --- /dev/null +++ b/windows/src/lib/plan.ts @@ -0,0 +1,73 @@ +/// Claude subscription usage as returned by the Rust `plan_usage` command, plus the +/// projection math from the macOS PlanInsight so both apps draw the same marker. + +export type PlanWindow = { + key: 'five_hour' | 'seven_day' | 'seven_day_opus' | 'seven_day_sonnet' | string + label: string + percent: number + resets_at: string | null + previous_final: number | null +} + +export type PlanUsage = + | { state: 'ok'; tier: string; raw_tier: string | null; windows: PlanWindow[]; fetched_at: string } + | { state: 'no_credentials' } + | { state: 'failed'; message: string } + +export type PlanProjection = { + percent: number + willOverflow: boolean + hitsLimitAt: Date | null + source: 'linear' | 'historical' +} + +const FIVE_HOUR_SECONDS = 5 * 3600 +const SEVEN_DAY_SECONDS = 7 * 86_400 +/// Below this fraction of the window the linear extrapolation is noise; fall back to +/// last cycle's final reading instead. +const FRESH_WINDOW_THRESHOLD = 0.05 +const FULL_PERCENT = 100 + +function windowSeconds(key: string): number { + return key === 'five_hour' ? FIVE_HOUR_SECONDS : SEVEN_DAY_SECONDS +} + +export function projectWindow(window: PlanWindow, now = new Date()): PlanProjection | null { + if (!window.resets_at) return null + const resetsAt = new Date(window.resets_at) + if (Number.isNaN(resetsAt.getTime())) return null + const seconds = windowSeconds(window.key) + const windowStart = resetsAt.getTime() / 1000 - seconds + const elapsed = now.getTime() / 1000 - windowStart + const elapsedFraction = elapsed / seconds + + if (elapsedFraction > FRESH_WINDOW_THRESHOLD && window.percent > 0) { + const projected = window.percent / elapsedFraction + let hitsLimitAt: Date | null = null + if (projected > FULL_PERCENT && window.percent < FULL_PERCENT) { + const percentPerSecond = window.percent / elapsed + if (percentPerSecond > 0) { + hitsLimitAt = new Date(now.getTime() + ((FULL_PERCENT - window.percent) / percentPerSecond) * 1000) + } + } + return { percent: projected, willOverflow: projected > FULL_PERCENT, hitsLimitAt, source: 'linear' } + } + + if (window.previous_final != null) { + return { + percent: window.previous_final, + willOverflow: window.previous_final > FULL_PERCENT, + hitsLimitAt: null, + source: 'historical', + } + } + return null +} + +export function earliestReset(windows: PlanWindow[]): Date | null { + const dates = windows + .map(w => (w.resets_at ? new Date(w.resets_at) : null)) + .filter((d): d is Date => d !== null && !Number.isNaN(d.getTime())) + if (dates.length === 0) return null + return dates.reduce((a, b) => (a < b ? a : b)) +} diff --git a/windows/src/lib/platform.ts b/windows/src/lib/platform.ts new file mode 100644 index 00000000..a7a1733f --- /dev/null +++ b/windows/src/lib/platform.ts @@ -0,0 +1,10 @@ +/// Paths shown in copy use the reader's own OS spelling. + +export const IS_WINDOWS = navigator.userAgent.includes('Windows') + +const HOME = IS_WINDOWS ? '%USERPROFILE%' : '~' +const SEP = IS_WINDOWS ? '\\' : '/' + +export function homePath(...parts: string[]): string { + return [HOME, ...parts].join(SEP) +} diff --git a/windows/src/lib/settings.ts b/windows/src/lib/settings.ts new file mode 100644 index 00000000..8aa4d2e1 --- /dev/null +++ b/windows/src/lib/settings.ts @@ -0,0 +1,42 @@ +/// The few preferences that live in the webview (everything the CLI also needs, like the +/// currency, lives in ~/.config/codeburn/config.json via the Rust side). + +const KEYS = { + theme: 'codeburn.theme', + insight: 'codeburn.insight', + starBannerDismissed: 'codeburn.starBannerDismissed', + trayBadge: 'codeburn.trayBadge', +} as const + +type Key = keyof typeof KEYS + +export function readSetting(key: Key): string | null { + try { + return localStorage.getItem(KEYS[key]) + } catch { + return null + } +} + +export function writeSetting(key: Key, value: string | null): void { + try { + if (value === null) localStorage.removeItem(KEYS[key]) + else localStorage.setItem(KEYS[key], value) + } catch { + // Storage can be unavailable in a locked-down webview; preferences are best-effort. + } +} + +export type Theme = 'light' | 'dark' + +export function currentTheme(): Theme { + const stamped = document.documentElement.getAttribute('data-theme') + if (stamped === 'dark' || stamped === 'light') return stamped + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' +} + +export function applyTheme(theme: Theme | null): void { + if (theme) document.documentElement.setAttribute('data-theme', theme) + else document.documentElement.removeAttribute('data-theme') + writeSetting('theme', theme) +} diff --git a/windows/src/lib/tips.ts b/windows/src/lib/tips.ts new file mode 100644 index 00000000..d80d9c1b --- /dev/null +++ b/windows/src/lib/tips.ts @@ -0,0 +1,48 @@ +import type { MenubarPayload } from './payload' +import type { CurrencyState } from './currency' +import { formatCompactCurrency, formatSmallCurrency } from './currency' +import { computeHistoryStats } from './history' + +export type TipItem = { text: string; trailing: string | null } +export type TipGroup = { label: string; icon: string; items: TipItem[] } + +const CACHE_HIT_GOOD = 80 +const CACHE_HIT_LOW = 50 +const ONESHOT_GOOD = 0.75 +const ONESHOT_LOW = 0.5 +const SPEND_DOWN_THRESHOLD = -10 +const SPEND_UP_THRESHOLD = 25 +const STREAK_MILESTONE = 5 +const MONTH_GROWTH_WARNING = 1.3 +const TOP_FINDINGS_COUNT = 3 + +export function computeTipGroups(payload: MenubarPayload, currency: CurrencyState): TipGroup[] { + const stats = computeHistoryStats(payload.history.daily) + const { cacheHitPercent, oneShotRate } = payload.current + + const wins: TipItem[] = [] + if (cacheHitPercent >= CACHE_HIT_GOOD) wins.push({ text: `Cache hit at ${Math.round(cacheHitPercent)}% - most prompts reuse cache`, trailing: null }) + if (oneShotRate != null && oneShotRate >= ONESHOT_GOOD) wins.push({ text: `${Math.round(oneShotRate * 100)}% one-shot - edits landing first try`, trailing: null }) + if (stats.weekDelta != null && stats.weekDelta < SPEND_DOWN_THRESHOLD) wins.push({ text: `Spend down ${Math.round(Math.abs(stats.weekDelta))}% vs last 7 days`, trailing: null }) + if (stats.currentStreak >= STREAK_MILESTONE) wins.push({ text: `${stats.currentStreak}-day usage streak`, trailing: null }) + + const improvements: TipItem[] = payload.optimize.topFindings.slice(0, TOP_FINDINGS_COUNT).map(f => ({ + text: f.title, + trailing: formatSmallCurrency(f.savingsUSD, currency), + })) + + const risks: TipItem[] = [] + if (stats.weekDelta != null && stats.weekDelta > SPEND_UP_THRESHOLD) risks.push({ text: `Spend up ${Math.round(stats.weekDelta)}% vs prior 7 days`, trailing: null }) + if (cacheHitPercent > 0 && cacheHitPercent < CACHE_HIT_LOW) risks.push({ text: `Cache hit only ${Math.round(cacheHitPercent)}% - paying for cold prompts`, trailing: null }) + if (oneShotRate != null && oneShotRate < ONESHOT_LOW) risks.push({ text: `${Math.round(oneShotRate * 100)}% one-shot - lots of iteration`, trailing: null }) + if (stats.previousMonthTotal != null && stats.previousMonthTotal > 0 && stats.monthProjection > stats.previousMonthTotal * MONTH_GROWTH_WARNING) { + const pct = Math.round(((stats.monthProjection - stats.previousMonthTotal) / stats.previousMonthTotal) * 100) + risks.push({ text: `On pace for ${formatCompactCurrency(stats.monthProjection, currency)} this month (+${pct}% vs last)`, trailing: null }) + } + + return [ + { label: "What's working", icon: 'check', items: wins }, + { label: 'What to improve', icon: 'up', items: improvements }, + { label: 'Risks', icon: 'warn', items: risks }, + ] +} diff --git a/windows/src/main.tsx b/windows/src/main.tsx new file mode 100644 index 00000000..5dd018a7 --- /dev/null +++ b/windows/src/main.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { App } from './App' +import './styles.css' + +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + +) diff --git a/windows/src/styles.css b/windows/src/styles.css new file mode 100644 index 00000000..c61da8b6 --- /dev/null +++ b/windows/src/styles.css @@ -0,0 +1,1153 @@ +/* CodeBurn tray popover. Values mirror mac/Sources/CodeBurnMenubar (Theme.swift + views): + translucent system label colours, 360x660 popover, 14px gutters, 11-13px type scale, + brand accent #C9521D used identically in both themes. */ + +:root { + --brand-accent: #C9521D; + --brand-accent-dark: #E8774A; + --ember-deep: #8B3E13; + --ember-glow: #F0A070; + + /* Light: warm popover material over the desktop. */ + --surface: rgba(250, 247, 243, 0.94); + --surface-solid: #FAF7F3; + --surface-window: #FFFFFF; + --label: rgba(0, 0, 0, 0.85); + --label-2: rgba(0, 0, 0, 0.50); + --label-3: rgba(0, 0, 0, 0.28); + --separator: rgba(0, 0, 0, 0.10); + --separator-soft: rgba(0, 0, 0, 0.05); + --fill-06: rgba(0, 0, 0, 0.06); + --fill-08: rgba(0, 0, 0, 0.08); + --fill-10: rgba(0, 0, 0, 0.10); + --fill-12: rgba(0, 0, 0, 0.12); + --fill-15: rgba(0, 0, 0, 0.15); + --fill-18: rgba(0, 0, 0, 0.18); + --fill-50: rgba(0, 0, 0, 0.45); + --tooltip-bg: #1C1816; + --tooltip-fg: rgba(255, 255, 255, 0.92); + --tooltip-fg-2: rgba(255, 255, 255, 0.72); + --tooltip-fg-3: rgba(255, 255, 255, 0.52); + --tooltip-border: rgba(255, 255, 255, 0.12); + --overlay-material: rgba(250, 247, 243, 0.55); + --control-bg: rgba(255, 255, 255, 0.85); + --control-border: rgba(0, 0, 0, 0.09); + --control-hover: rgba(0, 0, 0, 0.05); + --menu-bg: rgba(252, 250, 247, 0.98); + --menu-shadow: 0 8px 28px rgba(0, 0, 0, 0.18), 0 1px 3px rgba(0, 0, 0, 0.10); + --icon-contrast: #FFFFFF; + --danger: #C83F2C; + + --font-sans: 'Segoe UI Variable Text', 'Segoe UI', -apple-system, system-ui, sans-serif; + --font-display: 'Segoe UI Variable Display', 'Segoe UI', -apple-system, system-ui, sans-serif; + --font-mono: 'Cascadia Mono', 'Cascadia Code', Consolas, 'SF Mono', Menlo, monospace; + + --gutter: 14px; + --popover-radius: 10px; + --radius-bar: 2px; + --radius-util: 3px; + --radius-segment: 5px; + --radius-pill: 6px; + --radius-track: 7px; + --radius-card: 8px; + --scroll-height: 520px; + + --ease-ui: cubic-bezier(0.2, 0.7, 0.2, 1); +} + +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + --surface: rgba(28, 24, 22, 0.92); + --surface-solid: #1C1816; + --surface-window: #2A2320; + --label: rgba(255, 255, 255, 0.86); + --label-2: rgba(255, 255, 255, 0.55); + --label-3: rgba(255, 255, 255, 0.28); + --separator: rgba(255, 255, 255, 0.10); + --separator-soft: rgba(255, 255, 255, 0.05); + --fill-06: rgba(255, 255, 255, 0.06); + --fill-08: rgba(255, 255, 255, 0.08); + --fill-10: rgba(255, 255, 255, 0.10); + --fill-12: rgba(255, 255, 255, 0.12); + --fill-15: rgba(255, 255, 255, 0.15); + --fill-18: rgba(255, 255, 255, 0.18); + --fill-50: rgba(255, 255, 255, 0.45); + --tooltip-bg: #FAF7F3; + --tooltip-fg: rgba(0, 0, 0, 0.9); + --tooltip-fg-2: rgba(0, 0, 0, 0.7); + --tooltip-fg-3: rgba(0, 0, 0, 0.5); + --tooltip-border: rgba(0, 0, 0, 0.12); + --overlay-material: rgba(28, 24, 22, 0.55); + --control-bg: rgba(255, 255, 255, 0.08); + --control-border: rgba(255, 255, 255, 0.10); + --control-hover: rgba(255, 255, 255, 0.10); + --menu-bg: rgba(40, 35, 32, 0.98); + --menu-shadow: 0 8px 28px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.3); + --icon-contrast: #1C1816; + color-scheme: dark; + } +} + +:root[data-theme="dark"] { + --surface: rgba(28, 24, 22, 0.92); + --surface-solid: #1C1816; + --surface-window: #2A2320; + --label: rgba(255, 255, 255, 0.86); + --label-2: rgba(255, 255, 255, 0.55); + --label-3: rgba(255, 255, 255, 0.28); + --separator: rgba(255, 255, 255, 0.10); + --separator-soft: rgba(255, 255, 255, 0.05); + --fill-06: rgba(255, 255, 255, 0.06); + --fill-08: rgba(255, 255, 255, 0.08); + --fill-10: rgba(255, 255, 255, 0.10); + --fill-12: rgba(255, 255, 255, 0.12); + --fill-15: rgba(255, 255, 255, 0.15); + --fill-18: rgba(255, 255, 255, 0.18); + --fill-50: rgba(255, 255, 255, 0.45); + --tooltip-bg: #FAF7F3; + --tooltip-fg: rgba(0, 0, 0, 0.9); + --tooltip-fg-2: rgba(0, 0, 0, 0.7); + --tooltip-fg-3: rgba(0, 0, 0, 0.5); + --tooltip-border: rgba(0, 0, 0, 0.12); + --overlay-material: rgba(28, 24, 22, 0.55); + --control-bg: rgba(255, 255, 255, 0.08); + --control-border: rgba(255, 255, 255, 0.10); + --control-hover: rgba(255, 255, 255, 0.10); + --menu-bg: rgba(40, 35, 32, 0.98); + --menu-shadow: 0 8px 28px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.3); + --icon-contrast: #1C1816; + color-scheme: dark; +} + +* { box-sizing: border-box; } + +html, body, #root { + margin: 0; + padding: 0; + height: 100%; + background: transparent; + color: var(--label); + font-family: var(--font-sans); + font-size: 11.5px; + line-height: 1.3; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + overflow: hidden; + user-select: none; + cursor: default; +} + +button { + font: inherit; + color: inherit; + cursor: default; +} +button:focus-visible, a:focus-visible, summary:focus-visible { + outline: 2px solid var(--brand-accent); + outline-offset: 1px; + border-radius: 4px; +} +a { color: inherit; } +code { font-family: var(--font-mono); } + +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } +} + +/* ---- shell ---------------------------------------------------------------------- */ + +.popover { + display: flex; + flex-direction: column; + height: 100vh; + overflow: hidden; + border-radius: var(--popover-radius); + background: var(--surface); + box-shadow: inset 0 0 0 0.5px var(--separator); +} + +.header { + display: flex; + flex-direction: column; + gap: 1px; + padding: 10px var(--gutter) 8px; + border-bottom: 1px solid var(--separator); +} +.brand { font-size: 13px; font-weight: 600; letter-spacing: -0.15px; line-height: 16px; } +.brand-primary { color: var(--label); } +.brand-accent { color: var(--brand-accent); } +.subhead { font-size: 10.5px; color: var(--label-2); } + +.main-content { + position: relative; + flex: 1; + min-height: 0; + overflow-y: auto; + scrollbar-width: none; +} +.main-content::-webkit-scrollbar { display: none; } + +/* ---- agent tabs ---------------------------------------------------------------- */ + +.agent-tabs-wrap { + position: relative; + z-index: 40; + border-bottom: 1px solid var(--separator); +} +.agent-tabs { + display: flex; + gap: 5px; + padding: 8px 12px; + overflow-x: auto; + scrollbar-width: none; + mask-image: linear-gradient(90deg, #000 calc(100% - 18px), transparent); + -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 18px), transparent); +} +.agent-tabs::-webkit-scrollbar { display: none; } +.tab-muted, .tab-muted:hover { background: transparent; color: var(--label-3); box-shadow: inset 0 0 0 1px var(--fill-08); } +.tab-preview { + position: absolute; + left: 12px; + right: 12px; + top: calc(100% + 4px); + padding: 8px 10px; + border-radius: var(--radius-card); + background: var(--tooltip-bg); + color: var(--tooltip-fg); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), inset 0 0 0 0.5px var(--tooltip-border); + pointer-events: none; + animation: fadeIn 120ms ease-out; +} +.tab-preview-title { font-size: 11px; font-weight: 600; } +.tab-preview-body { margin-top: 2px; font-size: 10px; color: var(--tooltip-fg-2); font-variant-numeric: tabular-nums; } +.tab { + display: inline-flex; + align-items: baseline; + gap: 5px; + flex: 0 0 auto; + border: 0; + padding: 4px 10px; + border-radius: var(--radius-pill); + background: var(--fill-08); + color: var(--label-2); + font-size: 11.5px; + font-weight: 500; + letter-spacing: -0.05px; + line-height: 14px; + transition: background 120ms var(--ease-ui), color 120ms var(--ease-ui); +} +.tab:hover { background: var(--fill-12); } +.tab-active, .tab-active:hover { background: var(--brand-accent); color: #fff; } +.tab-cost { + font-family: var(--font-mono); + font-size: 10.5px; + font-weight: 500; + letter-spacing: -0.2px; + color: var(--label-2); +} +.tab-active .tab-cost { color: rgba(255, 255, 255, 0.8); } + +/* ---- hero ------------------------------------------------------------------------ */ + +.hero { + display: flex; + flex-direction: column; + gap: 8px; + padding: 10px var(--gutter) 12px; + border-bottom: 1px solid var(--separator-soft); +} +.hero-row { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 12px; +} +.hero-amount { + font-family: var(--font-display); + font-size: 32px; + font-weight: 600; + line-height: 36px; + letter-spacing: -1px; + font-variant-numeric: tabular-nums; + background: linear-gradient(180deg, var(--brand-accent), var(--ember-deep)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} +.hero-meta { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 2px; + font-variant-numeric: tabular-nums; +} +.hero-calls { font-size: 11px; color: var(--label-2); } +.hero-sessions { font-size: 10.5px; color: var(--label-3); } + +.hero-skeleton, .hero-skeleton-line { + display: block; + border-radius: 4px; + background: linear-gradient(90deg, var(--fill-06) 25%, var(--fill-12) 50%, var(--fill-06) 75%); + background-size: 200% 100%; + animation: shimmer 1.4s linear infinite; +} +.hero-skeleton { width: 128px; height: 30px; margin: 3px 0; -webkit-background-clip: border-box; background-clip: border-box; color: transparent; } +.hero-skeleton-line { width: 54px; height: 10px; } +.hero-skeleton-line.short { width: 64px; } +@keyframes shimmer { to { background-position: -200% 0; } } + +/* ---- section caption ----------------------------------------------------------- */ + +.section-caption { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 11.5px; + font-weight: 500; + letter-spacing: -0.1px; + color: var(--label-2); +} +.section-caption-strong { color: var(--label); } +.section-dot { + width: 3px; + height: 3px; + border-radius: 50%; + background: var(--brand-accent); + opacity: 0.7; + flex-shrink: 0; +} + +/* ---- period segmented control -------------------------------------------------- */ + +.period-wrap { + padding: 6px 12px 10px; + border-bottom: 1px solid var(--separator-soft); +} +.period-tabs { + display: flex; + gap: 1px; + padding: 2px; + border-radius: var(--radius-track); + background: var(--fill-08); +} +.period { + flex: 1; + border: 0; + background: transparent; + padding: 4px 0; + border-radius: var(--radius-segment); + font-size: 11px; + font-weight: 500; + line-height: 14px; + color: var(--label-2); + transition: background 120ms var(--ease-ui), color 120ms var(--ease-ui), box-shadow 120ms var(--ease-ui); +} +.period:hover { color: var(--label); } +.period-active, .period-active:hover { + background: var(--surface-window); + color: var(--label); + box-shadow: 0 0.5px 2px rgba(0, 0, 0, 0.10); +} + +/* ---- insight area -------------------------------------------------------------- */ + +.insight-area { + display: flex; + flex-direction: column; + gap: 10px; + padding: 10px var(--gutter); + border-bottom: 1px solid var(--separator-soft); + position: relative; + z-index: 10; +} +.insight-pills { display: flex; gap: 4px; } +.insight-pill { + border: 0; + padding: 4px 10px; + border-radius: var(--radius-pill); + background: var(--fill-10); + color: var(--label-2); + font-size: 11px; + font-weight: 500; + line-height: 14px; + transition: background 120ms var(--ease-ui), color 120ms var(--ease-ui); +} +.insight-pill:hover { background: var(--fill-15); } +.insight-pill-active, .insight-pill-active:hover { background: var(--brand-accent); color: #fff; } + +.insight-header { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 10px; +} +.insight-sublabel { font-size: 10px; font-weight: 500; color: var(--label-3); } +.insight-hero { + margin-top: 1px; + font-family: var(--font-display); + font-size: 18px; + font-weight: 600; + line-height: 22px; + font-variant-numeric: tabular-nums; + color: var(--label); +} +.delta-badge { + display: inline-flex; + align-items: center; + gap: 3px; + font-size: 10.5px; + font-variant-numeric: tabular-nums; + color: var(--brand-accent); + white-space: nowrap; +} +.delta-badge-block { margin-top: 0; } + +/* Trend */ +.trend-insight, .forecast-insight, .stats-insight, .plan-insight { + display: flex; + flex-direction: column; + gap: 10px; +} +.trend-chart { position: relative; height: 90px; } +.trend-bars { + display: flex; + align-items: flex-end; + gap: 4px; + height: 100%; +} +.trend-bar-col { + display: flex; + flex-direction: column; + justify-content: flex-end; + width: 13px; + height: 100%; +} +.trend-bar { + width: 100%; + min-height: 2px; + border-radius: var(--radius-bar); + background: var(--brand-accent); + opacity: 0.55; + transform-origin: bottom center; + transition: transform 120ms ease-out, opacity 120ms ease-out, box-shadow 120ms ease-out; +} +.trend-bar-today { opacity: 1; } +.trend-bar-empty { background: var(--label); opacity: 0.15; } +.trend-bar-hovered { + opacity: 0.85; + transform: scaleX(1.08); + box-shadow: inset 0 0 0 1px rgba(201, 82, 29, 0.9); +} +.trend-bar-today.trend-bar-hovered { opacity: 1; } +.trend-avg-line { + position: absolute; + left: 0; + right: 0; + border-top: 1px dashed var(--fill-50); + pointer-events: none; +} + +.bar-tooltip { + position: absolute; + left: 0; + right: 0; + top: calc(100% + 6px); + z-index: 20; + padding: 11px; + border-radius: var(--radius-card); + background: var(--tooltip-bg); + color: var(--tooltip-fg); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), inset 0 0 0 0.5px var(--tooltip-border); + pointer-events: none; + animation: fadeIn 120ms ease-out; +} +.bar-tooltip-header { + display: flex; + justify-content: space-between; + align-items: baseline; + font-size: 11px; + font-weight: 600; + margin-bottom: 5px; +} +.bar-tooltip-value { color: var(--brand-accent-dark); font-family: var(--font-mono); font-size: 10.5px; font-weight: 600; } +.bar-tooltip-model { + display: flex; + align-items: center; + gap: 6px; + padding: 1.5px 0; + font-size: 10px; + font-weight: 500; +} +.bar-tooltip-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--brand-accent); opacity: 0.7; flex-shrink: 0; } +.bar-tooltip-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.bar-tooltip-tokens { font-family: var(--font-mono); font-size: 9.5px; color: var(--tooltip-fg-2); } +.bar-tooltip-split { font-family: var(--font-mono); font-size: 9px; color: var(--tooltip-fg-3); } + +.mini-stats { display: flex; gap: 14px; } +.mini-stat { flex: 1; min-width: 0; } +.mini-stat-label { font-size: 9.5px; font-weight: 500; color: var(--label-3); } +.mini-stat-value { + margin-top: 1px; + font-size: 11.5px; + font-weight: 600; + font-variant-numeric: tabular-nums; + color: var(--label); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Forecast */ +.forecast-mtd { + margin-top: 2px; + font-family: var(--font-display); + font-size: 22px; + font-weight: 600; + line-height: 26px; + font-variant-numeric: tabular-nums; + color: var(--brand-accent); +} +.forecast-right { text-align: right; } +.forecast-projection { + margin-top: 2px; + font-size: 16px; + font-weight: 600; + line-height: 20px; + font-variant-numeric: tabular-nums; + color: var(--label); +} + +/* Pulse */ +.pulse-tiles { display: flex; gap: 10px; } +.pulse-tile { + flex: 1; + min-width: 0; + padding: 8px 10px; + border-radius: var(--radius-pill); + background: var(--fill-06); +} +.pulse-label { font-size: 10px; font-weight: 500; color: var(--label-3); } +.pulse-value { + margin-top: 3px; + font-family: var(--font-display); + font-size: 18px; + font-weight: 600; + line-height: 22px; + font-variant-numeric: tabular-nums; + color: var(--label-2); +} +.pulse-value-accent { color: var(--brand-accent); } + +/* Stats */ +.stats-grid { display: flex; gap: 14px; } +.stats-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; } +.stat-row-label { font-size: 9.5px; font-weight: 500; color: var(--label-3); } +.stat-row-value { + margin-top: 1px; + font-size: 12px; + font-weight: 600; + font-variant-numeric: tabular-nums; + color: var(--label); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.stats-lifetime { + display: flex; + justify-content: space-between; + align-items: baseline; + padding-top: 10px; + border-top: 1px solid var(--separator-soft); +} +.stats-lifetime-label { font-size: 10.5px; font-weight: 500; color: var(--label-3); } +.stats-lifetime-value { + font-family: var(--font-display); + font-size: 13px; + font-weight: 600; + font-variant-numeric: tabular-nums; + color: var(--brand-accent); +} + +/* Plan */ +.plan-header { display: flex; align-items: baseline; justify-content: space-between; } +.plan-tier { font-size: 13px; font-weight: 600; color: var(--brand-accent); } +.plan-reset { font-size: 10.5px; color: var(--label-2); } +.plan-rows { display: flex; flex-direction: column; gap: 8px; } +.util-row { display: flex; flex-direction: column; gap: 3px; } +.util-row-head { display: flex; align-items: baseline; justify-content: space-between; } +.util-label { font-size: 11px; font-weight: 500; color: var(--label-2); } +.util-percent { + font-family: var(--font-mono); + font-size: 11px; + font-weight: 600; + font-variant-numeric: tabular-nums; + color: var(--brand-accent); +} +.util-bar { + position: relative; + height: 6px; + border-radius: var(--radius-util); + background: var(--fill-12); + overflow: hidden; +} +.util-bar-fill { + height: 100%; + border-radius: var(--radius-util); + background: var(--brand-accent); + transition: width 400ms var(--ease-ui); +} +.util-bar-marker { + position: absolute; + top: 0; + bottom: 0; + width: 1.5px; + background: var(--label); + opacity: 0.55; +} +.util-caption { + display: flex; + align-items: center; + gap: 3px; + font-size: 9.5px; + font-weight: 500; + color: var(--label-3); +} +.util-caption-warn { color: var(--brand-accent); } +.savings-badge { + display: flex; + align-items: center; + gap: 6px; + width: 100%; + margin-top: 2px; + padding: 7px 10px; + border: 0; + border-radius: var(--radius-pill); + background: rgba(201, 82, 29, 0.10); + color: var(--label); + font-size: 11px; + font-weight: 500; + text-align: left; + transition: background 120ms var(--ease-ui); +} +.savings-badge:hover { background: rgba(201, 82, 29, 0.16); } +.savings-badge-icon { color: var(--brand-accent); flex-shrink: 0; } +.savings-badge span { flex: 1; } +.savings-badge-chevron { color: var(--label-3); } + +.plan-state { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 14px 8px; + text-align: center; +} +.plan-state-icon { color: var(--label-3); } +.plan-state-icon-accent { color: var(--brand-accent); } +.plan-state-title { font-size: 12px; font-weight: 600; color: var(--label); } +.plan-state-title-muted { font-size: 11.5px; font-weight: 500; color: var(--label-2); } +.plan-state-note { max-width: 260px; font-size: 10.5px; color: var(--label-2); } +.plan-state-error { + max-width: 280px; + font-size: 10px; + color: var(--label-3); + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} +.plan-actions { display: flex; gap: 8px; margin-top: 2px; } + +/* ---- collapsible sections (Activity / Models) ---------------------------------- */ + +.collapsible { + display: flex; + flex-direction: column; + gap: 7px; + padding: 11px var(--gutter); + border-bottom: 1px solid var(--separator-soft); +} +.collapsible-header { + display: flex; + align-items: center; + gap: 8px; + width: 100%; + border: 0; + padding: 0; + background: transparent; + color: var(--label-2); + text-align: left; +} +.collapsible-spacer { flex: 1; } +.col-header { + font-size: 10px; + font-weight: 500; + letter-spacing: -0.05px; + color: var(--label-3); + text-align: right; +} +.chevron { + color: var(--label-2); + opacity: 0.55; + transition: transform 180ms ease-in-out; + flex-shrink: 0; + margin-left: 2px; +} +.chevron-open { transform: rotate(90deg); } +.collapsible-body { + display: flex; + flex-direction: column; + gap: 7px; + animation: fadeIn 180ms ease-in-out; +} + +.data-row { + display: flex; + align-items: center; + gap: 8px; + padding: 1px 2px; + font-variant-numeric: tabular-nums; +} +.fixed-bar { + position: relative; + display: block; + width: 56px; + height: 6px; + flex-shrink: 0; + border-radius: var(--radius-bar); + background: var(--fill-15); + overflow: hidden; +} +.fixed-bar-fill { display: block; height: 100%; border-radius: var(--radius-bar); background: var(--brand-accent); } +.row-name { + flex: 1; + min-width: 0; + font-size: 12.5px; + font-weight: 500; + color: var(--label); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.row-cost { + font-family: var(--font-mono); + font-size: 12px; + font-weight: 500; + letter-spacing: -0.2px; + text-align: right; + color: var(--label); +} +.row-count { font-size: 11px; text-align: right; color: var(--label-2); } +.row-oneshot { font-size: 10.5px; text-align: right; color: var(--label-2); } + +.tokens-line { + display: flex; + align-items: baseline; + gap: 4px; + padding-top: 5px; + font-size: 10.5px; + font-variant-numeric: tabular-nums; +} +.tokens-label { color: var(--label-3); } +.tokens-value { color: var(--label-2); } +.tokens-sep { color: var(--label-3); } + +/* ---- tips card ------------------------------------------------------------------ */ + +.findings-wrap { padding: 8px var(--gutter); } +.findings-card { + display: flex; + flex-direction: column; + gap: 8px; + padding: 12px; + border-radius: var(--radius-card); + background: var(--fill-06); +} +.findings-header { + display: flex; + align-items: baseline; + justify-content: space-between; + width: 100%; + border: 0; + padding: 0; + background: transparent; + color: var(--label); + text-align: left; +} +.findings-header-left { display: inline-flex; align-items: center; gap: 6px; } +.findings-icon { color: var(--brand-accent); } +.findings-title { font-size: 12.5px; font-weight: 600; } +.findings-header-right { display: inline-flex; align-items: center; gap: 6px; color: var(--label-2); } +.findings-count { font-size: 10.5px; } +.findings-body { display: flex; flex-direction: column; gap: 10px; animation: fadeIn 180ms ease-in-out; } +.tips-group { display: flex; flex-direction: column; gap: 5px; } +.tips-group-header { + display: flex; + align-items: center; + gap: 5px; + font-size: 10.5px; + font-weight: 600; + letter-spacing: 0.4px; + text-transform: uppercase; + color: var(--brand-accent); +} +.tips-item { + display: flex; + align-items: baseline; + gap: 6px; + padding: 0; + font-size: 11.5px; + color: var(--label); +} +.tips-bullet { + width: 3px; + height: 3px; + border-radius: 50%; + background: var(--brand-accent); + flex-shrink: 0; + transform: translateY(-2px); +} +.tips-text { flex: 1; min-width: 0; } +.tips-trailing { + font-family: var(--font-mono); + font-size: 11px; + font-weight: 500; + letter-spacing: -0.2px; + color: var(--label-2); +} +.findings-open-optimize { + display: inline-flex; + align-items: center; + gap: 4px; + align-self: flex-start; + border: 0; + padding: 0; + background: transparent; + color: var(--brand-accent); + font-size: 11.5px; + font-weight: 600; +} +.findings-open-optimize:hover { text-decoration: underline; } + +/* ---- empty / no data / setup ------------------------------------------------- */ + +.empty-provider { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + padding: 60px 0; +} +.empty-provider-icon { color: var(--label-3); } +.empty-provider-text { font-size: 12px; font-weight: 500; color: var(--label-2); text-align: center; } + +.no-data { + padding: 10px var(--gutter) 14px; + color: var(--label-2); + font-size: 11.5px; + line-height: 1.5; +} +.no-data-title { margin: 0 0 6px; font-size: 12.5px; font-weight: 600; color: var(--label); } +.no-data p { margin: 0 0 8px; } +.no-data-sub { font-weight: 600; color: var(--label); margin-bottom: 4px; } +.no-data ul { margin: 0 0 10px; padding-left: 16px; } +.no-data li { margin-bottom: 3px; } +.no-data code { + font-size: 10.5px; + padding: 1px 4px; + border-radius: 3px; + background: var(--fill-06); + color: var(--label); + user-select: text; +} +.no-data-tool { color: var(--label-3); } + +.setup { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + padding: 36px 24px; + text-align: center; +} +.setup-title { margin: 4px 0 0; font-size: 14px; font-weight: 600; color: var(--label); } +.setup-copy { margin: 0; max-width: 280px; font-size: 11.5px; line-height: 1.5; color: var(--label-2); } +.setup-copy-muted { color: var(--label-3); font-size: 10.5px; } +.setup-command { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 6px 6px 12px; + border-radius: var(--radius-card); + background: var(--fill-06); +} +.setup-command code { font-size: 12px; color: var(--label); user-select: text; } +.setup-actions { display: flex; gap: 8px; margin-top: 4px; } +.setup-details { font-size: 10.5px; color: var(--label-2); max-width: 300px; } +.setup-details summary { display: inline-flex; align-items: center; gap: 4px; list-style: none; color: var(--label-3); } +.setup-details summary::-webkit-details-marker { display: none; } +.setup-error { margin-top: 6px; text-align: left; font-family: var(--font-mono); font-size: 10px; word-break: break-word; user-select: text; } +.setup-error-muted { margin-top: 4px; text-align: left; font-size: 10px; color: var(--label-3); word-break: break-all; } + +/* ---- settings ------------------------------------------------------------------- */ + +.settings { display: flex; flex-direction: column; padding: 8px 0 14px; } +.settings-head { + display: flex; + align-items: center; + gap: 8px; + padding: 2px var(--gutter) 10px; +} +.settings-title { font-size: 13px; font-weight: 600; color: var(--label); } +.settings-group { + display: flex; + flex-direction: column; + padding: 8px var(--gutter) 6px; + border-top: 1px solid var(--separator-soft); +} +.settings-group-label { + font-size: 10px; + font-weight: 600; + letter-spacing: 0.4px; + text-transform: uppercase; + color: var(--label-3); + margin-bottom: 4px; +} +.settings-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 7px 0; +} +.settings-row-text { flex: 1; min-width: 0; } +.settings-row-label { font-size: 12px; font-weight: 500; color: var(--label); } +.settings-row-hint { margin-top: 1px; font-size: 10.5px; line-height: 1.35; color: var(--label-2); word-break: break-word; } +.settings-row-control { flex-shrink: 0; display: flex; align-items: center; } +.settings-error { font-size: 10.5px; color: var(--danger); padding-bottom: 6px; } +.settings a.btn { text-decoration: none; } + +.toggle { + position: relative; + width: 34px; + height: 20px; + padding: 0; + border: 0; + border-radius: 10px; + background: var(--fill-18); + transition: background 160ms var(--ease-ui); +} +.toggle:disabled { opacity: 0.5; } +.toggle-on { background: var(--brand-accent); } +.toggle-knob { + position: absolute; + top: 2px; + left: 2px; + width: 16px; + height: 16px; + border-radius: 50%; + background: #fff; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); + transition: transform 160ms var(--ease-ui); +} +.toggle-on .toggle-knob { transform: translateX(14px); } + +.segmented { + display: flex; + gap: 1px; + padding: 2px; + border-radius: var(--radius-track); + background: var(--fill-08); +} +.segment { + border: 0; + background: transparent; + padding: 3px 9px; + border-radius: var(--radius-segment); + font-size: 11px; + font-weight: 500; + color: var(--label-2); +} +.segment-active { background: var(--surface-window); color: var(--label); box-shadow: 0 0.5px 2px rgba(0, 0, 0, 0.10); } + +/* ---- loading overlay ---------------------------------------------------------- */ + +.loading-overlay { + position: absolute; + inset: 0; + z-index: 30; + display: flex; + align-items: center; + justify-content: center; + background: var(--overlay-material); + backdrop-filter: blur(18px) saturate(160%); + -webkit-backdrop-filter: blur(18px) saturate(160%); + animation: fadeIn 200ms ease-in-out; +} +.loading-content { display: flex; flex-direction: column; align-items: center; gap: 14px; } +.loading-text { font-size: 11.5px; font-weight: 500; color: var(--label-2); } + +.burn-flame { position: relative; } +.burn-flame svg { position: absolute; inset: 0; } +.burn-flame-glow path { fill: var(--ember-glow); } +.burn-flame-glow { animation: burnGlow 0.9s ease-in-out infinite alternate; } +.burn-flame-outline path { fill: none; stroke: var(--brand-accent); stroke-width: 0.9; opacity: 0.25; } +.burn-clip-rect { animation: burnFill 1.4s ease-in-out infinite alternate; } +@keyframes burnGlow { + from { opacity: 0.20; filter: blur(6px); } + to { opacity: 0.55; filter: blur(14px); } +} +@keyframes burnFill { + from { y: 16px; height: 0px; } + to { y: 0px; height: 16px; } +} +@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } + +/* ---- footer ---------------------------------------------------------------------- */ + +.footer { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 12px; + border-top: 1px solid var(--separator); +} +.footer-spacer { flex: 1; } + +.btn { + display: inline-flex; + align-items: center; + gap: 5px; + height: 24px; + padding: 0 9px; + border: 1px solid var(--control-border); + border-radius: 6px; + background: var(--control-bg); + color: var(--label); + font-size: 11px; + font-weight: 500; + line-height: 1; + white-space: nowrap; + box-shadow: 0 0.5px 1px rgba(0, 0, 0, 0.06); + transition: background 120ms var(--ease-ui), border-color 120ms var(--ease-ui); +} +.btn:hover:not(:disabled) { background: var(--control-hover); } +.btn:disabled { opacity: 0.55; } +.btn-pressed { background: var(--control-hover); } +.btn-icon { padding: 0 6px; } +.btn-spinning svg { animation: spin 0.9s linear infinite; } +@keyframes spin { to { transform: rotate(360deg); } } +.btn-prominent, .btn-prominent:hover:not(:disabled) { + background: var(--brand-accent); + border-color: transparent; + color: #fff; + font-weight: 600; +} +.btn-prominent:hover:not(:disabled) { background: #B84A1A; } +.btn-prominent:active { background: var(--ember-deep); } + +.dropmenu { position: relative; } +.dropmenu-panel { + position: absolute; + bottom: calc(100% + 6px); + min-width: 132px; + max-height: 300px; + overflow-y: auto; + scrollbar-width: none; + padding: 4px; + border-radius: 8px; + background: var(--menu-bg); + box-shadow: var(--menu-shadow), inset 0 0 0 0.5px var(--separator); + z-index: 100; + animation: menuIn 120ms var(--ease-ui); +} +.dropmenu-panel::-webkit-scrollbar { display: none; } +.dropmenu-grid { display: grid; gap: 1px 2px; min-width: 204px; } +.dropmenu-grid .dropmenu-item { padding-right: 6px; } +.dropmenu-item-wrap { min-width: 0; } +.dropmenu-left { left: 0; } +.dropmenu-right { right: 0; } +@keyframes menuIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } } +.dropmenu-item { + display: flex; + align-items: center; + gap: 4px; + width: 100%; + height: 24px; + padding: 0 8px 0 4px; + border: 0; + border-radius: 5px; + background: transparent; + color: var(--label); + font-size: 11.5px; + text-align: left; +} +.dropmenu-item:hover:not(:disabled) { background: var(--brand-accent); color: #fff; } +.dropmenu-item:disabled { color: var(--label-3); } +.dropmenu-check { display: inline-flex; width: 14px; justify-content: center; flex-shrink: 0; } +.dropmenu-label { flex: 1; white-space: nowrap; } +.dropmenu-sep { height: 1px; margin: 4px 6px; background: var(--separator); } +.dropmenu-footnote { + padding: 6px 8px 3px; + font-size: 10px; + color: var(--label-3); + white-space: nowrap; + border-top: 1px solid var(--separator-soft); + margin-top: 4px; +} +.dropmenu-more .btn { padding: 0 6px; } + +/* ---- star banner --------------------------------------------------------------- */ + +.star-banner { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px; + background: rgba(201, 82, 29, 0.08); + box-shadow: inset 0 0.5px 0 var(--fill-18); +} +.star-banner-icon { color: var(--brand-accent); flex-shrink: 0; } +.star-banner-link { font-size: 10.5px; font-weight: 500; color: var(--label); text-decoration: none; } +.star-banner-cta { color: var(--brand-accent); text-decoration: underline; } +.star-banner-spacer { flex: 1; } +.star-banner-close { + display: inline-flex; + padding: 4px; + border: 0; + border-radius: 4px; + background: transparent; + color: var(--label-2); +} +.star-banner-close:hover { background: var(--fill-08); } + +/* ---- error toast --------------------------------------------------------------- */ + +.error-toast { + position: absolute; + left: 12px; + right: 12px; + bottom: 74px; + z-index: 200; + display: flex; + align-items: flex-start; + gap: 8px; + padding: 8px 8px 8px 10px; + border-radius: 8px; + background: var(--tooltip-bg); + color: var(--tooltip-fg); + font-size: 11px; + line-height: 1.4; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), inset 0 0 0 0.5px var(--tooltip-border); + animation: menuIn 160ms var(--ease-ui); +} +.error-toast-text { flex: 1; word-break: break-word; user-select: text; } +.error-toast-close { + display: inline-flex; + padding: 3px; + border: 0; + border-radius: 4px; + background: transparent; + color: var(--tooltip-fg-2); +} +.error-toast-close:hover { background: rgba(127, 127, 127, 0.2); } diff --git a/windows/tokens.json b/windows/tokens.json new file mode 100644 index 00000000..2d07b130 --- /dev/null +++ b/windows/tokens.json @@ -0,0 +1,75 @@ +{ + "version": 1, + "_comment": "Canonical design tokens for CodeBurn. The Swift mac/ app reads this at build time to populate Theme.swift; the windows/ Tauri frontend imports it as CSS custom properties. Side-by-side screenshots on macOS and Linux should read as the same product.", + "color": { + "brand": { + "accent": "#C9521D", + "accentDark": "#E8774A", + "emberDeep": "#8B3E13", + "emberGlow": "#F0A070", + "bright": "#FF7A2A" + }, + "surface": { + "light": "#FAF7F3", + "dark": "#1C1816", + "elevated": "#FFFFFF", + "elevatedDark": "#2A2320" + }, + "text": { + "primary": "#1C1816", + "primaryDark": "#FAF7F3", + "secondary": "#6E5D53", + "secondaryDark": "#B5A49A", + "tertiary": "#A0897D", + "tertiaryDark": "#8A7A70" + }, + "categorical": { + "claude": "#C9521D", + "cursor": "#4A7D5C", + "codex": "#5C7CA3", + "pi": "#8B5A9C", + "copilot":"#B8944C" + } + }, + "type": { + "family": { + "sans": "Inter, 'Segoe UI Variable', 'SF Pro Text', system-ui, sans-serif", + "mono": "'JetBrains Mono', 'SF Mono', 'Cascadia Code', Menlo, monospace", + "rounded": "'SF Pro Rounded', Inter, system-ui, sans-serif" + }, + "scale": { + "hint": 9.5, + "caption": 10.5, + "body": 11.5, + "label": 12.5, + "heading": 16, + "hero": 32 + }, + "weight": { + "regular": 400, + "medium": 500, + "semibold": 600 + } + }, + "spacing": { + "xs": 2, + "sm": 6, + "md": 10, + "lg": 14, + "xl": 20 + }, + "radius": { + "sm": 3, + "md": 6, + "lg": 8, + "pill": 999 + }, + "layout": { + "popoverWidth": 360, + "popoverHeight": 660, + "activityBarWidth": 56, + "trendBarWidth": 13, + "trendBarGap": 4, + "trendChartHeight": 90 + } +} diff --git a/windows/tsconfig.json b/windows/tsconfig.json new file mode 100644 index 00000000..f09bae3e --- /dev/null +++ b/windows/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true + }, + "include": ["src"], + "exclude": ["node_modules", "dist", "src-tauri"] +} diff --git a/windows/vite.config.ts b/windows/vite.config.ts new file mode 100644 index 00000000..ecb12221 --- /dev/null +++ b/windows/vite.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// Tauri expects a fixed dev-server port so the Rust webview can connect reliably. The +// `@tauri-apps/plugin-*` runtime expects these HMR + strictPort settings to mirror what +// `tauri dev` spawns; tweaking them breaks the IPC bridge on first boot. +const TAURI_DEV_PORT = 1420 + +export default defineConfig(async () => ({ + plugins: [react()], + clearScreen: false, + server: { + port: TAURI_DEV_PORT, + strictPort: true, + host: process.env.TAURI_DEV_HOST || false, + hmr: process.env.TAURI_DEV_HOST + ? { protocol: 'ws', host: process.env.TAURI_DEV_HOST, port: 1421 } + : undefined, + watch: { + ignored: ['**/src-tauri/**'], + }, + }, + envPrefix: ['VITE_', 'TAURI_ENV_*'], + build: { + target: process.env.TAURI_ENV_PLATFORM === 'windows' ? 'chrome105' : 'safari13', + minify: !process.env.TAURI_ENV_DEBUG ? 'esbuild' : false, + sourcemap: !!process.env.TAURI_ENV_DEBUG, + }, +}))