All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.9.0 - 2026-08-10
Shaped by a thirty-session unattended program built on 0.8.1. Every addition here is something that program had to build for itself in shell, and every fix is something it hit in the field.
If you are on 0.8.1 or earlier and run packets unattended, read the first entry under Fixed before anything else. A prompt that could not satisfy its verify contract re-invoked the provider without bound, and the cost of that is paid in provider tokens for as long as nobody is watching.
Added
mix prompt_runner packet lint [DIR], a static authoring-hazard gate and the sibling ofpacket doctor. Doctor reports authoring gaps; lint reports authoring hazards — constructs that load cleanly, run, and produce a wrong answer without ever raising. Errors: a prompt id that does not match its filename's numeric prefix (ordering comes from the filename, so a mismatch silently reorders the run), a filename with no numeric prefix, duplicate prompt ids, an unknown repo intargets:or in a verify entry'srepo:, legacy@groupsyntax intargets:(repo groups are never expanded for packets), and an unrecognizedverify:clause. Warnings: averify.commandsentry not wrapped intimeout, a prompt with noverifycontract, a contract with neither acommands:entry nor any content assertion, any use ofchanged_paths_only(it only sees uncommitted work, so it passes vacuously wherever the session commits for itself), and the four inert front-matter keys.--strictpromotes warnings to errors and--jsonemits a machine-readable report. The known-clause list is read fromPromptRunner.Verifier.contract_keys/0so lint and the verifier cannot drift.- The
doc:verify clause, an artifact-quality gate.files_existis satisfied by a three-line stub, so a prompt whose deliverable is a written document had no way to assert the document was written.doc:asserts a non-blank line floor (min_lines), verbatimrequires_sections, and the absence offorbids_markers(TODO/TBD/FIXME/XXXby default; an explicit empty list opts out, a custom list replaces the default). - The
repos_clean:verify clause, which asserts that sessions committed their own work. Under--no-committhe runner's committer never runs andchanged_paths_onlypasses vacuously, becausegit status --porcelainis empty precisely because the session committed.pushed: trueadditionally requires an upstream and comparesHEADto it — a missing upstream is a failure, since the clause was asked to assert publication and cannot.pushed: false(the default) treats an absent upstream as fine. The upstream comparison asks the remote withgit ls-remoteunder a bounded timeout (remote_timeout_ms, default 90s) rather than fetching:ls-remoteis a pure query and does not create or move remote-tracking refs, so the clause writes nothing at all into the repository it is judging. When the remote cannot be reached,details:says so and the comparison falls back to the cached remote-tracking ref, which can only be behind the remote and never ahead of it — the safe direction for a clause asserting publication. mix prompt_runner watch [DIR], supervision for a long unattended run. The quiet-time scan skips.git,_build,deps, andnode_modules, whose mtimes are derived output and say nothing about session progress while dominating the walk on a large repository. One compact line per interval:WATCH 16:57Z runner=UP prompt=11 quiet=0min repos=3 dirty=0 commits=27.--interval SECONDS(default 900),--once, and--json.PromptRunner.Watch.sample/2is public for host applications with their own monitoring.- A run pid file. Any run with a file-backed state directory writes
.prompt_runner/run.pidfor its duration and removes it on exit, including on failure, so liveness can be checked by signalling a pid.watchuses it rather than a process-name match: such a pattern matches any command line containing it, including the supervisor's own shell, and reports a live run forever. --dry-runonrun. The runner has honouredopts[:dry_run]since the packet rewrite, but no CLI switch ever set it, soprompt_runner run <packet> --dry-rundropped the unknown flag and started a real provider session.PromptRunner.Verifier.contract_keys/0, and read-only repository inspection inPromptRunner.Git(worktree?/1,status_lines/1,commit_count/1,upstream_ref/1,fetch/3) shared by the verifier andwatch.- Two guides: Packet Linting and Supervising A Long Run.
Fixed
The studio renderer showed nothing at all for a provider that does not stream. It discarded
message_receivedoutright, which is right for a provider that already streamed the same text as deltas and would otherwise print it twice, and wrong for one that only ever delivers a message whole. Codex does the latter, so a Codex run rendered its header and then stayed blank for the rest of the session while the provider was working normally. The test is now what actually reached the screen rather than which provider sent it; reasoning text is displayed but does not count as having shown the message. Only the studio renderer was affected — compact and verbose have always renderedmessage_received.Every run opened with
unknown session started. The model is named on the launched argv, but nothing carried it into therun_startedevent: provider metadata is populated only once a provider announces its session, which is after the header has already printed. The header now falls back to the argv, and reports reasoning effort alongside the model where the run requested one.confirmed_modeldeliberately does not use that fallback — thecli_confirmationgate judges what the provider echoed back, and reading the argv would let it confirm a request against itself. Where a provider genuinely names no model, the header now says so rather than printingunknownwhere a model name belongs.run PACKET 01 02 03now runs every listed prompt, in the order given.build_targets/3returned[hd(remaining)], so it ran only the first, exited0, and reported success for the work it had discarded — whileguides/cli.mdhas documented the multi-prompt form since the CLI existed. This is the most dangerous shape of defect for an unattended program: a mid-run resume with the nineteen remaining prompt ids executed one of them and stopped cleanly, with nothing in the log to say the other eighteen had been dropped. A prompt id that names no prompt is now an error rather than a silent no-op, on the same reasoning — a typo in a resume list should stop the run, not shorten it.A prompt that could not satisfy its verify contract repaired forever. This is the most operationally serious item in the release.
RecoveryPolicy.final_action/5returns{:verification_failed, ...}when repair is not available — repair disabled, its attempts spent, or the attempt that just failed was itself a repair. The runner routed that outcome through the same function as{:repair, ...}, which returns{:repair, ...}, and the outcome handler reacts to{:repair, ...}by starting another repair attempt. That attempt ran in:repairmode, took the same branch, and started another one.Exposure: every release through 0.8.1, on the default recovery policy, with no configuration required to trigger it. Any prompt whose contract simply cannot be met — a typo'd path in
files_exist, a deliverable the model will not produce, a verify command that can never exit zero — re-invoked the provider without bound. Unattended, that continues until someone notices; with a live provider the cost is real tokens per iteration, at the packet's own model and permission mode.It did not look like a loop. Each pass printed an ordinary
Verification failed for prompt NNand started over, so the terminal showed a plausible retry cadence rather than a runaway. The clearest signal was indirect: theattemptslist in.prompt_runner/state.jsongrew without bound, every entry after the first carrying"mode": "repair", until re-encoding that file became the slowest operation in the run.Detection on an affected version:
jq '.prompts["01"].attempts | length' .prompt_runner/state.jsonclimbing past1 + recovery.repair.max_attemptsmeans the loop is running.{:verification_failed, ...}is now terminal: the run stops and reports the unmet items. The two outcomes share only the state recording they legitimately have in common, and the reported failure names the failing items instead of inspecting the whole verifier report:ERROR: verification failed: file_exists docs/report.md: missingCall options were silently discarded by packet metadata.
Plan.merged_opts/2normalized option keys once, after merging every layer, so%{"provider" => "claude"}from a packet manifest and%{provider: "simulated"}from the call site both survived the deep merge as distinct keys, and normalization-after-merge let whichever it visited last win — by Erlang term order, the string one. Every CLI and API override was affected whenever the packet set the same key, and the failure pointed in the worst possible direction: a run intended for the simulated provider started the packet's live provider, at the packet's model, permission mode, and system prompt. Each layer is now normalized before it is merged.The ASM run deadline is derived from
timeout.ASM.Run.Statedefaults:run_deadline_msto 600_000 — a total wall-clock budget for the whole run, armed independently of the stream and transport timeouts — and Prompt Runner never set it. A packet that deliberately lefttimeoutunset got seven days on the stream and transport bounds and ten minutes on the run, and every prompt doing more than a few minutes of work died with aprovider_runtime_claimnaming a deadline nothing had configured, after the model had already done the work and often after it had committed it. All four bounds now derive fromresolve_effective_timeout_ms/1: an explicittimeoutbounds the run, and an absent one means the seven-day emergency bound.prompt_runner planreported the packet's provider regardless of overrides.CLI.run_plan/1parsed no flags and passed none toPromptRunner.plan/2, so the natural way to check an override before spending a session answered about a different plan thanrunwould build.planandrunnow share one switch list.
Changed
- The built-in templates and
prompt newno longer scaffoldreferences,required_reading,context_files, ordepends_on. None of them is read at runtime — they are parsed, stored onPromptRunner.Prompt, and never sent to the provider or used for ordering — so the first prompt anyone scaffolded taught them to record required reading in a field the model never sees. The## Required Readingbody section stays, since the body is what reaches the model, and theverify:skeleton now offerscommands:in place ofchanged_paths_only:. Prompts that still carry the keys keep working; lint reports them. - Full documentation refresh for 0.9.0 across
README.mdand every guide, including the run-deadline behaviour, the difference betweenchanged_paths_onlyandrepos_clean, and why the terminal event counters are not evidence that a session did work. - Release preparation now asserts that every documentation extra registered in
mix.exsexists on disk and is grouped, and that every guide on disk is registered.
0.8.1 - 2026-08-03
Changed
- Default live-provider models are now
gpt-5.6-lunafor Codex andhaiku(Haiku 4.5) for Claude, across every default and every path that reaches a live provider:- the
codex-defaultprofile created bymix prompt_runner init(gpt-5.4->gpt-5.6-luna,reasoning_effort: xhighunchanged) - the legacy-interface fallback model (
claude-sonnet-4-6->haiku) examples/single_repo_packetandexamples/multi_repo_packet(gpt-5.4-mini->gpt-5.6-luna)examples/claude_packet(sonnet->haiku)- the CLI help text and every guide/README sample
The simulated packets are unaffected; they never contact a provider.
Note that
haikuis the shared model registry's id for Haiku 4.5 —haiku-4.5is not a registered id or alias and is rejected as an unknown model.
- the
Fixed
- Generated artifacts no longer carry a stale hardcoded version. The
run_prompts.exsscaffold emitted{:prompt_runner_sdk, "~> 0.7.0"}, and both the CLI help banner and newly created packet manifests announcedPrompt Runner 0.7.0, on a 0.8.0 install. Scaffolding a project from 0.8.0 therefore produced a dependency entry one minor version behind.
Changed
PromptRunner.version/0is now the single source of truth for every version string Prompt Runner emits. It is baked in at compile time frommix.exs, and the CLI banner, generated packet manifests, and the scaffolded install entry all interpolate it.- Added a release-preparation regression test that fails when any file under
lib/hardcodes a release version, so this class of drift cannot ship again.
0.8.0 - 2026-08-03
Added
- A live Claude provider example,
examples/claude_packet/. It runs the same two prompts asexamples/single_repo_packet/(Codex), so the pair is the shortest demonstration that a packet is provider-portable. Both were verified against their real CLIs for this release. - The normalized common option surface introduced by
agent_session_manager0.11/0.12, accepted in every provider option map and gated at runtime by the provider's common-feature manifest:allow_unknown_modelcompletion_onlyoutput_schematransport_headless_timeout_ms
reasoning_effortfor Claude, which resolves through the shared model registry the same way Codex's does.include_thinkingremains the separate control for thinking output.- The Codex app-server option surface in
codex_opts:app_server,host_tools,dynamic_tools, andreviewed_approval. mix deps.sources, plus apublish_preflightregression test that fails when a committed Hex constraint cannot admit the sibling checkout it was developed against.
Changed
- Moved dependency resolution onto the shared
build_support/dependency_sources.exshelper (v7) vendored by the rest of this stack, replacing the bespokelocal_dev_or_hex_depselection inmix.exs. Sibling checkouts still win automatically, and a gitignored.dependency_sources.local.exscan now force Hex resolution — which is what makesmix deps.getfetch the packages thatmix hex.publishrequires. - Raised the runtime floor to
agent_session_manager ~> 0.12.1andcli_subprocess_core ~> 0.4.1.cli_subprocess_coreis now a declared dependency rather than a local-only override, matching the fact thatPromptRunner.SessionconsumesCliSubprocessCore.Payloaddirectly. - Refreshed the remaining dependencies:
ex_doc ~> 0.40.3,yaml_elixir ~> 2.12,mox ~> 1.2, andcredo ~> 1.7.19. The Credo floor is deliberate: 1.7.16 and earlier crash tokenizing Elixir 1.20 sigils. output_schemais no longer a Codex-local option. It is a normalized option gated by thestructured_outputcapability, so Claude can request it too.- Permission-mode validation is documented as capability-derived rather than hardcoded per provider, since the supported set moves with ASM.
Fixed
mix hex.publishcould not run from a workspace checkout.mix.lockstill pinned the staleagent_session_manager 0.10.0entry — which requirescursor_cli_sdk, a dependency ASM 0.12 dropped — and nothing in the old dependency selection could fetch the Hex packages that packaging needs. The lock is regenerated from a real Hex resolution and both modes now coexist.- Removed an unreachable verifier-override branch from the final-action
decision in
PromptRunner.RecoveryPolicy. An earlier clause already handles a passing report on the provider-error path, so the branch could only ever raiseKeyErroror evaluate to false. - Removed a dead
preflight_llm_provider/1fallback clause;llm_for_prompt/2always populates:sdk. - Dropped two redundant
||fallbacks in the Codex CLI confirmation audit;confirmation_source/1already guarantees a default. - The project again compiles cleanly under
--warnings-as-errorson Elixir 1.20, andmix dialyzerreports zero errors with no ignore file.
0.7.0 - 2026-07-13
Changed
- Breaking change: redesigned Prompt Runner around packet directories,
prompt_runner_packet.md, and prompt-local YAML front matter instead of the older duplicated control-file workflow. - Added home-scoped profiles under
~/.config/prompt_runner/and aligned the CLI around packet/profile authoring commands. - Added first-class packet APIs:
- Made completion verifier-owned. Prompt runs now record deterministic verifier reports in packet-local runtime state and use those reports to drive retry and repair decisions.
- Rebuilt the shipped examples as packet-native examples:
examples/single_repo_packetexamples/multi_repo_packet
- Rewrote the README, guides, and HexDocs menu around the packet/profile model.
- Standardized the release README badges and Hex/HexDocs package metadata.
- Aligned the public provider surface with
agent_session_manager ~> 0.10.0: Claude, Codex, Amp, Cursor, and Antigravity. Gemini CLI support is retired; Antigravity is the Google coding-agent provider, whilegemini_exremains a distinct model API SDK. - Added validated
cursor_optsandantigravity_optspacket and prompt sections, plus common-runtime coverage for all five ASM providers. - Raised the Elixir requirement to
~> 1.19to match the ASM dependency floor.
Fixed
- Packet, profile, and prompt-local execution options now normalize correctly
at plan-build time, so packet-defined
provider,model,reasoning_effort, andcodex_thread_optsactually reach runtime execution. mix prompt_runner run ...now sets the correct command flag before delegating to the runner.changed_paths_onlyverification now inherits the prompt's default repo scope when entries omit an explicitrepo.- Packet runtime state now serializes common result tuples into readable JSON maps instead of opaque tuple placeholders.
- Hex packaging now uses an explicit shipped-example allowlist, excluding generated repos, workspaces, logs, runtime state, and nested Git data.
0.6.1 - 2026-04-09
Changed
- Bumped the published
agent_session_managerdependency to~> 0.9.2. - Updated the standalone example runners to install
agent_session_manager ~> 0.9.2. - Refreshed README and guide version references for
prompt_runner_sdk ~> 0.6.1.
0.6.0 - 2026-04-09
Changed
- Removed direct provider SDK package requirements from
prompt_runner_sdk. Host projects now install onlyprompt_runner_sdk, while provider CLI execution flows throughagent_session_managercore lane pluscli_subprocess_core. - Prompt Runner now starts ASM sessions with
lane: :coreexplicitly instead of inheriting ASM's default:autolane selection. - Replaced provider-SDK runtime preflight with provider/core-lane preflight based on ASM provider metadata and common CLI discovery facts.
- Updated README, guides, scaffolding, and shipped examples to use provider names as the standard config surface and to stop installing provider SDK packages.
Fixed
- Standalone scaffold output and shipped example
run_prompts.exsfiles no longer declare unnecessary provider SDK dependencies. - Prompt Runner now behaves consistently whether provider SDK packages happen to be installed locally or not, because the runner always stays on ASM core lane.
0.5.1 - 2026-04-09
Changed
- Bumped the published Codex dependency guidance and package spec to
codex_sdk ~> 0.16.1. - Refreshed README, getting-started, provider docs, scaffolded dependency
output, and example
Mix.installsnippets for the0.5.1/0.16.1release pair.
Fixed
- Codex CLI confirmation auditing now falls back to the actual launched
run_startedcommand args when hidden confirmation metadata does not include model or reasoning details, socli_confirmation: :requireno longer fails falsely on otherwise-correct Codex runs. - Hidden Codex confirmation events now merge event metadata with raw
thread.startedmetadata before Prompt Runner evaluates the confirmation payload.
0.5.0 - 2026-04-08
Changed
- Aligned the published dependency matrix with the current Hex releases:
agent_session_manager ~> 0.9.1claude_agent_sdk ~> 0.17.0codex_sdk ~> 0.16.0gemini_cli_sdk ~> 0.2.0amp_sdk ~> 0.5.0
- Updated runtime missing-provider guidance to point at the current SDK ranges.
PromptRunner.Scaffoldnow derives provider dependencies from the configured provider plus any per-prompt provider overrides instead of hardcoding a stale provider list into generatedrun_prompts.exsfiles.- Synced Prompt Runner's config/session surface to the current ASM and SDK
contracts:
- normalizes provider-native and legacy permission aliases onto the shared
runner modes
:default | :auto | :bypass | :plan - rejects stale provider-specific inputs such as Codex
sandboxandask_for_approvalat config load instead of failing later during runtime - preserves inherited root
timeoutandpermission_modevalues when a prompt override switches providers without redefining those fields
- normalizes provider-native and legacy permission aliases onto the shared
runner modes
- Refreshed README, provider docs, getting-started docs, and example docs to reflect the 0.5.0 provider matrix and current install instructions.
- Expanded the shipped example packs and standalone
run_prompts.exsscripts to exercise all four providers: Claude, Codex, Amp, and Gemini. - Example setup scripts now reset their workspaces before seeding, so repeated example runs start from a deterministic clean repo state.
- Local sibling-repo development now requires explicit opt-in via
PROMPT_RUNNER_USE_LOCAL_DEPS=1, and Hex packaging tasks ignore that opt-in so release builds never emitpath:dependencies. - Hex package builds now exclude generated example runtime artifacts such as seeded repos, workspaces, logs, and progress files.
Fixed
- Removed stale Prompt Runner Claude model remapping so current short aliases
such as
sonnetresolve throughclaude_agent_sdkinstead of an outdated hardcoded model id. - Aligned recovery-related prompt-control behavior with the actual current
runtime support in the local ASM/SDK stack:
- Claude no longer defaults
max_turnsto1when the runner does not set it - Amp rejects unsupported prompt controls such as
system_promptandmax_turnsinstead of silently accepting dead config - Gemini SDK startup now uses
approval_mode: :yolowithout duplicating the deprecatedyolo: trueflag
- Claude no longer defaults
- Corrected the live example provider contracts:
- Codex now stays on the supported ASM shared permission modes
(
:default | :bypass | :plan) instead of the invalid shared:autopath - Amp examples now use the current
amp-1model instead of a Claude model id - Gemini examples allow the current provider-native shell tool name
run_shell_command - multi-repo prompts now describe the real working-directory and sibling-repo layout used at runtime
- Codex now stays on the supported ASM shared permission modes
(
0.4.0 - 2026-02-11
Added
- Studio rendering mode (
log_mode: :studio) — CLI-grade interactive output using AgentSessionManager's newStudioRenderer- Human-readable tool summaries instead of raw JSON token streams
- Status symbols:
◐(running),✓(success),✗(failure),●(info) - Three tool output verbosity levels via
tool_output:config::summary(default),:preview,:full - Automatic non-TTY fallback for piped/redirected output
- New
--tool-outputCLI flag for runtime verbosity override (summary,preview,full) - New
tool_outputconfig key in runner configuration - Redesigned prompt header with box-drawing characters and aligned layout in studio mode
- New guide:
guides/rendering.mddocumenting all three rendering modes - Codex CLI confirmation and model auditing — verify that the Codex CLI is actually using the model and reasoning effort you configured
- New
cli_confirmationconfig key (:off,:warn,:require) — controls response to confirmation mismatches - New
--cli-confirmation MODECLI flag for runtime override - New
--require-cli-confirmationCLI flag (shortcut for--cli-confirmation require) - Machine-readable audit lines written to session logs (
LLM_AUDIT,LLM_AUDIT_CONFIRMED,LLM_AUDIT_RESULT) - Mismatch and missing-confirmation warnings printed to console when
cli_confirmation: :warn(default for Codex) - Hard failure when
cli_confirmation: :requireand CLI does not confirm reasoning effort - Per-prompt
cli_confirmationoverride viaprompt_overrides
- New
- Unbounded and infinite timeout support —
timeoutnow accepts:unbounded,:infinity,"unbounded","infinity", and"infinite"in addition to positive integers- Sentinel values resolve to a 7-day emergency cap in the session layer
- Works in both top-level config and per-prompt
prompt_overrides
- LLM SDK preflight checks — Runner verifies that the required SDK module is loaded before starting a prompt (currently Codex only), with clear error messages including the missing package name
- Stream error handling —
Rendering.stream/2failures (exceptions, throws) are now caught and returned as{:error, {:stream_failed, message}}instead of crashing the runner - Codex
reasoning_effortdisplayed in prompt plan output when configured viacodex_thread_opts
Changed
- Default
log_moderemains:compact(studio is opt-in for this release) - Default
cli_confirmationis:warnfor Codex prompts, effectively a no-op for other providers - Modularized
Runnerinternals — extracted helper functions for prompt header printing, permission mode display, adapter option display, and codex thread options - Stream error tracking now preserves structured
provider_errorpayloads from:error_occurred/:run_failedevents instead of flattening to generic strings return_errornow renders concise summaries by default and prints provider stderr detail only whenlog_meta: :full- Updated
guides/configuration.mdwith new rendering, timeout, and CLI confirmation options - Updated
guides/providers.mdwith Codex reasoning effort and CLI confirmation details - Updated
guides/getting-started.mdwith studio mode and new CLI flags - Updated README with rendering modes section, new CLI options, and error detail behavior
Dependencies
- Requires
agent_session_manager ~> 0.8.0(StudioRenderer module) claude_agent_sdkupdated to~> 0.12.0codex_sdkupdated to~> 0.8.0
0.3.0 - 2026-02-09
Changed
- Migrated rendering to
AgentSessionManager.Rendering—Runnernow builds a renderer/sink pipeline from config instead of callingStreamRenderer.stream/4. UsesCompactRendererorVerboseRendererwithTTYSink,FileSink,JSONLSink, andCallbackSink. - Migrated session lifecycle to
AgentSessionManager.StreamSession—Sessionnow delegates stream creation, task management, and cleanup toStreamSession.start/1instead of hand-rolling ~200 lines ofStream.resource, receive loop, error event constructors, task shutdown, and child cleanup. - Canonical event format —
Sessionno longer normalizes ASM events. Canonical events (:run_started,:message_streamed,:tool_call_started,:tool_call_completed,:run_completed, etc.) pass through directly to the rendering pipeline. Session.start_stream/2signature and return type unchanged — existing callers work without modification.start_adapterreplaced withbuild_adapter_specreturning{Module, opts}tuples instead of starting processes directly.PromptRunner.Applicationsimplified — removedPromptRunner.TaskSupervisorandPromptRunner.SessionSupervisor(StreamSession manages its own lifecycle).- Error tracking changed from
StreamRendererreturn value toCallbackSinkwith process dictionary (Process.put/:prompt_runner_stream_result). - Session header now written directly to log file IO device via
IO.binwriteinstead of throughStreamRenderer.emit_line. - Tests updated to emit canonical ASM events instead of previously-normalized types.
- Examples now use isolated workspace directories — each example has
setup.sh/cleanup.shscripts and a standalonerun_prompts.exsusingMix.install, so examples no longer operate within the SDK repository itself. - Updated documentation (providers.md, getting-started.md, configuration.md, README) to reflect canonical event format, removed supervisors, new rendering pipeline, and example isolation.
Removed
- Deleted
PromptRunner.StreamRenderer(935 lines) — all rendering now handled byAgentSessionManager.Rendering. - Removed
normalize_event/1and all event normalization functions fromSession(:message_start,:text_delta,:tool_use_start,:tool_complete,:message_stop, etc. mappings). - Removed
build_stream_session,build_event_stream,next_stream_events,done_error_events,run_once,start_store,stop_task,await_task_exit,cleanup_children,terminate_child,start_supervised_child,ensure_runtime_startedfromSession(all replaced by StreamSession). - Removed
PromptRunner.TaskSupervisorandPromptRunner.SessionSupervisorprocess tree entries. - Removed
examples/simple/claude-output.txt(examples now write to workspace directories).
Added
- Standalone
run_prompts.exsscripts for simple and multi-repo-dummy examples (useMix.installfor self-contained execution). setup.shandcleanup.shfor the simple example to manage an isolated git workspace.workspace/added to.gitignorefor example directories.
Dependencies
- Requires
agent_session_manager ~> 0.7.0(StreamSession and Rendering modules).
0.2.0 - 2026-02-08
Added
- Added
PromptRunner.ApplicationOTP supervision tree with:PromptRunner.TaskSupervisorfor run execution tasks.PromptRunner.SessionSupervisorfor adapter/store process lifecycle.
- Added
PromptRunner.Sessionas the AgentSessionManager bridge layer. - Added support for provider alias
amp(amp_sdk) in LLM normalization. - Added
adapter_optsconfig support at both root andllmscopes. - Normalized adapter options passthrough — Session now forwards these config keys to all adapters:
permission_mode—:default,:accept_edits,:plan,:full_auto, or:dangerously_skip_permissionsmax_turns— integer turn limit (Claude: unlimited by default, Codex: SDK default 10, Amp: no-op)system_prompt— system-level instructions (Claude:system_prompt, Codex:base_instructions, Amp: stored only)sdk_opts— keyword list of arbitrary provider-specific SDK options (normalized options take precedence)
- Claude
cwdpassthrough — Session passesproject_dirascwdto the Claude adapter, so the Claude CLI runs in the correct working directory.
Changed
- Migrated runtime execution from direct SDK integration to
agent_session_manager. - Reworked
PromptRunner.LLMFacadeinto a thin delegator toPromptRunner.Session. - Updated config normalization to accept both
providerand legacysdkkeys. - Updated examples and CLI help text to use
providerin config snippets. - Updated README guidance from dual-SDK to multi-provider terminology.
Removed
- Removed direct
PromptRunner.LLM.CodexNormalizerintegration and tests. - Removed direct
claude_agent_sdkandcodex_sdkdependency declarations.
Dependencies
- Added
agent_session_manager ~> 0.6.0(now~> 0.7.0as of 0.3.0).
0.1.2 - 2026-01-26
Added
- New
RepoTargetsmodule for expanding repo group references in target_repos. Groups are defined in config asrepo_groups: %{"pipeline" => ["command", "flowstone"]}and referenced in prompts.txt as@pipeline. - Support for nested group references (e.g.,
@portfoliocontaining@pipeline). - Cycle detection for repo group definitions with clear error messages.
- Validator now checks repo-specific commit messages for default repo when prompt has no explicit target_repos.
- Test suites for
RepoTargetsandValidatormodules.
Changed
Runnernow expands repo group references before resolving target repositories.Validatorexpands repo groups when checking commit messages and repo references.- Improved error handling when target repos cannot be resolved.
0.1.1 - 2026-01-26
Fixed
- Fixed single-repo commit path bug where
commit_single_repoalways committed toconfig.project_dirinstead of the resolved target repository path. Now correctly passes repo name and path fromrunner.extogit.ex.
Changed
- Added
:inetsto extra_applications for OTP HTTP client support. commit_single_repo/2now accepts optionalrepo_nameandrepo_pathparameters for explicit targeting.
Dependencies
- Updated
ex_docfrom 0.39.3 to 0.40.0. - Updated
finchfrom 0.20.0 to 0.21.0.
0.1.0 - 2026-01-18
- Initial release.
- Prompt runner CLI with streaming output.
- Claude Agent SDK and Codex SDK support via a unified facade.
- Multi-repo prompt execution with per-repo commit messages.
- Example prompt sets for single-repo and multi-repo workflows.