6.8 KiB
Project Guidelines
Note
: CLAUDE.md is a symlink to AGENTS.md — editing either file updates both. 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 testat the root of the project - Always run this command before finishing a task to ensure the application isn't broken
pnpm lintincludes spellcheck via 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 insrc/lib/themes.ts - Available semantic color classes:
background,foreground— page/container background and textcard,card-foreground— card surfacespopover,popover-foreground— dropdown/popover surfacesprimary,primary-foreground— primary actionssecondary,secondary-foreground— secondary actionsmuted,muted-foreground— muted/disabled elementsaccent,accent-foreground— accent highlightsdestructive,destructive-foreground— errors, danger, delete actionssuccess,success-foreground— success states, valid indicatorswarning,warning-foreground— warnings, caution messagesborder— borderschart-1throughchart-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
Publishing Linux Repositories
The scripts/publish-repo.sh script publishes DEB and RPM packages to Cloudflare R2 (served at repo.donutbrowser.com). It requires Linux tools, so run it in Docker on macOS:
docker run --rm -v "$(pwd):/work" -w /work --env-file .env -e GH_TOKEN="$(gh auth token)" \
ubuntu:24.04 bash -c '
export DEBIAN_FRONTEND=noninteractive &&
apt-get update -qq > /dev/null 2>&1 &&
apt-get install -y -qq dpkg-dev createrepo-c gzip curl python3-pip > /dev/null 2>&1 &&
pip3 install --break-system-packages awscli > /dev/null 2>&1 &&
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null &&
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list &&
apt-get update -qq > /dev/null 2>&1 && apt-get install -y -qq gh > /dev/null 2>&1 &&
bash scripts/publish-repo.sh v0.18.1'
The .github/workflows/publish-repos.yml workflow runs automatically after stable releases and can also be triggered manually via gh workflow run publish-repos.yml -f tag=v0.18.1.
Required env vars / secrets: R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_ENDPOINT_URL, R2_BUCKET_NAME.
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.