69 KiB
Changelog
All notable changes to aaddrick/claude-desktop-debian are documented in this file.
The format follows Keep a Changelog — semantic versioning applies to REPO_VERSION; upstream Claude Desktop bumps (the +claude{X.Y.Z} suffix on the tag) are tracked separately by the check-claude-version workflow.
Unreleased
Added
- Report CDL-ANT-0010 Inside the Code Split: A Chunk Census of Claude Desktop 1.19367.0 — names what each of the 44 satellite chunks introduced by upstream's main-process code split is scoped to (the agent-session platform, enterprise sign-in, built-in MCP servers, the Claude Desktop Buddy BLE bridge, and the one satellite the patch suite touches), with the structured census data and require-graph manifest alongside.
- The artifact tests assert the launcher's
--versionfast-path end-to-end on all three formats (deb exact-matched against the control Version, rpm and AppImage prefix-matched against their metadata), closing the "deb/rpm static-verified only" gap from #775. (#781) - The artifact tests assert the bwrap fallback daemon (
resources/cowork-vm-service.js, ships since #776) is present in every package. (#781) - Direct coverage for the bwrap runtime plumbing: 9 doctor tests for
cowork_node_has_features/_doctor_check_bwrap_node(capability probe, WARN paths, readiness flag) and 5 launcher tests forsetup_cowork_bwrap_env(flag gating, node resolution, precedence, capability warning). (#781)
Changed
- The doctor-coverage campaign extracted
run_doctor's inline display-server, Electron-binary, chrome-sandbox, AppArmor-userns, and SingletonLock checks into unit-testable_doctor_check_*helpers with_DOCTOR_*path hooks (defaults are the real system paths, so production behavior is unchanged), each move verified byte-identical against the inline original and pinned by mutation-checked bats coverage. The SingletonLock extraction also fixes a false green: a regular file left atSingletonLockby an unclean update — which hard-blocks the next cold launch — was reported as[PASS] no lock file (OK)and now warns with anrmfix hint. (#740, #744, #745, #782)
[v3.2.1] — 2026-07-12
Added
--doctornow reports Cowork device-registration state: it flags whenant-device-registry.jsonis stuck atnonebecause Linux has no hardware-backed device key yet (upstream), which is why new Cowork cloud tasks show "Not linked to a computer" (#780).
Fixed
- Builds against upstream 1.19367.0 apply all asar patches again after
upstream code-split the main-process bundle.
index.jsbecame a thin entry stub thatrequire()s a content-hashed main chunk (index.chunk-<hash>.js), so every patch anchored on the hardcodedindex.jspath missed —patch_virtiofsd_probefailed the build andpatch_quick_window/patch_org_plugins_pathsilently skipped. The orchestrator now resolves the main chunk once (following the stub'srequire, falling back toindex.jsfor older single-file bundles) and every patch operates on it.patch_cowork_bwrap's warm-prefetch block (C2) resolves the separate warm chunk by its[warm]log literal, andpatch_quick_window's visibility anchor now tolerates theexports.mainWindowproperty-access shape upstream switched to. Verified end-to-end against the pinned 1.19367.0 bundle: all four active patches land,node --checkpasses, and re-runs are byte-identical. - Builds against upstream 1.19367.0 no longer fail on the AU-1
tripwire. Upstream renamed the Linux updater's disable reason from
apt_channel_pendingtomanaged_by_package_manager— the APT channel went live and Linux updates are now permanently delegated to the package manager. The updater gate itself is unchanged (verified against the official bundle: the constant-folded early-return,platformUnsupported:!0, and the LinuxcheckForUpdatesIPC stub that just opens the download page all survive), so decision D-001 (docs/decisions.md) is unaffected and the tripwire anchor now tracks the renamed literal. - The launcher no longer hangs at startup on a large
launcher.log. The pre-launch GPU-recovery check (_previous_launch_hit_gpu_fatal) accumulated each log section into an awk string, which is O(n²) in the size of the largest section — one GPU-crash-looping session could grow a single section to megabytes and make the check take minutes, blocking Electron from ever starting. The check is now a single-pass, constant-memory scan that tracks only the previous section's crash-signature flags, andsetup_loggingnow rotateslauncher.logwhen it exceeds 5 MB (keeping 2 old copies under~/.cache/claude-desktop-debian/) so it can't grow without bound across sessions. Retires the unbounded-growth half of #582 (the journald-flood half stays open pending a 3.x retest). (#747) claude-desktop-unofficialdeb/RPM installs no longer fail with a file conflict on/usr/share/metainfo/io.github.aaddrick.claude-desktop-debian.metainfo.xml. That path was hardcoded to the reverse-DNS AppStream ID, so unlike every other installed file it did not follow the v3.0.0 package rename and stayed byte-shared with this project's own pre-renameclaude-desktopbuilds at Claude ≥ 1.16000 (e.g.v2.0.22+claude1.18286.0); the version-scoped<< 1.16000conflict metadata deliberately does not sweep those (that bound protects side-by-side coexistence with Anthropic's official package, which ships no metainfo). The installed metainfo filename now follows the rename toio.github.aaddrick.claude-desktop-unofficial.metainfo.xml, so the path can no longer collide with any otherclaude-desktop-named package. (#769)- Corrected the parked Cowork bwrap AppArmor workaround in
docs/troubleshooting.mdto state its true scope. The recipe attachesflags=(unconfined)to the shared/usr/bin/bwrap, grantingusernsto every bwrap consumer on the host (Flatpak, Steam, user scripts); the section now warns about that blast radius, explains why a documentation-only per-application profile is not possible here (unlike opam/Apptainer, the namespace-creating binary is the sharedbwrap, and the shipped Electron-binary profile does not cover a separatebwrapchild), scopes the impact to opt-inCOWORK_VM_BACKEND=bwraplaunches on Ubuntu 24.04+, and points at the tracked scoped fix. (#542) claude-desktop-unofficial --doctorno longer treats a removed-but-not-purged deb (dpkgconfig-files/rc state) as installed: the version-reporting branch (claude-desktop-unofficial) and the name-collision classifier (claude-desktop) both gate on${db:Status-Status}beinginstalled, mirroring_pkg_installed. A leftover record fromapt removewithout--purge— made common by the transitionalclaude-desktopdummy being autoremoved to rc — now warns like an AppImage/Nix install (or stays silent) instead of a stale[PASS]/collision message. (#713, fixes #711)
[v3.1.0] — 2026-07-10
Added
- Opt-in bubblewrap Cowork backend for hosts that can't run the official KVM microVM, enabled with
COWORK_VM_BACKEND=bwrap. The official Linux client gates Cowork on/dev/kvm+/dev/vhost-vsockand drives QEMU through a bundled native helper; ChromeOS Crostini blocksvhost_vsockat the Termina kernel level, so that gate can never pass there no matter what's installed (#772). A newcowork-bwrapasar patch reinstates the pre-3.0.0 bubblewrap daemon as a fallback: it reports the KVM support evaluator as supported, swaps the native-helper spawn for a bundled Node daemon (resources/cowork-vm-service.js) that speaks the same length-prefixed-JSON socket protocol backed bybwrapinstead of QEMU, and suppresses the unused multi-GB VM-image download. Every injected branch is gated onprocess.platform==="linux" && COWORK_VM_BACKEND==="bwrap", so on an unflagged launch every branch evaluates false and the official KVM path runs unchanged — nothing changes for the KVM majority (per D-002, this clears the patch bar as an opt-in path compensating a genuine Linux-environment gap). Because the official binary'sRunAsNodefuse is off, the daemon runs under a systemnode/nodejs(auto-detected by the launcher, exported asCOWORK_NODE_PATH) that providesfs.statfsSync(Node >= 18.15 / 16.19, feature-detected by the daemon, launcher, and--doctor). To persist the flag for desktop/app-menu launches — which can't carry a per-command environment — the launcher reads an allowlistedKEY=valueconfig file at${XDG_CONFIG_HOME:-~/.config}/claude-desktop-debian/environment(an explicit command-line env still wins; the file is never executed as shell). Isolation is namespace-level, not a VM — weaker than the KVM default, which is the trade for running where KVM can't. (#772) claude-desktop-unofficial --versionprints the package version (<claude-version>-<repo-version>, e.g.1.18286.0-3.0.1) and exits, on all three launcher formats (deb, RPM, AppImage). Previously the flag fell through to the full launch path, where the launcher redirects all Electron output into~/.cache/claude-desktop-debian/launcher.log— so the terminal printed nothing. (#772)
Fixed
- Post-rename
claude-desktopleftovers found in a repo-wide audit: doctor's hardcoded chrome-sandbox default probed the official package's/usr/lib/claude-desktop/tree instead of ours, two doctor fix hints said to reinstallclaude-desktop, and the docs (quickstart, configuration, testing runbook/cases, triage-form mirror) still told users to runclaude-desktop. All now useclaude-desktop-unofficial; references that genuinely mean Anthropic's official package, the upstream ELF/process name, or the transitional dummy are unchanged. (#772)
Changed
- The artifact tests now assert that Cowork's bundled
resources/virtiofsdis present and executable in every package format: the #771 un-gate makes it the universal fallback and the client resolves it withX_OK, so a repack that drops the exec bit would silently kill Cowork on hosts without a client-probed system virtiofsd. The doctor's virtiofsd probe tests also grew coverage for the_cowork_incompletereadiness flag (the WARN branches were previously unasserted —runsubshells discard the mutation), the client-path-over-bundled precedence, and the mode-stripped bundled copy falling through to WARN. (#774)
[v3.0.1] — 2026-07-05
Added
- The launcher now rotates out-of-band backups of
claude_desktop_config.jsonand the per-account Cowork stores (spaces.json,remote-session-spaces.json,scheduled-tasks.json) before each launch, keeping the last 5 changed copies under~/.cache/claude-desktop-debian/config-backups/. This is the recovery path for the durable-loss config-wipe class: the official loader falls back to an empty value on a failed cold-start read and the next settings write serializes that empty state over the whole file, stubbing out keys whose only source of truth is the file itself —mcpServers, trusted folders, and the Coworkspaces.jsoncontent (upstream anthropics/claude-code#32345/#59640/#63651). Groupings/stars mirrored from IndexedDB (epitaxyPrefs) self-heal on restart and were the recoverable cousin that surfaced this during #768. Because the backup runs before Electron starts, an in-session wipe leaves the pre-wipe copy recoverable down the rotation. Patch-zero-clean (launcher-only; the officialapp.asarstill ships byte-identical) and covers the corrupt-JSON / ENOENT / single-bad-entry-Zod modes an in-band guard would miss. Mechanism and the parked in-band guard:docs/learnings/config-wipe-guard.md. (#768) - The Nix FHS env ships
qemu_kvm, so Cowork can boot its VM. Cowork gates VM boot on two requirements —firmwarePath(the OVMF shim already provided it) andqemuPath(a PATH search forqemu-system-x86_64/-aarch64);coworkdthen launches a realaccel=kvmguest (pflash OVMF, vhost-vsock, virtiofsd). Firmware alone left the gate atrequirement_missing.qemu_kvmis the host-cpu-only build (~1.5 GB closure vs 2.1 GB for the all-targetsqemu);/dev/kvmand/dev/vhost-vsockare reachable inside the env since buildFHSEnv binds the whole/dev, but the host must still grant kvm-group access (/dev/kvmisroot:kvm 0660) and loadvhost_vsock(--doctorflags both). x86_64 live-verified: a VM boots with KVM acceleration, and both the qemu binaries and usermode networking work. The aarch64 leg is still unverified. (#766)
Fixed
- Cowork reported "requires QEMU. Install it with…" on Arch, Debian, and Ubuntu-derivative hosts with a complete, doctor-green KVM stack: the official client resolves virtiofsd from exactly two absolute paths (
/usr/libexec/virtiofsd,/usr/bin/virtiofsd) and falls back to its own bundled copy only when/etc/os-releasereportsID=ubuntuwithVERSION_ID22.x — so Arch's/usr/lib/virtiofsd, Debian's/usr/lib/qemu/virtiofsd, and any Ubuntu derivative (ID=pop,ID=linuxmint) all resolve null and theyukonSilversupport evaluator gates VM startup before it ever spawns QEMU. A newvirtiofsd-probeasar patch un-gates the bundled fallback (system paths stay preferred; the probe list is deliberately not widened, since/usr/lib/qemu/virtiofsdcan be the CLI-incompatible legacy C implementation on qemu < 8 hosts). Reproduced on Anthropic's own.deb, so it is filed upstream as a genuine Linux gap per D-002 (docs/upstream-reports/771-cowork-virtiofsd-probe.md). (#771, #772) --doctorno longer PASSes a virtiofsd the client cannot see: the old check searched the broad distro path list (/usr/lib/virtiofsd,/usr/lib/qemu/virtiofsd, PATH), which produced the all-green doctor / "requires QEMU" app disagreement in #771. The check now mirrors the client's actual probe order — the two hardcoded paths, then the bundledresources/virtiofsd— and a binary found anywhere else WARNs with the one-line symlink fix instead of passing. (#771)- The Nix build crash-looped at startup on real NixOS: the GPU process failed EGL init (
Could not dlopen native EGL: libEGL.so.1), exited, and relaunched forever. Chromium's bundled ANGLE (libEGL.so/libGLESv2.so)dlopens the glvnd dispatcher by soname against the calling lib's runpath, andruntimeDependenciesreaches only dynamic executables (not the co-located.so), solibGLnever landed where the dlopen needed it.appendRunpathsnow adds the glvnd libs + NixOS driver tree to every patched ELF; glvnd then self-locates the vendor ICD under/run/opengl-driver. Runpath, not aLD_LIBRARY_PATHwrapper, so the driver tree stays out of the env of the MCP servers the app spawns. Chromium's bundled Vulkan loader can't be reached by runpath, so the launcher is wrapped to prepend the NixOS ICD dir viaVK_ADD_DRIVER_FILES(additive, so it can't shadow a user's config; harmless in spawned CLI subprocesses). Verified x86_64 + nvidia; mesa (Intel/AMD) and aarch64 unconfirmed. (#765) - The Nix FHS firmware shim shipped only the OVMF/AAVMF CODE file, so Cowork's VM boot would have failed with
no EFI variable-store template configured: Cowork derives its writable EFI VARS template from the CODE path by renamingOVMF_CODE→OVMF_VARS/AAVMF_CODE→AAVMF_VARS, and that sibling didn't exist on the Nix FHS (deb/rpm hide this — the distro's edk2 package already dropsOVMF_VARSbeside CODE). TheovmfCompatshim now symlinks the matched CODE+VARS pair on both arches and drops the wrongQEMU_EFI.fdaarch64 fallback (unpadded, no matching VARS name). With the qemu FHS entry landed (#766), Cowork now boots a VM end-to-end on x86_64 with this shim in place; aarch64 stays unverified. Build-behavior change on aarch64: a build-time guard now fails the build on nixpkgs OVMF-layout drift (e.g. a pinned nixpkgs missing the AAVMF pair) rather than shipping a dangling symlink that only bites at VM boot — fail-loud on the unverified arch is the deliberate trade, since there's no clean fallback (QEMU_EFIis unpadded and qemu rejects it for pflash). (#767)
[v3.0.0] — 2026-07-04
Rebased onto Anthropic's official first-party Claude Desktop for Linux .deb (pin 1.18286.0), replacing the Windows-installer repackaging and most of the legacy patch suite.
Added
- Build-time tripwires on upstream behavior we deleted patches for: the build now fails if the official bundle stops shipping the
apt_channel_pendingautoupdater marker (upstream turning on self-updating would fight the package manager — see D-001) or themenuBarEnabled:!0menu-bar default. Replaces the per-patch WARNINGs that left with each deletion. (AU-1/MB-1, #763) - The launcher self-heals the "Run on startup" autostart entry. The official app writes
~/.config/autostart/claude-desktop.desktopwithExec=<its own ELF> --startup, which bypasses the launcher's env/flag policy (Wayland opt-in, GPU recovery,--class,CLAUDE_PASSWORD_STORE) — and under AppImage points at an ephemeral/tmp/.mount_claude*path that rots on unmount. Each launch now repoints the entry'sExecat the launcher (deb/rpm:/usr/bin/claude-desktop-unofficial; AppImage: the persistent$APPIMAGEpath). The Settings toggle is unaffected — static analysis of the official bundle shows its is-enabled check never reads theExeccontent. (AUTO-1, #763) - The RPM bridges Cowork's hardcoded firmware probe on non-Debian layouts:
%postcreates a compat symlink at the probed path (/usr/share/OVMF/OVMF_CODE_4M.fd, arm64/usr/share/AAVMF/AAVMF_CODE.fd) when no probed path exists but a known edk2/qemu location does; erase removes it only if it is ours. Fedora already ships its own compat layer and is untouched. (CW-1, #763) claude-desktop-unofficial --doctorwarns when no keyring backend (Secret Service or KWallet, running or D-Bus-activatable) is reachable on the session bus: without one, Chromium'sos_cryptfalls back to the plaintextbasicbackend and the login token persists unencrypted at rest. Advisory only — login itself still works (live-verified on keyring-less wlroots/i3 sessions). (LD-3, #763)
Changed
- BREAKING: The packaging pipeline now consumes Anthropic's official Linux
.debinstead of repackaging the Windows installer.build.shresolves the newest pool entry via the APTPackagesindex, SHA-256 verifies it, and extracts withar/tar(nodpkg, so RPM-family hosts still build). The officialapp.asarships byte-identical in the common case —app-asar.shis a thin orchestrator with anactive_patchesarray, and only genuine Linux gaps are patched (see Removed). Full delete/keep rationale, byte-verified against the pristine bundle, is indocs/learnings/official-deb-rebase-verification.mdand report CDL-ANT-0009. (#763) - BREAKING:
--password-storeis no longer auto-detected. It is passed only whenCLAUDE_PASSWORD_STOREis set; otherwise Chromium's officialos_cryptautodetect owns the default. Governing rule of the rework: no default launcher flag may shadow an official code path. (#763) - BREAKING: The build flag
--exeis now--deb, and--node-pty-diris removed. - BREAKING: Our package is renamed
claude-desktop-unofficial(deb + rpm; matching artifact names for AppImage) so it can be installed beside Anthropic's officialclaude-desktoppackage. Install paths move to/usr/lib/claude-desktop-unofficial,/usr/bin/claude-desktop-unofficial,/etc/apparmor.d/claude-desktop-unofficial. The conflict metadata is version-scoped (Conflicts:/Replaces: claude-desktop (<< 1.16000); rpmObsoletes: claude-desktop < 1.16000), so it swaps out our legacy Windows-repack packages (≤ 1.15200.x) and never touches the official package (≥ 1.17377.1). DNF migrates on a normaldnf upgrade; APT migrates via a transitionalclaude-desktop1.16000.0 dummy package. Side-by-side installs share~/.config/Claude, so only one build can run at a time. (#763) - The Nix derivation was rebuilt for the official tree:
fetchurlthe official.debfrom the APT pool (SRI hashes auto-bumped bycheck-claude-version),autoPatchelfHookover the bare co-located tree (no nixpkgs Electron, no node-pty build, no resourcesPath hack), and the FHS env bind-provides OVMF firmware at Cowork's hardcoded probe paths. Build-verified on x86_64 (both flake outputs, zero unresolved libraries); the aarch64 leg and Cowork VM boot are still unverified — @typedrat owns the final shape. (#763) claude-desktop-unofficial --doctorreworked for the official layout: new checks for the KVM/Cowork stack (/dev/kvm,/dev/vhost-vsock, OVMF/AAVMF firmware), official-version drift (embeddedPackagesresolver, network-optional), name collision with Anthropic's own package, and set-but-dead legacy env vars. chrome-sandbox / pkg-version / AppArmor checks moved to the bare co-located ELF. (#763)- CI:
check-claude-versionresolves upstream via thePackagesindex instead of Playwright;build-amd64andbuild-arm64collapse into one cross-buildingbuild.yml; RC tags (v*-rc*) publish as prerelease and skip the repo jobs; a newmirror-official-debjob archives every consumed official.debto its release. Newtools/chromium-switch-smoke.sh+ checked-in baseline fail CI if the effective launcher switch list drifts. (#763) - Shipped docs rewritten for the official-deb reality: README repositioned (Anthropic serves the
.deb; this project serves everything else plus the launcher and doctor), building/configuration/troubleshooting reworked against the actual branch scripts, obsolete deep-dives moved todocs/archive/with obsolescence headers, the Electron WCO findings extracted todocs/upstream-reports/, and the rebase recorded as ADR D-002. (#763)
Removed
- BREAKING: Launcher env vars
CLAUDE_TITLEBAR_STYLE,ELECTRON_USE_SYSTEM_TITLE_BAR,CLAUDE_MENU_BAR,CLAUDE_KEEP_AWAKE, andCLAUDE_QUIT_ON_CLOSE— the official build handles these natively (close-to-tray moved to Settings ▸ General ▸ System Tray, on = tray / off = quit). The doctor warns if it sees a dead one still set, and pointsCLAUDE_QUIT_ON_CLOSEat the tray toggle specifically. (#763) - 11 legacy patches now redundant against the official Linux build: the frame-fix wrapper (incl. the autoUpdater no-op), the claude-native Rust-binding stub, the tray patches (
tray.sh), the WCO shim,claude-code.sh, the node-pty rebuild (+nix/node-pty.nix), the menuBarEnabled default, the cowork/.config.asarguards, and the i18n + tray-icon asar copies. Two Linux-specific survivors stay:quick-window(KDE stale-focus) andorg-plugins(upstream has no Linux case). (#763) - The Windows-installer acquisition path:
download.sh, the Playwrightresolve-download-url.py,fetch-electron-binary.js, andscripts/staging/*. (#763) - The codespell workflow (
.github/workflows/codespell.yml) and.codespellrc. (#763)
Fixed
- Cross-built arm64 AppImages embedded an x86_64 first-stage runtime stub, so they could not start on arm64 hardware: appimagetool always embeds the runtime bundled with the tool itself (host-arch) — the
ARCHexport only covers naming/validation. The build now downloads the target-arch runtime from the same AppImageKit release and passes--runtime-fileexplicitly. Caught by the first native-arm64 run of the artifact tests. (#763) - Artifact tests (
tests/test-artifact-{deb,rpm,appimage}.sh) no longer assert the oldnode_modules/electron/dist/on-disk layout, which the official bare co-located tree (/usr/lib/claude-desktop/{claude-desktop,chrome-sandbox,resources}) does not ship — they are repointed to the real layout, so the release-gating artifact jobs pass against the rebase packages. (SB-1, #763)
Security
- The launcher no longer writes the login OAuth authorization code to
launcher.log. A relaunch through the auth redirect carriedclaude://login/…?code=<code>in argv, which theExecuting:/Arguments:log lines recorded verbatim; thelog_messagechokepoint now strips the query string of anyclaude://logintoken. Low residual risk (single-use, redeemed), but a plaintext secret should not land in a log. (LOG-1, #763)
Known gap: the reworked Nix derivation is build-verified on x86_64 only — runtime on real NixOS, the aarch64 leg, and Cowork VM boot are still unvalidated (owner @typedrat).
[v2.0.22] — 2026-06-25
Tracks upstream Claude Desktop 1.15200.0.
Fixed
- The Cowork tab is no longer grayed out on Linux with a "Cowork requires a newer installation — Reinstall the desktop app" tooltip. Upstream 1.13576+ gates the tab's visibility on the yukonSilver support evaluator (
$oe/q4r, the Windows capability probe), which returnsmsix_requiredon Linux — a separate consumer from thestartVMexecution gate that #736 re-derived. The evaluator now reportssupportedon Linux so the renderer un-grays the tab (the bwrap daemon was already healthy underneath), while the VM-image download drivers it also feeds are re-blocked so they don't pull the multi-GBrootfs.vhdxbundle that is intentionally disabled on Linux — cowork runs through the bwrap sandbox, not a downloaded VM. (#743, #736 follow-up) - Claude Desktop no longer hangs at startup on Linux with no window ever appearing (a regression introduced by upstream 1.13576+). The bundle calls the Windows-only
@ant/claude-nativemethodsreadRegistryValues()andgetWindowsElevationType()unconditionally during its enterprise-policy lookup, guarding only the native module being null and not the method being absent — so the Linux stub threw"<method> is not a function"at top-level execution, which the early emptyuncaughtExceptionhandler swallowed, leaving the process alive but windowless. The Linux native stub now provides neutral no-ops for these Windows-only registry / MSIX / UAC methods. (#729) - Cowork Linux patches apply again on Claude Desktop 1.13576+ — the build's "Verify cowork patches in shipped asar" step had started failing with 9/11 markers missing. Upstream re-architected the cowork/VM subsystem ("yukonSilver") between 1.12603.1 and 1.13576.0: the platform gate moved from a
darwin/win32check intostartVM'syukonSilver.statusfeature-flag check, the vmClient module load moved behind the isMsix detector, andsharedCwdPath/mountCondawere removed. Patch 1 (which anchored on the gone check)process.exit(1)'d, which killed the whole node block and dropped every subsequent cowork patch. Patches 1, 2 and the daemon auto-launch anchor were re-derived against the new bundle, the smol-bin idempotency guard was fixed (it false-matched upstream's own log), the obsoletesharedCwdPaththreading (Patch 12) was retired in favor of the daemon's mountMap fallback, and the Linux smol-bin copy patch gained a verification marker. (#736) - Builds (deb, RPM, AppImage, nix) no longer abort in the patch phase with
FATAL: --add-dir pattern matches 2 times (expected 1). Upstream Claude Desktop 1.12603.1 ships two identical--add-dirdispatch loops, but the.asarfilter patch (#650) asserted exactly one. The patch now filters every matching dispatch loop instead of bailing on a duplicate, and stays idempotent on re-runs. (#718) claude-desktop --doctorreports the installed version from the package manager that actually owns the install (probed viarpm -qfon the bundled Electron binary) instead of trustingdpkg-queryalone — rpm installs on hosts that also carry a stale dpkg record (e.g. Fedora boxes with dpkg installed as a build tool) no longer show a months-old version with a PASS. (#712, fixes #711)
[v2.0.19] — 2026-06-10
Tracks upstream Claude Desktop 1.11847.5.
Added
- AppStream metainfo (
io.github.aaddrick.claude-desktop-debian.metainfo.xml) installed by the deb, RPM, and AppImage builds, so the package appears in GNOME Software, KDE Discover, and App Center with correct unofficial-repackaging branding and aLicenseRef-proprietaryproject license. Store search for not-yet-installed users needs repo-side DEP-11/appstream metadata, tracked in #708. (#633) - GPU crash auto-recovery in the launcher: when the previous launch died to a Chromium GPU-process FATAL (the #583 SIGTRAP signature), the next launch automatically applies safe GPU flags — and stays recovered on subsequent launches instead of oscillating crash/work/crash. Detects NixOS launcher log headers too; set
CLAUDE_DISABLE_GPU=0to override. (#666)
Fixed
claude-desktop --doctorno longer reports a false-green PASS when the password store reads back empty or whendfreturns a non-numeric disk reading — bad reads now fail or print a visible skip instead of falling through to the PASS branch, and leading-zerodfoutput can no longer slip past as octal arithmetic. (#692)- Explicit quit now keeps the launcher alive until Electron exits, then runs stale-helper cleanup for Desktop-owned Cowork, Claude config, and extension helpers. Close-to-tray still leaves the app and helpers running. (#682)
- All launchers (deb, RPM, AppImage, nix) no longer pass
app.asaras an Electron argument. Electron auto-loadsapp.asarfrom its defaultresources/dir next to the binary, so the extra argv entry was redundant — and the app treated it as a file-to-open, surfacing a spurious "Attach app.asar?" prompt on launch and on every taskbar reopen. This removes the path at the source, complementing the renderer-side.asarguards in #669 and surviving upstream re-minification. Live-UI detection in the launcher and doctor, which fingerprinted on the now-removed argv, was updated alongside. (#700, fixes #696) - Cowork's VM daemon never auto-launched on packages built under a restrictive umask (CI builds with umask
022, so released artifacts were unaffected; local builds with e.g.umask 077were) because the bundledapp.asar.unpacked/directory shipped as mode0700owned by the build uid, so the desktop user running the app couldn't traverse it and the auto-launchfs.existsSync()fork guard silently returnedfalse(symptom: endlessconnect ENOENT …/cowork-vm-service.sock, nocowork_vm_daemon.log, no[cowork-autolaunch]line).deb.shnow normalizes the installed tree to canonical permissions (directories and executables755, other files644) and builds withdpkg-deb --root-owner-groupforroot:rootownership;appimage.shapplies the same normalization to the AppDir beforemksquashfs(it copies withcp -a, which preserved the bad modes); andrpm.shnormalizes file modes in%install—%defattr(-, root, root, 0755)forces directory modes in the payload, but its-first field preserves file modes from thecp -r-populated buildroot, so a restrictive-umask RPM build shipped an unreadableapp.asarand a non-executable electron binary. - Claude Desktop no longer crashes on launch on Ubuntu 24.04+, where
apparmor_restrict_unprivileged_userns=1blocks the user namespaces Chromium's sandbox needs (sandbox/linux/services/credentials.ccFATAL,Trace/breakpoint trap, exit 133). The.debpostinstnow installs a scoped AppArmor profile grantingusernsto the bundled Electron binary — mirroring thegoogle-chrome/code/slackpackages — and removes it again on uninstall. The Chromium sandbox stays enabled (no--no-sandbox).claude-desktop --doctorgained a User namespaces check that flags a missing profile. (#687) - Cowork mode no longer silently falls back to host-direct (no isolation) on Ubuntu 24.04+, where
apparmor_restrict_unprivileged_userns=1blocks the user namespaces its bubblewrap sandbox needs. The.debpostinstnow installs a second scoped AppArmor profile grantingusernsto/usr/bin/bwrap(distinct from the Electron profile above), automating the manual workaround from #351 (contributed by @hfyeh). The profile is gated on the kernel'sapparmor_restrict_unprivileged_usernsknob and defers to any profile already attaching to/usr/bin/bwrap(a hand-made/etc/apparmor.d/bwrap,apparmor-profiles'bwrap-userns-restrict); put local overrides in/etc/apparmor.d/local/claude-desktop-bwrap— they survive upgrades.bubblewrapis now aRecommends. (#694)
Changed
- CI now validates the arm64 deb, RPM, and AppImage artifacts on native
ubuntu-22.04-armrunners (previously only amd64 was tested), and the AppImage launch smoke test's process sweep is keyed tomount_claudeand gated behind$CIso a local test run can't kill a developer's live Claude Desktop session. The launcher's orphaned-daemon reaper also gained mutation-tested BATS coverage. (#691, #693) - The native-Wayland launch path now routes Quick Entry's global shortcut (
Ctrl+Alt+Space) through the XDG GlobalShortcuts portal:GlobalShortcutsPortalis added to the--enable-featuresset, and all Chromium feature requests are merged into a single--enable-features=switch (Chromium honours only the last one, so the previous code could silently clobber features). GNOME Wayland users can opt into the portal route withCLAUDE_USE_WAYLAND=1, which works on GNOME ≤ 49 after a one-time portal permission dialog and fixes the focus-bound hotkey from #404. The default GNOME session stays on XWayland (no rendering/IME regression risk); auto-selecting native Wayland on GNOME is deferred until it can be gated on a real render check. On GNOME 50 / xdg-desktop-portal ≥ 1.20 the portal route is currently a no-op — Electron/Chromium doesn't perform the portal's new hostRegistry.Registerapp-id handshake (filed upstream as electron/electron#51875).CLAUDE_USE_WAYLANDis now tri-state:1native Wayland,0force XWayland, unset auto-detects. (#404)
[v2.0.18] — 2026-06-04
Tracks upstream Claude Desktop 1.10628.2.
Fixed
- Tray icon no longer stuck black at startup on dark desktops.
nativeTheme.shouldUseDarkColorsreadsfalsefor the first ~50 ms then flipstrue, but the leading-edge rebuild mutex latched the transientfalseand dropped the corrective"updated"events; the mutex is now trailing-edge (re-applies the final value) and the obsolete 3 s startup-suppression window was removed. (#680, fixes #679) - Restored the in-place tray
setImagefast-path (#515), which silently stopped applying after upstream changed the context-menu wiring fromsetContextMenu(BUILDER())to a prebuiltsetContextMenu(MENU)object —patch_tray_inplace_updatenow resolves the builder in both shapes, so the duplicate-icon SNI race no longer regresses. (#680) - File-drop collector no longer re-attaches the app's own
app.asaron every taskbar reopen. Electron's ASAR VFS shim returnstruefromexistsSync()for.asarpaths, so the second-instance argv collector dispatchedapp.asarto the file-drop handler and surfaced an attach prompt on each relaunch; it now rejects.asarpaths, mirroring the existingstatSyncguard. (#669, fixes #668)
Changed
- CI now runs a headless launch smoke test for the deb and rpm artifacts — previously only the AppImage actually booted, so a startup-only regression (e.g. the Fedora
SyntaxError) could stay green on the formats it broke. A sharedrun_launch_smoke_testhelper covers all three formats and gracefully skips when a container forbids Chromium's sandbox. (#671, closes #670)
[v2.0.17] — 2026-06-04
Tracks upstream Claude Desktop 1.10628.2.
Fixed
addTrustedFolder.asarguard re-anchored on theasync addTrustedFolder(…)method declaration. Upstream Claude Desktop 1.10628.x folded theLocalAgentModeSessions.addTrustedFolder: ${i}log call into a comma-expression inside anif, removing the trailing`);the old anchor matched —./build.shaborted with[FAIL] addTrustedFolder anchor not found. Both the parameter extraction and the injection point now key off the unminified method name, so they can't drift apart if upstream drops the log line. (#685)
[v2.0.16] — 2026-05-27
Tracks upstream Claude Desktop 1.9255.0.
Fixed
- Cowork spawn guard now captures
$-prefixed minified function names (e.g.$Be) and usesglobalThis._lastSpawninstead of a bare_globalLastSpawnidentifier, fixingReferenceError: _globalLastSpawn is not definedthat broke Cowork on all platforms with upstream 1.9255.0. (#660, fixes #658, #659, #661)
[v2.0.15] — 2026-05-27
Tracks upstream Claude Desktop 1.9255.0.
Fixed
StartupWMClassaligned toClaudeto match what Electron actually advertises viaproductName. The v2.0.14 valueclaude-desktopwas silently ignored by Electron, causing orphan windows and duplicate gear icons on GNOME/KDE. Value centralized from 6 hardcoded locations to one source of truth inbuild.sh, with build-time substitution and aproductNameassertion guard. (#655, fixes #652)- Tray variable extraction re-anchored on
.Tray()literal instead of minifier-dependent syntax that upstream 1.9255.0 reshuffled. (#657, fixes #656)
[v2.0.14] — 2026-05-25
Tracks upstream Claude Desktop 1.8555.2.
Fixed
WM_CLASSandStartupWMClassaligned toclaude-desktopacross all formats (deb, RPM, AppImage, autostart). Resolves ambiguity with the Claude Code CLI (claude) and ensures consistent taskbar grouping on KDE/GNOME. (#648, fixes #647)
Changed
- AppImage smoke test: replaced flat 10s sleep with readiness-marker poll (30s ceiling, 0.5s tick), unified cleanup trap to prevent 190MB
squashfs-rootleaks on interrupt. (#646)
v2.0.13 — 2026-05-24
Tracks upstream Claude Desktop 1.8555.2.
Added
CLAUDE_KEEP_AWAKE=0env var to suppresspowerSaveBlockersleep inhibitor that upstream holds indefinitely on Linux (no lifecycle management). Adds diagnostic logging for allpowerSaveBlockercalls and--doctorvisibility. (#605)--doctorflags filesystems withNAME_MAX < 200(eCryptfs, certain encrypted overlays) and surfaces the LUKS-symlink workaround for cowork. Thanks @RayCharlizard, @lizthegrey for the repro. (#614, fixes #590)- F11 fullscreen toggle via hidden menu accelerator — Linux parity with macOS green button / Windows F11. (#638, fixes #580)
- Linux org-plugins path (
/etc/claude/org-plugins) added to platform switch, enabling MDM-managed plugin configuration. (#639, fixes #607) - Top-level governance docs: this
CHANGELOG.md,RELEASING.md(pre-release checklist + tag-driven CI flow),SECURITY.md(private GHSA reporting + in/out-of-scope),docs/index.md(navigation hub), anddocs/styleguides/docs_styleguide.md(page anatomy, naming, antipatterns).CLAUDE.mdgains explicit § Required reading, § Anti-patterns, and § Docs sections;AGENTS.mdbecomes a byte-identical mirror of the new body (was a 13-line stub) so non-Claude tools get the same instructions. CONTRIBUTING.md"Before you start" triage section: where to go for a bug, a fix-in-hand, a new-feature ask, or a security report.--password-storekeyring detection: probes D-Bus for kwallet6 / gnome-libsecret at startup and injects the flag before the app path, fixing session persistence on KDE Plasma and other desktops wheresafeStorage.isEncryptionAvailable()returned false. AddsCLAUDE_PASSWORD_STOREenv override and--doctordiagnostic. Thanks @dubreal. (#611, fixes #593)- Unzip fallback for Node 24: detects missing electron binary after
extract-zipsilently no-ops and recovers from the@electron/getcache using systemunzip. Thanks @JustinJLeopard. (#631, fixes #584)
Fixed
- Config writes no longer drop externally-added
mcpServers. The stale in-memory cache was overwriting disk on every preference change; now re-readsmcpServersfrom disk before each write. (#643, fixes #400) - Menu bar toggle fires on Alt keyup only, not keydown — fixes Alt+Shift (language switch) and Alt+F4 accidentally triggering the menu bar.
CLAUDE_MENU_BAR=hiddendisables the Alt toggle entirely. (#642, fixes #630) .asarpaths rejected in directory check, preventing Electron's ASAR VFS shim from dispatchingapp.asarto Cowork as a "folder drop". Fixes permission dialog on every launch, forced Cowork mode on reopen from tray, and "No conversation found" loop in Claude Code >=2.1.111. (#640, fixes #383, #622, #632)- Identifier captures across all patch scripts hardened from
\w+to[$\w]+(PCRE) /[[:alnum:]_$]+(ERE). Fixes broken idempotency guard intray.sh, adds missing guards tocowork.shpatches 6/9/10, adds\s*whitespace tolerance to multiple patterns. (#644) execbefore Electron invocation in deb, RPM, and Nix launchers so Ctrl+C and signals forward correctly to the Electron process. (#637, fixes #424)--class=Claudeadded to launcher args ensuring WM_CLASS matchesStartupWMClassin the .desktop file, preventing GNOME extension crashes from unexpected class values. (#636, ref #635)- Sloppy/focus-follows-mouse: suppress redundant
webContents.focus()calls that trigger X11_NET_ACTIVE_WINDOWraise-on-hover. Grace window handles staleisFocused()on tray-restore and minimize-restore. Thanks @tkrag. (#589, fixes #416) - Tray: extracted JS identifier captures now accept
$so the 1.8089.1 minified bundle ('i$A' menu handler) matches. Switches\w+to[\w$]+. (#627, fixes #625) - RPM: silence "File listed twice" warning on
chrome-sandboxby movingchmod 4755into%install(replaces%attrin%files). Adds regression guard that fails the build if the warning reappears. Thanks @JoshuaVlantis. (#610, fixes #609) - Window close with
CLAUDE_QUIT_ON_CLOSE=1now actively quits viaapp.quit()instead of relying on the bundled handler that hardcodes hide-to-tray on Linux. Rides upstream's own quit-in-progress guard. Thanks @phelps-matthew. (#624, fixes #623) - node-pty: wipe upstream Windows binaries (winpty.dll, winpty-agent.exe, Windows
.nodefiles) before staging the Linux build, preventing PE32+ orphans in the packaged asar. Thanks @JoshuaVlantis. (#597, addresses #401)
Changed
- CI injection hardening: moved
${{ steps.*.outputs.* }}expressions fromrun:blocks toenv:blocks inissue-triage-v2.yml. Build pipeline:process.exit(0)→process.exit(1)inquick-window.shwhen patch anchors aren't found so CI fails instead of shipping broken patches. Packaging scriptlets: replaced&> /dev/nullwith> /dev/null 2>&1for dash compatibility in deb/RPM postinst. (#641) - Credit @lizthegrey, @sabiut, @typedrat, @RayCharlizard in README Acknowledgments. (#626)
- Troubleshooting: new "Repeated Electron Crashes / GPU Process FATAL" section documenting
CLAUDE_DISABLE_GPU=1. Adds tuning-rationale comments around the--doctor3-in-7-days threshold and thecoredumpctlCOMM=electronassumption. Thanks @sabiut. (#615, addresses #608) - Docs filenames are now lowercase kebab-case (
docs/building.md,docs/configuration.md,docs/decisions.md,docs/troubleshooting.md);STYLEGUIDE.mdmoved todocs/styleguides/bash_styleguide.md. Cross-references swept across README, CONTRIBUTING, CODEOWNERS,.github/,.claude/,scripts/, andclaude-desktop --doctoruser-facing output. [$\w]+is the codified identifier-capture convention for patch-script regexes (CONTRIBUTING § Patch-script regexes;patch-engineeragent examples updated to match). Closes a docs-vs-code gap that left the rule only indocs/learnings/patching-minified-js.md— the same\w+trap fixed in patches by #555 and #627.
v2.0.12 — 2026-05-19
Tracks upstream Claude Desktop 1.7196.3.
Added
- Headless launch +
--doctorsmoke tests for the AppImage artifact. (#592)
Changed
- CI: add concurrency group to
test-flagsworkflow. (#606)
v2.0.11 — 2026-05-16
Tracks upstream Claude Desktop 1.7196.1.
Fixed
- Catch About window after upstream
titleBarStylechange; guard Hardware Buddy. (#481, #489) - RPM
chrome-sandboxSUID now set via%attrinstead of%post chmod. (#539, #595) - No-op
autoUpdateron Linux to defend against feed activation; mask thenable/coercion traps on the Proxy. (#567, #596) node-ptyinstall fails loudly onnpm installfailure; requiregcc/make/python3. (#401, #598)- Fetch electron binary via
@electron/get, drop^41pin; resolve fromwork_dirnot script dir. (#587) - Dedupe packages mapped from multiple commands.
v2.0.10 — 2026-05-06
Tracks upstream Claude Desktop 1.6259.0, 1.6259.1, 1.6608.0, 1.6608.2, 1.7196.0.
Added
--doctorsurfaces recent Electron crashes with a#583pointer;CLAUDE_DISABLE_GPU=1opt-in for GPU-process fatal crashes. (#583, #585)--doctordetects IBus/GTK misconfigurations that break input. (#572)- Launcher:
CLAUDE_GTK_IM_MODULEopt-in override. (#571) - Launcher: log session/IME env block at startup. (#570)
- Linux compatibility test harness. (#579)
- Lifecycle: notify and offer restart on in-place package upgrade. (#564)
desktopNameset for Wayland window grouping. Thanks @jslatten. (#562)
Fixed
- Pin electron to
^41to restore postinstall binary fetch. (#584, #586) - Nix: make electron binary executable. (#581)
cowork.sh: emit WARNING on Patch 2a/2b inner anchor miss. (#576)- CI: force primary GPG key for
repomd.xmlsigning. Thanks @ProfFlow. (#566) - DNF: set
metadata_expire=1hon generated.repo. (#551) - BATS: isolate
cleanup_stale_cowork_socketfrom hostpgrepstate. (#534)
Changed
- Static-grep shipped asar for PR #555 markers as a verification step. (#559, #575)
- New
patching-minified-jslearnings doc +CONTRIBUTING. (#574) - Refine
mcp-double-spawnroot cause and routing in learnings. (#546, #547) - Archive upstream report draft for #546 (filed as
anthropics/claude-code#55353). (#552)
v2.0.8 — 2026-05-02
Tracks upstream Claude Desktop 1.5354.0 (unchanged from v2.0.7).
Fixed
- Cowork starts again on Claude Desktop 1.5354.0. Upstream's minifier started emitting
$-containing identifiers (C$i,g$i); two regex anchors inscripts/patches/cowork.shused\w+, which doesn't match$. Patch 2b silently no-op'd, the Swift VM module assignment never landed, and you'd hitSwift VM addon not availableat session init. Widens both anchors to[\w$]+. Patch 6 also moves fromindexOftolastIndexOfon the retry-delay anchor. Thanks @sirfaber, @HumboldtJoker, @zabka. (#555, fixes #558, likely fixes #553 and #445)
v2.0.7 — 2026-05-01
Tracks upstream Claude Desktop 1.5354.0 (unchanged from v2.0.6).
Added
- Linux in-app topbar works now. New
hybridtitlebar mode is the default: native OS frame plus a BrowserView preload shim that satisfies claude.ai's UA gate, so the hamburger, sidebar, search, and nav buttons render and are clickable. Layout is stacked (DE titlebar above the in-app topbar) rather than combined like Windows. SetCLAUDE_TITLEBAR_STYLE=nativeto opt out and hide the in-app topbar. The upstreamframe:false+ WCO config is preserved ashiddenfor investigation but still has unclickable buttons on Linux;--doctorwarns when it's active. Verified on KDE Plasma X11/Wayland and Hyprland; GNOME, Sway, Niri, and NixOS pending. (#538)
v2.0.6 — 2026-05-01
Tracks upstream Claude Desktop 1.5354.0. Absorbs three upstream bumps from v2.0.5: 1.4758.0, 1.5220.0, 1.5354.0.
Added
- Cowork bwrap mounts accept a
{src, dst}form, so you can map a host directory under$HOMEonto a different path inside the sandbox. Unlocks persistent-/tmpso Bash tool calls don't wipe state between invocations. String form unchanged. Thanks @cbonnissent. (#531) --doctorwarns whenCOWORK_VM_BACKENDis set to an unknown value instead of silently falling through to auto-detect; adds aCOWORK_VM_BACKENDrow and a Cowork Backend section todocs/configuration.md. Thanks @CyPack. (#324)--doctorwarns when an additional bwrap mount destination shadows a default sandbox path like/usr,/etc,/bin,/sbin,/lib. (#531)- Troubleshooting entries for Cowork VM connection timeout, virtiofsd outside
$PATHon Fedora/RHEL (/usr/libexec/virtiofsd), and Fedora tmpfsEXDEVerrors. (#324)
Fixed
- Closing the window no longer kills the app on Linux. The X button hides to tray, matching Windows and macOS. Quit explicitly with Ctrl+Q, the tray menu, or your DE's quit shortcut. Set
CLAUDE_QUIT_ON_CLOSE=1to restore the old behavior. Fixes scheduled tasks and/schedulefirings getting silently dropped overnight. Thanks @lizthegrey. (#451) - "Run on startup" toggle persists on Linux now. Electron's
setLoginItemSettingsisn't implemented on Linux; the wrapper backs the toggle with~/.config/autostart/claude-desktop.desktopper the XDG Autostart spec. Thanks @lizthegrey. (#450, fixes #128) - Tray icon updates in place on OS theme change instead of briefly duplicating on KDE Plasma. Uses
setImage+setContextMenurather than destroy + recreate. Thanks @IliyaBrook. (#515) - Window visibility check works again after an upstream minified-name change broke it. Thanks @Andrej730. (#496, fixes #495)
Changed
- APT/DNF install instructions point at
pkg.claude-desktop-debian.devdirectly, bypassing the GitHub Pages 301. Pages serves the redirect overhttp://because it can't provision a cert for thepkg.subdomain (DNS belongs to the Cloudflare Worker), andaptrefuses HTTPS→HTTP downgrades. DNF was unaffected. (#510, #514)
v2.0.5 — 2026-04-23
Wrapper/packaging update; upstream Claude Desktop unchanged at 1.3883.0.
Fixed
- CI: smoke test accepts release-assets CDN hostname. (#509)
- Strip CRLF from
cowork-plugin-shim.shduring staging. (#499, #505)
v2.0.4 — 2026-04-23
Wrapper/packaging update; upstream Claude Desktop unchanged at 1.3883.0. No GitHub Release published.
Fixed
- CI: smoke test accepts
http://on Pages 301 hop. (#506) - Worker: use
raw.githubusercontent.comas origin to avoid Pages 301 loop. (#504)
Changed
- Worker: flip route from staging to production for Phase 4a. (#503)
v2.0.3 — 2026-04-23
Wrapper/packaging update; upstream Claude Desktop unchanged at 1.3883.0. No GitHub Release published.
Added
- APT/DNF Worker scaffolding. (#498)
Fixed
Changed
v2.0.2 — 2026-04-22
Wrapper/packaging update; upstream Claude Desktop unchanged at 1.3883.0.
Added
- BATS unit tests for
launcher-common.sh. (#395)
Fixed
- Copy
ion-diststatic assets for theapp://protocol handler. (#490)
v2.0.1 — 2026-04-21
Wrapper/packaging update; tracks upstream Claude Desktop 1.3561.0, 1.3883.0.
Added
- Triage Phase 4 sub-PRs: Stage 8c enhancement-design variant, suspicious-input tells,
regression_of+ edit-during-triage. (#470, #471, #472) - Triage Phase 3: Stage 6 adversarial reviewer + duplicate gate. (#465)
- Decision log with D-001 (auto-update direction). (#477)
@sabiutadded to CODEOWNERS for testing & release quality. (#468)
Fixed
- Export
GDK_BACKEND=waylandin native Wayland mode. Thanks @aJV99. (#397) - Scope Ctrl+Q to the focused window, not system-wide. (#484)
- Cowork: forward
CLAUDE_CODE_OAUTH_TOKENto VM spawn env. (#482, #485) - Launcher: disable GPU compositing on XRDP sessions. (#475)
- Triage: normalize
claimed_versionbefore drift compare. (#483) - Triage: drift-as-banner — demote drift from gate to modifier. (#476)
- Triage: pull broken-expectation rule up into first-pass classify. (#469)
- Triage: raise 8b comment word cap 150 → 300. (#464)
Changed
- Triage v2 production cutover; README synced with shipped pipeline (drop plan + research). (#478, #480)
- Rename
featureclassification toenhancementin triage. (#466)
v2.0.0 — 2026-04-20
First v2 wrapper release; tracks upstream Claude Desktop 1.3109.0, 1.3561.0.
Added
- Always-on lifecycle logging for
cowork-vm-service. (#408) cowork-vm-daemonlearnings doc and Anthropic & Partners plugin install flow doc. (#439).github/CODEOWNERSfor per-subsystem review ownership.shellcheck -xto follow sourced modules in CI.
Fixed
- Restore
cowork-vm-servicedaemon recovery after crash. (#408) - Forward
userSelectedFolders[0]assharedCwdPathon cowork spawn. (#412, #436) - Strip mode on
node-ptycp at source; retirechmod. Chmodnode-ptyunpacked files before overwriting in Nix builds. (#432, #438) - Diagnose AppArmor userns block on bwrap probe. (#351, #434)
- Suppress Cowork tab auto-select on every launch. (#341, #433)
home --dirbefore SDK--ro-bindin bwrap sandbox. (#426)- Only route
claudecommands through SDK binary incowork-vm-service. (#430) launcher-common.shself-match and stale socket cleanup. (#407, #425)- Translate guest paths inside
--allowedToolsand--disallowedTools. (#411) - Resolve working directory from primary mount on HostBackend. (#392)
Changed
- BREAKING: Split
build.shinto topical modules underscripts/; relocate packaging scripts intoscripts/packaging/; extract--doctorintoscripts/doctor.sh. Patch files now live inscripts/patches/*.sh(one per subsystem);build.shis just an orchestrator. CI paths updated toscripts/setup/detect-host.sh. - Simplify cowork daemon recovery patch. (#408)