Compare commits

...

15 Commits

Author SHA1 Message Date
zhom e1c55233f7 chore: fix permissions for contributors workflow 2025-06-18 06:14:36 +04:00
zhom 801a2b5732 docs: rename agent instructions doc 2025-06-18 06:11:38 +04:00
zhom abe5c691ce docs: stale issue workflow 2025-06-18 06:08:15 +04:00
zhom 2f9a17c6e0 docs: automatically add contributors to readme 2025-06-18 05:38:38 +04:00
zhom fcdb80f75a docs: github newcomer greetings 2025-06-18 05:34:53 +04:00
zhom 7568e7998d chore : version bump 2025-06-18 03:00:45 +04:00
zhom e0f4f93c30 fix: don't create unique temp dir for every cli call 2025-06-18 02:59:11 +04:00
zhom d142b7f79b style: don't show release notes 2025-06-18 02:39:40 +04:00
zhom dc5553a5d3 chore: version bump 2025-06-18 01:30:02 +04:00
zhom 07445ff95b build: add content read permissions for linting workflows 2025-06-18 01:26:34 +04:00
zhom 6ecbc39e46 build: pin action versions 2025-06-18 01:25:21 +04:00
zhom 67849c00d5 refactor: use tmp for temp dirs and add more robust error handling for updateProxyConfig 2025-06-18 01:19:10 +04:00
zhom bdf71e4ef8 build: revert dependabot automerge workflow 2025-06-18 00:57:40 +04:00
zhom 2d2ebba40e build: assign read permission to all actions without one 2025-06-18 00:17:58 +04:00
zhom 2caac5bf4c build: pin action versions 2025-06-18 00:12:26 +04:00
22 changed files with 249 additions and 68 deletions
+5 -5
View File
@@ -29,13 +29,13 @@ jobs:
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- name: Set up pnpm package manager
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda #v4.1.0
- name: Set up Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0
with:
node-version-file: .node-version
cache: "pnpm"
@@ -44,7 +44,7 @@ jobs:
run: pnpm install --frozen-lockfile
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf #v3.29.0
with:
queries: security-extended
languages: ${{ matrix.language }}
@@ -56,6 +56,6 @@ jobs:
pnpm run build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf #v3.29.0
with:
category: "/language:${{matrix.language}}"
+21
View File
@@ -0,0 +1,21 @@
on:
push:
branches:
- main
permissions:
contents: write
pull-requests: write
jobs:
contrib-readme-job:
runs-on: ubuntu-latest
name: Automatically update the contributors list in the README
permissions:
contents: write
pull-requests: write
steps:
- name: Contribute List
uses: akhilmhdh/contributors-readme-action@1ff4c56187458b34cd602aee93e897344ce34bfc #v2.3.10
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,82 @@
name: Dependabot Automerge
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
checks: read
jobs:
security-scan:
name: Security Vulnerability Scan
if: ${{ github.actor == 'dependabot[bot]' }}
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@e69cc6c86b31f1e7e23935bbe7031b50e51082de" # v2.0.2
with:
scan-args: |-
-r
--skip-git
--lockfile=pnpm-lock.yaml
--lockfile=src-tauri/Cargo.lock
--lockfile=nodecar/pnpm-lock.yaml
./
permissions:
security-events: write
contents: read
actions: read
lint-js:
name: Lint JavaScript/TypeScript
if: ${{ github.actor == 'dependabot[bot]' }}
uses: ./.github/workflows/lint-js.yml
secrets: inherit
permissions:
contents: read
lint-rust:
name: Lint Rust
if: ${{ github.actor == 'dependabot[bot]' }}
uses: ./.github/workflows/lint-rs.yml
secrets: inherit
permissions:
contents: read
codeql:
name: CodeQL
uses: ./.github/workflows/codeql.yml
secrets: inherit
permissions:
security-events: write
contents: read
packages: read
actions: read
spellcheck:
name: Spell Check
uses: ./.github/workflows/spellcheck.yml
secrets: inherit
permissions:
contents: read
dependabot-automerge:
name: Dependabot Automerge
if: ${{ github.actor == 'dependabot[bot]' }}
needs: [security-scan, lint-js, lint-rust, codeql, spellcheck]
runs-on: ubuntu-latest
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b #v2.4.0
with:
compat-lookup: true
github-token: "${{ secrets.SECRET_DEPENDABOT_GITHUB_TOKEN }}"
- name: Auto-merge minor and patch updates
uses: ridedott/merge-me-action@338053c6f9b9311a6be80208f6f0723981e40627 #v2.10.122
with:
GITHUB_TOKEN: ${{ secrets.SECRET_DEPENDABOT_GITHUB_TOKEN }}
PRESET: DEPENDABOT_MINOR
MERGE_METHOD: SQUASH
timeout-minutes: 10
+16
View File
@@ -0,0 +1,16 @@
name: Greetings
on: [pull_request_target, issues]
jobs:
greeting:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/first-interaction@34f15e814fe48ac9312ccf29db4e74fa767cbab7 #v1.3.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: "Thank you for your first issue! If it's a feature request, please make sure it's clear what you want, why you want it, and how important it is to you. If you posted a bug report, please make sure it includes as much detail as possible. Thank you ❤️"
pr-message: "Welcome to the community and thank you for your first contribution ❤️ A human will review your PR shortly. Make sure that the pipelines are green, so that the PR is considered ready for a review and could be merged."
+6 -3
View File
@@ -16,6 +16,9 @@ on:
- ".github/workflows/lint-rs.yml"
- ".github/workflows/osv.yml"
permissions:
contents: read
jobs:
build:
strategy:
@@ -31,13 +34,13 @@ jobs:
run: git config --global core.autocrlf false
- name: Checkout repository code
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- name: Set up pnpm package manager
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda #v4.1.0
- name: Set up Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0
with:
node-version-file: .node-version
cache: "pnpm"
+8 -4
View File
@@ -24,6 +24,9 @@ on:
- "tsconfig.json"
- "biome.json"
permissions:
contents: read
jobs:
build:
strategy:
@@ -39,20 +42,21 @@ jobs:
run: git config --global core.autocrlf false
- name: Checkout repository code
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- name: Set up pnpm package manager
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda #v4.1.0
- name: Set up Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0
with:
node-version-file: .node-version
cache: "pnpm"
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b #master
with:
toolchain: stable
components: rustfmt, clippy
- name: Install cargo-audit
+4
View File
@@ -16,11 +16,15 @@ jobs:
name: Lint JavaScript/TypeScript
uses: ./.github/workflows/lint-js.yml
secrets: inherit
permissions:
contents: read
lint-rust:
name: Lint Rust
uses: ./.github/workflows/lint-rs.yml
secrets: inherit
permissions:
contents: read
security-scan:
name: Security Vulnerability Scan
+14 -7
View File
@@ -31,11 +31,15 @@ jobs:
name: Lint JavaScript/TypeScript
uses: ./.github/workflows/lint-js.yml
secrets: inherit
permissions:
contents: read
lint-rust:
name: Lint Rust
uses: ./.github/workflows/lint-rs.yml
secrets: inherit
permissions:
contents: read
codeql:
name: CodeQL
@@ -51,6 +55,8 @@ jobs:
name: Spell Check
uses: ./.github/workflows/spellcheck.yml
secrets: inherit
permissions:
contents: read
release:
needs: [security-scan, lint-js, lint-rust, codeql, spellcheck]
@@ -99,19 +105,20 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0
with:
node-version-file: .node-version
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda #v4.1.0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b #master
with:
toolchain: stable
targets: ${{ matrix.target }}
- name: Install dependencies (Ubuntu only)
@@ -121,7 +128,7 @@ jobs:
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev pkg-config xdg-utils
- name: Rust cache
uses: swatinem/rust-cache@v2
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 #v2.7.8
with:
workdir: ./src-tauri
@@ -153,7 +160,7 @@ jobs:
run: pnpm build
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
uses: tauri-apps/tauri-action@42e9df6c59070d114bf90dcd3943a1b8f138b113 #v0.5.20
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REF_NAME: ${{ github.ref_name }}
@@ -166,7 +173,7 @@ jobs:
args: ${{ matrix.args }}
- name: Commit CHANGELOG.md
uses: stefanzweifel/git-auto-commit-action@v6
uses: stefanzweifel/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 #v6.0.1
with:
branch: main
commit_message: "docs: update CHANGELOG.md for ${{ github.ref_name }} [skip ci]"
+13 -6
View File
@@ -30,11 +30,15 @@ jobs:
name: Lint JavaScript/TypeScript
uses: ./.github/workflows/lint-js.yml
secrets: inherit
permissions:
contents: read
lint-rust:
name: Lint Rust
uses: ./.github/workflows/lint-rs.yml
secrets: inherit
permissions:
contents: read
codeql:
name: CodeQL
@@ -50,6 +54,8 @@ jobs:
name: Spell Check
uses: ./.github/workflows/spellcheck.yml
secrets: inherit
permissions:
contents: read
rolling-release:
needs: [security-scan, lint-js, lint-rust, codeql, spellcheck]
@@ -98,19 +104,20 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0
with:
node-version-file: .node-version
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda #v4.1.0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b #master
with:
toolchain: stable
targets: ${{ matrix.target }}
- name: Install dependencies (Ubuntu only)
@@ -120,7 +127,7 @@ jobs:
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev pkg-config xdg-utils
- name: Rust cache
uses: swatinem/rust-cache@v2
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 #v2.7.8
with:
workdir: ./src-tauri
@@ -161,7 +168,7 @@ jobs:
echo "Generated timestamp: ${TIMESTAMP}-${COMMIT_HASH}"
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
uses: tauri-apps/tauri-action@42e9df6c59070d114bf90dcd3943a1b8f138b113 #v0.5.20
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_TAG: "nightly-${{ steps.timestamp.outputs.timestamp }}"
+2 -2
View File
@@ -21,6 +21,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- name: Spell Check Repo
uses: crate-ci/typos@v1.33.1
uses: crate-ci/typos@b1ae8d918b6e85bd611117d3d9a3be4f903ee5e4 #v1.33.1
+21
View File
@@ -0,0 +1,21 @@
name: Mark stale issues and pull requests
on:
schedule:
- cron: "35 23 * * *"
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.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-label: "stale"
stale-pr-label: "stale"
+3
View File
@@ -1,6 +1,7 @@
{
"cSpell.words": [
"ahooks",
"akhilmhdh",
"appimage",
"appindicator",
"applescript",
@@ -38,12 +39,14 @@
"libpango",
"librsvg",
"libwebkit",
"libxdo",
"mountpoint",
"msvc",
"msys",
"Mullvad",
"mullvadbrowser",
"nodecar",
"nodemon",
"ntlm",
"objc",
"orhun",
+5
View File
@@ -83,6 +83,11 @@ Have questions or want to contribute? We'd love to hear from you!
</picture>
</a>
## Contributors
<!-- readme: collaborators,contributors -start -->
<!-- readme: collaborators,contributors -end -->
## Contact
Have an urgent question or want to report a security vulnerability? Send an email to contact at donutbrowser dot com and we'll get back to you as fast as possible.
+4
View File
@@ -28,8 +28,12 @@
"get-port": "^7.1.0",
"nodemon": "^3.1.10",
"proxy-chain": "^2.5.9",
"tmp": "^0.2.3",
"ts-node": "^10.9.2",
"typescript": "^5.8.3",
"typescript-eslint": "^8.34.0"
},
"devDependencies": {
"@types/tmp": "^0.2.6"
}
}
+12 -11
View File
@@ -1,8 +1,7 @@
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
import tmp from "tmp";
// Define the proxy configuration type
export interface ProxyConfig {
id: string;
upstreamUrl: string;
@@ -12,10 +11,8 @@ export interface ProxyConfig {
pid?: number;
}
// Path to store proxy configurations
const STORAGE_DIR = path.join(os.tmpdir(), "donutbrowser", "proxies");
const STORAGE_DIR = path.join(tmp.tmpdir, "donutbrowser", "proxies");
// Ensure storage directory exists
if (!fs.existsSync(STORAGE_DIR)) {
fs.mkdirSync(STORAGE_DIR, { recursive: true });
}
@@ -88,7 +85,7 @@ export function listProxyConfigs(): ProxyConfig[] {
try {
const content = fs.readFileSync(
path.join(STORAGE_DIR, file),
"utf-8"
"utf-8",
);
return JSON.parse(content) as ProxyConfig;
} catch (error) {
@@ -111,14 +108,18 @@ export function listProxyConfigs(): ProxyConfig[] {
export function updateProxyConfig(config: ProxyConfig): boolean {
const filePath = path.join(STORAGE_DIR, `${config.id}.json`);
if (!fs.existsSync(filePath)) {
return false;
}
try {
fs.readFileSync(filePath, "utf-8");
fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
return true;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
console.error(
`Config ${config.id} was deleted while the app was running`,
);
return false;
}
console.error(`Error updating proxy config ${config.id}:`, error);
return false;
}
@@ -135,7 +136,7 @@ export function isProcessRunning(pid: number): boolean {
// but checks if it exists
process.kill(pid, 0);
return true;
} catch (error) {
} catch {
return false;
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "donutbrowser",
"private": true,
"license": "AGPL-3.0",
"version": "0.5.2",
"version": "0.5.4",
"type": "module",
"scripts": {
"dev": "next dev --turbopack",
+18
View File
@@ -183,6 +183,9 @@ importers:
proxy-chain:
specifier: ^2.5.9
version: 2.5.9
tmp:
specifier: ^0.2.3
version: 0.2.3
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@24.0.1)(typescript@5.8.3)
@@ -192,6 +195,10 @@ importers:
typescript-eslint:
specifier: ^8.34.0
version: 8.34.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
devDependencies:
'@types/tmp':
specifier: ^0.2.6
version: 0.2.6
packages:
@@ -1542,6 +1549,9 @@ packages:
'@types/react@19.1.8':
resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==}
'@types/tmp@0.2.6':
resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==}
'@typescript-eslint/eslint-plugin@8.34.0':
resolution: {integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -3409,6 +3419,10 @@ packages:
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
engines: {node: '>=12.0.0'}
tmp@0.2.3:
resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==}
engines: {node: '>=14.14'}
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -4825,6 +4839,8 @@ snapshots:
dependencies:
csstype: 3.1.3
'@types/tmp@0.2.6': {}
'@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
@@ -7001,6 +7017,8 @@ snapshots:
fdir: 6.4.5(picomatch@4.0.2)
picomatch: 4.0.2
tmp@0.2.3: {}
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
+1 -1
View File
@@ -993,7 +993,7 @@ dependencies = [
[[package]]
name = "donutbrowser"
version = "0.5.2"
version = "0.5.4"
dependencies = [
"async-trait",
"base64 0.22.1",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "donutbrowser"
version = "0.5.2"
version = "0.5.4"
description = "Simple Yet Powerful Browser Orchestrator"
authors = ["zhom@github"]
edition = "2021"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Donut Browser",
"version": "0.5.2",
"version": "0.5.4",
"identifier": "com.donutbrowser",
"build": {
"beforeDevCommand": "pnpm dev",
+11 -26
View File
@@ -35,20 +35,20 @@ export function AppUpdateToast({
};
return (
<div className="flex items-start w-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4 shadow-lg max-w-md">
<div className="flex items-start p-4 w-full max-w-md bg-white rounded-lg border border-gray-200 shadow-lg dark:bg-gray-800 dark:border-gray-700">
<div className="mr-3 mt-0.5">
{isUpdating ? (
<LuRefreshCw className="h-5 w-5 text-blue-500 animate-spin flex-shrink-0" />
<LuRefreshCw className="flex-shrink-0 w-5 h-5 text-blue-500 animate-spin" />
) : (
<FaDownload className="h-5 w-5 text-blue-500 flex-shrink-0" />
<FaDownload className="flex-shrink-0 w-5 h-5 text-blue-500" />
)}
</div>
<div className="flex-1 min-w-0">
<div className="flex items-start justify-between gap-2">
<div className="flex gap-2 justify-between items-start">
<div className="flex flex-col gap-1">
<div className="flex items-center gap-2">
<span className="font-semibold text-foreground text-sm">
<div className="flex gap-2 items-center">
<span className="text-sm font-semibold text-foreground">
Donut Browser Update Available
</span>
<Badge
@@ -69,9 +69,9 @@ export function AppUpdateToast({
variant="ghost"
size="sm"
onClick={onDismiss}
className="h-6 w-6 p-0 shrink-0"
className="p-0 w-6 h-6 shrink-0"
>
<FaTimes className="h-3 w-3" />
<FaTimes className="w-3 h-3" />
</Button>
)}
</div>
@@ -83,13 +83,13 @@ export function AppUpdateToast({
)}
{!isUpdating && (
<div className="flex items-center gap-2 mt-3">
<div className="flex gap-2 items-center mt-3">
<Button
onClick={() => void handleUpdateClick()}
size="sm"
className="flex items-center gap-2 text-xs"
className="flex gap-2 items-center text-xs"
>
<FaDownload className="h-3 w-3" />
<FaDownload className="w-3 h-3" />
Update Now
</Button>
<Button
@@ -102,21 +102,6 @@ export function AppUpdateToast({
</Button>
</div>
)}
{updateInfo.release_notes && !isUpdating && (
<div className="mt-2">
<details className="text-xs">
<summary className="cursor-pointer text-muted-foreground hover:text-foreground">
Release Notes
</summary>
<div className="mt-1 text-muted-foreground whitespace-pre-wrap max-h-32 overflow-y-auto">
{updateInfo.release_notes.length > 200
? `${updateInfo.release_notes.substring(0, 200)}...`
: updateInfo.release_notes}
</div>
</details>
</div>
)}
</div>
</div>
);