Repository navigation
feat(app-launch): support Windows and Linux application startup - #26
Merged
Merged
Conversation
Signed-off-by: suyao <sy20010504@gmail.com>
`gio launch` exits before its D-Bus Activate call is delivered, so DBusActivatable applications (GNOME Clocks, Text Editor, Files, Settings) started their service but never opened a window and timed out. Follow the Desktop Entry Specification natively on every desktop: activate DBusActivatable entries over the session bus, falling back to Exec only when no service is installed, and otherwise expand Exec in Go and start it detached with GIO launch metadata. Terminal entries are rejected. Discovery maps owners of activatable application bus names to identities, since D-Bus service command lines differ from Exec. Cover both launch paths in the Go and SDK cold-launch tests with a D-Bus-activatable GTK fixture, and stop installing GIO tools in CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run the Exec and D-Bus activation launch test in the Sway, Hyprland, KWin and GNOME Shell CI jobs, not only isolated X11. Isolated sessions start D-Bus before the compositor, so the launch session now passes the display to D-Bus activation as desktop sessions do; without it, activated services in Wayland-only sessions could not open a window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Qt 6 on Wayland, Gecko and Chromium publish no AT-SPI tree until assistive technology is enabled session-wide, so their launches timed out. Exec launches now opt the launched process alone into accessibility. A Qt application whose GTK platform theme loads GTK also registers an empty GTK application for the same process, which made every lookup of it ambiguous. Discovery drops a childless registration when the same process has a populated one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Flatpak export resolves into a deployment directory named after its commit, so every update gave the application a new identity and a host's authorization stopped matching. Identify the launcher by the installation's "active" link while it points at the same deployment; aliases still resolve fully, so they cannot create a second identity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chromium overwrites its environment for process titles, so the launch metadata of Electron apps cannot be read back, and AppImages run their application from a private mount, often as a child of AppRun. Both timed out after launch with no identity. Remember launched PIDs with their start times so reused PIDs never inherit an identity, and offer launched entries to discovery. Match an AppImage by APPIMAGE only for processes executing from the image's mount. Parse Exec as the specification quotes it for executable matching, so quoted program paths associate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chromium publishes its page content to AT-SPI only with --force-renderer-accessibility; neither ACCESSIBILITY_ENABLED nor the session's org.a11y.Status enables it, so launched Electron apps exposed only their window frame. Add the switch when Chromium's resource pack sits beside the resolved program or one level above a wrapper script, or inside an AppImage, which is mounted read-only with its runtime's --appimage-mount without running the application. Unknown programs never receive it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the Windows/Linux launch plan to completed and record the deferred Linux work: per-launch systemd scopes and activation tokens, accessibility for already-running, D-Bus-activated, Snap and Flatpak Electron apps, and the desktops, architectures and app types not yet validated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DeJeune
marked this pull request as ready for review
October 16, 2026 09:07
Merged
6 of 7 tasks
DeJeune
added a commit
to CherryHQ/cherry-studio
that referenced
this pull request
Oct 19, 2026
### What this PR does Before this PR: Cherry Studio pins `@cherrystudio/computer-use` and its six native runtime packages to `0.1.7`. After this PR: The SDK and all native runtime packages resolve to `0.1.9`. The exact-version release-age exceptions are updated alongside the manifest and lockfile. Fixes # N/A ### Why we need it and why it was done in this way Adopt upstream Windows/Linux installed-application launch support from `0.1.8` and macOS input capability, preflight rejection, and accessibility hit-testing fixes from `0.1.9`. The following tradeoffs were made: Keep exact SDK/runtime version alignment and the existing packaging path; no application integration changes are needed. The following alternatives were considered: Remaining on `0.1.7` would omit these upstream improvements. Links to places where the discussion took place: [Upstream application launch support](CherryHQ/cherry-computer-use#26), [upstream macOS input fixes](CherryHQ/cherry-computer-use#27). ### Agent Note / Spec Agent Note: N/A β mechanical dependency bump with no new repository architecture or ownership decision. Spec PR: N/A β no Spec implementation layer. Acceptance criteria: N/A β dependency maintenance; scoped regression evidence below. ### Verification - `pnpm install` β passed, including lockfile supply-chain checks. - `pnpm change:scope --base origin/main` β confirmed only `package.json`, `pnpm-lock.yaml`, and `pnpm-workspace.yaml` changed. - `pnpm check --plan` β inspected; dependency files trigger conservative full-gate selection. Ran focused checks locally instead. - `pnpm docs:affected --base origin/main` β inspected `docs/contrib/app-upgrade.md`; update-feed documentation is unaffected by this dependency bump. - `pnpm exec oxfmt --check package.json pnpm-workspace.yaml pnpm-lock.yaml` β passed for the two matched files (lockfile is ignored by the formatter). - `git diff --check` β passed. - `pnpm typecheck:node` β passed. - `pnpm test:scripts scripts/__tests__/computer-use-packaging.test.ts scripts/__tests__/computer-use-runtime-packaging.test.ts scripts/__tests__/package-contents.test.ts` β 3 files, 24 tests passed, including standalone ESM/CJS SDK loading and type resolution. - `pnpm test:main src/main/services/__tests__/ComputerUseService.test.ts src/main/services/__tests__/ComputerUseService.control.test.ts src/main/services/automation/__tests__/ComputerAutomationSession.test.ts src/main/ai/mcp/servers/__tests__/computerUse.test.ts src/main/ai/tools/adapters/aiSdk/builtin/__tests__/ComputerUseTools.test.ts` β 5 files, 51 tests passed. ### Breaking changes None expected. No application API or configuration changes. ### Special notes for your reviewer Only the SDK and its six platform packages changed in the lockfile. No computer-use patches exist in this repository. Actual Electron interaction and packaged desktop acceptance were not run; broader validation remains with CI and platform acceptance. ### Checklist This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR. Approvers are expected to review this list. - [x] Branch: This PR targets `main` - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [ ] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note Update Computer Use to 0.1.9, bringing Windows/Linux application launch support and fixes for macOS input capabilities and accessibility hit testing. ``` Signed-off-by: suyao <sy20010504@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Before this PR:
Windows and Linux SDK bindings could only select running applications. Binding an
installed app such as Calculator failed with
UNSUPPORTED_CAPABILITYbefore launch.After this PR:
executable paths; Linux XDG desktop names, IDs and paths.
reacquisition, and wait for a matching accessible window.
DBusActivatableentries receiveorg.freedesktop.Application.Activateon thesession bus (Exec only when no service is installed); other entries run their
expanded Exec, detached from the runtime, opted into accessibility for Qt, Gecko
and Chromium. Terminal entries are rejected.
preserving possible effects after dispatch failures or cancellation. Linux maps
owners of activatable application bus names to identities first.
CI integration, SDK guidance and a Changesets patch entry.
Fixes: None.
Why we need it and why it was done in this way
The shared Go backend explicitly rejected installed lookup and launch, while the
macOS backend already supported both. The optional application driver completes
that path without changing the wire protocol or host authorization contract.
The first Linux version delegated to
gio launch. Real-machine acceptance on GNOMEshowed that it exits before its D-Bus
Activatecall is delivered: the service of aDBusActivatableapp starts, never opens a window and quits from inactivity(Clocks, Text Editor, Files, Settings; 17 entries on a stock Ubuntu GNOME). GLib
works around this dbus-daemon race only in
gio openandgtk-launch.The following tradeoffs were made:
temporary UIA worker's kill-on-close Job Object.
Path, Flatpak@@umarkerspassed through) instead of depending on GIO tools, which Debian-family KDE or
minimal compositor installs may lack. A one-line POSIX
shshim recordsGIO_LAUNCHED_DESKTOP_FILE_PIDbeforeexec, so the runtime and desktop shellscan associate the process with its entry. The command itself never runs in a shell.
Identity uses the installation's
activelink instead, while that link pointsat the same deployment, so updates keep the identity. Full symlink resolution
still prevents aliases from creating a second identity.
launch metadata cannot be read back. The runtime therefore remembers the exact
PIDs it launched, with their start times, so a reused PID never inherits an
identity. AppImages are matched by
APPIMAGEonly for processes running fromthe image's mount (
APPDIR), so programs they start do not inherit the identity.so discovery first asks the bus which PID owns the application's name.
QT_LINUX_ACCESSIBILITY_ALWAYS_ON,GNOME_ACCESSIBILITYandACCESSIBILITY_ENABLEDfor the launched process only. Enablingorg.a11y.Status.IsEnabledwould also reach running apps, but GNOME persists itas a user setting. D-Bus-activated services do not inherit these variables.
--force-renderer-accessibility; noenvironment variable or session setting exposes their page content. The switch
is added only when Chromium's
chrome_100_percent.paksits beside the resolvedprogram (or one level above a wrapper script, as with VS Code), or inside an
AppImage. The AppImage is mounted read-only with its runtime's
--appimage-mount,without running its application. Unknown programs never get the switch.
Retrying with the switch after a failed launch was rejected: Electron does not
fail without it, and relaunching would replay the launch or reach a
single-instance app that ignores new switches.
childless registration when the same process has a populated one; otherwise
every lookup of that app is ambiguous.
The following alternatives were considered:
host stop checks.
gtk-launchhandles the race but takes only desktop IDs and adds a GTK tooldependency.
and callbacks inside a
CGO_ENABLED=0runtime.go-freedesktop/desktopentryexpands Exec but was 12 days old with no knownimporters.
Links to places where the discussion took place: None.
Breaking changes
None. Existing running-only bindings and legacy CLI/MCP launch policy are preserved.
Hosts need matching updated native artifacts to enable the new startup behavior.
Special notes for your reviewer
Validated:
a path containing Chinese characters and spaces; Calculator cold launch through
the TypeScript SDK, including identity mismatch and
launch: falsepreflight.CGO_ENABLED=0.Calculator (Exec) and Clocks, Text Editor and Files (D-Bus activation) cold-launch
with the correct identity and an accessibility tree. So do KWrite (Qt 6, native
Wayland) and Snap Firefox, which used to time out. Name, ID, executable and
path queries resolve; ambiguity, mismatch and
launch: falseare rejectedwithout effects.
D-Bus activation in X11, KDE KWin, Sway, Hyprland (nested in labwc) and headless
GNOME Shell, each with native Wayland and XWayland apps where applicable. It
also passes in KWin with
gio,gtk-launchandgapplicationhidden. CI runsit in every compositor job. With the old
gio launchdispatch, the D-Bus casetimes out. The existing X11 engine/input suite still passes with the extended
fixture.
integration: 31 scoped control/REPL tests with scoped lint/format and docs checks.
The Windows executable symlink test skipped because the test host lacks symlink
privilege.
Not yet covered
Deferred to follow-ups and tracked in
docs/exec-plans/tech-debt-tracker.md.Desktops and sessions. The compositors above ran isolated, not as full logged-in
desktops, and only GNOME Wayland was tested on a real machine (arm64).
kwin_x11). Inthese, the session itself must export the display to D-Bus activation.
passes, but these desktops were not installed.
The isolated sessions use a plain
dbus-daemon, not systemd activation.Launch paths:
ServiceUnknownfalling back to Exec, for anActivateerror or cancellation after dispatch, for
Path=, or for rejecting terminal entries.scope: KWrite started this way landed in
app-com.anthropic.Claude-*.scope.Desktops may attribute the app to the host, and stopping that scope can end the app.
compositor policy.
Applications:
Editor, Files).
already running, or that are started by D-Bus activation, still expose no tree
until accessibility is enabled session-wide.
policy refuses AT-SPI to clients with another label: this test session runs as
claude-desktopand was denied. A Firefox that is already running gets no opt-in.as an AppImage): launch, identity and page content work (103 and 104 elements;
one without the detected switch). MuseScore and Calculator launch without it.
Electron apps from Snap or Flatpak are not detected, so they get no switch.
Its Qt Quick UI returns empty references for most of its 75 children.
KCalc (Qt 6) cold-launch by name in isolated X11, KWin and GNOME Shell sessions
configured as after login. Identities come from
.flatpak-info, and the Qtopt-in reaches the sandbox. In a session started before Flatpak was installed,
neither app resolves by name and Weather cannot be activated (no bus service)
until the user logs in again. This matches the desktop shells. A real desktop
after re-login is untested.
Linux acceptance commands (need Xvfb or Xephyr, AT-SPI, Python GI and GTK 3 for the
fixture; the runtime needs neither Python nor GIO):
SDK/native packages have not been published.
Checklist
mainRelease note
π€ Generated with Claude Code