Skip to content

fix: detect npm.cmd on Windows in setup prerequisite check#2

Merged
DavidsonGomes merged 3 commits into
evolution-foundation:developfrom
mareanalitica:fix/setup-npm-windows-detection
Apr 10, 2026
Merged

fix: detect npm.cmd on Windows in setup prerequisite check#2
DavidsonGomes merged 3 commits into
evolution-foundation:developfrom
mareanalitica:fix/setup-npm-windows-detection

Conversation

@mareanalitica
Copy link
Copy Markdown
Contributor

@mareanalitica mareanalitica commented Apr 10, 2026

fix: detect npm.cmd on Windows in setup prerequisite check

On Windows (especially when using Git Bash), npm may only be available as npm.cmd rather than npm.

This change introduces a fallback mechanism:

  • Attempts to execute npm
  • If it fails, falls back to npm.cmd

Additionally, error handling has been improved:

  • Separates error messages for node and npm
  • Prevents both from being incorrectly reported as missing under "Node.js 18+"
  • Provides clearer feedback about which specific tool is not available

Summary by Sourcery

Improve prerequisite checks for Node.js tooling in setup script

Bug Fixes:

  • Detect npm as npm.cmd on Windows when npm is not directly available
  • Report missing node and missing npm separately instead of grouping them under Node.js 18+ requirements

Enhancements:

  • Clarify setup output by indicating when Node.js is installed but npm is missing from PATH

…/Git Bash, npm may only be available as npm.cmd and not directly as npm. Falls back to npm.cmd when the plain npm command fails. Also separates the error messages for node and npm so the user knows exactly which tool is missing instead of both being reported as "Node.js 18+".
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 10, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts the setup prerequisite check to correctly detect npm on Windows (including Git Bash) by falling back to npm.cmd, and improves error reporting by distinguishing between missing node and missing npm.

Flow diagram for npm detection fallback logic in check_prerequisites

flowchart TD
    A[Start npm check] --> B[Set npm_cmd = npm]
    B --> C[Run subprocess npm_cmd --version]
    C --> D{subprocess succeeded
and returncode == 0?}
    D -->|Yes| E[Print npm version as OK]
    E --> Z[End npm check]
    D -->|No| F[Raise FileNotFoundError]

    F --> G[Fallback: set npm_cmd = npm.cmd]
    G --> H[Run subprocess npm_cmd --version]
    H --> I{returncode == 0?}
    I -->|Yes| J[Print npm version as OK]
    J --> Z
    I -->|No| K[Append npm to errors]
    H --> L{subprocess raised
FileNotFoundError or TimeoutExpired?}
    L -->|Yes| K
    K --> Z
Loading

File-Level Changes

Change Details Files
Add Windows-aware npm detection with a fallback from npm to npm.cmd in the prerequisite check.
  • Introduce npm_cmd variable defaulting to 'npm' and use it when invoking subprocess.run for the npm version check.
  • Treat a non-zero npm --version exit code as a failure by raising FileNotFoundError to trigger fallback logic.
  • On failure of npm, attempt to run 'npm.cmd --version' and only record an npm error if that also fails or returns a non-zero exit code.
setup.py
Improve error messaging to distinguish missing Node.js from missing npm in the setup failure output.
  • Change the prerequisite summary to only print the Node.js 18+ requirement when node is missing instead of when either node or npm is missing.
  • Add a dedicated error message when npm is missing but Node.js is present, clarifying that npm is not on PATH and pointing to nodejs.org for installation guidance.
setup.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-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.

Hey - I've found 2 issues, and left some high level feedback:

  • Consider limiting the npm.cmd fallback to Windows platforms (e.g. using os.name == 'nt' or platform.system() == 'Windows') so non-Windows environments don't unnecessarily attempt to execute npm.cmd when npm exists but exits with a non-zero status for other reasons.
  • Instead of raising FileNotFoundError when npm returns a non-zero exit code, treat non-zero return codes separately from missing binaries so that genuine npm errors don't incorrectly trigger the fallback to npm.cmd.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider limiting the `npm.cmd` fallback to Windows platforms (e.g. using `os.name == 'nt'` or `platform.system() == 'Windows'`) so non-Windows environments don't unnecessarily attempt to execute `npm.cmd` when `npm` exists but exits with a non-zero status for other reasons.
- Instead of raising `FileNotFoundError` when `npm` returns a non-zero exit code, treat non-zero return codes separately from missing binaries so that genuine `npm` errors don't incorrectly trigger the fallback to `npm.cmd`.

## Individual Comments

### Comment 1
<location path="setup.py" line_range="74-75" />
<code_context>
-            print(f"  {GREEN}✓{RESET} npm: {DIM}v{result.stdout.strip()}{RESET}")
-        else:
-            errors.append("npm")
+        result = subprocess.run([npm_cmd, "--version"], capture_output=True, text=True, timeout=5)
+        if result.returncode != 0:
+            raise FileNotFoundError
+        print(f"  {GREEN}✓{RESET} npm: {DIM}v{result.stdout.strip()}{RESET}")
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Treating any non-zero npm exit code as FileNotFound conflates command discovery with runtime errors.

Mapping any non-zero exit code from `npm` to `FileNotFoundError` causes the code to always fall back to `npm.cmd` and ultimately report npm as missing, even when it exists but failed for another reason (e.g., config/permission issues). Instead, only fall back to `npm.cmd` when an actual `FileNotFoundError` occurs, and treat non-zero exit codes separately (e.g., log the error and add "npm" to `errors` without changing the exception type).
</issue_to_address>

### Comment 2
<location path="setup.py" line_range="99-103" />
<code_context>
-        if "node" in errors or "npm" in errors:
+        if "node" in errors:
             print(f"    {RED}•{RESET} Node.js 18+ — {BOLD}https://nodejs.org{RESET}")
+        if "npm" in errors:
+            print(f"    {RED}•{RESET} npm not found (Node.js installed but npm missing from PATH) — {BOLD}https://nodejs.org{RESET}")
         print()
         print(f"  {YELLOW}Install the missing tools and run setup again.{RESET}")
</code_context>
<issue_to_address>
**suggestion:** The npm error message can be misleading when Node.js is also missing.

This message assumes Node.js is present, but this branch can also run when `"node" in errors` is true (showing both lines). To avoid confusion, either use a neutral message like `npm not found (not installed or not in PATH)` or vary the text depending on whether `"node"` is also in `errors`.

```suggestion
        if "node" in errors:
            print(f"    {RED}•{RESET} Node.js 18+ — {BOLD}https://nodejs.org{RESET}")
        if "npm" in errors:
            print(f"    {RED}•{RESET} npm not found (not installed or not in PATH) — {BOLD}https://nodejs.org{RESET}")
        print()
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread setup.py
Comment on lines +74 to +75
result = subprocess.run([npm_cmd, "--version"], capture_output=True, text=True, timeout=5)
if result.returncode != 0:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (bug_risk): Treating any non-zero npm exit code as FileNotFound conflates command discovery with runtime errors.

Mapping any non-zero exit code from npm to FileNotFoundError causes the code to always fall back to npm.cmd and ultimately report npm as missing, even when it exists but failed for another reason (e.g., config/permission issues). Instead, only fall back to npm.cmd when an actual FileNotFoundError occurs, and treat non-zero exit codes separately (e.g., log the error and add "npm" to errors without changing the exception type).

Comment thread setup.py
Comment on lines +99 to 103
if "node" in errors:
print(f" {RED}•{RESET} Node.js 18+ — {BOLD}https://nodejs.org{RESET}")
if "npm" in errors:
print(f" {RED}•{RESET} npm not found (Node.js installed but npm missing from PATH) — {BOLD}https://nodejs.org{RESET}")
print()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion: The npm error message can be misleading when Node.js is also missing.

This message assumes Node.js is present, but this branch can also run when "node" in errors is true (showing both lines). To avoid confusion, either use a neutral message like npm not found (not installed or not in PATH) or vary the text depending on whether "node" is also in errors.

Suggested change
if "node" in errors:
print(f" {RED}{RESET} Node.js 18+ — {BOLD}https://nodejs.org{RESET}")
if "npm" in errors:
print(f" {RED}{RESET} npm not found (Node.js installed but npm missing from PATH) — {BOLD}https://nodejs.org{RESET}")
print()
if "node" in errors:
print(f" {RED}{RESET} Node.js 18+ — {BOLD}https://nodejs.org{RESET}")
if "npm" in errors:
print(f" {RED}{RESET} npm not found (not installed or not in PATH) — {BOLD}https://nodejs.org{RESET}")
print()

mareanalitica and others added 2 commits April 10, 2026 00:22
Prevents UnicodeEncodeError on systems where the default locale is not UTF-8 (e.g., Windows with cp1252). Also syncs package-lock.json with updated dependency tree.
Replace Unix-only PTY (pty/fcntl/termios) with a platform-aware
implementation that uses pywinpty on Windows and the existing PTY
stack on Unix. All session lifecycle operations (spawn, kill,
resize, WebSocket I/O) now branch on sys.platform.

Adds pywinpty>=3.0.3 as a conditional Windows dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@DavidsonGomes DavidsonGomes changed the base branch from main to develop April 10, 2026 13:12
Copy link
Copy Markdown
Member

@DavidsonGomes DavidsonGomes left a comment

Choose a reason for hiding this comment

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

LGTM — suporte Windows (npm.cmd fallback + ConPTY). Ajustes menores serão feitos direto na develop.

@DavidsonGomes DavidsonGomes merged commit 2224bb3 into evolution-foundation:develop Apr 10, 2026
1 check passed
@mareanalitica mareanalitica deleted the fix/setup-npm-windows-detection branch April 13, 2026 22:27
DavidsonGomes added a commit that referenced this pull request Apr 28, 2026
…tives (Step 1)

Introduces dashboard/packages/ui as an npm workspace package that gives plugins
direct access to the host design system without duplicating Tailwind config.

Primitives: Button, Card/CardHeader/CardBody, Badge, Input/FormField, Select,
Checkbox, Modal, ToastProvider/useToast, ErrorBoundary

Schema-driven CRUD:
- SchemaForm: driven by JSON Schema (string, number, boolean, enum, date widgets),
  client-side validation via bundled Ajv 8, no react-hook-form / zod dependency
- SchemaTable: data + TableColumn[] with sorting and type-aware cell formatting

Tailwind 4 tokens: packages/ui/src/tokens.css exports :root CSS custom properties
(:root vars work via @import; @theme utilities require inlining in the plugin's
CSS entry file — documented in tokens.css). Spike confirmed: @tailwindcss/vite
does not process @theme from transitively-imported CSS files.

Host wiring:
- dashboard/package.json: npm workspaces root (["frontend", "packages/*"])
- frontend/tsconfig.app.json: customConditions: ["source"] for workspace resolution
- frontend/vite.config.ts: resolve.conditions + @evonexus/ui/tokens.css alias
- frontend/src/index.css: @import "@evonexus/ui/tokens.css"
- frontend/src/App.tsx: /dev/ui-playground route
- frontend/src/pages/UIPlayground.tsx: playground showing all primitives + evo-essentials schema

Decisions recorded:
- #1 Distribution: workspace internal (no publish). Zero friction for parallel dev.
- #2 Tailwind preset: CSS-first via tokens.css :root block. @theme must be in root CSS.
- #3 Version: 0.1.0, lockstep with host.
- #5 Ajv: bundled inside @evonexus/ui, plugin authors do not install separately.
- usePluginNavigation: name reserved in index.ts, implements in Step 2.

Build: tsc -b -> 0 errors; vite build -> UIPlayground-yJlY1VKK.js (127KB) in dist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

2 participants