Prowl Agent Workflows
A workflow is a .pwlworkflow directory with workflow.yaml (schema: prowl.workflow/v1)
and optional local script actions, helpers, schemas, and assets. It declares roles and
sequential steps, typed state, nested conditions and loops. Prowl executes it; agent roles
use real terminal panes. Sources, later shadowing earlier by ID: app bundle (prowl.*
reserved), user (~/.prowl/workflows/*.pwlworkflow), repo
(<repo root>/.prowl/workflows/*.pwlworkflow). Pass bundle directories, not loose YAML files.
Pick the section for the task; load a reference file only when that task is at hand:
| Task | Where |
|---|---|
| Write or edit a workflow | read references/authoring.md first — full DSL, validator rules, patterns, worked example |
| Create or test a script action | references/actions.md — package layout, JSON protocol, approval, result records |
| Start a workflow, inspect or debug a run, decode an error | Running below; details in references/runbook.md |
A [Prowl] … line appeared in this pane | Participating below |
Authoring loop#
Read references/authoring.md, draft the requested workflow, validate it with
prowl workflow validate <bundle.pwlworkflow>, and fix errors while assessing warnings. validate and
prowl workflow schema work with Prowl closed. Passing static validation does not guarantee
start-time admission or successful execution: profiles, panes, inputs, CLI connectivity,
and the agents’ work still matter. If validation cannot run, disclose that limitation.
Creating a definition does not itself require starting it; run it when that is part of
the user’s request.
For launch roles, omit agents unless the user explicitly requires particular runtimes
or the task has a concrete runtime-specific requirement. Omission allows any qualifying
Agent Profile. Do not invent an allow-list from your own runtime, installed profiles,
example tokens, or assumptions about which model is best. Leave suggest unset too unless
it expresses a user-provided preference or a concrete task requirement; let Prowl’s profile
picker and saved preferences choose the agent by default.
Examples demonstrate individual capabilities, not a mandatory architecture. Use the roles, steps, and output contracts the task needs; add loops, deadlines, and automatic pane closure only when their behavior serves the requested outcome. The authoring reference explains data dependencies, loop exits, and typed state and result scopes.
Built-in handoff#
Use prowl workflow run prowl.handoff --role receiver=<Profile> --json to prepare and save
this conversation’s task context, then start and focus a receiver in a new tab. Both modes
require a source pane with a detected agent. Use --input next=save instead to
save without a receiver. Follow the returned self_initiated.line and deliver the briefing
with its exact command; do not wait for Prowl to message you again. The receiver reads the
saved packet and continues the task. A completed run confirms save/launch, not task completion.
Built-in Review Loop#
Use prowl workflow run prowl.review-loop --role reviewer=<Profile> --json from the
implementing agent. Follow the returned self_initiated.line to deliver the scope,
plan, and verification brief. The reviewer opens in a right split in the same tab.
Optional inputs: min_rounds=2, max_rounds=4 (each 1–30, minimum must not exceed
maximum), and focus=<one-line instruction>. Any qualifying Profile can review.
Prowl handles every round and handoff. Reviewer reports findings; main verifies and fixes or explains each disposition. Reviewer may run tests. Main owns commits, pushes, and existing PR updates unless it explicitly delegates them, subject to task restrictions. Do not dispatch the other role manually. Deliver each assigned step, then wait for its next task. Do not change reviewed code after your delivery.
Clean exit needs the minimum rounds, a clean reviewer report, and no later changes
or pending follow-up from main. At the maximum, main still addresses findings and
reports remaining issues and fixes not reviewed again. completed means the procedure ended; read the final
summary for clean versus not clean. The reviewer pane stays open.
Running a workflow#
prowl workflow list [--json] # what this worktree can see, with validation status
prowl workflow run <id|name> [source] \
[--role r=<profile|auto|pN>] [--input k=v] [--skip <step-id>] [--json]
prowl workflow status [run-id] [--json] # no args inside a run: who am I / what is awaited
prowl workflow cancel <run-id> [--json]
[source]is a pane/tab/worktree reference (pN,tN, UUID, or the worktree name thatprowl workflow listprints asWorktree: <name>—main, not theRepo:mainlabel ofprowl list). Omitted inside a pane: that pane serves thecurrentrole and its worktree is the run’s; outside a pane the focused worktree is used, and a workflow with acurrentrole fails withSOURCE_REQUIRED. Required inputs without defaults must be passed via--input k=v.- When starting from the
currentrole’s own pane, inspect therunresponse forself_initiated(.data.self_initiatedwith--json). If present, follow itslineorprompt_pathand completion command yourself; Prowl does not type that first task back into the same pane. Waiting for another message would leave your own step unfinished. - The run is asynchronous:
runreturns the run id and frozen bindings; pollprowl workflow status <run-id> --json(.data.status.stateisrunning,needs_attention, or a terminal state;.data.finished_atappears when it ended) or read the run directory (~/.prowl/logs/workflow-runs/<root-name>-<root-hash>/YYYY-MM/<run-id>/—log.mdis the timeline; field guide, layout, and error tables inreferences/runbook.md). Finishing never closes launched panes; only aclose:step does. - The GUI starts (Command Palette, Agents capsule popover, Active Agents context menu) go
through the same admission — behavior is identical to the CLI. Settings › Agents › Workflows
lists every bundle with the same validation diagnostics, the enable toggle (a disabled workflow
is
WORKFLOW_DISABLEDforrun), and the remembered profile per launch role.
Participating in a run#
An active task delivered by Prowl in this pane, a launched role’s kickoff protocol, or a
self_initiated task in the run response makes this agent a participant. A message task
looks like this:
[Prowl] <prompt or scoped-read command…> — finish with: PROWL_WORKFLOW_TOKEN=<token> prowl workflow deliver [--verdict <v>] -
- Do the work the prompt asks for, completely, before delivering.
- Deliver by running the exact rendered command with the body on stdin as markdown
(
printf '…' | PROWL_WORKFLOW_TOKEN=… prowl workflow deliver -). When verdict variants are offered, pick exactly one and run that variant. - Include the declared sections, format, and verdict. Empty bodies are rejected; other
contract mismatches are provisional by default or rejected under
strict: true. Check the receipt: Delivered means accepted; Provisional still needs resolution, even when the command exits successfully. Do not report a step completed merely because its output file exists. A provisional delivery waits for the user’s decision; Ask again reopens delivery so you can correct it. Do not blindly resubmit or invent a replacement token; runbook explains the states. - Lost?
prowl workflow status(no arguments) answers “who am I”: this pane’s run, role, awaited step, its requirements and completion command. - Never use
prowl agents dispatch-completefor a workflow activation — it is rejected withWORKFLOW_DELIVERY_REQUIREDnaming the correct command. - A launched participant finds the same contract in its kickoff prompt (“Prowl workflow
completion protocol”), with the token already in its environment as
PROWL_WORKFLOW_TOKEN.
This skill ships inside the app: prowl skills install prowl-workflow links it into every
detected agent skill folder; prowl skills list shows per-target status. prowl-cli is
the companion skill for driving individual panes outside a workflow.
Assigned content and retention#
Use the scoped prowl workflow read command supplied with the task to retrieve
the prompt. Read returned resource IDs with the same run ID and invocation number;
workflow-resource: references are handles, not filesystem paths. Use --json
for byte-preserving reads, decode each chunk by its encoding, and continue with
--offset <next_offset> until next_offset is absent. Only the assigned pane can read this content; reads do not require a token.
Deliver ordinary text/JSON on stdin with prowl workflow deliver -; no project-local
temporary output file is needed. Explicit delivery is required.
Run artifacts expire with their run: 30 days for unpinned terminal runs, with a 5 GiB soft global budget and a 24-hour diagnostic window. Keep Run prevents automatic cleanup. Export a terminal run from Execution History for a durable complete ZIP.