Actions
Actions are explicit one-shot operations: migrations, builds, tests, data seeding, or inspection commands. They are not represented as continuously running services.

Service actions
services:
api:
command: npm run dev
dir: apps/api
env_files: [.env]
actions:
migrate:
command: npm run db:migrate
description: Apply pending database migrations
timeout: 2m
confirm: true
test:
command: npm test
timeout: 5mService actions inherit dir, shell, env, and env_files. Expand a service with Enter, focus an action, and press s. Output, exit code, and duration are retained separately from service logs.
Run the action again and both results remain independently addressable. [ and ] move through the target's retained runs, l returns to the latest, and v opens the full run history. The selected run keeps its own scroll and search position, so comparing two executions does not lose your place.
Typed parameters
Use parameters when several actions differ only by a target, count, flag, or environment value. One declaration becomes the source of truth for the TUI, CLI, MCP, and prerequisites:
actions:
seed:
params:
environment:
type: select
options: [dev, staging, prod]
default: dev
arg: --environment
count:
type: number
min: 1
max: 10000
default: 100
arg: --count
write:
type: checkbox
default: false
flag: --write
confirm: This writes data
run: [./seed]
Parameterized actions use an argument vector instead of shell interpolation. The runtime validates raw values, normalizes defaults, renders the preview and executable definition once, and binds confirmation to that exact result. An interactive parameterized action hands the same immutable argv to the terminal after confirmation; a reload cannot swap in a different command.
The CLI exposes the same schema and values without prompting:
kranz actions info tools/seed
kranz actions run tools/seed \
--param environment=staging \
--param count=250 \
--param write=true \
--confirm
MCP reads the advisory JSON Schema from action_info and sends native values in action_run.params; the runtime repeats validation at execution. See the runnable action-parameters example and the configuration reference.
Project action groups
Use an action group when the operation does not belong to one service:
action_groups:
infrastructure:
description: Shared development infrastructure
dir: infra
actions:
inspect:
command: docker compose ps
reset:
command: docker compose down --volumes
confirm: trueGroups can provide shared execution context. An action's own values override the inherited group values.
Running an action before a service starts
Some actions are not something you remember to run — they are a precondition. before_start declares that relationship:
services:
api:
command: npm run dev
actions:
migrate:
command: npm run db:migrate
before_start:
- action: migrate
- group: infrastructure
action: up
run: alwaysEach entry references an action that already exists, so the command keeps one definition and stays runnable on demand. Reference an action of the declaring service with action: alone, another service's action with service:, or a group's with group:.
Prerequisites run in declared order, after dependencies are ready and before the service starts:
run: once is the default and means one successful run per Kranz session, including across restarts — a migration is not re-applied every time you restart the service. run: always runs before every start, for checks that are cheap and whose answer can change.
If a prerequisite fails, the service stays stopped and its log names the action and the reason. Only success is remembered, so fixing the cause and starting again retries it. When two services reference the same prerequisite, whichever reaches it first runs it and the other waits for that same run.
Interactive actions cannot be prerequisites: they run unattended while a start is already in flight, so they cannot own the terminal.
See the prerequisites example for a runnable walkthrough.
Confirmation and cancellation
confirm: true requires a separate explicit approval before starting an action. In the CLI, review the confirmation_required plan and repeat the command with --confirm; MCP repeats the call with the returned confirmation_token. Both paths use the same plan-bound, one-shot supervisor token. Actions without this setting still run immediately. Stopping a running action always asks for confirmation regardless of its start setting. timeout covers the whole process group; cancellation sends a graceful signal and escalates when necessary.
Actions that ask a question
Some commands have to be answered: a migration that confirms before it writes, a REPL, a scaffolding wizard. interactive: true hands the real terminal to the command:
actions:
migrate:
command: npm run db:migrate
interactive: trueRunning one always asks first, whether or not it also sets confirm. The confirmation says plainly that Kranz is about to leave the screen, because handing the terminal over is not something that should happen to someone who just pressed a key in a list:
Run action "migrate"?
⚠ KRANZ WILL LEAVE THE SCREEN
OWNER api
This action takes over your terminal so you can answer it.
Kranz returns as soon as the command exits.
[Enter/y] Hand over the terminal [Esc/n] Cancel
After you accept, the command owns the terminal until it exits. Kranz then resumes and records the result — running, succeeded or failed, with the exit code and duration — exactly like a captured action. Because the output went to your terminal rather than into a buffer, the action's log pane says so instead of showing an empty capture.
Two limits follow from what handoff means:
- lifecycle
start,stop, andlogscommands cannot be interactive; they run unattended, sometimes while Kranz is shutting down; - an interactive action cannot be a prerequisite, because prerequisites run while a start is already in flight.
confirm and interactive answer different questions. confirm is about whether the command should run at all — use it for anything destructive. interactive is about who owns the terminal while it runs. An interactive action already forces confirmation with handoff-specific wording, so adding confirm: true to it has no further effect.