Skip to main content

promptctl CLI

promptctl manages prompts stored as *.prompt files in a git repository. It validates prompts before they're committed, runs the semantic diff between git revisions, promotes prompts between branches, and publishes them to a Priompt server.

promptctl commit|diff|log|promote|push|pull|publish [args]

Run promptctl from the root of the repository. It finds every *.prompt file under the current directory, and the file's path becomes its address: acme/support/agent.prompt is priompt://acme/support/agent. The first directory is the org, so a .prompt file at the root is invalid.

Slots come from the template: every {name} is a slot. promptctl has no -slot flag.

Commands​

CommandDescription
commitValidate every prompt, then commit all changes in the working tree.
diffSemantic diff of every changed prompt against a git revision.
logList the commits that touched one prompt.
promoteCopy one prompt from one branch to another and commit it there.
pushValidate, push to the git remote, and optionally publish to a server.
pullPull from the git remote.
publishPublish prompts to a server without touching git.

Exit codes​

  • 0: Success. diff without -fail-on exits 0 whatever the verdicts are.
  • 1: The command failed, or diff -fail-on matched a verdict. The reason is on stderr, for example 2 invalid prompt(s); nothing committed.
  • 2: Unknown command, a flag that isn't defined, or an unknown verdict name in -fail-on.

To block a structural change in CI, run promptctl diff -fail-on structural. See Gate prompt changes in CI.

Environment​

Env varRead byDescription
PRIOMPT_TOKENpush, publishBearer token sent to the server. Needs write access.
PRIOMPT_GIT_TOKENpush, pullPassword for an HTTPS remote. SSH remotes use the running ssh-agent.
PRIOMPT_EMBED_URL, PRIOMPT_EMBED_MODEL, PRIOMPT_EMBED_KEYdiffEmbedding endpoint for the semantic diff. Without a URL, diff uses the offline lexical embedder.

promptctl doesn't read PRIOMPT_URL. Pass the server address with -server.

commit​

Validates every *.prompt file in the working tree, then stages all changes and commits them. One invalid prompt blocks the whole commit. The author comes from the repository's git config.

promptctl commit -m <message>
FlagEnv varDefaultDescription
-mCommit message. Required.

Example

promptctl commit -m "add support agent"
Output
committed d9643f658d3c

With invalid prompts, each one is listed and nothing is committed:

Output
invalid acme/support/bad.prompt: template uses doubled braces near "{{name}}\n": slots are written {name}; {{name}} is an escaped literal brace to a formatter, not a slot
invalid root.prompt: uri has an org but no prompt path
2 invalid prompt(s); nothing committed

For every validation message, see Errors.

diff​

Runs the semantic diff for every *.prompt file that differs between a git revision and the working tree, including added and deleted files.

promptctl diff [-fail-on <verdicts>] [<revision>]

<revision> is any git revision: a branch, a tag, a commit hash, or HEAD~1. The default is HEAD.

FlagEnv varDefaultDescription
-fail-onComma-separated verdicts that make diff exit 1: new, structural, tweak (localized tweak), minor (minor edit). Empty never fails.

A prompt that doesn't exist in <revision> prints new prompt (not in <revision>) and the verdict new.

Example

promptctl diff
Output
## acme/support/agent.prompt
change @ new lines 2-2 (old 2-2): replace
Signal 2 (point delta): 0.329
Signal 3 up: ±2=0.114 (boundary)
Signal 3 down: ±2=0.134 (boundary)
=> localized tweak

With no changes, it prints no prompt changes vs HEAD. An unknown revision prints unknown ref "<revision>": reference not found and exits 1.

With -fail-on, a match prints the matching prompts on stderr after the diff and exits 1:

promptctl diff -fail-on structural main
Output
## acme/support/agent.prompt
change @ new lines 4-4 (old 4-4): replace
Signal 2 (point delta): 0.908
Signal 3 up: ±2=0.369 ±4=0.254 (boundary)
Signal 3 down: ±2=0.494 (boundary)
=> structural

## acme/support/greeting.prompt
new prompt (not in main)
=> new

2026/10/19 01:03:58 diff: 1 prompt(s) match -fail-on structural: acme/support/agent.prompt (structural)

log​

Lists the commits that touched one prompt file, newest first, as a short hash and the first line of the message.

promptctl log <file.prompt>

Example

promptctl log acme/support/agent.prompt
Output
2b638773 cover refunds
d9643f65 add support agent

promote​

Copies one prompt from the <from> branch onto the <to> branch, validates it, and commits it on <to> with the message promote <file>: <from> -> <to>. Both branches must exist, and the working tree should be clean.

promptctl promote <file.prompt> <from> <to>

Example

promptctl promote acme/support/agent.prompt dev prod
Output
promoted acme/support/agent.prompt onto prod (18bd98a235c4)

promote returns to the branch you started on. If the prompt already matches, it prints already up to date: acme/support/agent.prompt on prod matches dev and exits 0.

push​

Validates every prompt, pushes all local branches to origin, and then, with -server, publishes every *.prompt file in the working tree to that server.

promptctl push [-server <host:port>] [-tls [-ca-cert <file>]]
FlagEnv varDefaultDescription
-serverServer to publish to after the push. Without it, push only pushes.
-tlsfalseConnect to -server over TLS. Without -ca-cert, it trusts the system CA roots.
-ca-certCA certificate that signed the server's certificate.

Example

promptctl push -server localhost:8443
Output
pushed
published priompt://acme/support/agent (03dd6040bee8)

When the remote already has every commit, the first line is already up to date, and the publish step still runs. Publishing unchanged content is a no-op on the server, so only changed prompts notify subscribers. The server records the publish on main, whichever git branch is checked out.

pull​

Pulls the current branch from origin.

promptctl pull
Output
already up to date

Without a remote named origin, push and pull print remote not found and exit 1.

publish​

Publishes prompts to a server without touching git. With no paths, it publishes every *.prompt file in the working tree.

promptctl publish -server <host:port> [-tls [-ca-cert <file>]] [<file.prompt>...]
FlagEnv varDefaultDescription
-serverServer address. Required.
-tlsfalseConnect over TLS. Without -ca-cert, it trusts the system CA roots.
-ca-certCA certificate that signed the server's certificate.

Example

PRIOMPT_TOKEN=<token> promptctl publish -server localhost:8443 acme/support/agent.prompt
Output
published priompt://acme/support/agent (0d7b8729099a)

<token> is a token with write access. Each prompt is validated before it's sent, and the first failure stops the run.