Workflows: Automate Dev Tasks on Android, No Server Needed
Automate tasks on Android with PocketCode Workflows: event triggers, cron scheduling on your phone, retries and a visual editor — no server, all on-device.
Every developer accumulates the same little chores: run the tests after a push, back up the database once a deploy lands, format on save, ping yourself when a build fails. On a laptop you glue these together with CI runners, cron jobs and a couple of shell scripts on a server somewhere. On a phone, the usual answer is "you can't." PocketCode changes that with Workflows — an event-driven automation engine that lets you automate tasks on Android entirely on the device, with no server to rent and nothing to keep alive in the cloud.
A workflow is simple to describe: a trigger (an event inside the IDE, or a schedule) plus a sequence of steps that run against a shared context. That's enough to build real dev workflows — the kind you'd normally stand up a CI pipeline for — right next to your editor, terminal and database manager.
Three ways to create one
You never have to start from a blank canvas. The module gives you three on-ramps:
| Mode | How you create it | Example |
|---|---|---|
| Template | Tap Activate on one of the 8 built-in templates | "CI/CD Pipeline", "Auto-Deploy on Push", "DB Backup on Deploy" |
| AI Generate | Type a prompt, get an editable scaffold | "when push to main, deploy and notify" becomes a 2-step workflow |
| Editor | Tap the "+" FAB for the full form | Build from scratch with bindings and retry policies |
Activating a template clones it into an editable copy with a fresh ID, so you can tweak it without touching the original.
Triggers: what wakes a workflow up
Workflows listen to events flowing through the IDE. The engine subscribes to the app's internal event bus and maps each event to a trigger type. There are ten trigger types:
| Trigger | Fires on | Typical filter |
|---|---|---|
| Git push | A completed push | branch ("main", "develop") |
| Git commit | A new commit | branch |
| File saved | A file save in the editor | extension (".kt", ".ts") |
| App opened | The app coming to foreground | — |
| Terminal command finished | A terminal command completing | command pattern |
| Database query executed | A query result landing | table name |
| Deployment completed | A successful deploy | provider ("vercel", "railway") |
| Deployment failed | A failed deploy | provider |
| Error detected | Another workflow failing | workflow name / error pattern |
| Manual | Nothing — run by schedule or by hand | — |
Only enabled workflows whose trigger type matches enter evaluation, and an
optional filter narrows it further with a case-insensitive substring match —
so a Git-push workflow filtered to main ignores every other branch.
Scheduling: cron on your phone, no server
This is where "no-server automation" gets concrete. A workflow with a manual
trigger and an attached schedule becomes a scheduled job. Under the hood the
scheduler wraps Android's WorkManager, and it offers two modes.
Interval schedules use a periodic work request. WorkManager's floor is 15
minutes, so shorter values are clamped up. The presets:
| Preset | Interval |
|---|---|
| Every 15 minutes | 15 min |
| Hourly | 60 min |
| Every 6 hours | 360 min |
Cron schedules are the interesting part. PocketCode ships its own 5-field
cron parser (minute, hour, day-of-month, month, day-of-week) — no external
library — supporting * wildcards, single values, N,M lists, N-M ranges and
*/N steps. Two cron presets are built in:
- Daily at 9am —
0 9 * * * - Weekly, Monday at 9am —
0 9 * * 1
Because WorkManager's periodic API can't express real cron, each cron run is
scheduled as a one-time job that re-arms the next fire when it finishes,
keeping the cron alive indefinitely. The schedule editor shows a live
"Next fire" preview computed from your expression, and turns red with
"Invalid cron expression" the moment the parse fails — immediate feedback before
you save. The parser deliberately keeps things simple in this version: month and
day names, ?, L, #, seconds and year are not supported.
Schedules are persisted, and are re-queued on app startup so a process death doesn't quietly empty your automation.
The visual editor
The editor is a full form: name, description, an enabled switch, a trigger dropdown with an optional filter, and a vertical list of step cards you can reorder, edit or delete. Adding a step opens a picker split into Control flow (Wait, If / Else) and Actions — eight action types, each with a readable label and a dynamic config form:
| Action | Form fields |
|---|---|
| Run command | Command |
| Notification | Title, message |
| AI analyze | Prompt, language (optional) |
| AI generate | Prompt, language (optional) |
| Git operation | Operation (commit/push/pull), branch, message |
| Deploy | Branch (optional) |
| Database backup | Command (optional) |
| Open file | File path, line (optional) |
Each action step also has collapsible Reliability and Conditional sections (more on those below). Nothing hits the database until you press Save in the top bar — apply and cancel work on local editor state so you can experiment freely. Save is enabled only once the workflow has a name and at least one step.
The editor exposes Wait and one level of If/Else today. The engine itself also executes Loop, Parallel and Try/Catch steps, but a visual editor for those is a known follow-up rather than a shipping surface — so treat them as engine-level building blocks, not something you can drag in from the picker yet.
Passing data between steps
Steps don't run in isolation — they share a context, and any value field can
reference an earlier step with a {{binding}}. The syntax:
| Expression | Resolves to |
|---|---|
{{var.<name>}} | A context variable |
{{step.<id>.status}} | A step's status |
{{step.<id>.output.<field>}} | A field from a step's output |
{{step.<id>.error}} | A step's error message |
{{item.<alias>}} | The current item inside a loop |
{{trigger.eventName}} | The event that started the run |
An expression that doesn't resolve returns an empty string on purpose, so a binding to a step that never ran (say, in a skipped conditional branch) doesn't blow up the whole run. Conditions build on the same idea: compare resolved values with equals, not-equals, greater-than, less-than, contains or is-null, and combine them with the usual and/or/not boolean logic.
Reliability: retries, backoff and timeouts
Automation you can't trust isn't automation. Every action step supports a retry policy and a timeout, surfaced in that collapsible Reliability section:
| Setting | Default |
|---|---|
| Max attempts | 1 (no retry) |
| Backoff strategy | Exponential |
| Initial delay | 500 ms |
| Max delay | initial × 30 |
| Timeout | none |
Backoff comes in fixed, linear and exponential flavours (exponential doubling: 500, 1000, 2000, 4000…), each capped at the max delay. Timeouts are real timeouts — when one fires, the step is marked as timed out. There's also a lightweight condition you can attach to a single action: bind it to a value, and that one step is skipped when the value is empty, false, 0 or null — so you can gate a single step without wrapping it in a full conditional.
Run history you can inspect
Every run is persisted with a full snapshot of its step results, which means the
history survives crashes. The Runs timeline lists runs newest-first with a
status icon, timestamp, step count, duration and a one-line error preview if
something failed. Tapping a run opens a step-by-step drill-down: per-step
status colour (success, failure, skipped, timed-out, running), the step's
duration, its output rendered as key=value pairs, and any error string.
Retention is automatic — the repository keeps the latest 100 runs per workflow and drops anything older than 30 days, so history stays useful without growing unbounded.
Templates to start from
Eight built-in templates cover the common cases, so you can have working automation in one tap — activating one clones it into an editable copy, so tweaking it never touches the original:
- CI/CD Pipeline — on push, run the tests, deploy, and notify you
- Auto-Deploy on Push — on push to
main, deploy and notify you - DB Backup on Deploy — once a deploy completes, back up the database and notify you
- On a workflow error, notify you and ask the AI to suggest a fix
- On file save, run Prettier (
prettier --write .) - On file save, stage and commit (
git add -A && git commit) - On push to
main, run the tests and notify you the branch is protected - On every commit, run the tests and notify you
Describe it in plain English
If you'd rather not assemble steps by hand, the AI Generator turns a prompt
into an editable workflow. It reads keywords to infer a trigger ("push", "deploy
failed", "error", "save"…) and a sequence of actions ("deploy", "backup", "test",
"format", "notify"…), then shows a preview you can Save & enable or discard.
A prompt like "when push to main, deploy and notify" produces a two-step
workflow wired to a Git push on main. The generator also has an LLM-backed path
that uses your configured AI provider and falls back silently to the heuristic
parser if anything goes wrong — so you always get a preview or a clear
"couldn't infer" message.
Your automation stays on your device
Workflow definitions, run history and schedules live in a local database on
your phone. Definitions can be backed up to the cloud for restore, but nothing
in the cloud is ever read to run your automation — the engine executes locally,
period. Run history and schedules aren't synced at all: history is device-local,
and schedules are WorkManager state that's specific to each device. Your
automation is yours, and it runs where you are.
PocketCode is heading to Google Play, bringing a full automation engine — triggers, cron-on-phone scheduling, retries and a visual editor — into the same app where you write and ship the code. Join the pre-registration to be among the first to try it on your own device.
Workflows