Dynamic shell interpolation for pi skills. Embed !command`` in your SKILL.md and the output replaces the placeholder before the model sees it.
Compatible with Claude Code's skill interpolation syntax.
---
name: pr-summary
description: Summarize changes in a pull request
allowed-tools: Bash(git:*) Bash(gh:*)
---
- PR diff: !`gh pr diff`
- Changed files: !`gh pr diff --name-only`
- Current branch: !`git branch --show-current`When you invoke /skill:pr-summary, the extension executes each !command`` and the model sees:
- PR diff: <actual diff output>
- Changed files: src/index.ts\nsrc/utils.ts
- Current branch: feat/my-feature
Interpolation only runs when the skill declares allowed-tools with a Bash permission in its frontmatter. Without it, !command`` patterns pass through as literal text.
# These enable interpolation:
allowed-tools: Bash
allowed-tools: Bash(git:*) Bash(gh:*)
allowed-tools: Read Bash(echo:*)
# These do NOT enable interpolation:
allowed-tools: Read Write
# (or no allowed-tools at all)This follows the Agent Skills spec allowed-tools field. Same trust model as npm postinstall scripts: you opt in per-skill.
pi install git:github.com/joelhooks/pi-skill-interpolationOr clone and symlink:
git clone git@github.com:joelhooks/pi-skill-interpolation.git ~/Code/joelhooks/pi-skill-interpolation
ln -sfn ~/Code/joelhooks/pi-skill-interpolation ~/.pi/agent/extensions/skill-interpolationTwo extension hooks, no core changes:
input hook - Intercepts /skill:name before pi's built-in expansion. Finds the skill file, checks allowed-tools for Bash, interpolates !command`` patterns, and returns the expanded <skill> block. Falls through to pi's normal expansion when there's nothing to interpolate.
tool_result hook on read - When the model reads a SKILL.md via the read tool (on-demand from the system prompt skill list), checks for !command`` patterns and allowed-tools, interpolates in the result content.
- Commands run in the skill's directory (where SKILL.md lives)
- 10-second timeout per command
- Failed commands produce an inline error:
[error: \command` failed: ...]` - Regular backticks (
`not interpolated`) are unaffected - No-op when
allowed-toolsis absent or doesn't include Bash