This machine, and especially this user, has near up-to-date pwsh v7 installed; it should be the shell that you do most work in, not cmd or git bash.
There are common utilities like locally cargo install built ripgrep available; but don't impromptedly install new ones globally, no matter user scoped or machine scoped. But you can update existing tools, just make sure that you acknowledge/notify the user when you do it.
The user has a complex pwsh profile. When you don't expect to find it necessary, start pwsh with -nop -noni -nol; helps you to avoid a lot of churn.
Prefer Python for complex or stateful tasks.
For a persistent session, start it with interactive=True, then reuse the same tool with task_id= to send input and read output in one step. Use wait_for_pattern to wait for a prompt. TaskOutput remains available as a fallback for listing/monitoring tasks. Send 'exit' to close the session.
PowerShell quick reference:
- Cmdlets use Verb-Noun names: Get-ChildItem (list files), Get-Content (read file), Set-Location (cd), Copy-Item, Move-Item, Remove-Item, New-Item, Select-String (grep), Get-Command, Get-Help.
- Splat cmdlet params with
@{}:$p = @{LiteralPath=$f; Destination=$d}; Copy-Item @p.$LASTEXITCODEis for native commands only, not cmdlet success. - The pipeline
|passes .NET objects, not plain text; shape with Where-Object, Select-Object, ForEach-Object, Sort-Object, Measure-Object. -
foreach (...) { }is a statement, not an expression — cannot be piped directly. Assign first or useForEach-Object. - Comparison operators: -eq -ne -gt -ge -lt -le, -like (wildcard), -match (regex), -contains (collection membership), -replace (regex replace). Logical operators: -and -or -not (or
!). - Chain commands with
;(always run next) or&&/||(PowerShell 7+: run next only on success / only on failure). - Strings: 'single quotes' literal; "double quotes" expand
$variables and $ (subexpressions). Use${name}_suffixfor variable boundaries,$($obj.prop)for properties. Avoid Bash-style"\"q\""; use'"q"'or backtick-escaping. - Here-strings:
@'...'@(literal) or@"..."@(expanded). Opening delimiter last on line; closing delimiter alone at line start. No Bash heredocs (python - <<'PY'). PreferConvertTo-Jsonover manual JSON escaping. - Native arguments:
& $exe @argList. Don't use$args(automatic variable). Omitted arg''$nullare distinct. Capture$LASTEXITCODEimmediately. - Avoid backtick continuation
`; trailing space silently breaks. Use@()arrays or natural breaks after pipes/commas/operators. - Avoid
--%(Stop-Parsing); it disables parsing. Use only for fixed literal native commands. - Environment variables: Use
$env:NAMEfor session-scoped read/write. Use[Environment]::SetEnvironmentVariable('NAME', 'value', 'Scope')for persistence. Resolution priority: Process > User > Machine. List withGet-ChildItem Env:. Append PATH with$env:PATH += ';new\path'— never overwrite, check for duplicates first. Do not use%NAME%inside PowerShell. Child process changes do not propagate back to parent. -
$LASTEXITCODE holds the exit code of the last native command; $ ? is $true if the last command succeeded. Note: $LASTEXITCODE may not be set if native output is piped to a cmdlet; capture it before piping. - Parameter value expressions must be parenthesized:
-Index (100..120)not-Index 100..120.