Prompt Runner SDK

Prompt Runner SDK

Packet-first prompt execution for Elixir, Mix, and local CLI workflows

GitHubLicense

Prompt Runner SDK executes packetized prompt workflows against local repositories. This README targets prompt_runner_sdk ~> 0.7.0.

0.7.0 is a breaking redesign:

The same runtime is exposed through public Elixir modules and the CLI.

Highlights

Installation

def deps do
[
{:prompt_runner_sdk, "~> 0.7.0"}
]
end
mix deps.get

Prompt Runner is an explicit agent_session_manager core-lane client. Host projects do not need codex_sdk, claude_agent_sdk, amp_sdk, cursor_cli_sdk, or antigravity_cli_sdk just to use Prompt Runner.

gemini_cli_sdk is retired. Antigravity is the Google coding-agent provider; gemini_ex remains a separate model API SDK and is not a Prompt Runner coding agent provider.

For recovery demos and onboarding, Prompt Runner also ships a built-in simulated provider that requires no external CLI or API credentials. That provider is package-local support for retry, repair, and resume behavior; cross-stack service-mode proofs should use configured ASM and cli_subprocess_core runtime profiles instead of treating :simulated as an end-to-end provider substitute.

Quick Start

Initialize Prompt Runner once per machine:

mix prompt_runner init
mix prompt_runner template list

That creates:

Start with the simulated path first. It is the shortest way to learn the packet model and authoring workflow.

Create a simulated packet with repos and a default prompt template in one command:

mix prompt_runner packet new demo \
--profile simulated-default \
--provider simulated \
--model simulated-demo \
--repo app=/path/to/repo \
--default-repo app \
--prompt-template from-adr

Create a prompt from that template:

mix prompt_runner prompt new 01 \
--packet demo \
--phase 1 \
--name "Capture runtime boundaries" \
--targets app \
--commit "docs: add runtime boundaries summary"

If you want a real provider packet after that, switch the packet to a real profile/provider/model or start with codex-default.

The generated prompt is template-based. It should then be finished by adding:

Example:

---
id: "01"
phase: 1
name: "Capture runtime boundaries"
template: "from-adr"
targets:
- "app"
commit: "docs: add runtime boundaries summary"
references:
- "docs/adr-001-runtime-boundaries.md"
required_reading:
- "docs/adr-001-runtime-boundaries.md"
context_files:
- "workspace/README.md"
depends_on: []
verify:
files_exist:
- "RUNTIME_BOUNDARIES.md"
contains:
- path: "RUNTIME_BOUNDARIES.md"
text: "Prompt Runner owns packet orchestration."
changed_paths_only:
- "RUNTIME_BOUNDARIES.md"
---
# Capture runtime boundaries
## Required Reading
- `docs/adr-001-runtime-boundaries.md`
## Mission
Read ADR 001 and create `RUNTIME_BOUNDARIES.md` in the target repo.
## Deliverables
- `RUNTIME_BOUNDARIES.md` summarizing the runtime boundary split
## Non-Goals
Do not modify any other files. Respond with exactly `ok`.

Turn the verification contract into a human checklist:

mix prompt_runner checklist sync demo
mix prompt_runner packet preflight demo
mix prompt_runner packet doctor demo

Inspect, run, and check status:

mix prompt_runner list demo
mix prompt_runner plan demo
mix prompt_runner run demo
mix prompt_runner status demo

Packet-local runtime state is written to demo/.prompt_runner/.

For a ready-made authoring walkthrough from ADRs/docs to finished prompts, see examples/authoring_packet/.

Packet Model

A packet directory is the primary unit of work:

demo/
prompt_runner_packet.md
templates/
from-adr.prompt.md
docs/
adr-001-runtime-boundaries.md
prompts/
01_capture_runtime_boundaries.prompt.md
01_capture_runtime_boundaries.prompt.checklist.md
.prompt_runner/
state.json
progress.log
logs/

Core files:

Programmatic API

The CLI is a thin layer over public modules:

{:ok, _paths} = PromptRunner.Profile.init()
{:ok, packet} = PromptRunner.Packet.new("demo", root: "/tmp")
{:ok, packet} = PromptRunner.Packet.add_repo(packet.root, "app", "/path/to/repo", default: true)
{:ok, _prompt_path} =
PromptRunner.Packets.create_prompt(packet.root, %{
"id" => "01",
"phase" => 1,
"name" => "Create hello file",
"targets" => ["app"],
"commit" => "docs: add hello file"
})
{:ok, plan} = PromptRunner.plan(packet.root, interface: :cli)
{:ok, run} = PromptRunner.run(packet.root, interface: :cli)
{:ok, status} = PromptRunner.status(packet.root)

For embedded use, PromptRunner.run/2 defaults to an in-memory runtime store plus a no-op committer:

{:ok, run} =
PromptRunner.run("/path/to/packet",
provider: :codex,
model: "gpt-5.4",
committer: :noop,
runtime_store: :memory
)

Verification, Retry, and Repair

Prompt Runner no longer equates provider success with completion.

Each prompt can declare a deterministic completion contract with checks such as:

After every attempt, the runner verifies the contract:

Generate checklist views from the contract:

mix prompt_runner checklist sync demo

The checklist is derived output for humans. The verifier report in .prompt_runner/state.json remains the actual completion source of truth.

mix prompt_runner packet doctor also flags common authoring gaps before a packet run:

mix prompt_runner packet preflight is the machine-readable runtime readiness gate. It checks packet-local repo paths and git readiness, prints JSON, exits 0 when runtime-ready, and exits non-zero when the provider run should not start yet. CLI run calls packet preflight before invoking a provider; pass --skip-preflight only when you intentionally want the run path to handle packet readiness failures itself. Setup remains explicit: if a packet documents a setup command such as bash examples/.../setup.sh, run it before preflight.

CLI Entry Points

Use any of these:

Examples

Documentation

Development

mix test
mix format
mix credo --strict
mix docs

For sibling-repo development, Prompt Runner automatically selects local checkouts of agent_session_manager and cli_subprocess_core when they are present next to this repository:

mix deps.get
mix test

Hex packaging tasks always select the declared Hex dependency and omit the local-only CLI core override, so package metadata stays Hex-clean.

License

MIT