{"id":31827389,"url":"https://github.com/patrickjaja/claude-desktop-bin","last_synced_at":"2026-04-26T20:00:48.507Z","repository":{"id":315058470,"uuid":"1057909657","full_name":"patrickjaja/claude-desktop-bin","owner":"patrickjaja","description":"Unofficial Linux packages for Claude Desktop AI assistant with automated updates.","archived":false,"fork":false,"pushed_at":"2026-04-23T22:15:11.000Z","size":375742,"stargazers_count":251,"open_issues_count":3,"forks_count":15,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-04-23T22:23:05.983Z","etag":null,"topics":["anthropic","appimage","arch-linux","aur","claude","claude-desktop","deb","electron","linux","rpm","wayland"],"latest_commit_sha":null,"homepage":"https://www.reddit.com/r/ClaudeAI/comments/1r871b0/claude_desktop_on_linux_chat_cowork_code/","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patrickjaja.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-16T11:19:05.000Z","updated_at":"2026-04-23T22:15:15.000Z","dependencies_parsed_at":"2026-02-16T21:02:15.565Z","dependency_job_id":"ec54b914-cd6e-4bba-befb-8e3efa3817bc","html_url":"https://github.com/patrickjaja/claude-desktop-bin","commit_stats":null,"previous_names":["patrickjaja/claude-desktop-bin"],"tags_count":139,"template":false,"template_full_name":null,"purl":"pkg:github/patrickjaja/claude-desktop-bin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjaja%2Fclaude-desktop-bin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjaja%2Fclaude-desktop-bin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjaja%2Fclaude-desktop-bin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjaja%2Fclaude-desktop-bin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickjaja","download_url":"https://codeload.github.com/patrickjaja/claude-desktop-bin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjaja%2Fclaude-desktop-bin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32310804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T19:15:34.056Z","status":"ssl_error","status_checked_at":"2026-04-26T19:15:15.467Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","appimage","arch-linux","aur","claude","claude-desktop","deb","electron","linux","rpm","wayland"],"created_at":"2025-10-11T18:25:34.819Z","updated_at":"2026-04-26T20:00:48.486Z","avatar_url":"https://github.com/patrickjaja.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Claude Desktop for Linux\n\n[![Claude Desktop](https://img.shields.io/endpoint?url=https://patrickjaja.github.io/claude-desktop-bin/badges/version-check.json)](https://claude.ai/download)\n[![AUR version](https://img.shields.io/aur/version/claude-desktop-bin)](https://aur.archlinux.org/packages/claude-desktop-bin)\n[![APT repo](https://img.shields.io/endpoint?url=https://patrickjaja.github.io/claude-desktop-bin/badges/apt-repo.json)](https://github.com/patrickjaja/claude-desktop-bin#debian--ubuntu-apt-repository)\n[![RPM repo](https://img.shields.io/endpoint?url=https://patrickjaja.github.io/claude-desktop-bin/badges/rpm-repo.json)](https://github.com/patrickjaja/claude-desktop-bin#fedora--rhel-dnf-repository)\n[![AppImage](https://img.shields.io/endpoint?url=https://patrickjaja.github.io/claude-desktop-bin/badges/appimage.json)](https://github.com/patrickjaja/claude-desktop-bin#appimage-any-distro)\n[![Nix flake](https://img.shields.io/endpoint?url=https://patrickjaja.github.io/claude-desktop-bin/badges/nix.json)](https://github.com/patrickjaja/claude-desktop-bin#nixos--nix)\n[![Build \u0026 Release](https://github.com/patrickjaja/claude-desktop-bin/actions/workflows/build-and-release.yml/badge.svg)](https://github.com/patrickjaja/claude-desktop-bin/actions/workflows/build-and-release.yml)\n\nUnofficial Linux packages for Claude Desktop AI assistant with automated updates.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eTable of contents\u003c/b\u003e\u003c/summary\u003e\n\n- [Installation](#installation)\n- [Optional Dependencies](#optional-dependencies)\n- [Features](#features)\n  - [Custom Features](#custom-features)\n- [Claude Chat](#claude-chat)\n- [Claude Code Integration](#claude-code-integration)\n- [Cowork Integration](#cowork-integration)\n- [CoworkSpaces](#coworkspaces)\n- [Computer Use](#computer-use)\n- [Hardware Buddy (Nibblet)](#hardware-buddy-nibblet)\n- [Third-Party Inference](#third-party-inference)\n- [Custom Themes (Experimental)](#custom-themes-experimental)\n- [Patches](#patches)\n- [Automation](#automation)\n- [Repository Structure](#repository-structure)\n- [Multiple Profiles](#multiple-profiles)\n  - [Quick start](#quick-start)\n  - [The default (unnamed) profile](#the-default-unnamed-profile)\n  - [Named profiles](#named-profiles)\n  - [Selecting a profile at launch](#selecting-a-profile-at-launch)\n  - [What's isolated](#whats-isolated)\n  - [Removing a profile](#removing-a-profile)\n  - [SSO and URL routing](#sso-and-url-routing)\n  - [Limitations](#limitations)\n  - [Why a copy of the binary?](#why-a-copy-of-the-binary)\n- [Environment Variables](#environment-variables)\n- [Debugging](#debugging)\n- [Dispatch Architecture](#dispatch-architecture)\n- [Known Limitations](#known-limitations)\n- [Tips](#tips)\n- [See Also](#see-also)\n- [Legal Notice](#legal-notice)\n\n\u003c/details\u003e\n\n## Installation\n\n\u003e After installing, see [Optional Dependencies](#optional-dependencies) to enable Computer Use, Cowork, and more.\n\n### Arch Linux / Manjaro (AUR)\n```bash\nyay -S claude-desktop-bin\n\n# Optional: Computer Use dependencies\n# Pick the line matching your session type (echo $XDG_SESSION_TYPE and echo $XDG_CURRENT_DESKTOP):\n# X11/XWayland:\nsudo pacman -S --needed xdotool scrot imagemagick wmctrl\n# Wayland (Sway):\nsudo pacman -S --needed ydotool grim jq\n# Wayland (Hyprland):\nsudo pacman -S --needed ydotool grim hyprland\n# Wayland (KDE Plasma):\nsudo pacman -S --needed ydotool xdotool spectacle imagemagick\n# Wayland (GNOME):\nsudo pacman -S --needed ydotool xdotool glib2 gnome-screenshot imagemagick python-gobject gst-plugin-pipewire\n# GNOME Wayland: enable Quick Entry hotkey (one-time, after install):\n# claude-desktop --install-gnome-hotkey\n# Optional: socat (faster Quick Entry toggle, ~2ms vs ~25ms python3 — not required)\nsudo pacman -S --needed socat\n```\nOn Wayland, the `ydotoold` daemon must be running — see [ydotool setup](#ydotool-setup-wayland).\n\nUpdates arrive through your AUR helper (e.g. `yay -Syu`).\n\n### Debian / Ubuntu (APT Repository)\n```bash\n# Add repository (one-time setup)\ncurl -fsSL https://patrickjaja.github.io/claude-desktop-bin/install.sh | sudo bash\n\n# Install\nsudo apt install claude-desktop-bin\n\n# Optional: Computer Use dependencies\n# Pick the line matching your session type (echo $XDG_SESSION_TYPE and echo $XDG_CURRENT_DESKTOP):\n# X11/XWayland:\nsudo apt install xdotool scrot imagemagick wmctrl\n# Wayland (Sway):\nsudo apt install ydotool grim jq\n# Wayland (Hyprland):\nsudo apt install ydotool grim hyprland\n# Wayland (KDE Plasma):\nsudo apt install ydotool xdotool kde-spectacle imagemagick\n# Wayland (GNOME):\nsudo apt install ydotool xdotool libglib2.0-bin gnome-screenshot imagemagick python3-gi gstreamer1.0-pipewire\n# GNOME Wayland: enable Quick Entry hotkey (one-time, after install):\n# claude-desktop --install-gnome-hotkey\n# Optional: socat (faster Quick Entry toggle, ~2ms vs ~25ms python3 — not required)\nsudo apt install socat\n```\n\n\u003e **Wayland users:** [Computer Use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/computer-use-tool) requires ydotool v1.0+, but Ubuntu/Debian ship v0.1.8 which is **too old**. Run the [ydotool setup script](#ydotool-setup-wayland) — without this, clicks will not work.\n\nUpdates are automatic via `sudo apt update \u0026\u0026 sudo apt upgrade`.\n\n\u003cdetails\u003e\n\u003csummary\u003eManual .deb install (without APT repo)\u003c/summary\u003e\n\n```bash\nwget https://github.com/patrickjaja/claude-desktop-bin/releases/latest/download/claude-desktop-bin_1.4758.0-2_amd64.deb\nsudo dpkg -i claude-desktop-bin_*_amd64.deb\n```\n\u003c/details\u003e\n\n### Fedora / RHEL (DNF Repository)\n```bash\n# Add repository (one-time setup)\ncurl -fsSL https://patrickjaja.github.io/claude-desktop-bin/install-rpm.sh | sudo bash\n\n# Install\nsudo dnf install claude-desktop-bin\n\n# Optional: Computer Use dependencies\n# Pick the line matching your session type (echo $XDG_SESSION_TYPE and echo $XDG_CURRENT_DESKTOP):\n# X11/XWayland:\nsudo dnf install xdotool scrot ImageMagick wmctrl\n# Wayland (Sway):\nsudo dnf install ydotool grim jq\n# Wayland (Hyprland):\nsudo dnf install ydotool grim hyprland\n# Wayland (KDE Plasma):\nsudo dnf install ydotool xdotool spectacle ImageMagick\n# Wayland (GNOME):\nsudo dnf install ydotool xdotool glib2 gnome-screenshot ImageMagick python3-gobject gstreamer1-plugin-pipewire\n# GNOME Wayland: enable Quick Entry hotkey (one-time, after install):\n# claude-desktop --install-gnome-hotkey\n# Optional: socat (faster Quick Entry toggle, ~2ms vs ~25ms python3 — not required)\nsudo dnf install socat\n```\nOn Wayland, the `ydotoold` daemon must be running — see [ydotool setup](#ydotool-setup-wayland).\n\nUpdates are automatic via `sudo dnf upgrade`.\n\n\u003cdetails\u003e\n\u003csummary\u003eManual .rpm install (without DNF repo)\u003c/summary\u003e\n\n```bash\nwget https://github.com/patrickjaja/claude-desktop-bin/releases/latest/download/claude-desktop-bin-1.4758.0-2.x86_64.rpm\nsudo dnf install ./claude-desktop-bin-*.x86_64.rpm\n```\n\u003c/details\u003e\n\n### NixOS / Nix\n```bash\n# Try without installing\nnix run github:patrickjaja/claude-desktop-bin\n\n# Or add to flake.nix\nnix profile install github:patrickjaja/claude-desktop-bin\n```\n\nFor Computer Use, pass optional dependencies via override. Pick the block matching your session type (`echo $XDG_SESSION_TYPE` and `echo $XDG_CURRENT_DESKTOP`):\n```nix\nclaude-desktop.override {\n  # X11/XWayland:\n  xdotool = pkgs.xdotool; scrot = pkgs.scrot;\n  imagemagick = pkgs.imagemagick; wmctrl = pkgs.wmctrl;\n  # Wayland (wlroots — Sway, Hyprland):\n  # ydotool = pkgs.ydotool; grim = pkgs.grim; jq = pkgs.jq;\n  # hyprland = pkgs.hyprland;\n  # Wayland (KDE Plasma):\n  # ydotool = pkgs.ydotool; xdotool = pkgs.xdotool;\n  # spectacle = pkgs.kdePackages.spectacle; imagemagick = pkgs.imagemagick;\n  # Wayland (GNOME):\n  # ydotool = pkgs.ydotool; xdotool = pkgs.xdotool;\n  # glib = pkgs.glib; gnome-screenshot = pkgs.gnome-screenshot;\n  # GNOME Wayland: enable Quick Entry hotkey (one-time, after install):\n  # Run: claude-desktop --install-gnome-hotkey\n  # Optional: socat (faster Quick Entry toggle, ~2ms vs ~25ms python3 — not required)\n  socat = pkgs.socat;\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eNixOS flake configuration\u003c/summary\u003e\n\n```nix\n{\n  inputs.claude-desktop.url = \"github:patrickjaja/claude-desktop-bin\";\n\n  # In your system config:\n  environment.systemPackages = [\n    inputs.claude-desktop.packages.x86_64-linux.default\n  ];\n}\n```\n\u003c/details\u003e\n\n\u003e **Note:** Update by running `nix flake update` to pull the latest version. `nix run` always fetches the latest.\n\n\u003e **Dispatch/Cowork:** Requires Claude Code \u003e= 2.1.86 (fixes `CLAUDE_CODE_BRIEF` env parsing). If nixpkgs ships an older version, [install Claude Code manually](https://docs.anthropic.com/en/docs/claude-code/overview) and override with `extraSessionPaths`:\n\u003e ```nix\n\u003e claude-desktop.override {\n\u003e   extraSessionPaths = [ \"/path/to/directory/containing/claude\" ];\n\u003e }\n\u003e ```\n\n### AppImage (Any Distro)\n```bash\n# Download from GitHub Releases\nwget https://github.com/patrickjaja/claude-desktop-bin/releases/latest/download/Claude_Desktop-1.4758.0-x86_64.AppImage\nchmod +x Claude_Desktop-*-x86_64.AppImage\n./Claude_Desktop-*-x86_64.AppImage\n```\n\n\u003e **Computer Use:** Install optional dependencies using your distro's package manager — see the [Computer Use packages table](#optional-dependencies). On Wayland, `ydotool` v1.0+ is required — see [ydotool setup](#ydotool-setup-wayland).\n\n\u003e **Update:** AppImage supports delta updates via [appimageupdatetool](https://github.com/AppImageCommunity/AppImageUpdate). Only changed blocks are downloaded.\n\u003e ```bash\n\u003e appimageupdatetool Claude_Desktop-*-x86_64.AppImage\n\u003e # Or from within the AppImage:\n\u003e ./Claude_Desktop-*-x86_64.AppImage --appimage-update\n\u003e ```\n\u003e Compatible with [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) and [Gear Lever](https://github.com/mijorus/gearlever) for automatic update notifications.\n\n### From Source\n```bash\ngit clone https://github.com/patrickjaja/claude-desktop-bin.git\ncd claude-desktop-bin\n./scripts/build-local.sh --install\n```\n\n\u003e **Note:** Source builds do not receive automatic updates. Pull and rebuild to update.\n\n### ARM64 / aarch64 (Raspberry Pi 5, NVIDIA DGX Spark, Jetson, etc.)\n\nARM64 .deb, .rpm, AppImage, and Nix packages are available for platforms like **Raspberry Pi 5** (Raspberry Pi OS 64-bit / Ubuntu arm64), **NVIDIA DGX Spark** (Ubuntu 24.04 arm64), and **Jetson** (JetPack/Ubuntu 22.04 arm64). All features including the integrated terminal are supported on ARM64.\n\n```bash\n# Debian/Ubuntu ARM64 (via APT repo)\ncurl -fsSL https://patrickjaja.github.io/claude-desktop-bin/install.sh | sudo bash\nsudo apt install claude-desktop-bin\n\n# Fedora ARM64 (via DNF repo)\ncurl -fsSL https://patrickjaja.github.io/claude-desktop-bin/install-rpm.sh | sudo bash\nsudo dnf install claude-desktop-bin\n```\n\nThe APT and DNF repos serve both x86_64 and arm64 packages — your package manager picks the correct architecture automatically.\n\n## Optional Dependencies\n\nClaude Desktop works without these — features degrade gracefully when tools are missing.\n\n| Feature | Packages | Notes |\n|---------|----------|-------|\n| **Computer Use** | See table below | Install manually for your session type (X11 or Wayland) — the app auto-detects which tools to call at runtime |\n| **Cowork \u0026 Dispatch** | [`claude-cowork-service`](https://github.com/patrickjaja/claude-cowork-service) | Agentic workspace and mobile→desktop task orchestration |\n| **Claude Code CLI** | [`claude`](https://code.claude.com/docs/en/setup) | Required for Code integration, Cowork, and Dispatch |\n| **Browser Tools** | [Claude in Chrome extension](https://chromewebstore.google.com/detail/claude-code/fcoeoabgfenejglbffodgkkbkcdhcgfn) | Uses Claude Code's native host (`~/.claude/chrome/chrome-native-host`). Claude Code CLI must be installed |\n| **Custom MCP Servers** | `nodejs` | Only needed for third-party MCP servers requiring system Node.js |\n\n**Computer Use packages** — check your session type (`echo $XDG_SESSION_TYPE`) and desktop (`echo $XDG_CURRENT_DESKTOP`), then install the matching packages. At runtime, the app auto-detects your compositor and calls the correct tools.\n\n| Operation | X11 / XWayland | Wayland — wlroots (Sway, Hyprland) | Wayland — GNOME | Wayland — KDE Plasma |\n|-----------|---------------|-------------------------------------|-----------------|----------------------|\n| Input automation | `xdotool` | `ydotool` (+ `ydotoold` running) | `ydotool` (+ `ydotoold` running) | `ydotool` (+ `ydotoold` running) |\n| Screenshots | `scrot`, `imagemagick` | `grim` | Portal+PipeWire (GNOME 46+), `gdbus`, `gnome-screenshot` | `spectacle`, `imagemagick` |\n| Clipboard | Electron API (built-in) | Electron API (built-in) | Electron API (built-in) | Electron API (built-in) |\n| Display info | Electron API (built-in) | Electron API (built-in) | Electron API (built-in) | Electron API (built-in) |\n| Window queries | `wmctrl` | `swaymsg` (Sway), `jq` | — | — |\n| Cursor positioning | `xdotool` | `ydotool` | `xdotool` (read), `ydotool` (move) | `xdotool` (read), `ydotool` (move) |\n\n\u003e **GNOME:** On GNOME 46+ (Ubuntu 25.10+, Fedora 40+), screenshots use the XDG ScreenCast portal with PipeWire restore tokens — the first screenshot shows a one-time permission dialog, all subsequent screenshots are silent (requires `python-gobject`/`python3-gi` and `gst-plugin-pipewire`, typically pre-installed on GNOME). Token is stored in `~/.config/Claude/pipewire-restore-token`. Falls back to `gnome-screenshot` and `gdbus` (glib2/libglib2.0-bin).\n\u003e\n\u003e **KDE:** `spectacle` captures screenshots. `imagemagick` (`convert`) crops to monitor region on multi-monitor setups.\n\u003e\n\u003e **Custom screenshot command:** Set `COWORK_SCREENSHOT_CMD` to override the auto-detection. Use placeholders `{FILE}` (output path), `{X}`, `{Y}`, `{W}`, `{H}` (region). Example: `COWORK_SCREENSHOT_CMD='spectacle -b -n -r -o {FILE}'`\n\n\u003ca id=\"ydotool-setup-wayland\"\u003e\u003c/a\u003e\n### ydotool setup (Wayland — all compositors)\n\nComputer Use needs `ydotool` **v1.0+** and the `ydotoold` daemon for mouse/keyboard input on Wayland. Without it, clicks won't reach native Wayland windows. Tested on KDE Plasma and GNOME.\n\n**Arch Linux / Fedora** — ydotool v1.x ships in the repos:\n```bash\n# Arch\nsudo pacman -S ydotool \u0026\u0026 sudo systemctl enable --now ydotool\n\n# Fedora\nsudo dnf install ydotool \u0026\u0026 sudo systemctl enable --now ydotool\n```\n\n**Ubuntu / Debian** — the repo ships v0.1.8 which is **incompatible**. Run the setup script to build and configure v1.0.4:\n```bash\ncurl -fsSL https://raw.githubusercontent.com/patrickjaja/claude-desktop-bin/master/scripts/setup-ydotool.sh | sudo bash\n```\n\n**GNOME users** — also set flat mouse acceleration for accurate cursor positioning:\n```bash\ngsettings set org.gnome.desktop.peripherals.mouse accel-profile flat\n```\n\u003e Note: this changes acceleration for all mice, not just ydotool. KDE handles this per-device automatically.\n\nRestart Claude Desktop after setup.\n\n## Features\n\nAll major Claude Desktop features work natively on Linux through [42+ patches](#patches):\n\n- [**Claude Chat**](#claude-chat) — full desktop UI on Linux (x86_64 and ARM64, X11 and Wayland)\n- [**Claude Code CLI**](#claude-code-integration) — auto-detects system-installed Claude Code ([setup](https://code.claude.com/docs/en/setup))\n- [**Local Agent Mode**](#claude-code-integration) — git worktrees and agent sessions\n- [**Cowork**](#cowork-integration) — agentic workspace with [Live Artifacts](#live-artifacts), [CoworkSpaces](#coworkspaces), and [Imagine/Visualize](#cowork-integration) (requires [claude-cowork-service](https://github.com/patrickjaja/claude-cowork-service))\n- [**Computer Use**](#computer-use) — 27 desktop automation tools (screenshot, click, type, scroll, drag, teach mode, and more) — see [Optional Dependencies](#optional-dependencies)\n- [**Dispatch**](#dispatch-architecture) — phone→desktop task orchestration via Anthropic's dispatch agent (requires [claude-cowork-service](https://github.com/patrickjaja/claude-cowork-service))\n- [**Browser Tools**](#features) — 18 Chrome automation tools via the [Claude in Chrome](https://chromewebstore.google.com/detail/claude-code/fcoeoabgfenejglbffodgkkbkcdhcgfn) extension\n- [**Third-Party Inference**](#third-party-inference) — use Vertex AI, Bedrock, Azure AI Foundry, or any Anthropic-compatible gateway ([docs](https://claude.com/docs/cowork/3p/installation))\n- [**Hardware Buddy (Nibblet)**](#hardware-buddy-nibblet) — BLE companion device showing animated session state (requires `bluez`)\n- **MCP server support** — Model Context Protocol servers work on Linux\n- **Multi-monitor Quick Entry** — global hotkey (Ctrl+Alt+Space) opens on the monitor where your cursor is\n- Automated daily version checks, and more\n\n### Custom Features\n\nFeatures unique to the Linux port — not available in upstream Claude Desktop:\n\n- [**Custom Themes**](#custom-themes-experimental) — 6 built-in color themes (Nord, Catppuccin variants, Sweet) or create your own via JSON config. See [themes/README.md](themes/README.md) for the full guide\n- [**Multiple Profiles**](#multiple-profiles) — run several instances side by side, each logged in to a different account with fully isolated state. `claude-desktop --create-profile=work` and you're done\n- [**Native Cowork Backend**](#cowork-integration) — [claude-cowork-service](https://github.com/patrickjaja/claude-cowork-service) replaces the macOS/Windows VM with a native Linux daemon, enabling Cowork, Dispatch, and Live Artifacts without emulation\n\n## Claude Chat\n\nThe main Chat tab running natively on Linux.\n\n![Claude Chat](docs/chat/cc.png)\n\n## Claude Code Integration\n\nThis package patches Claude Desktop to work with system-installed Claude Code on Linux.\n\n![Claude Code in Claude Desktop](docs/code/cc_in_cd.png)\n\n| | |\n|:---:|:---:|\n| \u003cimg src=\"docs/code/cc_in_cd_preview.png\" width=\"180\"\u003e | \u003cimg src=\"docs/code/terminal.png\" width=\"180\"\u003e |\n| Code Preview | Integrated Terminal |\n\nTo use Claude Code (and Cowork) features, install the CLI following the [official setup guide](https://code.claude.com/docs/en/setup), then verify it's accessible:\n```bash\nwhich claude  # e.g. ~/.local/bin/claude, /usr/bin/claude, /usr/local/bin/claude\n```\n\nThe patch auto-detects claude in `/usr/bin`, `~/.local/bin`, and `/usr/local/bin`.\n\n## Cowork Integration\n\nCowork is Claude Desktop's agentic workspace feature. This package patches it to work on Linux using a native backend daemon instead of the macOS/Windows VM.\n\n![Cowork in Claude Desktop](docs/cowork/co_in_cd.png)\n\n| | | | | | |\n|:---:|:---:|:---:|:---:|:---:|:---:|\n| \u003cimg src=\"docs/cowork/co_in_cd_bar.png\" width=\"180\"\u003e | \u003cimg src=\"docs/cowork/co_in_cd_flow.png\" width=\"180\"\u003e | \u003cimg src=\"docs/cowork/co_in_cd_mock.png\" width=\"180\"\u003e | \u003cimg src=\"docs/cowork/co_in_cd_mock_db.png\" width=\"180\"\u003e | \u003cimg src=\"docs/cowork/co_in_cd_pie.png\" width=\"180\"\u003e | \u003cimg src=\"docs/cowork/co_in_cd_qa.png\" width=\"180\"\u003e |\n\n### Live Artifacts\n\nLive Artifacts are persistent HTML pages stored within Cowork sessions that can pull live data from connected MCP tools (Jira, GitLab, HubSpot, Trello, etc.). They persist across sessions and can be starred for quick access.\n\n![Live Artifacts in Cowork](docs/cowork/live-artifacts.png)\n\nRequires Claude Code CLI (see above) and [claude-cowork-service](https://github.com/patrickjaja/claude-cowork-service). See its Installation section for distro-specific instructions ([APT](https://github.com/patrickjaja/claude-cowork-service#debian--ubuntu-apt-repository), [DNF](https://github.com/patrickjaja/claude-cowork-service#fedora--rhel-dnf-repository), [AUR](https://github.com/patrickjaja/claude-cowork-service#arch-linux-aur), [Nix](https://github.com/patrickjaja/claude-cowork-service#nixos), or [binary install](https://github.com/patrickjaja/claude-cowork-service#quick-install-any-distro-x86_64--arm64)).\n\n## CoworkSpaces\n\nCoworkSpaces organizes folders, projects, and links into named Spaces for Cowork sessions. On macOS/Windows this is handled by the native backend (`@ant/claude-swift`). On Linux, `fix_cowork_spaces.nim` provides a full file-based implementation:\n\n- Stores spaces in `~/.config/Claude/spaces.json`\n- Full CRUD: create, update, delete spaces with folders, projects, and links\n- File operations: list folder contents, read files, open with system handler\n- Auto-memory directories per space (`~/.config/Claude/spaces/\u003cid\u003e/memory/`)\n- Integrates with the SpaceManager singleton so `resolveSpaceContext` works for sessions\n\nThe Spaces UI is rendered by the claude.ai web frontend (loaded in the BrowserView).\n\n## Computer Use\n\nClaude Desktop includes a built-in Computer Use MCP server with 27 tools for desktop automation — screenshot, click, type, scroll, drag, clipboard, and more. The **learn tools** (`learn_application`, `learn_screen_region`) generate interactive overlay tutorials that walk through any application's UI elements step by step.\n\nExample prompt: *\"Can you use computer use MCP to explain me the PhpStorm application?\"*\n\n| Welcome | Menu Bar | Toolbar |\n|---------|----------|---------|\n| ![Learn Tool - Welcome](docs/cowork/co_computer_use_learn_tool.png) | ![Learn Tool - Menu Bar](docs/cowork/co_computer_use_learn_tool2.png) | ![Learn Tool - Toolbar](docs/cowork/co_computer_use_learn_tool3.png) |\n\n**How it works on Linux:** Upstream Computer Use is macOS-only — gated behind `process.platform===\"darwin\"` checks, macOS TCC permissions, and a native Swift executor. The patch ([fix_computer_use_linux.nim](patches/fix_computer_use_linux.nim)) removes 3 platform gates, bypasses TCC with a no-op `{granted: true}`, and injects a Linux executor that auto-detects your session type and uses the right tools. See [Optional Dependencies](#optional-dependencies) for the full package list.\n\n**App discovery** for the teach/learn overlay scans `.desktop` files from `/usr/share/applications`, `~/.local/share/applications`, and Flatpak directories. Each app is registered with multiple name variants (full name, first word, exec basename, icon name, .desktop filename) so the model can match apps flexibly (e.g., \"Thunar\" matches \"Thunar File Manager\").\n\n**Multi-monitor limitation:** Computer Use on Linux is limited to the **primary monitor** only. Screenshots, clicks, and the teach overlay all target the primary display. On multi-monitor setups, coordinates are translated from display-relative to absolute screen space automatically. Use `switch_display` if you need to target a different monitor for screenshots/clicks, but the teach overlay always appears on primary.\n\n**Teach overlay on Linux:** Since Electron's `setIgnoreMouseEvents(true, {forward: true})` is [broken on X11](https://github.com/electron/electron/issues/16777), the teach overlay stays fully interactive (buttons are clickable) but blocks clicks to apps behind it during the guided tour. The tooltip repositions between steps via `anchorLogical` coordinates pointing to UI elements.\n\nSee [CLAUDE_BUILT_IN_MCP.md](CLAUDE_BUILT_IN_MCP.md#14-computer-use) for the full tool reference and [Optional Dependencies](#optional-dependencies) for required packages.\n\n## Hardware Buddy (Nibblet)\n\nHardware Buddy connects Claude Desktop to a [Nibblet](https://github.com/felixrieseberg/nibblet) — a small M5StickC Plus BLE companion device that displays animated characters reflecting Claude's session state (idle, busy, celebrating, etc.).\n\n\u003cimg src=\"docs/global/buddy.png\" alt=\"Hardware Buddy (Nibblet)\" width=\"330\"\u003e\n\n**Access:** App menu → Developer → Open Hardware Buddy…\n\n**How it works on Linux:** The BLE communication uses standard Web Bluetooth (Nordic UART Service) via Electron's Chromium layer — no native code needed. Upstream gates the feature behind a server-side flag. The patch ([fix_buddy_ble_linux.nim](patches/fix_buddy_ble_linux.nim)) forces the flag on Linux so the BLE bridge initializes.\n\n**Prerequisites:** `bluez` package (`sudo pacman -S bluez bluez-utils` / `sudo apt install bluez`). Bluetooth must be enabled (`bluetoothctl power on`).\n\n**Pairing:** Power on the Nibblet — it advertises as `Nibblet-XXXX`. Click \"Open Hardware Buddy…\" from the Developer menu, then pair from the buddy window. The device shows session activity, token counts, and responds to permission prompts with physical button presses.\n\n## Third-Party Inference\n\nConfigure Claude Desktop to use your own cloud inference backend instead of Anthropic's API. Supports **Vertex AI** (Google Cloud), **Bedrock** (AWS), **Azure AI Foundry** (Microsoft), or any **Anthropic-compatible gateway** (LiteLLM, Portkey, in-house proxies). Access via **Developer → Configure Third-Party Inference**.\n\n![Third-Party Inference Configuration](docs/global/third-party-inference.png)\n\nThe configuration window lets you manage connection settings, provider credentials, model lists, sandbox/workspace restrictions, MCP servers, telemetry, usage limits, and org-plugin directories — all from a single UI. Configurations can be exported as `.mobileconfig` (macOS MDM), `.reg` (Windows GPO), or plain JSON (Linux `/etc/claude-desktop/enterprise.json`).\n\n**How it works on Linux:** The upstream SPA is mostly Linux-compatible — the main process already reads enterprise config from `/etc/claude-desktop/enterprise.json` and passes `platform: \"linux\"` to the frontend. The patch ([fix_ion_dist_linux.nim](patches/fix_ion_dist_linux.nim)) adds the Linux org-plugins path (`/etc/claude-desktop/org-plugins`) to the UI.\n\n**Enterprise deployment:** Use MDM (macOS), GPO (Windows), or drop a JSON file at `/etc/claude-desktop/enterprise.json` (Linux) to manage fleet-wide configuration. See the [Anthropic 3P configuration docs](https://claude.com/docs/cowork/3p/configuration) for the full key reference and recommended security profiles.\n\n## Custom Themes (Experimental)\n\nThemes override CSS variables in **all windows** (main chat, Quick Entry, Find-in-Page, About) via Electron's `insertCSS()` API. Set Claude Desktop to **dark mode** for best results with dark themes.\n\n**Quick start:**\n```bash\necho '{\"activeTheme\": \"sweet\"}' \u003e ~/.config/Claude/claude-desktop-bin.json\n# Restart Claude Desktop\n```\n\n**Built-in themes:** `sweet`, `nord`, `catppuccin-mocha`, `catppuccin-frappe`, `catppuccin-latte`, `catppuccin-macchiato`\n\n| Sweet | Nord | Catppuccin Mocha |\n|-------|------|------------------|\n| Purple/pink warm tones ([github.com/EliverLara/Sweet](https://github.com/EliverLara/Sweet)) | Arctic blue-grey ([nordtheme.com](https://nordtheme.com)) | Warm pastels ([catppuccin.com](https://catppuccin.com)) |\n\nSee **[themes/README.md](themes/README.md)** for the full theming guide: CSS variable reference, how to extract app HTML/CSS for inspection, custom theme creation, and screenshots.\n\n## Patches\n\nThe package applies several patches to make Claude Desktop work on Linux. Each patch is isolated in `patches/` for easy maintenance:\n\n| Patch | Purpose | Debug pattern |\n|-------|---------|---------------|\n| `add_feature_custom_themes.nim` | CSS theme injection — 6 built-in themes (sweet, nord, catppuccin-*) | Prepended IIFE, no regex |\n| `claude-native.js` | Linux stubs for `@anthropic/claude-native` (Windows-only module) | Static file, no regex |\n| `enable_local_agent_mode.nim` | Removes platform gates for Code/Cowork features, spoofs UA | `rg -o 'function \\w+\\(\\)\\{return process\\.platform.*status' index.js` |\n| `fix_0_node_host.nim` | Fixes MCP node host and shell worker paths for Linux | `rg -o 'nodeHostPath.{0,50}' index.js` |\n| `fix_app_quit.nim` | Uses `app.exit(0)` to prevent hang on exit | `rg -o '.{0,50}app\\.quit.{0,50}' index.js` |\n| `fix_asar_folder_drop.nim` | Prevents app.asar from being misdetected as a folder drop on launch ([#24](https://github.com/patrickjaja/claude-desktop-bin/issues/24)) | `rg -o 'filter.*\\.asar' index.js` |\n| `fix_asar_workspace_cwd.nim` | Redirects app.asar workspace paths to home directory ([#24](https://github.com/patrickjaja/claude-desktop-bin/issues/24)) | `rg -o '__cdb_sanitizeCwd' index.js` |\n| `fix_browse_files_linux.nim` | Enables `openDirectory` in file dialog (upstream macOS-only) | `rg -o 'openDirectory.{0,60}' index.js` |\n| `fix_browser_tools_linux.nim` | Enables Chrome browser tools — redirects native host to Claude Code's wrapper | `rg -o '\"Helpers\".{0,50}' index.js` |\n| `fix_buddy_ble_linux.nim` | Enables Hardware Buddy (Nibblet BLE device) — forces feature flag, uses Web Bluetooth via BlueZ | `rg -o '2358734848.{0,50}' index.js` |\n| `fix_claude_code.nim` | Detects system-installed Claude Code binary | `rg -o 'async getStatus\\(\\)\\{.{0,200}' index.js` |\n| `fix_computer_use_linux.nim` | Enables Computer Use — removes platform gates, injects Linux executor (portal+PipeWire/grim/GNOME D-Bus/spectacle/scrot, xdotool/ydotool) | `rg -o 'process.platform.*darwin.*t7r' index.js` |\n| `fix_computer_use_tcc.nim` | Stubs macOS TCC permission handlers to prevent error logs | Prepended IIFE, UUID extraction |\n| `fix_cowork_error_message.nim` | Replaces Windows VM errors with Linux-friendly guidance | String literal match |\n| `fix_cowork_linux.nim` | Enables Cowork — VM client, Unix socket, bundle config, binary resolution | `rg -o '.{0,50}vmClient.{0,50}' index.js` |\n| `fix_cowork_sandbox_refs.nim` | Replaces VM/sandbox system prompts and tool descriptions with accurate host-system text | `rg 'lightweight Linux VM\\|isolated Linux' index.js` |\n| `fix_cowork_first_bash.nim` | Fixes first bash command returning empty output — events socket race condition | `rg -o 'subscribeEvents' index.js` |\n| `fix_cowork_spaces.nim` | File-based CoworkSpaces service (CRUD, file ops, events) | `rg -o 'CoworkSpaces' index.js` |\n| `fix_cross_device_rename.nim` | EXDEV fallback for cross-filesystem file moves | Uses `.rename(` literal |\n| `fix_detected_projects_linux.nim` | Enables detected projects with Linux IDE paths (VSCode, Cursor, Zed) | `rg -o 'detectedProjects.{0,50}' index.js` |\n| `fix_disable_autoupdate.nim` | Disables auto-updater (no Linux installer) | `rg -o '.{0,40}isInstalled.{0,40}' index.js` |\n| `fix_dispatch_linux.nim` | Enables Dispatch — forces bridge init, bypasses platform gate, forwards responses natively | `rg -o 'sessions-bridge.*init' index.js` |\n| `fix_dispatch_outputs_dir.nim` | Fixes \"Show folder\" opening empty outputs dir — falls back to child session outputs | `rg -o 'openOutputsDir.{0,80}' index.js` |\n| `fix_dock_bounce.nim` | Suppresses taskbar attention-stealing on KDE/Wayland | Prepended IIFE, no regex |\n| `fix_enterprise_config_linux.nim` | Reads enterprise config from `/etc/claude-desktop/enterprise.json` | `rg -o 'enterprise.json' index.js` |\n| `fix_imagine_linux.nim` | Enables Imagine/Visualize — forces GrowthBook flag for inline SVG/HTML rendering | `rg -o '3444158716' index.js` |\n| `fix_ion_dist_linux.nim` | Patches ion-dist 3P config SPA — adds Linux org-plugins path, fixes platform ternary | `rg 'org-plugins' locales/ion-dist/assets/v1/*.js` |\n| `fix_locale_paths.nim` | Redirects locale file paths to Linux install location (also handles `index.pre.js` if present) | Global string replace on `process.resourcesPath` |\n| `fix_marketplace_linux.nim` | Forces host-local mode for plugin operations (no VM) | `rg -o 'function \\w+\\(\\w+\\)\\{return\\(\\w+==null.*mode.*ccd' index.js` |\n| `fix_native_frame.nim` | Native window frames on Linux, preserves Quick Entry transparency | `rg -o 'titleBarStyle.{0,30}' index.js` |\n| `fix_office_addin_linux.nim` | Extends Office Addin MCP server to include Linux | `rg -o '.{0,30}louderPenguinEnabled.{0,30}' index.js` |\n| `fix_process_argv_renderer.nim` | Injects `process.argv=[]` in renderer preload to prevent TypeError | `rg -o '.{0,30}\\.argv.{0,30}' mainView.js` |\n| `fix_profile_url_routing.nim` | Hooks `shell.openExternal` to write a per-profile auth-marker file before opening SSO URLs, so the system `claude://` handler can route callbacks to the right profile | `rg -o 'shell\\.openExternal' index.js` |\n| `fix_profile_window_title.nim` | Appends profile name to window title (`Claude` → `Claude (work)`) for named profiles | Prepended IIFE, `page-title-updated` listener |\n| `fix_quick_entry_app_id.nim` | Gives Quick Entry a distinct Wayland `app_id` so shell-extension users can blacklist it independently ([#39](https://github.com/patrickjaja/claude-desktop-bin/issues/39)); resets to per-profile `app_id` after Quick Entry closes | `rg -o '.{0,30}BrowserWindow.*titleBarStyle.*hidden.{0,30}' index.js` |\n| `fix_quick_entry_cli_toggle.nim` | Enables `claude-desktop --toggle` Quick Entry hotkey (~5-25 ms via Unix socket); per-profile socket path | `rg -o 'QUICK_ENTRY.{0,80}' index.js` |\n| `fix_quick_entry_position.nim` | Quick Entry opens on cursor's monitor (multi-monitor); position+focus retries gated to X11 only (Wayland: no jitter) | `rg -o 'getPrimaryDisplay.{0,50}' index.js` |\n| `fix_quick_entry_ready_wayland.nim` | Adds 100ms timeout to Quick Entry ready-to-show wait (Wayland hang fix; `ready-to-show` never fires for frameless transparent windows) | `rg -o 'ready-to-show.{0,50}' index.js` |\n| `fix_quick_entry_wayland_blur_guard.nim` | Guards Quick Entry blur-to-dismiss against spurious Wayland blur events | `rg -o '.{0,30}blur.{0,30}null.{0,30}' index.js` |\n| ~~`fix_read_terminal_linux.py`~~ | **Removed in v1.2.234** — upstream now natively supports Linux | N/A |\n| `fix_startup_settings.nim` | XDG autostart management for \"Start at login\" toggle; per-profile autostart files for named profiles | `rg -o 'isStartupOnLoginEnabled.{0,50}' index.js` |\n| `fix_tray_dbus.nim` | Prevents DBus race conditions with mutex and cleanup delay | `rg -o 'menuBarEnabled.*function' index.js` |\n| `fix_tray_icon_theme.nim` | Theme-aware tray icon (light/dark) | `rg -o 'nativeTheme.{0,50}tray' index.js` |\n| ~~`fix_tray_path.py`~~ | **Removed** — tray icon paths handled by `fix_locale_paths.nim` | N/A |\n| `fix_updater_state_linux.nim` | Adds version fields to idle updater state to prevent TypeError | `rg -o 'status:\"idle\".{0,50}' index.js` |\n| `fix_utility_process_kill.nim` | SIGKILL fallback when UtilityProcess doesn't exit gracefully | `rg -o 'Killing utiltiy proccess' index.js` |\n| `fix_vm_session_handlers.nim` | Global exception handler for VM session safety | Prepended IIFE with fallbacks |\n| `fix_window_bounds.nim` | Fixes BrowserView bounds on maximize/snap, Quick Entry blur | Injected IIFE, minimal regex |\n\nWhen Claude Desktop updates break a patch, only the specific patch file needs updating. The **debug pattern** column shows the `rg` command to find the relevant code in the new version's `index.js`.\n\n## Automation\nThis repository automatically:\n- Checks for new Claude Desktop versions daily\n- **Validates all patches in Docker** before pushing to AUR\n- Updates the AUR package when new versions are detected\n- Creates GitHub releases for tracking updates\n- Maintains proper SHA256 checksums\n\n### Patch Validation\n\nThe CI pipeline includes a test build step that validates patches before updating AUR:\n\n1. **Docker Test Build** - Runs `makepkg` in an `archlinux:base-devel` container\n2. **Pattern Matching Validation** - Each patch exits with code 1 if patterns don't match\n3. **Pipeline Stops on Failure** - Broken packages never reach AUR users\n4. **Build Logs Uploaded** - Artifacts available for debugging failures\n\nIf upstream Claude Desktop changes break a patch:\n- The pipeline fails with clear `[FAIL]` output\n- Build logs show which pattern didn't match\n- AUR package remains unchanged until patches are updated\n\n## Repository Structure\n- `.github/workflows/` - GitHub Actions for automation\n- `scripts/` - Build and validation scripts\n- `patches/` - Linux compatibility patches\n- `packaging/` - Debian, RPM, AppImage, and Nix build scripts\n- `PKGBUILD.template` - AUR package template\n\n## Multiple Profiles\n\nRun several Claude Desktop instances side by side, each logged in to a different account, with fully isolated state for both Desktop and the Claude Code CLI it spawns. Useful for separating work from personal accounts, juggling multiple SSO tenants, or testing config changes without affecting your main install.\n\n### Quick start\n\n```bash\n# One-time setup per profile\nclaude-desktop --create-profile=work\nclaude-desktop --create-profile=personal\n\n# Launch (any of these work)\nclaude-desktop-work                     # via the per-profile shortcut\nclaude-desktop --profile=work           # via the system launcher\n# …or click \"Claude (work)\" in your application menu\n\n# Inspect / clean up\nclaude-desktop --list-profiles\nclaude-desktop --delete-profile=work    # removes entry points; user data preserved\n```\n\n### The default (unnamed) profile\n\nIf you don't pass `--profile=` and don't launch through a named-profile shortcut, you get the **default profile**. This is byte-identical to a single-instance install — same `~/.config/Claude`, same `~/.claude`, same sockets, same WM identity. Nothing changes for users who never touch profiles. There's no `--create-profile=default` step, and it's always available implicitly.\n\nYou can run the default profile alongside any number of named profiles. The default profile is just \"the profile with no suffix.\"\n\n### Named profiles\n\nA named profile is created with `--create-profile=NAME`. Names must match `[a-zA-Z0-9_-]+` and the literal `default` is reserved.\n\n`--create-profile` installs three things in your home directory (no root needed):\n\n| Path | Purpose |\n|---|---|\n| `~/.local/lib/claude-desktop/com.anthropic.claude-desktop-NAME` | Per-profile Electron binary (real file — see [Why a copy?](#why-a-copy-of-the-binary) below). Sibling files in the same directory are symlinks back to the system install. |\n| `~/.local/bin/claude-desktop-NAME` | Convenience launcher — symlink to the system launcher. Pulls profile name from its own basename. |\n| `~/.local/share/applications/com.anthropic.claude-desktop-NAME.desktop` | Application-menu entry titled `Claude (NAME)`. `Exec=` is absolute so it works regardless of `$PATH`. |\n\nUser data is **not** created until first launch — that way `--create-profile` is cheap and reversible.\n\n### Selecting a profile at launch\n\nThree equivalent ways:\n\n1. `claude-desktop --profile=NAME [args…]` — explicit flag.\n2. `CLAUDE_PROFILE=NAME claude-desktop [args…]` — env var, useful for scripts.\n3. `claude-desktop-NAME [args…]` — invocation via the per-profile shortcut. The launcher infers `NAME` from its own basename.\n\nAll three set the same `CLAUDE_PROFILE` env var, which propagates through Electron, the cowork hooks, and any spawned `claude` (Code CLI) child processes.\n\nSubcommands honor the active profile: `claude-desktop-work --toggle` toggles work's Quick Entry, `claude-desktop --profile=work --diagnose` reports work's paths.\n\n### What's isolated\n\n| Resource | Default profile | Named profile (e.g. `work`) |\n|---|---|---|\n| Electron userData (login, logs, settings, custom themes, spaces.json, PipeWire portal token) | `~/.config/Claude` | `~/.config/Claude-work` |\n| Claude Code config (settings, projects, sessions, plugins) | `~/.claude` | `~/.claude-work` |\n| Quick Entry toggle socket | `$XDG_RUNTIME_DIR/claude-desktop-qe.sock` | `…/claude-desktop-qe-work.sock` |\n| systemd user scope (cgroup, portal identity) | `app-com.anthropic.claude-desktop-PID.scope` | `app-com.anthropic.claude-desktop-work-PID.scope` |\n| WM_CLASS / Wayland app_id (taskbar grouping, Alt-Tab) | `com.anthropic.claude-desktop` | `com.anthropic.claude-desktop-work` |\n| XDG autostart entry (\"Start at login\") | `~/.config/autostart/com.anthropic.claude-desktop.desktop` | `…/com.anthropic.claude-desktop-work.desktop` |\n\nThe cowork VM-service socket (`$XDG_RUNTIME_DIR/cowork-vm-service.sock`) is **shared** across all profiles. The cowork-svc daemon is a stateless process spawner — per-profile isolation comes from the spawned `claude` CLI inheriting `CLAUDE_CONFIG_DIR=~/.claude-NAME` and using the per-profile `--plugin-dir` (which derives from Electron's `app.getPath(\"userData\")`). One daemon serves them all.\n\nPlugins, MCP servers, login state, and chat history from one profile are **not** visible in another. This is by design — profiles are independent installs, not views into shared state.\n\n### Removing a profile\n\n```bash\nclaude-desktop --delete-profile=work\n```\n\nRemoves the three entry points listed above. **User data is preserved** at `~/.config/Claude-work` and `~/.claude-work`. Delete those manually if you really want a clean slate:\n\n```bash\nrm -rf ~/.config/Claude-work ~/.claude-work\n```\n\n### SSO and URL routing\n\nThe `claude://` URL scheme is registered system-wide and points to the default profile's `.desktop` file. Without extra work, an SSO callback initiated from a named profile would launch the default profile and consume the auth token there, breaking login. claude-desktop-bin uses a small two-part routing mechanism to fix this:\n\n1. **Marker on browser open.** When a profile-active instance calls `shell.openExternal()` on an auth-ish URL (matches `oauth`, `sso`, `auth`, `login`, `signin`, `callback`, or `accounts`), it writes a marker file at `$XDG_RUNTIME_DIR/claude-desktop-pending-auth-\u003cprofile\u003e` containing the current timestamp. Implementation: [`patches/fix_profile_url_routing.nim`](patches/fix_profile_url_routing.nim).\n2. **Marker dispatch on callback.** When the launcher is invoked with a `claude://` URL and no explicit profile, it picks the most recent marker (less than 5 minutes old) and re-execs as that profile. Electron's `second-instance` event delivers the URL to the running profile window.\n\nYou can log in to multiple profiles in any order, including multiple SSO logins, with one narrow caveat:\n\n| Scenario | Result |\n|---|---|\n| Single profile (any kind) | ✅ |\n| Default + named, log in to either first, in any order | ✅ |\n| Multiple named profiles, SSO into each one sequentially | ✅ |\n| Profile crashes mid-auth | ✅ Marker self-heals via 5-minute TTL |\n| SSO into profile A, click an unrelated outbound link, then complete the SSO flow | ⚠️ The link click overwrites the marker; the callback may misroute. Re-attempt SSO. |\n| Two SSO flows in flight concurrently (browser tabs open in parallel for different profiles) | ⚠️ \"Most recent marker wins\"; the loser's callback lands in the winner's profile. Re-attempt for the loser. |\n\nThe marker is `0600`-permissioned and contains only a timestamp; nothing about the URL or session is persisted. To inspect what the launcher saw at routing time, run `claude-desktop --diagnose` while a marker is fresh.\n\nIf routing misbehaves, the escape hatch is to launch the URL explicitly:\n\n```bash\nclaude-desktop --profile=NAME 'claude://\u003ccallback-url\u003e'\n```\n\n### Limitations\n\n- **~200 MB disk per profile on cross-filesystem installs.** See [Why a copy?](#why-a-copy-of-the-binary) below.\n- **Auto-refresh after package upgrades.** Hardlinks and reflinks snapshot the binary at creation; an upgrade replaces `/usr/lib/claude-desktop-bin/com.anthropic.claude-desktop` with a new file while the per-profile copy keeps pointing at the old version. The launcher detects this on every named-profile launch (canonical newer than per-profile, or per-profile non-executable on NixOS where store paths move, or any sibling symlink dangling) and re-materialises the binary plus refreshes the symlink mirror automatically. You'll see `claude-desktop: refreshing stale per-profile binary (...)` on stderr when this fires. To force-refresh manually:\n  ```bash\n  for p in $(claude-desktop --list-profiles | awk 'NR\u003e1 {print $1}'); do\n      claude-desktop --delete-profile=\"$p\"\n      claude-desktop --create-profile=\"$p\"\n  done\n  ```\n- **MCP servers and plugins do not cross profiles.** If you need the same MCP setup in two profiles, configure each independently.\n- **Concurrent SSO race** as noted in the table above. Sequential SSO is reliable.\n- **Quick Entry GNOME hotkey is global, not per-profile.** `claude-desktop --install-gnome-hotkey` writes a single keybinding bound to `claude-desktop --toggle`, which targets the **default** profile's Quick Entry socket. Per-profile hotkeys would need separate accelerators and bindings — install them by hand if needed: `gsettings`-write a custom-keybinding slot whose `command` is `claude-desktop --profile=NAME --toggle`. The launcher's `--toggle` does honor the active profile when invoked with `--profile=NAME`.\n- **`--profile=NAME` without `--create-profile`** isolates state but not WM identity (the window joins the default profile's taskbar entry). The launcher prints a one-line hint pointing at `--create-profile`; suppress with `CLAUDE_PROFILE_QUIET=1`.\n- **Wayland portal identity caveats on NixOS** (already true single-instance) carry over to named profiles too.\n\n### Why a copy of the binary?\n\nElectron derives its WM_CLASS (X11) and Wayland `app_id` from the basename of `/proc/self/exe`, which the kernel always resolves through symlinks. A symlink at `~/.local/lib/claude-desktop/com.anthropic.claude-desktop-work` pointing to `/usr/lib/claude-desktop-bin/com.anthropic.claude-desktop` would still report the system path as the exe — and the WM would group all profile windows as one app. That's how Chrome itself handles channels: `google-chrome-stable` and `google-chrome-beta` are separate copies, not symlinks.\n\nTo get distinct app identity per profile, `--create-profile` materialises a real, independently-named binary file. It tries (in order):\n\n1. **Hardlink** (`ln`) — zero disk cost, only works on the same filesystem.\n2. **Reflink** (`cp --reflink=always`) — zero disk cost via copy-on-write, only on btrfs/xfs.\n3. **Plain copy** (`cp`) — ~200 MB per profile, fallback.\n\nThe `Created profile` output tells you which path was taken. Sibling files in the same directory (`libffmpeg.so`, `.pak`, `locales/`, `resources/`, `version`, etc.) are always symlinks back to the system install — Electron's `RPATH=$ORIGIN` and Chromium's resource loader expect them next to the binary, but they don't need to be per-profile. Sibling symlinks are shared across all profiles in `~/.local/lib/claude-desktop/`.\n\n## Environment Variables\n\n| Variable | Values | Description |\n|----------|--------|-------------|\n| `CLAUDE_PROFILE` | name | Select a profile by name (alternative to `--profile=` or the per-profile symlink). Inherited by Electron and Claude Code so per-profile sockets and config dirs are picked up everywhere |\n| `CLAUDE_PROFILE_QUIET` | `1` | Suppress the \"no per-profile WM identity\" hint that fires when `CLAUDE_PROFILE` is set without a matching `--create-profile` |\n| `CLAUDE_CONFIG_DIR` | path | Override Claude Code's config dir. Auto-set by the launcher when `CLAUDE_PROFILE` is active; honored by `@anthropic-ai/claude-code` |\n| `CLAUDE_DISABLE_GPU` | `1`, `full` | Fix white screen on some GPU/driver combos ([#13](https://github.com/patrickjaja/claude-desktop-bin/issues/13)). `1` disables compositing only, `full` disables GPU entirely |\n| `CLAUDE_USE_XWAYLAND` | `1` | Force XWayland instead of native Wayland |\n| `CLAUDE_MENU_BAR` | `auto`, `visible`, `hidden` | Menu bar visibility (default: `auto`, toggle with Alt) |\n| `CLAUDE_DEV_TOOLS` | `detach` | Open Chromium DevTools on launch |\n| `CLAUDE_ELECTRON` | path | Override Electron binary path |\n| `CLAUDE_APP_ASAR` | path | Override app.asar path |\n| `ELECTRON_ENABLE_LOGGING` | `1` | Log Electron main process to stderr |\n\nSet permanently in `~/.bashrc` or `~/.zshrc`, or pass per-launch: `CLAUDE_DISABLE_GPU=1 claude-desktop`\n\n## Debugging\n\nRuntime logs are written to `~/.config/Claude/logs/`:\n| Log File | Description |\n|----------|-------------|\n| `main.log` | Main Electron process |\n| `claude.ai-web.log` | BrowserView web content |\n| `mcp.log` | MCP server communication |\n\n```bash\n# Tail logs in real-time\ntail -f ~/.config/Claude/logs/main.log\n\n# Search for errors across all logs\ngrep -ri 'error\\|exception\\|fatal' ~/.config/Claude/logs/\n\n# Launch with DevTools + full logging\nCLAUDE_DEV_TOOLS=detach ELECTRON_ENABLE_LOGGING=1 claude-desktop 2\u003e\u00261 | tee /tmp/claude-debug.log\n```\n\n## Dispatch Architecture\n\nDispatch lets you send tasks from the Claude mobile app to your Linux desktop. It's fully native — no VM, no emulation.\n\n\u003cimg src=\"docs/global/android_dispatch_feature.png\" alt=\"Dispatch on Android\" width=\"300\"\u003e\n\nClaude Desktop spawns a long-running **dispatch orchestrator agent** (Anthropic internally calls it \"Ditto\"). This agent receives messages from your phone, delegates work to child sessions, and sends responses back via `SendUserMessage`.\n\n```\nPhone → Anthropic API → SSE → Claude Desktop → Ditto agent (via cowork-service)\n  ├── Ditto calls SendUserMessage → response appears on phone\n  ├── Ditto calls mcp__dispatch__start_task → child session spawned\n  │     └── Child does the work (code, files, research, etc.)\n  │     └── Child completes → Ditto reads transcript → Ditto replies to phone\n  └── Ditto has access to all SDK MCP servers (Gmail, Drive, Chrome, etc.)\n```\n\nOn Windows/Mac, dispatch runs inside a VM. On Linux, [claude-cowork-service](https://github.com/patrickjaja/claude-cowork-service) handles it natively with several adaptations (stripping VM-only tool restrictions, path mapping, local `present_files` interception). See the [Dispatch Support](https://github.com/patrickjaja/claude-cowork-service#dispatch-support) section in claude-cowork-service for full technical details.\n\n\n## Known Limitations\n\n### Quick Entry hotkey on GNOME Wayland\n\nThe Quick Entry global hotkey (default `Ctrl+Alt+Space`) works out of the box on **KDE Plasma**, **Hyprland**, and **Sway** via `xdg-desktop-portal` GlobalShortcuts.\n\nOn **GNOME**, the portal silently fails to register the hotkey. Run once after install:\n\n```bash\nclaude-desktop --install-gnome-hotkey                 # default Ctrl+Alt+Space\nclaude-desktop --install-gnome-hotkey '\u003cSuper\u003espace'  # or any accelerator\n```\n\nThis binds the key directly via `gsettings`, bypassing the portal. See [wayland.md](wayland.md#quick-entry-hotkey-not-firing-on-gnome) for details. Run `claude-desktop --diagnose` to check hotkey status.\n\n### Quick Entry hotkey command\n\nSet your keyboard shortcut (GNOME, KDE, Sway, Hyprland) to:\n\n```bash\nclaude-desktop --toggle\n```\n\nThis toggles Quick Entry in ~5-25 ms via a Unix domain socket. If the app is not running, it starts it automatically.\n\n### App identity on Wayland\n\n`xdg-desktop-portal` resolves unsandboxed apps via the systemd user scope /\ncgroup name. Starting with this release we launch under\n`app-com.anthropic.claude-desktop-*.scope` (via `systemd-run --user --scope`)\nand install the `.desktop` file under the matching reverse-URL name.\n\n- **Pinned taskbar entries**: if you had the old `claude-desktop.desktop` pinned, re-pin once after this update.\n- **Custom X11 WM rules**: `WM_CLASS` / Wayland `app_id` changed from `Claude` to `com.anthropic.claude-desktop`. Users with i3 / xmonad / awesome / bspwm / KWin rules matching the old class will need to update them. Named profiles (see [Multiple Profiles](#multiple-profiles)) get a `-\u003cprofile\u003e` suffix on this class so each profile shows up as a separate app — write WM rules accordingly.\n- **NixOS**: the Nix package materialises a renamed Electron binary (`com.anthropic.claude-desktop`) for correct Wayland `app_id`, but does not use `systemd-run --scope`. Portal identity may not resolve on GNOME Wayland — use `--install-gnome-hotkey` instead. Other sessions (KDE, Hyprland, Sway, X11) are unaffected.\n\n## Tips\n- Press **Alt** to toggle the app menu bar (Electron default)\n\n\n## See Also\n\n- [tweakcc](https://github.com/Piebald-AI/tweakcc) — A great CLI tool for customizing Claude Code (system prompts, themes, UI). Same patching-JS-to-make-it-yours energy. Thanks to the Piebald team for their work.\n\n## Legal Notice\n\n\u003e This is an **unofficial community project** for educational and research purposes.\n\u003e Claude Desktop is proprietary software owned by **Anthropic PBC**.\n\u003e\n\u003e This repository contains only build scripts and patches — not the Claude Desktop\n\u003e application itself. The upstream binary is downloaded directly from Anthropic\n\u003e during the build process.\n\u003e\n\u003e This project is not affiliated with, endorsed by, or sponsored by Anthropic.\n\u003e \"Claude\" is a trademark of Anthropic PBC.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickjaja%2Fclaude-desktop-bin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatrickjaja%2Fclaude-desktop-bin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickjaja%2Fclaude-desktop-bin/lists"}