Skip to content

fix(desktop): skip the PowerShell profile probe when node is already resolvable - #5771

Closed
CDVolvik wants to merge 1 commit into
pingdotgg:mainfrom
CDVolvik:fix/windows-skip-profile-probe-when-node-resolvable
Closed

fix(desktop): skip the PowerShell profile probe when node is already resolvable#5771
CDVolvik wants to merge 1 commit into
pingdotgg:mainfrom
CDVolvik:fix/windows-skip-profile-probe-when-node-resolvable

Conversation

@CDVolvik

@CDVolvik CDVolvik commented Aug 9, 2026

Copy link
Copy Markdown

Problem

On Windows, installWindowsEnvironment runs two PowerShell probes on every desktop start: one with -NoProfile, then one that loads the user profile. Each probe walks pwsh.exe and then powershell.exe, and every candidate gets its own 5 second timeout, so a slow or failing profile can burn up to four timeout budgets before the window appears.

The profile probe was never meant to be unconditional. #1729 added it as a fallback for when node is missing, and resolveWindowsEnvironment in packages/shared/src/shell.ts still works that way:

if (yield* commandAvailable("node", { env: baselineEnv })) {
  return baselinePatch
}

The desktop copy lost that gate in #2546 when the app was ported to Effect, so both probes now run every time.

Fix

  • build the baseline PATH from the no-profile probe, the known CLI directories, and the inherited environment
  • return early when node already resolves from that baseline
  • fall through to the profile probe only when it does not, so fnm users still get FNM_DIR and FNM_MULTISHELL_PATH
  • resolve CommandAvailability in make alongside the other services, so the check is injectable in tests

PATH precedence is unchanged: profile, then known CLI directories, then the no-profile probe, then the inherited environment.

Validation

  • vp test run src/shell/DesktopShellEnvironment.test.ts in apps/desktop (10 passed)
  • vp run --filter @t3tools/desktop typecheck
  • vp lint --report-unused-disable-directives (clean; the one warning it reports is pre-existing in apps/web)

The new test fails with expected 2 to equal 1 when the gate is removed, so it covers the regression rather than just the current behavior.

I did not measure packaged-app startup traces, so the probe count is covered by the test rather than by a trace comparison.

Closes #4403


Note

Low Risk
Localized Windows shell hydration logic with shared parity to resolveWindowsEnvironment; profile fallback remains when node is missing.

Overview
Windows desktop startup no longer always runs the slow PowerShell profile probe. After the existing no-profile PATH probe, known CLI directories, and inherited PATH are merged into a baseline, the app uses shared CommandAvailability to check whether node resolves; if it does, it returns early and skips the profile probe (and fnm env vars unless needed).

When node is still missing, behavior matches before: profile probe runs to pick up profile PATH, FNM_DIR, and FNM_MULTISHELL_PATH, with the same PATH merge order (profile ahead of baseline). CommandAvailability is resolved in make and injected into installIntoProcess so tests can stub it.

Tests gain a nodeAvailable hook and a case that asserts only one PowerShell invocation (-NoProfile) when node is already available.

Reviewed by Cursor Bugbot for commit ccb618c. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Skip PowerShell profile probe on Windows when node is already resolvable

  • On Windows, a baseline PATH is now computed by merging known CLI directories, a -NoProfile PATH probe, and the existing process PATH before any profile probing occurs.
  • If node is resolvable in the baseline environment, the full PowerShell profile probe is skipped entirely, avoiding slow or side-effectful profile execution.
  • When node is not resolvable, the existing profile-loading behavior is preserved and FNM-related variables (FNM_DIR, FNM_MULTISHELL_PATH) are still populated.
  • DesktopShellEnvironment.make now explicitly depends on Path.Path and CommandAvailability services to support the new resolution check.
  • Behavioral Change: baseline PATH is always set before profile probing, which changes the PATH order on Windows even when the probe runs.

Macroscope summarized ccb618c.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bf5b851c-9b82-4136-9a0e-bc67533a5418

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

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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 9, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved ccb618c

Performance optimization that skips expensive PowerShell profile probe when node is already available. Self-contained change with good test coverage covering both code paths.

You can customize Macroscope's approvability policy. Learn more.

@CDVolvik

Copy link
Copy Markdown
Author

Closing this one. #5878 landed the concurrency fix on the same function and removes most of what this PR was for: with both probes running under Effect.all, the serial cost is gone, and by the numbers in that PR the profile probe is the faster of the two (2066ms against 2718ms), so skipping it no longer buys measurable startup time.

What remains is one fewer PowerShell spawn. That is real but small, and I cannot put a measurement behind it, so it is not worth carrying a conflicting branch through a rewritten file. If profile load does turn out to dominate on machines with heavy profiles, that is a separate PR with numbers attached.

@CDVolvik CDVolvik closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unconditional PowerShell profile discovery delays Windows desktop startup

1 participant