jao 0.3.7

Discover and run workspace scripts from a simple CLI
jao-0.3.7 is not a library.

jao runs scripts as if you made your own, repo specific CLI The name jao comes from the Hindi "जाओ" meaning "Go!" :D

Compared with tools like make, just, or npm run, jao is a better fit when:

  • you don't want to commit to a full task runner, and want something both seamlessly added and seamlessly removed from your workflow
  • the scripts already exist and you do not want to rewrite them
  • the same script names appear in multiple subprojects
  • you want commands to get shorter as you move deeper into the repo (as in, jao is aware of your current working directory)
  • you want changes in scripts to enforce detectable changes in anything depending on them, with the fingerprinting system

Quick Start

Repo:

scripts/
  check.sh
  test.integration.sh
  db.reset.local.sh

Commands:

jao --list
jao check
jao test integration
jao db reset local

This is the default model: command parts map to script stems like check, test.integration, and db.reset.local.

What It Does

  • Finds runnable scripts under the directory you start from
  • Matches .sh on Unix and .bat on Windows
  • Lets you run scripts by command parts instead of file paths
  • Respects .gitignore during discovery
  • Supports .jaofolder to expose directory names in commands
  • Supports recursive .jaoignore files to hide scripts or whole areas
  • Supports trust prompts for local use and fingerprints for CI
  • Prints shell completion scripts for Bash and Zsh

jao runs scripts from the script's own directory, so existing scripts that rely on relative paths keep working.

Shell Completion

Bash:

source <(jao --completions bash)

Zsh:

source <(jao --completions zsh)

Then jao can complete discovered script parts from the current directory:

jao m<TAB>         -> myapp
jao myapp <TAB>    -> backend frontend
jao myapp backend b<TAB> -> build

Obviously you can add this to e.g. your .bashrc to enable completions always.

Example 2: .jaofolder In A Multi-Project Repo

Repo:

apps/
  .jaofolder
  frontend/
    .jaofolder
    scripts/
      build.sh
      dev.sh
  backend/
    .jaofolder
    scripts/
      build.sh
      dev.sh

From the repo root:

jao apps frontend dev
jao apps backend build

From inside apps/:

jao frontend dev
jao backend build

From inside apps/backend/:

jao dev
jao build

Use this when multiple projects have the same script names and you want commands to get shorter as you move deeper into the repo.

Example 3: .jaoignore For Internal Or Throwaway Scripts

Repo:

.jaoignore
scripts/
  check.sh
scratch/
  scripts/
    one-off-fix.sh
services/
  api/
    .jaofolder
    .jaoignore
    scripts/
      migrate.dev.sh
      seed.dev.sh

Root .jaoignore:

scratch/

services/api/.jaoignore:

seed.dev.sh

Result:

  • scratch/ is not walked at all
  • seed.dev.sh is hidden from jao --list
  • migrate.dev.sh still resolves normally

Use this when a repo contains one-off maintenance scripts, experiments, or internal scripts that should not be part of the public command surface.

Example 4: Fingerprinting In CI

Print the fingerprint for a script:

jao --fingerprint db reset local

Use that value in CI:

jao --ci --require-fingerprint <FINGERPRINT> db reset local

That gives CI an exact content check instead of trusting whatever script happens to be present.

For local interactive use, jao keeps a trust manifest under ~/.jao/:

  • unknown scripts ask before running
  • modified scripts ask again

Installation

Prebuilt binaries

Download the latest archive for Linux, macOS, or Windows from GitHub Releases.

Each release from v0.3.7+ includes platform-specific archives plus a SHA256SUMS file.

On Linux and macOS, place the binary on your PATH and mark it executable if needed:

tar -xzf jao-*.tar.gz
chmod +x ./jao
mv ./jao /usr/local/bin/jao

On Windows, extract the .zip archive and place jao.exe somewhere on your PATH.

crates.io

cargo install jao

Docker

docker pull royprinsgh/jao:latest

License

Apache-2.0