agentsclimarketplace

Shell portability

Skill Evan-Daruwalla/claude-skill-suite/shell-portability

Read-only SYNTAX/semantics scanner for cross-shell traps in shell scripts — the proactive counterpart to your own reactive troubleshooting runbook. Flags, with file:line + why it breaks + the PowerShell-5.1-safe fix: in .ps1/.psm1, the && / || pipeline chain (PS 5.1 parser error), ?: ternary, ?. null-conditional and ?? / ??= null-coalescing (PS7-only), Read-Host / pause / Out-GridView (block a non-interactive or scheduled run), Set-Content / Add-Content / Out-File written WITHOUT -Encoding (ANSI/UTF-16 default corrupts UTF-8), and bash-style NAME=value assignments; in .sh/.bash, PowerShell-isms ($env:NAME, Verb-Noun cmdlet calls). Use when the user says "shell-portability", "scan for PS5.1 traps", "will this script run on PowerShell 5.1", "check my .ps1 for portability", "lint my shell scripts", or before shipping a script to the scheduled-task / CI path. Encoding and filename quirks belong to path-quirk-audit; this is syntax only. Deterministic, zero dependencies, no model calls.From its SKILL.md

Install
npx -y skills add Evan-Daruwalla/claude-skill-suite --skill shell-portability

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.7 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it

shell-portability — cross-shell syntax trap scanner

The engine is shell-portability.js (portable Node, zero deps). It is the proactive counterpart to a reactive shell-troubleshooting runbook (that runbook diagnoses a script that already broke; this scans the source and flags the same documented traps before they reach the shell) — with file:line, why it breaks on a Windows machine, and the PowerShell-5.1-safe alternative. Read-only; it never writes outside its own canary temp dir.

Scope is syntax and semantics only. Encoding and filename quirks (non-ASCII bytes that corrupt a .bat parse, UTF-16 BOMs, builtin-shadowing stray files) are path-quirk-audit's job — this scanner deliberately does not duplicate them, and it skips .bat files entirely.

What it flags

.ps1 / .psm1 — the target here is PowerShell 5.1 (the common Windows default, not PS7):

TrapWhy it breaksPS5.1-safe fix
&& / ||no pipeline-chain operators — parser errorA; if ($?) { B } / A; if (-not $?) { B }
?: ternaryPS7-onlyif/else
?. / ?[]null-conditional, PS7-onlyguard with if ($null -ne $x)
?? / ??=null-coalescing, PS7-onlyif ($null -eq $x) { ... }
Read-Host / pause / Out-GridViewblock a non-interactive / scheduled runtake input as a param / env / file
Set-Content/Add-Content/Out-File w/o -EncodingANSI/UTF-16 default corrupts UTF-8 for the next readeradd -Encoding utf8
bash-style NAME=value / export NAME=valuePS can't assign to a bareword; export isn't a cmdlet$name = value / $env:NAME = 'value'

.sh / .bash — PowerShell-isms leaking into a POSIX script:

TrapWhy it breaksPOSIX fix
$env:NAMEbash has no $env: namespace$NAME / ${NAME}, set with export
Verb-Noun cmdlet (Get-ChildItem, Set-Content, ...)PowerShell cmdlet, not a bash commandPOSIX equivalent (ls/find, printf > file)

Commands

node shell-portability.js scan <path> [<path>...]
node shell-portability.js --canary
node shell-portability.js --help
  • scan recurses any files or directories given (skips .git, node_modules, .golden, graphify-out), reads every .ps1/.psm1/.sh/.bash file, and prints one block per finding:

    path\to\deploy.ps1:12: [chain-and-or] PS 5.1 has no && / || pipeline-chain operators (parser error)
        fix: A; if ($?) { B }  (and)   /   A; if (-not $?) { B }  (or)
        > git pull && npm run build
    

    Exit 1 if anything is flagged, 0 if clean.

Suppression

A trailing # portability-ok comment silences every finding on that line — use it for a deliberate exception (e.g. a string that merely contains &&, or a script that is PS7-only on purpose):

$result = git pull && git push   # portability-ok  (PS7 CI runner only)

Examples

  • Guard a scheduled job's script before it ships (a monthly rebalance job runs as a Windows scheduled task — a Read-Host or a && would hang or parser-error unattended): node shell-portability.js scan /path/to/scripts — catches any interactive prompt or PS7-ism before the scheduled run hits it.
  • Check a helper .ps1 writes UTF-8 for the next tool (Set-Content's ANSI default is a well-known trap): the scanner flags every Set-Content/Out-File missing -Encoding utf8.
  • Scan a .sh you cross-wrote in a PowerShell headspace: catches a stray $env:PATH or Get-ChildItem before it silently does nothing under bash.

Windows notes

  • PowerShell 5.1 lacks &&, ||, ternary, ?., and ?? — this scanner exists because those keep leaking in from PS7 / bash habits.
  • Backtick line-continuations are joined into one logical line, so an -Encoding flag on the following line still counts. <# ... #> block comments and whole-line # comments are not scanned.
  • .bat files are out of scope — their traps are byte/parse-level, which is path-quirk-audit's domain.

Storage / exit codes

Read-only — writes nothing except inside a throwaway temp dir during --canary.

0 clean · 1 findings or canary failure · 2 usage error.

Verification (the done-check)

node shell-portability.js --canary

Self-tests both directions in a throwaway temp dir: the documented traps are CAUGHT (a bad .ps1 with && + a ternary + an unencoded Set-Content yields exactly 3 findings; ??, ?., Read-Host, bash-assign, and a bad .sh each caught) AND clean PS5.1-safe / POSIX code stays quiet (0 findings), plus the # portability-ok suppression and an end-to-end directory walk. MUST print CANARY PASS 10/10 before you trust a result.

What ships with it: 1 file

13.7 KB alongside SKILL.md, 1 of them executable

Gives 0 of the 12 instructions most quality gates skills give in ~1.4k tokens

Counted across 1,195 of the 2,094 authors here whose files we hold, read 2026-08-07

  • Read the output and check the exit codein 54 of 1195, across 14 files
  • Verify requirements using a line-by-line checklistin 53 of 1195, across 12 files
  • Identify the verification command proving the claimin 51 of 1195, across 12 files
  • Run the full verification commandin 50 of 1195, across 11 files
  • Verify output confirms the claimin 49 of 1195, across 12 files
  • Check version control diff after agent delegationin 46 of 1195, across 6 files
  • State claim with evidencein 44 of 1195, across 4 files
  • Run the test suitein 33 of 1195, across 26 files
  • Keep state in memory by defaultin 27 of 1195, across 6 files
  • Make prototype runnable with one commandin 26 of 1195, across 5 files
  • Produce a verification reportin 25 of 1195, across 14 files
  • Detect the package manager from lockfilesin 24 of 1195, across 5 files

Said here and by no other author read

  • scan given paths to detect cross-shell syntax traps
  • print file, line, break reason, and safe fix for each finding
  • exit with code one if any finding is flagged
  • exit with code zero if the scan is clean
  • suppress findings on lines with a trailing portability-ok comment
  • skip bat files entirely

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,851. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.