Skip to main content
The run command executes agents from YAML configuration files or direct prompts. The same modern engine also handles bare prompts with run-supported flags: praisonai "fix bug" --model gpt-4o is equivalent to praisonai run "fix bug" --model gpt-4o. See CLI Dispatcher for how routing is decided.
You can omit the run subcommand for prompts and YAML workflows: praisonai "..." and praisonai agents.yaml are equivalent to praisonai run "..." and praisonai run agents.yaml (see YAML workflows through the modern run engine). Flags that run accepts (--output, --continue, --session, --fork, --stream, --allow, --deny, --approval, --permission-default, --plan, …) reach the modern engine on either shape; only legacy-only flags (--auto, --serve, --n8n, …) drop to the legacy dispatcher. The short-form -s (legacy --save) and -f (legacy --file) stay on legacy to protect existing scripts — use the long forms --session / --framework for modern behaviour.
Single-word direct prompts that look like reserved commands or common typos now fail fast with a hint on stderr and exit code 2. To send a genuine single word to the model, use praisonai run "<word>" explicitly. See Unknown Command Guard.
praisonai run exits 1 whenever the agent fails to produce a result. Under --output json / --output stream-json the failure surfaces as {"status": "failed", "code": "run_failed"} with an actionable remediation. See Exit Codes for the full table.
praisonai run exits 2 when the run hits its max_iter / max_steps budget and wraps up with a partial-progress summary. Under --output json / --output stream-json this surfaces as {"status": "truncated", "result": "<summary>"}, so CI and scripts never mistake a truncated run for a completed one. See Exit Codes and the Truncated payload subsection.
praisonai run "..." with no cloud key and no --model picks a reachable local model automatically. If Ollama (or any OpenAI-compatible local server) is running, you’ll see a one-line stderr notice and the run continues:
An explicit --model still takes over. See Keyless Local-First Run.

Usage

Arguments

Bare Prompts and YAML

You can drop the run keyword entirely for one-shot prompts and YAML workflows:
Both shapes inherit everything run gives you — --output modes, session continuity, credential gate, and permissions.
A prompt or a .yaml/.yml workflow whose flags are all accepted by run (--continue, --session, --output, --stream, --framework, …) reaches the modern engine; the value of a value-taking option stays attached to its flag. Only a genuinely legacy-only flag (--auto, --serve, --n8n, …) keeps the legacy dispatcher — and when one forces that, a one-line stderr notice points at praisonai run "…". The short-form -s (legacy --save) and -f (legacy --file) also stay on legacy to protect existing scripts; use --session / --framework for the modern equivalents. Multi-token unquoted prompts are joined into a single run positional so praisonai build a weather agent reaches the model as one prompt.

YAML workflows through the modern run engine

praisonai agents.yaml now flows through the same modern run envelope as praisonai run agents.yaml — the router forwards a .yaml/.yml target to the Typer run engine automatically. That unlocks the full run surface for plain YAML invocations:
--framework crewai / --framework autogen is a run option, so multi-framework YAML is carried into the modern envelope too.
Legacy fallback. A YAML target carrying a genuinely legacy-only flag (or a short option whose meaning differs between engines, e.g. -s / -f) still drops to the legacy dispatcher — and prints a one-line notice so you know the flag downshifted you. Remove the legacy-only flag to stay on the modern engine.

Options

Setting --append-system-prompt keeps run in-process; the warm-runtime fast path is bypassed for this invocation so the suffix is always applied. See Append System Prompt.
The permission and approval flags (--allow, --deny, --permissions, --permission-default, --approval, --approve-all-tools, --approval-timeout) are honoured on both paths — a direct prompt and a YAML workflow file. On the YAML path, any --allow / --deny / --permissions / --permission-default rule with no explicit --approval implicitly activates the console backend so deny / ask patterns are actually enforced. See YAML Workflows Are Permission-Gated.
--plan is honoured on the YAML path and under --profile too — a profiled run (praisonai run --plan --profile "…") stays strictly read-only, and the profiling report still prints. It’s a discoverable alias for --approval plan (PermissionMode.PLAN); see Permission Modes.
For workflow guidance, see Isolated Runs or the flag-focused guide at Run —worktree.
Pass --pure (alias --no-plugins) to skip external-plugin discovery for a single run without touching your saved enable/disable state — see Pure Mode.

Append to the system prompt

--append-system-prompt adds a one-off suffix to the assembled system prompt for a single run. It is never persisted and disappears when the process exits.
Omit the flag and set the environment variable instead — handy for CI:
--append-system-prompt bypasses the warm runtime and runs in-process. The warm runtime is a separate process that never receives the CLI’s PRAISONAI_APPEND_SYSTEM_PROMPT export and reuses a cached agent whose system prompt is already assembled — so attaching would silently drop the suffix. The in-process path applies it correctly, at the cost of a slightly higher first-invocation startup than a plain run.
See Append System Prompt for the full behaviour.

Delegating to Named Agents

Let a running agent delegate sub-tasks to your own named agents in .praisonai/agents/*.md. Pass --subagents to opt agents in for a single run, or mark agents with mode: subagent to expose them on every run.
See Named Agent Delegation for the full guide.

Isolated Runs (Git Worktree)

Add --worktree and each run gets its own git branch and checkout — concurrent runs never clobber each other’s edits.
What happens on exit depends on what the run produced:
The run commits everything (git add -A + git commit --no-verify) to the isolated branch, then removes the worktree checkout while keeping the branch. You’ll see:
If the commit can’t be made (e.g. no git identity configured), the worktree is kept in place with a warning so output is never lost.
The worktree checkout and its branch are torn down entirely — nothing is left behind.
The worktree checkout stays in place for in-place review, regardless of whether changes were made.
--worktree is a no-op outside a git repository — it prints Not a git repository; running without worktree isolation. and runs in place, so it’s safe to add unconditionally. Change detection uses git status --porcelain, so brand-new untracked output counts as a change.
Isolation applies to direct prompt and YAML file runs only. These combinations are rejected up front (exit code 1):
  • --worktree + --attach — the warm runtime is a separate process whose working directory can’t be redirected.
  • --worktree + --agent / --command / --profile / --profile-deep — only prompt and YAML runs are supported.
  • --keep without --worktree--keep requires --worktree.
When --worktree is used with a warm-runtime-eligible prompt, the run falls back to in-process execution so it never attaches to a cached warm agent.
Human-facing worktree messages are suppressed under --output json / --output stream-json, so structured runs stay machine-parseable.
This CLI flag wraps the same core primitive documented for the Python API. Pick the layer that fits:

Python API — GitWorktreeAdapter

Provision worktrees directly from Python for concurrent agents.

Per-Kanban-Task Worktrees

Give each kanban task its own worktree with workspace_kind="worktree".

Piped Input

praisonai run composes in Unix pipelines. Piped stdin is merged with your prompt argument (prompt first, then piped body).
Piped input is skipped when:
  • TARGET is an existing .yaml / .yml file (case-insensitive).
  • --agent or --command is used.
  • --restore is set (the command exits before ingestion).
See Piped Input for the full behaviour.

Output Modes

--output controls how results and events are written to stdout.
Rich-formatted human-readable output in the terminal.

Exit Codes

praisonai run returns a non-zero exit code whenever the agent fails to produce a result, so CI pipelines and scripts can branch on the exit code instead of scraping stderr.
Exit 2 covers two independent cases: truncation (a new terminal outcome introduced by PR #4100) and the pre-existing reserved-command guard. They share the code but are unrelated — a truncated run always emits status: "truncated" under --output json, while the guard fails fast before any run.

Failure payload (--output json / --output stream-json)

When the agent produces no result, the CLI emits a machine-readable failure object and exits 1:
The paired error event carries the same status and an error code:
The human-facing stderr line includes an actionable remediation:
The failure contract applies to every run path — direct prompt, YAML file, --agent, --attach, --profile, and --profile-deep. Profiled runs still print the profiling report before exiting non-zero, so you keep the profile even on failure.

Truncated payload (--output json / --output stream-json)

When a run hits its max_iter / max_steps budget, the CLI keeps the wrap-up summary but marks the run truncated and exits 2:
In interactive (non-JSON) mode the CLI also prints a one-line stderr notice so a human knows the answer is partial:
JSON / stream-JSON consumers do not receive this stderr warning (the CLI checks output.is_json_mode) — the status: "truncated" field is the machine signal.
stream-json contract: the terminal run.result event is emitted with ok: false (not ok: true), in lockstep with exit 2. A stream-json consumer therefore never sees a contradictory success terminal event ahead of the truncated status. The classification runs bridge.emit_run_result(result, ok=succeeded and not truncated), covered by the regression test test_actions_stream_reports_truncated_run_not_ok.
See Step Budget for how max_steps truncation works, and Agent Run Outcomes → CLI Mapping for the SDK-to-CLI status mapping.

CI usage

Test the run in-process first — the CLI’s exit-code contract mirrors this success test.
The CLI does the same success test for you and returns exit 1 on failure:
Branch on the JSON status to handle all three outcomes — success, truncated, and failed:
Or branch on the exit code directly:
See Step Budget for the truncation contract, and Agent Run Outcomes → CLI Mapping for how the SDK-level statuses map to these exit signals.

Standalone vs wrapper

On a standalone pip install praisonai-code install, default run "…" and the human-readable text modes (--output plain/verbose/silent) route through the in-process Agent (PR #2853) — the same path used by the structured modes (--output actions|json|stream|stream-json). As of PR #3818, chat and code also open their resident interactive TUI standalone — pip install praisonai-code alone delivers run, chat, and code:
Pre-PR-#3818 praisonai-code builds emitted Error: chat requires the praisonai wrapper on a standalone install. Upgrading to a build with the resident TUI removes that hint — chat and code now run without the wrapper.
Every text mode — default run "…" and --output plain|verbose|silent|actions|json|stream|stream-json — plus interactive chat/code runs with no wrapper. The wrapper (pip install praisonai) still adds the gateway, channel bots, and the richer legacy interactive dispatch. See the PraisonAI Code CLI standalone-limits table for the full command matrix.
run --output actions honours --tools and --toolset. These flags were previously dropped in actions mode; they now reach parity with the default, YAML, and Python surfaces. The same ToolResolver path resolves comma-separated names, and tools.py file paths continue to load as before.
run --agent honours --tools, --toolset, and auto-discovers .praisonai/tools/*.py. These were previously silently dropped when --agent was used. The --agent path now composes its toolset by unioning the agent’s frontmatter tools: list with --tools/--toolset and (when PRAISONAI_ALLOW_LOCAL_TOOLS=true or --allow-local-tools is set) auto-discovered project-local tools, dedup’d by callable identity. Fixes #3047.

Examples

Run a built-in preset (no YAML required)

Run with a custom agent

Run with delegatable subagents

Let the running agent hand named sub-tasks to your other .praisonai/agents/*.md agents, each under its own model/tools/permissions.
Wiring is a no-op when no delegatable agents exist — default runs are unchanged. See Named Agent Delegation.

Run with a custom agent and CLI permission override

Run with reasoning effort

--thinking applies across direct-prompt, actions-mode, and custom-agent paths. See Thinking.

Run with a custom command

Session flags (--continue, --session, --fork, --no-save) work with --agent.

Run from YAML file

To gate a workflow file with the same --allow / --deny / --approval rules you use on a prompt run, see YAML Workflows Are Permission-Gated.

Run with a prompt

Run in read-only planning mode

--plan denies every mutating tool (write/edit/delete/shell/exec). See Permission Modes and Permissions.

Run in a monorepo

Touching a nested package auto-loads that package’s AGENTS.md — no config, same as chat.

Run with specific model

Run in interactive mode

Run with memory enabled

Run with verbose output

Run with custom tools

In run actions mode, --tools and --toolset are now wired end-to-end (previously silently dropped). The same is now true for run --agent <name>--tools/--toolset merge into the agent’s frontmatter tools: list instead of being dropped (#3047).

Run with project-local tools

Local .praisonai/tools/*.py files require an opt-in because loading them executes Python:
If tool files exist but neither is set, run prints a one-line hint naming the location(s) and enable step — no more silent skip. See Project-Local Tools.

Resume a previous session

Continue where you left off in your current project:
Resume a specific session by ID:
Fork from a session to try a different approach:
Run without saving the session:
--continue and --session restore the model recorded on that session — even if your default model has changed since. Pass --model <name> to override and update the recorded model going forward. See Session Resume — Model Restoration.
After every run with an active session, a compact usage footer prints to stdout:
This footer is silenced under --output json. Token and cost totals accumulate across resumed runs — they are never reset. See Cost Tracking for per-session totals.

Run without project instruction files

By default, praisonai run auto-loads AGENTS.md, CLAUDE.md, PRAISON.md, etc. from the project root and attaches nested-subtree instruction files as the agent touches them. Use --no-rules (or PRAISON_NO_RULES=true) to opt out of both:
Use --verbose to see which instruction files were loaded:

Isolated worktree runs

Pass --worktree to run the agent on a fresh git branch and worktree so its output never touches your working tree. Add --keep to retain the worktree and branch for review.
See Run in an Isolated Worktree for the full teardown behaviour matrix and rejected-combination rules.

Live session attach

Tag a warm-runtime run with a session id so other terminals can stream its events with praisonai attach.
--attach <id> is an event-stream label, not a session identity — it only fans out live events to praisonai attach <id> clients (falling back to the session id when omitted). It does not by itself select or persist a conversation; persistence is driven by --session <id> or --continue. So praisonai run "..." --no-save --attach obs-1 streams events under obs-1 but persists nothing.--attach is supported for direct prompt runs only — not YAML files, --agent, or --command. Requires a compatible warm runtime (praisonai daemon start). Major-version mismatch falls back to in-process execution for run, or exit code 1 for attach.

Isolated Runs (--worktree)

Add --worktree to run the agent on a fresh git branch and worktree so its edits never touch your working tree.
--worktree provisions a fresh git worktree on a new branch, chdirs into it, runs the agent, then prints the branch name and a git status --short summary. Every other flag (--tools, --model, --session, --thinking, --memory) applies unchanged.

How teardown protects your output

Changes are detected with git status --porcelain, so brand-new untracked files count. When the agent produced output, the CLI auto-commits everything to the branch (praisonai run: <target>, --no-verify) and retains the branch — only the worktree checkout is pruned. A run with no changes is torn down completely. If the auto-commit fails (for example no user.email/user.name is configured, or a hook rejects it), the worktree checkout is kept in place with a Could not commit isolated changes; worktree kept at <path> (branch '<branch>') for manual review. warning — your output is never lost.

What happens on teardown

The run detects changes with git status --porcelain, so brand-new (untracked) files are never lost.
--worktree never destroys the agent’s output. On any change the branch is committed and retained even without --keep — only the worktree checkout is pruned.

When to use it

Recipes

A short uuid4 token is appended to each run’s branch name (e.g. praisonai/agents.yaml-a1b2c3d4), so concurrent runs of the same target never collide.

Compatibility

The CLI rejects incompatible combinations at parse time.
A short random 8-char token is appended to every branch/worktree name, so two runs of the same target never collide — run praisonai run "..." --worktree twice in parallel and each gets its own branch and directory.

Best practices

On completion, any tracked or untracked change is committed to the branch and the branch is retained. Even if the auto-commit fails (missing user.email/user.name, hook rejection), the worktree checkout is kept in place — you never have to fight the CLI for your agent’s output.
Auto-commit already preserves your work on a branch. --keep is for cases where you want to review files in place before merging — compare screenshots, or run a local dev server against the checkout.
The flag is a transparent no-op outside git. Wire it into every project script without conditionals: praisonai run --worktree "..." runs in the current cwd if there’s no repo, printing Not a git repository; running without worktree isolation.
--keep never auto-removes. When you’re done: git worktree remove <path> && git branch -D praisonai/…. To see leftovers from all runs: git worktree list.
Three ways to get worktree isolation, one shared primitive:
  • CLI (this page)praisonai run --worktree for one-off human-driven runs.
  • Kanban — set workspace_kind="worktree" on a task so dispatched workers each get one (Per-Task Worktree Isolation).
  • Library — instantiate GitWorktreeAdapter yourself for programmatic isolation (Workspace Isolation).

See Workspace Isolation for the underlying GitWorktreeAdapter and the Python API.

Project context

By default, praisonai run walks up from the current directory to your git root and prepends any AGENTS.md / CLAUDE.md / agents.md / .agents/AGENTS.md it finds to the agent’s system prompt, layered on top of ~/.praisonai/AGENTS.md. In a monorepo it also attaches a nested packages/foo/AGENTS.md the first time the agent touches a file under packages/foo/ (parity with chat, wired in PR #3552). Pass --no-context (or set PRAISON_NO_CONTEXT=true) to disable the up-front walk-up, or --no-rules (or PRAISON_NO_RULES=true) to disable both. See Context Files for details.

Declared instruction sources

To declare extra instruction sources — files, globs, or URLs — that load on every run, use the top-level instructions: config key or the repeatable --instructions flag. Config sources merge first, then --instructions flags append on top; the result is prepended to the agent’s backstory as # Project Instructions. See Instruction Sources.
The --agent and --command paths honour declared instructions too:
--no-rules (or PRAISON_NO_RULES=true) suppresses these declared sources along with the auto-discovered walk-up.

Environment variables

These env vars gate the same context behaviour as the flags, for CI and scripted runs.

First-run Credential Check

praisonai run verifies credentials are configured before doing any work. With no cloud key, it first checks for a reachable local endpoint and adopts it automatically — the prompt below only appears when nothing is reachable. If no cloud key and no local endpoint is found, you’ll see: Interactive (TTY):
Local model reachable (no cloud key needed):
CI / non-interactive (no key and no local endpoint):
When no cloud key is set, PraisonAI probes for a local OpenAI-compatible endpoint (Ollama or any /v1-speaking server) and adopts it automatically before falling back — see Keyless local-first fallback. Non-TTY/CI still exits 1 when nothing is detected, so pipelines fail safe. Exit code is 1 in CI mode. Set any supported env var to bypass the check entirely:
“Supported env var” now means any of the 14 credential keys in the Credential → default-model map, so MISTRAL_API_KEY (or any catalogue key) also silences the credential gate:

Local model fallback

When no cloud key is configured, praisonai run "..." probes for a reachable local endpoint (Ollama or any OpenAI-compatible server) and adopts its model + base URL for the run — no --model needed. A cloud key always wins; the local probe only runs as a fallback.
See Auth, First-run Onboarding, and Keyless Local-First Run for the full behaviour matrix and CI examples.

Session Continuity

Pick up where you left off — praisonai run remembers per-project conversations and tracks cumulative token usage and cost.

Continue / session runs attach to the warm daemon

When a warm daemon is running, --continue and --session <id> runs now attach to it and reuse a warm, per-session agent instead of paying cold-start each turn. The first turn rehydrates history from the project session store; subsequent turns run against the retained warm agent. On failure the warm agent is dropped and the next turn rehydrates cleanly from the store, so recovery semantics match the in-process path. Fork (--fork) still runs the first turn in-process to mint the new id, then attaches warm on later turns against that id. See Daemon for the full warm-runtime lifecycle. When running with an active session (--session <id> or --continue), a compact footer appears after each answer:
The footer is suppressed in --json / --output json mode, but usage is still persisted into the session record. Totals accumulate across runs and survive resume. See Cost & Token Tracking for the full breakdown.
1

Continue the last run

Continue the most recent session for your current project:
--continue searches both the project store and the global default store, so it resolves the genuinely most-recent root session — including ones created by chat, gateway, TUI, API, or a bare Agent(memory={"session_id": "..."}). If no previous session exists, a warning is shown and a new session starts.
2

Resume a specific session

Resume a specific session by ID (find IDs with praisonai session list):
Errors out if the session ID does not exist in the current project.
3

Try a different approach without losing history

Fork from an existing session to try alternatives:
Creates a new session ID copied from the source. Both sessions evolve independently.
4

What gets restored on --continue / --session

When you use --continue or --session <id>, every prior user, assistant, assistant-tool-call, and tool-result message in that session is replayed into the agent’s chat history before your new prompt runs. The agent answers with full awareness of what was discussed and what tools it called — no manual context-passing required. Tool-call persistence in the default JSON store landed in PraisonAI PR #3099.Restored automatically: user, assistant, assistant-tool-call, and tool-result chat_history messages; auto_save continues for the resumed session.Not restored: intermediate scratchpad beyond the persisted tool turns; file artefacts from earlier runs remain on disk but are not re-emitted.
As of the fix for PraisonAI #2655, --continue searches both the project-scoped store and the global default store, so sessions created by chat, gateway, TUI, API, or a bare Agent(memory={"session_id": "..."}) are all resumable. Sub-agent / forked child sessions are skipped in favour of the last root session.
History restore and save wiring landed in PR #1963. Earlier builds discovered the session but silently dropped prior history on resume — upgrade praisonai if --continue returns empty context.

Choosing between the flags

--continue / --session / --fork / --no-save work for YAML/team runs identically to prompt runs. Prior team conversation — per-agent chat history and shared team state — is replayed. The flags are honored regardless of whether agents.yaml sets memory: true; session continuity opts the team into shared memory automatically. See YAML / Team Session Continuity.
After every prompt run inside an active session, a single-line footer shows cumulative token and cost totals:
The format is:
  • Totals are cumulative since session start — not just the last prompt.
  • Best-effort: if usage cannot be read or priced, the footer is silently skipped.
  • Suppressed in JSON mode (--output json, --output stream-json). There is no --no-usage flag.
  • Usage is persisted to ~/.praisonai/sessions/<id>.json so resuming with --continue or --session <id> rehydrates the totals and keeps accumulating.
JSON mode — the footer is suppressed but usage is included in the payload:

Troubleshooting session continuity

Fixed in PR #1963 — sessions were discovered but history was not loaded. Upgrade praisonai and re-run.
Fixed by PR #1963. Upgrade praisonai.
Fixed by commit 7016bfa (issue #2700). The actions-output branch of run re-imported build_cli_memory_config / apply_cli_session_continuity from praisonai_code.cli.utils.project, shadowing the correct praisonai_code.cli.state.project_sessions versions. The stale variant lacked the auto_save keyword, so wiring session continuity in actions mode raised TypeError: apply_cli_session_continuity() got an unexpected keyword argument 'auto_save'. Upgrade praisonai-code and re-run.
Also fixed by PR #1963 — YAML and file-mode runs use the same project session store as prompt-mode runs.
--no-save wins — the run still resumes from the named session (agent has context), but new messages are not persisted. Useful for read-only follow-ups on an existing thread.
Sessions are scoped to the current project — detected from the git root, or the current directory if you’re not in a repo. Two projects never see each other’s sessions.

Agent File Format

Create an agents.yaml file:

Session Management

Sessions are scoped to the current project (git root, or current directory if not a git repository). Each run auto-saves to a generated session-<uuid8> unless --no-save is set.
Use praisonai session list to view saved sessions for the current project, or praisonai session list --all to see sessions across all projects.

Checkpoint & Rewind

praisonai run auto-checkpoints your workspace before YAML-file runs so a bad turn can be rewound with one command.
Auto-checkpoint behaviour:
  • Runs before any YAML-file execution (*.yaml / *.yml targets only).
  • Label: run:<run_id> (or "auto checkpoint before run" as a fallback).
  • Workspace: the directory of the target YAML file, not the current directory.
  • Plain-prompt runs are skipped to avoid empty-checkpoint noise.
  • Best-effort — failures are swallowed and never block the run. Use --verbose to see "Auto-checkpoint skipped: …" on failure.
  • Gated by checkpoints.auto (default true) in your project config; override per-run with --no-checkpoint.
  • Reads checkpoints.storage_dir from your project config so the auto-checkpoint/restore path shares the same store as praisonai code --checkpoints sessions. See Checkpoints for the config block.
New checkpoint flags:
--restore rewinds the workspace and exits before any agent execution — it is a pure undo, not a run. See Checkpoints and Checkpoint CLI for managing checkpoints directly.

Coherent rewind (--revert)

Roll files and the named session’s conversation back to a prior turn, then exit. Distinct from --restore, which is file-only.
When --session <id> is provided the flag also rewinds that session’s conversation to the same boundary. Rewind counts real user messages (not a fixed 2·N assumption) so tool/system messages don’t orphan a partial turn.
File checkpoints are workspace-wide (they carry no session tag). In a workspace shared by multiple sessions the Nth-back file checkpoint may not belong to the session whose conversation is being rewound — the CLI prints this note explicitly and recommends interactive /undo for fully per-session coherence.

YAML Workflows Are Permission-Gated

praisonai run workflow.yaml honours the same approval and permission flags as a single-agent praisonai run "<prompt>". The flags are threaded onto the workflow engine, so a YAML run can no longer bypass a deny rule that a prompt run would enforce.
On older versions these flags were silently dropped on the YAML path, so a --deny "bash:rm *" on a workflow file did nothing. They are now enforced. Runs with no permission or approval flags are unchanged — see the backward-compatible default below.

Precedence ladder

What propagates to a YAML run

praisonai run workflow.yaml --approval console (or plan, accept-edits, bypass) sets the backend for the workflow run — identical to the prompt path.
A --deny, --allow, --permissions, or --permission-default on its own activates a console backend. Without this, a permission rule on a YAML workflow used to be silently bypassed.
Both propagate to YAML runs, matching the single-agent run "<prompt>" semantics.
A plain praisonai run workflow.yaml --no-save with no permission or approval flags threads no approval override at all, so the legacy engine preserves prior behaviour exactly. Existing pipelines see no change.
--continue, --session <id>, --fork, and --no-save already flow into the same YAML engine; the approval/permission flags now compose with them. A --no-save workflow run with only --allow sets approval without persisting a session.
Permission rules come from CLI flags and project config, merged the same way the prompt path merges them — so a YAML run picks up .praisonai/permissions.yaml (or equivalent) identically. See Permissions.
For the full approval-gating story and backend semantics, see Approval › YAML workflow approval gating.

See Also