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.
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:
exit - Exit¶
ExitCommand. Calls ctx.exit(), which calls ctx.terminal.stop().
clear - Clear screen¶
ClearCommand. Writes \x1Bc (ANSI form-feed) to stdout.
json - Format as JSON¶
JsonCommand. Pretty-prints pipeline objects as a JSON array.
Standalone it writes an empty array:
table - Render as table¶
TableCommand. Formats pipeline objects as an aligned text table; column widths are computed from the data.
Objects with missing keys produce empty cells. Nested objects and arrays render as compact JSON ({"x":1}, ["a","b"]), not [object Object].
csv - Format as CSV¶
CsvCommand. Formats pipeline objects as a CSV document. The header row is the union of all keys in first-seen order; cells containing commas, quotes, or newlines are quoted. Empty input writes nothing.
Nested objects and arrays are JSON-stringified in the cell ({"x":1}, "[1,2]"); null/missing values render as empty cells.
select - Pick, rename and set attributes¶
SelectCommand. Projects each object to the listed attributes, optionally renaming them or filling in empty values. Names are a positional comma-separated argument; whitespace around commas is tolerated (select name, age). Bare names keep the object's own (non-inherited) top-level key; a missing kept attribute is silently ignored. Without arguments all attributes pass through.
Each comma-separated item is one projection:
| Form | Meaning |
|---|---|
key |
Keep the object's own key as-is |
new=old |
Rename: resolve source old (dot-notation supported) into output new |
new= |
Emit new as an empty string |
Rename pairs apply against the original object (no chaining), so a=b, b=a swaps both values; a missing source path is silently ignored. The last projection wins when two target the same output key. An empty output key (=x) throws an error.
> cmd | select name,age | next_cmd
> cmd | select id=taskId | next_cmd
> cmd | select owner=user.name, author= | next_cmd
sort - Sort objects¶
SortCommand. Sorts objects by one or more comma-separated attributes (a positional argument); later attributes break ties. Defaults to the first key of the first object.
sort is an intermediate pipeline command.
> cmd | sort name | next_cmd
> cmd | sort milestone, status, title | next_cmd # later names are tie-breakers
> cmd | sort | next_cmd
Use -d / --descending to reverse the sort order:
> cmd | sort name -d | next_cmd # Z → A
> cmd | sort milestone, status -d | next_cmd # entire tie-breaker order reversed
Numbers compare numerically, everything else as strings; null sorts last. Empty or universally missing sort keys leave objects in their original order. Ties are resolved by the next listed attribute; all attributes tied means the original order is kept.
clip - Copy to clipboard¶
ClipCommand. Copies pipeline objects to the clipboard as a JSON string.
Tries pbcopy, xclip, xsel, clip in order; errors if none is available.
filter - Filter objects¶
FilterCommand. Keeps objects matching comma-separated conditions. Conditions are key<operator>value; nested paths use dot notation (user.name=Alice).
| 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:
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:
-h/--head N keeps the first N matching items and -t/--tail N keeps the last N; with both the result is the head slice followed by the tail slice (the whole input passes through when the slices overlap or sum to the count). The positional slice is applied on top of the filtered result and is independent of --any/--not. Omitting both flags performs no slicing.
> cmd | filter role=admin --head 5 | next_cmd
> cmd | filter role=admin -h 2 -t 2 | next_cmd
> cmd | filter --tail 3 | next_cmd
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 }
]
from / to - File I/O for JSON/CSV¶
FromCommand reads a JSON or CSV file (format inferred from the file extension) and submits each record as a pipeline object. ToCommand writes pipeline objects back out as JSON or CSV.
> from data.csv | sort name | table
> from data.csv --delimiter ',' | table
> from out.json | filter role=admin
> cmd | select name,age | to out.csv --delimiter ','
| Format | Extension | Read | Write |
|---|---|---|---|
| JSON | .json |
Array of objects or single object | Pretty-printed JSON array |
| CSV | .csv |
Header row + rows | Header row (union of keys) + rows |
CSV cells are strings; cells containing the delimiter, quotes, or newlines are quoted. CSV files use the terminal's configured default delimiter (; by default, configurable via the defaultDelimiter terminal option); pass --delimiter with a single character (e.g. ',') to override for a single command. A leading UTF-8 BOM is ignored for both JSON and CSV; malformed CSV (an unterminated or misquoted field) and malformed JSON throw a clear error. Unknown file extensions throw an error.
shortcut - Manage persistent command shortcuts¶
ShortcutCommand. Binds names to full command strings; typing the name alone runs the stored command. Shortcuts persist to shortcutPath (default ./shortcuts.json) and load automatically on start(). See Shortcuts for details.
| Subcommand | Description |
|---|---|
shortcut add <name> <command> |
Create or update a shortcut; quote commands containing flags (shortcut add ll 'ls -la /tmp') |
shortcut save <name> |
Save the most recently executed command as a shortcut |
shortcut remove <name> |
Delete a shortcut from store and tree |
shortcut list |
Print all shortcuts as name → command lines |
shortcut show <name> |
Print the stored command string |
> shortcut add gs git status
Saved shortcut "gs".
> shortcut list
gs → git status
> gs
On branch main
nothing to commit, working tree clean
Names must not contain whitespace or shadow registered commands; re-adding an existing shortcut name updates it.
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