zena:cli

zena
import {…} from 'zena:cli';

CLI Standard Library - Command-Line Interface Utilities

Provides command-line argument parsing, environment variable access, process control, and related utilities for CLI applications.

API Design Philosophy

This library's API is designed to closely mirror WASI Preview 2's CLI interfaces (wasi:cli/environment, wasi:cli/exit) even though the current implementation uses WASI Preview 1 under the hood. This ensures:

  1. Easy migration when Zena moves to WASI P2
  2. Familiar API for developers familiar with WASI
  3. Consistent with other WASI-based Zena standard libraries

WASI P2 Interface Mapping

Zena API WASI P2 Interface
getArguments() wasi:cli/environment.get-arguments
getEnvironment() wasi:cli/environment.get-environment
getEnv(name) (convenience wrapper)
initialCwd() wasi:cli/environment.initial-cwd
exit(code) wasi:cli/exit.exit-with-code

WASI Preview 1 Implementation

Under the hood, this uses WASI Preview 1 functions:

  • args_sizes_get, args_get - for command-line arguments
  • environ_sizes_get, environ_get - for environment variables
  • proc_exit - for process termination

Example

zena
import { getArguments, getEnv, exit, ExitCode } from 'zena:cli';

let main = () => {
  let args = getArguments();

  if (args.length < 2) {
    console.error("Usage: program <filename>");
    exit(ExitCode.Failure);
  }

  let verbose = getEnv("VERBOSE") != null;
  // ... process args[1] ...

  exit(ExitCode.Success);
};

Enums

ExitCode

zena
enum ExitCode

Standard exit codes for CLI applications.

Maps to WASI P2's result-based exit where:

  • Success (0) = Ok
  • Failure (1) = Err with no specific code

Use exit() with these codes or a custom u8 value.

Members
zena
Success
#

Successful program termination (code 0).

zena
Failure
#

Generic failure (code 1).

zena
InvalidArguments
#

Invalid command-line arguments (code 2).

zena
NotFound
#

Resource not found (code 3).

zena
PermissionDenied
#

Permission denied (code 4).

zena
IoError
#

I/O error (code 5).

Type aliases

EnvVar

zena
type EnvVar = {name: String, value: String}

A key-value pair representing an environment variable. Matches WASI P2's tuple<String, String> representation.

ParsedOption

zena
type ParsedOption = {name: String, value: String | null}

Result of parsing a command-line option.

Functions

getEnvironment

zena
function getEnvironment(): Array<EnvVar>

Get all environment variables.

Returns a list of (name, value) pairs for all environment variables available to the process.

Maps to: wasi:cli/environment.get-environment

Returns

Array of environment variable key-value pairs

zena
for (let env in getEnvironment()) {
  console.log(env.name + "=" + env.value);
}

getEnv

zena
function getEnv(name: String): String | null

Get a single environment variable by name.

This is a convenience wrapper around getEnvironment() for the common case of looking up a single variable.

name
  • The name of the environment variable to look up

Returns

The value if found, or null if not found

zena
let home = getEnv("HOME");
if (home != null) {
  console.log("Home directory: " + home);
}

// Or with default value pattern:
let port = getEnv("PORT") ?? "8080";

getArguments

zena
function getArguments(): Array<String>

Get the command-line arguments passed to the program.

Returns all arguments including the program name (typically at index 0).

Maps to: wasi:cli/environment.get-arguments

Returns

Array of argument strings

zena
let args = getArguments();

// args[0] is typically the program name
console.log("Program: " + args[0]);

// Process remaining arguments
for (var i = 1; i < args.length; i += 1) {
  console.log("Arg: " + args[i]);
}

getProgramName

zena
function getProgramName(): String

Get the program name (first argument).

Convenience function to get just the program name without loading all arguments.

Returns

The program name, or an empty string if not available

zena
console.log("Usage: " + getProgramName() + " [options] <file>");

initialCwd

zena
function initialCwd(): String | null

Get the initial current working directory.

Returns the path that programs should use as their initial working directory, interpreting . as shorthand for this path.

Maps to: wasi:cli/environment.initial-cwd

Note: WASI Preview 1 does not have a direct equivalent. This function may return null if the runtime doesn't provide CWD information through environment variables or other means.

Returns

The initial CWD if available, or null

zena
let cwd = initialCwd();
if (cwd != null) {
  console.log("Current directory: " + cwd);
}

exit

zena
function exit(code: i32): void

Exit the program with the specified exit code.

This function does not return. It immediately terminates the process with the given status code.

Maps to: wasi:cli/exit.exit-with-code

Exit code conventions:

  • 0: Success
  • 1: General failure
  • 2: Misuse of shell command / invalid arguments
  • 126: Command invoked cannot execute
  • 127: Command not found
  • 128+N: Fatal error signal N
code
  • The exit code (0-255). Use ExitCode enum for common cases.
zena
// Using enum
exit(ExitCode.Success);

// Using numeric code
exit(0);

// Error exit
console.error("Fatal error occurred");
exit(ExitCode.Failure);

exitSuccess

zena
function exitSuccess(): void

Exit successfully (code 0).

Convenience function for successful program termination. Equivalent to exit(ExitCode.Success).

Maps to: wasi:cli/exit.exit with Ok result

exitFailure

zena
function exitFailure(): void

Exit with failure (code 1).

Convenience function for failed program termination. Equivalent to exit(ExitCode.Failure).

Maps to: wasi:cli/exit.exit with Err result

isShortOption

zena
function isShortOption(arg: String): boolean

The option name (without leading dashes). The option value, if provided (for --name=value or -n value). Null if no value.

Check if an argument is a short option (e.g., -v, -h).

arg
  • The argument to check

Returns

true if it's a short option (single dash + single char)

isLongOption

zena
function isLongOption(arg: String): boolean

Check if an argument is a long option (e.g., --verbose, --help).

arg
  • The argument to check

Returns

true if it's a long option (starts with --)

isOption

zena
function isOption(arg: String): boolean

Check if an argument is any kind of option (short or long).

arg
  • The argument to check

Returns

true if it starts with a dash

parseLongOption

zena
function parseLongOption(arg: String): ParsedOption

Parse a long option that may have a value (--name=value).

arg
  • The argument to parse (should start with --)

Returns

ParsedOption with name and optional value

zena
let opt = parseLongOption("--output=file.txt");
// opt.name == "output", opt.value == "file.txt"

let opt2 = parseLongOption("--verbose");
// opt2.name == "verbose", opt2.value == null