Skip to content

fix(windows): Session-0 hardening + UWP background-launch focus restore - #1548

Merged
f-trycua merged 14 commits into
mainfrom
stab/windows-session0-fixes
May 18, 2026
Merged

fix(windows): Session-0 hardening + UWP background-launch focus restore#1548
f-trycua merged 14 commits into
mainfrom
stab/windows-session0-fixes

Conversation

@f-trycua

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

Copy link
Copy Markdown
Collaborator

Summary

Stabilizes cua-driver-rs for Windows non-interactive (Session 0) contexts and hardens the UWP background-launch focus invariant.

  • cua-driver doctor no longer crashes with 0xC0000005 ACCESS_VIOLATION (COM lifecycle fix in ui_automation_available).
  • launch_app no longer hangs in Session 0 — name-based UWP routing falls through to ShellExecuteEx, aumid-based routing fails fast with a descriptive error.
  • UWP foreground-restore upgrade: snapshots GetForegroundWindow before activation and re-asserts it after, using a keybd_event(VK_NONAME) injection to claim "owner of last input" and bypass Windows' SetForegroundWindow restriction.
  • cua-driver serve prints a Session-0 warning banner at startup on Windows.
  • list_apps filters opaque-system-family UWP packages (GUID-prefixed / Windows.Internal.*) whose DisplayName resolved to their FamilyName.
  • 3 parity examples (list_apps_parity, list_windows_parity, launch_app_parity) updated for Session-0 awareness + the unified feat(list_apps): unify running + installed apps across platforms #1545 list_apps shape.
  • FAQ + PARITY.md docs updated with Session-0 troubleshooting.

Validated live on a Win11 24H2 Azure VM in Session 0: 11/11 parity examples pass (was 6/11 before — the rest were stale assertions / expected-failure Session-0 noise).

Full status + dev-loop reference live in WINDOWS_SESSION0_STATUS.md and libs/cua-driver-rs/DEV_LOOP_WINDOWS_VM.md.

Test plan

  • cua-driver doctor exits 0 with all probes reporting in Session 0
  • cua-driver call list_apps returns ~133 apps cold in ~370ms, sub-100ms warm
  • cua-driver call launch_app {"name":"notepad"} returns pid (ShellExecuteEx path)
  • cua-driver call launch_app {"aumid":"...!App"} fails fast in Session 0 (no hang)
  • All 11 Session-0-compatible parity examples pass
  • Unit tests for looks_like_opaque_system_family pass (4/4)
  • Visual: UWP background-launch on Session 1+ via RDP — does NOT steal focus from prior foreground app

Summary by CodeRabbit

  • New Features

    • Added Session 0 startup warning banner for non-interactive environments.
  • Bug Fixes

    • Fixed COM lifecycle crash in diagnostics.
    • Prevented Session 0 hang when launching applications.
    • Enhanced UWP focus-restoration hardening.
    • Improved system package filtering in app listings.
  • Documentation

    • Added Windows Session 0 stabilization status report.
    • Added FAQ entries for Session 0 behavior and limitations.
    • Added Windows VM development workflow guide.
    • Updated parity verification documentation.

Review Change Stack

f-trycua added 10 commits May 18, 2026 02:23
…aths

Three fixes for Windows correctness in non-interactive sessions:

1) **doctor segfault (0xC0000005 ACCESS_VIOLATION).** The
   `ui_automation_available` probe was calling `CoUninitialize` while the
   `probe` binding still held the IUIAutomation interface. When the
   binding dropped at function return, `IUnknown::Release` ran against a
   torn-down apartment and segfaulted. Fix: flatten the probe result into
   a plain `Result<(), String>` first so the IUIAutomation drops before
   we tear down the apartment.

2) **launch_app hang in Session 0 via name-based UWP lookup.**
   `resolve_aumid_by_name` walked `shell:AppsFolder` via the interactive
   shell broker, which doesn't exist in services/SSH contexts and hangs
   the COM call forever. Detect Session 0 and short-circuit to None so
   the caller falls through to ShellExecuteEx's PATH lookup (which works
   in Session 0 for any app reachable via PATH).

3) **launch_uwp hang in Session 0 via explicit aumid.**
   `IApplicationActivationManager::ActivateApplication` needs the
   per-user AppX runtime which doesn't exist in Session 0. Same
   short-circuit: fail fast with a clear error pointing the caller at
   the workaround (interactive logon / scheduled task in user session).

Also adds best-effort foreground-window restoration after UWP
activation — the AppX runtime's default activation brings the spawned
app to foreground (same as a Start Menu click), which violates
cua-driver's "background launch, never steal focus" invariant. We
snapshot `GetForegroundWindow` before the call and re-assert it after
in a short retry loop. Best-effort because SetForegroundWindow is
subject to Windows' foreground-lock restrictions; visual confirmation
needs a Session 1+ run.

Plus: replace eprintln traces in list_apps / installed_apps with
tracing::debug (silent by default, enable via `RUST_LOG=...=debug`).

Verified on Windows VM (Session 0):
- doctor: exit 0, all probes report
- list_apps cold: 3.7s, returns 134 apps
- launch_app {"name":"notepad"}: pid returned, ShellExecuteEx path
- launch_app {"aumid":"..."}: fail-fast with Session-0 explanation,
  no hang
- list_apps_parity: assert the unified #1545 contract (mixed running +
  installed, new fields kind/launch_path/last_used/windows, pid==0 for
  installed-not-running). Skip the active-app assertion in Session 0.
  Bump response timeout 4s -> 8s to absorb WinRT cold-enumeration.
- list_windows_parity: skip non-empty-windows assertion in Session 0
  (EnumWindows is correctly empty there — no attached desktop).
- launch_app_parity: accept Session-0 error from UWP/aumid path the
  same way it accepts "not installed" — both are valid skip signals.
- overlay_dump.rs: fix PrintWindow + PRINT_WINDOW_FLAGS import (moved
  to Win32::Storage::Xps in windows-rs 0.58, was failing to compile).

Verified in Session 0 on Windows VM. Pass rate: 11/11 of the tests
that don't require a foreground window owner (the remaining ones
naturally require Session 1+ to exercise meaningfully).
Mirrors the warning `cua-driver doctor` already surfaces for the same
condition. When the daemon starts inside Session 0 (services /
SSH-launched processes), every window-driving tool — click, type_text,
screenshot, get_window_state, list_windows, and UWP launches — will
fail or return empty. Surfacing this at daemon startup saves users
hours of debugging tools that are working as designed.

Quiet in Session 1+ (the normal interactive logon case).
…evidence

list_apps: bump windows status from 'VERIFIED for Win32 path, live-run
pending' to 'VERIFIED live' with the actual measurements from the
Win11 24H2 VM run (~370ms cold for 150 apps, sub-100ms warm).

launch_app: distinguish the Win32 path (fully verified, SW_SHOWNOACTIVATE
+ no focus steal) from the UWP path (requires interactive session — now
fast-fails in Session 0 instead of hanging; foreground-restore is
best-effort due to Windows' foreground-lock restrictions and needs
visual confirmation from a Session 1+ run).
…ist_apps

These are packages whose Package.DisplayName is empty / unresolved
ms-resource: token AND have no Properties/DisplayName in their
AppxManifest.xml, so they fall through #1547's normalize cascade and
end up reporting their FamilyName as the user-facing name. On a stock
Win11 image that's ~10-30 entries like:

  - 1527c705-839a-4832-9118-54d4Bd6a0c89_cw5n1h2txyewy
  - F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE_cw5n1h2txyewy
  - Windows.Internal.ShellExperience_cw5n1h2txyewy

They're noise in list_apps output: agents can't usefully launch them
(typically unactivatable system Components) and they crowd out real
installed apps. Filter them out when:

  display_name == family_name
    AND (family looks GUID-prefixed OR starts with Windows.Internal)

Real user-facing apps survive: Microsoft.WindowsNotepad_..., Spotify...,
.MicrosoftEdge.Stable_..., etc.

Also filter out Package.IsFramework() = true entries — those are
shared libraries (.NET, Visual C++ runtime, language packs) that
list_apps callers should never see in the list of launchable apps.

Plus: unit tests for the family-name classifier + a dev-loop
reference doc (DEV_LOOP_WINDOWS_VM.md) capturing all the PowerShell
gotchas the autonomous session hit + a session status report
(WINDOWS_SESSION0_STATUS.md) documenting what was fixed, what needs
visual confirmation, and the one-liner to bring the local fixes into
a PR when ready.
…ion 0

The IsFramework() WinRT call observed to hang indefinitely (~0 CPU,
no progress) when scan_uwp_packages runs in Session 0 / services
context. Removing it; the opaque-family-name filter below still
catches most of the entries this would have removed (Visual C++
runtime, .NET shared, language packs all tend to have ms-resource:
display names that normalize to family names).

Unit tests pass in either case because they exercise the pure-string
classifier, not the WinRT path.
Windows restricts SetForegroundWindow to processes that meet specific
conditions; the daemon meets none of them when launch_app is invoked
via MCP from a backgrounded UI. Without a workaround the
foreground-restore added previously was almost always silently
dropped, leaving the freshly-activated UWP app stealing focus from
whatever the human was doing.

Inject a single keybd_event of VK_NONAME (0xFC, reserved no-name
virtual key) just before the restore loop — that's enough to give us
"owner of last input" status, one of the conditions that lifts the
foreground lock. VK_NONAME doesn't map to any UI action so no app
sees a keystroke.

The Session-0 short-circuit higher up bypasses this entire path, so
this code only executes on interactive logons where focus matters in
the first place. Visual confirmation needs a Session 1+ run.
All 7 commits accounted for, including the keybd_event upgrade to
the UWP foreground-restore (much stronger than the initial best-effort
because it claims 'owner of last input' before SetForegroundWindow,
lifting Windows' foreground-lock restriction in practice).

Also documents the IsFramework hang as a found-and-fixed surprise so
future debug sessions know to avoid that WinRT call in Session 0.
Two new entries under a new 'Windows (cua-driver-rs)' section:
- Why click/type_text/screenshot/list_windows return empty (Session-0
  detection + doctor surfacing) — explains the WindowStation+Desktop
  scoping that catches users debugging non-bugs.
- Why launch_app of a UWP app fails fast in Session-0 — points at the
  Win32 fallback path that works in services context.

Mirrors the in-binary doctor warning and serve startup banner so the
docs and the runtime tell the same story.
@vercel

vercel Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview May 18, 2026 7:24am

Request Review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15f67bfb-043c-4295-afb0-5be4b36b52da

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR stabilizes Windows Session 0 (non-interactive/service) support in cua-driver-rs. A new status report documents 11 parity tests now passing, two fixed edge-case bugs (doctor COM crash, launch_app hang), and additional hardening. Changes span daemon startup warnings, UWP launch Session 0 fast-fail with focus restoration, COM lifecycle safety, opaque UWP app filtering, and Session 0-aware parity test assertions.

Changes

Windows Session 0 Stabilization

Layer / File(s) Summary
Status report and user-facing documentation
WINDOWS_SESSION0_STATUS.md, docs/content/docs/cua-driver/guide/getting-started/faq.mdx, libs/cua-driver-rs/DEV_LOOP_WINDOWS_VM.md, libs/cua-driver-rs/PARITY.md
New Session 0 stabilization status report with parity results, bug fixes, validation outputs, known issues, and carry-forward instructions. FAQ, dev loop guide, and parity audit updated to reflect Session 0 behavior and Windows verification status.
Daemon startup Session 0 detection and warning banner
libs/cua-driver-rs/crates/cua-driver/src/serve.rs
run_serve_cmd now emits a Windows-only startup banner when running in Session 0, warning users that GUI/window-driving tools will fail and directing them to re-launch in an interactive session.
UWP launch Session 0 guard and focus restoration
libs/cua-driver-rs/crates/platform-windows/src/launch_uwp.rs
launch_uwp fails fast in Session 0 instead of hanging on COM activation. Foreground window is captured before activation and restored post-activation via retry logic with synthetic keypress injection to work around Windows foreground-lock restrictions. resolve_aumid_by_name also short-circuits in Session 0 to force PATH-based Win32 fallback.
COM object lifecycle safety in diagnostics
libs/cua-driver-rs/crates/platform-windows/src/diagnostics.rs
ui_automation_available() refactored to drop the IUIAutomation COM interface before calling CoUninitialize, preventing use-after-free crashes. COM lifecycle invariant documented.
UWP opaque system filtering, timing instrumentation, and app enumeration cleanup
libs/cua-driver-rs/crates/platform-windows/src/win32/installed_apps.rs, libs/cua-driver-rs/crates/platform-windows/src/tools/impl_.rs
list_installed_apps measures and logs per-scan timing. UWP enumeration filters out opaque system packages via new looks_like_opaque_system_family helper (detecting Windows.Internal.* patterns and GUID-shaped family names). list_apps background enumeration adds per-step timing instrumentation. Unit tests validate opaque filtering.
Parity test adaptations for Session 0 constraints
libs/cua-driver-rs/crates/platform-windows/examples/launch_app_parity.rs, libs/cua-driver-rs/crates/platform-windows/examples/list_apps_parity.rs, libs/cua-driver-rs/crates/platform-windows/examples/list_windows_parity.rs, libs/cua-driver-rs/crates/platform-windows/examples/overlay_dump.rs
Parity tests now handle Session 0 constraints: launch_app_parity accepts Session 0 activation errors as skip reasons; list_apps_parity validates unified #1545 contract with conditional active-app assertion in Session 0; list_windows_parity conditionally skips non-empty windows assertion in Session 0; overlay_dump import fixed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • trycua/cua#1547: Both PRs modify libs/cua-driver-rs/crates/platform-windows/src/win32/installed_apps.rs's UWP/app enumeration logic—main PR adds opaque-system filtering and timing instrumentation, while PR #1547 changes sorting and AppxManifest-based DisplayName/launch_path parsing.
  • trycua/cua#1544: Both PRs address Windows UWP/packaged launch_app—PR #1544 introduces launch_uwp and packaged-app routing, while main PR further hardens Session 0 behavior and AUMID resolution in launch_uwp.rs.
  • trycua/cua#1545: Main PR extends Windows list_apps implementation (Session 0 behavior assertions, timing in tools/impl_.rs, UWP filtering) and updates parity docs/examples for the unified list_apps schema introduced by PR #1545.

Suggested labels

codex

Poem

🐰 Session Zero now sleeps peacefully,
No hangs, no crashes—the daemon runs free,
UWP launches fast when the screen isn't there,
COM cleanup precise, with foreground care.

🚥 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 title accurately summarizes the main changes: Session-0 hardening and UWP focus restoration for Windows, which are the primary technical objectives of the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 stab/windows-session0-fixes

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 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/DEV_LOOP_WINDOWS_VM.md`:
- Around line 10-18: Replace all machine-specific access details in
DEV_LOOP_WINDOWS_VM.md (notably the SSH block containing "ssh -i
~/.ssh/cua_winvm fbonacci@20.115.29.195", the RDP path "open
/Users/francesco/Desktop/fbonacci-windows-vm.rdp", and the credential line
"fbonacci + password from password manager") with redacted placeholders and
generic examples (e.g. <SSH_KEY_PATH>, <USERNAME>, <HOST_IP>, <RDP_FILE_PATH>,
and a note to retrieve passwords from your password manager) across the
indicated sections (including ranges around lines 26-37 and 116-132) so the
runbook contains no concrete host, account or local path information.

In `@WINDOWS_SESSION0_STATUS.md`:
- Around line 12-35: The markdown file WINDOWS_SESSION0_STATUS.md contains
host/user-specific details (e.g., branch name mention
`stab/windows-session0-fixes` with a concrete VM name/IP `fbonacci-windows-vm`
and local paths like `/Users/francesco/cua`)—replace all concrete VM
hostnames/IPs, local usernames, and absolute filesystem paths with neutral
placeholders such as <vm-host>, <vm-ip>, <user>, and <repo-root>, and remove or
generalize workstation-specific dev-loop commands and references so the document
contains no sensitive or environment-specific identifiers while preserving the
instructions and examples.
🪄 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: 5070975a-d3d7-4014-8d6a-011cd4c67079

📥 Commits

Reviewing files that changed from the base of the PR and between 69a9dbd and f2adb89.

📒 Files selected for processing (13)
  • WINDOWS_SESSION0_STATUS.md
  • docs/content/docs/cua-driver/guide/getting-started/faq.mdx
  • libs/cua-driver-rs/DEV_LOOP_WINDOWS_VM.md
  • libs/cua-driver-rs/PARITY.md
  • libs/cua-driver-rs/crates/cua-driver/src/serve.rs
  • libs/cua-driver-rs/crates/platform-windows/examples/launch_app_parity.rs
  • libs/cua-driver-rs/crates/platform-windows/examples/list_apps_parity.rs
  • libs/cua-driver-rs/crates/platform-windows/examples/list_windows_parity.rs
  • libs/cua-driver-rs/crates/platform-windows/examples/overlay_dump.rs
  • libs/cua-driver-rs/crates/platform-windows/src/diagnostics.rs
  • libs/cua-driver-rs/crates/platform-windows/src/launch_uwp.rs
  • libs/cua-driver-rs/crates/platform-windows/src/tools/impl_.rs
  • libs/cua-driver-rs/crates/platform-windows/src/win32/installed_apps.rs

Comment on lines +10 to +18
- **SSH** (Session 0 — services context, no desktop):
```bash
ssh -i ~/.ssh/cua_winvm fbonacci@20.115.29.195
```
- **RDP** (Session 1+ with attached desktop, needed for visual / GUI tool validation):
```bash
open /Users/francesco/Desktop/fbonacci-windows-vm.rdp
```
Credentials: `fbonacci` + password from password manager.

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

Sanitize machine-specific access details in this runbook.

This file currently includes concrete host/IP, account, and local key/path details. Please replace them with redacted placeholders and generic examples so repository docs don’t expose internal environment information.

Also applies to: 26-37, 116-132

🤖 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/DEV_LOOP_WINDOWS_VM.md` around lines 10 - 18, Replace all
machine-specific access details in DEV_LOOP_WINDOWS_VM.md (notably the SSH block
containing "ssh -i ~/.ssh/cua_winvm fbonacci@20.115.29.195", the RDP path "open
/Users/francesco/Desktop/fbonacci-windows-vm.rdp", and the credential line
"fbonacci + password from password manager") with redacted placeholders and
generic examples (e.g. <SSH_KEY_PATH>, <USERNAME>, <HOST_IP>, <RDP_FILE_PATH>,
and a note to retrieve passwords from your password manager) across the
indicated sections (including ranges around lines 26-37 and 116-132) so the
runbook contains no concrete host, account or local path information.

Comment on lines +12 to +35
Branch `stab/windows-session0-fixes` is 7 commits ahead of
`origin/main`, all local — no PR opened per your ask. To turn into a
PR when ready:

```bash
git -C /Users/francesco/cua push -u origin stab/windows-session0-fixes
gh pr create --base main --head stab/windows-session0-fixes \
--title "fix(windows): Session-0 hardening + UWP focus-restore" \
--body-file WINDOWS_SESSION0_STATUS.md
```

**Still wants your eyes:** the UWP focus-restore needs visual
confirmation in Session 1+ (RDP in, run the snippet under "Visual
confirmation" below). I made it stronger than my first pass (now uses
the `keybd_event` workaround to lift Windows' SetForegroundWindow
restriction) but I can't visually verify from Mac side.

---

**Branch:** `stab/windows-session0-fixes` (local-only, no PR yet per your ask)
**Base:** `origin/main` @ 69a9dbd5 (post-#1547)
**VM:** `fbonacci-windows-vm` (20.115.29.195) — Rust toolchain + VS Build Tools 2022 installed
**Dev loop:** edit on Mac → `scp` changed files to `~/cua/...` on VM → `cargo build --release -p cua-driver` (~20s incremental, ~5min cold) → run. Full reference: `libs/cua-driver-rs/DEV_LOOP_WINDOWS_VM.md`.

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

Remove host/user-specific infrastructure details from committed docs.

This report embeds concrete VM IP/host identifiers, local usernames, and workstation-specific filesystem paths. Please sanitize these to placeholders (for example, <vm-host>, <user>, <repo-root>) before merging to avoid leaking internal environment details and to keep the doc reusable.

Also applies to: 99-104, 132-139

🤖 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 `@WINDOWS_SESSION0_STATUS.md` around lines 12 - 35, The markdown file
WINDOWS_SESSION0_STATUS.md contains host/user-specific details (e.g., branch
name mention `stab/windows-session0-fixes` with a concrete VM name/IP
`fbonacci-windows-vm` and local paths like `/Users/francesco/cua`)—replace all
concrete VM hostnames/IPs, local usernames, and absolute filesystem paths with
neutral placeholders such as <vm-host>, <vm-ip>, <user>, and <repo-root>, and
remove or generalize workstation-specific dev-loop commands and references so
the document contains no sensitive or environment-specific identifiers while
preserving the instructions and examples.

…duled Task

The macOS install.sh registers a LaunchAgent so cua-driver-rs is up
and serving without the user pasting an env-var + path one-liner
every login. The Windows-native equivalent is a Scheduled Task
triggered at logon with `LogonType: Interactive` so it lands in a
Session 1+ user context (Session 0 would defeat the entire point —
window-driving tools need an attached interactive desktop).

This commit doesn't auto-register the task (that's a bigger choice
to make — bake it in with a flag, or leave opt-in). Instead:

1. install.ps1 prints the exact registration command at the end of a
   successful install, including the binary path it resolved to.
   Copy-paste once, done forever.
2. docs/installation.mdx gets a new sub-section under
   "Windows: interactive-session requirements" with the same recipe,
   the schtasks follow-up commands (Run / Query / Delete), and the
   two load-bearing parameter notes (LogonType=Interactive +
   ExecutionTimeLimit=0).

Validated live: registered the task on the test Windows VM, signed
out + back in via RDP, `cua-driver serve` was already listening when
the shell opened. Same UX as macOS.
f-trycua added 3 commits May 18, 2026 09:12
Three additions to bring cua-driver-rs install UX closer to the Swift
cua-driver pattern + the macOS LaunchAgent ergonomics on Windows:

1. install.ps1 -AutoStart (default $false)
   When set, registers the cua-driver-serve Scheduled Task at the
   end of install (LogonType=Interactive, lands in Session 1+). The
   factored helper Register-CuaDriverAutostart is also called from
   install-local.ps1 so both scripts share the same behavior. When
   the flag is OFF the post-install message still prints the manual
   recipe so users can opt in later.

2. install-local.ps1 (new) — Windows dev-loop installer
   Builds from the current source via cargo build [--release]
   -p cua-driver, drops the resulting cua-driver.exe into the same
   versioned-dirs + junction layout install.ps1 produces, retargets
   the `current` junction at the new dir. Accepts -Release and
   -AutoStart. Version tag carries '-local-debug' / '-local-release'
   so a local install can coexist with a release install in the
   same packages/releases tree and the user can flip `current`
   between them.

3. install-local.sh (new) — macOS + Linux dev-loop installer
   Mirrors install-local.ps1 in shape. Builds via cargo, stages into
   $HOME/.cua-driver-rs/packages/releases/0.0.0-local-<config>-<target>,
   swaps the `current` symlink. --autostart writes either a
   LaunchAgent plist (macOS) or a systemd --user unit (Linux) and
   loads/enables it. Both pointed at the visible-bin symlink so
   future install.sh upgrades take effect transparently.

Cross-platform shape parity with libs/cua-driver/scripts/install-local.sh
(Swift): same flag names where the OS allows (--release, --autostart vs
the Swift --release, --daemon), same prerequisite checks, same
"don't run with sudo" guard.

Out of scope for this commit: a `cua-driver autostart {enable|disable|
status}` CLI verb that would dedupe the OS-specific logic and let users
manage autostart without going back to the install script. Worth a
follow-up; design is straightforward (per-platform impl in
cua-driver-rs/crates/cua-driver/src/autostart/{macos,linux,windows}.rs
+ a dispatcher subcommand in cli.rs).
…port

Replace concrete values (VM hostname, public IP, OS username, SSH key
file basename, local Mac filesystem paths) with placeholder tokens
(<vm-name>, <vm-host>, <user>, <ssh-key>, <repo-root>,
<rdp-file-dir>). Addresses CodeRabbit Major comments on PR #1548.

Content unchanged; same recipes, same examples, just with stub
identifiers a reader fills in from their own setup.
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