Compare commits

..

29 Commits

Author SHA1 Message Date
zhom 248927ae6f chore: linting 2026-03-28 14:05:45 +04:00
zhom 6d71dbc62c Merge pull request #255 from zhom/dependabot/npm_and_yarn/frontend-dependencies-9854c608ec
deps(deps): bump the frontend-dependencies group with 35 updates
2026-03-28 13:53:32 +04:00
dependabot[bot] 3f0029c778 deps(deps): bump the frontend-dependencies group with 35 updates
Bumps the frontend-dependencies group with 35 updates:

| Package | From | To |
| --- | --- | --- |
| [i18next](https://github.com/i18next/i18next) | `25.10.5` | `26.0.0` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.577.0` | `1.7.0` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.6.2` | `17.0.0` |
| [recharts](https://github.com/recharts/recharts) | `3.8.0` | `3.8.1` |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.2` |
| [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) | `3.1015.0` | `3.1019.0` |
| [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/s3-request-presigner) | `3.1015.0` | `3.1019.0` |
| [@aws-sdk/core](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/core) | `3.973.24` | `3.973.25` |
| [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-env) | `3.972.22` | `3.972.23` |
| [@aws-sdk/credential-provider-http](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-http) | `3.972.24` | `3.972.25` |
| [@aws-sdk/credential-provider-ini](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-ini) | `3.972.24` | `3.972.26` |
| [@aws-sdk/credential-provider-login](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-login) | `3.972.24` | `3.972.26` |
| [@aws-sdk/credential-provider-node](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-node) | `3.972.25` | `3.972.27` |
| [@aws-sdk/credential-provider-process](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-process) | `3.972.22` | `3.972.23` |
| [@aws-sdk/credential-provider-sso](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-sso) | `3.972.24` | `3.972.26` |
| [@aws-sdk/credential-provider-web-identity](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-web-identity) | `3.972.24` | `3.972.26` |
| [@aws-sdk/middleware-flexible-checksums](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/middleware-flexible-checksums) | `3.974.4` | `3.974.5` |
| [@aws-sdk/middleware-recursion-detection](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/middleware-recursion-detection) | `3.972.8` | `3.972.9` |
| [@aws-sdk/middleware-sdk-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/middleware-sdk-s3) | `3.972.24` | `3.972.26` |
| [@aws-sdk/middleware-user-agent](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/middleware-user-agent) | `3.972.25` | `3.972.26` |
| [@aws-sdk/nested-clients](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/nested-clients) | `3.996.14` | `3.996.16` |
| [@aws-sdk/region-config-resolver](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/region-config-resolver) | `3.972.9` | `3.972.10` |
| [@aws-sdk/signature-v4-multi-region](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/signature-v4-multi-region) | `3.996.12` | `3.996.14` |
| [@aws-sdk/token-providers](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/token-providers) | `3.1015.0` | `3.1019.0` |
| [@aws-sdk/util-user-agent-node](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/util-user-agent-node) | `3.973.11` | `3.973.12` |
| [@aws-sdk/xml-builder](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/xml-builder) | `3.972.15` | `3.972.16` |
| [@biomejs/cli-darwin-arm64](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-darwin-x64](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-linux-arm64-musl](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-linux-arm64](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-linux-x64-musl](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-linux-x64](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-win32-arm64](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |
| [@biomejs/cli-win32-x64](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.9` |


Updates `i18next` from 25.10.5 to 26.0.0
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v25.10.5...v26.0.0)

Updates `lucide-react` from 0.577.0 to 1.7.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.7.0/packages/lucide-react)

Updates `react-i18next` from 16.6.2 to 17.0.0
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/react-i18next/compare/v16.6.2...v17.0.0)

Updates `recharts` from 3.8.0 to 3.8.1
- [Release notes](https://github.com/recharts/recharts/releases)
- [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md)
- [Commits](https://github.com/recharts/recharts/compare/v3.8.0...v3.8.1)

Updates `@biomejs/biome` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `typescript` from 5.9.3 to 6.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.2)

Updates `@aws-sdk/client-s3` from 3.1015.0 to 3.1019.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1019.0/clients/client-s3)

Updates `@aws-sdk/s3-request-presigner` from 3.1015.0 to 3.1019.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/s3-request-presigner/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1019.0/packages/s3-request-presigner)

Updates `@aws-sdk/core` from 3.973.24 to 3.973.25
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/core/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/core)

Updates `@aws-sdk/credential-provider-env` from 3.972.22 to 3.972.23
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-env)

Updates `@aws-sdk/credential-provider-http` from 3.972.24 to 3.972.25
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-http/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-http)

Updates `@aws-sdk/credential-provider-ini` from 3.972.24 to 3.972.26
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-ini/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-ini)

Updates `@aws-sdk/credential-provider-login` from 3.972.24 to 3.972.26
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-login/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-login)

Updates `@aws-sdk/credential-provider-node` from 3.972.25 to 3.972.27
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-node/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-node)

Updates `@aws-sdk/credential-provider-process` from 3.972.22 to 3.972.23
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-process/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-process)

Updates `@aws-sdk/credential-provider-sso` from 3.972.24 to 3.972.26
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-sso/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-sso)

Updates `@aws-sdk/credential-provider-web-identity` from 3.972.24 to 3.972.26
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-web-identity/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-web-identity)

Updates `@aws-sdk/middleware-flexible-checksums` from 3.974.4 to 3.974.5
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/middleware-flexible-checksums/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/middleware-flexible-checksums)

Updates `@aws-sdk/middleware-recursion-detection` from 3.972.8 to 3.972.9
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/middleware-recursion-detection/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/middleware-recursion-detection)

Updates `@aws-sdk/middleware-sdk-s3` from 3.972.24 to 3.972.26
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/middleware-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/middleware-sdk-s3)

Updates `@aws-sdk/middleware-user-agent` from 3.972.25 to 3.972.26
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/middleware-user-agent/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/middleware-user-agent)

Updates `@aws-sdk/nested-clients` from 3.996.14 to 3.996.16
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages/nested-clients)

Updates `@aws-sdk/region-config-resolver` from 3.972.9 to 3.972.10
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/region-config-resolver/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/region-config-resolver)

Updates `@aws-sdk/signature-v4-multi-region` from 3.996.12 to 3.996.14
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages/signature-v4-multi-region)

Updates `@aws-sdk/token-providers` from 3.1015.0 to 3.1019.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/token-providers/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1019.0/packages/token-providers)

Updates `@aws-sdk/util-user-agent-node` from 3.973.11 to 3.973.12
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/util-user-agent-node/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/util-user-agent-node)

Updates `@aws-sdk/xml-builder` from 3.972.15 to 3.972.16
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/xml-builder/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/xml-builder)

Updates `@biomejs/cli-darwin-arm64` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-darwin-x64` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-linux-arm64-musl` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-linux-arm64` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-linux-x64-musl` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-linux-x64` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-win32-arm64` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

Updates `@biomejs/cli-win32-x64` from 2.4.8 to 2.4.9
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.9/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 26.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-dependencies
- dependency-name: lucide-react
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-dependencies
- dependency-name: react-i18next
  dependency-version: 17.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-dependencies
- dependency-name: recharts
  dependency-version: 3.8.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: typescript
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/client-s3"
  dependency-version: 3.1019.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/s3-request-presigner"
  dependency-version: 3.1019.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/core"
  dependency-version: 3.973.25
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.972.23
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-http"
  dependency-version: 3.972.25
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-ini"
  dependency-version: 3.972.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-login"
  dependency-version: 3.972.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-node"
  dependency-version: 3.972.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-process"
  dependency-version: 3.972.23
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-sso"
  dependency-version: 3.972.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/credential-provider-web-identity"
  dependency-version: 3.972.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/middleware-flexible-checksums"
  dependency-version: 3.974.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/middleware-recursion-detection"
  dependency-version: 3.972.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/middleware-sdk-s3"
  dependency-version: 3.972.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/middleware-user-agent"
  dependency-version: 3.972.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/nested-clients"
  dependency-version: 3.996.16
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/region-config-resolver"
  dependency-version: 3.972.10
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/signature-v4-multi-region"
  dependency-version: 3.996.14
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/token-providers"
  dependency-version: 3.1019.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/util-user-agent-node"
  dependency-version: 3.973.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@aws-sdk/xml-builder"
  dependency-version: 3.972.16
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-darwin-arm64"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-darwin-x64"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-linux-arm64-musl"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-linux-arm64"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-linux-x64-musl"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-linux-x64"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-win32-arm64"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
- dependency-name: "@biomejs/cli-win32-x64"
  dependency-version: 2.4.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: frontend-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 09:52:43 +00:00
zhom fff1fe7087 Merge pull request #254 from zhom/dependabot/cargo/src-tauri/rust-dependencies-23f0da4b4d
deps(rust)(deps): bump the rust-dependencies group in /src-tauri with 13 updates
2026-03-28 13:48:55 +04:00
dependabot[bot] 1c971c664f deps(rust)(deps): bump the rust-dependencies group
Bumps the rust-dependencies group in /src-tauri with 13 updates:

| Package | From | To |
| --- | --- | --- |
| [bzip2](https://github.com/trifectatechfoundation/bzip2-rs) | `0.5.2` | `0.6.1` |
| [uuid](https://github.com/uuid-rs/uuid) | `1.22.0` | `1.23.0` |
| [sha1](https://github.com/RustCrypto/hashes) | `0.10.6` | `0.11.0` |
| [tao](https://github.com/tauri-apps/tao) | `0.34.8` | `0.35.0` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.57` | `1.2.58` |
| [embed-resource](https://github.com/nabijaczleweli/rust-embed-resource) | `3.0.7` | `3.0.8` |
| libredox | `0.1.14` | `0.1.15` |
| [mio](https://github.com/tokio-rs/mio) | `1.1.1` | `1.2.0` |
| [num-conv](https://github.com/jhpratt/num-conv) | `0.2.0` | `0.2.1` |
| [rust_decimal](https://github.com/paupino/rust-decimal) | `1.40.0` | `1.41.0` |
| [simd-adler32](https://github.com/mcountryman/simd-adler32) | `0.3.8` | `0.3.9` |
| [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation) | `1.12.0` | `1.13.2` |
| [zune-jpeg](https://github.com/etemesi254/zune-image) | `0.5.14` | `0.5.15` |


Updates `bzip2` from 0.5.2 to 0.6.1
- [Release notes](https://github.com/trifectatechfoundation/bzip2-rs/releases)
- [Commits](https://github.com/trifectatechfoundation/bzip2-rs/compare/v0.5.2...v0.6.1)

Updates `uuid` from 1.22.0 to 1.23.0
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.22.0...v1.23.0)

Updates `sha1` from 0.10.6 to 0.11.0
- [Commits](https://github.com/RustCrypto/hashes/compare/sha1-v0.10.6...sha1-v0.11.0)

Updates `tao` from 0.34.8 to 0.35.0
- [Release notes](https://github.com/tauri-apps/tao/releases)
- [Changelog](https://github.com/tauri-apps/tao/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/tauri-apps/tao/compare/tao-v0.34.8...tao-v0.35)

Updates `cc` from 1.2.57 to 1.2.58
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.57...cc-v1.2.58)

Updates `embed-resource` from 3.0.7 to 3.0.8
- [Release notes](https://github.com/nabijaczleweli/rust-embed-resource/releases)
- [Commits](https://github.com/nabijaczleweli/rust-embed-resource/compare/v3.0.7...v3.0.8)

Updates `libredox` from 0.1.14 to 0.1.15

Updates `mio` from 1.1.1 to 1.2.0
- [Release notes](https://github.com/tokio-rs/mio/releases)
- [Changelog](https://github.com/tokio-rs/mio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/mio/compare/v1.1.1...v1.2.0)

Updates `num-conv` from 0.2.0 to 0.2.1
- [Commits](https://github.com/jhpratt/num-conv/compare/v0.2.0...v0.2.1)

Updates `rust_decimal` from 1.40.0 to 1.41.0
- [Release notes](https://github.com/paupino/rust-decimal/releases)
- [Changelog](https://github.com/paupino/rust-decimal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/paupino/rust-decimal/compare/1.40.0...1.41.0)

Updates `simd-adler32` from 0.3.8 to 0.3.9
- [Changelog](https://github.com/mcountryman/simd-adler32/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mcountryman/simd-adler32/commits/v0.3.9)

Updates `unicode-segmentation` from 1.12.0 to 1.13.2
- [Commits](https://github.com/unicode-rs/unicode-segmentation/compare/v1.12.0...v1.13.2)

Updates `zune-jpeg` from 0.5.14 to 0.5.15
- [Release notes](https://github.com/etemesi254/zune-image/releases)
- [Changelog](https://github.com/etemesi254/zune-image/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/etemesi254/zune-image/commits)

---
updated-dependencies:
- dependency-name: bzip2
  dependency-version: 0.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: uuid
  dependency-version: 1.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: sha1
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: tao
  dependency-version: 0.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: cc
  dependency-version: 1.2.58
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: embed-resource
  dependency-version: 3.0.8
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: libredox
  dependency-version: 0.1.15
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: mio
  dependency-version: 1.2.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: num-conv
  dependency-version: 0.2.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: rust_decimal
  dependency-version: 1.41.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: simd-adler32
  dependency-version: 0.3.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
- dependency-name: unicode-segmentation
  dependency-version: 1.13.2
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: rust-dependencies
- dependency-name: zune-jpeg
  dependency-version: 0.5.15
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rust-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 09:48:00 +00:00
zhom 0788797e3f Merge pull request #253 from zhom/dependabot/github_actions/github-actions-f059b8c920
ci(deps): bump the github-actions group with 8 updates
2026-03-28 13:22:06 +04:00
dependabot[bot] 8c338515b7 ci(deps): bump the github-actions group with 8 updates
Bumps the github-actions group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.3.1` | `6.0.2` |
| [google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml](https://github.com/google/osv-scanner-action) | `2.3.3` | `2.3.5` |
| [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) | `2.5.0` | `3.0.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.12.0` | `4.0.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.7.0` | `4.0.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.19.2` | `7.0.0` |
| [anomalyco/opencode](https://github.com/anomalyco/opencode) | `1.2.27` | `1.3.3` |
| [google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml](https://github.com/google/osv-scanner-action) | `2.3.3` | `2.3.5` |


Updates `actions/checkout` from 4.3.1 to 6.0.2
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v4.3.1...v6.0.2)

Updates `google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml` from 2.3.3 to 2.3.5
- [Release notes](https://github.com/google/osv-scanner-action/releases)
- [Commits](https://github.com/google/osv-scanner-action/compare/c5996e0193a3df57d695c1b8a1dec2a4c62e8730...c51854704019a247608d928f370c98740469d4b5)

Updates `dependabot/fetch-metadata` from 2.5.0 to 3.0.0
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/21025c705c08248db411dc16f3619e6b5f9ea21a...ffa630c65fa7e0ecfa0625b5ceda64399aea1b36)

Updates `docker/setup-buildx-action` from 3.12.0 to 4.0.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/8d2750c68a42422c14e847fe6c8ac0403b4cbd6f...4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd)

Updates `docker/login-action` from 3.7.0 to 4.0.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/c94ce9fb468520275223c153574b00df6fe4bcc9...b45d80f862d83dbcd57f89517bcf500b2ab88fb2)

Updates `docker/build-push-action` from 6.19.2 to 7.0.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/10e90e3645eae34f1e60eeb005ba3a3d33f178e8...d08e5c354a6adb9ed34480a06d141179aa583294)

Updates `anomalyco/opencode` from 1.2.27 to 1.3.3
- [Release notes](https://github.com/anomalyco/opencode/releases)
- [Commits](https://github.com/anomalyco/opencode/compare/4ee426ba549131c4903a71dfb6259200467aca81...54443bfb7e090ec3130dc972e689a3e5cc55a7f9)

Updates `google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml` from 2.3.3 to 2.3.5
- [Release notes](https://github.com/google/osv-scanner-action/releases)
- [Commits](https://github.com/google/osv-scanner-action/compare/c5996e0193a3df57d695c1b8a1dec2a4c62e8730...c51854704019a247608d928f370c98740469d4b5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml
  dependency-version: 2.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: dependabot/fetch-metadata
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: docker/login-action
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: docker/build-push-action
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: anomalyco/opencode
  dependency-version: 1.3.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml
  dependency-version: 2.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 09:05:04 +00:00
zhom a8c179fca7 docs: agents 2026-03-28 01:41:01 +04:00
zhom d0f436ce2d chore: commit doc changes directly and pretty discord notifications 2026-03-28 01:41:01 +04:00
zhom 4019701186 Merge pull request #252 from zhom/contributors-readme-action-7fGCZTC5jp
docs(contributor): contributors readme action update
2026-03-27 20:11:15 +04:00
github-actions[bot] 53f85abe24 docs(contributor): contrib-readme-action has updated readme 2026-03-27 16:08:11 +00:00
zhom 2aafb4c7a4 Merge pull request #249 from yb403/fix/sync-loop-circular-dependency
This fix prevents the file watcher from triggering a new sync when th…
2026-03-27 20:07:59 +04:00
zhom 00d5c655dc Merge pull request #251 from zhom/chore/update-flake-0.18.1
chore: update flake.nix for v0.18.1
2026-03-25 03:39:31 +04:00
zhom b12a704d9f Merge pull request #250 from zhom/docs/release-0.18.1
docs: release notes for v0.18.1
2026-03-25 03:39:20 +04:00
github-actions[bot] 0e134fd145 chore: update flake.nix for v0.18.1 [skip ci] 2026-03-24 23:08:33 +00:00
github-actions[bot] adcdc91de2 docs: update CHANGELOG.md and README.md for v0.18.1 [skip ci] 2026-03-24 23:08:31 +00:00
yb 880014d4c4 chore: fix linting and formatting 2026-03-24 22:50:28 +01:00
zhom 71f367f0ae docs: cleanup 2026-03-25 01:36:43 +04:00
zhom daa001cdf2 chore: version bump 2026-03-25 01:05:26 +04:00
zhom 17056360ab chore: require ai disclosure 2026-03-25 01:01:16 +04:00
zhom 80d5b77a80 chore: redeploy web on new release 2026-03-25 00:54:43 +04:00
zhom 701605fa73 chore: fix e2e in pr requests 2026-03-25 00:52:48 +04:00
zhom 19cb24f67f chore: issues get stale after 30 days 2026-03-25 00:33:20 +04:00
zhom c3fec3d095 docs: agents.md 2026-03-24 23:58:33 +04:00
zhom bb8b6ea0b7 chore: better issue validation 2026-03-24 23:58:21 +04:00
zhom a6dfc5664b refactor: run docker workflow on release 2026-03-24 21:12:52 +04:00
yb 001a292185 This fix prevents the file watcher from triggering a new sync when the client updates the last_sync timestamp in metadata.json. 2026-03-24 13:20:28 +01:00
github-actions[bot] c7d7ff19a7 chore: update flake.nix for v0.18.0 [skip ci] (#247)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-24 06:59:11 +00:00
zhom aec05fb725 docs: new star history url 2026-03-24 09:29:03 +04:00
35 changed files with 935 additions and 395 deletions
+7
View File
@@ -10,4 +10,11 @@
- [ ] Read [CONTRIBUTING.md](https://github.com/zhom/donutbrowser/blob/main/CONTRIBUTING.md)
- [ ] Ran `pnpm format && pnpm lint && pnpm test` locally and it passes
- [ ] I tested the changes myself by running the app locally
- [ ] Updated translations in all locale files (if UI text changed)
## AI usage
- [ ] I used AI to help write this PR
<!-- If you checked the box above, briefly explain how AI was used (e.g. "generated the test", "wrote the initial implementation", "full PR"). -->
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Set up pnpm package manager
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 #v4.4.0
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Contribute List
uses: akhilmhdh/contributors-readme-action@83ea0b4f1ac928fbfe88b9e8460a932a528eb79f #v2.3.11
env:
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
security-scan:
name: Security Vulnerability Scan
if: github.repository == 'zhom/donutbrowser' && github.actor == 'dependabot[bot]'
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c5996e0193a3df57d695c1b8a1dec2a4c62e8730" # v2.3.3
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c51854704019a247608d928f370c98740469d4b5" # v2.3.5
with:
scan-args: |-
-r
@@ -69,7 +69,7 @@ jobs:
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a #v2.5.0
uses: dependabot/fetch-metadata@ffa630c65fa7e0ecfa0625b5ceda64399aea1b36 #v3.0.0
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Enable auto-merge for minor and patch updates
+14 -12
View File
@@ -1,12 +1,16 @@
name: Build and Push donut-sync Docker Image
on:
release:
types: [published]
push:
branches: [main]
paths:
- "donut-sync/**"
workflow_call:
inputs:
tag:
description: "Docker tag (e.g., v1.0.0)"
required: true
type: string
workflow_dispatch:
inputs:
tag:
@@ -26,13 +30,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f #v3
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd #v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 #v3
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -41,26 +45,24 @@ jobs:
id: tags
run: |
TAGS=""
INPUT_TAG="${{ inputs.tag }}"
if [ "${{ github.event_name }}" = "release" ]; then
# Stable release: tag with version and latest
VERSION="${{ github.event.release.tag_name }}"
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION}"
if [ -n "$INPUT_TAG" ]; then
# Called from release workflow or manual dispatch
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${INPUT_TAG}"
TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
elif [ "${{ github.event_name }}" = "push" ]; then
# Push to main (nightly): tag with nightly and commit SHA
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly"
TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${SHORT_SHA}"
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tag }}"
fi
echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
echo "Tags: ${TAGS}"
- name: Build and push Docker image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 #v6
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 #v7.0.0
with:
context: .
file: ./donut-sync/Dockerfile
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Install Nix
uses: cachix/install-nix-action@a6f7623b2e2401f485f1eead77ced45bd99b09b0 #v31
+118 -21
View File
@@ -21,6 +21,9 @@ jobs:
if: github.repository == 'zhom/donutbrowser' && github.event_name == 'issues'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Check if first-time contributor
id: check-first-time
env:
@@ -37,6 +40,67 @@ jobs:
echo "is_first_time=false" >> $GITHUB_OUTPUT
fi
- name: Build repo context and find related files
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
run: |
# Read project guidelines (contains repo structure)
cp CLAUDE.md /tmp/repo-context.txt
printf '%s' "$ISSUE_TITLE" > /tmp/issue-title.txt
printf '%s' "${ISSUE_BODY:-}" > /tmp/issue-body.txt
# List all source files for the AI to pick from
find . -type f \( -name "*.rs" -o -name "*.ts" -o -name "*.tsx" \) \
! -path "*/node_modules/*" ! -path "*/target/*" ! -path "*/.next/*" ! -path "*/dist/*" \
! -path "*/.git/*" ! -path "*/gen/*" ! -path "*/data/*" \
| sed 's|^\./||' | sort > /tmp/all-source-files.txt
- name: Select relevant files with AI
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
run: |
PAYLOAD=$(jq -n \
--rawfile title /tmp/issue-title.txt \
--rawfile body /tmp/issue-body.txt \
--rawfile files /tmp/all-source-files.txt \
'{
model: "anthropic/claude-opus-4.6",
messages: [
{
role: "system",
content: "You are a file selector for Donut Browser (Tauri + Next.js + Rust anti-detect browser). Given an issue and a list of source files, output ONLY the 10 most likely relevant file paths, one per line. No explanations, no numbering, just paths."
},
{
role: "user",
content: ("Issue: " + $title + "\n\n" + $body + "\n\nFiles:\n" + $files)
}
]
}')
RESPONSE=$(curl -fsSL https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d "$PAYLOAD")
jq -r '.choices[0].message.content // empty' <<< "$RESPONSE" > /tmp/selected-files.txt
# Read the selected files in full (skip binary files)
echo "" > /tmp/file-contents.txt
while IFS= read -r filepath; do
filepath=$(echo "$filepath" | xargs)
[ -z "$filepath" ] && continue
if [ -f "$filepath" ] && file --mime "$filepath" | grep -q "text/"; then
echo "=== $filepath ===" >> /tmp/file-contents.txt
cat "$filepath" >> /tmp/file-contents.txt
echo "" >> /tmp/file-contents.txt
fi
done < /tmp/selected-files.txt
# Cap total context at 100KB
head -c 100000 /tmp/file-contents.txt > /tmp/file-context.txt
- name: Analyze issue with AI
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
@@ -50,25 +114,24 @@ jobs:
GREETING='This is a first-time contributor. Start your comment with: "Thanks for opening your first issue!"'
fi
# Write all user content to files to avoid shell escaping issues
printf '%s' "$ISSUE_TITLE" > /tmp/issue-title.txt
printf '%s' "${ISSUE_BODY:-}" > /tmp/issue-body.txt
printf '%s' "$ISSUE_AUTHOR" > /tmp/issue-author.txt
printf '%s' "$GREETING" > /tmp/greeting.txt
# Build the JSON payload entirely in jq — never interpolate user content in shell
PAYLOAD=$(jq -n \
--rawfile title /tmp/issue-title.txt \
--rawfile body /tmp/issue-body.txt \
--rawfile author /tmp/issue-author.txt \
--rawfile greeting /tmp/greeting.txt \
--rawfile repo_context /tmp/repo-context.txt \
--rawfile context /tmp/file-context.txt \
'{
model: "z-ai/glm-5",
max_tokens: 1024,
model: "anthropic/claude-opus-4.6",
messages: [
{
role: "system",
content: "You are a triage bot for Donut Browser (open-source anti-detect browser, Tauri + Next.js + Rust).\n\nAnalyze the issue and produce a single concise comment. Format:\n\n1. One sentence acknowledging what the user wants.\n2. A short **Action items** list - what specific info is missing or what the user should do next. Only include items that are actually missing. If the issue is complete, say so and skip this section.\n3. Suggest a label at the very end of your response on its own line in the exact format: Label: bug OR Label: enhancement\n\nRules:\n- Be brief. No filler, no generic tips, no templates.\n- If it is a bug report, check for: reproduction steps, OS/version, error messages. Only ask for what is actually missing.\n- If it is a feature request, check for: clear description of desired behavior, use case. Only ask for what is actually missing.\n- If the issue already has everything needed, just acknowledge it.\n- Never exceed 6 items total."
content: ("You are a triage bot for Donut Browser, an open-source anti-detect browser (Tauri desktop app: Rust backend + Next.js frontend).\n\nProject guidelines and structure:\n" + $repo_context + "\n\nYou have access to relevant source files for context. Use them to give specific, actionable advice.\n\nAnalyze the issue and produce a single comment. Format:\n\n1. One sentence acknowledging the issue.\n2. **Possible cause** - Based on the source code, briefly explain what might be going wrong and which files are involved. Be specific (mention file names, function names, line ranges if possible).\n3. **Action items** - What specific info is missing or what the user should try. Only include items that are actually missing.\n - For bug reports: if logs are needed, tell the user EXACTLY how to get them:\n - macOS app logs: `~/Library/Logs/Donut Browser/`\n - Linux app logs: `~/.local/share/DonutBrowser/logs/`\n - Windows app logs: `%APPDATA%\\DonutBrowser\\logs\\`\n - Sync server logs: `docker logs <container>` or check the server console\n - Provide a ready-to-run shell command when possible.\n - For self-hosted sync issues: check if the user is using the latest Docker image (`docker pull donutbrowser/donut-sync:latest`).\n4. Suggest a label: `Label: bug` or `Label: enhancement` on its own line.\n\nRules:\n- Be brief but specific. Reference actual code when possible.\n- If the issue already has everything needed, just acknowledge it and point to the likely cause.\n- Never exceed 15 lines.")
},
{
role: "user",
@@ -76,7 +139,8 @@ jobs:
(if ($greeting | length) > 0 then $greeting + "\n\n" else "" end) +
"Analyze this issue:\n\nTitle: " + $title +
"\nAuthor: " + $author +
"\n\nBody:\n" + $body
"\n\nBody:\n" + $body +
"\n\nRelevant source files:\n" + $context
)
}
]
@@ -87,7 +151,6 @@ jobs:
-H "Content-Type: application/json" \
-d "$PAYLOAD")
# Extract the comment using jq — never parse AI output in shell
jq -r '.choices[0].message.content // empty' <<< "$RESPONSE" > /tmp/ai-comment.txt
if [ ! -s /tmp/ai-comment.txt ]; then
@@ -102,7 +165,6 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
# Extract and strip the label line before posting
LABEL=$(grep -oP '^Label:\s*\K.*' /tmp/ai-comment.txt | tail -1 | tr '[:upper:]' '[:lower:]' | xargs)
sed -i '/^Label:/d' /tmp/ai-comment.txt
@@ -118,6 +180,9 @@ jobs:
if: github.repository == 'zhom/donutbrowser' && github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Check if first-time contributor
id: check-first-time
env:
@@ -134,6 +199,40 @@ jobs:
echo "is_first_time=false" >> $GITHUB_OUTPUT
fi
- name: Gather PR context
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
# Get changed files list
gh api "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" \
--jq '.[] | "- \(.filename) (\(.status)) +\(.additions)/-\(.deletions)"' \
> /tmp/pr-files.txt
# Get the actual diff
gh api "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" \
--header "Accept: application/vnd.github.diff" \
> /tmp/pr-diff-full.txt 2>/dev/null || true
head -c 20000 /tmp/pr-diff-full.txt > /tmp/pr-diff.txt
# Get CONTRIBUTING.md and README.md for context
cat CONTRIBUTING.md > /tmp/contributing.txt 2>/dev/null || echo "Not found" > /tmp/contributing.txt
head -50 README.md > /tmp/readme.txt 2>/dev/null || echo "Not found" > /tmp/readme.txt
# Read project guidelines (contains repo structure)
cp CLAUDE.md /tmp/repo-context.txt
# Read full contents of all changed files (skip binary)
echo "" > /tmp/related-file-contents.txt
gh api "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' | while IFS= read -r filepath; do
if [ -f "$filepath" ] && file --mime "$filepath" | grep -q "text/"; then
echo "=== $filepath (full file) ===" >> /tmp/related-file-contents.txt
cat "$filepath" >> /tmp/related-file-contents.txt
echo "" >> /tmp/related-file-contents.txt
fi
done
head -c 100000 /tmp/related-file-contents.txt > /tmp/pr-file-context.txt
- name: Analyze PR with AI
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -151,7 +250,6 @@ jobs:
GREETING='This is a first-time contributor. Start your comment with: "Thanks for your first PR!"'
fi
# Write all user content to files to avoid shell escaping issues
printf '%s' "$PR_TITLE" > /tmp/pr-title.txt
printf '%s' "${PR_BODY:-}" > /tmp/pr-body.txt
printf '%s' "$PR_AUTHOR" > /tmp/pr-author.txt
@@ -159,11 +257,6 @@ jobs:
printf '%s' "$PR_HEAD" > /tmp/pr-head.txt
printf '%s' "$GREETING" > /tmp/greeting.txt
gh api "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" \
--jq '.[] | "- \(.filename) (\(.status)) +\(.additions)/-\(.deletions)"' \
> /tmp/pr-files.txt
# Build the JSON payload entirely in jq — never interpolate user content in shell
PAYLOAD=$(jq -n \
--rawfile title /tmp/pr-title.txt \
--rawfile body /tmp/pr-body.txt \
@@ -171,14 +264,17 @@ jobs:
--rawfile base /tmp/pr-base.txt \
--rawfile head /tmp/pr-head.txt \
--rawfile files /tmp/pr-files.txt \
--rawfile diff /tmp/pr-diff.txt \
--rawfile greeting /tmp/greeting.txt \
--rawfile repo_context /tmp/repo-context.txt \
--rawfile contributing /tmp/contributing.txt \
--rawfile file_context /tmp/pr-file-context.txt \
'{
model: "z-ai/glm-5",
max_tokens: 1024,
model: "anthropic/claude-opus-4.6",
messages: [
{
role: "system",
content: "You are a review bot for Donut Browser (open-source anti-detect browser, Tauri + Next.js + Rust).\n\nReview this PR and produce a single concise comment. Format:\n\n1. One sentence summarizing what this PR does.\n2. **Action items** - only list things that actually need to be fixed or addressed. If the PR looks good, say so and skip this section.\n\nRules:\n- Be brief. No filler, no praise padding.\n- Focus on: bugs, security issues, missing edge cases, breaking changes.\n- If the PR touches UI text or adds new strings, remind to update translation files in src/i18n/locales/.\n- If the PR modifies Tauri commands, remind to check the unused-commands test.\n- Do not nitpick style or formatting - the project has automated linting.\n- Never exceed 8 lines total."
content: ("You are a code review bot for Donut Browser, an open-source anti-detect browser (Tauri desktop app: Rust backend + Next.js frontend).\n\nProject guidelines and structure:\n" + $repo_context + "\n\nContributing guidelines:\n" + $contributing + "\n\nYou have access to the full changed files and the diff. Use them to give a substantive review.\n\nReview this PR and produce a single comment. Format:\n\n1. One sentence summarizing what this PR does and whether the approach is sound.\n2. **Code review** - Specific observations about the actual code changes. Mention file names and what you see in the diff. Look for:\n - Bugs or logic errors in the changed code\n - Security issues (SQL injection, path traversal, XSS, command injection)\n - Missing error handling or edge cases\n - Breaking changes to existing APIs or behavior\n - If UI text was added/changed, check if all 7 translation files (en, es, fr, ja, pt, ru, zh) in src/i18n/locales/ were updated\n - If Tauri commands were added/removed, the unused-commands test in lib.rs needs updating\n3. **Suggestions** - Concrete improvements if any. Skip if the PR looks good.\n\nRules:\n- Be substantive. Review the actual diff, not just the description.\n- Do NOT nitpick formatting or style — the project has automated linting (biome + clippy + rustfmt).\n- Do NOT just summarize the PR description back to the user — they wrote it, they know what it says.\n- If the PR is good, say so briefly.\n- Never exceed 20 lines.")
},
{
role: "user",
@@ -188,7 +284,9 @@ jobs:
"\nAuthor: " + $author +
"\nBase: " + $base + " <- Head: " + $head +
"\n\nDescription:\n" + $body +
"\n\nChanged files:\n" + $files
"\n\nChanged files:\n" + $files +
"\n\nDiff:\n" + $diff +
"\n\nFull file contents:\n" + $file_context
)
}
]
@@ -199,7 +297,6 @@ jobs:
-H "Content-Type: application/json" \
-d "$PAYLOAD")
# Extract the comment using jq — never parse AI output in shell
jq -r '.choices[0].message.content // empty' <<< "$RESPONSE" > /tmp/ai-comment.txt
if [ ! -s /tmp/ai-comment.txt ]; then
@@ -227,10 +324,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Run opencode
uses: anomalyco/opencode/github@4ee426ba549131c4903a71dfb6259200467aca81 #v1.2.27
uses: anomalyco/opencode/github@54443bfb7e090ec3130dc972e689a3e5cc55a7f9 #v1.3.3
env:
ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
run: git config --global core.autocrlf false
- name: Checkout repository code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Set up pnpm package manager
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 #v4.4.0
+1 -1
View File
@@ -41,7 +41,7 @@ jobs:
run: git config --global core.autocrlf false
- name: Checkout repository code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Set up pnpm package manager
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 #v4.4.0
+2 -2
View File
@@ -46,7 +46,7 @@ jobs:
scan-scheduled:
name: Scheduled Security Scan
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c5996e0193a3df57d695c1b8a1dec2a4c62e8730" # v2.3.3
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c51854704019a247608d928f370c98740469d4b5" # v2.3.5
with:
scan-args: |-
-r
@@ -58,7 +58,7 @@ jobs:
scan-pr:
name: PR Security Scan
if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c5996e0193a3df57d695c1b8a1dec2a4c62e8730" # v2.3.3
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c51854704019a247608d928f370c98740469d4b5" # v2.3.5
with:
scan-args: |-
-r
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
security-scan:
name: Security Vulnerability Scan
if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c5996e0193a3df57d695c1b8a1dec2a4c62e8730" # v2.3.3
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c51854704019a247608d928f370c98740469d4b5" # v2.3.5
with:
scan-args: |-
-r
@@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
fetch-depth: 0
+107 -28
View File
@@ -20,7 +20,7 @@ jobs:
security-scan:
if: github.repository == 'zhom/donutbrowser'
name: Security Vulnerability Scan
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c5996e0193a3df57d695c1b8a1dec2a4c62e8730" # v2.3.3
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c51854704019a247608d928f370c98740469d4b5" # v2.3.5
with:
scan-args: |-
-r
@@ -105,7 +105,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 #v4.4.0
@@ -237,8 +237,9 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
ref: main
fetch-depth: 0
@@ -368,16 +369,28 @@ jobs:
/<!-- install-links-end -->/!d
}' README.md
- name: Commit release docs
- name: Create release docs PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |
VERSION="${TAG#v}"
BRANCH="docs/release-${VERSION}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
git add CHANGELOG.md README.md
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "docs: update CHANGELOG.md and README.md for ${{ github.ref_name }} [skip ci]"
git push origin main
git commit -m "docs: update CHANGELOG.md and README.md for ${TAG} [skip ci]"
git push origin "$BRANCH"
gh pr create \
--title "docs: release notes for ${TAG}" \
--body "Automated update of CHANGELOG.md and README.md download links for ${TAG}." \
--base main \
--head "$BRANCH"
gh pr merge "$BRANCH" --squash --admin
fi
- name: Update release notes
@@ -389,26 +402,98 @@ jobs:
notify-discord:
if: github.repository == 'zhom/donutbrowser'
needs: [release]
needs: [release, changelog]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
ref: main
fetch-depth: 0
- name: Generate changelog summary
env:
TAG: ${{ github.ref_name }}
run: |
PREV_TAG=$(git tag --sort=-version:refname \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| grep -v "^${TAG}$" \
| head -n 1)
if [ -z "$PREV_TAG" ]; then
PREV_TAG=$(git rev-list --max-parents=0 HEAD)
fi
strip_prefix() { echo "$1" | sed -E 's/^[a-z]+(\([^)]*\))?: //'; }
CHANGES=""
while IFS= read -r msg; do
[ -z "$msg" ] && continue
case "$msg" in
feat\(*\):*|feat:*) CHANGES="${CHANGES}• $(strip_prefix "$msg")\n" ;;
fix\(*\):*|fix:*) CHANGES="${CHANGES}• $(strip_prefix "$msg")\n" ;;
refactor\(*\):*|refactor:*) CHANGES="${CHANGES}• $(strip_prefix "$msg")\n" ;;
perf\(*\):*|perf:*) CHANGES="${CHANGES}• $(strip_prefix "$msg")\n" ;;
esac
done < <(git log --pretty=format:"%s" "${PREV_TAG}..${TAG}" --no-merges)
# Truncate to fit Discord embed (max 4096 chars)
if [ ${#CHANGES} -gt 3900 ]; then
CHANGES="${CHANGES:0:3900}\n..."
fi
if [ -z "$CHANGES" ]; then
CHANGES="See the full changelog on GitHub."
fi
printf '%s' "$CHANGES" > /tmp/discord-changes.txt
- name: Send Discord notification
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_STABLE_WEBHOOK_URL }}
TAG: ${{ github.ref_name }}
run: |
VERSION="${GITHUB_REF_NAME}"
VERSION="${TAG}"
RELEASE_URL="https://github.com/${GITHUB_REPOSITORY}/releases/tag/${VERSION}"
CHANGES=$(cat /tmp/discord-changes.txt)
curl -fsSL -H "Content-Type: application/json" \
-d "{
\"embeds\": [{
\"title\": \"Donut Browser ${VERSION} Released\",
\"url\": \"${RELEASE_URL}\",
\"description\": \"A new stable release of Donut Browser is available.\",
\"color\": 5814783
# Build JSON with jq to handle escaping
PAYLOAD=$(jq -n \
--arg title "Donut Browser ${VERSION} Released" \
--arg url "$RELEASE_URL" \
--arg changes "$CHANGES" \
--arg dl_mac_arm "https://github.com/'"${GITHUB_REPOSITORY}"'/releases/download/'"${VERSION}"'/Donut_'"${VERSION#v}"'_aarch64.dmg" \
--arg dl_mac_intel "https://github.com/'"${GITHUB_REPOSITORY}"'/releases/download/'"${VERSION}"'/Donut_'"${VERSION#v}"'_x64.dmg" \
--arg dl_win "https://github.com/'"${GITHUB_REPOSITORY}"'/releases/download/'"${VERSION}"'/Donut_'"${VERSION#v}"'_x64-setup.exe" \
--arg dl_linux "https://github.com/'"${GITHUB_REPOSITORY}"'/releases/download/'"${VERSION}"'/Donut_'"${VERSION#v}"'_amd64.AppImage" \
'{
embeds: [{
title: $title,
url: $url,
description: $changes,
color: 5814783,
fields: [
{ name: "Download", value: ("[macOS (Apple Silicon)](" + $dl_mac_arm + ") · [macOS (Intel)](" + $dl_mac_intel + ")\n[Windows x64](" + $dl_win + ") · [Linux x64](" + $dl_linux + ")"), inline: false }
],
footer: { text: "donutbrowser.com" }
}]
}" \
"$DISCORD_WEBHOOK_URL"
}')
curl -fsSL -H "Content-Type: application/json" -d "$PAYLOAD" "$DISCORD_WEBHOOK_URL"
deploy-website:
if: github.repository == 'zhom/donutbrowser'
needs: [release]
runs-on: ubuntu-latest
steps:
- name: Trigger Cloudflare Pages deployment
run: curl -fsSL -X POST "${{ secrets.CLOUDFLARE_WEB_DEPLOYMENT_HOOK }}"
docker:
if: github.repository == 'zhom/donutbrowser'
needs: [release]
uses: ./.github/workflows/docker-sync.yml
with:
tag: ${{ github.ref_name }}
secrets: inherit
update-flake:
if: github.repository == 'zhom/donutbrowser'
@@ -418,7 +503,7 @@ jobs:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
ref: main
@@ -435,19 +520,13 @@ jobs:
echo "Downloading x86_64 AppImage..."
curl -fsSL -o /tmp/amd64.AppImage "$AMD64_URL" || { echo "x86_64 AppImage not found"; exit 1; }
AMD64_HASH=$(nix-hash --type sha256 --base32 --flat /tmp/amd64.AppImage 2>/dev/null || sha256sum /tmp/amd64.AppImage | awk '{print $1}')
echo "Downloading aarch64 AppImage..."
curl -fsSL -o /tmp/aarch64.AppImage "$AARCH64_URL" || { echo "aarch64 AppImage not found"; exit 1; }
AARCH64_HASH=$(nix-hash --type sha256 --base32 --flat /tmp/aarch64.AppImage 2>/dev/null || sha256sum /tmp/aarch64.AppImage | awk '{print $1}')
# Convert to SRI format (sha256-<base64>) if we got hex
if echo "$AMD64_HASH" | grep -qE '^[0-9a-f]{64}$'; then
AMD64_HASH="sha256-$(echo "$AMD64_HASH" | xxd -r -p | base64 | tr -d '\n')"
fi
if echo "$AARCH64_HASH" | grep -qE '^[0-9a-f]{64}$'; then
AARCH64_HASH="sha256-$(echo "$AARCH64_HASH" | xxd -r -p | base64 | tr -d '\n')"
fi
# Compute SRI hashes (sha256-<base64>)
AMD64_HASH="sha256-$(sha256sum /tmp/amd64.AppImage | awk '{print $1}' | xxd -r -p | base64 | tr -d '\n')"
AARCH64_HASH="sha256-$(sha256sum /tmp/aarch64.AppImage | awk '{print $1}' | xxd -r -p | base64 | tr -d '\n')"
echo "AMD64_HASH=${AMD64_HASH}" >> "$GITHUB_ENV"
echo "AARCH64_HASH=${AARCH64_HASH}" >> "$GITHUB_ENV"
@@ -493,4 +572,4 @@ jobs:
--body "Automated update of flake.nix with new AppImage hashes for v${VERSION}." \
--base main \
--head "$BRANCH"
gh pr merge "$BRANCH" --auto --squash
gh pr merge "$BRANCH" --squash --admin
+30 -12
View File
@@ -19,7 +19,7 @@ jobs:
security-scan:
if: github.repository == 'zhom/donutbrowser'
name: Security Vulnerability Scan
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c5996e0193a3df57d695c1b8a1dec2a4c62e8730" # v2.3.3
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c51854704019a247608d928f370c98740469d4b5" # v2.3.5
with:
scan-args: |-
-r
@@ -104,7 +104,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 #v4.4.0
@@ -248,7 +248,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Generate nightly tag
id: tag
@@ -345,6 +345,14 @@ jobs:
--notes-file /tmp/nightly-notes.md \
--prerelease
deploy-website:
if: github.repository == 'zhom/donutbrowser'
needs: [update-nightly-release]
runs-on: ubuntu-latest
steps:
- name: Trigger Cloudflare Pages deployment
run: curl -fsSL -X POST "${{ secrets.CLOUDFLARE_WEB_DEPLOYMENT_HOOK }}"
notify-discord:
if: github.repository == 'zhom/donutbrowser'
needs: [update-nightly-release]
@@ -356,14 +364,24 @@ jobs:
run: |
COMMIT_SHORT=$(echo "${GITHUB_SHA}" | cut -c1-7)
RELEASE_URL="https://github.com/${GITHUB_REPOSITORY}/releases/tag/nightly"
COMMIT_URL="https://github.com/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}"
curl -fsSL -H "Content-Type: application/json" \
-d "{
\"embeds\": [{
\"title\": \"Donut Browser Nightly Updated\",
\"url\": \"${RELEASE_URL}\",
\"description\": \"A new nightly build is available (${COMMIT_SHORT}).\",
\"color\": 16752128
PAYLOAD=$(jq -n \
--arg title "Donut Browser Nightly (${COMMIT_SHORT})" \
--arg url "$RELEASE_URL" \
--arg commit_url "$COMMIT_URL" \
--arg commit_short "$COMMIT_SHORT" \
'{
embeds: [{
title: $title,
url: $url,
color: 16752128,
fields: [
{ name: "Commit", value: ("[" + $commit_short + "](" + $commit_url + ")"), inline: true },
{ name: "Download", value: ("[Nightly Release](" + $url + ")"), inline: true }
],
footer: { text: "donutbrowser.com" }
}]
}" \
"$DISCORD_WEBHOOK_URL"
}')
curl -fsSL -H "Content-Type: application/json" -d "$PAYLOAD" "$DISCORD_WEBHOOK_URL"
+1 -1
View File
@@ -21,6 +21,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Spell Check Repo
uses: crate-ci/typos@631208b7aac2daa8b707f55e7331f9112b0e062d #v1.44.0
+4 -2
View File
@@ -16,7 +16,9 @@ jobs:
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "This issue has been inactive for 60 days. Please respond to keep it open."
stale-pr-message: "This pull request has been inactive for 60 days. Please respond to keep it open."
stale-issue-message: "This issue has been inactive for 30 days. Please respond to keep it open."
stale-pr-message: "This pull request has been inactive for 30 days. Please respond to keep it open."
stale-issue-label: "stale"
stale-pr-label: "stale"
days-before-stale: 30
days-before-close: 7
+2 -2
View File
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v6.0.2
- name: Install pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 #v4.4.0
@@ -73,7 +73,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v6.0.2
- name: Start MinIO
run: |
+39
View File
@@ -37,6 +37,7 @@
"codesign",
"codesigning",
"commitish",
"coreutils",
"Crashpad",
"CTYPE",
"daijro",
@@ -58,6 +59,7 @@
"doctest",
"doesn",
"domcontentloaded",
"dont",
"donutbrowser",
"doorhanger",
"dpkg",
@@ -70,21 +72,31 @@
"esbuild",
"etree",
"fetchurl",
"findutils",
"firstrun",
"flate",
"fontconfig",
"freetype",
"fribidi",
"frontmost",
"fsprogs",
"geoip",
"getcwd",
"gettimezone",
"gifs",
"globset",
"gnugrep",
"gnumake",
"gnused",
"GOPATH",
"gsettings",
"harfbuzz",
"healthreport",
"hiddenimports",
"hkcu",
"hooksconfig",
"hookspath",
"hostable",
"Hoverable",
"icns",
"idlelib",
@@ -110,13 +122,33 @@
"libayatana",
"libc",
"libcairo",
"libdrm",
"libfuse",
"libgbm",
"libgdk",
"libglib",
"libglvnd",
"libgpg",
"libpango",
"librsvg",
"libsoup",
"libwebkit",
"libx",
"libxcb",
"libxcomposite",
"libxcursor",
"libxdamage",
"libxdo",
"libxext",
"libxfixes",
"libxi",
"libxinerama",
"libxkbcommon",
"libxrandr",
"libxrender",
"libxscrnsaver",
"libxshmfence",
"libxtst",
"localtime",
"lpdw",
"lxml",
@@ -134,6 +166,8 @@
"msys",
"muda",
"mypy",
"nixos",
"nixpkgs",
"noarchive",
"nobrowse",
"noconfirm",
@@ -143,9 +177,11 @@
"nomount",
"norestart",
"NSIS",
"nspr",
"ntfs",
"ntlm",
"numpy",
"numtide",
"objc",
"oneshot",
"opencode",
@@ -156,6 +192,7 @@
"oscpu",
"outpath",
"OVPN",
"pango",
"passout",
"patchelf",
"pathex",
@@ -163,12 +200,14 @@
"peerconnection",
"PHANDLER",
"pids",
"pipefail",
"pixbuf",
"pkexec",
"pkgs",
"pkill",
"plasmohq",
"platformdirs",
"pname",
"prefs",
"presign",
"PRIO",
+48
View File
@@ -1,5 +1,53 @@
# Project Guidelines
> **IMPORTANT**: CLAUDE.md and AGENTS.md must always be identical. If you update one, update the other.
> After significant changes (new modules, renamed files, new directories), re-evaluate the Repository Structure below and update it if needed.
## Repository Structure
```
donutbrowser/
├── src/ # Next.js frontend
│ ├── app/ # App router (page.tsx, layout.tsx)
│ ├── components/ # 50+ React components (dialogs, tables, UI)
│ ├── hooks/ # Event-driven React hooks
│ ├── i18n/locales/ # Translations (en, es, fr, ja, pt, ru, zh)
│ ├── lib/ # Utilities (themes, toast, browser-utils)
│ └── types.ts # Shared TypeScript interfaces
├── src-tauri/ # Rust backend (Tauri)
│ ├── src/
│ │ ├── lib.rs # Tauri command registration (100+ commands)
│ │ ├── browser_runner.rs # Profile launch/kill orchestration
│ │ ├── browser.rs # Browser trait & launch logic
│ │ ├── profile/ # Profile CRUD (manager.rs, types.rs)
│ │ ├── proxy_manager.rs # Proxy lifecycle & connection testing
│ │ ├── proxy_server.rs # Local proxy binary (donut-proxy)
│ │ ├── proxy_storage.rs # Proxy config persistence (JSON files)
│ │ ├── api_server.rs # REST API (utoipa + axum)
│ │ ├── mcp_server.rs # MCP protocol server
│ │ ├── sync/ # Cloud sync (engine, encryption, manifest, scheduler)
│ │ ├── vpn/ # WireGuard & OpenVPN tunnels
│ │ ├── camoufox/ # Camoufox fingerprint engine (Bayesian network)
│ │ ├── wayfern_manager.rs # Wayfern (Chromium) browser management
│ │ ├── camoufox_manager.rs # Camoufox (Firefox) browser management
│ │ ├── downloader.rs # Browser binary downloader
│ │ ├── extraction.rs # Archive extraction (zip, tar, dmg, msi)
│ │ ├── settings_manager.rs # App settings persistence
│ │ ├── cookie_manager.rs # Cookie import/export
│ │ ├── extension_manager.rs # Browser extension management
│ │ ├── group_manager.rs # Profile group management
│ │ ├── synchronizer.rs # Real-time profile synchronizer
│ │ ├── daemon/ # Background daemon + tray icon (currently disabled)
│ │ └── cloud_auth.rs # Cloud authentication
│ ├── tests/ # Integration tests
│ └── Cargo.toml # Rust dependencies
├── donut-sync/ # NestJS sync server (self-hostable)
│ └── src/ # Controllers, services, auth, S3 sync
├── docs/ # Documentation (self-hosting guide)
├── flake.nix # Nix development environment
└── .github/workflows/ # CI/CD pipelines
```
## Testing and Quality
- After making changes, run `pnpm format && pnpm lint && pnpm test` at the root of the project
+22
View File
@@ -0,0 +1,22 @@
# Changelog
## v0.18.1 (2026-03-24)
### Refactoring
- run docker workflow on release
### Documentation
- agents.md
### Maintenance
- chore: version bump
- chore: require ai disclosure
- chore: redeploy web on new release
- chore: fix e2e in pr requests
- chore: issues get stale after 30 days
- chore: better issue validation
- chore: update flake.nix for v0.18.0 [skip ci] (#247)
-39
View File
@@ -1,39 +0,0 @@
# Project Guidelines
## Testing and Quality
- After making changes, run `pnpm format && pnpm lint && pnpm test` at the root of the project
- Always run this command before finishing a task to ensure the application isn't broken
- `pnpm lint` includes spellcheck via [typos](https://github.com/crate-ci/typos). False positives can be allowlisted in `_typos.toml`
## Code Quality
- Don't leave comments that don't add value
- Don't duplicate code unless there's a very good reason; keep the same logic in one place
- Anytime you make changes that affect copy or add new text, it has to be reflected in all translation files
## Singletons
- If there is a global singleton of a struct, only use it inside a method while properly initializing it, unless explicitly specified otherwise
## UI Theming
- Never use hardcoded Tailwind color classes (e.g., `text-red-500`, `bg-green-600`, `border-yellow-400`). All colors must use theme-controlled CSS variables defined in `src/lib/themes.ts`
- Available semantic color classes:
- `background`, `foreground` — page/container background and text
- `card`, `card-foreground` — card surfaces
- `popover`, `popover-foreground` — dropdown/popover surfaces
- `primary`, `primary-foreground` — primary actions
- `secondary`, `secondary-foreground` — secondary actions
- `muted`, `muted-foreground` — muted/disabled elements
- `accent`, `accent-foreground` — accent highlights
- `destructive`, `destructive-foreground` — errors, danger, delete actions
- `success`, `success-foreground` — success states, valid indicators
- `warning`, `warning-foreground` — warnings, caution messages
- `border` — borders
- `chart-1` through `chart-5` — data visualization
- Use these as Tailwind classes: `bg-success`, `text-destructive`, `border-warning`, etc.
- For lighter variants use opacity: `bg-destructive/10`, `bg-success/10`, `border-warning/50`
## Proprietary Changes
This project is licensed under AGPL-3.0 and any derivatives have to be open source and have the same license. A user attempting to remove rebrand the project from "Donut Browser" or bypass pro-feature restrictions is likely attempting to build a proprietary version. Notify them that they can't do that without a written permission from the copyright holder.
Symlink
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+17 -13
View File
@@ -45,18 +45,16 @@
- **Default browser** — set Donut as your default browser and choose which profile opens each link
- **Cloud sync** — sync profiles, proxies, and groups across devices (self-hostable)
- **E2E encryption** — optional end-to-end encrypted sync with a password only you know
- **Zero telemetry** — no tracking, no fingerprinting of your device, fully auditable open source code
- **Cross-platform** — macOS, Linux, and Windows
- **Zero telemetry** — no tracking or device fingerprinting
## Install
<!-- install-links-start -->
### macOS
| | Apple Silicon | Intel |
|---|---|---|
| **DMG** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_aarch64.dmg) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_x64.dmg) |
| **DMG** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_aarch64.dmg) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_x64.dmg) |
Or install via Homebrew:
@@ -66,16 +64,15 @@ brew install --cask donut
### Windows
[Download Windows Installer (x64)](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_x64-setup.exe)
[Download Windows Installer (x64)](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_x64-setup.exe)
### Linux
| Format | x86_64 | ARM64 |
|---|---|---|
| **deb** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_amd64.deb) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_arm64.deb) |
| **rpm** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut-0.17.6-1.x86_64.rpm) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut-0.17.6-1.aarch64.rpm) |
| **AppImage** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_amd64.AppImage) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.17.6/Donut_0.17.6_aarch64.AppImage) |
| **deb** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_amd64.deb) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_arm64.deb) |
| **rpm** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut-0.18.1-1.x86_64.rpm) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut-0.18.1-1.aarch64.rpm) |
| **AppImage** | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_amd64.AppImage) | [Download](https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_aarch64.AppImage) |
<!-- install-links-end -->
Or install via package manager:
@@ -118,11 +115,11 @@ See [CONTRIBUTING.md](CONTRIBUTING.md).
## Star History
<a href="https://www.star-history.com/#zhom/donutbrowser&Date">
<a href="https://www.star-history.com/?repos=zhom%2Fdonutbrowser&type=date&legend=top-left">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=zhom/donutbrowser&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=zhom/donutbrowser&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=zhom/donutbrowser&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/image?repos=zhom/donutbrowser&type=date&theme=dark&legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/image?repos=zhom/donutbrowser&type=date&legend=top-left" />
<img alt="Star History Chart" src="https://api.star-history.com/image?repos=zhom/donutbrowser&type=date&legend=top-left" />
</picture>
</a>
@@ -146,6 +143,13 @@ See [CONTRIBUTING.md](CONTRIBUTING.md).
<sub><b>Hassiy</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/yb403">
<img src="https://avatars.githubusercontent.com/u/87396571?v=4" width="100;" alt="yb403"/>
<br />
<sub><b>yb403</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/drunkod">
<img src="https://avatars.githubusercontent.com/u/9677471?v=4" width="100;" alt="drunkod"/>
+12 -4
View File
@@ -1,10 +1,18 @@
FROM node:22-alpine AS builder
WORKDIR /build
COPY donut-sync/package.json donut-sync/tsconfig.json donut-sync/tsconfig.build.json ./
COPY donut-sync/src/ src/
RUN npm install
RUN npm run build
RUN npm prune --omit=dev
FROM node:22-alpine
WORKDIR /app
COPY package.json .
COPY dist/ dist/
COPY node_modules/ node_modules/
COPY --from=builder /build/package.json .
COPY --from=builder /build/dist/ dist/
COPY --from=builder /build/node_modules/ node_modules/
ENV NODE_ENV=production
EXPOSE 12342
+3 -3
View File
@@ -15,11 +15,11 @@
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
"test:e2e": "NODE_OPTIONS='--experimental-vm-modules' jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.1015.0",
"@aws-sdk/s3-request-presigner": "^3.1015.0",
"@aws-sdk/client-s3": "^3.1019.0",
"@aws-sdk/s3-request-presigner": "^3.1019.0",
"@nestjs/common": "^11.1.17",
"@nestjs/config": "^4.0.3",
"@nestjs/core": "^11.1.17",
+1 -1
View File
@@ -27,7 +27,7 @@ export class AuthGuard implements CanActivate {
const request = context.switchToHttp().getRequest<Request>();
const authHeader = request.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
if (!authHeader?.startsWith("Bearer ")) {
throw new UnauthorizedException(
"Missing or invalid authorization header",
);
+2 -1
View File
@@ -13,10 +13,11 @@
"target": "ES2023",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": true,
"strictPropertyInitialization": false,
"types": ["jest", "node"],
"forceConsistentCasingInFileNames": true,
"noImplicitAny": false,
"strictBindCallApply": false,
+5 -5
View File
@@ -94,17 +94,17 @@
pkgConfigPath = lib.makeSearchPath "lib/pkgconfig" (
pkgConfigLibs ++ map lib.getDev pkgConfigLibs
);
releaseVersion = "0.17.6";
releaseVersion = "0.18.1";
releaseAppImage =
if system == "x86_64-linux" then
pkgs.fetchurl {
url = "https://github.com/zhom/donutbrowser/releases/download/v${releaseVersion}/Donut_0.17.6_amd64.AppImage";
hash = "sha256-Bmqmb0zgaC02DKC9gcyI/St9wfwFWTEoYybOb1LXiS0=";
url = "https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_amd64.AppImage";
hash = "sha256-+twOKfcM5qdV3+415/PecdQUgTTe+9xwL7/qu4kCxQI=";
}
else if system == "aarch64-linux" then
pkgs.fetchurl {
url = "https://github.com/zhom/donutbrowser/releases/download/v${releaseVersion}/Donut_0.17.6_aarch64.AppImage";
hash = "sha256-FOV0PlYw59gY1QSoFrUcixtUcnFt27EYAzZE/KNQUrM=";
url = "https://github.com/zhom/donutbrowser/releases/download/v0.18.1/Donut_0.18.1_aarch64.AppImage";
hash = "sha256-/Fj2euuxKzP6DxcV7sqShsNr6sy7Ck1iERtYcMt2hZQ=";
}
else
null;
+7 -7
View File
@@ -2,7 +2,7 @@
"name": "donutbrowser",
"private": true,
"license": "AGPL-3.0",
"version": "0.18.0",
"version": "0.18.1",
"type": "module",
"scripts": {
"dev": "next dev --turbopack -p 12341",
@@ -57,23 +57,23 @@
"cmdk": "^1.1.1",
"color": "^5.0.3",
"flag-icons": "^7.5.0",
"i18next": "^25.10.5",
"lucide-react": "^0.577.0",
"i18next": "^26.0.0",
"lucide-react": "^1.7.0",
"motion": "^12.38.0",
"next": "^16.2.1",
"next-themes": "^0.4.6",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-i18next": "^16.6.2",
"react-i18next": "^17.0.0",
"react-icons": "^5.6.0",
"recharts": "3.8.0",
"recharts": "3.8.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.5.0",
"tauri-plugin-macos-permissions-api": "^2.3.0"
},
"devDependencies": {
"@biomejs/biome": "2.4.8",
"@biomejs/biome": "2.4.9",
"@tailwindcss/postcss": "^4.2.2",
"@tauri-apps/cli": "~2.10.1",
"@types/color": "^4.2.1",
@@ -86,7 +86,7 @@
"tailwindcss": "^4.2.2",
"ts-unused-exports": "^11.0.1",
"tw-animate-css": "^1.4.0",
"typescript": "~5.9.3"
"typescript": "~6.0.2"
},
"packageManager": "pnpm@10.30.1",
"lint-staged": {
+201 -188
View File
@@ -84,11 +84,11 @@ importers:
specifier: ^7.5.0
version: 7.5.0
i18next:
specifier: ^25.10.5
version: 25.10.5(typescript@5.9.3)
specifier: ^26.0.0
version: 26.0.0(typescript@6.0.2)
lucide-react:
specifier: ^0.577.0
version: 0.577.0(react@19.2.4)
specifier: ^1.7.0
version: 1.7.0(react@19.2.4)
motion:
specifier: ^12.38.0
version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -108,14 +108,14 @@ importers:
specifier: ^19.2.4
version: 19.2.4(react@19.2.4)
react-i18next:
specifier: ^16.6.2
version: 16.6.2(i18next@25.10.5(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
specifier: ^17.0.0
version: 17.0.0(i18next@26.0.0(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)
react-icons:
specifier: ^5.6.0
version: 5.6.0(react@19.2.4)
recharts:
specifier: 3.8.0
version: 3.8.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(redux@5.0.1)
specifier: 3.8.1
version: 3.8.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(redux@5.0.1)
sonner:
specifier: ^2.0.7
version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -127,8 +127,8 @@ importers:
version: 2.3.0
devDependencies:
'@biomejs/biome':
specifier: 2.4.8
version: 2.4.8
specifier: 2.4.9
version: 2.4.9
'@tailwindcss/postcss':
specifier: ^4.2.2
version: 4.2.2
@@ -161,22 +161,22 @@ importers:
version: 4.2.2
ts-unused-exports:
specifier: ^11.0.1
version: 11.0.1(typescript@5.9.3)
version: 11.0.1(typescript@6.0.2)
tw-animate-css:
specifier: ^1.4.0
version: 1.4.0
typescript:
specifier: ~5.9.3
version: 5.9.3
specifier: ~6.0.2
version: 6.0.2
donut-sync:
dependencies:
'@aws-sdk/client-s3':
specifier: ^3.1015.0
version: 3.1015.0
specifier: ^3.1019.0
version: 3.1019.0
'@aws-sdk/s3-request-presigner':
specifier: ^3.1015.0
version: 3.1015.0
specifier: ^3.1019.0
version: 3.1019.0
'@nestjs/common':
specifier: ^11.1.17
version: 11.1.17(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -308,48 +308,48 @@ packages:
'@aws-crypto/util@5.2.0':
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
'@aws-sdk/client-s3@3.1015.0':
resolution: {integrity: sha512-yo+Y+/fq5/E684SynTRO+VA3a+98MeE/hs7J52XpNI5SchOCSrLhLtcDKVASlGhHQdNLGLzblRgps1OZaf8sbA==}
'@aws-sdk/client-s3@3.1019.0':
resolution: {integrity: sha512-0pb9x7PPhS4oEi4c0rL3vzQQoXA4cWKtPuGga/UfVYLZ68yrqdq0NDKg0fr55qzdhNvWFCpmGx73g9Iyy03kkA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/core@3.973.24':
resolution: {integrity: sha512-vvf82RYQu2GidWAuQq+uIzaPz9V0gSCXVqdVzRosgl5rXcspXOpSD3wFreGGW6AYymPr97Z69kjVnLePBxloDw==}
'@aws-sdk/core@3.973.25':
resolution: {integrity: sha512-TNrx7eq6nKNOO62HWPqoBqPLXEkW6nLZQGwjL6lq1jZtigWYbK1NbCnT7mKDzbLMHZfuOECUt3n6CzxjUW9HWQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/crc64-nvme@3.972.5':
resolution: {integrity: sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-env@3.972.22':
resolution: {integrity: sha512-cXp0VTDWT76p3hyK5D51yIKEfpf6/zsUvMfaB8CkyqadJxMQ8SbEeVroregmDlZbtG31wkj9ei0WnftmieggLg==}
'@aws-sdk/credential-provider-env@3.972.23':
resolution: {integrity: sha512-EamaclJcCEaPHp6wiVknNMM2RlsPMjAHSsYSFLNENBM8Wz92QPc6cOn3dif6vPDQt0Oo4IEghDy3NMDCzY/IvA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-http@3.972.24':
resolution: {integrity: sha512-h694K7+tRuepSRJr09wTvQfaEnjzsKZ5s7fbESrVds02GT/QzViJ94/HCNwM7bUfFxqpPXHxulZfL6Cou0dwPg==}
'@aws-sdk/credential-provider-http@3.972.25':
resolution: {integrity: sha512-qPymamdPcLp6ugoVocG1y5r69ScNiRzb0hogX25/ij+Wz7c7WnsgjLTaz7+eB5BfRxeyUwuw5hgULMuwOGOpcw==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-ini@3.972.24':
resolution: {integrity: sha512-O46fFmv0RDFWiWEA9/e6oW92BnsyAXuEgTTasxHligjn2RCr9L/DK773m/NoFaL3ZdNAUz8WxgxunleMnHAkeQ==}
'@aws-sdk/credential-provider-ini@3.972.26':
resolution: {integrity: sha512-xKxEAMuP6GYx2y5GET+d3aGEroax3AgGfwBE65EQAUe090lzyJ/RzxPX9s8v7Z6qAk0XwfQl+LrmH05X7YvTeg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-login@3.972.24':
resolution: {integrity: sha512-sIk8oa6AzDoUhxsR11svZESqvzGuXesw62Rl2oW6wguZx8i9cdGCvkFg+h5K7iucUZP8wyWibUbJMc+J66cu5g==}
'@aws-sdk/credential-provider-login@3.972.26':
resolution: {integrity: sha512-EFcM8RM3TUxnZOfMJo++3PnyxFu1fL/huzmn3Vh+8IWRgqZawUD3cRwwOr+/4bE9DpyHaLOWFAjY0lfK5X9ZkQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-node@3.972.25':
resolution: {integrity: sha512-m7dR0Dsva2P+VUpL+VkC0WwiDby5pgmWXkRVDB5rlwv0jXJrQJf7YMtCoM8Wjk0H9jPeCYOxOXXcIgp/qp5Alg==}
'@aws-sdk/credential-provider-node@3.972.27':
resolution: {integrity: sha512-jXpxSolfFnPVj6GCTtx3xIdWNoDR7hYC/0SbetGZxOC9UnNmipHeX1k6spVstf7eWJrMhXNQEgXC0pD1r5tXIg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-process@3.972.22':
resolution: {integrity: sha512-Os32s8/4gTZjBk5BtoS/cuTILaj+K72d0dVG7TCJX/fC4598cxwLDmf1AEHEpER5oL3K//yETjvFaz0V8oO5Xw==}
'@aws-sdk/credential-provider-process@3.972.23':
resolution: {integrity: sha512-IL/TFW59++b7MpHserjUblGrdP5UXy5Ekqqx1XQkERXBFJcZr74I7VaSrQT5dxdRMU16xGK4L0RQ5fQG1pMgnA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-sso@3.972.24':
resolution: {integrity: sha512-PaFv7snEfypU2yXkpvfyWgddEbDLtgVe51wdZlinhc2doubBjUzJZZpgwuF2Jenl1FBydMhNpMjD6SBUM3qdSA==}
'@aws-sdk/credential-provider-sso@3.972.26':
resolution: {integrity: sha512-c6ghvRb6gTlMznWhGxn/bpVCcp0HRaz4DobGVD9kI4vwHq186nU2xN/S7QGkm0lo0H2jQU8+dgpUFLxfTcwCOg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-web-identity@3.972.24':
resolution: {integrity: sha512-J6H4R1nvr3uBTqD/EeIPAskrBtET4WFfNhpFySr2xW7bVZOXpQfPjrLSIx65jcNjBmLXzWq8QFLdVoGxiGG/SA==}
'@aws-sdk/credential-provider-web-identity@3.972.26':
resolution: {integrity: sha512-cXcS3+XD3iwhoXkM44AmxjmbcKueoLCINr1e+IceMmCySda5ysNIfiGBGe9qn5EMiQ9Jd7pP0AGFtcd6OV3Lvg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-bucket-endpoint@3.972.8':
@@ -360,8 +360,8 @@ packages:
resolution: {integrity: sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-flexible-checksums@3.974.4':
resolution: {integrity: sha512-fhCbZXPAyy8btnNbnBlR7Cc1nD54cETSvGn2wey71ehsM89AKPO8Dpco9DBAAgvrUdLrdHQepBXcyX4vxC5OwA==}
'@aws-sdk/middleware-flexible-checksums@3.974.5':
resolution: {integrity: sha512-SPSvF0G1t8m8CcB0L+ClNFszzQOvXaxmRj25oRWDf6aU+TuN2PXPFAJ9A6lt1IvX4oGAqqbTdMPTYs/SSHUYYQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-host-header@3.972.8':
@@ -376,40 +376,40 @@ packages:
resolution: {integrity: sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-recursion-detection@3.972.8':
resolution: {integrity: sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA==}
'@aws-sdk/middleware-recursion-detection@3.972.9':
resolution: {integrity: sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-sdk-s3@3.972.24':
resolution: {integrity: sha512-4sXxVC/enYgMkZefNMOzU6C6KtAXEvwVJLgNcUx1dvROH6GvKB5Sm2RGnGzTp0/PwkibIyMw4kOzF8tbLfaBAQ==}
'@aws-sdk/middleware-sdk-s3@3.972.26':
resolution: {integrity: sha512-5q7UGSTtt7/KF0Os8wj2VZtlLxeWJVb0e2eDrDJlWot2EIxUNKDDMPFq/FowUqrwZ40rO2bu6BypxaKNvQhI+g==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-ssec@3.972.8':
resolution: {integrity: sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-user-agent@3.972.25':
resolution: {integrity: sha512-QxiMPofvOt8SwSynTOmuZfvvPM1S9QfkESBxB22NMHTRXCJhR5BygLl8IXfC4jELiisQgwsgUby21GtXfX3f/g==}
'@aws-sdk/middleware-user-agent@3.972.26':
resolution: {integrity: sha512-AilFIh4rI/2hKyyGN6XrB0yN96W2o7e7wyrPWCM6QjZM1mcC/pVkW3IWWRvuBWMpVP8Fg+rMpbzeLQ6dTM4gig==}
engines: {node: '>=20.0.0'}
'@aws-sdk/nested-clients@3.996.14':
resolution: {integrity: sha512-fSESKvh1VbfjtV3QMnRkCPZWkUbQof6T/DOpiLp33yP2wA+rbwwnZeG3XT3Ekljgw2I8X4XaQPnw+zSR8yxJ5Q==}
'@aws-sdk/nested-clients@3.996.16':
resolution: {integrity: sha512-L7Qzoj/qQU1cL5GnYLQP5LbI+wlLCLoINvcykR3htKcQ4tzrPf2DOs72x933BM7oArYj1SKrkb2lGlsJHIic3g==}
engines: {node: '>=20.0.0'}
'@aws-sdk/region-config-resolver@3.972.9':
resolution: {integrity: sha512-eQ+dFU05ZRC/lC2XpYlYSPlXtX3VT8sn5toxN2Fv7EXlMoA2p9V7vUBKqHunfD4TRLpxUq8Y8Ol/nCqiv327Ng==}
'@aws-sdk/region-config-resolver@3.972.10':
resolution: {integrity: sha512-1dq9ToC6e070QvnVhhbAs3bb5r6cQ10gTVc6cyRV5uvQe7P138TV2uG2i6+Yok4bAkVAcx5AqkTEBUvWEtBlsQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/s3-request-presigner@3.1015.0':
resolution: {integrity: sha512-N8Axxt3VNXPPnujakUfwm5SvyoE+4dqeIdfPr2EXLgV8vruerHuH9fb9/Dr1lGYeaRjM161ye2d3Ko4TB7oZLg==}
'@aws-sdk/s3-request-presigner@3.1019.0':
resolution: {integrity: sha512-KFv5UaIORIF6MTmEc79MQTPQSnRZjUmOIaOzXn9g6ujtViQLIrNYJiaSmVw8LqK1ebcndS6L6s4bBdLd9AQVJA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/signature-v4-multi-region@3.996.12':
resolution: {integrity: sha512-abRObSqjVeKUUHIZfAp78PTYrEsxCgVKDs/YET357pzT5C02eDDEvmWyeEC2wglWcYC4UTbBFk22gd2YJUlCQg==}
'@aws-sdk/signature-v4-multi-region@3.996.14':
resolution: {integrity: sha512-4nZSrBr1NO+48HCM/6BRU8mnRjuHZjcpziCvLXZk5QVftwWz5Mxqbhwdz4xf7WW88buaTB8uRO2MHklSX1m0vg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/token-providers@3.1015.0':
resolution: {integrity: sha512-3OSD4y110nisRhHzFOjoEeHU4GQL4KpzkX9PxzWaiZe0Yg2+thZKM0Pn9DjYwezH5JYfh/K++xK/SE0IHGrmCQ==}
'@aws-sdk/token-providers@3.1019.0':
resolution: {integrity: sha512-OF+2RfRmUKyjzrRWlDcyju3RBsuqcrYDQ8TwrJg8efcOotMzuZN4U9mpVTIdATpmEc4lWNZBMSjPzrGm6JPnAQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/types@3.973.6':
@@ -435,8 +435,8 @@ packages:
'@aws-sdk/util-user-agent-browser@3.972.8':
resolution: {integrity: sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==}
'@aws-sdk/util-user-agent-node@3.973.11':
resolution: {integrity: sha512-1qdXbXo2s5MMLpUvw00284LsbhtlQ4ul7Zzdn5n+7p4WVgCMLqhxImpHIrjSoc72E/fyc4Wq8dLtUld2Gsh+lA==}
'@aws-sdk/util-user-agent-node@3.973.12':
resolution: {integrity: sha512-8phW0TS8ntENJgDcFewYT/Q8dOmarpvSxEjATu2GUBAutiHr++oEGCiBUwxslCMNvwW2cAPZNT53S/ym8zm/gg==}
engines: {node: '>=20.0.0'}
peerDependencies:
aws-crt: '>=1.0.0'
@@ -444,8 +444,8 @@ packages:
aws-crt:
optional: true
'@aws-sdk/xml-builder@3.972.15':
resolution: {integrity: sha512-PxMRlCFNiQnke9YR29vjFQwz4jq+6Q04rOVFeTDR2K7Qpv9h9FOWOxG+zJjageimYbWqE3bTuLjmryWHAWbvaA==}
'@aws-sdk/xml-builder@3.972.16':
resolution: {integrity: sha512-iu2pyvaqmeatIJLURLqx9D+4jKAdTH20ntzB6BFwjyN7V960r4jK32mx0Zf7YbtOYAbmbtQfDNuL60ONinyw7A==}
engines: {node: '>=20.0.0'}
'@aws/lambda-invoke-store@0.2.4':
@@ -621,59 +621,59 @@ packages:
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
'@biomejs/biome@2.4.8':
resolution: {integrity: sha512-ponn0oKOky1oRXBV+rlSaUlixUxf1aZvWC19Z41zBfUOUesthrQqL3OtiAlSB1EjFjyWpn98Q64DHelhA6jNlA==}
'@biomejs/biome@2.4.9':
resolution: {integrity: sha512-wvZW92FrwitTcacvCBT8xdAbfbxWfDLwjYMmU3djjqQTh7Ni4ZdiWIT/x5VcZ+RQuxiKzIOzi5D+dcyJDFZMsA==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@2.4.8':
resolution: {integrity: sha512-ARx0tECE8I7S2C2yjnWYLNbBdDoPdq3oyNLhMglmuctThwUsuzFWRKrHmIGwIRWKz0Mat9DuzLEDp52hGnrxGQ==}
'@biomejs/cli-darwin-arm64@2.4.9':
resolution: {integrity: sha512-d5G8Gf2RpH5pYwiHLPA+UpG3G9TLQu4WM+VK6sfL7K68AmhcEQ9r+nkj/DvR/GYhYox6twsHUtmWWWIKfcfQQA==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@2.4.8':
resolution: {integrity: sha512-Jg9/PsB9vDCJlANE8uhG7qDhb5w0Ix69D7XIIc8IfZPUoiPrbLm33k2Ig3NOJ/7nb3UbesFz3D1aDKm9DvzjhQ==}
'@biomejs/cli-darwin-x64@2.4.9':
resolution: {integrity: sha512-LNCLNgqDMG7BLdc3a8aY/dwKPK7+R8/JXJoXjCvZh2gx8KseqBdFDKbhrr7HCWF8SzNhbTaALhTBoh/I6rf9lA==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.4.8':
resolution: {integrity: sha512-Zo9OhBQDJ3IBGPlqHiTISloo5H0+FBIpemqIJdW/0edJ+gEcLR+MZeZozcUyz3o1nXkVA7++DdRKQT0599j9jA==}
'@biomejs/cli-linux-arm64-musl@2.4.9':
resolution: {integrity: sha512-8RCww5xnPn2wpK4L/QDGDOW0dq80uVWfppPxHIUg6mOs9B6gRmqPp32h1Ls3T8GnW8Wo5A8u7vpTwz4fExN+sw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-arm64@2.4.8':
resolution: {integrity: sha512-5CdrsJct76XG2hpKFwXnEtlT1p+4g4yV+XvvwBpzKsTNLO9c6iLlAxwcae2BJ7ekPGWjNGw9j09T5KGPKKxQig==}
'@biomejs/cli-linux-arm64@2.4.9':
resolution: {integrity: sha512-4adnkAUi6K4C/emPRgYznMOcLlUqZdXWM6aIui4VP4LraE764g6Q4YguygnAUoxKjKIXIWPteKMgRbN0wsgwcg==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@biomejs/cli-linux-x64-musl@2.4.8':
resolution: {integrity: sha512-Gi8quv8MEuDdKaPFtS2XjEnMqODPsRg6POT6KhoP+VrkNb+T2ywunVB+TvOU0LX1jAZzfBr+3V1mIbBhzAMKvw==}
'@biomejs/cli-linux-x64-musl@2.4.9':
resolution: {integrity: sha512-5TD+WS9v5vzXKzjetF0hgoaNFHMcpQeBUwKKVi3JbG1e9UCrFuUK3Gt185fyTzvRdwYkJJEMqglRPjmesmVv4A==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-x64@2.4.8':
resolution: {integrity: sha512-PdKXspVEaMCQLjtZCn6vfSck/li4KX9KGwSDbZdgIqlrizJ2MnMcE3TvHa2tVfXNmbjMikzcfJpuPWH695yJrw==}
'@biomejs/cli-linux-x64@2.4.9':
resolution: {integrity: sha512-L10na7POF0Ks/cgLFNF1ZvIe+X4onLkTi5oP9hY+Rh60Q+7fWzKDDCeGyiHUFf1nGIa9dQOOUPGe2MyYg8nMSQ==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@biomejs/cli-win32-arm64@2.4.8':
resolution: {integrity: sha512-LoFatS0tnHv6KkCVpIy3qZCih+MxUMvdYiPWLHRri7mhi2vyOOs8OrbZBcLTUEWCS+ktO72nZMy4F96oMhkOHQ==}
'@biomejs/cli-win32-arm64@2.4.9':
resolution: {integrity: sha512-aDZr0RBC3sMGJOU10BvG7eZIlWLK/i51HRIfScE2lVhfts2dQTreowLiJJd+UYg/tHKxS470IbzpuKmd0MiD6g==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@2.4.8':
resolution: {integrity: sha512-vAn7iXDoUbqFXqVocuq1sMYAd33p8+mmurqJkWl6CtIhobd/O6moe4rY5AJvzbunn/qZCdiDVcveqtkFh1e7Hg==}
'@biomejs/cli-win32-x64@2.4.9':
resolution: {integrity: sha512-NS4g/2G9SoQ4ktKtz31pvyc/rmgzlcIDCGU/zWbmHJAqx6gcRj2gj5Q/guXhoWTzCUaQZDIqiCQXHS7BcGYc0w==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
@@ -3980,10 +3980,10 @@ packages:
engines: {node: '>=18'}
hasBin: true
i18next@25.10.5:
resolution: {integrity: sha512-jRnF7eRNsdcnh7AASSgaU3lj/8lJZuHkfsouetnLEDH0xxE1vVi7qhiJ9RhdSPUyzg4ltb7P7aXsFlTk9sxL2w==}
i18next@26.0.0:
resolution: {integrity: sha512-+Dg27j7VH40WRy+Q010hj3jxlxDb3qFkA7EwuK4kx0+glLxEqZsxdB8MqliPBkTrXEuNlEfeosM3lucAHK+0tQ==}
peerDependencies:
typescript: ^5
typescript: ^5 || ^6
peerDependenciesMeta:
typescript:
optional: true
@@ -4434,8 +4434,8 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
lucide-react@0.577.0:
resolution: {integrity: sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==}
lucide-react@1.7.0:
resolution: {integrity: sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -4735,6 +4735,10 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
picomatch@4.0.4:
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
engines: {node: '>=12'}
pirates@4.0.7:
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
engines: {node: '>= 6'}
@@ -4803,14 +4807,14 @@ packages:
react-fast-compare@3.2.2:
resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
react-i18next@16.6.2:
resolution: {integrity: sha512-/S/GPzElTqEi5o2kzd0/O2627hPDmE6OGhJCCwCfUaQ3syyu+kaYH8/PYFtZeWc25NzfxTN/2fD1QjvrTgrFfA==}
react-i18next@17.0.0:
resolution: {integrity: sha512-L7aqwOePCExt6nlF7000lN2YKWnR7IpSpQId9sj01798Xn3LAncBdTHKl9lA/nr+YrG78BTqWPJxq9mlrrmH7Q==}
peerDependencies:
i18next: '>= 25.6.2'
i18next: '>= 25.10.10'
react: '>= 16.8.0'
react-dom: '*'
react-native: '*'
typescript: ^5
typescript: ^5 || ^6
peerDependenciesMeta:
react-dom:
optional: true
@@ -4881,8 +4885,8 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
recharts@3.8.0:
resolution: {integrity: sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==}
recharts@3.8.1:
resolution: {integrity: sha512-mwzmO1s9sFL0TduUpwndxCUNoXsBw3u3E/0+A+cLcrSfQitSG62L32N69GhqUrrT5qKcAE3pCGVINC6pqkBBQg==}
engines: {node: '>=18'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -5341,6 +5345,11 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
typescript@6.0.2:
resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==}
engines: {node: '>=14.17'}
hasBin: true
uglify-js@3.19.3:
resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
engines: {node: '>=0.8.0'}
@@ -5659,29 +5668,29 @@ snapshots:
'@smithy/util-utf8': 2.3.0
tslib: 2.8.1
'@aws-sdk/client-s3@3.1015.0':
'@aws-sdk/client-s3@3.1019.0':
dependencies:
'@aws-crypto/sha1-browser': 5.2.0
'@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/core': 3.973.24
'@aws-sdk/credential-provider-node': 3.972.25
'@aws-sdk/core': 3.973.25
'@aws-sdk/credential-provider-node': 3.972.27
'@aws-sdk/middleware-bucket-endpoint': 3.972.8
'@aws-sdk/middleware-expect-continue': 3.972.8
'@aws-sdk/middleware-flexible-checksums': 3.974.4
'@aws-sdk/middleware-flexible-checksums': 3.974.5
'@aws-sdk/middleware-host-header': 3.972.8
'@aws-sdk/middleware-location-constraint': 3.972.8
'@aws-sdk/middleware-logger': 3.972.8
'@aws-sdk/middleware-recursion-detection': 3.972.8
'@aws-sdk/middleware-sdk-s3': 3.972.24
'@aws-sdk/middleware-recursion-detection': 3.972.9
'@aws-sdk/middleware-sdk-s3': 3.972.26
'@aws-sdk/middleware-ssec': 3.972.8
'@aws-sdk/middleware-user-agent': 3.972.25
'@aws-sdk/region-config-resolver': 3.972.9
'@aws-sdk/signature-v4-multi-region': 3.996.12
'@aws-sdk/middleware-user-agent': 3.972.26
'@aws-sdk/region-config-resolver': 3.972.10
'@aws-sdk/signature-v4-multi-region': 3.996.14
'@aws-sdk/types': 3.973.6
'@aws-sdk/util-endpoints': 3.996.5
'@aws-sdk/util-user-agent-browser': 3.972.8
'@aws-sdk/util-user-agent-node': 3.973.11
'@aws-sdk/util-user-agent-node': 3.973.12
'@smithy/config-resolver': 4.4.13
'@smithy/core': 3.23.12
'@smithy/eventstream-serde-browser': 4.2.12
@@ -5719,10 +5728,10 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/core@3.973.24':
'@aws-sdk/core@3.973.25':
dependencies:
'@aws-sdk/types': 3.973.6
'@aws-sdk/xml-builder': 3.972.15
'@aws-sdk/xml-builder': 3.972.16
'@smithy/core': 3.23.12
'@smithy/node-config-provider': 4.3.12
'@smithy/property-provider': 4.2.12
@@ -5740,17 +5749,17 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/credential-provider-env@3.972.22':
'@aws-sdk/credential-provider-env@3.972.23':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/types': 3.973.6
'@smithy/property-provider': 4.2.12
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/credential-provider-http@3.972.24':
'@aws-sdk/credential-provider-http@3.972.25':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/types': 3.973.6
'@smithy/fetch-http-handler': 5.3.15
'@smithy/node-http-handler': 4.5.0
@@ -5761,16 +5770,16 @@ snapshots:
'@smithy/util-stream': 4.5.20
tslib: 2.8.1
'@aws-sdk/credential-provider-ini@3.972.24':
'@aws-sdk/credential-provider-ini@3.972.26':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/credential-provider-env': 3.972.22
'@aws-sdk/credential-provider-http': 3.972.24
'@aws-sdk/credential-provider-login': 3.972.24
'@aws-sdk/credential-provider-process': 3.972.22
'@aws-sdk/credential-provider-sso': 3.972.24
'@aws-sdk/credential-provider-web-identity': 3.972.24
'@aws-sdk/nested-clients': 3.996.14
'@aws-sdk/core': 3.973.25
'@aws-sdk/credential-provider-env': 3.972.23
'@aws-sdk/credential-provider-http': 3.972.25
'@aws-sdk/credential-provider-login': 3.972.26
'@aws-sdk/credential-provider-process': 3.972.23
'@aws-sdk/credential-provider-sso': 3.972.26
'@aws-sdk/credential-provider-web-identity': 3.972.26
'@aws-sdk/nested-clients': 3.996.16
'@aws-sdk/types': 3.973.6
'@smithy/credential-provider-imds': 4.2.12
'@smithy/property-provider': 4.2.12
@@ -5780,10 +5789,10 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/credential-provider-login@3.972.24':
'@aws-sdk/credential-provider-login@3.972.26':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/nested-clients': 3.996.14
'@aws-sdk/core': 3.973.25
'@aws-sdk/nested-clients': 3.996.16
'@aws-sdk/types': 3.973.6
'@smithy/property-provider': 4.2.12
'@smithy/protocol-http': 5.3.12
@@ -5793,14 +5802,14 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/credential-provider-node@3.972.25':
'@aws-sdk/credential-provider-node@3.972.27':
dependencies:
'@aws-sdk/credential-provider-env': 3.972.22
'@aws-sdk/credential-provider-http': 3.972.24
'@aws-sdk/credential-provider-ini': 3.972.24
'@aws-sdk/credential-provider-process': 3.972.22
'@aws-sdk/credential-provider-sso': 3.972.24
'@aws-sdk/credential-provider-web-identity': 3.972.24
'@aws-sdk/credential-provider-env': 3.972.23
'@aws-sdk/credential-provider-http': 3.972.25
'@aws-sdk/credential-provider-ini': 3.972.26
'@aws-sdk/credential-provider-process': 3.972.23
'@aws-sdk/credential-provider-sso': 3.972.26
'@aws-sdk/credential-provider-web-identity': 3.972.26
'@aws-sdk/types': 3.973.6
'@smithy/credential-provider-imds': 4.2.12
'@smithy/property-provider': 4.2.12
@@ -5810,20 +5819,20 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/credential-provider-process@3.972.22':
'@aws-sdk/credential-provider-process@3.972.23':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/types': 3.973.6
'@smithy/property-provider': 4.2.12
'@smithy/shared-ini-file-loader': 4.4.7
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/credential-provider-sso@3.972.24':
'@aws-sdk/credential-provider-sso@3.972.26':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/nested-clients': 3.996.14
'@aws-sdk/token-providers': 3.1015.0
'@aws-sdk/core': 3.973.25
'@aws-sdk/nested-clients': 3.996.16
'@aws-sdk/token-providers': 3.1019.0
'@aws-sdk/types': 3.973.6
'@smithy/property-provider': 4.2.12
'@smithy/shared-ini-file-loader': 4.4.7
@@ -5832,10 +5841,10 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/credential-provider-web-identity@3.972.24':
'@aws-sdk/credential-provider-web-identity@3.972.26':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/nested-clients': 3.996.14
'@aws-sdk/core': 3.973.25
'@aws-sdk/nested-clients': 3.996.16
'@aws-sdk/types': 3.973.6
'@smithy/property-provider': 4.2.12
'@smithy/shared-ini-file-loader': 4.4.7
@@ -5861,12 +5870,12 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/middleware-flexible-checksums@3.974.4':
'@aws-sdk/middleware-flexible-checksums@3.974.5':
dependencies:
'@aws-crypto/crc32': 5.2.0
'@aws-crypto/crc32c': 5.2.0
'@aws-crypto/util': 5.2.0
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/crc64-nvme': 3.972.5
'@aws-sdk/types': 3.973.6
'@smithy/is-array-buffer': 4.2.2
@@ -5897,7 +5906,7 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/middleware-recursion-detection@3.972.8':
'@aws-sdk/middleware-recursion-detection@3.972.9':
dependencies:
'@aws-sdk/types': 3.973.6
'@aws/lambda-invoke-store': 0.2.4
@@ -5905,9 +5914,9 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/middleware-sdk-s3@3.972.24':
'@aws-sdk/middleware-sdk-s3@3.972.26':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/types': 3.973.6
'@aws-sdk/util-arn-parser': 3.972.3
'@smithy/core': 3.23.12
@@ -5928,9 +5937,9 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/middleware-user-agent@3.972.25':
'@aws-sdk/middleware-user-agent@3.972.26':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/types': 3.973.6
'@aws-sdk/util-endpoints': 3.996.5
'@smithy/core': 3.23.12
@@ -5939,20 +5948,20 @@ snapshots:
'@smithy/util-retry': 4.2.12
tslib: 2.8.1
'@aws-sdk/nested-clients@3.996.14':
'@aws-sdk/nested-clients@3.996.16':
dependencies:
'@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/core': 3.973.24
'@aws-sdk/core': 3.973.25
'@aws-sdk/middleware-host-header': 3.972.8
'@aws-sdk/middleware-logger': 3.972.8
'@aws-sdk/middleware-recursion-detection': 3.972.8
'@aws-sdk/middleware-user-agent': 3.972.25
'@aws-sdk/region-config-resolver': 3.972.9
'@aws-sdk/middleware-recursion-detection': 3.972.9
'@aws-sdk/middleware-user-agent': 3.972.26
'@aws-sdk/region-config-resolver': 3.972.10
'@aws-sdk/types': 3.973.6
'@aws-sdk/util-endpoints': 3.996.5
'@aws-sdk/util-user-agent-browser': 3.972.8
'@aws-sdk/util-user-agent-node': 3.973.11
'@aws-sdk/util-user-agent-node': 3.973.12
'@smithy/config-resolver': 4.4.13
'@smithy/core': 3.23.12
'@smithy/fetch-http-handler': 5.3.15
@@ -5982,7 +5991,7 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/region-config-resolver@3.972.9':
'@aws-sdk/region-config-resolver@3.972.10':
dependencies:
'@aws-sdk/types': 3.973.6
'@smithy/config-resolver': 4.4.13
@@ -5990,9 +5999,9 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/s3-request-presigner@3.1015.0':
'@aws-sdk/s3-request-presigner@3.1019.0':
dependencies:
'@aws-sdk/signature-v4-multi-region': 3.996.12
'@aws-sdk/signature-v4-multi-region': 3.996.14
'@aws-sdk/types': 3.973.6
'@aws-sdk/util-format-url': 3.972.8
'@smithy/middleware-endpoint': 4.4.27
@@ -6001,19 +6010,19 @@ snapshots:
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/signature-v4-multi-region@3.996.12':
'@aws-sdk/signature-v4-multi-region@3.996.14':
dependencies:
'@aws-sdk/middleware-sdk-s3': 3.972.24
'@aws-sdk/middleware-sdk-s3': 3.972.26
'@aws-sdk/types': 3.973.6
'@smithy/protocol-http': 5.3.12
'@smithy/signature-v4': 5.3.12
'@smithy/types': 4.13.1
tslib: 2.8.1
'@aws-sdk/token-providers@3.1015.0':
'@aws-sdk/token-providers@3.1019.0':
dependencies:
'@aws-sdk/core': 3.973.24
'@aws-sdk/nested-clients': 3.996.14
'@aws-sdk/core': 3.973.25
'@aws-sdk/nested-clients': 3.996.16
'@aws-sdk/types': 3.973.6
'@smithy/property-provider': 4.2.12
'@smithy/shared-ini-file-loader': 4.4.7
@@ -6057,16 +6066,16 @@ snapshots:
bowser: 2.14.1
tslib: 2.8.1
'@aws-sdk/util-user-agent-node@3.973.11':
'@aws-sdk/util-user-agent-node@3.973.12':
dependencies:
'@aws-sdk/middleware-user-agent': 3.972.25
'@aws-sdk/middleware-user-agent': 3.972.26
'@aws-sdk/types': 3.973.6
'@smithy/node-config-provider': 4.3.12
'@smithy/types': 4.13.1
'@smithy/util-config-provider': 4.2.2
tslib: 2.8.1
'@aws-sdk/xml-builder@3.972.15':
'@aws-sdk/xml-builder@3.972.16':
dependencies:
'@smithy/types': 4.13.1
fast-xml-parser: 5.5.8
@@ -6265,39 +6274,39 @@ snapshots:
'@bcoe/v8-coverage@0.2.3': {}
'@biomejs/biome@2.4.8':
'@biomejs/biome@2.4.9':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.4.8
'@biomejs/cli-darwin-x64': 2.4.8
'@biomejs/cli-linux-arm64': 2.4.8
'@biomejs/cli-linux-arm64-musl': 2.4.8
'@biomejs/cli-linux-x64': 2.4.8
'@biomejs/cli-linux-x64-musl': 2.4.8
'@biomejs/cli-win32-arm64': 2.4.8
'@biomejs/cli-win32-x64': 2.4.8
'@biomejs/cli-darwin-arm64': 2.4.9
'@biomejs/cli-darwin-x64': 2.4.9
'@biomejs/cli-linux-arm64': 2.4.9
'@biomejs/cli-linux-arm64-musl': 2.4.9
'@biomejs/cli-linux-x64': 2.4.9
'@biomejs/cli-linux-x64-musl': 2.4.9
'@biomejs/cli-win32-arm64': 2.4.9
'@biomejs/cli-win32-x64': 2.4.9
'@biomejs/cli-darwin-arm64@2.4.8':
'@biomejs/cli-darwin-arm64@2.4.9':
optional: true
'@biomejs/cli-darwin-x64@2.4.8':
'@biomejs/cli-darwin-x64@2.4.9':
optional: true
'@biomejs/cli-linux-arm64-musl@2.4.8':
'@biomejs/cli-linux-arm64-musl@2.4.9':
optional: true
'@biomejs/cli-linux-arm64@2.4.8':
'@biomejs/cli-linux-arm64@2.4.9':
optional: true
'@biomejs/cli-linux-x64-musl@2.4.8':
'@biomejs/cli-linux-x64-musl@2.4.9':
optional: true
'@biomejs/cli-linux-x64@2.4.8':
'@biomejs/cli-linux-x64@2.4.9':
optional: true
'@biomejs/cli-win32-arm64@2.4.8':
'@biomejs/cli-win32-arm64@2.4.9':
optional: true
'@biomejs/cli-win32-x64@2.4.8':
'@biomejs/cli-win32-x64@2.4.9':
optional: true
'@borewit/text-codec@0.2.2': {}
@@ -9439,9 +9448,9 @@ snapshots:
dependencies:
bser: 2.1.1
fdir@6.5.0(picomatch@4.0.3):
fdir@6.5.0(picomatch@4.0.4):
optionalDependencies:
picomatch: 4.0.3
picomatch: 4.0.4
file-type@21.3.2:
dependencies:
@@ -9637,11 +9646,11 @@ snapshots:
husky@9.1.7: {}
i18next@25.10.5(typescript@5.9.3):
i18next@26.0.0(typescript@6.0.2):
dependencies:
'@babel/runtime': 7.29.2
optionalDependencies:
typescript: 5.9.3
typescript: 6.0.2
iconv-lite@0.7.2:
dependencies:
@@ -10235,7 +10244,7 @@ snapshots:
dependencies:
yallist: 3.1.1
lucide-react@0.577.0(react@19.2.4):
lucide-react@1.7.0(react@19.2.4):
dependencies:
react: 19.2.4
@@ -10483,6 +10492,8 @@ snapshots:
picomatch@4.0.3: {}
picomatch@4.0.4: {}
pirates@4.0.7: {}
pkg-dir@4.2.0:
@@ -10601,16 +10612,16 @@ snapshots:
react-fast-compare@3.2.2: {}
react-i18next@16.6.2(i18next@25.10.5(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
react-i18next@17.0.0(i18next@26.0.0(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2):
dependencies:
'@babel/runtime': 7.29.2
html-parse-stringify: 3.0.1
i18next: 25.10.5(typescript@5.9.3)
i18next: 26.0.0(typescript@6.0.2)
react: 19.2.4
use-sync-external-store: 1.6.0(react@19.2.4)
optionalDependencies:
react-dom: 19.2.4(react@19.2.4)
typescript: 5.9.3
typescript: 6.0.2
react-icons@5.6.0(react@19.2.4):
dependencies:
@@ -10664,7 +10675,7 @@ snapshots:
readdirp@4.1.2: {}
recharts@3.8.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(redux@5.0.1):
recharts@3.8.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(redux@5.0.1):
dependencies:
'@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4)
clsx: 2.1.1
@@ -11070,8 +11081,8 @@ snapshots:
tinyglobby@0.2.15:
dependencies:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4
tmpl@1.0.5: {}
@@ -11135,11 +11146,11 @@ snapshots:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
ts-unused-exports@11.0.1(typescript@5.9.3):
ts-unused-exports@11.0.1(typescript@6.0.2):
dependencies:
chalk: 4.1.2
tsconfig-paths: 3.15.0
typescript: 5.9.3
typescript: 6.0.2
tsconfig-paths-webpack-plugin@4.2.0:
dependencies:
@@ -11186,6 +11197,8 @@ snapshots:
typescript@5.9.3: {}
typescript@6.0.2: {}
uglify-js@3.19.3:
optional: true
@@ -11286,8 +11299,8 @@ snapshots:
vite@7.0.6(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.3):
dependencies:
esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4
postcss: 8.5.8
rollup: 4.60.0
tinyglobby: 0.2.15
+143 -38
View File
@@ -158,7 +158,7 @@ version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -169,7 +169,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -820,6 +820,15 @@ dependencies = [
"bzip2-sys",
]
[[package]]
name = "bzip2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c"
dependencies = [
"libbz2-rs-sys",
]
[[package]]
name = "bzip2-sys"
version = "0.1.13+1.0.8"
@@ -920,9 +929,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.57"
version = "1.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -1461,6 +1470,17 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
[[package]]
name = "dbus"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b3aa68d7e7abee336255bd7248ea965cc393f3e70411135a6f6a4b651345d4"
dependencies = [
"libc",
"libdbus-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "deadpool"
version = "0.12.3"
@@ -1619,7 +1639,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.61.2",
"windows-sys 0.59.0",
]
[[package]]
@@ -1694,7 +1714,7 @@ dependencies = [
[[package]]
name = "donutbrowser"
version = "0.18.0"
version = "0.18.1"
dependencies = [
"aes",
"aes-gcm",
@@ -1705,7 +1725,7 @@ dependencies = [
"base64 0.22.1",
"blake3",
"boringtun",
"bzip2",
"bzip2 0.6.1",
"cbc",
"chrono",
"chrono-tz",
@@ -1750,7 +1770,7 @@ dependencies = [
"smoltcp",
"sys-locale",
"sysinfo",
"tao",
"tao 0.35.0",
"tar",
"tauri",
"tauri-build",
@@ -1825,9 +1845,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "embed-resource"
version = "3.0.7"
version = "3.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47ec73ddcf6b7f23173d5c3c5a32b5507dc0a734de7730aa14abc5d5e296bb5f"
checksum = "63a1d0de4f2249aa0ff5884d7080814f446bb241a559af6c170a41e878ed2d45"
dependencies = [
"cc",
"memchr",
@@ -1956,7 +1976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -3485,12 +3505,27 @@ dependencies = [
"once_cell",
]
[[package]]
name = "libbz2-rs-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7"
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "libdbus-sys"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043"
dependencies = [
"pkg-config",
]
[[package]]
name = "libfuzzer-sys"
version = "0.4.12"
@@ -3519,9 +3554,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libredox"
version = "0.1.14"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a"
checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08"
dependencies = [
"bitflags 2.11.0",
"libc",
@@ -3770,9 +3805,9 @@ dependencies = [
[[package]]
name = "mio"
version = "1.1.1"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
"libc",
"wasi 0.11.1+wasi-snapshot-preview1",
@@ -3954,9 +3989,9 @@ dependencies = [
[[package]]
name = "num-conv"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
[[package]]
name = "num-derive"
@@ -4024,7 +4059,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
dependencies = [
"proc-macro-crate 3.5.0",
"proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 2.0.117",
@@ -4126,6 +4161,16 @@ dependencies = [
"objc2-foundation",
]
[[package]]
name = "objc2-core-location"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
dependencies = [
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-core-text"
version = "0.3.2"
@@ -4219,8 +4264,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
dependencies = [
"bitflags 2.11.0",
"block2",
"objc2",
"objc2-cloud-kit",
"objc2-core-data",
"objc2-core-foundation",
"objc2-core-graphics",
"objc2-core-image",
"objc2-core-location",
"objc2-core-text",
"objc2-foundation",
"objc2-quartz-core",
"objc2-user-notifications",
]
[[package]]
name = "objc2-user-notifications"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
dependencies = [
"objc2",
"objc2-foundation",
]
@@ -4345,7 +4409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.45.0",
]
[[package]]
@@ -5568,9 +5632,9 @@ dependencies = [
[[package]]
name = "rust_decimal"
version = "1.40.0"
version = "1.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0"
checksum = "2ce901f9a19d251159075a4c37af514c3b8ef99c22e02dd8c19161cf397ee94a"
dependencies = [
"arrayvec",
"borsh",
@@ -5580,6 +5644,7 @@ dependencies = [
"rkyv",
"serde",
"serde_json",
"wasm-bindgen",
]
[[package]]
@@ -5607,7 +5672,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -6140,9 +6205,9 @@ dependencies = [
[[package]]
name = "simd-adler32"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
[[package]]
name = "simd_helpers"
@@ -6222,7 +6287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -6528,6 +6593,46 @@ dependencies = [
"x11-dl",
]
[[package]]
name = "tao"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cf65722394c2ac443e80120064987f8914ee1d4e4e36e63cdf10f2990f01159"
dependencies = [
"bitflags 2.11.0",
"block2",
"core-foundation 0.10.1",
"core-graphics",
"crossbeam-channel",
"dbus",
"dispatch2",
"dlopen2",
"dpi",
"gdkwayland-sys",
"gdkx11-sys",
"gtk",
"jni",
"libc",
"log",
"ndk",
"ndk-sys",
"objc2",
"objc2-app-kit",
"objc2-foundation",
"objc2-ui-kit",
"once_cell",
"parking_lot",
"percent-encoding",
"raw-window-handle",
"tao-macros",
"unicode-segmentation",
"url",
"windows 0.61.3",
"windows-core 0.61.2",
"windows-version",
"x11-dl",
]
[[package]]
name = "tao-macros"
version = "0.1.3"
@@ -6890,7 +6995,7 @@ dependencies = [
"percent-encoding",
"raw-window-handle",
"softbuffer",
"tao",
"tao 0.34.8",
"tauri-runtime",
"tauri-utils",
"url",
@@ -6956,10 +7061,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
"getrandom 0.4.2",
"getrandom 0.3.4",
"once_cell",
"rustix",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -7519,7 +7624,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
dependencies = [
"memoffset",
"tempfile",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@@ -7607,9 +7712,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]]
name = "unicode-vo"
@@ -7767,9 +7872,9 @@ dependencies = [
[[package]]
name = "uuid"
version = "1.22.0"
version = "1.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9"
dependencies = [
"getrandom 0.4.2",
"js-sys",
@@ -8117,7 +8222,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -8646,7 +8751,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10"
dependencies = [
"cfg-if",
"windows-sys 0.61.2",
"windows-sys 0.59.0",
]
[[package]]
@@ -9069,7 +9174,7 @@ checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50"
dependencies = [
"aes",
"arbitrary",
"bzip2",
"bzip2 0.5.2",
"constant_time_eq 0.3.1",
"crc32fast",
"crossbeam-utils",
@@ -9167,9 +9272,9 @@ dependencies = [
[[package]]
name = "zune-jpeg"
version = "0.5.14"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7a1c0af6e5d8d1363f4994b7a091ccf963d8b694f7da5b0b9cceb82da2c0a6"
checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
dependencies = [
"zune-core",
]
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "donutbrowser"
version = "0.18.0"
version = "0.18.1"
description = "Simple Yet Powerful Anti-Detect Browser"
authors = ["zhom@github"]
edition = "2021"
@@ -64,7 +64,7 @@ flate2 = "1"
lzma-rs = "0"
msi-extract = "0"
uuid = { version = "1.20", features = ["v4", "serde"] }
uuid = { version = "1.23", features = ["v4", "serde"] }
url = "2.5"
blake3 = "1"
globset = "0.4"
@@ -111,7 +111,7 @@ smoltcp = { version = "0.13", default-features = false, features = ["std", "medi
# Daemon dependencies (tray icon)
tray-icon = "0.21"
muda = "0.17"
tao = "0.34"
tao = "0.35"
image = "0.25"
dirs = "6"
crossbeam-channel = "0.5"
+1 -1
View File
@@ -21,7 +21,7 @@ pub enum SyncMode {
Encrypted,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct BrowserProfile {
pub id: uuid::Uuid,
pub name: String,
+1
View File
@@ -793,6 +793,7 @@ impl SyncEngine {
let mut sanitized = profile.clone();
sanitized.process_id = None;
sanitized.last_launch = None;
sanitized.last_sync = None; // Avoid triggering sync loop on timestamp change
let json = serde_json::to_string_pretty(&sanitized)
.map_err(|e| SyncError::SerializationError(format!("Failed to serialize profile: {e}")))?;
+134 -2
View File
@@ -8,6 +8,7 @@ use std::path::Path;
use std::time::SystemTime;
use super::types::{SyncError, SyncResult};
use crate::profile::types::BrowserProfile;
/// Default exclude patterns for volatile browser profile files.
/// Patterns use `**/` prefix to match at any directory depth, since the sync
@@ -209,6 +210,39 @@ fn hash_file(path: &Path) -> Result<Option<String>, SyncError> {
Ok(Some(hasher.finalize().to_hex().to_string()))
}
/// Compute blake3 hash of metadata.json after sanitizing volatile fields.
/// This prevents infinite sync loops where updating last_sync triggers a new sync.
fn hash_sanitized_metadata(path: &Path) -> Result<Option<String>, SyncError> {
let content = match fs::read_to_string(path) {
Ok(c) => c,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(None),
Err(e) => {
return Err(SyncError::IoError(format!(
"Failed to read metadata at {}: {e}",
path.display()
)));
}
};
let mut profile: BrowserProfile = serde_json::from_str(&content).map_err(|e| {
SyncError::SerializationError(format!("Failed to parse metadata for hashing: {e}"))
})?;
// Sanitize volatile fields that should not trigger a re-sync
profile.last_sync = None;
profile.process_id = None;
profile.last_launch = None;
let sanitized_json = serde_json::to_string(&profile).map_err(|e| {
SyncError::SerializationError(format!("Failed to serialize sanitized metadata: {e}"))
})?;
let mut hasher = blake3::Hasher::new();
hasher.update(sanitized_json.as_bytes());
Ok(Some(hasher.finalize().to_hex().to_string()))
}
/// Get mtime as unix timestamp
/// Returns None if the file doesn't exist (was deleted)
fn get_mtime(path: &Path) -> Result<Option<i64>, SyncError> {
@@ -324,7 +358,19 @@ pub fn generate_manifest(
*max_mtime = (*max_mtime).max(mtime);
// Check cache for existing hash
let hash = if let Some(cached_hash) = cache.get(&relative_path, size, mtime) {
let hash = if relative_path == "metadata.json" {
// Special case: sanitize metadata.json before hashing to prevent sync loops
match hash_sanitized_metadata(&path)? {
Some(computed_hash) => computed_hash,
None => {
log::debug!(
"File disappeared during manifest generation, skipping: {}",
path.display()
);
continue;
}
}
} else if let Some(cached_hash) = cache.get(&relative_path, size, mtime) {
cached_hash.to_string()
} else {
match hash_file(&path)? {
@@ -592,7 +638,12 @@ mod tests {
fs::write(profile_dir.join("profile/Crashpad/report"), "exclude").unwrap();
// metadata.json at root
fs::write(profile_dir.join("metadata.json"), "keep").unwrap();
let profile = BrowserProfile::default();
fs::write(
profile_dir.join("metadata.json"),
serde_json::to_string(&profile).unwrap(),
)
.unwrap();
let mut cache = HashCache::default();
let manifest = generate_manifest("test-profile", &profile_dir, &mut cache).unwrap();
@@ -800,4 +851,85 @@ mod tests {
assert!(diff.files_to_delete_remote.is_empty());
assert!(diff.files_to_delete_local.is_empty());
}
#[test]
fn test_generate_manifest_sanitizes_metadata() {
let temp_dir = TempDir::new().unwrap();
let profile_dir = temp_dir.path().join("profile");
fs::create_dir_all(&profile_dir).unwrap();
let profile_id = uuid::Uuid::new_v4();
let metadata_path = profile_dir.join("metadata.json");
let profile = BrowserProfile {
id: profile_id,
name: "test-profile".to_string(),
last_sync: Some(100),
process_id: Some(1234),
..Default::default()
};
fs::write(&metadata_path, serde_json::to_string(&profile).unwrap()).unwrap();
let mut cache = HashCache::default();
let manifest1 = generate_manifest(&profile_id.to_string(), &profile_dir, &mut cache).unwrap();
let hash1 = manifest1
.files
.iter()
.find(|f| f.path == "metadata.json")
.unwrap()
.hash
.clone();
// Update volatile fields
let profile2 = BrowserProfile {
id: profile_id,
name: "test-profile".to_string(),
last_sync: Some(200),
process_id: Some(5678),
..Default::default()
};
fs::write(&metadata_path, serde_json::to_string(&profile2).unwrap()).unwrap();
let manifest2 = generate_manifest(&profile_id.to_string(), &profile_dir, &mut cache).unwrap();
let hash2 = manifest2
.files
.iter()
.find(|f| f.path == "metadata.json")
.unwrap()
.hash
.clone();
// Hash should be identical because volatile fields are sanitized
assert_eq!(
hash1, hash2,
"Metadata hash should be stable across last_sync/process_id updates"
);
// Change a non-volatile field
let profile3 = BrowserProfile {
id: profile_id,
name: "changed-name".to_string(),
last_sync: Some(200),
..Default::default()
};
fs::write(&metadata_path, serde_json::to_string(&profile3).unwrap()).unwrap();
let manifest3 = generate_manifest(&profile_id.to_string(), &profile_dir, &mut cache).unwrap();
let hash3 = manifest3
.files
.iter()
.find(|f| f.path == "metadata.json")
.unwrap()
.hash
.clone();
// Hash should be different because name changed
assert_ne!(
hash1, hash3,
"Metadata hash should change when non-volatile fields change"
);
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Donut",
"version": "0.18.0",
"version": "0.18.1",
"identifier": "com.donutbrowser",
"build": {
"beforeDevCommand": "pnpm copy-proxy-binary && pnpm dev",