From 002d974fb20f3d7973077131e27f4964d690f6bc Mon Sep 17 00:00:00 2001 From: jimmy-guzman Date: Fri, 21 Aug 2026 15:42:26 -0500 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E2=9C=A8=20in-app=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds tauri-plugin-updater and tauri-plugin-process. The app checks once on launch and offers an install through a toast; the palette gains 'check for updates...', which unlike the launch check reports when there is nothing to install. The launch check is silent on failure, because a network blip during startup is the wrong moment to interrupt someone. src/lib/updater.ts holds the two functions, split so one answers whether an update exists and one installs it. It lives in src/lib rather than src/data because an update check is app lifecycle, not note IO, and ARCHITECTURE.md puts that in UI code. The check is PROD-guarded: the endpoint does not answer in development. tauri.conf.json gains createUpdaterArtifacts and the plugins.updater block, and the build job gains TAURI_SIGNING_PRIVATE_KEY. That also makes max-parallel: 1 load-bearing for the first time, since latest.json now exists to race over. The cask gets auto_updates true back and the README says notras updates itself again; both were removed in #95 precisely because they were not true yet. src/lib/updater.spec.ts asserts the shipped pubkey is a real minisign key. tauri build does not validate it (the plugin parses it at runtime), so without this a placeholder would ship and only fail in an installed app. It fails right now by design: the key is not in yet. Carries an unrelated dependency upgrade that was already in the working tree from pnpm deps:up; pnpm add regenerated the lockfile on top of it and the two cannot be separated without discarding it. --- .github/workflows/release.yml | 19 +- .gitignore | 4 + README.md | 2 +- SPEC.md | 7 +- package.json | 44 +- pnpm-lock.yaml | 993 +++++++++++++++++----------- scripts/notras.rb.tmpl | 2 + src-tauri/Cargo.lock | 387 ++++++++++- src-tauri/Cargo.toml | 2 + src-tauri/capabilities/default.json | 4 +- src-tauri/src/lib.rs | 11 +- src-tauri/tauri.conf.json | 12 + src/components/command-palette.tsx | 34 + src/lib/updater.spec.ts | 33 + src/lib/updater.ts | 28 + src/routes/__root.tsx | 29 + 16 files changed, 1182 insertions(+), 429 deletions(-) create mode 100644 src/lib/updater.spec.ts create mode 100644 src/lib/updater.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6b4ee3eb..c4f86de1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -123,14 +123,12 @@ jobs: contents: write strategy: fail-fast: false - # Guards the updater artifacts, not today's build. tauri-action builds - # latest.json by fetching the existing asset off the release, merging its - # platforms map and re-uploading; concurrent legs race that - # delete-then-upload and 404 (tauri-action#1270), and upstream's fix is a - # random 1-10s retry its own src/utils.ts calls provisional. - # upload-version-json.ts returns early with no .sig files, so the race - # cannot fire until `createUpdaterArtifacts` lands, and no release is cut - # before then. Goes if the updater ever does. + # tauri-action builds latest.json by fetching the existing asset off the + # release, merging its platforms map and re-uploading. Concurrent legs + # race that delete-then-upload and 404 (tauri-action#1270), and + # upstream's fix is a random 1-10s retry its own src/utils.ts calls + # provisional. Now that `createUpdaterArtifacts` emits .sig files the + # race is live, so serialize. Goes if the updater ever does. max-parallel: 1 matrix: include: @@ -226,6 +224,11 @@ jobs: uses: tauri-apps/tauri-action@1deb371b0cd8bd54025b384f1cd735e725c4060f # v1.0.0 env: GITHUB_TOKEN: ${{ github.token }} + # Signs the updater artifacts. Unrelated to Apple signing, and not + # optional: without it `createUpdaterArtifacts` emits no .sig files + # and the published latest.json would be unverifiable. + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} with: releaseId: ${{ steps.release.outputs.id }} args: ${{ matrix.args }} diff --git a/.gitignore b/.gitignore index e8d65c54..81cad479 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,10 @@ .DS_Store *.pem +# tauri updater signing keys +*.key +*.key.pub + # debug npm-debug.log* yarn-debug.log* diff --git a/README.md b/README.md index d3112e03..921545ee 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ brew install --cask jimmy-guzman/tap/notras The cask is published by the release pipeline, so it appears with the first release. -Upgrade with `brew upgrade --cask notras`. Or download a `.dmg`, `.AppImage`, +notras updates itself. Or download a `.dmg`, `.AppImage`, `.deb` or `.msi` from [releases](https://github.com/jimmy-guzman/notras/releases), alongside that release's `SHA256SUMS.txt`, and check what you got: diff --git a/SPEC.md b/SPEC.md index 398812fc..4d4be20d 100644 --- a/SPEC.md +++ b/SPEC.md @@ -31,6 +31,10 @@ walkthrough is their only coverage. Run it under `pnpm dev`. - [x] 13. `pnpm tauri build` → built artifact launches; "Open With" on a random `.md` works - [x] 14. Type, then quit from the tray and again with ⌘Q → relaunch and the last keystrokes are on disk +- [ ] 15. Install the first release carrying the updater, cut a second, relaunch + the installed copy → "version x.y.z is available" toast → install → + relaunches into the new version. ⌘K → "check for updates..." reports + either way. `pnpm dev` cannot cover this: the check is `PROD`-guarded. ## Deferred @@ -39,9 +43,6 @@ walkthrough is their only coverage. Run it under `pnpm dev`. - Backlinks panel (wikilinks are one-directional today) - Git integration UI (the folder is git-init-able by hand today) - wdio + tauri-driver e2e (replaces the deleted Playwright smoke tests) -- In-app auto-update (`tauri-plugin-updater`; the release pipeline ships without - it, and turning it on needs a signing key, two releases to verify, and - `auto_updates true` restored to the cask so brew stops upgrading it) - SHA-pinning the three actions in `.github/actions/install` (`release.yml` pins everything it names, but the composite action both privileged jobs call resolves `setup-node`, `action-setup` and `cache` by mutable major tag, and diff --git a/package.json b/package.json index 2a072b41..6d7449f5 100644 --- a/package.json +++ b/package.json @@ -25,25 +25,27 @@ "@base-ui/react": "1.7.0", "@fontsource-variable/literata": "5.3.0", "@fontsource/ia-writer-mono": "5.3.0", - "@tanstack/react-router": "1.170.29", + "@tanstack/react-router": "1.170.30", "@tauri-apps/api": "2.11.1", "@tauri-apps/plugin-autostart": "2.5.1", "@tauri-apps/plugin-dialog": "2.7.2", "@tauri-apps/plugin-opener": "2.5.4", - "@tiptap/core": "3.30.1", - "@tiptap/extension-code-block-lowlight": "3.30.1", - "@tiptap/extension-document": "3.30.1", - "@tiptap/extension-image": "3.30.1", - "@tiptap/extension-table": "3.30.1", - "@tiptap/extension-task-item": "3.30.1", - "@tiptap/extension-task-list": "3.30.1", - "@tiptap/extension-text": "3.30.1", - "@tiptap/extensions": "3.30.1", - "@tiptap/markdown": "3.30.1", - "@tiptap/pm": "3.30.1", - "@tiptap/react": "3.30.1", - "@tiptap/starter-kit": "3.30.1", - "@tiptap/suggestion": "3.30.1", + "@tauri-apps/plugin-process": "2.3.1", + "@tauri-apps/plugin-updater": "2.10.1", + "@tiptap/core": "3.30.2", + "@tiptap/extension-code-block-lowlight": "3.30.2", + "@tiptap/extension-document": "3.30.2", + "@tiptap/extension-image": "3.30.2", + "@tiptap/extension-table": "3.30.2", + "@tiptap/extension-task-item": "3.30.2", + "@tiptap/extension-task-list": "3.30.2", + "@tiptap/extension-text": "3.30.2", + "@tiptap/extensions": "3.30.2", + "@tiptap/markdown": "3.30.2", + "@tiptap/pm": "3.30.2", + "@tiptap/react": "3.30.2", + "@tiptap/starter-kit": "3.30.2", + "@tiptap/suggestion": "3.30.2", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "1.1.1", @@ -51,7 +53,7 @@ "drizzle-orm": "0.45.2", "effect": "4.0.0-rc.109", "lowlight": "3.3.0", - "lucide-react": "1.31.0", + "lucide-react": "1.32.0", "react": "19.2.8", "react-dom": "19.2.8", "react-hotkeys-hook": "5.3.3", @@ -60,16 +62,16 @@ "use-debounce": "10.1.1" }, "devDependencies": { - "@biomejs/biome": "2.5.6", + "@biomejs/biome": "2.5.9", "@tailwindcss/vite": "4.3.3", - "@tanstack/router-plugin": "1.168.32", + "@tanstack/router-plugin": "1.168.33", "@tauri-apps/cli": "2.11.4", "@total-typescript/ts-reset": "0.6.1", "@types/node": "26.2.0", "@types/react": "19.2.18", "@types/react-dom": "19.2.4", "@vitejs/plugin-react": "6.0.5", - "@vitest/coverage-v8": "4.1.10", + "@vitest/coverage-v8": "4.1.11", "gitzy": "7.2.2", "happy-dom": "20.11.2", "jiti": "2.7.0", @@ -78,10 +80,10 @@ "shadcn": "4.18.0", "tailwindcss": "4.3.3", "tw-animate-css": "1.4.0", - "typescript": "6.0.3", + "typescript": "7.0.2", "ultracite": "7.10.5", "vite": "8.2.1", - "vitest": "4.1.10" + "vitest": "4.1.11" }, "packageManager": "pnpm@11.22.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f225be14..7bfb1f10 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: 5.3.0 version: 5.3.0 '@tanstack/react-router': - specifier: 1.170.29 - version: 1.170.29(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: 1.170.30 + version: 1.170.30(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@tauri-apps/api': specifier: 2.11.1 version: 2.11.1 @@ -32,48 +32,54 @@ importers: '@tauri-apps/plugin-opener': specifier: 2.5.4 version: 2.5.4 + '@tauri-apps/plugin-process': + specifier: 2.3.1 + version: 2.3.1 + '@tauri-apps/plugin-updater': + specifier: 2.10.1 + version: 2.10.1 '@tiptap/core': - specifier: 3.30.1 - version: 3.30.1(@tiptap/pm@3.30.1) + specifier: 3.30.2 + version: 3.30.2(@tiptap/pm@3.30.2) '@tiptap/extension-code-block-lowlight': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/extension-code-block@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)(highlight.js@11.11.2)(lowlight@3.3.0) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/extension-code-block@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)(highlight.js@11.11.2)(lowlight@3.3.0) '@tiptap/extension-document': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) '@tiptap/extension-image': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) '@tiptap/extension-table': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) '@tiptap/extension-task-item': - specifier: 3.30.1 - version: 3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) + specifier: 3.30.2 + version: 3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) '@tiptap/extension-task-list': - specifier: 3.30.1 - version: 3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) + specifier: 3.30.2 + version: 3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) '@tiptap/extension-text': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) '@tiptap/extensions': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) '@tiptap/markdown': - specifier: 3.30.1 - version: 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + specifier: 3.30.2 + version: 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) '@tiptap/pm': - specifier: 3.30.1 - version: 3.30.1 + specifier: 3.30.2 + version: 3.30.2 '@tiptap/react': - specifier: 3.30.1 - version: 3.30.1(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: 3.30.2 + version: 3.30.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@tiptap/starter-kit': - specifier: 3.30.1 - version: 3.30.1 + specifier: 3.30.2 + version: 3.30.2 '@tiptap/suggestion': - specifier: 3.30.1 - version: 3.30.1(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + specifier: 3.30.2 + version: 3.30.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) class-variance-authority: specifier: 0.7.1 version: 0.7.1 @@ -96,8 +102,8 @@ importers: specifier: 3.3.0 version: 3.3.0 lucide-react: - specifier: 1.31.0 - version: 1.31.0(react@19.2.8) + specifier: 1.32.0 + version: 1.32.0(react@19.2.8) react: specifier: 19.2.8 version: 19.2.8 @@ -118,14 +124,14 @@ importers: version: 10.1.1(react@19.2.8) devDependencies: '@biomejs/biome': - specifier: 2.5.6 - version: 2.5.6 + specifier: 2.5.9 + version: 2.5.9 '@tailwindcss/vite': specifier: 4.3.3 version: 4.3.3(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: 1.168.32 - version: 1.168.32(@tanstack/react-router@1.170.29(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(rolldown@1.2.4)(supports-color@7.2.0)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) + specifier: 1.168.33 + version: 1.168.33(@tanstack/react-router@1.170.30(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(rolldown@1.2.4)(supports-color@7.2.0)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) '@tauri-apps/cli': specifier: 2.11.4 version: 2.11.4 @@ -145,8 +151,8 @@ importers: specifier: 6.0.5 version: 6.0.5(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) '@vitest/coverage-v8': - specifier: 4.1.10 - version: 4.1.10(vitest@4.1.10) + specifier: 4.1.11 + version: 4.1.11(vitest@4.1.11) gitzy: specifier: 7.2.2 version: 7.2.2 @@ -164,7 +170,7 @@ importers: version: 2.1.10 shadcn: specifier: 4.18.0 - version: 4.18.0(supports-color@7.2.0)(typescript@6.0.3) + version: 4.18.0(supports-color@7.2.0)(typescript@7.0.2) tailwindcss: specifier: 4.3.3 version: 4.3.3 @@ -172,8 +178,8 @@ importers: specifier: 1.4.0 version: 1.4.0 typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 ultracite: specifier: 7.10.5 version: 7.10.5 @@ -181,8 +187,8 @@ importers: specifier: 8.2.1 version: 8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0) vitest: - specifier: 4.1.10 - version: 4.1.10(@types/node@26.2.0)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) + specifier: 4.1.11 + version: 4.1.11(@types/node@26.2.0)(@vitest/coverage-v8@4.1.11)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) packages: @@ -350,59 +356,59 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@2.5.6': - resolution: {integrity: sha512-lxVNjv7UF6KfhMJfL9gaUHbWdJdHbsAj6OSmwSYNdhRuG67NxNQ4Xdvh3TUxsSK9sBzJBQhEJj3AopmmNJ5pSA==} + '@biomejs/biome@2.5.9': + resolution: {integrity: sha512-KkgCvdHB4IhtpHpF564plA9jo6fDOwWGQ/3jvreLzgOtRLEDoPqr7QO9qejNA8jKwDsSkAKr77hqBHnyUbIw4g==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.5.6': - resolution: {integrity: sha512-zMOLZP4oMrjh6m1zcSj1ud2awUPgTuMVbmQhYYWL7J8HwCnbHHBvTm7VBTRuY7epT5bez76IpKYQ11ZAqHFlnw==} + '@biomejs/cli-darwin-arm64@2.5.9': + resolution: {integrity: sha512-am22pX2aBqznqq1eMyIj/bZ++riF3Lk6ct7cbv+gQK0csFhr+d8O0RkOi2FF2qSgFgANbqNkIZ0/PxlnW2pLFg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.5.6': - resolution: {integrity: sha512-JAC1VqzvO7Th5ZplU0G2uGfkZbxEe9uDDektPAhF0JLusoz1w+T4okp2bkykI0bbaO2vslKiRfj4gU43JaGreA==} + '@biomejs/cli-darwin-x64@2.5.9': + resolution: {integrity: sha512-l44KWDHLDvEnD0N/XcrVs7VXb3A18xL7QS3WB0eL93wbmk529ffIG55vleGCqaunpRUjLrdnjK05Qki1dsjylg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.5.6': - resolution: {integrity: sha512-eUa3jeeYvfMt19LBeh6E5PUZpxnTC4JqNWo+EDjTtQjAr2xLGnWaxACtVU1DQqmHYbvThlJzLX+ZsYgrqh2qVw==} + '@biomejs/cli-linux-arm64-musl@2.5.9': + resolution: {integrity: sha512-7ImVPwBLCtkmpR5esd8RHhTqW94f0JLJQum6AneYcy94jRm18TaPPm7slaigGzFhfgt3QiD1Vj52LKmBAnKizA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.5.6': - resolution: {integrity: sha512-6XsYwCFkp5sMxl85ffhgeGpGgs6A7dRYFnkceZ7WVxvycuTnGdD5xa534Z3xfrBQ0JCMK/mujT6ZNPJoghedwg==} + '@biomejs/cli-linux-arm64@2.5.9': + resolution: {integrity: sha512-ICaK+IYaVZvKbBxX2rwrPT0DdUDMnE9Vm3nQGe+mltQPmUg19pONzkPWGdY4FCsoreDETWDynvdt4ysCbF5gNQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.5.6': - resolution: {integrity: sha512-2Vp13QdKysH3HIWLaYLhUUwbK+jbZonJD1K+Lr0d0RO4wH7mkYd43vJixEDm8cUWrowoRz4UUHF1nm9Ae7ym8A==} + '@biomejs/cli-linux-x64-musl@2.5.9': + resolution: {integrity: sha512-RXGaD0o1/pTTguYw1aeDJh9ad6Lfrui0fI7mBderTyGr7WuUJkBIttgLkR3XJyoxOkkgfBDspaUT8wXArTqLZw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.5.6': - resolution: {integrity: sha512-Pop9VXCFUhFTMfFefZ39S+u2rOPyNp5iHlxbZRwXGACHLy2r0jjiRgJHmaEKJzL3SyxlVeGShXhvvElvWowonA==} + '@biomejs/cli-linux-x64@2.5.9': + resolution: {integrity: sha512-z22Q/zFYSvbIJfW1CbfZPu4X8PddS6Qd2ORbc6h+aT6EcwAxUF3m6fA4HjNvA3TU4X0dTJRwNPB165ES3PJXzg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.5.6': - resolution: {integrity: sha512-tDGshcm6BdkZOCGnTDX0Y8/U4IfBSlnUU7T56nNDuPEfed+aHg+u8G36NB43fJVl0Os6+QURXIE1yuD7AaEofA==} + '@biomejs/cli-win32-arm64@2.5.9': + resolution: {integrity: sha512-nHK+/HHC+D0ogAHUxomgoSTdjImb6fmNNVTKmf0tyu4eDL1DqPKIHc+i+UL8+b0RnAu8224qo8F2tCVnaT0A3w==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.5.6': - resolution: {integrity: sha512-WN05KwXnTO/2J45RQPvzZMXf7tZUIofHoR35xIPfCo7pQ2RFidxI8sfb5mGsaTxdMmEOzHzOPRCdA5/fCpc7xQ==} + '@biomejs/cli-win32-x64@2.5.9': + resolution: {integrity: sha512-Yiq0H56LjXSSw/hd9YkXgSLQfzyDJzbzU2TezozxyNw+uKWAqOtqGVvBfzKRRDiaFF5avGAhHdWKx7LtDOShUw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -1126,8 +1132,8 @@ packages: resolution: {integrity: sha512-DR9t6lfLVdrjgCwpglrR9DR7Ok8/HlXjcOE+goWXF3zyuLUO/ug7vMbSFxTqrQTtbRghJfyhmIZ0S6LhPIy44w==} engines: {node: '>=20.19'} - '@tanstack/react-router@1.170.29': - resolution: {integrity: sha512-xQwakR0ReaUGu3xeXEl2CqzlIXk4i9vxaf/zqdzoELMY0mDZgMOr+xobiA5cQdn8cnovqZgqqUxcwXhsruC+NA==} + '@tanstack/react-router@1.170.30': + resolution: {integrity: sha512-FB3FD6cPPKQFMyYaEsm3Isb8TkIvNAuSeADCS25OzMgKyFXZK/B/Y3m9fpBoKS55pjbvtRPpW87NMY8GVwNPlg==} engines: {node: '>=20.19'} peerDependencies: react: '>=18.0.0 || >=19.0.0' @@ -1139,20 +1145,20 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/router-core@1.171.24': - resolution: {integrity: sha512-+j+8NmV4QOS+ILNLdXFlLTdKPPbBQIy6mXDZ0QWEKYZ0xQOdlnOCXVHPflyGanD2SWSxjqGkw8CsW0CXXP7fLg==} + '@tanstack/router-core@1.171.25': + resolution: {integrity: sha512-w74Al2ar8UKx3Xp4ICTxIZD2Vmd6N9Yn4xH8ILq40gI5UqlxzjPPYoR5l2+5cmv9XCWZehxw7saIofmZpf1G4w==} engines: {node: '>=20.19'} - '@tanstack/router-generator@1.167.30': - resolution: {integrity: sha512-Tf9TJfdpP0yL3k1D1ke6hR1dvPCgKShTik3HcBRDeTK5eNrp9/X0Q0YApN8thE6pVcXL6a78O3ZE7XN7s7KwNw==} + '@tanstack/router-generator@1.167.31': + resolution: {integrity: sha512-xgk+8BCKzAoIONVJPeyyzLRKhb9W0PNWJepPIjx5gRU36+FDZUMNeZ/gjyOBZ4EzQgrUOCPs4/Vkr8JcnuRLLA==} engines: {node: '>=20.19'} - '@tanstack/router-plugin@1.168.32': - resolution: {integrity: sha512-P+qYIY9b/K+ZGUPNiyLqsd20vN/1abgmSNG0Ch9KTKldag3icR7TlrJgnM2km86yuRdXa4nJ5YT7+JLV5rJRZg==} + '@tanstack/router-plugin@1.168.33': + resolution: {integrity: sha512-Zdz2Cis8hf/U7Ft9pv7QjwLJgKO2lYej10Sr5cpBWX1Y1fO9sXqdQGy0OW6XLiDt5RgcdfEST81k4I3cRCD4Ag==} engines: {node: '>=20.19'} peerDependencies: '@rsbuild/core': '>=1.0.2 || ^2.0.0' - '@tanstack/react-router': ^1.170.29 + '@tanstack/react-router': ^1.170.30 vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' vite-plugin-solid: ^2.11.10 || ^3.0.0-0 webpack: '>=5.92.0' @@ -1267,198 +1273,204 @@ packages: '@tauri-apps/plugin-opener@2.5.4': resolution: {integrity: sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ==} - '@tiptap/core@3.30.1': - resolution: {integrity: sha512-HWEO6Qi8fI8Zt8X4atVV6GxthJx7Vrjr6L5YFq4OkjYJ7HG2/bFw6IKsDA3jOYgY4DM9lv8IadaiWUQ2JJRIBA==} + '@tauri-apps/plugin-process@2.3.1': + resolution: {integrity: sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==} + + '@tauri-apps/plugin-updater@2.10.1': + resolution: {integrity: sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA==} + + '@tiptap/core@3.30.2': + resolution: {integrity: sha512-QbZC/s1OOqcoUdkhIY16TjR/gCtR0qAk9e4bJwUqOJqZuv5ozqCL5hzWm22jjTPp6c6Ei2tPd6t30VwfIKW4lQ==} peerDependencies: - '@tiptap/pm': 3.30.1 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-blockquote@3.30.1': - resolution: {integrity: sha512-nUBIPmf9fKfBzeMpQsexsHw3/ICzDfBK8DN9uLf5wO3I/gWycAByynvfNIqfHyl6Q77QgTIHrdjihEXUSYzeJg==} + '@tiptap/extension-blockquote@3.30.2': + resolution: {integrity: sha512-BOkwhZenek7vzXBOgKppSrlx4YryBdAYu1p1MXKn0R9A9eNmE2HVhmm0gG49+E8BhsE/TG8wKVclwET42JJiIg==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-bold@3.30.1': - resolution: {integrity: sha512-xnEGv7evFQquT0r/byjBt5iqDYQi6bF/W7DPO2rAG0z33mShDEUHhE407jakMiOSYNUilFjuQj1naLvwpQC3Bw==} + '@tiptap/extension-bold@3.30.2': + resolution: {integrity: sha512-MsvJhPgYejY2D9MhwYJv8AmscozvLBI8qtJ7YLdYZBWkMR4bgmxHq5+xqEfBsao9bOMMwBon9p3+P+/Tq5ReWA==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-bubble-menu@3.30.1': - resolution: {integrity: sha512-6asFH7ZW0gTh0aX7qrABYRVqiU/IOSjk4PKt6qdZM5YS455bjVLZDM0PcIccMDaYiomuCNjfuCSj5dxmPDoWiQ==} + '@tiptap/extension-bubble-menu@3.30.2': + resolution: {integrity: sha512-oS0WiWNXHKpiPYMkcnHm1j7iEvufTGGtLFtcJJd3olb5OS6V2acoXVDL0nNJDmRQ32K3QXut3fbRcMseMxT+lw==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-bullet-list@3.30.1': - resolution: {integrity: sha512-9bf4VgIxaOe+c7W20WZGUU5d2SFNGSpVwDGU/7jGlnjobzR7ZhDK/THk9JQr8OpvZrVN8Nmf84ZD3axjt+h/hQ==} + '@tiptap/extension-bullet-list@3.30.2': + resolution: {integrity: sha512-+awIL/TUz4aB3rL68igU1rWfaaoBIAkPcakkktkRq8gYf0bd9eSb48P6kHkpx/3q+JyK7g9vsnltLNHNh6twnA==} peerDependencies: - '@tiptap/extension-list': 3.30.1 + '@tiptap/extension-list': 3.30.2 - '@tiptap/extension-code-block-lowlight@3.30.1': - resolution: {integrity: sha512-Qu+owe3DPHUxeKWD+hSUq4/AF6ZfAcTbvlv5ua1/R7gad4/404dDCXUdwwAr7lxqh3kzjdzYF8IDZsuy7CBIhA==} + '@tiptap/extension-code-block-lowlight@3.30.2': + resolution: {integrity: sha512-xmC1MOAMl7QmcayV0H/SLxpJ84o4SPwzAcJDhtgUWFdWyf8aO5rnNtUj/2HnvLXlM1nqZPMjTBOmSK7qgPwSZw==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/extension-code-block': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/extension-code-block': 3.30.2 + '@tiptap/pm': 3.30.2 highlight.js: ^11 lowlight: ^2 || ^3 - '@tiptap/extension-code-block@3.30.1': - resolution: {integrity: sha512-j19Ml9BpvHgTMSN4SfkJ26B5xSuHaxPXvMoXyAX1iOoSc4J92sCqShLGgpmtce42sIroYFRs4sBv0ndBRDcxtA==} + '@tiptap/extension-code-block@3.30.2': + resolution: {integrity: sha512-9otGKaQZmePHrLXFtCtz+BYDn5z4sSumTkUqQIQHz0gVxwPoTi7g51RedwxvViTb/zu2XV5ROXYLHIxKxypMPg==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-code@3.30.1': - resolution: {integrity: sha512-oqLEOLZel3lrLhACP4vMhH5RNbV9yxFsJYiOmQjjEFEoCEWWxVfJuhZ+8NFS3mUCdgy77G62XimjEvqC3+7V7Q==} + '@tiptap/extension-code@3.30.2': + resolution: {integrity: sha512-r8EZk3R9yGpF6v5xxafAU1HwrD/e+RpbfnmVi2TeB/ZHAsVO62fW96E32G0t6IdaCtOFtAd85hkDAaOfCT4yGg==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-document@3.30.1': - resolution: {integrity: sha512-aeMhO7EDoJyl5AGkF9hDQ9e52s18L8oYdbYjzcmXeo0YuXeaxbZCuUueVH4DnTfV7/vSkDRpDkk4TFF5LfKQpg==} + '@tiptap/extension-document@3.30.2': + resolution: {integrity: sha512-+xIv67V+/2L1uvz98FAT5W7kWEfHwfNV3MD7b4UsKPU0lhcCWuVOXy0JB8yYmdNExqpI7xT9g3MWzREoBvBQSg==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-dropcursor@3.30.1': - resolution: {integrity: sha512-N3R5rA01WX/brGm1Qcnf2KLu0xkyGbRPMsHzzl1YG2sOLQM9t+FQi1T8WvSJiOpfYBVaWQkILUoCymADSpgUAg==} + '@tiptap/extension-dropcursor@3.30.2': + resolution: {integrity: sha512-nyRKUmItATnKI9AiRChmjhcBbCEsNxRu+AaCz+cx8EvnAcNHsVRdNYL5PmBs3WlNA/Et4Eb2DG0hVQDnNF61eg==} peerDependencies: - '@tiptap/extensions': 3.30.1 + '@tiptap/extensions': 3.30.2 - '@tiptap/extension-floating-menu@3.30.1': - resolution: {integrity: sha512-/Rlqsn7OXThZNzD0Qq/Ru4rZCFj3YnxL8Vf01cez+pvcyxgbwf4b9Wir+1JWJmaEMYsmWprSgEBW0l9ctbq97w==} + '@tiptap/extension-floating-menu@3.30.2': + resolution: {integrity: sha512-A8PLvvh8W6PUMrqh+EpBerxm+Ucr0irGxJvwAnzYQmNGNIJ9U4OVgw4OcEU+9JH0gMmEzDcHzMPP2s/s1lIcyw==} peerDependencies: '@floating-ui/dom': ^1.0.0 - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-gapcursor@3.30.1': - resolution: {integrity: sha512-dp13WaPNj32SkDN9tun0OtwtfdO/y52BJWigwXPgpUFLEyr8hQ84TxXL3rDshGHE4Eyjdd+erdBHisjBEV9vwQ==} + '@tiptap/extension-gapcursor@3.30.2': + resolution: {integrity: sha512-7Xk0ut6FM+RAsvKxDN3bAtk7zvYZ6Aa8pawJ6s7dLAmLR9JwrZevlcL4FSrj4bR7rqKOj92RYCFxzgTEbWimag==} peerDependencies: - '@tiptap/extensions': 3.30.1 + '@tiptap/extensions': 3.30.2 - '@tiptap/extension-hard-break@3.30.1': - resolution: {integrity: sha512-2emcEkSSj+Y3dXXEugKQZDNeWCum0LBuKFmun7SiJyLOdxNuRnxwm2l4/LLiEHGDJBchDti4Oo8jZGLTRt4uog==} + '@tiptap/extension-hard-break@3.30.2': + resolution: {integrity: sha512-IxSNgmG3d4OZdUTeebrOI7SxdIWXXJqlcGiSNDabWqxipUitfy3mZ3gDDE6G01koKxZRbhz4KIplAZlpxnTFSg==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-heading@3.30.1': - resolution: {integrity: sha512-TGM1ZNeH/D8HQK59vFMZql2gesMoHy+6nLq3mFsYpiRT2TShMGoq+K7SC+ty6N5a/k4M82ZQrDq8t4zjiiS5xA==} + '@tiptap/extension-heading@3.30.2': + resolution: {integrity: sha512-PblDvgSJ05p1t6hzyPi02xeiBjB0M2abReoGEImqSWCy79UqnAGacgsZo4EeEawtJV1NEP8chhvmX+nRtzdT1A==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-horizontal-rule@3.30.1': - resolution: {integrity: sha512-fTaSDapNV3cRgsek94z/Z4+Fyr0UpkE8/9PdSvt9MHYo/2yx3mmuamEJwUhUCpe7gDfzGdrMMsRpDOcd0b1ZEQ==} + '@tiptap/extension-horizontal-rule@3.30.2': + resolution: {integrity: sha512-j8aswLTsuEdJKC62DF+kw0EgvIRL7QMUyAVp2fdjR0qgM0ZVlEwCC4qIEq3kK9tFVU4kRtQ5BSj/jn6QwrlbCA==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-image@3.30.1': - resolution: {integrity: sha512-LChYqHC0u7dq9/zj9R+SYgT04tuT549tzFeu8Ymo1TJ46Y9Iy3BfwlETZRvyV8NkC/eoGqUevJeD3HtG/vMaog==} + '@tiptap/extension-image@3.30.2': + resolution: {integrity: sha512-K/BPlWauHXI6Y4s7se2A1BLcZ2pnWmRQTEDkPJYe/8kmv1GyJzPu34sZed5Mvfu5chUH8u6aNZ/utZbvSbI/0Q==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-italic@3.30.1': - resolution: {integrity: sha512-KldMtozKk8OBHexo6akCQpJCWMgJ5OwPYuEOJO+vFjgw6VS+9N16peIo5dY+vXAiVIZL+swEsBp4barwz7NiLw==} + '@tiptap/extension-italic@3.30.2': + resolution: {integrity: sha512-pp8uaiuXsUbLm5rYzR1jlWbwm1mAahRajdHwAKBtthFRB2rDvC7ZWhKaCSoKhZvfIDRmu9/B67+uAHoutL0dCA==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-link@3.30.1': - resolution: {integrity: sha512-krq5yHDT4K+u2r7rS0CGk/yafyAKY1gbxexfbMmq+jyHtUUrr0UuCT1nOTa61bV3zX1nrObM1lKSpZ5FgbfdhQ==} + '@tiptap/extension-link@3.30.2': + resolution: {integrity: sha512-jwdcymKcrbFpj5hRAuGVLCq8FieVkGFnENyroYmvkad+XAt8ZLy/MTFYRN6SK3ukH6PZMY7H4iObGtciQaC5nw==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-list-item@3.30.1': - resolution: {integrity: sha512-8QqIKvEqXKlT4Cv3ZySHAq1jzKimT/UnFxNBCnkBg+aZBgImvPlRFdN5nFs0elxiSQ7Jtt6k29aOyrkjxgyeew==} + '@tiptap/extension-list-item@3.30.2': + resolution: {integrity: sha512-HWgRCRlGxulE+hN1VUcnWD6P2NE08VBgGtcaxOfdXVqaI93BCK6AhRQZGpLsfKgajLk+5DXTBraaitwnBqzCxg==} peerDependencies: - '@tiptap/extension-list': 3.30.1 + '@tiptap/extension-list': 3.30.2 - '@tiptap/extension-list-keymap@3.30.1': - resolution: {integrity: sha512-ju39AnbRyWr1vG4GnMM7BritV/9heGMeH103wccXgJU9hOEqzwmN9zpf5CZqeRnXOjzwQiojrEL+nwm5MnuboA==} + '@tiptap/extension-list-keymap@3.30.2': + resolution: {integrity: sha512-TTve3WOlQaYu1ahMqsQ/T0wzaxfgZvcOl3/OuPyInOi8QtxXhqGhFjmYe5jOr56G9W2QDuFWVsZecVwfDte9zg==} peerDependencies: - '@tiptap/extension-list': 3.30.1 + '@tiptap/extension-list': 3.30.2 - '@tiptap/extension-list@3.30.1': - resolution: {integrity: sha512-LizBu3fWrjifsL7QxKt+NhnHJDVGW/WWL+5asfqyznMqCZTy6tvPJ2W39pUHH2dBaVtzRIkAlsgWjDcNX/ep/Q==} + '@tiptap/extension-list@3.30.2': + resolution: {integrity: sha512-MIUpo1Bd9Rf1Qg+TNYNwDZ4xsfFeQahjU9Xhy6UcaszKQzbAM7KCzn5BObNytK1NdcqNHsC8Wj5vFvMKEzrXdw==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-ordered-list@3.30.1': - resolution: {integrity: sha512-kJ4+4I1n4b5jV8OpWH+dbKOlIWTWVPv/fxDQKZuAT/a0DRoowpRoAuGJ0Nk9/Azeqel6c8Ocb4n1J7xLR6Xl2Q==} + '@tiptap/extension-ordered-list@3.30.2': + resolution: {integrity: sha512-Z7OO1HcF0idda1n6vodXeQ3h2ylN9JR4IfIGUYkar5Xl9JusK8PDETTBQZQn//96p49I2d+GoWsD2LXPtjHXXg==} peerDependencies: - '@tiptap/extension-list': 3.30.1 + '@tiptap/extension-list': 3.30.2 - '@tiptap/extension-paragraph@3.30.1': - resolution: {integrity: sha512-1kAYoyIF88l2qPgHi9ZeS5D5N7TzdJg3FvVCOJvUplQtBIwrsNAx6zaH/16NKN7kRiW7zETMKXMKkhL6MIvnDg==} + '@tiptap/extension-paragraph@3.30.2': + resolution: {integrity: sha512-ulEu3LNt+kPVAWEnrhoz13Fs8Q/v/8NUxQbAeteuBchQ8joxJXuWExhpy1fUfZir5+b+W5z7/NesgPjZQfv47w==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-strike@3.30.1': - resolution: {integrity: sha512-vyF8TPTARaN5coGrFwqVREPXDONE4SXJMIxo9qMaBJWl7723m+Enpy7qmFscnwifW5XTpOA8jKl/QJ7qud/ljw==} + '@tiptap/extension-strike@3.30.2': + resolution: {integrity: sha512-fBLxMXz6hYIURzLOD+/L6aVATztsKham00ANWmGi13vN0hx2lQMYZffN+gR+QqiCDfMQxBXzrf5a7tJuDiQHLQ==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-table@3.30.1': - resolution: {integrity: sha512-frZvuNbgi4ohLGeweHMfKWoCVAlCUB/BULgzjLMaFSaSpVGk2KVeoYtCJf9wR240IAj3t7tti3A7E4Ymz98qOQ==} + '@tiptap/extension-table@3.30.2': + resolution: {integrity: sha512-zWp0ehZnx6N5lwRa8anSTn17GBEF3wxHXfOJGbBugf4Vwmp5keUEAXrgeIS4j7gIdxjN3XawdwjuMImG93N+Fg==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/extension-task-item@3.30.1': - resolution: {integrity: sha512-QHXZAaMinLmzMHksI47WxKBiD+KISOpGgnuyJhyt7DqGCbdRqIeTSCIIrxiZGSnwaCpCHbwRYpTz3kKRNvZURw==} + '@tiptap/extension-task-item@3.30.2': + resolution: {integrity: sha512-cb9SK9TxfK6rOJZSQemqwdEhv3KsUWwTAZG4aKE4ByLWOPhf7omAw7P5/4NO4TxnnwyZglOZMNhmrFXoKqoMWw==} peerDependencies: - '@tiptap/extension-list': 3.30.1 + '@tiptap/extension-list': 3.30.2 - '@tiptap/extension-task-list@3.30.1': - resolution: {integrity: sha512-g5VEXuifD1ZcR4bhaWnTb0InP3UWNWtfPy4xy06YpkaT0whCn5hQUppi6oE7RP9y+3ATfbBy7AnHWj2XU2JiMg==} + '@tiptap/extension-task-list@3.30.2': + resolution: {integrity: sha512-xo59REkBIb/1EMKQth24RW2CEcyZbuBTQog3JHqcQJotItsaIQP/HBRggtI3W+6eMxhujbRsuL9sLWbW1OPw6Q==} peerDependencies: - '@tiptap/extension-list': 3.30.1 + '@tiptap/extension-list': 3.30.2 - '@tiptap/extension-text@3.30.1': - resolution: {integrity: sha512-Zt3Ik95ZKJx5YNzC6TUXWTNBHUfRH/qVENmqfPjA7x7q4cqNdOEU+tX9DrlFjgxu/x0k48dlQS0Kaop24/vihA==} + '@tiptap/extension-text@3.30.2': + resolution: {integrity: sha512-n/iZnirgRmXet6f97kolAnP3j8DsgLSiTbz/KLWc8eBYiFmkjRzkuisOm5xuGdfGIxwpB4x3tlSF4ef4DLnbRg==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extension-underline@3.30.1': - resolution: {integrity: sha512-Xro/EzEgWW+46ztrw5f4epDWQvcGpD+HUykzigj30bpIS8Vv4XDXFt+89dAcyDC7zRUMQULlWZV0UCyRLFEKBw==} + '@tiptap/extension-underline@3.30.2': + resolution: {integrity: sha512-SZiTMnvqXcnrtJX+X25ZbYsuDO83haGOVMBD/O+mAWYNYXhaSc5Rkph5czzItxrd+Yyp/vs4PiwD7XTNbfqmpA==} peerDependencies: - '@tiptap/core': 3.30.1 + '@tiptap/core': 3.30.2 - '@tiptap/extensions@3.30.1': - resolution: {integrity: sha512-prNrvF1oMj+tngCLmZgXzQfuUuvYMbCe2sEPXXKJPqJNNffHd2wAuUZ0h6UQS5aRILaxB2kN1/yfwpxnhRpwYA==} + '@tiptap/extensions@3.30.2': + resolution: {integrity: sha512-2LqAHXk26QDsryW+beECxYeBzv5Ylk4GuB3cOmfghS7/G37R2W+Te3TkUK7BT0EWoDryvBT57/5q0DEFIhfZZg==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/markdown@3.30.1': - resolution: {integrity: sha512-IIZJTnf+lPfcMzqXxKS7RMHMVUFVHdE5vWPU6oqkAsTcQyVwvlQVaUZcdNpC5J1qXFgoleNwoMKC4mtYrErNXg==} + '@tiptap/markdown@3.30.2': + resolution: {integrity: sha512-csgdehtAi2G+ETWFSEDUF8pJ7Ip/G3mwyhvIoqws6Hp3kTBkx39zTUpz+Wm0Sld4xmStRqg1V+cgh5ZNmbZuBw==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 - '@tiptap/pm@3.30.1': - resolution: {integrity: sha512-2bHY+ihexKpfBURbAD+ahY0+lWle0TueTK80GAGYqZ/G7ErAPOmzN5RVAGMyZJI4wDkcFycRNLi3k0/3VT9a1A==} + '@tiptap/pm@3.30.2': + resolution: {integrity: sha512-BJN8tUx4ppFN3R3cV/FJfrJbJkvo1lj4uciq+nwpjwzdRvFzqIuglWf+HLcJ6CwlYpLOHp7ArgkBg4Q5e60Gog==} - '@tiptap/react@3.30.1': - resolution: {integrity: sha512-SZvUkUlRpZxzNHcQsBeiExWG6vEAdk2y/YeiwHaVmTJAiFaA5+IhKW/MuN1qJEvYS5LXE0uFy/VJaZtfKV5uWw==} + '@tiptap/react@3.30.2': + resolution: {integrity: sha512-7hGaTstpUeTmQ008mCPkjz+GSlChWhucgy+PeX0z93v4+nh7qM5F+0lh+kJ9zo6Os5abO7v36GtgHRZdQI6+FQ==} peerDependencies: - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tiptap/starter-kit@3.30.1': - resolution: {integrity: sha512-6P2WEp2ZHsx8LV6hQ3K/MB3n39oiVhKESlzh0v+KhK8RR/iKSKGxvTFbi1D/1fo4j3fZf+43PGHjyKXskn9ZmQ==} + '@tiptap/starter-kit@3.30.2': + resolution: {integrity: sha512-fJSrhW1CyD4sjYA20evSP4Cp13B/HhbxCdM974K0xpHOVqvCtNU9w2s9hfq9mg2yGoU7MSNHKNYMkJjIi2/Xyw==} - '@tiptap/suggestion@3.30.1': - resolution: {integrity: sha512-jhzZGR+6SCCHCdfsAi8g5DRo+lvcTfsw/71s4IEki+SFL8ykpOAF4tpV+G51IcGLOhxvB6xfkWDvm4B4eACqjw==} + '@tiptap/suggestion@3.30.2': + resolution: {integrity: sha512-qsQv+rlh5ik9G1n+SGLak69JoLQAFwdtQRjGpABYxx5USc14J7hrR1K8sj9tnWymX1fKXfJOlz+Dimcb1kDhWA==} peerDependencies: '@floating-ui/dom': ^1.0.0 - '@tiptap/core': 3.30.1 - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2 + '@tiptap/pm': 3.30.2 '@total-typescript/ts-reset@0.6.1': resolution: {integrity: sha512-cka47fVSo6lfQDIATYqb/vO1nvFfbPw7uWLayIXIhGETj0wcOOlrlkobOMDNQOFr9QOafegUPq13V2+6vtD7yg==} @@ -1507,6 +1519,126 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + '@vitejs/plugin-react@6.0.5': resolution: {integrity: sha512-BOVzne/NL162sMdResB25mUv+vWMF5NoAjNf09TeGlE7ZpszZWSD3winycicLJw72yeVsoCn/2kOhEuCvEShMA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1520,20 +1652,20 @@ packages: babel-plugin-react-compiler: optional: true - '@vitest/coverage-v8@4.1.10': - resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==} + '@vitest/coverage-v8@4.1.11': + resolution: {integrity: sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==} peerDependencies: - '@vitest/browser': 4.1.10 - vitest: 4.1.10 + '@vitest/browser': 4.1.11 + vitest: 4.1.11 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.10': - resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} + '@vitest/expect@4.1.11': + resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==} - '@vitest/mocker@4.1.10': - resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} + '@vitest/mocker@4.1.11': + resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1543,20 +1675,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.10': - resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} + '@vitest/pretty-format@4.1.11': + resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} - '@vitest/runner@4.1.10': - resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} + '@vitest/runner@4.1.11': + resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==} - '@vitest/snapshot@4.1.10': - resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} + '@vitest/snapshot@4.1.11': + resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} - '@vitest/spy@4.1.10': - resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} + '@vitest/spy@4.1.11': + resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==} - '@vitest/utils@4.1.10': - resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} + '@vitest/utils@4.1.11': + resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} @@ -2666,8 +2798,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-react@1.31.0: - resolution: {integrity: sha512-G8u2eEtoHUnUa9f8lbvqDhCiORMnYLdUEo06EEG9MQvHQrInKcX3Pa2TH39MM5qyzRcWETxB0+aOwAPI1g1kEg==} + lucide-react@1.32.0: + resolution: {integrity: sha512-txX56hMFnRxPi1f9/nH69YN8uvAO6a7Y1KSWKjCDAtdD9+soEgmWuCt6iRm1pkxUZo2+YntSdsE1L6bIuKoY8Q==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3316,9 +3448,9 @@ packages: resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} engines: {node: '>= 18'} - typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} hasBin: true ufo@1.6.4: @@ -3483,20 +3615,20 @@ packages: yaml: optional: true - vitest@4.1.10: - resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} + vitest@4.1.11: + resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.10 - '@vitest/browser-preview': 4.1.10 - '@vitest/browser-webdriverio': 4.1.10 - '@vitest/coverage-istanbul': 4.1.10 - '@vitest/coverage-v8': 4.1.10 - '@vitest/ui': 4.1.10 + '@vitest/browser-playwright': 4.1.11 + '@vitest/browser-preview': 4.1.11 + '@vitest/browser-webdriverio': 4.1.11 + '@vitest/coverage-istanbul': 4.1.11 + '@vitest/coverage-v8': 4.1.11 + '@vitest/ui': 4.1.11 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3824,39 +3956,39 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@2.5.6': + '@biomejs/biome@2.5.9': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.5.6 - '@biomejs/cli-darwin-x64': 2.5.6 - '@biomejs/cli-linux-arm64': 2.5.6 - '@biomejs/cli-linux-arm64-musl': 2.5.6 - '@biomejs/cli-linux-x64': 2.5.6 - '@biomejs/cli-linux-x64-musl': 2.5.6 - '@biomejs/cli-win32-arm64': 2.5.6 - '@biomejs/cli-win32-x64': 2.5.6 + '@biomejs/cli-darwin-arm64': 2.5.9 + '@biomejs/cli-darwin-x64': 2.5.9 + '@biomejs/cli-linux-arm64': 2.5.9 + '@biomejs/cli-linux-arm64-musl': 2.5.9 + '@biomejs/cli-linux-x64': 2.5.9 + '@biomejs/cli-linux-x64-musl': 2.5.9 + '@biomejs/cli-win32-arm64': 2.5.9 + '@biomejs/cli-win32-x64': 2.5.9 - '@biomejs/cli-darwin-arm64@2.5.6': + '@biomejs/cli-darwin-arm64@2.5.9': optional: true - '@biomejs/cli-darwin-x64@2.5.6': + '@biomejs/cli-darwin-x64@2.5.9': optional: true - '@biomejs/cli-linux-arm64-musl@2.5.6': + '@biomejs/cli-linux-arm64-musl@2.5.9': optional: true - '@biomejs/cli-linux-arm64@2.5.6': + '@biomejs/cli-linux-arm64@2.5.9': optional: true - '@biomejs/cli-linux-x64-musl@2.5.6': + '@biomejs/cli-linux-x64-musl@2.5.9': optional: true - '@biomejs/cli-linux-x64@2.5.6': + '@biomejs/cli-linux-x64@2.5.9': optional: true - '@biomejs/cli-win32-arm64@2.5.6': + '@biomejs/cli-win32-arm64@2.5.9': optional: true - '@biomejs/cli-win32-x64@2.5.6': + '@biomejs/cli-win32-x64@2.5.9': optional: true '@clack/core@1.4.3': @@ -4390,11 +4522,11 @@ snapshots: '@tanstack/history@1.162.1': {} - '@tanstack/react-router@1.170.29(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@tanstack/react-router@1.170.30(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@tanstack/history': 1.162.1 '@tanstack/react-store': 0.9.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@tanstack/router-core': 1.171.24 + '@tanstack/router-core': 1.171.25 isbot: 5.2.1 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) @@ -4406,17 +4538,17 @@ snapshots: react-dom: 19.2.8(react@19.2.8) use-sync-external-store: 1.6.0(react@19.2.8) - '@tanstack/router-core@1.171.24': + '@tanstack/router-core@1.171.25': dependencies: '@tanstack/history': 1.162.1 cookie-es: 3.1.1 seroval: 1.6.2 seroval-plugins: 1.6.2(seroval@1.6.2) - '@tanstack/router-generator@1.167.30(supports-color@7.2.0)': + '@tanstack/router-generator@1.167.31(supports-color@7.2.0)': dependencies: '@babel/types': 7.29.8 - '@tanstack/router-core': 1.171.24 + '@tanstack/router-core': 1.171.25 '@tanstack/router-utils': 1.162.2(supports-color@7.2.0) '@tanstack/virtual-file-routes': 1.162.0 jiti: 2.7.0 @@ -4426,19 +4558,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.168.32(@tanstack/react-router@1.170.29(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(rolldown@1.2.4)(supports-color@7.2.0)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0))': + '@tanstack/router-plugin@1.168.33(@tanstack/react-router@1.170.30(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(rolldown@1.2.4)(supports-color@7.2.0)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/template': 7.29.7 '@babel/types': 7.29.8 - '@tanstack/router-core': 1.171.24 - '@tanstack/router-generator': 1.167.30(supports-color@7.2.0) + '@tanstack/router-core': 1.171.25 + '@tanstack/router-generator': 1.167.31(supports-color@7.2.0) '@tanstack/router-utils': 1.162.2(supports-color@7.2.0) chokidar: 5.0.0 unplugin: 3.3.0(rolldown@1.2.4)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) zod: 4.4.3 optionalDependencies: - '@tanstack/react-router': 1.170.29(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@tanstack/react-router': 1.170.30(react-dom@19.2.8(react@19.2.8))(react@19.2.8) vite: 8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0) transitivePeerDependencies: - '@farmfe/core' @@ -4528,151 +4660,159 @@ snapshots: dependencies: '@tauri-apps/api': 2.11.1 - '@tiptap/core@3.30.1(@tiptap/pm@3.30.1)': + '@tauri-apps/plugin-process@2.3.1': dependencies: - '@tiptap/pm': 3.30.1 + '@tauri-apps/api': 2.11.1 - '@tiptap/extension-blockquote@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tauri-apps/plugin-updater@2.10.1': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tauri-apps/api': 2.11.1 + + '@tiptap/core@3.30.2(@tiptap/pm@3.30.2)': + dependencies: + '@tiptap/pm': 3.30.2 + + '@tiptap/extension-blockquote@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': + dependencies: + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 - '@tiptap/extension-bold@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-bold@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-bubble-menu@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-bubble-menu@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 optional: true - '@tiptap/extension-bullet-list@3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-bullet-list@3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-code-block-lowlight@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/extension-code-block@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)(highlight.js@11.11.2)(lowlight@3.3.0)': + '@tiptap/extension-code-block-lowlight@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/extension-code-block@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)(highlight.js@11.11.2)(lowlight@3.3.0)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/extension-code-block': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/extension-code-block': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 highlight.js: 11.11.2 lowlight: 3.3.0 - '@tiptap/extension-code-block@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-code-block@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 - '@tiptap/extension-code@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-code@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-document@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-document@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-dropcursor@3.30.1(@tiptap/extensions@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-dropcursor@3.30.2(@tiptap/extensions@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extensions': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extensions': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-floating-menu@3.30.1(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-floating-menu@3.30.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 optional: true - '@tiptap/extension-gapcursor@3.30.1(@tiptap/extensions@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-gapcursor@3.30.2(@tiptap/extensions@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extensions': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extensions': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-hard-break@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-hard-break@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-heading@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-heading@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-horizontal-rule@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-horizontal-rule@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 - '@tiptap/extension-image@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-image@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-italic@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-italic@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-link@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-link@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 linkifyjs: 4.3.3 - '@tiptap/extension-list-item@3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-list-item@3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-list-keymap@3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-list-keymap@3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 - '@tiptap/extension-ordered-list@3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-ordered-list@3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-paragraph@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-paragraph@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-strike@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-strike@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-table@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extension-table@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 - '@tiptap/extension-task-item@3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-task-item@3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-task-list@3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1))': + '@tiptap/extension-task-list@3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) - '@tiptap/extension-text@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-text@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extension-underline@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))': + '@tiptap/extension-underline@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) - '@tiptap/extensions@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/extensions@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 - '@tiptap/markdown@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/markdown@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 marked: 17.0.6 - '@tiptap/pm@3.30.1': + '@tiptap/pm@3.30.2': dependencies: prosemirror-changeset: 2.4.1 prosemirror-commands: 1.7.2 @@ -4688,10 +4828,10 @@ snapshots: prosemirror-transform: 1.12.0 prosemirror-view: 1.42.2 - '@tiptap/react@3.30.1(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@tiptap/react@3.30.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 '@types/react': 19.2.18 '@types/react-dom': 19.2.4(@types/react@19.2.18) '@types/use-sync-external-store': 0.0.6 @@ -4700,43 +4840,43 @@ snapshots: react-dom: 19.2.8(react@19.2.8) use-sync-external-store: 1.6.0(react@19.2.8) optionalDependencies: - '@tiptap/extension-bubble-menu': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/extension-floating-menu': 3.30.1(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) + '@tiptap/extension-bubble-menu': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/extension-floating-menu': 3.30.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) transitivePeerDependencies: - '@floating-ui/dom' - '@tiptap/starter-kit@3.30.1': - dependencies: - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/extension-blockquote': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/extension-bold': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-bullet-list': 3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) - '@tiptap/extension-code': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-code-block': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/extension-document': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-dropcursor': 3.30.1(@tiptap/extensions@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) - '@tiptap/extension-gapcursor': 3.30.1(@tiptap/extensions@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) - '@tiptap/extension-hard-break': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-heading': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-horizontal-rule': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/extension-italic': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-link': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/extension-list': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/extension-list-item': 3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) - '@tiptap/extension-list-keymap': 3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) - '@tiptap/extension-ordered-list': 3.30.1(@tiptap/extension-list@3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)) - '@tiptap/extension-paragraph': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-strike': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-text': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extension-underline': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1)) - '@tiptap/extensions': 3.30.1(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 - - '@tiptap/suggestion@3.30.1(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.1(@tiptap/pm@3.30.1))(@tiptap/pm@3.30.1)': + '@tiptap/starter-kit@3.30.2': + dependencies: + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/extension-blockquote': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/extension-bold': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-bullet-list': 3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) + '@tiptap/extension-code': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-code-block': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/extension-document': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-dropcursor': 3.30.2(@tiptap/extensions@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) + '@tiptap/extension-gapcursor': 3.30.2(@tiptap/extensions@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) + '@tiptap/extension-hard-break': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-heading': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-horizontal-rule': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/extension-italic': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-link': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/extension-list': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/extension-list-item': 3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) + '@tiptap/extension-list-keymap': 3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) + '@tiptap/extension-ordered-list': 3.30.2(@tiptap/extension-list@3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)) + '@tiptap/extension-paragraph': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-strike': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-text': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extension-underline': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2)) + '@tiptap/extensions': 3.30.2(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 + + '@tiptap/suggestion@3.30.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.30.2(@tiptap/pm@3.30.2))(@tiptap/pm@3.30.2)': dependencies: '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.30.1(@tiptap/pm@3.30.1) - '@tiptap/pm': 3.30.1 + '@tiptap/core': 3.30.2(@tiptap/pm@3.30.2) + '@tiptap/pm': 3.30.2 '@total-typescript/ts-reset@0.6.1': {} @@ -4788,15 +4928,75 @@ snapshots: dependencies: '@types/node': 26.2.0 + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + '@vitejs/plugin-react@6.0.5(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.1 vite: 8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0) - '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': + '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.10 + '@vitest/utils': 4.1.11 ast-v8-to-istanbul: 1.0.5 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -4805,46 +5005,46 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@types/node@26.2.0)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) + vitest: 4.1.11(@types/node@26.2.0)(@vitest/coverage-v8@4.1.11)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) - '@vitest/expect@4.1.10': + '@vitest/expect@4.1.11': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 + '@vitest/spy': 4.1.11 + '@vitest/utils': 4.1.11 chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0))': + '@vitest/mocker@4.1.11(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.10 + '@vitest/spy': 4.1.11 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: vite: 8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0) - '@vitest/pretty-format@4.1.10': + '@vitest/pretty-format@4.1.11': dependencies: tinyrainbow: 3.1.1 - '@vitest/runner@4.1.10': + '@vitest/runner@4.1.11': dependencies: - '@vitest/utils': 4.1.10 + '@vitest/utils': 4.1.11 pathe: 2.0.3 - '@vitest/snapshot@4.1.10': + '@vitest/snapshot@4.1.11': dependencies: - '@vitest/pretty-format': 4.1.10 - '@vitest/utils': 4.1.10 + '@vitest/pretty-format': 4.1.11 + '@vitest/utils': 4.1.11 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.10': {} + '@vitest/spy@4.1.11': {} - '@vitest/utils@4.1.10': + '@vitest/utils@4.1.11': dependencies: - '@vitest/pretty-format': 4.1.10 + '@vitest/pretty-format': 4.1.11 convert-source-map: 2.0.0 tinyrainbow: 3.1.1 @@ -5052,14 +5252,14 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig@9.0.2(typescript@6.0.3): + cosmiconfig@9.0.2(typescript@7.0.2): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.3.1 parse-json: 5.2.0 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 cross-spawn@7.0.6: dependencies: @@ -5765,7 +5965,7 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@1.31.0(react@19.2.8): + lucide-react@1.32.0(react@19.2.8): dependencies: react: 19.2.8 @@ -6291,7 +6491,7 @@ snapshots: setprototypeof@1.2.0: {} - shadcn@4.18.0(supports-color@7.2.0)(typescript@6.0.3): + shadcn@4.18.0(supports-color@7.2.0)(typescript@7.0.2): dependencies: '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/parser': 7.29.8 @@ -6302,7 +6502,7 @@ snapshots: '@types/validate-npm-package-name': 4.0.2 browserslist: 4.28.8 commander: 14.0.3 - cosmiconfig: 9.0.2(typescript@6.0.3) + cosmiconfig: 9.0.2(typescript@7.0.2) dedent: 1.7.2 deepmerge: 4.3.1 diff: 8.0.4 @@ -6492,7 +6692,28 @@ snapshots: media-typer: 1.1.1 mime-types: 3.0.2 - typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 ufo@1.6.4: {} @@ -6584,15 +6805,15 @@ snapshots: jiti: 2.7.0 yaml: 2.9.0 - vitest@4.1.10(@types/node@26.2.0)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)): + vitest@4.1.11(@types/node@26.2.0)(@vitest/coverage-v8@4.1.11)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)): dependencies: - '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.10 - '@vitest/runner': 4.1.10 - '@vitest/snapshot': 4.1.10 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 + '@vitest/expect': 4.1.11 + '@vitest/mocker': 4.1.11(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.11 + '@vitest/runner': 4.1.11 + '@vitest/snapshot': 4.1.11 + '@vitest/spy': 4.1.11 + '@vitest/utils': 4.1.11 es-module-lexer: 2.3.1 expect-type: 1.4.0 magic-string: 0.30.21 @@ -6608,7 +6829,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 26.2.0 - '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) + '@vitest/coverage-v8': 4.1.11(vitest@4.1.11) happy-dom: 20.11.2 transitivePeerDependencies: - msw diff --git a/scripts/notras.rb.tmpl b/scripts/notras.rb.tmpl index 4776e3df..dd64c1da 100644 --- a/scripts/notras.rb.tmpl +++ b/scripts/notras.rb.tmpl @@ -7,6 +7,8 @@ cask "notras" do desc "Local-first, keyboard-driven notes app" homepage "https://github.com/jimmy-guzman/notras" + auto_updates true + app "notras.app" caveats <<~CAVEATS diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 57b8a7ca..8f5a8bdd 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -47,6 +47,15 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "async-broadcast" version = "0.7.2" @@ -718,6 +727,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "derive_more" version = "2.1.1" @@ -1042,6 +1062,16 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + [[package]] name = "find-msvc-tools" version = "0.1.11" @@ -1653,6 +1683,21 @@ dependencies = [ "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", +] + [[package]] name = "hyper-util" version = "0.1.20" @@ -2008,6 +2053,36 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.20", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + [[package]] name = "jni-sys" version = "0.3.1" @@ -2228,6 +2303,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minisign-verify" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2369,7 +2450,9 @@ dependencies = [ "tauri-plugin-dialog", "tauri-plugin-global-shortcut", "tauri-plugin-opener", + "tauri-plugin-process", "tauri-plugin-store", + "tauri-plugin-updater", ] [[package]] @@ -2570,6 +2653,18 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "objc2-osa-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0" +dependencies = [ + "bitflags 2.13.1", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + [[package]] name = "objc2-quartz-core" version = "0.3.2" @@ -2644,6 +2739,12 @@ dependencies = [ "libc", ] +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "option-ext" version = "0.2.0" @@ -2660,6 +2761,20 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "osakit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" +dependencies = [ + "objc2", + "objc2-foundation", + "objc2-osa-kit", + "serde", + "serde_json", + "thiserror 2.0.20", +] + [[package]] name = "pango" version = "0.18.3" @@ -3083,15 +3198,20 @@ dependencies = [ "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-util", "js-sys", "log", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", "serde", "serde_json", "sync_wrapper", "tokio", + "tokio-rustls", "tokio-util", "tower", "tower-http", @@ -3127,6 +3247,20 @@ dependencies = [ "windows-sys 0.60.2", ] +[[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 = "rusqlite" version = "0.37.0" @@ -3169,6 +3303,79 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni 0.22.4", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.23" @@ -3184,6 +3391,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "schemars" version = "0.8.22" @@ -3241,6 +3457,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.13.1", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "selectors" version = "0.36.1" @@ -3462,6 +3701,22 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "1.0.3" @@ -3574,6 +3829,12 @@ 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" @@ -3668,7 +3929,7 @@ dependencies = [ "gdkwayland-sys", "gdkx11-sys", "gtk", - "jni", + "jni 0.21.1", "libc", "log", "ndk", @@ -3701,6 +3962,17 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -3726,7 +3998,7 @@ dependencies = [ "http", "http-range", "image", - "jni", + "jni 0.21.1", "libc", "log", "mime", @@ -3931,6 +4203,16 @@ dependencies = [ "zbus", ] +[[package]] +name = "tauri-plugin-process" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a" +dependencies = [ + "tauri", + "tauri-plugin", +] + [[package]] name = "tauri-plugin-store" version = "2.4.4" @@ -3947,6 +4229,39 @@ dependencies = [ "tracing", ] +[[package]] +name = "tauri-plugin-updater" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806d9dac662c2e4594ff03c647a552f2c9bd544e7d0f683ec58f872f952ce4af" +dependencies = [ + "base64 0.22.1", + "dirs 6.0.0", + "flate2", + "futures-util", + "http", + "infer", + "log", + "minisign-verify", + "osakit", + "percent-encoding", + "reqwest", + "rustls", + "semver", + "serde", + "serde_json", + "tar", + "tauri", + "tauri-plugin", + "tempfile", + "thiserror 2.0.20", + "time", + "tokio", + "url", + "windows-sys 0.60.2", + "zip", +] + [[package]] name = "tauri-runtime" version = "2.11.3" @@ -3957,7 +4272,7 @@ dependencies = [ "dpi", "gtk", "http", - "jni", + "jni 0.21.1", "objc2", "objc2-ui-kit", "objc2-web-kit", @@ -3980,7 +4295,7 @@ checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f" dependencies = [ "gtk", "http", - "jni", + "jni 0.21.1", "log", "objc2", "objc2-app-kit", @@ -4190,6 +4505,16 @@ dependencies = [ "syn 3.0.3", ] +[[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.19" @@ -4503,6 +4828,12 @@ version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -4752,6 +5083,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.38.2" @@ -4982,6 +5322,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -5286,7 +5635,7 @@ dependencies = [ "gtk", "http", "javascriptcore-rs", - "jni", + "jni 0.21.1", "libc", "ndk", "objc2", @@ -5350,6 +5699,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + [[package]] name = "xkeysym" version = "0.2.1" @@ -5470,6 +5829,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + [[package]] name = "zerotrie" version = "0.2.5" @@ -5503,6 +5868,18 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "zip" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1" +dependencies = [ + "arbitrary", + "crc32fast", + "indexmap 2.14.0", + "memchr", +] + [[package]] name = "zmij" version = "1.0.23" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 1bca3b00..55f8717d 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -36,6 +36,8 @@ tauri-plugin-store = "2" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] tauri-plugin-autostart = "2" tauri-plugin-global-shortcut = "2" +tauri-plugin-process = "2" +tauri-plugin-updater = "2" # Already in the tree through tao and wry; named here to reach # prefersCompactControlSizeMetrics, which is what keeps the window buttons at diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index c564b1bc..9fbe47f1 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -19,6 +19,8 @@ "global-shortcut:allow-is-registered", "autostart:allow-enable", "autostart:allow-disable", - "autostart:allow-is-enabled" + "autostart:allow-is-enabled", + "process:allow-restart", + "updater:default" ] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8579779d..85d17dc0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -256,10 +256,13 @@ pub fn run() { #[cfg(desktop)] { - builder = builder.plugin(tauri_plugin_autostart::init( - tauri_plugin_autostart::MacosLauncher::LaunchAgent, - None, - )); + builder = builder + .plugin(tauri_plugin_autostart::init( + tauri_plugin_autostart::MacosLauncher::LaunchAgent, + None, + )) + .plugin(tauri_plugin_process::init()) + .plugin(tauri_plugin_updater::Builder::new().build()); } let app = builder diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 9c3f3c5f..f9c9fefc 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -36,6 +36,7 @@ }, "bundle": { "active": true, + "createUpdaterArtifacts": true, "targets": "all", "category": "Productivity", "icon": [ @@ -55,5 +56,16 @@ "role": "Editor" } ] + }, + "plugins": { + "updater": { + "endpoints": [ + "https://github.com/jimmy-guzman/notras/releases/latest/download/latest.json" + ], + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDM5RThEOEYyODhGQkU3MzgKUldRNDUvdUk4dGpvT1lxTmE2Rlp1Y1FxZ3lqSVVjMHE3MTJacWt3OFhHUlZYRXlxeExxdjBMajMK", + "windows": { + "installMode": "passive" + } + } } } diff --git a/src/components/command-palette.tsx b/src/components/command-palette.tsx index 9cde5557..36103241 100644 --- a/src/components/command-palette.tsx +++ b/src/components/command-palette.tsx @@ -1,6 +1,7 @@ import { useNavigate, useParams } from "@tanstack/react-router"; import { revealItemInDir } from "@tauri-apps/plugin-opener"; import { + DownloadIcon, FilePlusIcon, FileTextIcon, FolderIcon, @@ -38,6 +39,7 @@ import { moveNote } from "@/data/move-note"; import { setNotePinned } from "@/data/pin-note"; import { reindexAll } from "@/data/reindex"; import { retitleNote } from "@/data/retitle-note"; +import { findUpdate, installUpdate } from "@/lib/updater"; import { getSnippetParts } from "@/lib/utils/fts-snippet"; import { parseTagQuery } from "@/lib/utils/tag-query"; @@ -625,6 +627,30 @@ export function CommandPalette({ }); }, [runAction]); + // Unlike the launch check, this one was asked for, so it reports either way. + const checkForUpdates = useCallback(() => { + runAction(async () => { + const update = await findUpdate(); + + if (update === null) { + toast.success("notras is up to date"); + + return; + } + + toast(`version ${update.version} is available`, { + action: { + label: "install", + onClick: () => { + installUpdate(update).catch(() => { + toast.error("could not install the update"); + }); + }, + }, + }); + }); + }, [runAction]); + const actions = [ { Icon: FilePlusIcon, @@ -698,6 +724,14 @@ export function CommandPalette({ text: "reindex library", value: "reindex", }, + { + Icon: DownloadIcon, + label: "check for updates", + needsNote: false, + onSelect: checkForUpdates, + text: "check for updates...", + value: "check-for-updates", + }, ]; return ( diff --git a/src/lib/updater.spec.ts b/src/lib/updater.spec.ts new file mode 100644 index 00000000..841226d4 --- /dev/null +++ b/src/lib/updater.spec.ts @@ -0,0 +1,33 @@ +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +import { describe, expect, it } from "vitest"; + +/** + * A bogus `pubkey` is not caught by `tauri build`; the updater plugin only + * parses it at runtime, so a placeholder would ship and fail in an installed + * app. Read the shipped config and refuse that here instead. + */ +const config = JSON.parse( + readFileSync(join(process.cwd(), "src-tauri", "tauri.conf.json"), "utf8") +) as { + bundle: { createUpdaterArtifacts?: boolean }; + plugins: { updater: { endpoints: string[]; pubkey: string } }; +}; + +describe("updater config", () => { + it("should carry a real minisign public key", () => { + const { pubkey } = config.plugins.updater; + + // `tauri signer generate` emits the base64 of a minisign public key file, + // which always opens with its "untrusted comment:" header. + expect(pubkey.startsWith("dW50cnVzdGVkIGNvbW1lbnQ6")).toBe(true); + }); + + it("should emit the artifacts the endpoint serves", () => { + expect(config.bundle.createUpdaterArtifacts).toBe(true); + expect(config.plugins.updater.endpoints).toContain( + "https://github.com/jimmy-guzman/notras/releases/latest/download/latest.json" + ); + }); +}); diff --git a/src/lib/updater.ts b/src/lib/updater.ts new file mode 100644 index 00000000..6248c18f --- /dev/null +++ b/src/lib/updater.ts @@ -0,0 +1,28 @@ +import { relaunch } from "@tauri-apps/plugin-process"; +import { check, type Update } from "@tauri-apps/plugin-updater"; + +/** + * Ask the release endpoint whether a newer version exists. Resolves to `null` + * when the app is current, and always in development, where the endpoint that + * `latest.json` is published to does not answer. + * + * The resolved `Update` owns a native handle. Hand it to `installUpdate`, which + * consumes it, or call its `close()` to let it go. A handle that is neither is + * released when the app exits, which bounds the leak at one per check. + */ +export async function findUpdate() { + if (!import.meta.env.PROD) { + return null; + } + + return await check(); +} + +/** + * Download the update, install it, and restart into it. Does not resolve on the + * happy path: `relaunch` replaces the process. + */ +export async function installUpdate(update: Update) { + await update.downloadAndInstall(); + await relaunch(); +} diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index f40b9a90..2d6857d6 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -20,6 +20,7 @@ import { getNotes } from "@/data/get-notes"; import { getTags } from "@/data/get-tags"; import { getNotesDir } from "@/data/notes-dir"; import { flushPendingWrites } from "@/lib/pending-flush"; +import { findUpdate, installUpdate } from "@/lib/updater"; interface RootSearch { /** Set by a tag chip to open the palette already filtered to that tag. */ @@ -88,6 +89,34 @@ function RootLayout() { setSettingsOpen(true); }, []); + // One check per launch. Silent when there is nothing to install and silent + // when the check itself fails: a launch is the wrong moment to interrupt + // someone over a network blip, and the palette offers a check that reports. + useEffect(() => { + const offerUpdate = async () => { + const update = await findUpdate(); + + if (update === null) { + return; + } + + toast(`version ${update.version} is available`, { + action: { + label: "install", + onClick: () => { + installUpdate(update).catch(() => { + toast.error("could not install the update"); + }); + }, + }, + }); + }; + + offerUpdate().catch(() => { + // Deliberately quiet; see above. + }); + }, []); + // External writers (AI agents, other editors, the watcher) drive refreshes. useEffect(() => { const unlisten = listen("notes-changed", () => { From 579b2c186b186ac7dc93c2aa3f1063ed1bde3430 Mon Sep 17 00:00:00 2001 From: jimmy-guzman Date: Fri, 21 Aug 2026 15:51:21 -0500 Subject: [PATCH 2/5] =?UTF-8?q?docs:=20=F0=9F=93=9D=20do=20not=20wrap=20pr?= =?UTF-8?q?=20bodies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub renders every single newline in a PR body as a line break, so wrapped paragraphs arrive as a ragged narrow column. Nothing said PR bodies were different from the markdown files here, which is how both #95 and #97 shipped wrapped. --- AGENTS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 3b0a646b..2807a47e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -494,7 +494,9 @@ They cover every markdown file here, plus commit messages and PR bodies. ``` Two sections force the description to answer the two questions a reviewer - opens with, and a third section pads. + opens with, and a third section pads. Do not wrap the paragraphs: GitHub + renders every single newline in a PR body as a line break, so wrapped text + arrives as a ragged column. One line per paragraph. - **`## Why` also says what happens when the change is wrong and how someone finds out.** The section carries the problem the change addresses. Two more From bb46457b2846654d3f5afe93604035d703bb19c4 Mon Sep 17 00:00:00 2001 From: jimmy-guzman Date: Fri, 21 Aug 2026 16:13:56 -0500 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=F0=9F=90=9B=20apply=20review=20feed?= =?UTF-8?q?back?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ARCHITECTURE.md | 12 ++++++++++-- SPEC.md | 8 +++++--- src-tauri/src/lib.rs | 10 +++++++++- src/components/command-palette.tsx | 19 ++++++++++++++---- src/lib/updater.spec.ts | 29 +++++++++++++++++++++++----- src/lib/updater.ts | 31 ++++++++++++++++++++++++------ src/routes/__root.tsx | 14 +++++++++++--- 7 files changed, 99 insertions(+), 24 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 65320634..8993d829 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -155,6 +155,7 @@ src/ runtime.ts # AppRuntime (ManagedRuntime), wires the adapters lib/ # Client utilities pending-flush.ts # autosave flush registry read by the quit handshake + updater.ts # release check + install, gated by updatesSupported ui/utils.ts # cn() utils/ # fts-snippet, tag-query, word-count src-tauri/ @@ -265,6 +266,13 @@ one chain so overlapping flushes cannot land out of order, and flushes on blur, unmount, and quit. Rust holds `ExitRequested` until the webview reports back, and a failed flush cancels the quit through `cancel_quit`. +An update restart is the exception. It reaches `ExitRequested` carrying +`RESTART_EXIT_CODE`, which Tauri refuses to prevent, so `lib.rs` returns before +the handshake rather than opening one it cannot honour. `installUpdate` in +`src/lib/updater.ts` awaits `flushPendingWrites` itself between +`downloadAndInstall` and `relaunch`, and a failed flush leaves the app running +on the installed bundle instead of restarting into it. + ### External-change reload guard A loader refresh replaces the buffer only when the buffer is clean and the @@ -284,8 +292,8 @@ into `attachments/`, and `write_external` writes outside the notes dir. ### The palette is the action surface `command-palette.tsx` holds search, tag filtering via `#`, new note, pin, tag -editing, rename, move, delete, reveal, settings, and reindex. New note-level -actions belong there rather than in new chrome. +editing, rename, move, delete, reveal, settings, reindex, and the update check. +New note-level actions belong there rather than in new chrome. `move`, `delete`, `rename`, and `tags` are sub-views of `PaletteView`. The tags view is the one place an action row does not dismiss the palette: toggling calls diff --git a/SPEC.md b/SPEC.md index 4d4be20d..334cdbfe 100644 --- a/SPEC.md +++ b/SPEC.md @@ -32,9 +32,11 @@ walkthrough is their only coverage. Run it under `pnpm dev`. - [x] 14. Type, then quit from the tray and again with ⌘Q → relaunch and the last keystrokes are on disk - [ ] 15. Install the first release carrying the updater, cut a second, relaunch - the installed copy → "version x.y.z is available" toast → install → - relaunches into the new version. ⌘K → "check for updates..." reports - either way. `pnpm dev` cannot cover this: the check is `PROD`-guarded. + the installed copy → "version x.y.z is available" toast → type, leave the + keystrokes unsaved, then install → relaunches into the new version with + those keystrokes on disk. ⌘K → "check for updates..." reports either way. + Only the development message is reachable under `pnpm dev`: the check is + `PROD`-guarded, so the install path needs two real releases. ## Deferred diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 85d17dc0..80ec5290 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -307,7 +307,15 @@ pub fn run() { // is held back so the webview can flush unsaved buffers; the frontend // answers by calling `quit_app`, and a timer covers the case where it // never does. - RunEvent::ExitRequested { api, .. } => { + RunEvent::ExitRequested { api, code, .. } => { + // An update restart arrives here too, and Tauri ignores + // `prevent_exit` for it, so the handshake below would be a promise + // this process cannot keep. `installUpdate` flushes before it calls + // `relaunch` instead. + if code == Some(tauri::RESTART_EXIT_CODE) { + return; + } + if app.state::().quitting.swap(true, Ordering::SeqCst) { return; } diff --git a/src/components/command-palette.tsx b/src/components/command-palette.tsx index 36103241..72c3e2fd 100644 --- a/src/components/command-palette.tsx +++ b/src/components/command-palette.tsx @@ -39,7 +39,7 @@ import { moveNote } from "@/data/move-note"; import { setNotePinned } from "@/data/pin-note"; import { reindexAll } from "@/data/reindex"; import { retitleNote } from "@/data/retitle-note"; -import { findUpdate, installUpdate } from "@/lib/updater"; +import { findUpdate, installUpdate, updatesSupported } from "@/lib/updater"; import { getSnippetParts } from "@/lib/utils/fts-snippet"; import { parseTagQuery } from "@/lib/utils/tag-query"; @@ -627,9 +627,16 @@ export function CommandPalette({ }); }, [runAction]); - // Unlike the launch check, this one was asked for, so it reports either way. + // Unlike the launch check, this one was asked for, so it reports either way, + // including the way a development build cannot report on: it never ran. const checkForUpdates = useCallback(() => { runAction(async () => { + if (!updatesSupported()) { + toast("update checks are off in development"); + + return; + } + const update = await findUpdate(); if (update === null) { @@ -642,8 +649,12 @@ export function CommandPalette({ action: { label: "install", onClick: () => { - installUpdate(update).catch(() => { - toast.error("could not install the update"); + installUpdate(update).catch((error: unknown) => { + toast.error( + error instanceof Error + ? error.message + : "could not install the update" + ); }); }, }, diff --git a/src/lib/updater.spec.ts b/src/lib/updater.spec.ts index 841226d4..1bd9575e 100644 --- a/src/lib/updater.spec.ts +++ b/src/lib/updater.spec.ts @@ -1,3 +1,4 @@ +import { Buffer } from "node:buffer"; import { readFileSync } from "node:fs"; import { join } from "node:path"; @@ -15,13 +16,31 @@ const config = JSON.parse( plugins: { updater: { endpoints: string[]; pubkey: string } }; }; +/** + * `tauri signer generate` emits the base64 of a minisign public key file: a + * comment line, then the base64 of 2 algorithm bytes, an 8-byte key ID, and a + * 32-byte ed25519 key. + */ +const [comment, key] = Buffer.from(config.plugins.updater.pubkey, "base64") + .toString("utf8") + .trim() + .split("\n"); + +const material = Buffer.from(key ?? "", "base64"); + describe("updater config", () => { - it("should carry a real minisign public key", () => { - const { pubkey } = config.plugins.updater; + it("should carry a whole minisign public key", () => { + expect(comment?.startsWith("untrusted comment:")).toBe(true); + expect(material).toHaveLength(42); + expect(material.subarray(0, 2).toString("utf8")).toBe("Ed"); + }); + + it("should carry key material the comment names", () => { + // minisign writes the ID little-endian in the key and hex in the comment, + // so a payload swapped for another key or cut short stops agreeing with it. + const id = Buffer.from(material.subarray(2, 10)).reverse().toString("hex"); - // `tauri signer generate` emits the base64 of a minisign public key file, - // which always opens with its "untrusted comment:" header. - expect(pubkey.startsWith("dW50cnVzdGVkIGNvbW1lbnQ6")).toBe(true); + expect(comment).toContain(id.toUpperCase()); }); it("should emit the artifacts the endpoint serves", () => { diff --git a/src/lib/updater.ts b/src/lib/updater.ts index 6248c18f..0d192f00 100644 --- a/src/lib/updater.ts +++ b/src/lib/updater.ts @@ -1,28 +1,47 @@ import { relaunch } from "@tauri-apps/plugin-process"; import { check, type Update } from "@tauri-apps/plugin-updater"; +import { flushPendingWrites } from "@/lib/pending-flush"; + +/** + * Whether this build can reach the updater at all. The endpoint that + * `latest.json` is published to only answers for a release, so a development + * build has nothing to ask and no bundle to replace. + */ +export function updatesSupported() { + return import.meta.env.PROD; +} + /** * Ask the release endpoint whether a newer version exists. Resolves to `null` - * when the app is current, and always in development, where the endpoint that - * `latest.json` is published to does not answer. + * when the app is current. Call it only when `updatesSupported()` holds. * * The resolved `Update` owns a native handle. Hand it to `installUpdate`, which * consumes it, or call its `close()` to let it go. A handle that is neither is * released when the app exits, which bounds the leak at one per check. */ export async function findUpdate() { - if (!import.meta.env.PROD) { - return null; - } - return await check(); } /** * Download the update, install it, and restart into it. Does not resolve on the * happy path: `relaunch` replaces the process. + * + * Throws when a buffer could not be written, which leaves the app running on + * the installed bundle: it takes effect the next time someone launches it. */ export async function installUpdate(update: Update) { await update.downloadAndInstall(); + + // Tauri ignores `prevent_exit` for a restart, so Rust cannot hold this one + // open for the quit handshake the way it holds a ⌘Q. Flushing here is what + // keeps the last keystrokes from dying with the old process. + if (!(await flushPendingWrites())) { + throw new Error( + "could not save your changes: the update will apply on next launch" + ); + } + await relaunch(); } diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 2d6857d6..87c5e3bd 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -20,7 +20,7 @@ import { getNotes } from "@/data/get-notes"; import { getTags } from "@/data/get-tags"; import { getNotesDir } from "@/data/notes-dir"; import { flushPendingWrites } from "@/lib/pending-flush"; -import { findUpdate, installUpdate } from "@/lib/updater"; +import { findUpdate, installUpdate, updatesSupported } from "@/lib/updater"; interface RootSearch { /** Set by a tag chip to open the palette already filtered to that tag. */ @@ -94,6 +94,10 @@ function RootLayout() { // someone over a network blip, and the palette offers a check that reports. useEffect(() => { const offerUpdate = async () => { + if (!updatesSupported()) { + return; + } + const update = await findUpdate(); if (update === null) { @@ -104,8 +108,12 @@ function RootLayout() { action: { label: "install", onClick: () => { - installUpdate(update).catch(() => { - toast.error("could not install the update"); + installUpdate(update).catch((error: unknown) => { + toast.error( + error instanceof Error + ? error.message + : "could not install the update" + ); }); }, }, From dbd951b908170d52975a66349ff74e92dfb4eaee Mon Sep 17 00:00:00 2001 From: jimmy-guzman Date: Fri, 21 Aug 2026 16:19:21 -0500 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=F0=9F=90=9B=20fix=20note=20tags=20t?= =?UTF-8?q?rggier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/notes/note-tags.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/notes/note-tags.tsx b/src/components/notes/note-tags.tsx index 310a4dd5..4b4f5e67 100644 --- a/src/components/notes/note-tags.tsx +++ b/src/components/notes/note-tags.tsx @@ -111,7 +111,7 @@ export function NoteTags({ allTags, onFilter, path, tags }: NoteTagsProps) { className="[&>svg:last-child]:hidden" render={