Executes bash command in shell session for terminal operations like git, bun, cargo, python.

<instruction>
- You **MUST** use `cwd` parameter to set working directory instead of `cd dir && …`
- Every call starts in the session working directory, or in `cwd` when provided. A `cd` affects only
  that call and does not relocate later tool calls.
- Always provide a `description` parameter: a short, human-readable summary of what the command does (e.g. "Install dependencies", "Run test suite"). This is displayed in compact mode and during execution.
- Prefer `env: { NAME: "…" }` for multiline, quote-heavy, or untrusted values instead of inlining them into shell syntax; reference them from the command as `$NAME`
- Quote variable expansions like `"$NAME"` to preserve exact content and avoid shell parsing bugs
- PTY mode is opt-in: set `pty: true` only when command expects a real terminal (for example `sudo`, `ssh` where you need input from the user); default is `false`
- You **MUST** use `;` only when later commands should run regardless of earlier failures
- Whole-word internal URLs are auto-resolved to filesystem paths before execution
  - Set `expand_urls: false` when a whole-word internal URL must reach the command literally; command text is then left byte-for-byte unchanged
  - `python skill://my-skill/scripts/init.py` runs the script from the skill directory
  - `skill://<name>/<relative-path>` resolves within the skill's base directory
  - The default is `expand_urls: true`
{{#if asyncEnabled}}
- Use `async: true` for long-running commands when you don't need immediate output; the call returns a background job ID and the result is delivered automatically as a follow-up.
{{/if}}
{{#if autoBackgroundEnabled}}
- Long-running non-PTY bash commands may auto-background after about {{autoBackgroundThresholdSeconds}}s and continue as background jobs automatically.
{{/if}}
{{#if asyncEnabled}}
{{else}}
{{#if autoBackgroundEnabled}}
- Auto-backgrounded jobs use the same background-job pipeline as explicit async execution.
{{/if}}
{{/if}}
{{#if asyncEnabled}}
- Use `read jobs://` to inspect all background jobs and `read jobs://<job-id>` for detailed status/output when needed.
- When you need to wait for async results before continuing, call `poll` — it blocks until jobs complete. Do NOT poll `read jobs://` in a loop or yield and hope for delivery.
{{else}}
{{#if autoBackgroundEnabled}}
- If a command auto-backgrounds, use `read jobs://` to inspect jobs and `poll` when you need to wait for completion instead of polling in a loop.
{{/if}}
{{/if}}
</instruction>

<output>
Returns the output, and an exit code from command execution.
- If output truncated, full output can be retrieved from `artifact://<id>`, linked in metadata
- Exit codes shown on non-zero exit
</output>

<critical>
You **MUST** use specialized tools instead of bash for ALL file operations:

|Instead of (WRONG)|Use (CORRECT)|
|---|---|
|`cat file`, `head -n N file`|`read(path="file", limit=N)`|
|`cat -n file \|sed -n '50,150p'`|`read(path="file", offset=50, limit=100)`|
<!-- markdownlint-disable MD055 MD056 -→
{{#if hasGrep}}|`grep -A 20 'pat' file`|`grep(pattern="pat", path="file", post=20)`|
|`grep -rn 'pat' dir/`|`grep(pattern="pat", path="dir/")`|
|`rg 'pattern' dir/`|`grep(pattern="pattern", path="dir/")`|{{/if}}
{{#if hasFind}}|`find dir -name '*.ts'`|`find(pattern="dir/**/*.ts")`|{{/if}}
<!-- markdownlint-enable MD055 MD056 -→
|`ls dir/`|`read(path="dir/")`|
|`cat <<'EOF' > file`|`write(path="file", content="…")`|
|`sed -i 's/old/new/' file`|`edit(path="file", edits=[…])`|

<!-- markdownlint-disable MD055 MD056 -→
{{#if hasAstEdit}}|`sed -i 's/oldFn(/newFn(/' src/*.ts`|`ast_edit({ops:[{pat:"oldFn($$$A)", out:"newFn($$$A)"}], path:"src/"})`|{{/if}}
<!-- markdownlint-enable MD055 MD056 -→
{{#if hasAstGrep}}- You **MUST** use `ast_grep` for structural code search instead of bash `grep`/`awk`/`perl` pipelines{{/if}}
{{#if hasAstEdit}}- You **MUST** use `ast_edit` for structural rewrites instead of bash `sed`/`awk`/`perl` pipelines{{/if}}
- You **MUST NOT** use Bash for these operations like read, grep, find, edit, write, where specialized tools exist.
- You **MUST NOT** use `2>&1` | `2>/dev/null` pattern, stdout and stderr are already merged.
- You **MUST NOT** use `| head -n 50` or `| tail -n 100` pattern, use `head` and `tail` parameters instead.
</critical>
