pmp is a CLI-first prompt builder for assembling reusable LLM prompts from Markdown blocks.
It supports:
- fast prompt assembly through
pmp --preset ... - project-local overrides through
./.pmp/ - interactive composition through
pmp ui - output to clipboard, stdout, file, or JSON
flowchart TB
subgraph CLI["CLI Layer (cli/)"]
direction LR
BUILD["build"]
UI["ui"]
INIT["init"]
LIST["list"]
DOCTOR["doctor"]
end
subgraph Core["Core Packages (internal/)"]
CONFIG["config<br/>Two-tier config resolution<br/>project .pmp/ + global ~/.pmp/"]
BLOCK["block<br/>Markdown parser<br/>YAML front matter"]
ENGINE["engine<br/>Block assembly + ordering<br/>Template rendering<br/>Token counting (cl100k_base)"]
OUTPUT["output<br/>clipboard / stdout<br/>file / JSON"]
INTERACTIVE["interactive<br/>BubbleTea TUI<br/>4-step flow"]
TEMPLATES["templates<br/>Embedded starter files<br/>Scaffold for init"]
end
BUILD --> CONFIG
BUILD --> ENGINE
BUILD --> OUTPUT
UI --> INTERACTIVE
INTERACTIVE --> ENGINE
INTERACTIVE --> OUTPUT
INIT --> TEMPLATES
LIST --> CONFIG
DOCTOR --> CONFIG
CONFIG --> BLOCK
ENGINE --> BLOCK
ENGINE --> CONFIG
flowchart LR
A["pmp --preset feature -m 'Add profiles'"] --> B["Load Config"]
B --> C["Resolve Blocks"]
C --> D["Assemble Prompt"]
D --> E["Count Tokens"]
E --> F{Output}
F -->|default| G["Clipboard"]
F -->|--no-copy| H["Stdout"]
F -->|--out file| I["File"]
F -->|--json| J["JSON"]
subgraph "Assemble Prompt"
D1["Base blocks<br/>(always_include)"]
D2["Preset blocks"]
D3["Extra blocks<br/>(--block flag)"]
D4["User message<br/>(--message flag)"]
end
D1 --> D2 --> D3 --> D4
The prompt is assembled by concatenating blocks in order: base -> preset -> extra -> message.
Message position is configurable via message_position (top or bottom, default: bottom).
go install github.com/singl3focus/pmp/cmd/pmp@latestThis installs the latest release into your $GOPATH/bin.
Pre-built binaries are available for Linux, macOS, and Windows (amd64 + arm64):
- Go to Releases
- Download the archive for your platform
- Extract and move
pmp(orpmp.exe) to a directory in yourPATH
git clone https://github.com/singl3focus/pmp.git
cd pmp
make build VERSION=0.1.0Or without Make:
go build ./cmd/pmpOn Windows this produces pmp.exe.
Initialize a project-local setup:
pmp initBuild a prompt from a preset:
pmp --preset feature -m "Add user profiles to product cards"Build to a file:
pmp --preset review -m "Review auth flow" --out prompt.mdPreview the resolved plan without emitting output:
pmp --preset feature -m "Add CSV export" --dry-runLaunch the interactive builder:
pmp uiPrimary path:
pmp --preset <name> -m "<task>"Short alias:
pmp -p <name> -m "<task>"Explicit form is also supported:
pmp build --preset <name> -m "<task>"Other commands:
pmp init
pmp init --global
pmp list
pmp doctor
pmp version
pmp ui
pmp version prints:
version: 0.1.0
commit: abc1234
date: 2026-04-02T12:00:00Z
pmp supports two configuration roots:
./.pmp/~/.pmp/
Resolution order:
- project-local config overrides global config
- project-local blocks override global blocks by relative path
Example project-local layout:
./.pmp/
config.yaml
base/
global.md
blocks/
intro/
communication/
tools/
tasks/
version: 1
separator: "\n\n"
copy_by_default: true
token_warning_threshold: 24000
message_position: bottom # "top" or "bottom" (default: "bottom")
base:
always_include:
- global.md
presets:
feature:
description: "New feature implementation"
blocks:
- intro/senior-dev.md
- communication/concise.md
- tools/dev-tools.md
- tasks/feature.md| Field | Type | Default | Description |
|---|---|---|---|
version |
int | 1 |
Config schema version |
separator |
string | "\n\n" |
Separator between prompt parts |
copy_by_default |
bool | true |
Copy result to clipboard automatically |
token_warning_threshold |
int | 24000 |
Warn when token count exceeds this |
message_position |
string | "bottom" |
Where to place the user message: "top" or "bottom" |
Blocks are Markdown files with optional YAML front matter:
---
title: Senior Developer
description: Senior engineering persona
tags: [engineering, coding]
weight: 10
---
You are a senior software engineer. Favor clear reasoning, practical tradeoffs, and production-grade output.Current pmp ui flow:
- choose a preset
- filter and toggle extra blocks
- enter the task message
- choose output target
Useful keys:
up/down: moveenter: continue or confirmspace: toggle extra block/: start block filterctrl+s: save current configuration as a presetpgup/pgdown: scroll previewesc: go backctrl+c: quit
Run:
go test ./...
go build ./cmd/pmpOr with the local release helpers:
make fmt
make test
make build VERSION=devLocal snapshot build with GoReleaser:
make snapshotGitHub release flow:
- push a tag like
v0.1.0 - GitHub Actions runs
.github/workflows/release.yml - GoReleaser builds archives and publishes the GitHub release
CI flow:
.github/workflows/ci.ymlruns on pushes and pull requests- validates
go mod tidy,go test ./..., andgo build ./cmd/pmp
- the TUI is functional but still intentionally lightweight
- preview scrolling is basic offset-based scrolling, not a rich viewport yet
- there is no separate editor integration yet