npx skills add ...
npx skills add unipds-engenharia-de-ia-aplicada/engenharia-de-software-com-ia-aplicada --skill windowsfy
Invoked as "/windowsfy [path]" or when the user asks to "fix windows compatibility", "make package.json cross-platform", "windows portability", "run on windows", "cross-env", "shx", "PowerShell 5.1 error", "rm -rf on windows", "chmod on windows", "NODE_ENV not recognized", "glob not expanded on windows", "native binary on windows", "tfjs-node windows", "better-sqlite3 windows", "transformers windows", "token && is not a valid statement separator", "single quotes in npm scripts", or encounters npm script failures specific to Windows native shells. Path may be a directory, a single package.json file, or omitted (defaults to ./).
npx skills add unipds-engenharia-de-ia-aplicada/engenharia-de-software-com-ia-aplicada --skill windowsfy
Scans a Node.js project for Unix-only patterns in package.json scripts that fail on Windows native shells (CMD and PowerShell 5.1), then applies portable fixes after user confirmation. Each finding can be fixed in the recommended cross-platform style (using cross-env, shx, glob) or with a shell-specific fallback (CMD, PowerShell, or Bash-family native syntax).
| Category | Description | Reference |
|---|---|---|
native-dep | C++ addon packages needing MS BuildTools (tfjs-node, better-sqlite3). | native-deps |
inline-env | KEY=val node … prefix unsupported by CMD and PowerShell. | inline-env-vars |
single-quote | CMD passes single quotes literally — --message 'text' breaks. | single-quotes |
unix-cmd | rm -rf, chmod, cp -r, mv, mkdir -p absent on Windows shells. | unix-commands |
glob-expand | CMD/PS don't expand **/*.test.ts; literal string reaches the binary. | glob-patterns |
ps5-ampamp | PowerShell 5.1 rejects && interactively (npm scripts still work). | powershell-5-operator |
This skill only runs on Windows native shells:
cmd.exe, powershell.exe (PS 5.1), pwsh.exe (PS 7+).Blocked environments already provide POSIX shell semantics — the scripts in troubleshooting/windows/commons.md execute correctly there, so running windowsfy would either add unneeded devDependencies or apply shell-locked fallbacks where none are required. There is no override flag.
[path] may be a directory, a single package.json, or omitted../ (current working directory, recursive scan).package.json file → scan only that file.package.json) → abort with a clear error.Before parsing the path, run:
Parse the JSON object: {"env":"...","allowed":true|false,"reason":"..."}.
allowed === false: print the detected env and reason, then stop. Do not parse the path. Do not invoke the scanner. Do not edit files.allowed === true: continue to step 1.The scanner also runs detectEnv() internally on every other mode, so even if this step is skipped, --root/--file will exit 2 with a stderr message.
Once the env guard passes, use AskUserQuestion to ask which shell the user is sitting in. Three options, no auto-detect:
cmd.exe)powershell.exe) — default on Windows 10 and 11pwsh.exe)Store the answer as $SHELL_CHOICE with values cmd, ps5, or ps7. Pass it to every subsequent scan.mjs invocation via --shell $SHELL_CHOICE.
The choice drives two things:
ps5-ampamp is reported as info only for ps5; for cmd and ps7 it is silenced because && works natively in both. All other categories remain error regardless of the choice, because npm on Windows spawns scripts via cmd.exe by default — the script runtime is CMD even when the user's interactive shell is PowerShell.$SHELL_CHOICE appears second (immediately after the cross-platform option), highlighted as the natural alternative.| Category | cmd | ps5 | ps7 |
|---|---|---|---|
native-dep | info | info | info |
inline-env | error | error | error |
single-quote | error | error | error |
unix-cmd | error | error | error |
glob-expand | error | error | error |
ps5-ampamp | silent | info | silent |
Extract [path] from the user's invocation. If empty, treat as ./.
Resolve to absolute path. Use Bash with realpath or node -e "console.log(require('path').resolve(...))".
Classify the path:
Apply (always include --shell $SHELL_CHOICE):
node <skill-dir>/scripts/scan.mjs --root <abs-path> --shell $SHELL_CHOICE --json.package.json. node <skill-dir>/scripts/scan.mjs --file <abs-path> --shell $SHELL_CHOICE --json.windowsfy: path not found: <input> and stop.| # | Category | What fails on Windows | Severity |
|---|---|---|---|
| 1 | native-dep | Packages with C++ addons need MS BuildTools to install (@tensorflow/tfjs-node, better-sqlite3, @huggingface/transformers, @xenova/transformers). | info |
| 2 | inline-env | KEY=val node … — Windows treats KEY=val as a command name. | error |
| 3 | single-quote | --message 'text' — CMD passes single quotes literally. | error |
| 4 | unix-cmd | rm -rf, chmod, cp -r, mv, mkdir -p — not present on Windows. | error |
| 5 | glob-expand | tests/**/*.test.ts — CMD/PS don't expand globs; the literal string is passed to the program. | error |
| 6 | ps5-ampamp | && in PS 5.1 throws ParserError: The token '&&' is not a valid statement separator. | info |
--json output by category.Category | Files affected | Severity.Use AskUserQuestion to ask which categories the user wants fixed. Pre-explain:
native-dep (info) → manual winget install steps from references/native-deps.md. No package.json edit.ps5-ampamp (info) → install PowerShell 7. No package.json edit by default (a PS-locked fallback exists).For the categories the user confirmed in step 4, ask globally which style to apply (single AskUserQuestion). Order the options based on $SHELL_CHOICE so the fallback matching the user's shell appears second:
$SHELL_CHOICE | Option order |
|---|---|
cmd | 1. Cross-platform · 2. CMD fallback · 3. PowerShell fallback · 4. Per-finding |
ps5 or ps7 | 1. Cross-platform · 2. PowerShell fallback · 3. CMD fallback · 4. Per-finding |
Option descriptions:
cross-env, shx, glob. Works everywhere; adds devDependencies.cmd /V:ON /C "set KEY=val & node …", rmdir /S /Q. Locks scripts to CMD.$env:KEY='val'; node …, Remove-Item -Recurse -Force. Locks scripts to PS.The Bash-family fallback is intentionally omitted on Windows-native (it makes no sense here — the user is running CMD or PowerShell). If a category has no fallback (e.g., glob-expand, chmod on CMD), silently downgrade to cross-platform for that category and note it in the output.
| # | Category | Cross-platform (primary) | CMD fallback | PowerShell fallback | Bash-family fallback |
|---|---|---|---|---|---|
| 2 | inline-env | cross-env KEY=val node … | cmd /V:ON /C "set KEY=val & node …" | $env:KEY='val'; node … | keep KEY=val node … |
| 3 | single-quote | escape \"…\" | escape \"…\" (CMD requires it) | keep '…' or escape | keep '…' |
| 4a | unix-cmd (rm -rf) | shx rm -rf folder | rmdir /S /Q folder | Remove-Item -Recurse -Force folder | keep rm -rf folder |
| 4b | unix-cmd (chmod) | shx chmod 755 file (no-op on Win) | no native equivalent — downgrade | no native equivalent — downgrade | keep chmod 755 file |
| 5 | glob-expand | dir (Node 22+) or glob -c "…" "…**" | no fallback — downgrade | no fallback — downgrade | no fallback — downgrade |
| 6 | ps5-ampamp | install PS 7 (manual) | n/a — && works in CMD | PS 5.1: cmd1; if ($?) { cmd2 } | n/a — && works |
Full diffs and edge cases for each category live in references/<topic>.md.
For each affected package.json, fix categories in this order to avoid reflowing already-modified strings:
unix-cmdinline-envsingle-quoteglob-expandRules:
Edit, one targeted edit per script value. No full-file rewrites.npm install --save-dev <pkg> in that package.json's directory, but only for tools not already in dependencies/devDependencies:
inline-env cross-platform → cross-envunix-cmd cross-platform → shxglob-expand option B → globRe-run the scanner with the same path/mode (--root or --file). Categories that were fixed must no longer appear. Residual findings are likely false positives (e.g., sed matched by unix-cmd); present them for manual review.
--shell defaults to cmd (strictest). Invalid values exit with code 64.
Exit codes:
0 success / env allowed2 env not Windows-native, or path not found64 invalid CLI argumentsHuman-readable output format:
JSON output: array of {file, script, category, severity, snippet, fix} (or the env object when --check-env).
examples/cross-env-before-after.jsonexamples/shx-rm-rf-before-after.jsonexamples/shx-chmod-before-after.jsonexamples/single-quotes-before-after.jsonexamples/glob-directory-before-after.jsonexamples/native-deps-flag.jsonshx chmod is a silent no-op on Windows. The Windows file system has no executable bit. If the executable bit is needed for Linux CI/deploy, replace with a Node script using fs.chmodSync guarded by process.platform.@tensorflow/tfjs-node requires Node 24 on Windows. Node 22 is unsupported per troubleshooting/windows/commons.md. Migration: https://nodejs.org/en/blog/migrations/v22-to-v24&& in PS 5.1 is not auto-fixable in package.json. The scanner flags it as info, not error. Do not rewrite && to ; — that would break Unix execution. The PS-locked rewrite (cmd1; if ($?) { cmd2 }) is a fallback only.sed, URLs with single quotes, scripts intentionally Unix-only. The --json snippet field lets the user deselect findings before fixes are applied.cross-env double-wrap guard. The scanner skips values where cross-env appears before the KEY=value token. A chained && cross-env KEY=val node … is recognized as already-handled.package.json becomes tied to that shell — scripts will break on the others. Recommend documenting the chosen shell in the project README.package.json unless the user explicitly chose "per-finding".references/*.md if needed from those environments.script-shell is cmd.exe by default on Windows. Even when the user picks ps5 or ps7 in Step 0b, single-quote and unix-cmd remain error — those failures happen at script runtime (inside cmd.exe spawned by npm run), not in the interactive shell. The only category affected by the shell choice is ps5-ampamp, which becomes silent for cmd and ps7 (where && works natively). A user who has run npm config set script-shell powershell.exe (uncommon) would see different runtime behavior; the skill does not detect this.**