# How to Use Prompt Templates in pi-ai: A Complete Guide to Reusable Markdown Snippets

> Master prompt templates in pi-ai. Learn to store reusable Markdown snippets with arguments and Bash-style slicing for efficient AI prompting. Explore this complete guide.

- Repository: [Mario Zechner/pi-mono](https://github.com/badlogic/pi-mono)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Prompt templates in pi-ai let you store reusable prompt snippets in Markdown files and expand them on-the-fly using positional arguments and Bash-style slicing syntax.**

The pi-ai coding agent, part of the `badlogic/pi-mono` repository, implements a powerful templating system that transforms how you interact with AI-assisted development. By defining prompt templates in Markdown files with YAML frontmatter, you can create reusable command shortcuts that expand into full prompts with dynamic argument substitution.

## What Are Prompt Templates in pi-ai?

Prompt templates are Markdown files containing reusable prompt text and metadata. The system discovers these files across multiple locations, parses their frontmatter, and makes them available as slash commands within the Pi coding agent. When you type `/template-name arg1 arg2`, the system expands the template by substituting arguments into placeholders like `$1`, `$2`, or `$@`.

According to the source code in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts), the system handles five distinct phases: discovery, loading, argument parsing, placeholder substitution, and expansion.

## How Prompt Template Discovery Works

The pi-ai agent scans multiple locations to find template files, ensuring both global and project-specific customization. As implemented in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts) (lines 21-30), discovery occurs in the following order:

1. **Global directory**: `~/.pi/agent/prompts` for system-wide templates
2. **Project directory**: `.pi/prompts` within the current working directory
3. **Package directories**: `prompts/` folders inside individual packages
4. **Package.json entries**: Paths specified in the `prompts` array of [`package.json`](https://github.com/badlogic/pi-mono/blob/main/package.json)
5. **CLI arguments**: Additional paths passed via the `--prompt-template` flag

Each discovered `.md` file undergoes parsing where frontmatter is extracted using [`packages/coding-agent/src/utils/frontmatter.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/utils/frontmatter.ts), and the first non-empty line becomes the description if none is specified in the frontmatter.

## Creating Your First Prompt Template

### Basic Template Structure

A prompt template is a Markdown file with optional YAML frontmatter followed by the prompt text. Create a file at `~/.pi/agent/prompts/review.md`:

```markdown
---
description: Review staged git changes
---
Review the staged changes (`git diff --cached`). Look for:
- Bugs and logic errors
- Security issues
- Missing error handling

```

The `description` field appears in the agent's command suggestions. If omitted, the system uses the first non-empty line of the file as the description.

### Using Positional Arguments

Templates become powerful when you incorporate dynamic arguments using `$1`, `$2`, etc., or `$@` for all arguments. Create `~/.pi/agent/prompts/component.md`:

```markdown
---
description: Create a React component
---
Create a React component named $1 with the following features: $@

```

When you invoke `/component Button "click handler" "disabled support"`, the `expandPromptTemplate` function in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts) (lines 82-99) processes the substitution:

- `$1` becomes `Button`
- `$@` becomes `click handler disabled support`

The `parseCommandArgs` function handles quote-respecting argument splitting, ensuring multi-word arguments in quotes remain intact.

### Advanced Slicing with Bash-Style Syntax

For complex argument manipulation, pi-ai supports Bash-style array slicing. The `substituteArgs` function in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts) (lines 55-99) implements:

- `${@:N}` - Slice from position N to end
- `${@:N:L}` - Slice from position N with length L

Create a template using slicing:

```markdown
---
description: List items
---
Items: ${@:2}

```

Invocation `/list first second third fourth` produces:

```

Items: second third fourth

```

This syntax allows you to skip command names or specific arguments while passing the remainder to the prompt.

## Loading and Expanding Templates Programmatically

While the Pi agent handles expansion automatically, you can interact with the template system directly using the public API exported from [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts).

### Loading Templates

Use `loadPromptTemplates` to discover and parse templates from all configured locations:

```typescript
import {
  loadPromptTemplates,
  expandPromptTemplate,
  PromptTemplate,
} from "@mariozechner/pi-coding-agent";

// Load all available templates (defaults + CLI-specified paths)
const templates: PromptTemplate[] = loadPromptTemplates({
  cwd: process.cwd(),          // Project root for .pi/prompts discovery
  agentDir: undefined,         // Defaults to ~/.pi/agent
  promptPaths: ["./my-templates"], // Extra folders/files
  includeDefaults: true,       // Enable global & project discovery
});

```

The function returns an array of `PromptTemplate` objects containing the parsed frontmatter, file path, and template content.

### Expanding Templates Manually

Call `expandPromptTemplate` to process a command string against loaded templates:

```typescript
const raw = "/component Button \"onClick\" disabled";
const expanded = expandPromptTemplate(raw, templates);
console.log(expanded);
// Output: Create a React component named Button with the following features: onClick disabled

```

If the input doesn't match any template name (doesn't start with `/` or matches no template), the function returns the text unchanged.

## CLI Options for Prompt Templates

The Pi coding agent exposes template configuration through command-line arguments defined in [`packages/coding-agent/src/cli/args.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/cli/args.ts).

### Disabling Default Discovery

To run the agent without loading any default templates:

```bash
pi --no-prompt-templates

```

This skips scanning of `~/.pi/agent/prompts`, `.pi/prompts`, and package directories.

### Loading Specific Templates

To load additional template files or directories beyond the defaults:

```bash
pi --prompt-template ./my-custom-template.md
pi --prompt-template ./templates-folder/

```

You can specify this flag multiple times to load from multiple sources.

## Summary

Prompt templates in pi-ai transform repetitive prompt engineering into reusable, parameterized commands. Key takeaways include:

- **Markdown-based**: Templates are standard `.md` files with YAML frontmatter stored in `~/.pi/agent/prompts` or project `.pi/prompts` directories.
- **Argument substitution**: Use `$1`, `$2`, and `$@` for positional arguments, with Bash-style slicing `${@:N}` and `${@:N:L}` for advanced manipulation.
- **Programmatic API**: Import `loadPromptTemplates` and `expandPromptTemplate` from `@mariozechner/pi-coding-agent` to build custom tooling.
- **CLI flexibility**: Control template loading with `--prompt-template` to add sources or `--no-prompt-templates` to disable defaults.

## Frequently Asked Questions

### How do I create a global prompt template available across all projects?

Place your Markdown template file in the `~/.pi/agent/prompts/` directory. The Pi coding agent automatically discovers this location during startup according to the discovery logic in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts). Ensure your file has a `.md` extension and optionally include YAML frontmatter with a `description` field.

### What is the difference between `$@` and `$ARGUMENTS` in templates?

Both `$@` and `$ARGUMENTS` expand to all arguments passed to the template after the command name. The `substituteArgs` function in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts) treats these as aliases, replacing either placeholder with the space-joined list of all arguments. Use whichever syntax feels more natural—`$@` for Bash familiarity or `$ARGUMENTS` for explicit readability.

### Can I use prompt templates without the Pi coding agent CLI?

Yes. The template system is exposed as a programmatic API through `@mariozechner/pi-coding-agent`. Import `loadPromptTemplates` to discover and parse template files, then use `expandPromptTemplate` to process command strings. This allows you to build custom tools, testing suites, or integrations that leverage the same template expansion logic without invoking the full agent.

### How do I handle arguments that contain spaces or quotes?

Wrap arguments containing spaces in double quotes when invoking templates (e.g., `/template "argument with spaces"`). The `parseCommandArgs` function in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/prompt-templates.ts) respects quoted strings, ensuring they are treated as single arguments during substitution. If you need literal quotes inside arguments, escape them according to your shell's requirements before the Pi agent parses the command.