Skip to content

Built-in Commands

Registered in every Terminal by registerBuiltins(). Cannot be removed or shadowed.

select, sort, filter, and aggregate print their help when run without a | downstream.

help - Show help

HelpCommand. Renders usage from the command tree at runtime.

> help
Commands:
  help    Show help
  exit    Exit the terminal
  clear   Clear terminal

Scope to a command with --command <name> or a positional path:

> help --command help
help - Show help
Arguments:
  --command   Show help for a specific command

> help help
help - Show help
Arguments:
  --command   Show help for a specific command

Subcommands resolve by walking the tree; nested paths and quoted paths work the same way:

> help --command config
config - Configuration commands
Arguments:
  --file   Config file
Subcommands:
  get   Get a config value
  set   Set a config value

> help config get
get - Get a config value
Arguments:
  --key   Config key

> help --command "game list verify"
verify - Verify a listing

Unknown command:

> help nonexistent
Unknown command: nonexistent

exit - Exit

ExitCommand. Calls ctx.exit(), which calls ctx.terminal.stop().

> exit

clear - Clear screen

ClearCommand. Writes \x1Bc (ANSI form-feed) to stdout.

> clear

json - Format as JSON

JsonCommand. Pretty-prints pipeline objects as a JSON array.

> ls | json
[
  {
    "name": "file1.txt",
    "size": 1024
  },
  {
    "name": "file2.txt",
    "size": 2048
  }
]

Standalone it writes an empty array:

> json
[]

table - Render as table

TableCommand. Formats pipeline objects as an aligned text table; column widths are computed from the data.

> ls | table
| name        | size |
|-------------|------|
| file1.txt   | 1024 |
| file2.txt   | 2048 |

Objects with missing keys produce empty cells. Nested objects and arrays render as compact JSON ({"x":1}, ["a","b"]), not [object Object].

select - Pick attributes

SelectCommand. Keeps only the listed attributes from each object. Names are a positional comma-separated argument; whitespace around commas is tolerated (select name, age). Missing attributes are silently ignored; only own (non-inherited) keys are picked. Without arguments all attributes pass through.

> cmd | select name,age | next_cmd
> cmd | select | next_cmd

sort - Sort objects

SortCommand. Sorts objects by an attribute; defaults to the first key of the first object.

> cmd | sort --attribute name | next_cmd
> cmd | sort -a name          | next_cmd   # short alias
> cmd | sort | next_cmd

Numbers compare numerically, everything else as strings; null sorts last. Empty or universally missing sort keys leave objects in their original order.

clip - Copy to clipboard

ClipCommand. Copies pipeline objects to the clipboard as a JSON string.

> cmd | clip
Copied 3 object(s) to clipboard.

Tries pbcopy, xclip, xsel, clip in order; errors if none is available.

> clip
No pipeline input to copy to clipboard.

filter - Filter objects

FilterCommand. Keeps objects matching comma-separated conditions. Conditions are key<operator>value; nested paths use dot notation (user.name=Alice).

> cmd | filter role=admin | next_cmd
> cmd | filter role=admin,state=running | next_cmd
Operator Meaning
key=value Equal (numbers, booleans, strings; numeric strings coerce)
key!=value Not equal
key>value, key>=value, key<value, key<=value Relational
key~value Contains substring
key^value Starts with
key$value Ends with
key=~regex Regular expression match
key Key exists (non-null)

| inside a regex needs no quoting; only a whitespace-delimited | starts a new pipeline stage:

> cmd | filter name=~^bot|^host | next_cmd

A leading ! negates a condition; !! cancels out. null/missing values fail equality and relational conditions, pass !=, and act as empty strings for string operators. Conditions combine with AND; --any switches to OR, --not inverts the predicate, --icase compares case-insensitively:

> cmd | filter role=admin --any
> cmd | filter role=admin --not
> cmd | filter name=alice --icase

aggregate - Aggregate objects

AggregateCommand. Reduces pipeline objects to a single value or grouped rows.

> cmd | aggregate | next_cmd                          # count
> cmd | aggregate -m mean -a score | next_cmd         # 5.333333333333333
> cmd | aggregate --mode median --attribute score | next_cmd

Modes (-m / --mode): count, min, max, sum, mean, median. Without a mode it counts objects. min, max, sum, mean, median need an attribute (-a / --attribute), looked up per object (dot notation works) and coerced from numeric strings. null/missing attribute values are excluded, so -m count -a <attr> counts only objects with a non-null value. Over an empty value list sum is 0; min, max, mean, median are null.

--distinct counts distinct values; --round <n> rounds sum, mean, median:

> cmd | aggregate -m count -a status --distinct | next_cmd
> cmd | aggregate -m mean -a score --round 2 | next_cmd

Without grouping, a single object is emitted: { "mean": 5.33 }. -g / --groupBy emits one row per group, sorted by key, as an array; missing and null group keys collapse into one null group:

> cmd | aggregate -m sum -a score -g team | next_cmd
[
  { "team": "alpha", "sum": 14 },
  { "team": "beta",  "sum": 2 }
]

Shadowing

Builtins cannot be removed or shadowed. Registering a command whose name or alias collides with an existing command throws InvalidArgumentsError:

import { Terminal, Command } from '@johannes.latzel/terminal';

class SafeExit extends Command {
    constructor() {
        super('exit', 'Exit with confirmation');
    }
    async execute(ctx, _args) {
        ctx.stdout.write('Are you sure? (y/N) ');
        // read ctx.stdin, then ctx.exit()
    }
}

const term = new Terminal();
term.register(new SafeExit()); // throws InvalidArgumentsError: "exit" conflicts with the builtin