evo-cli 0.1.0

Agent-first command registry with explicit execution and searchable metadata.
Documentation

evo

Agent-first command registry with explicit execution and searchable metadata.

Install

From crates.io:

cargo install evo-cli

From npm for prebuilt macOS and glibc-based Linux binaries:

npm install -g @evo-cli/evo-cli

Supported npm targets:

  • x86_64-unknown-linux-gnu
  • aarch64-unknown-linux-gnu
  • x86_64-apple-darwin
  • aarch64-apple-darwin

The installed command is always:

evo

CLI

evo create <name>
evo create <name> --description <text> [--tag <tag>]...
evo update <name>
evo update <name> [--description <text>] [--tag <tag>]...
evo ls [--json | --compact]
evo show <name> [--json]
evo rm <name>
evo run <name> [args...]
evo env <name> ls
evo env <name> set <key> <value>
evo env <name> unset <key> [key ...]
evo reindex
evo search [query] [--json] [--limit <n>]

Saved commands are never executed as evo <name>. The only execution path is:

evo run <name> [args...]

Command layout

Commands live under ~/.evo/cmds or $EVO_HOME/cmds.

~/.evo/cmds/<name>/run
~/.evo/cmds/<name>/manifest.json
~/.evo/cmds/<name>/.env
~/.evo/cmds/<name>/README.md
  • run is required and executable.
  • manifest.json is required and is the canonical metadata file.
  • .env is optional and loaded on top of the parent process environment for that command.
  • README.md is optional and indexed for search.

manifest.json

{
  "name": "deploy-api",
  "description": "Deploy the API service",
  "tags": ["ops", "release"]
}

evo run always passes trailing CLI args through unchanged, including --help. If stdin is piped from a file, pipe, or socket, evo run forwards those bytes to the runner unchanged. If stdin is not piped, the runner inherits the caller's stdin normally.

If a command needs help text, argument parsing, argument validation, or JSON validation, that logic belongs in the runner script itself.

Create and update

evo create and evo update support two authoring modes:

  • Bare evo create <name> or evo update <name> launches an interactive terminal wizard.
  • Explicit flags provide a deterministic non-interactive path for humans and agents.

If you run the bare command without a TTY, evo fails with guidance to use explicit flags instead.

Interactive wizard

evo create hello
evo update hello

evo create prompts for:

  • description
  • optional comma-separated tags
  • a runner template
  • a generated README file

evo update prompts for:

  • description
  • optional comma-separated tags

Interactive update only changes metadata. Edit run and README.md directly in your own editor using the printed file paths if those files need changes.

Non-interactive flags

Create:

evo create hello \
  --description "Print a greeting" \
  --tag example

Update:

evo update hello \
  --description "Print a friendlier greeting" \
  --tag example \
  --tag shell

Non-interactive rules:

  • create requires --description.
  • non-interactive create always scaffolds both run and README.md.
  • non-interactive create prints the runner and README paths after creation so you can read and edit them directly.
  • non-interactive update only changes manifest fields and preserves run, .env, and README.md.
  • non-interactive update prints the runner and README paths after the update so you can read and edit them directly.

Listing commands

evo ls renders one block per saved command with:

  • name
  • description
  • tags
  • runner (the file path to run)
  • env (keys only, never values)
  • readme (the file path to README.md, with a missing marker when absent)

evo ls --compact renders a one-line summary per command.

evo ls --json returns structured metadata with absolute runner and readme path values plus readme_exists.

Env management

.env values are managed separately from the manifest:

evo env deploy-api ls
evo env deploy-api set GITHUB_TOKEN secret
evo env deploy-api unset GITHUB_TOKEN REGION
  • ls prints sorted keys only.
  • set creates or updates a key.
  • unset removes one or more keys and deletes .env if it becomes empty.
  • show and show --json expose only env keys, never raw values.

Search

Bare evo search launches an interactive fuzzy picker when stdin/stdout are TTYs. Selecting a result immediately runs that saved command.

If no positional query is provided and stdin is piped, evo search reads the piped text as the query and uses the normal non-interactive search output.

evo maintains an SQLite FTS index at $EVO_HOME/index.db.

Indexed fields:

  • command name
  • description
  • tags
  • README text
  • full run file contents, including the shebang

Not indexed:

  • .env keys
  • .env values

The index is refreshed on create, update, and rm. If the database is missing or corrupted, evo rebuilds it automatically from the command files.

Run evo reindex to force a full rebuild when command files or README contents changed outside evo.

Quick start

evo create hello

evo create script-hello \
  --description "Print a greeting" \
  --tag example

evo env script-hello set GREETING_STYLE plain
evo search
evo ls
evo show hello --json
evo run script-hello codex
evo reindex
evo search greeting --json