# How to Use Prompt Templates in earendil pi: A Complete Guide

> Master prompt templates in earendil pi. Learn to use reusable text fragments with variable substitution via placeholders in .prompt.md files. Integrate seamlessly into CLI, TUI, and RPC modes.

- Repository: [Earendil Works/pi](https://github.com/earendil-works/pi)
- Tags: how-to-guide
- Published: 2026-05-25

---

**Prompt templates in earendil pi are reusable text fragments stored in [`.prompt.md`](https://github.com/earendil-works/pi/blob/main/.prompt.md) files that support variable substitution via placeholders like `$1` and `$@`, and can be invoked from the CLI, interactive TUI, or RPC mode.**

Prompt templates are a first-class feature in the `earendil-works/pi` repository that enable you to standardize repetitive LLM interactions. By storing prompt fragments in plain-text files with front-matter metadata, you can invoke complex instructions using simple slash commands or CLI arguments. This guide covers the complete implementation from the `PromptTemplate` interface to the interactive mode integration.

## Understanding the PromptTemplate Architecture

The core implementation resides in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/prompt-templates.ts). This file defines the **PromptTemplate** interface, which describes each template's name, description, source location, and loader-generated diagnostics. The **loadPromptTemplates()** function (lines 194-215) handles the actual file system scanning, parsing front-matter metadata from [`.prompt.md`](https://github.com/earendil-works/pi/blob/main/.prompt.md) files and returning an array of template objects ready for use in the session.

## Creating Your First Prompt Template

### File Structure and Naming Convention

Store templates in directories containing files with the [`.prompt.md`](https://github.com/earendil-works/pi/blob/main/.prompt.md) extension. The loader scans these directories recursively, extracting both the YAML front-matter and the template body.

### Front-Matter Configuration

Each template file begins with YAML front-matter containing three key fields:

- **name**: The command identifier used for invocation (e.g., `pr` becomes `/pr`)
- **description**: Help text displayed in autocomplete and `--help` output
- **argumentHint**: Optional usage hint showing expected parameters

Example template:

```markdown
---
name: pr
description: Generate a pull-request description
argumentHint: "<title> <body>"
---
Write a concise PR description for: $1
Include the following details: $@

```

This file demonstrates variable substitution where `$1` captures the first argument and `$@` expands to all arguments.

## Loading Templates via CLI Configuration

Pass template directories to the engine using the `--prompt-template` flag defined in [`packages/coding-agent/src/cli/args.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/cli/args.ts). You can specify multiple directories by repeating the flag; the loader merges them into a single collection (verified in [`packages/coding-agent/test/args.test.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/test/args.test.ts) lines 204-212).

```bash
pi --prompt-template ~/.pi/prompts --prompt-template ./project-prompts /pr "Fix login bug"

```

To completely disable template loading even if default locations exist, use the `--no-prompt-templates` flag (tested in lines 235-237 of the same test file).

## Placeholder Syntax Reference

The template engine supports sophisticated argument parsing through these placeholders:

- **$1, $2, ...**: Positional arguments corresponding to the nth word after the template name
- **$@**: All arguments joined by spaces
- **$ARGUMENTS**: Alias for `$@` provided for readability in documentation
- **${@:N:M}**: Slice syntax extracting M arguments starting at position N (1-based)
- **${:N}**: First N arguments only
- **${N:}**: Drop first N arguments, keep the remainder

The parser handles multi-line templates where the command name and body are separated by blank lines, as verified in [`packages/coding-agent/test/prompt-templates.test.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/test/prompt-templates.test.ts).

## Invoking Templates Across Interface Modes

### Command-Line Execution

Invoke templates directly from the terminal using the slash-command syntax:

```bash
pi /pr "Add authentication" "Closes #123, implements OAuth"

```

The engine expands placeholders with provided arguments and sends the resulting prompt to the configured LLM provider.

### Interactive Mode Integration

When running `pi` without arguments, the interactive TUI converts each loaded template into a slash-command (`/template-name`). The implementation in [`packages/coding-agent/src/modes/interactive/interactive-mode.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/modes/interactive/interactive-mode.ts) (lines 486-519) maps template names to autocomplete entries, displaying the description from front-matter during tab completion.

### RPC Mode for Remote Clients

In RPC mode, the server publishes the template list to remote clients, enabling execution via the same `/template-name` syntax over the wire. This functionality is implemented in [`packages/coding-agent/src/modes/rpc/rpc-mode.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/modes/rpc/rpc-mode.ts) (lines 644-649).

## Programmatic Usage

Import **loadPromptTemplates** directly for custom tooling:

```typescript
import { loadPromptTemplates } from "./core/prompt-templates.ts";

const env = process.env;
const dirs = ["./my-prompts", "./shared-prompts"];
const templates = loadPromptTemplates(env, dirs);
// Returns array of PromptTemplate objects for session integration

```

## Summary

- Store reusable prompts in [`.prompt.md`](https://github.com/earendil-works/pi/blob/main/.prompt.md) files with YAML front-matter containing **name**, **description**, and optional **argumentHint**
- Use `--prompt-template` to specify directories and `--no-prompt-templates` to disable loading
- Reference positional arguments with **$1**, **$2**, or all arguments with **$@** and slice syntax **${@:N:M}**
- Access templates as slash-commands in interactive mode (lines 486-519 of interactive-mode.ts) or via RPC (lines 644-649 of rpc-mode.ts)
- The core loader and `PromptTemplate` interface reside in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/prompt-templates.ts)

## Frequently Asked Questions

### What file extension do prompt templates use in earendil pi?

Prompt templates use the [`.prompt.md`](https://github.com/earendil-works/pi/blob/main/.prompt.md) extension. The `loadPromptTemplates()` function specifically scans for these files, parsing their YAML front-matter and markdown bodies according to the implementation in [`packages/coding-agent/src/core/prompt-templates.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/prompt-templates.ts).

### How do I pass multiple arguments to a prompt template?

Use `$@` to capture all arguments or `$1`, `$2` for specific positions. For advanced slicing, use `${@:N:M}` to extract M arguments starting at position N. These placeholders are substituted before the prompt reaches the LLM provider.

### Can I disable prompt templates completely?

Yes. Pass the `--no-prompt-templates` flag to prevent the engine from loading any templates, even from default locations. This is parsed in [`packages/coding-agent/src/cli/args.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/cli/args.ts) and verified in the test suite at lines 235-237.

### Where does the interactive mode load template commands from?

The interactive mode loads templates from the same directories specified via `--prompt-template` flags. In [`packages/coding-agent/src/modes/interactive/interactive-mode.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/modes/interactive/interactive-mode.ts) (lines 486-519), each template is converted to a slash-command with autocomplete support using the metadata defined in the template's front-matter.