fix(server): installed editors no longer go undetected on Windows - #6221
fix(server): installed editors no longer go undetected on Windows#6221JstnMcBrd wants to merge 2 commits into
Conversation
Resolving a command probed every (directory, command, extension) combination: on Windows that is ~40 PATH directories times 24 candidate names, so editor discovery's 22 commands cost over 20,000 filesystem probes and took 14s on an ordinary machine. That overran the 5s timeout in server.getConfig, which yields an empty editor list on expiry, so no editors were ever detected and the Open button stayed disabled — intermittently, because the old per-command cache carried partial progress across reconnects and a lucky rescan occasionally finished in time. Other platforms have no PATHEXT and so probe one candidate per directory, which stayed well inside the timeout. Each PATH directory is now read once and candidates are matched against its listing, with the cache keyed by directory rather than by command; the same discovery takes 85ms. A listing match only selects which candidates to stat, so the stat still decides what resolves, and a directory that denies read permission falls back to probing directly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
ApprovabilityVerdict: Needs human review This PR changes the core PATH resolution algorithm from per-command caching to per-directory listing cache, with new error-handling logic. While the bug fix intent is clear and tests are comprehensive, the algorithmic change to how Windows command detection works warrants human review. You can customize Macroscope's approvability policy. Learn more. |
Only three failure reasons prove a PATH entry can never hold a command: NotFound (ENOENT), BadResource (ENOTDIR/EISDIR/ELOOP) and BadArgument. Everything else — EBUSY, EIO and EPERM, the last two arriving unclassified as Unknown — is transient or unproven, and treating it as an empty listing ruled out every candidate without the stat fallback and cached that false negative for the full 30s window, so an installed command could briefly appear missing. Unproven failures now list as null, which makes the caller probe candidates directly the way it did before this cache existed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hi, I'm a new user trying out T3 Code for the first time. I encountered a bug, so I thought I'd get some practice by using T3 Code to fix T3 Code.
Thanks for taking the time to review. I hope you'll find this valuable. Feedback is much appreciated.
Problem
On Windows, the "Open in…" picker listed no editors and stayed disabled, even with VS Code installed.
server.getConfigresolves 22 editor commands through PATH under a 5s timeout that returns[]on expiry. The scan probed every (directory, command, extension) combination: ~40 directories × 24 candidate names × 22 commands ≈ 21,000 filesystem probes, 14.4s measured. It never finished in time. Other platforms (Linux, macOS) have no PATHEXT and probe one candidate per directory, so they stayed well inside the budget.Solution
Read and cache each PATH directory once and match candidates against the listing. Same discovery: 14,375ms → 85ms.
The cache moved to an axis that actually repeats
Before: Keyed per command, and a pass resolves each command once — so the cache is never hit:
After: Keyed per directory, one listing serves every command:
Same 30s TTL, same monotonic-clock expiry — only the key changed.
Results are identical
A listing match only selects which candidates get
stated —statstill decides what resolves, checking file type and the executable bit exactly as before.Names fold to lowercase on every platform. This is necessary because the listing introduces a userspace name comparison that didn't exist before; previously the kernel did all name matching inside
stat. Folding can only widen the candidate set, and the OS validates each one anyway, so an extra match costs onestat— whereas exact matching would miss a real command on a case-insensitive volume (Windows, default APFS).Two behaviors preserved deliberately: a search-only directory (read permission denied) falls back to probing candidates directly, and explicit paths never consult the cache, so a just-installed binary stays immediately visible.
Changes
packages/shared/src/shell.tspackages/shared/src/shell.test.tsapps/server/src/process/externalLauncher.test.tsapps/server/src/process/externalLauncher.ts38 tests pass; targeted lint, typecheck and format clean. Verified on Windows 11 — I have no macOS or Linux machine to test on.
Further Reading
Checklist
I included before/after screenshots for any UI changesNAI included a video for animation/interaction changesNANote
Medium Risk
Changes shared PATH command-resolution used by editor discovery and other availability checks; incorrect listing/cache behavior could hide or mis-resolve installed commands.
Overview
Fixes Windows editor discovery timing out by replacing per-candidate
statprobing with cached PATH directory listings.resolveCommandPathnow reads each PATH directory once (vialistPathDirectory/PathListingCache), matches candidates against the lowercase name set, and onlystats hits. Unreadable directories fall back to probing; missing/unusable ones are skipped. Same 30s TTL, but keyed by directory so one listing serves every command in a scan.Tests cover case-insensitive Windows matches, listing-failure fallbacks, and updated editor-discovery memoization expectations.
Reviewed by Cursor Bugbot for commit 59849f9. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix editor detection on Windows by switching to directory-listing-based command resolution
shell.ts: each PATH entry is read once per 30-second window, with file names stored in lowercase for case-insensitive matching (fixing missed detections on Windows where extensions like.CMDdiffer in case).NotFoundorBadResourcereasons are skipped outright; directories that fail for other reasons (e.g.PermissionDenied) fall back to probing each candidate withstat.Macroscope summarized 59849f9.