Lynxer

Documentation

cli

Command-line helpers: arguments, environment, terminal queries, process execution and Click/Typer-style command builders.

Backend: native — stdlib/cli.so, built from stdlib/cli.cpp over POSIX APIs. Import: import("cli") → global.cli.*

Command builders

The Click/Typer builders are implemented natively; command definitions live in integer handles. Call clickInit() (or typerInit()) before creating anything.

FunctionSignatureNotes
clickInit()Resets the builder registry
clickCommandCreate(str name, str help) -> intCommand handle, 0 on failure
clickGroupCreate(str name, str help) -> intCommand group handle
clickGroupAddCommand(int group, int command, str name) -> intRegisters a command in a group
clickAddArgument(int command, str name, bool required, int nargs, str help = "") -> intPositional argument; nargs < 0 collects the rest
clickAddOption(int command, str declarations, str help, str default, bool flag, bool required, str kind, str envvar = "", bool multiple = false) -> intOption or flag
clickCommandSetShell(int command, str template) -> intShell template run when invoked
clickInvoke(int handle, str argsJson) -> strJSON {"params": …, "output": …, "exitCode": …}
clickGroupInvoke(int handle, str argsJson) -> strThe first argument selects the subcommand
clickRun(int command) -> strInvoke with the process command line
clickLastParams() -> strParameters of the most recent invoke

The Typer surface mirrors it: typerInit, typerAppCreate(str name, str help, bool noArgsHelp), typerCommandCreate(int app, str name, str help), typerAddArgument, typerAddOption, typerCommandSetShell, typerInvoke(int app, str argsJson), typerRun(int app), typerLastParams. A Typer app with a single command is invoked without the command name; with two or more, the first argument selects the command.

global setup(){ import("cli"); }

global main(){
    global.cli.clickInit();
    int command = global.cli.clickCommandCreate("greet", "Greet a person");
    global.cli.clickAddArgument(command, "name", true, 1);
    global.cli.clickAddOption(command, "--shout,-s", "Use uppercase", "", true, false, "bool");
    global.cli.clickCommandSetShell(command, "printf 'Hello {name}'");
    println(global.cli.clickInvoke(command, "[\"Ada\", \"--shout\"]"));
    // {"params": {"name": "Ada", "shout": true}, "output": "Hello Ada", "exitCode": 0}
}

Arguments and environment

FunctionSignatureNotes
argv() -> strProcess command line as a JSON array
argCount() -> intNumber of command-line entries
getArg(int index) -> strEntry at index, or ""
envGet(str name) -> strValue, or ""
envHas(str name) -> boolWhether the variable is set
envAll() -> strAll variables as a JSON object

Lynxer does not forward extra arguments to a program, so argv describes the lynxer process itself.

Terminal and IO

FunctionSignatureNotes
cwd() -> strWorking directory
chdir(str path) -> boolChanges the working directory
stdinIsTty / stdoutIsTty() -> boolTerminal detection
readStdin() -> strReads all of stdin
writeStdout / writeStderr(str text)Writes without a trailing newline
terminalSize() -> strJSON {"columns": N, "lines": M}
exit(int code)Exits the process immediately

Paths and processes

FunctionSignatureNotes
pathExists(str path) -> boolaccess(2)
isFile / isDirectory(str path) -> boolstat(2) type tests
which(str executable) -> strResolves on PATH, or ""
run(str command, bool capture) -> strWith capture returns stdout, otherwise the exit code as text
runCode(str command) -> intRuns silently and returns the exit code

Example

global setup(){ import("cli"); }

global main(){
    println(global.cli.argCount());
    if(global.cli.envHas("HOME")){
        println(global.cli.envGet("HOME"));
    }
    println(global.cli.run("printf ok", true));
    println(global.cli.runCode("false"));
}

See also