Skip to content

Fix/hardcoded legacy powershell#12411

Open
Charlweed wants to merge 4 commits into
continuedev:mainfrom
Charlweed:fix/hardcoded_legacy_powershell
Open

Fix/hardcoded legacy powershell#12411
Charlweed wants to merge 4 commits into
continuedev:mainfrom
Charlweed:fix/hardcoded_legacy_powershell

Conversation

@Charlweed
Copy link
Copy Markdown

@Charlweed Charlweed commented May 14, 2026

Description

Centralize and Modernize PowerShell Command Detection
Resolves issue #12410

Overview

This PR eliminates hardcoded dependencies on legacy Windows PowerShell (powershell.exe) across the codebase and introduces a dynamic, centralized detection mechanism. By preferring modern PowerShell Core (pwsh), we resolve critical runtime failures caused by executing modern scripts in legacy environments, while maintaining backward compatibility.

Rationale & Technical Implementation Choices

1. Centralized Synchronous Detection

A new utility getPowerShellCommand() has been added to core/util/shell.ts.

  • Why Synchronous (spawnSync)? Several call sites, notably core/tools/definitions/runTerminalCommand.ts, invoke the shell detection during module initialization to populate static metadata and configuration. A synchronous implementation was mandatory to prevent [object Promise] from bleeding into module-level constants.
  • Performance Tradeoff: While synchronous process spawning blocks the event loop, this is an explicitly accepted tradeoff. The detection result is cached at the module level for the process lifetime. In the context of a CLI or local developer tool (which is already I/O bound), a one-time synchronous probe does not meaningfully degrade the performance profile.

2. Architectural Boundaries & Public API

  • Module Isolation: The detection logic utilizing the Node.js child_process module is strictly isolated in core/util/shell.ts. This prevents Node-specific dependencies from being accidentally pulled into non-Node environments (like browser extensions or WASM contexts) that might import from the general utility barrel.
  • Enforcing the Public API: Instead of allowing consumers (like the CLI extensions) to perform deep internal imports directly from core/util/shell.js, the function is re-exported via core/util/index.ts. This enforces strict encapsulation and provides a stable import path through the core package's public API.

3. Robust Test Infrastructure

  • Broad Vitest Aliasing: Updated extensions/cli/vitest.config.ts with a broad core alias mapping to the source directory (../../core/src). This correctly mirrors the tsconfig.json path resolution, allowing tests to run directly against the source files via the public API without requiring tightly coupled, file-specific aliases or a prior build step.
  • Interface Mocking: Tests now mock the core/util/index.js public API rather than intercepting internal execAsync or child_process calls. This makes the tests resilient to internal implementation changes and focuses verification strictly on the logic's boundaries.

AI Code Review

  • Team members only: AI review runs automatically when PR is opened or marked ready for review
  • Team members can also trigger a review by commenting @continue-review

Checklist

  • I've read the contributing guide
  • The relevant docs, if any, have been updated or created
  • The relevant tests, if any, have been updated or created

Tests

Verification Results

  • Confirmed pwsh is correctly preferred when available on Windows.
  • Confirmed safe fallback to powershell on legacy Windows environments.
  • Verified zero module resolution errors during testing via the new public API alias.
  • All CLI tests, including refactored clipboard utility tests, pass successfully.

Summary by cubic

Centralizes PowerShell detection and switches Windows tooling to prefer PowerShell Core (pwsh) with a safe fallback to legacy powershell. Fixes Windows runtime issues in terminal, TTS, and clipboard flows by routing all calls through one API.

  • Bug Fixes

    • Prefer pwsh on Windows; fall back to powershell when unavailable in runTerminalCommand, TTS, and clipboard utilities.
    • Improve Windows clipboard reliability using System.Windows.Forms APIs and -STA for image checks and saves.
  • Refactors

    • Add getPowerShellCommand() in core/util/shell.ts (sync, cached) and re-export via core/util/index.ts.
    • Replace hardcoded powershell.exe across core and extensions/cli with getPowerShellCommand().
    • Update extensions/cli vitest.config.ts to alias core to source and adjust tests to mock the core/util/index.js public API.

Written for commit 5bf7d3e. Summary will update on new commits.

@Charlweed Charlweed requested a review from a team as a code owner May 14, 2026 20:53
@Charlweed Charlweed requested review from sestinj and removed request for a team May 14, 2026 20:53
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label May 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 9 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant