Recently Written · git

ai-config

One canonical AI agent config (rules, skills, MCP servers) rendered into Claude Code, Codex, Copilot CLI and Antigravity by acsync

git clone https://github.com/equwal/ai-config

Log | Files | Refs


skills/powershell/SKILL.md (3738 bytes)

1 ---
2 name: PowerShell
3 slug: powershell
4 version: 1.0.0
5 description: Avoid common PowerShell mistakes — output behavior, array traps, and comparison operator gotchas.
6 homepage: https://clawic.com/skills/powershell
7 metadata:
8   clawdbot:
9     emoji: 🔵
10     requires:
11       bins:
12       - pwsh
13     os:
14     - linux
15     - darwin
16     - win32
17     displayName: PowerShell
18 ---
19 
20 ## Output Behavior
21 - Everything not captured goes to output — even without `return` or `Write-Output`
22 - `return` doesn't stop output — previous uncaptured expressions still output
23 - `Write-Host` bypasses pipeline — use for display only, not data
24 - Assign to `$null` to suppress — `$null = SomeFunction`
25 - `[void]` cast also suppresses — `[void](SomeFunction)`
26 
27 ## Array Gotchas
28 - Single item result is scalar, not array — `@(Get-Item .)` forces array
29 - Empty result is `$null`, not empty array — check with `if ($result)` carefully
30 - Array unrolling in pipeline — `@(1,2,3) | ForEach` sends items one by one
31 - `+=` on array creates new array — slow in loops, use `[System.Collections.ArrayList]`
32 - `,` is array operator — `,$item` wraps single item in array
33 
34 ## Comparison Operators
35 - `-eq`, `-ne`, `-gt`, `-lt` — not `==`, `!=`, `>`, `<`
36 - `-like` with wildcards, `-match` with regex — both return bool
37 - `-contains` for array membership — `$arr -contains $item`, not `$item -in $arr` (though `-in` works too)
38 - Case-insensitive by default — `-ceq`, `-cmatch` for case-sensitive
39 - `$null` on left side — `$null -eq $var` prevents array comparison issues
40 
41 ## String Handling
42 - Double quotes interpolate — `"Hello $name"` expands variable
43 - Single quotes literal — `'$name'` stays as literal text
44 - Subexpression for complex — `"Count: $($arr.Count)"` for properties/methods
45 - Here-strings for multiline — `@" ... "@` or `@' ... '@`
46 - Backtick escapes — `` `n `` for newline, `` `t `` for tab
47 
48 ## Pipeline
49 - `$_` or `$PSItem` is current object — same thing, `$_` more common
50 - `ForEach-Object` for pipeline — `foreach` statement doesn't take pipeline
51 - `-PipelineVariable` saves intermediate — `Get-Service -PV svc | Where ...`
52 - Pipeline processes one at a time — unless function doesn't support streaming
53 
54 ## Error Handling
55 - `$ErrorActionPreference` sets default — `Stop`, `Continue`, `SilentlyContinue`
56 - `-ErrorAction Stop` per command — makes non-terminating errors terminating
57 - `try/catch` only catches terminating — set `ErrorAction Stop` first
58 - `$?` is last command success — `$LASTEXITCODE` for native commands
59 
60 ## Common Mistakes
61 - No space before `{` in `if` — `if($x){` works but `if ($x) {` preferred
62 - `=` is assignment in conditions — use `-eq` for comparison
63 - Function return array unrolls — `return ,@($arr)` to keep array
64 - `Get-Content` returns lines array — `-Raw` for single string
65 - `Select-Object` creates new object — properties are copies, not references
66 
67 ## Claude Code PowerShell tool: delete guard
68 - The tool scans the command text. It blocks the call when the text has a delete word (`rm`, `rmdir`, `Remove-Item`) and a token that looks like a top-level path (`/`, `/home`, `/1KB`). The error is `Remove-Item on system path '<token>' is blocked`.
69 - The guard also reads inside a single-quoted `ssh` string, and it reads a division such as `$sum/1KB` as a path.
70 - Put each delete in its own call, with the full exact path. Keep `cd /`, `df -h /home`, and `/` arithmetic out of that call.
71 
72 ## Cross-Platform
73 - `pwsh` is PowerShell 7+ — `powershell` is Windows PowerShell 5.1
74 - Paths use `/` or `\` — `Join-Path` for portable
75 - Environment vars: `$env:VAR` — works on all platforms
76 - Aliases differ across platforms — `ls`, `cat` may not exist, use full cmdlet names