Skip to content
Home
Docs/Workflows

Workflows

Free — the whole engine

A workflow is a trigger and a sequence of steps that run over a shared context. It all happens on the device: there is no server to rent and nothing to keep alive in the cloud. Steps branch, loop and call each other, they reference each other's output through expressions, and they react to failure with retry, timeouts and a failure branch.

The step tree of a workflow with an if / else branch
The «Tests, then deploy if they pass» template. The branch is numbered — 2.1, 2.2 inside «if it matches», 2.e1 inside «otherwise» — and each step says what it does on failure. The Deploy step offers «Run this step for real» rather than «Test this step»: it cannot be simulated, and the button says so.

Four ways to make one

The module opens on a welcome screen. Whichever path you take, what you end up with is the same editable workflow.

Templates

17 built-in templates in four families. Tap Activate and you get an editable copy with a fresh id — nothing is shared with the original.

Describe it to the AI

Write a sentence. The model's answer is repaired where it can be, run through the linter, dry-run, and the result is shown to you before anything is saved.

The editor

A step tree with nested blocks, a searchable action palette, undo/redo, copy-paste of steps and a problems panel. On a tablet the step config opens as a side panel instead of a sheet.

Import a file

Someone shares a .pcwf.json and you open it. It arrives disabled and with a new id, so nothing runs until you have read it.

Triggers (25)

A workflow has one main trigger and as many extra ones as you want, each with its own filter. The filter is typed: every trigger declares its fields, and you compare field against value with operators — equals, contains, starts with, matches, path globs. It is not a substring search over the event's text.

GitGit push · Git commit
FilesFile saved · File created · File deleted · File renamed
Project and buildProject opened · Project closed · Build finished · Run finished · Terminal command finished
Deploy and dataDeployment completed · Deployment failed · Database query executed
Other modulesAPI Tester response · Design exported · AI agent touched a file · AI agent finished a turn
From the phone itselfShortcut · Quick Settings tile · Shared text · Shared file · App foregrounded
Chaining and manualError detected (another workflow failed) · Manual or scheduled

Not every type has something emitting it yet. Rather than hide those, the editor's problems panel warns you when a workflow uses a trigger that would never fire today — a trigger that exists and cannot be used is worse if nobody says so. There is also a «capture the next event» button: you do the thing, and the editor shows you the real payload the trigger carries so you can write the filter against something real.

A trigger and its filter
A trigger with no condition says so in words — «this trigger fires with every event of its type» — instead of leaving an empty box you have to interpret. Underneath, «capture the next event» listens once and shows you the real payload.

Actions (15)

All fifteen are wired to something that really runs, and a test goes red naming any type that loses its implementation. A type with nothing behind it fails loudly instead of quietly reporting success — that used to be possible and is not any more.

ActionWhat it doesOutputs
Run terminal commandRuns a command in the terminalcommand · exitCode · stdout · stderr · durationMs · timedOut
HTTP requestCalls an endpoint; the body is parsed as JSON when it is JSONstatus · body · json · headers · durationMs
Git operationcommit, push or pullsha · branch · changedFiles · ahead · behind · text
DeployTriggers a deploy on the connected providerstatus · url · provider · projectName · logsTail · reason
Database queryRuns a query against the active databaserows · rowCount · columns
Database backupBacks up the active databasepath · sizeBytes
Read fileReads a file from the projectcontent · sizeBytes · path
Write fileWrites or appends to a file in the projectpath · bytesWritten · created
File existsChecks whether a path existsexists · isDirectory · sizeBytes
Open fileOpens a file in the editor, optionally at a linepath · line
AI analyzeSends code or text to the assistant and captures the answertext · model · tokens
AI generateGenerates new code from a prompttext · model · tokens
TransformReshapes a value with the expression filters — no side effectsvalue
Set variablePuts a value into the run context for later stepsname · value
NotificationShows a notification with title and messageshown

Whether a step is destructive is worked out with its parameters in hand, not from its type: git status is not git push, and creating a new file is not overwriting one. Labelling the whole type destructive would mean confirming a status, and asking for confirmation on everything teaches people to accept without reading.

The action palette
The palette searches by name, by description and by output name — if you know you want stdout, you do not need to know what the action is called. Each entry shows what it gives you and marks what is irreversible before you add it, not after.

Branches, loops and sub-workflows

Seven kinds of step, of which six are control flow. Branches nest inside branches, so what you build is a tree, not a straight line.

If / else

Two branches. The condition is a tree, not a single slot: And, Or and Not nest, so «tests passed and the branch is main» is one condition, not two workflows.

Parallel

N branches at once, joined one of three ways: when all finish, with the first that finishes, or with the first that finishes well. The last two cancel the losing branches so they stop firing side effects.

For each

Iterates a list with a per-item alias, a safety cap on iterations, and an optional number of iterations to run at once.

Try / on failure

If anything in the first block fails, the second runs with the error message bound to a variable you name.

Sub-workflow

Runs another workflow inside this run, with its own inputs. The child inherits the intersection of the permissions — it cannot open what the parent closed.

Wait

Pauses for a time — or until an event happens, with the time as the cap. «Wait for the deploy to finish» rather than «wait two minutes and hope».

A condition on any step

Every step carries an optional condition of its own: if it is false the step is skipped, without wrapping it in a whole if / else.

Passing data between steps

Any field takes a literal or an expression in double braces. The editor offers a picker, so you do not have to remember step ids.

ExpressionResolves to
{{var.name}}A declared input or a value a step set
{{step.<id>.status}}SUCCESS, FAILURE, SKIPPED, TIMED_OUT
{{step.<id>.output}}The whole output map
{{step.<id>.output.json.items[0].name}}A field of the output, navigating inside JSON
{{step.<id>.error}}The step's error message
{{item.<alias>}}The element of the live iteration
{{trigger.<field>}}The typed payload of the event that fired it
{{secret.NAME}}A stored secret. Terminal — you cannot navigate inside one

Chainable filters

lines · first · last · trim · upper · lower · length · json · default:"x" · split:"," · join · date:"HH:mm" · replace:a:b

So the first line of a command's output is {{step.sh.output.stdout | lines | first | trim}}.

When something goes wrong

Reliability is set per step, and the workflow sets the defaults the steps inherit.

Retry

Number of attempts, with a fixed, linear or exponential wait and a cap on that wait

Timeout

Cancels the step and marks it TIMED_OUT. A timeout is not retried — it comes back as it is

On failure

Stop the run or carry on. Carrying on does not tint the run: the step stays red and the run comes out green

Off

A disabled step is skipped without running. It is what you want while debugging, instead of deleting it and typing it again

And for the whole workflow

Run cap

A time limit for the whole run, not just one step

Concurrency

What to do when a trigger arrives with a run already in flight: skip it, queue it, or cancel the previous one

Default on failure

The value steps inherit when they do not set their own

Retention

How much history to keep: 100 runs and 30 days by default, anywhere from 1 to 1,000 runs and 1 to 365 days

Result step

Which step's output is the workflow's answer when the AI agent calls it

Strict expressions

Off by default, so a reference to a branch that did not run gives an empty string instead of felling the run. On, it is an error with a reason

There is also a cap across the whole app: eight runs at a time. Beyond that they queue, and a run that is turned away or skipped is written to the history as cancelled, saying which of the two caps it was. It is not silent.

Scheduling — cron on your phone

Any workflow can carry one or more schedules: an interval, or a five-field cron expression with wildcards, lists, ranges and steps. As you type, the app shows the next fire time or tells you the expression is wrong. Schedules survive the app closing and are queued again on launch.

Time zones and daylight saving

Each schedule stores its own zone, and the awkward days are resolved and tested: in spring, at the hour that does not exist, it fires on the jump; in autumn, at the hour that happens twice, it fires once.

Missed runs

You choose: skip whatever fell while the device was off, or catch up once when it comes back. Once — not the forty-eight of a long weekend.

Device conditions

Any network, Wi-Fi only or none; only while charging; not on low battery; only while the device is idle. A condition delays the run, it does not cancel it — and the screen says so.

The fifteen-minute floor

Android does not run background work more often than every fifteen minutes. An interval below that is raised and the app tells you the exact number. A cron below it is nobody's to raise, so the only true thing to say is that there is no guarantee — and that is what the screen says, instead of a number that would be made up.

The editor

A step tree with undo and redo, keyboard shortcuts, copy and paste of steps, and drag to reorder. Its problems panel runs 34 rules across structure, parameters, expressions, triggers, loops, reliability, security, sub-workflows and permissions. Only errors block saving; warnings do not — someone who closes a workflow's network usually does it before removing the step that used it, and blocking there would stop them finishing.

Testing one step on its own

Rather than running the whole workflow — with its deploys and its notifications — every time you tweak a parameter, you can run a single step with the pinned data as its context. A step whose implementation says it cannot be simulated is not simulated: the button then says «run this step for real» and asks first. A button that says «fine» without having run anything is worse than no button.

History and activity

Every run is written down whole, with each step's result, how long it took, how many attempts it needed and its error if it had one. It survives crashes and the app closing.

  • •An Activity tab across every workflow, filtered by status, by date, by workflow and by the text of the error
  • •Per-run detail: step by step, with the output in monospace and the reason it stopped
  • •The live log is batched into 100 ms windows before it reaches the screen — a git clone with its progress bar emits hundreds of lines a second
  • •Retention is yours to set: 100 runs and 30 days by default

Permissions and secrets

What a workflow is allowed to do

Per workflow: go out to the network, write files, run commands, and a list of domains it may reach. The implementations check before they touch anything, and a refusal says which permission it was, what was about to run and where to change it.

It is not a sandbox, and the screen says so: anyone who can edit the workflow can open the belt. It protects against carelessness — a workflow you opened to the AI, one someone else sent you, or the curl somebody pasted «just to try» and left there.

Secrets

An encrypted store, per account. You reference a secret as {{secret.NAME}} and its value is never shown again, not even on its own screen.

  • • They are only resolved in a real run — a dry run does not take them out of the store
  • • The masking covers every stored value, not only the ones a step read: if you pasted your token by hand into a command, it is masked too
  • • And it happens before writing to the database, not when drawing the screen — masking at paint time would be too late, the value would already be in the file and in any backup

The domain allowlist only reaches HTTP steps: an AI, deploy or git step goes to whatever service it has configured, and the screen says so in those words. The host name is compared, not the address it resolves to, so it is not protection against SSRF. Separately, every file path is confined to the project root.

The permissions block in the editor
The summary is a sentence, not a row of icons: it tells you what this workflow may do, and then says outright that it is not a sandbox and that whoever can edit it can change this.

What the AI can do here

Write one from a sentence, or change one you have

The answer is repaired where it can be, checked by the linter and dry-run, and shown to you before anything is saved. Changing an existing one merges the answer on top, keeping its id, its switch and its date, and shows you the diff. If you have no model configured there is a local fallback — which is the only thing that works for someone who has not put in a key yet.

Workflows as tools for the agent

Tick «available to AI agent» on a workflow and the chat can call it. Six tools in all: three that read (list, get, runs) and three that write (create, update, run) and go through the agent's confirmation gate.

The document sent to the model carries no secret parameter values — they are replaced by a marker.

Templates (17)

A test is the templates' linter: it checks that every trigger has something emitting it, that every action is wired, that every parameter key is declared, that every expression points at something real, and that a dry run of each template finishes without leaving the run in failure. A template that does not work is not shipped.

Classic · 8

Prettier on save · Auto-commit on Kotlin save · Lint the file you just saved · Tests then deploy if they pass · Auto-deploy on push to main · Tests after push to main · Test on commit · DB backup after deploy

Data flow · 3

HTTP health check · Three endpoints in parallel · Release notes from the commit log

Control flow · 3

Deploy or tell me why not · Test every module you touched · Branch protect

From the phone · 3

Share a link straight into the project · Nightly backup · Tests on the branch you are on

The template gallery
Grouped by when you would want them — when you edit, when you use git, around a deploy, when something breaks, from your phone — and each card says what it needs before you activate it.

Sharing one

A workflow travels as a .pcwf.json file. What does not travel: the run history, the pinned outputs, the schedules and the on/off switch. What arrives is disabled and has a new id.

Parameter values marked secret are emptied before the file is written — and listed, so whoever opens it knows what they have to fill in. A {{secret.NAME}} reference does travel: it is a name, not the secret, and emptying it would break the workflow beyond repair. A file that is not ours, a damaged one and one written by a newer version give three different messages, because they are three different things and only one has a way out.

What costs money

The engine is free, with no asterisks

The 25 triggers, the 15 actions, branches, loops, sub-workflows, cron scheduling, permissions, secrets, the whole history, exporting, the templates, and exposing a workflow as a tool for the AI agent — all of it is on the free plan.

Pro: asking the AI to write or change one

That is the one paid thing, and the limit lives in the chat, not here. Letting the agent run a workflow you already marked as available is free — that tool is the only thing that makes the tick mean anything. History and export are free too: charging for them would be taking away something people already have, and export is the only way to get your work out of the app.

What is not there

Worth knowing before you plan around it.

Webhook triggerOut of scope: it needs a backend, push and a secrets model that reaches the server
Exact alarmsThe floor is fifteen minutes and the app says so, rather than asking you for another permission
Workflows in the MarketplaceNeither installing nor publishing. Sharing a workflow today means sharing the file
Time zone pickerEvery schedule is stored with a zone and handles daylight saving, but new ones take the device's
A graph canvasBranches are a nested tree, not nodes you wire on a canvas: no N-way switch and no arbitrary merge
Anti-SSRF on the domain allowlistThe host name is compared, not the address it resolves to

The module in numbers

25

Trigger types

15

Actions, all wired

7

Kinds of step

17

Templates

34

Linter rules

13

Expression filters

6

AI agent tools

8

Concurrent runs, app-wide