Skip to content

Repository files navigation

AutoPie

AutoPie is a command hub and workflow runner for Android. It gives shell commands and Python scripts a friendly UI, runs them inside an embedded Termux environment, and lets you trigger them manually, from Android's share sheet, when files appear, on a schedule, from a home-screen shortcut, or from another app.

AutoPie currently supports aarch64/arm64-v8a devices (most newer Android phones).

AutoPie screenshot AutoPie feature demo
autopie-feature-demo1.mp4

What AutoPie supports

  • Bash commands, shell scripts, inline Python, Python packages, and Termux packages.
  • Multistage workflows with a persistent shell, per-step working directories and inputs, automatic step-to-step values, and reusable command steps.
  • Share-sheet commands for text, URLs, one or many files, and directories.
  • File observers with regular-expression filename filters.
  • Periodic commands through Android WorkManager.
  • Manual runs from the command hub and pinned home-screen shortcuts.
  • Calls from other Android apps through an explicit intent, with asynchronous or final result reporting.
  • Rich command inputs: strings, booleans, single-select, multi-select, flags, sliders, passwords/secrets, and file pickers.
  • Conditional inputs, persistent internal configuration, environment-backed options, and realtime controls.
  • A searchable command catalog with command documentation, install scripts, versions, and updates.
  • Per-command history, process logs, success/failure notifications, command search, cloning, and editing.
  • A full embedded Termux terminal. Install more software with pkg or pip.
  • Config storage in shared external storage or AutoPie's private app-data home.

Installation

  1. Download an APK from Releases or build it from source.
  2. Install it and accept any Play Protect prompt.
  3. Open AutoPie and wait for the embedded Termux bootstrap to finish installing.
  4. Grant the requested storage and notification permissions.
  5. If scheduled or background workflows are important, disable battery optimization for AutoPie.

If pkg install fails immediately after the first launch, reopen the terminal and give the bootstrap a little more time to finish.

Quick start

  1. Open AutoPie and press the add button.
  2. Choose Share, Observer, or Cron.
  3. Give the command a name and enter Bash or Python code.
  4. Optionally choose a working directory and add inputs under Extras.
  5. Save the command, then run it from AutoPie or its configured trigger.

You can also browse the command catalog to install ready-made commands and their dependencies.

Command types and triggers

Type When it runs Type-specific configuration
SHARE From AutoPie, Android's share sheet, a pinned shortcut, or another app Receives text, URLs, files, or directories
FILE_OBSERVER After a new file in the configured directory has finished being written selectors: a list of regexes matched against the filename
CRON Periodically in the background cronInterval: values such as 15m, 30m, or 1h

Android limits periodic work to a minimum interval of 15 minutes. AutoPie raises shorter cron intervals to that minimum. File observers can be disabled globally from Settings.

The three types live together in commands.json. If type is omitted, AutoPie treats the entry as a share command.

Command environment

AutoPie exposes inputs and extras as environment variables. Use normal shell syntax such as "$INPUT_FILE" or "${QUALITY}".

Variable Value
INPUT The raw active input. In a multistage workflow, the previous step's exported OUTPUT becomes the next step's INPUT.
INPUT_TEXT Shared or manually entered text.
INPUT_FILE A single file path, directory path, or first URL, depending on the input.
INPUT_FILES Multiple file paths separated by newlines.
INPUT_FILES_ARR INPUT_FILES converted to a Bash array; use "${INPUT_FILES_ARR[@]}".
INPUT_URL A single detected HTTP(S) URL.
INPUT_URLS All detected URLs in shared text.
FILENAME Input filename without its parent path.
FILENAME_NO_EXT Filename without its parent path or extension.
FILE_EXT File extension without the leading dot.
DIRECTORY Parent directory of the input file.
HOST Hostname for a URL input.
RAND A random four-digit number for collision-resistant output names.

Availability depends on the kind of input. Extras are exported under their configured uppercase name as well.

Examples:

Use Command
Extract audio from a video ffmpeg -i "$INPUT_FILE" -b:a 192K -vn "$DIRECTORY/$FILENAME_NO_EXT.mp3"
Combine images horizontally magick "${INPUT_FILES_ARR[@]}" +append "$DIRECTORY/$FILENAME_NO_EXT-horiz-$RAND.jpeg"
Run inline Python #@PYTHON followed by Python source on the next line

commands.json

AutoPie stores user and catalog commands in a single JSON object. Each top-level key is the command's display name.

{
  "Convert image to WebP": {
    "id": "local.convert-image-webp",
    "type": "SHARE",
    "path": "Pictures",
    "command": "magick \"$INPUT_FILE\" -quality \"$QUALITY\" \"$DIRECTORY/$FILENAME_NO_EXT.webp\"",
    "extras": [
      {
        "id": "quality",
        "name": "QUALITY",
        "type": "SLIDER",
        "default": "1,85,100",
        "description": "WebP quality",
        "required": true,
        "flags": ["--int"]
      }
    ]
  }
}

Common command fields:

Field Meaning
id Stable ID used by command references and Android intents. The top-level name is used as a fallback.
type SHARE, FILE_OBSERVER, or CRON.
path Working directory, normally relative to shared storage.
command Bash command or inline script.
selectors Regex list for a file observer.
cronInterval Periodic interval for a cron command.
flags Command-level behavior flags.
extras Inputs exported as environment variables.
multiStage / steps Enables and defines a multistage workflow.
version Installed catalog-command version used for update detection.

The legacy exec field is still accepted for packaged commands, but new shell commands can normally put the complete invocation in command.

You can edit commands.json directly from Settings → Edit Config File. AutoPie skips individual incompatible entries instead of hiding the rest of the valid configuration.

Multistage workflows

Set multiStage to true and provide a steps array. Steps execute in order in the same shell and with the same process ID, so exported variables and other shell state survive between steps.

Use a SHARE command for a multistage workflow. AutoPie's command hub, share sheet, shortcuts, and direct-intent runner drive the step transitions and any per-step UI.

{
  "Prepare and compress audio": {
    "id": "local.prepare-compress-audio",
    "type": "SHARE",
    "multiStage": true,
    "flags": ["--show-loading-screen"],
    "steps": [
      {
        "id": "prepare",
        "path": "Music",
        "command": "ffmpeg -y -i \"$INPUT_FILE\" \"$DIRECTORY/$FILENAME_NO_EXT.wav\"\nexport OUTPUT=\"$DIRECTORY/$FILENAME_NO_EXT.wav\""
      },
      {
        "id": "compress",
        "path": "Music",
        "command": "ffmpeg -y -i \"$INPUT\" -b:a \"$BITRATE\" \"$DIRECTORY/$FILENAME_NO_EXT-compressed.mp3\"",
        "extras": [
          {
            "id": "bitrate",
            "name": "BITRATE",
            "type": "SELECTABLE",
            "default": "192k",
            "selectableOptions": {
              "Small (128 kbps)": "128k",
              "Balanced (192 kbps)": "192k",
              "High (320 kbps)": "320k"
            }
          }
        ]
      }
    ]
  }
}

Workflow behavior:

  • If a step succeeds, AutoPie advances to the next step. A failed step stops the workflow.
  • export OUTPUT=... in one step passes that value to the next step as INPUT. AutoPie then clears OUTPUT, ready for the next handoff.
  • Other exported variables remain available because the shell stays alive.
  • A step with visible extras pauses the workflow and shows that step's input sheet. A step without visible extras continues automatically.
  • Every step may define its own id, path, command, flags, and extras.
  • An omitted step ID falls back to its zero-based position. At runtime, step IDs are namespaced under the parent command.
  • Parent command flags apply to the first step; later steps use their own flags.
  • Dismissing a workflow input sheet or cancelling its process stops the persistent shell.

Reuse an installed command as a step

A step can contain commandId instead of repeating a command:

{
  "Reuse installed commands": {
    "id": "local.reuse-demo",
    "type": "SHARE",
    "multiStage": true,
    "steps": [
      { "commandId": "namespace.first-command" },
      { "commandId": "namespace.second-command" }
    ]
  }
}

commandId must exactly match the stable ID of an installed share command. AutoPie resolves that command's path, command, flags, and extras before the workflow starts. A missing reference fails the workflow with a clear error instead of running a partial pipeline.

Extras and custom command UIs

An extra becomes an environment variable. For example, an extra named QUALITY is available as $QUALITY in the command.

Extra type UI and exported value
STRING Text input; can also become a password or file picker.
BOOLEAN true or false.
SELECTABLE One value from a label-to-value map.
MULTI_SELECTABLE Multiple values joined with newlines.
FLAG Exports its default value when checked, otherwise an empty string.
SLIDER Numeric value. Configure default as minimum,initial,maximum.

Useful extra fields:

Field Meaning
id Stable identifier used by visibility rules and saved values.
name Environment-variable name. Uppercase shell names are recommended.
default Initial/exported value.
defaultBoolean Initial value for a boolean extra.
required Makes an empty string extra open the input sheet instead of being skipped by a quick run.
description Help text shown below the input.
selectableOptions Object of display labels to exported values. A legacy string array is also accepted.
flags Input behavior such as secrets, pickers, layout, integer sliders, or realtime runs.
visibleWhen Condition that controls whether the input is shown.

Extra flags:

Flag Behavior
--password / --secret Masks the input and stores its value in AutoPie's private encrypted preferences instead of writing it into commands.json.
--internal-config Treats the value as persistent setup rather than an input that must be shown on every run.
--file-picker Adds a single-file picker to a string input. Names ending in FILE also get this behavior.
--multi-file-picker Adds a multi-file picker. Names ending in FILES also get this behavior.
--mime-type=audio/* Restricts a file picker; the default is */*.
--int Makes a slider use integer values.
--large Forces the input to use the full available row width.
--realtime Re-runs the current command when this extra changes.

String extras ending in FILE, FILES, or FOLDER are resolved to usable paths when relative values are supplied.

Conditional extras

Use visibleWhen to build dependent forms. A simple rule references another extra by extraId:

{
  "id": "custom_path",
  "name": "CUSTOM_PATH",
  "type": "STRING",
  "default": "",
  "required": false,
  "visibleWhen": {
    "extraId": "destination",
    "equals": "custom"
  }
}

Supported conditions are equals, notEquals, startsWith, endsWith, contains, matches (regex), gt, gte, lt, lte, oneOf, exists, and isEmpty. Compose rules with all, or/any, and not.

Values generated by an earlier step

For STRING, BOOLEAN, SELECTABLE, MULTI_SELECTABLE, and SLIDER inputs, a default or sole selectable value in the form $$VARIABLE_NAME is read from the workflow's live shell. This is useful when an earlier step discovers the valid choices or slider range.

For example, a preparation step can run:

export AUDIO_FORMATS='MP3=mp3,Opus=opus,FLAC=flac'
export VOLUME_RANGE='0,50,100'

Then a later selectable can use {"From previous step": "$$AUDIO_FORMATS"}, or a slider can set "default": "$$VOLUME_RANGE".

Realtime commands

Add --realtime to a command's top-level flags to re-run it whenever its visible inputs change, or add the flag to selected extras to trigger only on those values. Changes are debounced briefly, notifications are suppressed while adjusting, and the same shell/process is kept alive until the input sheet closes.

Command and script flags

Command-level flags:

Flag Behavior
--show-loading-screen Opens AutoPie's loading screen while the command runs.
--realtime Re-runs as inputs change in the extras sheet.

Script headers must appear at the beginning of command; multiple headers can be combined:

Header Behavior
#@PYTHON Treats the remaining command body as inline Python.
#@INTERACTIVE Opens a regular single-stage command in the interactive Termux shell. This is also available as Debug Mode in command details.
#@OPEN_LOGS Opens the live output viewer when execution starts.
#@SHELL Explicitly labels the command as shell code for command grouping and display.

Example:

#@PYTHON
#@OPEN_LOGS
import os

print(f"Received: {os.environ.get('INPUT', '')}")

Interactive mode is for single-stage commands; multistage workflows use their own persistent background shell.

Command catalog and packages

The Commands catalog is backed by autopie-commands. You can search by name, ID, summary, or tag; read a command's README and changelog; install it; and update it when a newer catalog version is available. A catalog command can include an install script for its Termux or Python dependencies.

The embedded terminal is still the fastest way to install arbitrary tools:

pkg update
pkg install ffmpeg imagemagick
pip install yt-dlp

The bootstrap already contains Python, pip, binutils, OpenSSH, and sshpass.

Run AutoPie commands from another app

Other apps can open AutoPie's command dialog with an explicit intent. The user is always shown AutoPie's UI before an external app can run a command.

@Composable
fun RunAutoPieCommandButton() {
    val context = LocalContext.current

    val intent = Intent(Intent.ACTION_MAIN).apply {
        component = ComponentName(
            "com.autopi",
            "com.autopi.DirectCommandActivity"
        )
        putExtra("commandId", "autopie.yt-dlp-downloader")
        putExtra("input", "https://example.com/video")
        putExtra("async", true)
        flags = Intent.FLAG_ACTIVITY_NEW_TASK
    }

    Button(onClick = {
        runCatching { context.startActivity(intent) }
            .onFailure { Log.e("AutoPie", "Unable to open AutoPie", it) }
    }) {
        Text("Run with AutoPie")
    }
}

Intent extras:

Extra Meaning
commandId Required command ID or display name.
input Optional text or URL input.
async Defaults to true. A regular command can return as soon as it starts; false waits for completion. Multistage workflows return after their final step.
processId Optional non-negative process ID supplied by the caller.

When launched for a result, AutoPie returns status (running, ok, or failed), processId, and a logFile content URI. Use Android's Activity Result API and grant/read URI access as appropriate for your app.

You can also open a command's details in AutoPie and choose Add to Home Screen to create a launcher shortcut without writing any Android code.

File observer example

The following kind of observer can automatically convert every new screenshot to WebP. Set the observer directory to your screenshots folder and use a selector such as ^.*\.png$.

AutoPie file observer example command

Configuration, logs, and troubleshooting

AutoPie can store AutoSec in either shared external storage or its private app-data home. Change the location in Settings → AutoPie Config Path; AutoPie moves the directory when possible. External storage survives an uninstall but is less private. App-data storage is more private but is normally removed with the app.

Important files and directories inside AutoSec include:

  • commands.json — all share, observer, cron, and multistage command definitions.
  • bin/ — packaged command executables.
  • logs/autopie.log — optional application file log.

Useful Settings actions include opening the Termux terminal, editing commands.json in nano, enabling file logging, opening logs with less, turning file observers on or off, and clearing the packaged-command cache.

Troubleshooting:

  • If the command list is empty, open Settings and verify the active config path and commands.json.
  • If commands.json is missing or the initial config is unusable, move the current AutoSec directory somewhere safe and reopen AutoPie so it can initialize a fresh one. Restore custom entries after comparing the files.
  • AutoPie does not overwrite an existing AutoSec directory during app updates, which protects custom commands but can leave bundled package data behind. See README-updates.md before replacing package data.
  • Enable File Logger and inspect AutoSec/logs/autopie.log when a service, observer, or scheduled command does not start.
  • Each command also has a History view, and process notifications link to command output logs.
  • Android battery restrictions can delay cron commands and stop long-running background work; disable battery optimization if necessary.

Build from source

AutoPie requires JDK 17 and an Android SDK. Open the project in Android Studio for normal development builds, or use the included scripts to prepare the patched Termux modules and bootstrap.

To clone the latest official Termux source, apply AutoPie's patches, prepare the embedded bootstrap, and build a debug APK:

./build_with_termux.sh

Pass Gradle tasks to make another build, for example:

./build_with_termux.sh :app:assembleRelease

Set TERMUX_REF to pin an upstream Termux tag or commit.

The build script downloads Termux's pinned bootstrap, injects AutoPie's required packages from the Termux repository, rewrites package paths for com.autopi, and writes app/src/main/assets/bootstrap-aarch64.zip.

For individual preparation stages:

./scripts/prepare-termux-app.sh
./scripts/prepare-termux-bootstrap.sh

To build the bootstrap entirely from source with the native termux-generator pipeline, run the following on a compatible Ubuntu x86_64 host:

./build_from_source.sh

It installs the generated archive at app/src/main/assets/bootstrap-aarch64.zip; afterward, build normally in Android Studio or with Gradle.

Support

Thanks

AutoPie is licensed under the Apache License 2.0.

About

Swiss Army Knife For Android. Automate with Linux Commands on Android in a single click.

Resources

Stars

180 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages