Skip to content

fix: resolve PowerShell as default shell on Windows when CLAUDE_CODE_USE_POWERSHELL_TOOL=true#1043

Open
Keker8841 wants to merge 4 commits intoGitlawb:mainfrom
Keker8841:fix/windows-powershell-default-on-env
Open

fix: resolve PowerShell as default shell on Windows when CLAUDE_CODE_USE_POWERSHELL_TOOL=true#1043
Keker8841 wants to merge 4 commits intoGitlawb:mainfrom
Keker8841:fix/windows-powershell-default-on-env

Conversation

@Keker8841
Copy link
Copy Markdown

Summary

When users set CLAUDE_CODE_USE_POWERSHELL_TOOL=true to enable the PowerShell tool on Windows, also resolve PowerShell as the default shell for ! commands and bash-mode.

Previously, users had to separately configure defaultShell: powershell in settings.json even after enabling the env var. This change makes the env var a single opt-in switch that fully activates PowerShell on Windows.

Change

src/utils/shell/resolveDefaultShell.ts — added Windows + env var check in the fallback chain:

settings.defaultShell -> (Windows + CLAUDE_CODE_USE_POWERSHELL_TOOL) -> 'bash'

Safety

  • No change for existing users unless they explicitly set the env var. Without CLAUDE_CODE_USE_POWERSHELL_TOOL=true, behavior is identical.
  • Follows the same pattern already used elsewhere (isEnvTruthy, getPlatform).
  • Non-Windows platforms unaffected.

Copy link
Copy Markdown
Contributor

@kevincodex1 kevincodex1 left a comment

Choose a reason for hiding this comment

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

can we rename this env var to OPEN_CLAUDE_USE_POWERSHELL_TOOL ? and also kindly add this too .env.example with proper comments

…ELL_TOOL

- Rename the env var in resolveDefaultShell.ts, shellToolUtils.ts, tipRegistry.ts
- Add documentation in .env.example with usage notes (Windows-only, opt-in)
- Resolves PowerShell as default shell for ! commands and bash-mode on Windows
  when OPENCLAUDE_USE_POWERSHELL_TOOL is set to a truthy value

Co-Authored-By: Deepseek-V4-Pro
@Keker8841 Keker8841 force-pushed the fix/windows-powershell-default-on-env branch from 02edf2d to 16d1898 Compare May 6, 2026 17:01
@Keker8841 Keker8841 requested a review from kevincodex1 May 6, 2026 17:04
kevincodex1
kevincodex1 previously approved these changes May 7, 2026
Copy link
Copy Markdown
Contributor

@kevincodex1 kevincodex1 left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you

Copy link
Copy Markdown
Collaborator

@Vasanthdev2004 Vasanthdev2004 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR. The goal makes sense, but I found one compatibility blocker on the current head.

Review scope: Targeted review of the PowerShell env-var/default-shell behavior.

Verdict: Needs changes

Blocking issue:

  1. The PR title/body describe making CLAUDE_CODE_USE_POWERSHELL_TOOL=true also select PowerShell as the default shell, but the implementation replaces the existing env var with OPENCLAUDE_USE_POWERSHELL_TOOL only. That means existing Windows users who already set CLAUDE_CODE_USE_POWERSHELL_TOOL=1 would lose PowerShell tool/default-shell behavior after this change unless they rename their env var. This is especially risky because the current code already uses the legacy env var in isPowerShellToolEnabled().

Please keep OPENCLAUDE_USE_POWERSHELL_TOOL as the preferred name, but preserve CLAUDE_CODE_USE_POWERSHELL_TOOL as a backward-compatible fallback, ideally with precedence like:

  • explicit OPENCLAUDE_USE_POWERSHELL_TOOL wins
  • otherwise fall back to CLAUDE_CODE_USE_POWERSHELL_TOOL

Also please add a focused test covering:

  • Windows + preferred env var => PowerShell enabled/default
  • Windows + legacy env var only => still PowerShell enabled/default
  • settings.defaultShell still overrides both
  • non-Windows remains unchanged

Non-blocking note:

  • The .env.example docs can recommend only the OpenClaude name, but the runtime should not silently strand existing users using the legacy name.

Keep OPENCLAUDE_USE_POWERSHELL_TOOL as the preferred env var name,
but preserve CLAUDE_CODE_USE_POWERSHELL_TOOL as a legacy fallback.
Precedence: explicit OPENCLAUDE > legacy CLAUDE_CODE.

- Extract getPowershellToolEnv() helper with `??` fallback chain
- Use it in both isPowerShellToolEnabled() and resolveDefaultShell()
- Update tipRegistry to suppress tip when either env var is set
- Add 20 focused tests covering both env vars, ant/external users,
  settings.defaultShell override, and non-Windows platforms

Co-Authored-By: OpenClaude (deepseek-v4-pro) <openclaude@gitlawb.com>
kevincodex1
kevincodex1 previously approved these changes May 8, 2026
Copy link
Copy Markdown
Contributor

@kevincodex1 kevincodex1 left a comment

Choose a reason for hiding this comment

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

LGTM

@kevincodex1 kevincodex1 requested review from jatmn and techbrewboss May 8, 2026 01:02
Copy link
Copy Markdown
Collaborator

@techbrewboss techbrewboss left a comment

Choose a reason for hiding this comment

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

Thanks for the compatibility fallback here. The implementation direction looks reasonable, but the new test suite currently fails on non-Windows runners because the Windows cases do not mock getPlatform() to return windows.

In src/utils/shell/shellToolUtils.test.ts, the tests under isPowerShellToolEnabled (Windows) and resolveDefaultShell (Windows) assert Windows behavior while running against the real platform. On my macOS checkout, the Windows truthy-env cases return false/bash because getPlatform() is macos; Linux CI should behave the same way. Please mock ../platform.js to windows for those sections, or otherwise isolate these cases so they are platform-independent.

Failing command:

bun test src/utils/shell/shellToolUtils.test.ts

Result: 14 pass, 6 fail. The failing assertions are around lines 72, 78, 95, 127, 137, and 148.

Tests under isPowerShellToolEnabled (Windows) and resolveDefaultShell (Windows)
now explicitly mock ../platform.js → 'windows' so they pass on macOS/Linux CI.

Co-Authored-By: OpenClaude (deepseek-v4-pro) <openclaude@gitlawb.com>
Copy link
Copy Markdown
Collaborator

@jatmn jatmn left a comment

Choose a reason for hiding this comment

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

I reviewed the latest PR head (53196d7875f0e61271e3820c9341cc123b8c9123) and do not have a new blocking finding to request fixes for.

The focused shell test suite now passes locally on the latest branch.

Requested fixes

No additional fixes from me.

techbrewboss requested changes

Verified against techbrewboss's review request: the latest PR head now mocks ../platform.js to return windows in the Windows cases under both isPowerShellToolEnabled (Windows) and resolveDefaultShell (Windows).

The requested failing command now passes locally:

bun test src/utils/shell/shellToolUtils.test.ts

Result: 20 pass, 0 fail.

Notes from validation

  • OPENCLAUDE_USE_POWERSHELL_TOOL is documented in .env.example.
  • CLAUDE_CODE_USE_POWERSHELL_TOOL remains supported as a backward-compatible fallback.
  • The preferred OpenClaude env var takes precedence over the legacy env var.
  • The Windows test sections now mock getPlatform() as windows, addressing techbrewboss's existing platform-specific test concern.

Commands run

bun test src/utils/shell/shellToolUtils.test.ts
bun test src/utils/shell/shellToolUtils.test.ts src/utils/processUserInput/processBashCommand.test.tsx
bun run build

All three commands passed locally.

LGTM

Copy link
Copy Markdown
Collaborator

@techbrewboss techbrewboss left a comment

Choose a reason for hiding this comment

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

LGTM. The latest commit fixes my previous blocker: the Windows-specific shell tests now mock ../platform.js to return windows, so they are no longer dependent on the runner OS.

I reran the focused validation in an isolated worktree:

bun test ./src/utils/shell/shellToolUtils.test.ts ./src/utils/processUserInput/processBashCommand.test.tsx
bun run build

The shell suite passed with 20 pass, 0 fail, and the build completed successfully.

Copy link
Copy Markdown
Collaborator

@Vasanthdev2004 Vasanthdev2004 left a comment

Choose a reason for hiding this comment

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

Targeted re-review of current head 53196d7.

Verdict: Needs changes

The previous compatibility concern is fixed: OPENCLAUDE_USE_POWERSHELL_TOOL is preferred, CLAUDE_CODE_USE_POWERSHELL_TOOL remains a legacy fallback, and the helper is used by both tool enablement and default-shell resolution.

Blocking issue:

  1. The focused test suite added by this PR is still not deterministic locally. Running bun test src/utils/shell/shellToolUtils.test.ts src/utils/processUserInput/processBashCommand.test.tsx fails in resolveDefaultShell (Windows) > returns bash by default on Windows without env var with:
Cannot find module './commands/fork/index.js' from 'src/commands.ts'

That specific test imports resolveDefaultShell without first mocking ../settings/settings.js, so the real settings module pulls in the broader command graph and hits the feature-gated missing commands/fork require path. The later resolveDefaultShell tests already mock settings before import, so the fix should be small: make the default-shell test use the same settings mock/isolation pattern before importing resolveDefaultShell.

What I checked:

  • Current head: 53196d7
  • The legacy/preferred env fallback implementation in shellToolUtils.ts and resolveDefaultShell.ts
  • Tip suppression behavior for both env var names
  • Local validation: bun run build passed, but the focused test command above fails as described.

Happy to re-review once the test import path is made deterministic.

…t failure

The first resolveDefaultShell test imported the real settings module, which
pulls in the broader command graph. When co-located with other test suites
(e.g. processBashCommand.test.tsx) the unmocked import fails on missing
feature-gated requires like commands/fork/index.js. Mock settings.js before
the import, matching the pattern used by the other resolveDefaultShell tests.

Co-Authored-By: OpenClaude (deepseek-v4-pro) <openclaude@gitlawb.com>
@Keker8841 Keker8841 requested a review from Vasanthdev2004 May 8, 2026 11:56
Copy link
Copy Markdown
Collaborator

@gnanam1990 gnanam1990 left a comment

Choose a reason for hiding this comment

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

Thanks for the iteration here — the legacy/preferred env var precedence (OPENCLAUDE_USE_POWERSHELL_TOOL wins, CLAUDE_CODE_USE_POWERSHELL_TOOL falls back) and the getPlatform() mocking in the Windows test sections both look right. techbrewboss and jatmn already verified the latest head and approved.

On Vasanthdev2004's most recent CHANGES_REQUESTED: I cannot reproduce the Cannot find module './commands/fork/index.js' failure they cited. The path they ran with — src/utils/processUserInput/processBashCommand.test.tsx — does not exist in this branch (only processBashCommand.tsx), so bun test silently no-ops on the missing path and only runs the shell suite. The shell suite is deterministic on its own.

Non-blocking:

  • .env.example documents the OpenClaude name only, with a comment about legacy compatibility — appropriate.
  • Tip suppression covers both names.

Verified locally: gh pr checkout 1043; bun test src/utils/shell/shellToolUtils.test.ts → 20 pass, 0 fail; combined run with the (non-existent) processBashCommand path matches Vasanthdev's command and still passes 20/20 for me.

Copy link
Copy Markdown
Collaborator

@Vasanthdev2004 Vasanthdev2004 left a comment

Choose a reason for hiding this comment

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

Targeted re-review of current head a88664f.

Verdict: Approve-ready

The previous blocker I raised is fixed on the latest head. The default resolveDefaultShell test now mocks settings.js before importing resolveDefaultShell, so it no longer pulls the broader command graph and no longer hits the missing feature-gated commands/fork require path.

What I checked:

  • Preferred env var remains OPENCLAUDE_USE_POWERSHELL_TOOL.
  • Legacy CLAUDE_CODE_USE_POWERSHELL_TOOL still works as a fallback.
  • Preferred OpenClaude env var wins when both are set.
  • Tip suppression checks both env var names.
  • Windows-specific tests mock platform as windows.

Local validation:

  • bun test src/utils/shell/shellToolUtils.test.ts passed: 20 pass, 0 fail.
  • bun run build passed.

I do not see a remaining blocker from my side.

@Keker8841 Keker8841 requested a review from kevincodex1 May 8, 2026 13:11
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.

6 participants