Skip to content

feat(cua-driver-rs)(windows): rename install paths trycua\cua-driver-rs → Cua\cua-driver (auto-migration)#1644

Merged
f-trycua merged 1 commit into
mainfrom
feat/install-path-rename-cua-cua-driver
May 21, 2026
Merged

feat(cua-driver-rs)(windows): rename install paths trycua\cua-driver-rs → Cua\cua-driver (auto-migration)#1644
f-trycua merged 1 commit into
mainfrom
feat/install-path-rename-cua-cua-driver

Conversation

@f-trycua
Copy link
Copy Markdown
Collaborator

@f-trycua f-trycua commented May 21, 2026

Summary

User-facing install paths drop the GitHub org prefix + Rust-port suffix:

Before (v0.2.13 and earlier) After (v0.2.14+)
`%LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin` `%LOCALAPPDATA%\Programs\Cua\cua-driver\bin`
`%USERPROFILE%\.cua-driver-rs\` `%USERPROFILE%\.cua-driver\`

Rationale

  • The Rust port IS the canonical Windows driver — there's no Swift Windows binary it's coexisting with anymore. The `-rs` suffix was the disambiguator while the Swift driver still shipped Windows binaries; it doesn't anymore.
  • `trycua\` is the GitHub org prefix that doesn't belong in `%LOCALAPPDATA%\Programs` — vendor folders there are conventionally PascalCase company names (Microsoft\, Google\, NVIDIA\, …). `Cua\` matches that convention.

Auto-migration

`install.ps1` detects the v0.2.13-and-earlier layout (when default paths are in use, i.e. no `CUA_DRIVER_RS_INSTALL_DIR` / `CUA_DRIVER_RS_HOME` override) and migrates transparently before installing the new layout. Steps mirror uninstall.ps1's cleanup: stop daemon → unregister task → remove legacy junctions + empty parent dirs → remove legacy package home → prune legacy PATH entry.

`uninstall.ps1` always sweeps both layouts so a single `irm uninstall.ps1 | iex` leaves nothing behind.

What's preserved

  • Env var names (`CUA_DRIVER_RS_INSTALL_DIR`, `CUA_DRIVER_RS_HOME`) — changing them silently would break existing automation.
  • Crate names (`cua-driver`, `cua-driver-rs`), release tag prefix (`cua-driver-rs-v0.2.x`), CD asset filenames, binary name (`cua-driver.exe`), Scheduled Task name (`cua-driver-serve`), named pipe (`\\.\pipe\cua-driver`).

Compat table

Scenario Outcome
Fresh v0.2.14 install New paths only
v0.2.13 → v0.2.14 via `irm install.ps1 | iex` Auto-migration; one shot
User with `CUA_DRIVER_RS_INSTALL_DIR`/`_HOME` set Override wins; legacy migration skipped (don't surprise users)
User runs new `uninstall.ps1` on a legacy-only install Both layouts cleaned up

Test plan

  • install.ps1 parses cleanly on PS 5.1
  • Fresh install on cuademo (no legacy) → installs at new path, autostart works
  • v0.2.13 → v0.2.14 upgrade on cuademo with legacy install present → migration log shows legacy paths removed, new paths installed, only one PATH entry post-upgrade
  • uninstall.ps1 after legacy-only install → both old and new paths handled

Out of scope (follow-ups)

  • Linux `.cua-driver-rs` → `.cua-driver` (install.sh, uninstall.sh) — separate PR, same rationale, no `Cua\` vendor-dir question on Linux
  • macOS LaunchAgent label `com.trycua.cua-driver-rs` — keeping as-is (it's the service identity, renaming would orphan existing installs without a benefit)
  • `cua-driver skills` skill pack name (`cua-driver-rs` constant in skills.rs) — separate PR if we want to rename .claude/skills/cua-driver-rs → cua-driver
  • Internal Rust crate names (`cua-driver-rs`) — would touch CD workflow + cargo registry, big blast radius for no user-facing gain

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Automatic migration from v0.2.13 and earlier installations to the new directory structure, including cleanup of legacy paths
    • Enhanced installer detects and migrates existing legacy installations
  • Documentation

    • Updated Windows installation guide with new directory paths and layout information
    • Updated uninstall documentation to reflect current directory structure
    • Added migration notes for users upgrading from v0.2.13 and earlier

Review Change Stack

…rs → Cua\cua-driver, with auto-migration

User-facing install paths drop the GitHub org prefix + Rust-port suffix:

  %LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin  →  Cua\cua-driver\bin
  %USERPROFILE%\.cua-driver-rs\                     →  .cua-driver\

Rationale:
- The Rust port IS the canonical Windows driver — there's no Swift
  Windows binary it's coexisting with anymore. The `-rs` suffix was
  the disambiguator while the Swift driver still shipped Windows
  binaries; it doesn't anymore, so the suffix is dead weight.
- `trycua` is the GitHub org prefix that doesn't belong in
  %LOCALAPPDATA%\Programs — vendor folders there are conventionally
  PascalCase company names (Microsoft\, Google\, NVIDIA\, ...).
  `Cua\` matches that convention.

## Auto-migration

install.ps1 detects the v0.2.13-and-earlier layout (when default paths
are in use, i.e. no $env:CUA_DRIVER_RS_INSTALL_DIR or
$env:CUA_DRIVER_RS_HOME override) and migrates transparently before
laying down the new install:

  1. Stop any cua-driver / cua-driver-uia daemon pinning legacy binary
     files open.
  2. Unregister the cua-driver-serve Scheduled Task (idempotent; uses
     the same defensive $ErrorActionPreference handling as
     uninstall.ps1's #1633 fix).
  3. Remove the legacy visible bin junction + empty parent dirs
     (cua-driver-rs\ and trycua\ when the latter is empty after the
     pass — vendor dir is preserved if other apps live under it).
  4. Remove the legacy package home tree (.cua-driver-rs\).
  5. Prune the legacy bin path from User PATH (the new install adds
     the new path; without pruning we'd accumulate stale PATH entries
     on every upgrade).

uninstall.ps1 always sweeps legacy paths too, so a single
`irm uninstall.ps1 | iex` leaves nothing behind even when run AFTER
the user has already upgraded to the new layout.

## Env var names unchanged

$env:CUA_DRIVER_RS_INSTALL_DIR and $env:CUA_DRIVER_RS_HOME keep the
`_RS_` infix even though the underlying paths are renamed. Changing
env var names silently would break existing automation (CI, devx
scripts, dotfiles) that pins a custom install dir.

## Compat

- v0.2.13 → v0.2.14 upgrade via `irm install.ps1 | iex`: transparent
  one-shot migration.
- Fresh v0.2.14 install: new paths only, no legacy detection needed.
- User with $env:CUA_DRIVER_RS_INSTALL_DIR or _HOME set: their
  override wins; legacy migration skipped to avoid surprising them.
- Crate names (cua-driver, cua-driver-rs), release tag prefix
  (cua-driver-rs-v0.2.x), CD asset filenames, binary names
  (cua-driver.exe), Scheduled Task name (cua-driver-serve), and named
  pipe (\\.\pipe\cua-driver) are all unchanged — only the user-facing
  install paths move.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment May 21, 2026 6:38pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

This PR migrates the Windows cua-driver installation layout from the legacy trycua\cua-driver-rs paths to a new Programs\Cua\cua-driver structure. The install script now auto-detects and removes legacy installations, while both install and uninstall scripts recognize and handle legacy paths to ensure smooth user transitions.

Changes

Windows Install/Uninstall Layout Migration

Layer / File(s) Summary
Documentation of new Windows install layout
docs/content/docs/cua-driver/guide/getting-started/installation.mdx
Updated PowerShell 5.1 workaround paths, User-scope PATH directory reference, and Windows versioned-dirs layout diagram to reflect the new %LOCALAPPDATA%\Programs\Cua\cua-driver\bin structure. Added migration note indicating v0.2.13 and earlier used legacy trycua\cua-driver-rs and .cua-driver-rs paths.
Install script path setup and legacy migration
libs/cua-driver/scripts/install.ps1
Changed path defaults from legacy trycua\cua-driver-rs to Programs\Cua\cua-driver for install and .cua-driver for home. Added explicit legacy path variables and introduced Remove-LegacyInstall function that detects legacy installs, stops daemons, removes junctions/directories safely, prunes legacy PATH entries, and cleans legacy home tree before proceeding with main installation.
Uninstall script legacy cleanup and new layout support
libs/cua-driver/scripts/uninstall.ps1
Updated path defaults to new layout and added legacy path variables for v0.2.13 and earlier. Inserted new "Legacy install layout" uninstall step (step 6) to remove legacy bin junctions, prune empty legacy parent/vendor directories, and delete legacy package home. Updated closing instructions to reference both new and legacy locations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • trycua/cua#1556: Both PRs involve the Windows installer script install.ps1feat(install): converge to one canonical .sh + .ps1 entry point per platform #1556 shifts the entrypoint/shim and CI URLs, while this PR changes the script's default install/junction layout and adds legacy-migration cleanup logic.
  • trycua/cua#1576: Both PRs modify install.ps1 to manage User PATH entries for the cua-driver bin directory—this PR switches to the new layout and removes legacy PATH entries via legacy cleanup, while #1576 adds auto-adding the bin dir to PATH with opt-out.
  • trycua/cua#1540: Both PRs implement the same Windows install layout migration pattern in their respective install.ps1 and uninstall.ps1, migrating to the %LOCALAPPDATA%\Programs\Cua\cua-driver\bin junction-based layout with legacy cleanup support.

Poem

A bunny hops through Windows paths with glee,
Old trycua roads now Programs\Cua decree,
Legacy junctions swept with care so fine,
The installer hops forth on the new design! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and specifically describes the main change: renaming Windows install paths from trycua\cua-driver-rs to Cua\cua-driver with auto-migration support, which aligns with all file changes in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/install-path-rename-cua-cua-driver

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/content/docs/cua-driver/guide/getting-started/installation.mdx (2)

230-230: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Lockfile example path references legacy location.

The PowerShell example shows the old .cua-driver-rs path for the lockfile, but the new home directory is .cua-driver.

Proposed fix
-Get-Content $env:USERPROFILE\.cua-driver-rs\install.lock
+Get-Content $env:USERPROFILE\.cua-driver\install.lock
🤖 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` at line
230, Update the PowerShell example that references the legacy lockfile path by
replacing the ".cua-driver-rs" folder with the new ".cua-driver" folder;
specifically modify the line containing the command string "Get-Content
$env:USERPROFILE\.cua-driver-rs\install.lock" so it points to
"$env:USERPROFILE\.cua-driver\install.lock" (ensure only the folder name changes
and keep the rest of the example intact).

176-178: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Env-var defaults table still references legacy paths.

The table shows old defaults (trycua\cua-driver-rs\bin and .cua-driver-rs) while the rest of the document has been updated to the new paths (Cua\cua-driver\bin and .cua-driver). This will confuse users.

Proposed fix
-| `CUA_DRIVER_RS_INSTALL_DIR` | `~/.local/bin` | `%LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin` | The visible PATH-entry directory. On Windows this is itself a junction. |
-| `CUA_DRIVER_RS_HOME` | `~/.cua-driver-rs` | `%USERPROFILE%\.cua-driver-rs` | Package home — holds `packages/releases/<v>/` and `packages/current`. |
+| `CUA_DRIVER_RS_INSTALL_DIR` | `~/.local/bin` | `%LOCALAPPDATA%\Programs\Cua\cua-driver\bin` | The visible PATH-entry directory. On Windows this is itself a junction. |
+| `CUA_DRIVER_RS_HOME` | `~/.cua-driver-rs` | `%USERPROFILE%\.cua-driver` | Package home — holds `packages/releases/<v>/` and `packages/current`. |
🤖 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 176 - 178, Update the env-var defaults table to match the new path
conventions: replace legacy Windows path
`%LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin` with
`%LOCALAPPDATA%\Programs\Cua\cua-driver\bin` and replace the package home
`~/.cua-driver-rs` / `%USERPROFILE%\.cua-driver-rs` with `~/.cua-driver` /
`%USERPROFILE%\.cua-driver` for the CUA_DRIVER_RS_INSTALL_DIR and
CUA_DRIVER_RS_HOME rows respectively; keep the CUA_DRIVER_RS_NO_MODIFY_PATH row
text unchanged except where it echoes the same path string so those references
also use the new `Cua\cua-driver\bin` and `.cua-driver` values.
🤖 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/scripts/install.ps1`:
- Around line 919-931: Remove-LegacyInstall currently deletes
$LegacyVisibleBinDir even when it is a real directory; mirror the safety in
Ensure-Junction by checking the item's reparse status first (use Get-Item to set
$item and compute $isReparse as in the diff), and only delete when $isReparse is
true (junction) — otherwise skip removal, write a warning/notice (e.g., via
Write-Host) that a non-junction directory was left intact, and avoid Remove-Item
on non-reparse directories to prevent accidental user data deletion; update the
logic inside Remove-LegacyInstall around $LegacyVisibleBinDir to perform this
check and early-return or continue accordingly.

In `@libs/cua-driver/scripts/uninstall.ps1`:
- Around line 280-288: The cleanup for $LegacyVisibleBinDir currently removes
the path regardless of type; change the block around Test-IsReparsePoint and
Remove-Item so it mirrors the logic used for $VisibleBinDir: call
Test-IsReparsePoint $LegacyVisibleBinDir and only Remove-Item when it returns
true (treat as a junction), otherwise skip removal and call Write-Step (or a
warning) indicating the path was not a reparse point and was left intact; keep
the existing messages (use "removed legacy junction $LegacyVisibleBinDir" on
success and a clear "skipped non-junction legacy path $LegacyVisibleBinDir"
message when not a reparse point), leaving Test-IsReparsePoint, Remove-Item, and
Write-Step as the referenced symbols.

---

Outside diff comments:
In `@docs/content/docs/cua-driver/guide/getting-started/installation.mdx`:
- Line 230: Update the PowerShell example that references the legacy lockfile
path by replacing the ".cua-driver-rs" folder with the new ".cua-driver" folder;
specifically modify the line containing the command string "Get-Content
$env:USERPROFILE\.cua-driver-rs\install.lock" so it points to
"$env:USERPROFILE\.cua-driver\install.lock" (ensure only the folder name changes
and keep the rest of the example intact).
- Around line 176-178: Update the env-var defaults table to match the new path
conventions: replace legacy Windows path
`%LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin` with
`%LOCALAPPDATA%\Programs\Cua\cua-driver\bin` and replace the package home
`~/.cua-driver-rs` / `%USERPROFILE%\.cua-driver-rs` with `~/.cua-driver` /
`%USERPROFILE%\.cua-driver` for the CUA_DRIVER_RS_INSTALL_DIR and
CUA_DRIVER_RS_HOME rows respectively; keep the CUA_DRIVER_RS_NO_MODIFY_PATH row
text unchanged except where it echoes the same path string so those references
also use the new `Cua\cua-driver\bin` and `.cua-driver` values.
🪄 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: 316918ac-1b23-4e3f-951b-97352793aba0

📥 Commits

Reviewing files that changed from the base of the PR and between b3d1930 and 06e0106.

📒 Files selected for processing (3)
  • docs/content/docs/cua-driver/guide/getting-started/installation.mdx
  • libs/cua-driver/scripts/install.ps1
  • libs/cua-driver/scripts/uninstall.ps1

Comment on lines +919 to +931
if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
try {
$item = Get-Item -LiteralPath $LegacyVisibleBinDir -Force -ErrorAction Stop
$isReparse = ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0
if ($isReparse) {
# NTFS junction — delete the link, not the target.
[System.IO.Directory]::Delete($LegacyVisibleBinDir, $false)
} else {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Recurse -Force -ErrorAction SilentlyContinue
}
} catch {
Write-Host " (could not remove $LegacyVisibleBinDir : $($_.Exception.Message))" -ForegroundColor Yellow
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Legacy cleanup removes non-junction directories, unlike main install logic.

The Ensure-Junction function (lines 500-505) explicitly refuses to replace an existing non-junction directory at the bin path. However, Remove-LegacyInstall will remove $LegacyVisibleBinDir even if it's a real directory (line 927). This inconsistency could delete user data if someone manually created a directory at the legacy path.

Consider aligning with the safety check in Ensure-Junction:

Proposed fix - skip non-junction directories
     if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
         try {
             $item = Get-Item -LiteralPath $LegacyVisibleBinDir -Force -ErrorAction Stop
             $isReparse = ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0
             if ($isReparse) {
                 # NTFS junction — delete the link, not the target.
                 [System.IO.Directory]::Delete($LegacyVisibleBinDir, $false)
             } else {
-                Remove-Item -LiteralPath $LegacyVisibleBinDir -Recurse -Force -ErrorAction SilentlyContinue
+                Write-Host "  (legacy $LegacyVisibleBinDir is not a junction — skipping to preserve user data)" -ForegroundColor Yellow
             }
         } catch {
             Write-Host "  (could not remove $LegacyVisibleBinDir : $($_.Exception.Message))" -ForegroundColor Yellow
         }
     }
📝 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.

Suggested change
if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
try {
$item = Get-Item -LiteralPath $LegacyVisibleBinDir -Force -ErrorAction Stop
$isReparse = ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0
if ($isReparse) {
# NTFS junction — delete the link, not the target.
[System.IO.Directory]::Delete($LegacyVisibleBinDir, $false)
} else {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Recurse -Force -ErrorAction SilentlyContinue
}
} catch {
Write-Host " (could not remove $LegacyVisibleBinDir : $($_.Exception.Message))" -ForegroundColor Yellow
}
if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
try {
$item = Get-Item -LiteralPath $LegacyVisibleBinDir -Force -ErrorAction Stop
$isReparse = ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0
if ($isReparse) {
# NTFS junction — delete the link, not the target.
[System.IO.Directory]::Delete($LegacyVisibleBinDir, $false)
} else {
Write-Host " (legacy $LegacyVisibleBinDir is not a junction — skipping to preserve user data)" -ForegroundColor Yellow
}
} catch {
Write-Host " (could not remove $LegacyVisibleBinDir : $($_.Exception.Message))" -ForegroundColor Yellow
}
}
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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.ps1` around lines 919 - 931,
Remove-LegacyInstall currently deletes $LegacyVisibleBinDir even when it is a
real directory; mirror the safety in Ensure-Junction by checking the item's
reparse status first (use Get-Item to set $item and compute $isReparse as in the
diff), and only delete when $isReparse is true (junction) — otherwise skip
removal, write a warning/notice (e.g., via Write-Host) that a non-junction
directory was left intact, and avoid Remove-Item on non-reparse directories to
prevent accidental user data deletion; update the logic inside
Remove-LegacyInstall around $LegacyVisibleBinDir to perform this check and
early-return or continue accordingly.

Comment on lines +280 to +288
if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
if (Test-IsReparsePoint $LegacyVisibleBinDir) {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
Write-Step "removed legacy junction $LegacyVisibleBinDir"
} else {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
Write-Step "removed legacy directory $LegacyVisibleBinDir"
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Legacy cleanup removes non-junction directories without the safety check applied to main paths.

Step 3 (lines 233-236) refuses to remove $VisibleBinDir if it's not a reparse point, but step 6 removes $LegacyVisibleBinDir regardless of whether it's a junction. For consistency and safety, consider applying the same protection:

Proposed fix - align with step 3's safety check
 if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
     if (Test-IsReparsePoint $LegacyVisibleBinDir) {
         Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
         Write-Step "removed legacy junction $LegacyVisibleBinDir"
     } else {
-        Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
-        Write-Step "removed legacy directory $LegacyVisibleBinDir"
+        Write-WarningStep "$LegacyVisibleBinDir exists but is not a reparse point — skipping."
+        Write-WarningStep "  install.ps1 only creates junctions at this path, so this may be a hand-managed directory."
     }
 }
📝 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.

Suggested change
if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
if (Test-IsReparsePoint $LegacyVisibleBinDir) {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
Write-Step "removed legacy junction $LegacyVisibleBinDir"
} else {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
Write-Step "removed legacy directory $LegacyVisibleBinDir"
}
}
if (Test-Path -LiteralPath $LegacyVisibleBinDir) {
if (Test-IsReparsePoint $LegacyVisibleBinDir) {
Remove-Item -LiteralPath $LegacyVisibleBinDir -Force -Recurse -ErrorAction SilentlyContinue
Write-Step "removed legacy junction $LegacyVisibleBinDir"
} else {
Write-WarningStep "$LegacyVisibleBinDir exists but is not a reparse point — skipping."
Write-WarningStep " install.ps1 only creates junctions at this path, so this may be a hand-managed directory."
}
}
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'uninstall.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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/uninstall.ps1` around lines 280 - 288, The cleanup
for $LegacyVisibleBinDir currently removes the path regardless of type; change
the block around Test-IsReparsePoint and Remove-Item so it mirrors the logic
used for $VisibleBinDir: call Test-IsReparsePoint $LegacyVisibleBinDir and only
Remove-Item when it returns true (treat as a junction), otherwise skip removal
and call Write-Step (or a warning) indicating the path was not a reparse point
and was left intact; keep the existing messages (use "removed legacy junction
$LegacyVisibleBinDir" on success and a clear "skipped non-junction legacy path
$LegacyVisibleBinDir" message when not a reparse point), leaving
Test-IsReparsePoint, Remove-Item, and Write-Step as the referenced symbols.

@f-trycua f-trycua merged commit d9e8f86 into main May 21, 2026
7 of 9 checks passed
@f-trycua f-trycua deleted the feat/install-path-rename-cua-cua-driver branch May 21, 2026 18:49
f-trycua added a commit that referenced this pull request May 21, 2026
…driver (PR #1644 completion) (#1650)

PR #1644's path rename (Programs\trycua\cua-driver-rs → Programs\Cua\cua-driver
and ~/.cua-driver-rs → ~/.cua-driver) only updated the install scripts.
The Rust binary's telemetry module hardcodes ~/.cua-driver-rs/ for its
.telemetry_id + .installation_recorded files, so every daemon run
recreated the legacy directory in the user's home regardless of the new
install path.

Discovered during cuademo SSH dogfood of v0.2.15: cleanup script removed
the legacy `.cua-driver-rs/` four times; every spin of `cua-driver serve`
brought it back with `.telemetry_id` + `.installation_recorded` files
timestamped at runtime.

## Changes

- `crates/cua-driver/src/telemetry.rs::HOME_SUBDIRECTORY`: `.cua-driver-rs`
  → `.cua-driver`. Doc comment updated to note the rename + describe the
  one-shot migration of legacy telemetry files.
- New `migrate_legacy_telemetry_home()` runs once per process at the
  start of `load_or_create_install_id_uncached`. Best-effort move of
  `.telemetry_id` + `.installation_recorded` from `.cua-driver-rs/` to
  `.cua-driver/` (preserving the per-install UUID so analytics survive
  the rename), then `remove_dir` on the legacy directory if empty.
- `crates/cua-driver/src/doctor.rs::probe_home_dir` + `probe_telemetry`:
  same `.cua-driver-rs` → `.cua-driver` rename so `cua-driver doctor`
  reports the canonical path.

## Verification

cuademo SSH session, v0.2.15 installed at new paths but with telemetry
still writing legacy:

  Before this fix:
    Remove-Item .cua-driver-rs; spin daemon; check
    → .cua-driver-rs/.telemetry_id recreated every time

  After this fix (v0.2.16):
    Remove-Item .cua-driver-rs; spin daemon; check
    → .cua-driver/.telemetry_id created; .cua-driver-rs not recreated

Existing users with a v0.2.15-or-earlier `.cua-driver-rs/` get a
transparent migration on first v0.2.16 launch: the telemetry UUID and
install-recorded marker move to `.cua-driver/`, then `.cua-driver-rs/`
removes itself.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant