Skip to content

fix(tray): keep Windows Run command under 260 chars - #771

Closed
Wibias wants to merge 3 commits into
lidge-jun:devfrom
Wibias:fix/696-tray-run-limit
Closed

fix(tray): keep Windows Run command under 260 chars#771
Wibias wants to merge 3 commits into
lidge-jun:devfrom
Wibias:fix/696-tray-run-limit

Conversation

@Wibias

@Wibias Wibias commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Shorten Windows tray Run launcher command so it stays under the 260-character limit.
  • Add regression tests for tray Run string length and behavior.

Fixes #696

Test plan

  • �un run test (windows-tray-run-limit / windows-tray tests)
  • Manual: tray launch on Windows when path is long

Security

  • none

Summary by CodeRabbit

  • New Features

    • Improved Windows tray startup registration for installations with long file paths.
    • Added a dedicated launcher script to keep startup commands within Windows’ 260-character limit.
    • Installation state now tracks and validates the launcher script.
  • Bug Fixes

    • Improved installation rollback and removal handling for the launcher.
  • Tests

    • Added coverage for command length limits, launcher usage, UNC paths, and non-ASCII installation paths.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The Windows tray installer now writes an owned VBS launcher, registers a short wscript.exe Run command, persists launcherPath, validates launcher presence, and restores launcher state during rollback. Tests cover quoting, path handling, encoding, and the 260-character startup limit.

Changes

Windows tray autostart

Layer / File(s) Summary
Launcher command and script generation
src/tray/windows.ts
Separates the long PowerShell command from the short wscript.exe Run command, generates opencodex-tray.vbs, and retains a deprecated legacy wrapper.
Installation state and rollback
src/tray/windows.ts
Persists and validates launcherPath, prevents overwriting unowned launchers, writes the UTF-16LE launcher, and restores or removes it during rollback.
Command-length and quoting validation
tests/windows-tray-run-limit.test.ts, tests/windows-tray.test.ts
Verifies the short Run command stays within 260 characters and covers UNC paths, non-ASCII content, encoding, and separate PowerShell command generation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WindowsSignIn
  participant HKCURun
  participant WScript
  participant PowerShellTrayHost
  WindowsSignIn->>HKCURun: Execute registered short command
  HKCURun->>WScript: Launch opencodex-tray.vbs
  WScript->>PowerShellTrayHost: Run the PowerShell tray command invisibly
Loading

Possibly related PRs

  • lidge-jun/opencodex#306: The Windows tray implementation updated here builds on the related Run command, launcher, persistence, installation, rollback, and uninstall behavior.

Suggested reviewers: lidge-jun, ingwannu

🚥 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 clearly and concisely describes the primary fix: keeping the Windows Run command below the 260-character limit.
Linked Issues check ✅ Passed The implementation adds an owned VBS launcher, preserves installation lifecycle handling, and adds regression tests covering the issue #696 requirements.
Out of Scope Changes check ✅ Passed All code and test changes directly support the linked issue’s Windows tray startup, launcher ownership, encoding, and command-length requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 `@src/tray/windows.ts`:
- Around line 157-159: Update quoteVbsPath to stop replacing backslashes and
only escape double quotes before values are passed to WScript.Shell.Run,
preserving UNC and other Windows paths unchanged.
- Around line 531-533: Update the launcher ownership guard around the existing
existsSync check to reject an existing launcher whenever persisted state is
absent or state.launcherPath is missing; only allow it when the stored launcher
path resolves to the current launcherPath. Preserve the existing error behavior
and message for unowned launchers.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c09c0da2-6b49-4e94-82bc-1bacf2119939

📥 Commits

Reviewing files that changed from the base of the PR and between be177ea and 52920d3.

📒 Files selected for processing (3)
  • src/tray/windows.ts
  • tests/windows-tray-run-limit.test.ts
  • tests/windows-tray.test.ts

Comment thread src/tray/windows.ts
Comment thread src/tray/windows.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52920d3189

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tray/windows.ts Outdated
Comment thread src/tray/windows.ts
Comment thread src/tray/windows.ts Outdated
Comment thread src/tray/windows.ts Outdated
Comment thread src/tray/windows.ts
@Wibias

Wibias commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

[shipping-github] Merge-ready

  • \mergeStateStatus: CLEAN after windows-latest rerun passed
  • Cross-platform CI + enforce-target + label + react-doctor all green
  • Initial windows failure was \previewArchivedCleanup\ 5s timeouts (infra flake); rerun clean

Escape only quotes in VBS paths, refuse overwriting unowned launchers, and write UTF-16LE tray scripts so WSH reads non-ASCII paths correctly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@tests/windows-tray.test.ts`:
- Around line 70-75: Update the test around buildWindowsTrayLauncherScript to
verify the actual persisted launcher bytes produced by the Windows tray
installation flow, rather than re-encoding the in-memory script with the
production expression. Assert both the UTF-16LE byte order and preservation of
the non-ASCII path from the installed output; alternatively, extract and test a
shared production encoding helper.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 214253a9-5ccf-436e-8895-981c2fcaa2be

📥 Commits

Reviewing files that changed from the base of the PR and between 52920d3 and e0bae53.

📒 Files selected for processing (2)
  • src/tray/windows.ts
  • tests/windows-tray.test.ts

Comment thread tests/windows-tray.test.ts
lidge-jun added a commit that referenced this pull request Jul 31, 2026
…oundary

Windows CI died with `panic(...): Internal assertion failure` and no `(fail)`
line — four runs across `dev`, #771, #780 and #781. The crash header names the
shape: `workers_spawned(9) workers_terminated(8)`, one worker never reclaimed,
and it lands exactly at the `api-storage-policy` -> `api-storage` file
boundary. That suite is the only one that spawns policy workers.

`Worker.terminate()` returns void and does not wait for the thread to go away.
Under `bun test --isolate` the harness reclaims a file's realm at the boundary,
so a worker still exiting at that instant trips a Bun-internal assertion and
takes the whole run down. macOS and Linux tolerate the same race, which is why
it reads as a Windows-only flake.

`worker-lifecycle.ts` tracks live workers and terminates them through the
`close` event, so callers can await the thread actually being gone rather than
a timer they hope is long enough; a 5s cap keeps a wedged worker from hanging
teardown. Both storage jobs settle their run promise after that await, and the
policy suite's `afterEach` now drains.

devlog `_plan/260730_remote_issue_merge_round/150` reproduced this panic twice
against an unchanged tree, confirmed the same tree passed in PR context, and
left this defence as the follow-up if it recurred. It recurred.

Evidence: 6190 pass / 0 fail across 445 files, typecheck clean, privacy scan
green. The regression test asserts a worker was really spawned before checking
it is gone, so it cannot pass vacuously.
@Wibias

Wibias commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: approve-comment

  • Usefulness: Fixes Windows tray autostart Run entry exceeds 260-character limit and does not launch after sign-in #696 — short HKCU Run + owned VBS launcher keeps the command under 260 chars.
  • Bugs: Prior P1s addressed (quote-only VBS escaping, unowned overwrite guard, UTF-16LE+BOM). Remaining installer-byte assertion nit is non-blocking.
  • Security: Path validation + owned-file ACL hardening preserved; no new injection surface.
  • Owner/maintainer reviews: none open requiring action.
  • Bots: addressed / declined follow-ups.
  • Base / CI: dev, windows green on tip.
  • Gate: none.

Ready for maintainer merge when convenient.

@lidge-jun

Copy link
Copy Markdown
Owner

Landed on codex/260731-pr-merge-round as 13a76a38a, squashed with your authorship preserved.

The VBS launcher approach is the right shape: the long PowerShell invocation lives in an owned launcher file and the Run value becomes wscript.exe //B //NoLogo <launcher>, comfortably under the 260-character HKCU cap. The ownership check, state tracking and rollback all came across unchanged — a foreign file at the launcher path is not executed, which an independent review confirmed at src/tray/windows.ts:559 and :613.

Two notes on how it got here.

The earlier conflict is gone. This PR was blocked mid-round by a conflict in tests/windows-tray.test.ts. Landing #768 first resolved it and the branch now merges clean, so no rebase was needed from you.

The ablation initially fooled me. Disabling the 260-character guard failed nothing, which looked like a vacuous test. It is not: that guard is a startup assertion, not the fix. Substituting the old PowerShell command back into buildWindowsTrayRunCommand — the actual pre-fix behavior — fails your test (0 pass / 1 fail), and restoring passes 18/18 across both tray suites. Your test asserts the right thing; I was ablating the wrong line.

One gap worth naming: nothing invokes installWindowsTray itself, so the installer's ownership check and directory hardening are verified by reading rather than by execution. That needs a Windows filesystem, so the matrix CI is what confirms it.

Closing here since the work is staged; the branch merges into dev and ships once the optimization work in flight there completes. #696 closed alongside.

@lidge-jun lidge-jun closed this Jul 31, 2026
@Wibias
Wibias deleted the fix/696-tray-run-limit branch July 31, 2026 04:09
@coderabbitai coderabbitai Bot mentioned this pull request Jul 31, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants