Automations
Flows react to what happens on your trackers and repositories, and keep running with the app window closed.
Triggers & actions
Triggers
Ten, in the order the picker offers them:
| Trigger | Fires when |
|---|---|
issue_status_changed | An issue's status changes on a watched board |
task_status_changed | One of your tasks reaches a state — an agent landing in needs_review |
issue_created | A new issue appears on a watched board |
issue_assigned | An issue's assignee changes |
schedule | An interval elapses or a cron time arrives |
webhook | An inbound HTTP call matches a locally recorded endpoint + token |
git_push | A watched repository/branch's HEAD moves |
pr_merged | A pull request or merge request merges — GitHub and GitLab, polled per (integration, repo) |
ci_status | A CI run reaches a terminal state — GitHub and GitLab |
manual | You run the flow yourself — how to test one before arming it |
Conditions narrow any trigger further, with operators including regular-expression
matches, label membership, priority ranking and a business-hours guard.
Actions
| Action | Does |
|---|---|
create-worktree | Open a worktree + task, reusing one already linked to the ticket |
run-agent | Spawn an agent into the task |
open-pr | Open a pull request |
set-issue-status | Push status back to the tracker |
set-task-status | Move the task's own state |
notify | Desktop notification or log line |
run-command | Run a shell command in the worktree |
http-request | Call a webhook |
if | Branch: run one sub-sequence or another depending on conditions |
run-agent chooses how long the flow waits on it: until_review,
until_done, or fire_and_forget. That is what lets a flow start an agent
and then act on the result rather than merely launching it.
Actions interpolate values from the trigger — {{ issue.key }},
{{ issue.title }}, {{ worktree.branch }} — and interpolated values are
shell-quoted, so a ticket title cannot inject a second command.
Safety rails
- Disabled by default, with a per-flow arming level:
disabled,dry_run,manual_approveorauto. - The priming gate. The first poll of a board records a baseline and fires nothing, so enabling a flow does not stampede over your existing backlog.
- Idempotency —
once_per_issue,once_per_transitionoralways, backed by a durable ledger, so a retried poll cannot run the flow twice for the same ticket. - A loop guard. A status change Muster itself made does not re-trigger the flow that made it.
- Rate limits per flow (runs per hour), plus at most one live run per
idempotency key — so
once_per_issueandonce_per_transitionserialise a ticket. There is no live-run cap: a flow set toalwaysstarts a concurrent run for every matching event. - A global kill switch that takes effect on the next tick, not on restart.
- Single owner. When the app and the daemon are both running against one database, a cross-process lease means exactly one dispatches each tick.
Every run is recorded with its steps, statuses and errors, so you can see what fired, what it did, and why it failed.
Running with the window closed
The daemon hosts the flow engine, so automations keep working after you close the app — provided the daemon is allowed to keep running. It polls on a fixed interval, resolves secrets from the same backend the app uses, and writes to the same database, so the runs you see in the app are the runs that happened.
session-only, secrets live in the app's
memory and the daemon genuinely cannot read them. It says so in its log rather than silently
failing to poll. Choose database or keyring for headless
automations.New here? Start the 7-day trial — every feature, card up front, $0 today, key on screen. Or buy outright: $39 once per device, no subscription.