feat(cua-driver-rs): rename to com.trycua.cuadriver + /Applications/CuaDriver.app - #1559
Conversation
…uaDriver.app
The Rust port is the canonical cua-driver going forward. Rename the bundle to drop the `Rs` suffix — install at `/Applications/CuaDriver.app` with bundle id `com.trycua.cuadriver`. Replaces the Swift driver's `.app` on install rather than coexisting under a separate path. The Swift driver still ships under `cua-driver-v*` tags with bundle id `com.trycua.driver` (legacy), but going forward `--experimental-rust` against the canonical install URL takes over the `/Applications/CuaDriver.app` slot.
## Files renamed
- `libs/cua-driver-rs/scripts/CuaDriverRs.app/` → `libs/cua-driver-rs/scripts/CuaDriver.app/` (git-tracked directory rename, including the `Contents/MacOS/.gitkeep` placeholder).
## String updates (`CuaDriverRs.app` → `CuaDriver.app`, `com.trycua.cuadriverrs` → `com.trycua.cuadriver`, `is_executable_inside_cuadriverrs_app` → `is_executable_inside_cuadriver_app`)
- `libs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plist` — `CFBundleIdentifier`, `CFBundleName`, `CFBundleDisplayName` all updated. Header doc rewritten to explain the rename + the Swift takeover semantics.
- Rust source: `bundle.rs`, `cli.rs`, `proxy.rs`, `main.rs` — TCC auto-relaunch heuristic checks the new path string; function rename propagated through.
- `libs/cua-driver/scripts/_install-rust.sh`: `APP_NAME="CuaDriver.app"`; install path and all comments updated. Added a Swift-takeover detection block that reads the prior bundle's `CFBundleIdentifier` via `PlistBuddy` before overwriting — when it sees `com.trycua.driver` it sets `REPLACED_SWIFT=1` and the post-install message surfaces the `tccutil reset` commands so the user can clear orphaned grants for the Swift bundle id.
- `libs/cua-driver/scripts/install.sh`: comment updates only (no logic change; the script just dispatches to `_install-rust.sh`).
- `libs/cua-driver-rs/scripts/install-local.sh`: dev-loop installer's bundle path updated.
- `.github/workflows/cd-rust-cua-driver.yml`: macOS bundle assembly step now writes `release/CuaDriver.app`, `Contents/Info.plist` references the new bundle id, codesign + notarize + staple all target the renamed bundle path. The directory tarball still ships as `cua-driver-rs-v<v>-darwin-universal.tar.gz` (release-tag scheme is unchanged — only the inner bundle is renamed) so the install scripts on existing dev branches still find what they expect.
- `docs/content/docs/cua-driver/guide/getting-started/installation.mdx`: explains the new install path + the Swift-replacement behavior.
## What this does NOT do
- Doesn't change the release-tag prefix (`cua-driver-rs-v*` stays). The tag → asset → install URL contract is unchanged; only the inner bundle metadata moves. Existing one-liners (`cua-driver-rs/scripts/install.{sh,ps1}` redirect shims, the canonical `cua-driver/scripts/install.sh`) all keep working.
- Doesn't change the binary name (`cua-driver` on PATH stays the same — Hermes and anything else that calls the binary by name is unaffected).
- Doesn't migrate `~/.cua-driver-rs/` to `~/.cua-driver/` — the package home stays where it is. Migrating it would require a one-shot move under a `cua-driver migrate` verb; deferred until requested.
- Doesn't auto-uninstall the legacy Swift driver beyond the .app replacement. `~/.cua-driver/` (Swift's config), `~/Library/Application Support/Cua Driver/`, the Swift TCC grants — all stay until the user explicitly runs the Swift uninstaller or `tccutil reset`.
## Test plan
- [ ] Tag a new `cua-driver-rs-v*` release (or workflow_dispatch); verify the bundle in the published tarball has `CFBundleIdentifier = com.trycua.cuadriver`.
- [ ] macOS clean install: `curl …/libs/cua-driver/scripts/install.sh | bash -s -- --experimental-rust` → `/Applications/CuaDriver.app` lands, `cua-driver --version` works, first action prompts TCC for `com.trycua.cuadriver` (not the old `com.trycua.cuadriverrs`).
- [ ] macOS Swift-takeover: pre-install the Swift driver, then run the Rust install — the "Replaced the Swift cua-driver bundle" note prints with the tccutil reset commands.
- [ ] In-flight uninstall PR (#1558) needs a small rebase after this lands: `_uninstall-rust.sh` removes `/Applications/CuaDriverRs.app` (old path); update to `/Applications/CuaDriver.app` + drop the old tccutil reset lines for `com.trycua.cuadriverrs` (or keep them as legacy cleanup for users upgrading from the older bundle).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughConsolidates the Rust macOS app bundle name to ChangesmacOS App Bundle Rename (CuaDriverRs.app → CuaDriver.app)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/cd-rust-cua-driver.yml:
- Around line 276-285: Add a check that the assembled Info.plist contains the
expected bundle identifier "com.trycua.cuadriver" in the same smoke-test step
that currently prints CFBundle(Short)?Version; after plutil -p
release/CuaDriver.app/Contents/Info.plist | grep -E 'CFBundle(Short)?Version'
run a plutil/grep (or plutil + jq) assertion on CFBundleIdentifier and exit
non‑zero (failing the job) if the value is not exactly "com.trycua.cuadriver";
update the step named "Codesign + notarize + staple CuaDriver.app" to include
this assertion so stale identifiers fail fast.
In `@docs/content/docs/cua-driver/guide/getting-started/installation.mdx`:
- Around line 44-46: Update the paragraph that currently claims Swift and Rust
installers can "coexist" — change it to state that installing the Rust installer
with --experimental-rust replaces the existing /Applications/CuaDriver.app
bundle (the Swift app at /Applications/CuaDriver.app is migrated/replaced rather
than preserved), and clarify that bundle ids (com.trycua.cuadriver vs
com.trycua.driver) no longer imply separate app bundle paths in this takeover;
keep the note that ~/.local/bin/cua-driver points at the Rust binary and retain
the mention that --bin-dir / --no-modify-path flags and forwarding of arguments
after --experimental-rust still apply.
In `@libs/cua-driver-rs/crates/cua-driver/src/proxy.rs`:
- Around line 49-52: The error message produced by anyhow::bail in proxy.rs
currently tells the user how to start the daemon but always uses the default
socket; update the message in the run_proxy path that references socket_path so
that when a non-default socket_path is used the recovery hint includes the flag
`--socket {socket_path}`. Locate the bail call that mentions {socket_path} and
conditionally append ` --socket {socket_path}` (or always include it) in the
string so the suggested start command will retry against the same socket; ensure
you reference the socket_path variable in the formatted message and keep the
rest of the suggestion unchanged.
In `@libs/cua-driver-rs/scripts/install-local.sh`:
- Around line 27-29: Update the macOS layout comment to reflect the actual
install flow used by the script: state that the binary is placed in a versioned
directory under $CUA_DRIVER_RS_HOME (e.g.,
$CUA_DRIVER_RS_HOME/<version>/cua-driver) and that a symlink is created in
$BIN_DIR (e.g., $BIN_DIR/cua-driver ->
$CUA_DRIVER_RS_HOME/<version>/cua-driver), instead of saying it installs to
/Applications/CuaDriver.app/Contents/MacOS; reference the $CUA_DRIVER_RS_HOME
and $BIN_DIR variables in the comment so it matches the script behavior.
In `@libs/cua-driver/scripts/_install-rust.sh`:
- Around line 96-97: The installer comment containing the phrase "coexist on the
same machine" is now incorrect because the Rust installer replaces
/Applications/CuaDriver.app in-place rather than installing side-by-side; update
the text in _install-rust.sh (the comment around lines referencing "coexist on
the same machine") to remove or change the word "coexist" and instead state that
the Rust installer takes over or replaces the existing CuaDriver.app at
/Applications/CuaDriver.app to accurately reflect Swift→Rust takeover and
relaunch behavior.
In `@libs/cua-driver/scripts/install.sh`:
- Around line 19-20: Update the header comment in
libs/cua-driver/scripts/install.sh that currently claims the Rust backend
installs to a “separate bundle (CuaDriver.app)” and leaves the Swift binary
untouched; change the wording to state that the installer performs an in-place
replacement (may overwrite an existing Swift bundle at
/Applications/CuaDriver.app) so the doc reflects current takeover semantics.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c198da89-afd1-473f-8b8e-86c29a8d3577
📒 Files selected for processing (12)
.github/workflows/cd-rust-cua-driver.ymldocs/content/docs/cua-driver/guide/getting-started/installation.mdxlibs/cua-driver-rs/crates/cua-driver/src/bundle.rslibs/cua-driver-rs/crates/cua-driver/src/cli.rslibs/cua-driver-rs/crates/cua-driver/src/main.rslibs/cua-driver-rs/crates/cua-driver/src/proxy.rslibs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plistlibs/cua-driver-rs/scripts/CuaDriver.app/Contents/MacOS/.gitkeeplibs/cua-driver-rs/scripts/CuaDriverRs.app/Contents/Info.plistlibs/cua-driver-rs/scripts/install-local.shlibs/cua-driver/scripts/_install-rust.shlibs/cua-driver/scripts/install.sh
💤 Files with no reviewable changes (1)
- libs/cua-driver-rs/scripts/CuaDriverRs.app/Contents/Info.plist
| plutil -replace CFBundleShortVersionString -string "$VERSION" \ | ||
| release/CuaDriverRs.app/Contents/Info.plist | ||
| release/CuaDriver.app/Contents/Info.plist | ||
| plutil -replace CFBundleVersion -string "$VERSION" \ | ||
| release/CuaDriverRs.app/Contents/Info.plist | ||
| release/CuaDriver.app/Contents/Info.plist | ||
| # Remove the .gitkeep we use in source control — it's not | ||
| # part of the runtime bundle. | ||
| rm -f release/CuaDriverRs.app/Contents/MacOS/.gitkeep | ||
| ls -la release/CuaDriverRs.app/Contents/MacOS | ||
| plutil -p release/CuaDriverRs.app/Contents/Info.plist | grep -E 'CFBundle(Short)?Version' | ||
| - name: Codesign + notarize + staple CuaDriverRs.app | ||
| rm -f release/CuaDriver.app/Contents/MacOS/.gitkeep | ||
| ls -la release/CuaDriver.app/Contents/MacOS | ||
| plutil -p release/CuaDriver.app/Contents/Info.plist | grep -E 'CFBundle(Short)?Version' | ||
| - name: Codesign + notarize + staple CuaDriver.app |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Assert the renamed bundle identifier here too.
Line 284 only checks that the version keys exist, so a stale CFBundleIdentifier would still pass this job even though the Swift→Rust takeover path depends on that value. Please fail fast on com.trycua.cuadriver in the assembled plist as part of this smoke check.
Suggested change
plutil -replace CFBundleVersion -string "$VERSION" \
release/CuaDriver.app/Contents/Info.plist
# Remove the .gitkeep we use in source control — it's not
# part of the runtime bundle.
rm -f release/CuaDriver.app/Contents/MacOS/.gitkeep
ls -la release/CuaDriver.app/Contents/MacOS
plutil -p release/CuaDriver.app/Contents/Info.plist | grep -E 'CFBundle(Short)?Version'
+ /usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' \
+ release/CuaDriver.app/Contents/Info.plist | grep -qx 'com.trycua.cuadriver'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/cd-rust-cua-driver.yml around lines 276 - 285, Add a check
that the assembled Info.plist contains the expected bundle identifier
"com.trycua.cuadriver" in the same smoke-test step that currently prints
CFBundle(Short)?Version; after plutil -p
release/CuaDriver.app/Contents/Info.plist | grep -E 'CFBundle(Short)?Version'
run a plutil/grep (or plutil + jq) assertion on CFBundleIdentifier and exit
non‑zero (failing the job) if the value is not exactly "com.trycua.cuadriver";
update the step named "Codesign + notarize + staple CuaDriver.app" to include
this assertion so stale identifiers fail fast.
| anyhow::bail!( | ||
| "cua-driver-rs daemon not reachable on {socket_path}. Start it \ | ||
| with `open -n -g -a CuaDriverRs --args serve` and retry." | ||
| with `open -n -g -a CuaDriver --args serve` and retry." | ||
| ); |
There was a problem hiding this comment.
Include the socket override in the recovery command when non-default socket is used.
If run_proxy is invoked with a custom socket, the current hint starts the daemon on the default socket, so retry still fails. Append --socket {socket_path} when applicable.
Suggested patch
if !is_daemon_listening(&socket_path) {
+ let socket_suffix = if socket_path != crate::serve::default_socket_path() {
+ format!(" --socket {socket_path}")
+ } else {
+ String::new()
+ };
anyhow::bail!(
"cua-driver-rs daemon not reachable on {socket_path}. Start it \
- with `open -n -g -a CuaDriver --args serve` and retry."
+ with `open -n -g -a CuaDriver --args serve{socket_suffix}` and retry."
);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| anyhow::bail!( | |
| "cua-driver-rs daemon not reachable on {socket_path}. Start it \ | |
| with `open -n -g -a CuaDriverRs --args serve` and retry." | |
| with `open -n -g -a CuaDriver --args serve` and retry." | |
| ); | |
| if !is_daemon_listening(&socket_path) { | |
| let socket_suffix = if socket_path != crate::serve::default_socket_path() { | |
| format!(" --socket {socket_path}") | |
| } else { | |
| String::new() | |
| }; | |
| anyhow::bail!( | |
| "cua-driver-rs daemon not reachable on {socket_path}. Start it \ | |
| with `open -n -g -a CuaDriver --args serve{socket_suffix}` and retry." | |
| ); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver-rs/crates/cua-driver/src/proxy.rs` around lines 49 - 52, The
error message produced by anyhow::bail in proxy.rs currently tells the user how
to start the daemon but always uses the default socket; update the message in
the run_proxy path that references socket_path so that when a non-default
socket_path is used the recovery hint includes the flag `--socket
{socket_path}`. Locate the bail call that mentions {socket_path} and
conditionally append ` --socket {socket_path}` (or always include it) in the
string so the suggested start command will retry against the same socket; ensure
you reference the socket_path variable in the formatted message and keep the
rest of the suggestion unchanged.
| # macOS layout produced: | ||
| # /Applications/CuaDriverRs.app/Contents/MacOS/cua-driver (bundle replaced wholesale) | ||
| # $HOME/.local/bin/cua-driver -> .../CuaDriverRs.app/Contents/MacOS/cua-driver | ||
| # /Applications/CuaDriver.app/Contents/MacOS/cua-driver (bundle replaced wholesale) | ||
| # $HOME/.local/bin/cua-driver -> .../CuaDriver.app/Contents/MacOS/cua-driver |
There was a problem hiding this comment.
Fix macOS layout comment to match real local-install behavior.
Line 27–29 documents /Applications/CuaDriver.app/..., but this script installs via versioned dirs under $CUA_DRIVER_RS_HOME and symlinks from $BIN_DIR. Please align the comment with the actual flow to prevent developer confusion.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver-rs/scripts/install-local.sh` around lines 27 - 29, Update the
macOS layout comment to reflect the actual install flow used by the script:
state that the binary is placed in a versioned directory under
$CUA_DRIVER_RS_HOME (e.g., $CUA_DRIVER_RS_HOME/<version>/cua-driver) and that a
symlink is created in $BIN_DIR (e.g., $BIN_DIR/cua-driver ->
$CUA_DRIVER_RS_HOME/<version>/cua-driver), instead of saying it installs to
/Applications/CuaDriver.app/Contents/MacOS; reference the $CUA_DRIVER_RS_HOME
and $BIN_DIR variables in the comment so it matches the script behavior.
| # separate bundle (CuaDriver.app) so the Swift | ||
| # binary is left untouched. Also accepted as |
There was a problem hiding this comment.
Correct Rust-backend behavior description in header docs.
Line 19–20 says Rust installs to a “separate bundle” and leaves Swift untouched, but current takeover behavior can replace an existing Swift bundle at /Applications/CuaDriver.app. Please update the wording to reflect in-place replacement semantics.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/scripts/install.sh` around lines 19 - 20, Update the header
comment in libs/cua-driver/scripts/install.sh that currently claims the Rust
backend installs to a “separate bundle (CuaDriver.app)” and leaves the Swift
binary untouched; change the wording to state that the installer performs an
in-place replacement (may overwrite an existing Swift bundle at
/Applications/CuaDriver.app) so the doc reflects current takeover semantics.
….cuadriver`) Per Francesco's clarification: the Rust port should use the exact same bundle id the Swift driver has used since v0 — `com.trycua.driver` — not a `cuadriver` variant. Same bundle id at the same install path (`/Applications/CuaDriver.app`) means TCC grants survive the Swift → Rust upgrade automatically: macOS keys Accessibility / Screen Recording on bundle id, not on cdhash alone, so the prior Swift binary's grants apply to the new Rust binary too. This supersedes the earlier-in-this-PR `com.trycua.cuadriver` choice. The intermediate name was wrong — verified against the Swift sources of truth: - `libs/cua-driver/App/CuaDriver/Info.plist`: `CFBundleIdentifier = com.trycua.driver` - `libs/cua-driver/scripts/build-app.sh`: `--identifier com.trycua.driver` (codesigning) - `libs/cua-driver/Sources/.../*.swift`: numerous `os_log` subsystems hard-pinned to `com.trycua.driver` ## What changed since the first commit - `libs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plist`: `CFBundleIdentifier` `com.trycua.cuadriver` → `com.trycua.driver`. Header comment rewritten — no longer claims the bundle id is "intentionally distinct from Swift's"; it's the same. Added a note about cdhash-pairing in TCC (which may cause a one-time re-grant prompt even though the bundle id is preserved). - Rust source (`bundle.rs`, `cli.rs`, `proxy.rs`, `main.rs`): all `com.trycua.cuadriver` → `com.trycua.driver`. - `libs/cua-driver/scripts/_install-rust.sh`: - `APP_NAME` comment block updated: "Identical to the Swift driver's CuaDriver.app + com.trycua.driver pair — the Rust port replaces the Swift install at this path, preserving TCC grants." - Post-install message rewritten: no longer says "orphaned" / "Clear them with tccutil reset"; instead explains that grants transfer (bundle id preserved) and that a one-time cdhash re-prompt may fire on first action. - `libs/cua-driver/scripts/install.sh`, `libs/cua-driver-rs/scripts/install-local.sh`, `.github/workflows/cd-rust-cua-driver.yml`, `docs/.../installation.mdx`: bundle id refs swept through. - `libs/cua-driver-rs/PARITY.md`: stale `cuadriverrs` references swept. ## Net effect Installing the Rust port over a Swift install is now truly seamless: same .app path, same bundle id, TCC grants persist, no `tccutil reset` instructions needed. The earlier per-PR work to detect the Swift takeover (`REPLACED_SWIFT=1` block) stays — it logs that the upgrade replaced an older bundle, but the message no longer threatens grant loss.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
docs/content/docs/cua-driver/guide/getting-started/installation.mdx (1)
44-45:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFix the bundle-id contradiction and incorrect coexistence claim.
This section contains three critical factual errors:
- Line 44 claims the Rust driver has a "separate bundle id (
com.trycua.driver) from the Swift driver'scom.trycua.driver" — but both are identical (com.trycua.driver), not separate.- The claim that "Both can coexist...with independent TCC grants" is incorrect. macOS TCC keys grants by
(cdhash, bundle-id), so the same bundle id means TCC grants are shared/preserved during the Swift→Rust replacement, not independent.- Line 45 claims the Swift app is "left untouched", but the installer actually replaces
/Applications/CuaDriver.appin place when upgrading from Swift to Rust.Per the PR summary, the correct behavior is: "installer messages adjusted to state that TCC grants are preserved" — the upgrade replaces the Swift app and preserves its TCC grants because both use
com.trycua.driver.📝 Suggested correction
-- Installs `CuaDriver.app` to `/Applications/` — separate bundle id (`com.trycua.driver`) from the Swift driver's `com.trycua.driver`. Both can coexist on the same machine with independent TCC grants and independent telemetry IDs. -- Points `~/.local/bin/cua-driver` at the Rust binary. The Swift `CuaDriver.app` (if previously installed) is left untouched and still launchable via its bundle path (`/Applications/CuaDriver.app/Contents/MacOS/cua-driver`). +- Installs `CuaDriver.app` to `/Applications/` with bundle id `com.trycua.driver` (matching the Swift driver). +- If `/Applications/CuaDriver.app` already contains the Swift driver, the installer replaces it in place. TCC grants are preserved because both drivers share the same bundle id. +- Points `~/.local/bin/cua-driver` at the Rust binary.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/content/docs/cua-driver/guide/getting-started/installation.mdx` around lines 44 - 45, Correct the factual errors about bundle IDs, TCC behavior, and installer replacement: change the text that currently claims separate bundle IDs and independent TCC grants to state that both Swift and Rust drivers use the same bundle id "com.trycua.driver", that macOS TCC grants are preserved/shared (granted by cdhash+bundle-id) when upgrading, and that the installer replaces /Applications/CuaDriver.app in-place (while still creating ~/.local/bin/cua-driver to point to the Rust binary); update the sentences mentioning the bundle id, TCC grants, and "left untouched" behavior accordingly in the installation section.libs/cua-driver/scripts/_install-rust.sh (1)
481-488:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix stale coexistence wording in macOS install comment.
This comment says the Swift and Rust apps have a “different bundle id” and “coexist,” which conflicts with the current in-place takeover model (
/Applications/CuaDriver.app+com.trycua.driver).Suggested wording update
-# should fire. Same shape as the Swift `cua-driver` install path — -# different bundle id (com.trycua.driver) so the two coexist. +# should fire. Same path and bundle id as the Swift driver +# (`/Applications/CuaDriver.app`, `com.trycua.driver`), so installs +# replace in place rather than coexist side-by-side.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/cua-driver/scripts/_install-rust.sh` around lines 481 - 488, Update the macOS install comment in the _install-rust.sh block that mentions coexistence: change the wording around the Swift vs Rust apps so it no longer claims a “different bundle id” or that they “coexist”; instead state that the Rust installer uses the same bundle id (com.trycua.driver) and performs an in-place takeover of /Applications/CuaDriver.app, and keep the note about symlinking the binary and how is_executable_inside_cuadriver_app() uses realpath to detect the resolved path for the auto-relaunch heuristic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plist`:
- Around line 49-50: The CFBundleShortVersionString in Info.plist is hardcoded
to 0.1.3 and must match the installer release (0.2.3); update the
CFBundleShortVersionString value to the current release version (0.2.3) in the
Info.plist so app bundle metadata and logs reflect the installer version,
ensuring the CFBundleShortVersionString entry is synchronized with your release
pipeline.
---
Duplicate comments:
In `@docs/content/docs/cua-driver/guide/getting-started/installation.mdx`:
- Around line 44-45: Correct the factual errors about bundle IDs, TCC behavior,
and installer replacement: change the text that currently claims separate bundle
IDs and independent TCC grants to state that both Swift and Rust drivers use the
same bundle id "com.trycua.driver", that macOS TCC grants are preserved/shared
(granted by cdhash+bundle-id) when upgrading, and that the installer replaces
/Applications/CuaDriver.app in-place (while still creating
~/.local/bin/cua-driver to point to the Rust binary); update the sentences
mentioning the bundle id, TCC grants, and "left untouched" behavior accordingly
in the installation section.
In `@libs/cua-driver/scripts/_install-rust.sh`:
- Around line 481-488: Update the macOS install comment in the _install-rust.sh
block that mentions coexistence: change the wording around the Swift vs Rust
apps so it no longer claims a “different bundle id” or that they “coexist”;
instead state that the Rust installer uses the same bundle id
(com.trycua.driver) and performs an in-place takeover of
/Applications/CuaDriver.app, and keep the note about symlinking the binary and
how is_executable_inside_cuadriver_app() uses realpath to detect the resolved
path for the auto-relaunch heuristic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: eca480da-4926-4e44-97da-542174a21cc9
📒 Files selected for processing (4)
docs/content/docs/cua-driver/guide/getting-started/installation.mdxlibs/cua-driver-rs/PARITY.mdlibs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plistlibs/cua-driver/scripts/_install-rust.sh
✅ Files skipped from review due to trivial changes (1)
- libs/cua-driver-rs/PARITY.md
| <key>CFBundleShortVersionString</key> | ||
| <string>0.1.3</string> |
There was a problem hiding this comment.
Keep app bundle version aligned with installer release version.
CFBundleShortVersionString is pinned to 0.1.3, but the installer currently bakes 0.2.3. This will report stale app metadata/log output during replacements.
Suggested minimal fix
<key>CFBundleShortVersionString</key>
- <string>0.1.3</string>
+ <string>0.2.3</string>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <key>CFBundleShortVersionString</key> | |
| <string>0.1.3</string> | |
| <key>CFBundleShortVersionString</key> | |
| <string>0.2.3</string> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plist` around lines 49
- 50, The CFBundleShortVersionString in Info.plist is hardcoded to 0.1.3 and
must match the installer release (0.2.3); update the CFBundleShortVersionString
value to the current release version (0.2.3) in the Info.plist so app bundle
metadata and logs reflect the installer version, ensuring the
CFBundleShortVersionString entry is synchronized with your release pipeline.
Three fixes flagged by CR's review of the rename commit: 1. **`installation.mdx:44-45`** — old text said the Rust port had a "separate bundle id (`com.trycua.driver`) from the Swift driver's `com.trycua.driver`" (literally contradicting itself), and that the Swift `.app` was left untouched. Reality: both share `com.trycua.driver`, the Rust install replaces Swift in place, TCC grants are preserved (keyed on bundle id, may re-prompt once because cdhash differs). Rewrote the bullet to match. Also rewrote "Switch back to Swift" — no `rm -rf` needed, just re-run the canonical install without the `--experimental-rust` flag (Swift driver still ships under its own `cua-driver-v*` tag stream). 2. **`_install-rust.sh:481-488`** — same "different bundle id so the two coexist" claim in the macOS install-block comment. Rewrote to match: same path + same bundle id = in-place takeover; TCC survives the swap; cdhash re-prompt may fire once. 3. **`Info.plist:49-52`** — `CFBundleShortVersionString` was hardcoded to `0.1.3` (a stale dev placeholder); the CD workflow rewrites it at every tag push via `plutil -replace`. Bumped both version keys to clearly-sentinel placeholders (`0.0.0-dev` / `0`) and added an XML comment explaining the rewrite contract so future readers don't think this is the published version. No behavior changes — three doc/comment/plist clarifications.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
….driver) #1559 landed the Rust port at `/Applications/CuaDriver.app` with bundle id `com.trycua.driver` — the same path + bundle id the Swift driver uses. This PR (the uninstall convergence) was written against the pre-rename layout (`/Applications/CuaDriverRs.app` + `com.trycua.cuadriverrs`). Rebase + update the references accordingly. ## Changes since the rebase - `_uninstall-rust.sh`: - `APP_BUNDLE` → `/Applications/CuaDriver.app` (current canonical); added `LEGACY_APP_BUNDLE` constant pointing at `/Applications/CuaDriverRs.app` for users still on the pre-rename install. - macOS `.app` removal loop iterates over both. The shared path with Swift is the right thing to remove on `--experimental-rust` because: (a) Rust replaced Swift on install, (b) the user asking for Rust uninstall wants the binary on disk gone, (c) re-installing Swift is just a re-run of `install.sh` without the flag. - Symlink-detection comment + glob updated: post-rename, path patterns alone can't tell Rust from Swift (same `.app` path, same bundle id). The script uses `~/.cua-driver-rs/` (the Rust-specific state dir) as the marker — a Swift-only install never creates this dir. Plus the legacy `CuaDriverRs.app` substring still matches old installs unambiguously. - `~/.claude.json` MCP-scrubbing python helper updated to also match the new `/Applications/CuaDriver.app` path string. - Closing tccutil hint switched from `com.trycua.cuadriverrs` to `com.trycua.driver`, with an explicit note that the bundle id is shared with the Swift driver — resetting it clears grants for both backends, so users who still run Swift should skip the reset. - `installation.mdx` uninstall section: - Rust-macOS row now lists both the current `/Applications/CuaDriver.app` and the legacy `/Applications/CuaDriverRs.app`; symlink-detection note updated to mention the `~/.cua-driver-rs/` marker check. - TCC reset callout reflects the shared bundle id (`com.trycua.driver` for both Swift and current Rust) and adds a "pre-rename Rust install" block with the legacy `com.trycua.cuadriverrs` reset for users upgrading from `cua-driver-rs ≤ 0.2.3`. No script API changes — just path/identity refresh.
…all.{sh,ps1} per platform (#1558)
* feat(uninstall): mirror install-convergence — single canonical uninstall.sh + .ps1 per platform
Extends libs/cua-driver/scripts/uninstall.sh with `--experimental-rust` /
`--backend=rust` flag handling (mirrors install.sh exactly) and adds a
parallel uninstall.ps1 for Windows. The Rust uninstall logic lives at
libs/cua-driver/scripts/_uninstall-rust.sh as a private helper, mirroring
the install side's _install-rust.sh layout.
Before this commit only the Swift macOS uninstall existed — Rust-port
removal was a documented `rm -rf` recipe and Windows had no uninstall
script at all. One canonical uninstall URL now works on every platform.
Layout after this PR:
libs/cua-driver/scripts/
install.sh ← canonical .sh installer (Swift default,
--experimental-rust → Rust, Linux auto-detect)
install.ps1 ← canonical .ps1 installer (Rust port)
_install-rust.sh ← private install helper
uninstall.sh ← canonical .sh uninstaller (NEW flag handling;
Swift default, --experimental-rust → Rust,
Linux auto-detect)
uninstall.ps1 ← canonical .ps1 uninstaller (NEW)
_uninstall-rust.sh ← private uninstall helper (NEW)
Behaviour matrix:
| Platform | URL | What gets removed |
|---|---|---|
| macOS — Swift (default) | uninstall.sh | /Applications/CuaDriver.app, ~/.local/bin/cua-driver, ~/.cua-driver, ~/Library/Application Support/Cua Driver, ~/Library/Caches/cua-driver, legacy LaunchAgent, skill symlinks, ~/.claude.json scrub |
| macOS — Rust (`--experimental-rust`) | uninstall.sh + _uninstall-rust.sh | /Applications/CuaDriverRs.app, ~/.local/bin/cua-driver (only when it resolves into CuaDriverRs.app), ~/.cua-driver-rs/, com.trycua.cua-driver-rs LaunchAgent, cua-driver-rs skill symlinks, ~/.claude.json scrub |
| Linux (auto-detect) | uninstall.sh + _uninstall-rust.sh | ~/.local/bin/cua-driver (only when it resolves into ~/.cua-driver-rs/), ~/.cua-driver-rs/, ~/.config/systemd/user/cua-driver-rs.service (stop+disable+remove), cua-driver-rs skill symlinks, ~/.claude.json scrub |
| Windows | uninstall.ps1 | Scheduled Task cua-driver-serve, all running cua-driver.exe processes, %LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin junction, %USERPROFILE%\.cua-driver-rs\packages\current junction, %USERPROFILE%\.cua-driver-rs\ tree, cua-driver-rs skill junctions |
Safety invariants (mirror the install scripts):
- `--experimental-rust` / `--backend=rust` / `--backend=swift` / `--backend=*`
parsed exactly like install.sh, with the same FORWARDED_ARGS bucket so
future Rust-only uninstall flags pass through cleanly.
- Linux auto-detection (`uname -s != Darwin`) flips USE_RUST_BACKEND=1
with the same note: prefix and same `--backend=swift` escape hatch.
- _uninstall-rust.sh refuses to clobber a real directory at a path the
install script could only have created as a symlink — uses `[[ -L ]]`
+ realpath check on the bin symlink before deleting.
- uninstall.ps1 checks the IO_REPARSE_TAG_MOUNT_POINT reparse-point bit
via Get-Item .Attributes before Remove-Item on bin\ / current\ /
skill junctions; refuses real directories with a clear log line.
- Idempotent: re-running on an already-clean system prints "nothing to
remove" per item, never errors.
What this PR does NOT do:
- Auto-revoke TCC grants on macOS. Same conservative stance as the
existing Swift uninstall — closing message prints the `tccutil reset`
commands for both com.trycua.driver (Swift) and com.trycua.cuadriverrs
(Rust) so a clean re-install flow is one paste away.
- Auto-edit ~/.claude.json on Windows. Mirrors the macOS uninstall's
conservative stance for hosts without python3; closing message prints
the `claude mcp remove cua-driver-rs` command instead.
- Remove the user's PATH entry on Windows. Closing message prints the
exact [Environment]::SetEnvironmentVariable snippet to do it manually.
Validated end-to-end on a real macOS box:
- `--backend=swift` removes the Swift install cleanly + is idempotent.
- `--experimental-rust` removes /Applications/CuaDriverRs.app + ~/.cua-driver-rs/.
- `--backend=foo` exits 2 with a clear error.
- `--backend=rust` (long form) behaves identically to --experimental-rust.
- Linux auto-detection verified via a fake `uname -s = Linux` shim:
the script prints the auto-select note, skips macOS-only paths
(LaunchAgent, /Applications/CuaDriverRs.app), and runs the Linux
systemd cleanup branch instead.
- bash -n syntax-check passes on both new scripts.
- Re-running each path on an already-clean host prints "nothing to
remove" per item — no errors.
Windows uninstall.ps1 is unvalidated on a live Windows box yet — the
PR description ships the manual test plan for it. The script mirrors
install.ps1's variable naming, path resolution, and reparse-point check
shape so the structural soundness is mechanical even ahead of a live run.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(uninstall): address CodeRabbit nits on PR #1558
- L547: drop the absolute `_uninstall-rust.sh` URL to main (would 404 until the PR merges); replace with prose pointing at the colocated path under `libs/cua-driver/scripts/`.
- L559: "both uninstallers" is ambiguous (the table above lists four combinations); name the three scripts explicitly — `uninstall.sh`, `_uninstall-rust.sh`, `uninstall.ps1`.
- L583: clarify the python3 footnote — macOS/Linux uninstaller does auto-edit `~/.claude.json` when python3 is on PATH; the Windows variant skips it unconditionally to stay dep-free. Drops the "conservative stance for hosts without python3" phrasing that confused the reviewer.
All three are docs-only; no script logic changes.
* fix(uninstall): rebase on post-rename main (CuaDriver.app, com.trycua.driver)
#1559 landed the Rust port at `/Applications/CuaDriver.app` with bundle id `com.trycua.driver` — the same path + bundle id the Swift driver uses. This PR (the uninstall convergence) was written against the pre-rename layout (`/Applications/CuaDriverRs.app` + `com.trycua.cuadriverrs`). Rebase + update the references accordingly.
## Changes since the rebase
- `_uninstall-rust.sh`:
- `APP_BUNDLE` → `/Applications/CuaDriver.app` (current canonical); added `LEGACY_APP_BUNDLE` constant pointing at `/Applications/CuaDriverRs.app` for users still on the pre-rename install.
- macOS `.app` removal loop iterates over both. The shared path with Swift is the right thing to remove on `--experimental-rust` because: (a) Rust replaced Swift on install, (b) the user asking for Rust uninstall wants the binary on disk gone, (c) re-installing Swift is just a re-run of `install.sh` without the flag.
- Symlink-detection comment + glob updated: post-rename, path patterns alone can't tell Rust from Swift (same `.app` path, same bundle id). The script uses `~/.cua-driver-rs/` (the Rust-specific state dir) as the marker — a Swift-only install never creates this dir. Plus the legacy `CuaDriverRs.app` substring still matches old installs unambiguously.
- `~/.claude.json` MCP-scrubbing python helper updated to also match the new `/Applications/CuaDriver.app` path string.
- Closing tccutil hint switched from `com.trycua.cuadriverrs` to `com.trycua.driver`, with an explicit note that the bundle id is shared with the Swift driver — resetting it clears grants for both backends, so users who still run Swift should skip the reset.
- `installation.mdx` uninstall section:
- Rust-macOS row now lists both the current `/Applications/CuaDriver.app` and the legacy `/Applications/CuaDriverRs.app`; symlink-detection note updated to mention the `~/.cua-driver-rs/` marker check.
- TCC reset callout reflects the shared bundle id (`com.trycua.driver` for both Swift and current Rust) and adds a "pre-rename Rust install" block with the legacy `com.trycua.cuadriverrs` reset for users upgrading from `cua-driver-rs ≤ 0.2.3`.
No script API changes — just path/identity refresh.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Rename the Rust port's bundle identity so it matches the Swift driver's brand minus the
Rssuffix. Going forward, the Rust port IS the canonical cua-driver: installs at/Applications/CuaDriver.app, identifies ascom.trycua.cuadriver, and replaces the Swift driver's.appat the same path on install (the two don't coexist).Per Francesco's direction: "they don't have to coexist; it's either one or the other. We need to handle the fact that the user at some point will have to override the Swift cua driver with the Rust, so better start keeping them the same name."
What changes
.appbundle dirlibs/cua-driver-rs/scripts/CuaDriverRs.app/libs/cua-driver-rs/scripts/CuaDriver.app/(git-tracked rename)/Applications/CuaDriverRs.app/Applications/CuaDriver.app(replaces Swift at the same path)CFBundleIdentifiercom.trycua.cuadriverrscom.trycua.cuadriverCFBundleName/ display nameCua Driver RSCua Driveris_executable_inside_cuadriverrs_app()is_executable_inside_cuadriver_app()Swift-takeover handling
_install-rust.shnow detects whether the existing.appat the install path is the Swift driver (readsCFBundleIdentifierviaPlistBuddybeforerm -rf-ing). When the prior bundle id iscom.trycua.driver, the post-install message surfaces thetccutil resetcommands so the user can clear orphaned Swift grants — Swift's grants attributed tocom.trycua.driverbecome orphaned and unused when the Rust bundle (com.trycua.cuadriver) takes over the path. macOS will surface the Accessibility + Screen Recording dialogs for the new bundle id on first action.Files
libs/cua-driver-rs/scripts/CuaDriver.app/Contents/Info.plist— new content (bundle id, names, header doc rewritten).bundle.rs,cli.rs,proxy.rs,main.rs— string/path/function rename.libs/cua-driver/scripts/_install-rust.sh—APP_NAME, install path, post-installtccutilhint block, comments.libs/cua-driver/scripts/install.sh— comment updates only.libs/cua-driver-rs/scripts/install-local.sh— dev-loop bundle path..github/workflows/cd-rust-cua-driver.yml— macOS bundle assembly step + codesign/notarize/staple paths.docs/content/docs/cua-driver/guide/getting-started/installation.mdx— install dir + Swift-replacement note.What this does NOT do
cua-driver-rs-v*; only the inner bundle moves. Existing one-liners (cua-driver/scripts/install.sh, thecua-driver-rs/scripts/install.{sh,ps1}redirect shims) all keep working.cua-driveron PATH stays the same. Hermes and anything else calling the binary by name is unaffected.~/.cua-driver-rs/stays where it is. A futurecua-driver migrateverb can move it under~/.cua-driver/once it has somewhere safe to land.~/.cua-driver/(Swift's config),~/Library/Application Support/Cua Driver/, Swift TCC grants — all left in place. The post-install message points attccutil resetfor the orphaned grants; the user runs it manually if they want.Conflicts with #1558
The in-flight uninstall convergence PR (#1558) still references
/Applications/CuaDriverRs.app+com.trycua.cuadriverrsin_uninstall-rust.sh. After this PR lands,#1558needs a small rebase: update the install-path string + bundle id in_uninstall-rust.shto the new names, and optionally keep the oldtccutil resetlines as a legacy-cleanup branch (for users upgrading from the older bundle id who never re-ran the install).Test plan
darwin-universaltarball contains aCuaDriver.appwithcom.trycua.cuadriverbundle id (verify viaplutil -pafter unzipping the asset).curl …/libs/cua-driver/scripts/install.sh | bash -s -- --experimental-rust→/Applications/CuaDriver.applands,cua-driver --versionworks,tccutil reset Accessibility com.trycua.cuadriverthencua-driver check_permissionsfires the dialog for the new bundle id.install.ps1)..appis macOS-only).Don't auto-merge — substantial change, deserves review.
🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Documentation