johnzfitch/claude-cowork-linux
GitHub: johnzfitch/claude-cowork-linux
通过逆向工程和桩代码替换,让 Claude Desktop 的 Cowork 模式在 Linux 上原生运行,无需 macOS 或虚拟机。
Stars: 57 | Forks: 10

# Linux 上的 Claude Cowork
### 无需 macOS,无需虚拟机。




**[快速开始](#-quick-start)** · **[工作原理](#-how-it-works)** · **[手动设置](#-manual-setup)** · **[故障排除](#-troubleshooting)**
##  概述
Claude Cowork 是一个特殊的 Claude Desktop 版本,它在你指定的文件夹内工作——在执行计划时,它会读取、写入和组织那里的文件。Cowork 目前是一个 **仅限 macOS 的预览版**,由沙盒化的 Linux VM 支持;本仓库对 macOS 原生部分进行了逆向工程和桩代码替换(stub),使 Cowork 能够直接在 Linux (x86_64) 上运行——无需虚拟机,也无需 macOS。桩代码将 VM 路径转换为宿主机路径,以便 Cowork 指向 Linux 上的正确文件。
**工作原理:**
| 步骤 | 描述 |
|:-----|:------------|
|  **桩代码替换** | 用 JavaScript 替换仅限 macOS 的原生模块(`@ant/claude-swift`, `@ant/claude-native`) |
|  **直接执行** | 直接运行 Claude Code 二进制文件(无需虚拟机——我们已经在 Linux 上了!) |
|  **路径转换** | 透明地将 VM 路径转换为宿主机路径 |
|  **平台伪装** | 发送 macOS 头信息以便服务器启用该功能 |
##  状态
- **非官方研究预览版**:这是逆向工程的成果,可能会在 Claude Desktop 更新时失效。
- **Linux 支持**:目前目标是 **Linux x86_64**。Wayland:通过 `$WAYLAND_DISPLAY` / `$XDG_SESSION_TYPE` 自动检测(Ozone 后端)。
- **访问权限**:需要 Claude 账户。安装程序会自动下载 Claude Desktop DMG;无需 macOS 机器。
##  兼容性
| 发行版 | 桌面环境 | 状态 | 备注 |
|:-------|:--------|:-------|:------|
| **Arch Linux** | Hyprland (Wayland) | 已测试 | 主要开发环境 |
| **Arch Linux** | KDE Plasma (Wayland) | 预期可行 | KDE Wallet 通过 SecretService D-Bus 暴露 |
| **Arch Linux** | GNOME (Wayland) | 预期可行 | 全局快捷键需要手动配置 DE(GNOME 缺乏门户支持) |
| **Ubuntu 22.04+** | GNOME / X11 | 预期可行 | gnome-keyring 提供 SecretService |
| **Fedora 39+** | GNOME / KDE | 预期可行 | DMG 解压可能需要 `p7zip-plugins` |
| **Debian 12+** | 任意 | 预期可行 | apt 中的 `p7zip-full` |
| **NixOS** | 任意 | 未测试 | Electron + bwrap 沙盒可能需要额外配置 |
| **openSUSE** | 任意 | 已测试 | 使用 `7zip` 包(而非 `p7zip`);Node.js 使用 `nodejs-default` |
**已知限制:**
- 未实现 `GlobalShortcuts` 门户的 Wayland 合成器(如 GNOME)将不支持全局热键 —— 请改为在 DE 设置中设置自定义快捷键。
- 如果 `gnome-keyring` 或其他 SecretService 提供程序未运行,启动器将回退到 `--password-store=basic`(凭据存储在磁盘上,而非密钥环中)。
- `/sessions` 根符号链接在安装期间需要一次 `sudo`。如果你的发行版以不同方式限制根符号链接,请手动指向它:`sudo ln -s ~/.local/share/claude-cowork/sessions /sessions`。
安装后运行 `./install.sh --doctor`(或 `claude-desktop --doctor`)以验证你的环境。
##  系统要求
- **Linux x86_64**(在 Arch Linux,内核 6.18.7 上测试)
- **Node.js 18+** / npm
- **Electron**(系统包或 npm 全局安装)
- **asar** (`npm install -g @electron/asar`)
- **p7zip**(用于解压 macOS DMG;openSUSE 使用 `7zip` 代替)
- **bubblewrap**(沙盒隔离)
- **Python 3.11+**(用于自动下载和补丁)
- **Claude Pro**(或更高级别)订阅以获取 Cowork 访问权限
- **Secret service provider**(可选)—— gnome-keyring、KDE Wallet 或 KeePassXC 用于安全凭据存储。如果没有,启动器将回退到 `--password-store=basic`。
##  快速开始
### 方法 1: install.sh(推荐)
```
git clone https://github.com/johnzfitch/claude-cowork-linux.git
cd claude-cowork-linux
./install.sh # auto-downloads the latest DMG
claude-desktop
```
### 方法 2: AUR (Arch Linux)
```
yay -S claude-cowork-linux # auto-downloads the latest DMG
```
### 方法 3: curl pipe
```
bash <(curl -fsSL https://raw.githubusercontent.com/johnzfitch/claude-cowork-linux/master/install.sh)
```
安装程序会自动下载最新的 Claude Desktop DMG(使用 [rnet](https://github.com/nicholasgasior/rnet) 绕过 API 端点上的 Cloudflare,然后使用 curl 进行 CDN 下载)。你也可以手动提供 DMG:
```
./install.sh ~/Downloads/Claude-*.dmg
# 或
CLAUDE_DMG=~/Downloads/Claude-1.1.4010.dmg ./install.sh
```
##  架构
```
┌─────────────────────────────────────────────────────────────────┐
│ Claude Desktop (Electron) │
├─────────────────────────────────────────────────────────────────┤
│ ipc-handler-setup.js (baked into app.asar) │
│ ├── EIPC handler registration (all namespaces) │
│ ├── Session lifecycle & sessions.json persistence │
│ └── Transcript migration & directory setup │
├─────────────────────────────────────────────────────────────────┤
│ @ant/claude-swift (STUBBED) │
│ ├── vm.setEventCallbacks() → Register process event handlers │
│ ├── vm.startVM() → No-op (we're already on Linux) │
│ ├── vm.spawn() → Creates mount symlinks, spawns processes │
│ ├── vm.kill() → Kills spawned processes │
│ └── vm.writeStdin() → Writes to process stdin │
├─────────────────────────────────────────────────────────────────┤
│ @ant/claude-native (STUBBED) │
│ ├── AuthRequest → Opens system browser (xdg-open) │
│ └── Platform helpers → Minimal compatibility shims │
├─────────────────────────────────────────────────────────────────┤
│ Claude Code Binary │
│ └── Resolved from ~/.local/bin, mise/asdf shims, PATH, etc. │
└─────────────────────────────────────────────────────────────────┘
```
### 路径转换
桩代码将 VM 路径转换为宿主机路径:
| VM 路径 | 宿主机路径 |
|:--------|:----------|
| `/usr/local/bin/claude` 或 `claude` | 通过 `~/.local/bin/claude`、`~/.config/Claude/claude-code-vm/{version}/claude` 或 PATH 解析 |
| `/sessions/...` | `~/.local/share/claude-cowork/sessions/...` |
### 挂载符号链接
当你在 Cowork 中选择一个文件夹时,桩代码会创建符号链接,使其在预期的 VM 路径下可访问:
```
~/.local/share/claude-cowork/sessions/
/mnt/
├── → /home/user/path/to/selected/folder (symlink)
├── .claude → ~/.config/Claude/.../session/.claude (symlink)
├── .skills → ~/.config/Claude/.../skills-plugin/... (symlink)
└── uploads/ (directory for file uploads)
```
来自 Claude Desktop 的 `additionalMounts` 参数提供了挂载名称与宿主机路径之间的映射。
##  工作原理
1. 平台伪装
应用程序向 Anthropic 的服务器发送以下头信息:
```
'Anthropic-Client-OS-Platform': 'darwin'
'Anthropic-Client-OS-Version': '14.0'
```
这让服务器认为我们在 macOS 14 (Sonoma) 上,从而启用 Cowork 功能。
2. 平台门禁绕过
平台门禁函数(混淆名称随版本变化 —— v1.1.3963 中为 `xPt()`,旧版本中为 `wj()`)检查是否支持 Cowork。`enable-cowork.py` 会自动找到它并将其替换为无条件返回 `{status: "supported"}`。
3. Swift 插件桩代码
原始的 `@ant/claude-swift` 使用 Apple 的虚拟化框架。我们的桩代码:
- 实现相同的 API 接口
- 使用 Node.js `child_process` 生成真实进程
- 进行行缓冲 JSON 输出以正确解析流
- 将 VM 路径转换为宿主机路径
关键洞察:应用程序调用 `Si()`,它返回 `module.default.vm`,因此方法必须位于 `vm` 对象上。
4. 原生工具桩代码
应用程序还需要 `@ant/claude-native`(一个 macOS 特有的原生模块)。我们的桩代码提供最小兼容性,以便应用程序可以在 Linux 上启动。例如,OAuth 流程回退到通过 `xdg-open` 打开系统浏览器。
5. IPC 处理程序设置
所有 EIPC 处理程序(会话生命周期、记录管理、功能标志)均由 `ipc-handler-setup.js` 注册,该文件直接打包进 `app.asar`。每当桩代码或 frame-fix 文件更改时,`launch.sh` 会自动重新打包 asar —— 无需手动步骤。
6. 直接执行
在 macOS 上,Cowork 运行一个 Linux VM。在 Linux 上,我们完全跳过 VM,直接在宿主机上运行 Claude Code 二进制文件。这实际上更简单、更快捷!
桩代码按优先级顺序解析二进制文件:
```
$CLAUDE_CODE_PATH (explicit override)
~/.config/Claude/claude-code-vm/{version}/claude (downloaded by Desktop)
~/.local/bin/claude (npm/bun global)
~/.npm-global/bin/claude
/usr/local/bin/claude
/usr/bin/claude
/home/linuxbrew/.linuxbrew/bin/claude (Linuxbrew system)
~/.linuxbrew/bin/claude (Linuxbrew user)
~/.local/share/mise/shims/claude (mise version manager)
~/.asdf/shims/claude (asdf version manager)
```
##  项目结构
```
claude-cowork-linux/
├── stubs/
│ ├── @ant/claude-swift/js/index.js # Primary stub: vm.spawn(), filterEnv(), path translation
│ ├── @ant/claude-native/index.js # Auth (xdg-open), keyboard constants, platform helpers
│ └── frame-fix/
│ ├── frame-fix-wrapper.js # Early bootstrap: TMPDIR fix, platform spoofing, graceful shutdown
│ └── frame-fix-entry.js # Entry point: loads frame-fix-wrapper then main index.js
├── cowork/
│ ├── event_dispatch.js # EIPC event dispatch for LocalAgentModeSessions
│ └── sdk_bridge.js # SDK bridge (spawn dead code, kept for session state)
├── tests/
│ ├── test-install-paths.sh # 8-stage install validation (static analysis → Docker)
│ └── Dockerfile.test # Arch Linux container for full install testing
├── docs/
│ ├── extensions.md # MCP and Chrome Extension integration overview
│ ├── known-issues.md # Safe Storage encryption, keyring setup
│ └── safestorage-tokens.md # How to persist tokens across restarts
├── config/
│ └── hyprland/claude.conf # Optional: Hyprland window rules
├── .github/assets/ # README icons and hero image
├── enable-cowork.py # Patches platform gate to return {status:"supported"}
├── fetch-dmg.py # Auto-download Claude DMG via rnet (Cloudflare bypass)
├── install.sh # Installer + --doctor preflight diagnostics
├── launch.sh # Launcher: syncs stubs, repacks asar, runs electron
├── launch-devtools.sh # Launcher with --inspect (Node.js DevTools)
├── validate.sh # Env var checks, stub URL validation, log scanning
├── PKGBUILD # Arch Linux AUR package definition
├── OAUTH-COMPLIANCE.md # OAuth token handling audit
├── CLAUDE.md # Project guide and critical paths
├── README.md # This file
└── LICENSE
```
运行 `install.sh` 后,`linux-app-extracted/` 目录将包含解压后的 Claude Desktop。
##  手动设置
如果自动安装程序不起作用,请执行以下步骤:
1. 从 DMG 解压 Claude Desktop
安装程序会自动处理 `app.asar` 解压。如需手动解压或针对旧的非打包版本:
```
# 使用 7z 提取 DMG
7z x Claude-*.dmg -o/tmp/claude-extract
# 创建 app 目录
mkdir -p linux-app-extracted
# 对于较新版本 (app.asar):
if [ -f "/tmp/claude-extract/Claude/Claude.app/Contents/Resources/app.asar" ]; then
npx --yes asar extract "/tmp/claude-extract/Claude/Claude.app/Contents/Resources/app.asar" linux-app-extracted
# Copy unpacked files if they exist
[ -d "/tmp/claude-extract/Claude/Claude.app/Contents/Resources/app.asar.unpacked" ] && \
cp -r "/tmp/claude-extract/Claude/Claude.app/Contents/Resources/app.asar.unpacked/"* linux-app-extracted/
# 对于较旧版本 (unpacked app/):
elif [ -d "/tmp/claude-extract/Claude/Claude.app/Contents/Resources/app" ]; then
cp -r "/tmp/claude-extract/Claude/Claude.app/Contents/Resources/app/"* linux-app-extracted/
fi
# 清理
rm -rf /tmp/claude-extract
```
2. 安装桩代码模块
```
# 复制我们的 stub 到原始模块上
cp -r stubs/@ant/* linux-app-extracted/node_modules/@ant/
```
3. 修补 index.js
运行 cowork 补丁(自动检测混淆函数名):
```
python3 enable-cowork.py linux-app-extracted/.vite/build/index.js
```
4. 创建所需目录
```
# 创建用户 session 目录
mkdir -p ~/.local/share/claude-cowork/sessions
chmod 700 ~/.local/share/claude-cowork/sessions
# 创建 symlink (需要 sudo 一次)
sudo ln -s ~/.local/share/claude-cowork/sessions /sessions
```
5. 安装 Electron 和 asar
```
# 系统 package (推荐)
# Arch: pacman -S electron
# Ubuntu/Debian: apt install electron
# 或通过 npm:
npm install -g electron @electron/asar
```
##  故障排除
验证补丁是否已应用
检查 `linux-app-extracted/.vite/build/index.js` 中是否存在 Cowork 补丁:
```
grep -q 'cowork-patched' linux-app-extracted/.vite/build/index.js && echo "✓ Cowork patch applied" || echo "✗ Patch missing - run ./install.sh"
```
该补丁将平台门禁函数替换为无条件返回 `{status:"supported"}`,从而在 Linux 上启用 Cowork。`/*cowork-patched*/` 标记表示补丁成功。
EACCES: permission denied, mkdir '/sessions'
创建一个指向用户空间的符号链接,而不是创建一个全局可写目录:
```
mkdir -p ~/.local/share/claude-cowork/sessions
sudo ln -s ~/.local/share/claude-cowork/sessions /sessions
```
Unexpected non-whitespace character after JSON
JSON 解析问题。桩代码使用行缓冲发送完整的 JSON 对象。如果问题持续存在,请检查跟踪日志:
```
cat ~/.local/share/claude-cowork/logs/claude-swift-trace.log
```
Failed to start Claude's workspace
首先运行 `claude-desktop --doctor` 检查你的环境。然后验证:
1. Swift 桩代码是否正确加载(检查日志中是否有 `[claude-swift-stub] LOADING MODULE`)
2. Claude 二进制文件是否存在于某个解析路径中(`~/.local/bin/claude`、`~/.config/Claude/claude-code-vm/{version}/claude` 等)
3. 你是否拥有有效的 Claude 账户
Process exits immediately (code=1)
检查跟踪日志中的 stderr 以获取实际错误:
```
tail -50 ~/.local/share/claude-cowork/logs/claude-swift-trace.log
```
常见问题:
- 缺少 `/sessions` 符号链接
- 未找到二进制文件
- 权限问题
t.setEventCallbacks is not a function
这意味着桩代码未正确导出方法。应用程序期望:
- `module.default.vm.setEventCallbacks()` —— 而不是直接在类上
确保桩代码在 `this.vm` 对象上有方法,而不仅仅在类上。
App won't relaunch / appears to do nothing
上一个实例可能未完全关闭,留下了过时的锁定文件。清除它并重新启动:
```
rm -f ~/.config/Claude/SingletonLock ~/.config/Claude/SingletonSocket ~/.config/Claude/SingletonCookie
claude-desktop
```
此问题已在 v3.0.4 中修复 —— 应用程序现在能优雅地处理 SIGTERM 和窗口关闭事件。更新到最新版本以防止再次发生。
Global shortcuts don't work on Wayland (GNOME)
应用程序通过 `xdg-desktop-portal` 启用 `GlobalShortcutsPortal` 以支持 Wayland 全局快捷键。这在 **KDE Plasma** 和 **Hyprland** 上有效,但在 **GNOME** 上无效 —— `xd-desktop-portal-gnome` 尚未实现 GlobalShortcuts 门户。
**GNOME Wayland 用户的解决方法:** 在 GNOME 设置 > 键盘 > 自定义快捷键 中设置一个自定义快捷键来启动 `claude-desktop`。
##  开发
```
./launch.sh # repacks asar automatically if stubs changed
./launch-devtools.sh # with Node.js inspector
./validate.sh # env var checks, stub URL validation, log errors
./install.sh --doctor # preflight: binaries, node, CLI, /sessions, secret service, patches
```
### 调试日志
```
# 在 trace log 中包含 Claude Code stdout/stderr (已脱敏,但仍需将日志视为敏感信息)
export CLAUDE_COWORK_TRACE_IO=1
# 启用 debug 模式
export CLAUDE_COWORK_DEBUG=1
# 启用 Electron logging
export ELECTRON_ENABLE_LOGGING=1
# 清除旧 logs
rm -f ~/.local/share/claude-cowork/logs/claude-swift-trace.log
# 运行并捕获输出
./launch.sh 2>&1 | tee /tmp/claude-full.log
# 在另一个终端中,监控 trace
tail -f ~/.local/share/claude-cowork/logs/claude-swift-trace.log
```
### 跟踪日志格式
桩代码写入 `~/.local/share/claude-cowork/logs/claude-swift-trace.log`:
```
[timestamp] === MODULE LOADING ===
[timestamp] vm.setEventCallbacks() CALLED
[timestamp] vm.startVM() bundlePath=... memoryGB=4
[timestamp] vm.spawn() id=... cmd=... args=[...]
[timestamp] Translated command: /usr/local/bin/claude -> ~/.config/Claude/...
[timestamp] stdout line: {"type":"stream_event",...}
[timestamp] Process ... exited: code=0
```
##  安全
本项目包含安全加固:
- **命令白名单** - `vm.spawn()` 仅接受经过审查的二进制路径;未知命令将被拒绝
- **命令注入防护** - 使用 `execFile()` 而非 `exec()`
- **路径遍历保护** - 使用 `isPathSafe()` 验证会话路径
- **环境变量过滤** - 安全环境变量白名单
- **安全权限** - 会话目录使用 700 权限,而非 777
- **/sessions 符号链接** - 无全局可写目录
- **URL 来源验证** - `Auth_$_doAuthInBrowser` 和 `AuthRequest.start()` 强制仅限 Anthropic 域名
- **OAuth 合规性** - `BLOCKED_ENV_KEY_PATTERN` + `CREDENTIAL_EXEMPT_KEYS` 防止令牌泄露到子进程
## 法律声明
## 致谢
通过检查 Claude Desktop Electron 应用结构、使用 pyghidra-lite 进行二进制分析以及迭代调试,完成了逆向工程和实现。
**贡献者:**
- [@Boermt-die-Buse](https://github.com/Boermt-die-Buse) -- Linux UI 修复:原生窗口边框、标题栏补丁、图标提取
- [@JaPossert](https://github.com/JaPossert) -- 资源复制修复、Wayland 全局快捷键报告
- [@alpham8](https://github.com/alpham8) -- openSUSE 兼容性修复、二进制解析路径、Swift 桩代码方法存根
- [@matiasandina](https://github.com/matiasandina) -- 图标修复和终端分离建议(问题 #37)
**MIT 许可证** · 详情见 [LICENSE](LICENSE)
标签:AI 助手, Anthropic, API 欺骗, Arch Linux, CIS基准, Claude Desktop, CMS安全, Cowork Mode, Cutter, DNS 反向解析, DNS解析, JavaScript, MITM代理, x86_64, 云资产清单, 兼容层, 原生运行, 平台欺骗, 开源项目, 技术研究, 数据可视化, 文件管理, 无需 macOS, 系统仿真, 自定义脚本, 虚拟化绕过, 路径转换, 逆向工具, 逆向工程