Command line
kupcad is one executable: it runs scripts, exports models, checks and formats code, manages
packages and serves editors.
kupcad build part.kup -o part.stl # exportkupcad build part.kup -p width=50 -o part.step # with a parameterkupcad check . # lint every script under herekupcad fmt --write . # format them| Command | Does |
|---|---|
build |
Runs a script and exports its model. |
run |
Runs a script for what it prints, writing no model. |
watch |
Rebuilds a script whenever it, or a file it reads, changes. |
check |
Reports syntax errors, compile errors and lint findings. |
fmt |
Formats scripts. |
doc |
Prints a script’s parameters and metadata as JSON. |
pkg |
Manages dependencies. |
lsp |
Starts the language server. |
version |
Prints the version. |
dev |
Compiler and VM tools. |
Common behaviour
Section titled “Common behaviour”- Exit status. Every command exits 0 on success and 1 on any failure: bad arguments, an unreadable file, a syntax or runtime error, a failed export, a lint error. Each is safe as a CI step.
- Help.
kupcad --helplists the commands. Every command explains its options with--help(or-h) wherever it appears:kupcad build --help,kupcad check part.kup -h. An option a command doesn’t take is an error that prints its usage. - Version.
kupcad --version(or-V) prints the version. - Colour. Output is coloured only on a terminal; piped or redirected output is plain.
NO_COLOR=1turns colours off everywhere, andCLICOLOR_FORCE=1keeps them when redirected. - Errors. A syntax or compile error is printed with its file, line and column and a code in
brackets (
part.kup:2:1: E: 'cube' is a built-in and can't be assigned [builtin-redefined]). An uncaught runtime error is printed once with its class and where it was raised. See Errors.
kupcad build
Section titled “kupcad build”kupcad build <file.kup> [options]Runs a script and exports its model, the script’s last value. Without -o, it writes a .glb
file next to the script, named after it (-f picks another format).
| Option | Description |
|---|---|
-o, --output <file> |
The output path; its extension picks the format: .stl, .glb, .gltf, .step, .stp, .3mf, .obj, .svg, .dxf. Repeatable: the script runs once and is written to each. |
-f, --format <name> |
stl, glb, gltf, step, 3mf, obj, svg or dxf. With a single -o; an extension it contradicts is an error. |
-d, --draco |
Compress glb and gltf meshes with Draco. |
--draco-bits <n> |
Quantize Draco positions to n bits, 1 to 30 (default 14: an error of a part’s size / 16384). Finer files are larger. |
--stroke-width <mm> |
An SVG’s outline width (default 0.1), such as a laser’s hairline. |
--mtl |
Also write an OBJ’s materials as a library beside it (<output>.mtl; materials.mtl with --split). |
--bom <file.json> |
Also write the model’s parts list: each part, its count, volume, size and mass. |
--split <dir> |
Write each part to its own file in <dir>, as made and not placed, named after it; STL unless -f names another format. |
-p, --param <name=value> |
A parameter’s value, read as its kind (an Array’s or a Map’s as JSON). Repeatable. |
-P, --params <file.json> |
Parameter values from a JSON object. Repeatable. |
kupcad build part.kup -o part.stl -o part.glb # one run, two fileskupcad build part.kup -f 3mf # part.3mf beside the scriptkupcad build part.kup -o part.glb --draco --draco-bits 12kupcad build part.kup --bom bom.json -o part.3mfkupcad build part.kup --split parts/ # parts/plate.stl, parts/M3 bolt.stl, ...kupcad build part.kup -P bracket.json -p width=50 # the later value wins--draco, --mtl and --stroke-width apply to the outputs they fit, and each must fit one:
--mtl without an .obj output is an error. A .step output is built on the exact B-Rep
engine, so it is a build of its own. What each format holds, and what a model must be for it, is
on Export formats. The --bom file is
{"parts": [...]}, each part as bom gives it, with null
for what a part has none of. Parameter values are described on
Parameters.
Files a script can read and write
Section titled “Files a script can read and write”A build reads and writes files from its script’s root: the working directory when the script is
under it; otherwise the nearest folder above the script that holds a kupcad.json or
.kupcad.json; otherwise the script’s own folder. Imports and import_* calls can’t reach
outside it, through .. or through a symbolic link. A script’s export_* methods write only
files named for their format (export_stl a .stl), so neither a script nor a package it
imports can write over the project’s scripts or settings.
kupcad run
Section titled “kupcad run”kupcad run <file.kup> [-p name=value]... [-P file.json]...Runs a script and writes no model. What it prints and the errors it raises are the result, for a
script that computes or checks rather than models. A model that is one Solid is evaluated by the
geometry kernel, as the editor’s preview evaluates it, so a kernel error in it (a polyhedron
that isn’t closed) fails the run as it would a build. An Array or an Assembly of Solids is built
but not evaluated, so a kernel error in one waits for kupcad build. The script can still write
files itself with export_*. Takes -p and -P as build does.
kupcad watch
Section titled “kupcad watch”kupcad watch <file.kup> [options]Builds a script, then rebuilds it whenever it, a module it imports or a file it reads as data
changes; a file restored to an older version counts as a change, and a data file that was missing
is watched until it appears. It takes build’s options. With an export option (-o, -f,
--split, --bom, …), each build that succeeds writes its files, for a slicer or viewer that
reloads them; without one it writes nothing. A failed build is reported as build reports it, and
watching goes on until the fix.
A watched run stops after 100 million instructions and, unless the project sets
vm_memory_limit, at 1 GiB of script memory, so a script that loops forever can’t hang it.
kupcad check
Section titled “kupcad check”kupcad check [--fix] [--format text|json|sarif] [--max-warnings <n>] [--config <file>] <file|dir>...Reports syntax errors, compile errors and lint findings, without running the scripts.
| Option | Description |
|---|---|
--fix |
Apply the fixes that keep the model the same, rewrite the files, then report what is left. |
--format <kind> |
text (the default), json, or sarif for code scanning. JSON and SARIF write one document to stdout. |
--max-warnings <n> |
Fail when there are more than n warnings; 0 fails on any. |
--config <file> |
Read lint settings from <file> instead of .kupcad.json. |
Errors fail the check; warnings and infos alone don’t, unless --max-warnings says so. Given a
directory, check takes every .kup file under it except in hidden directories (.git,
.kupcad); a hidden path named outright is still taken. kupcad check --help lists the rules.
See Lint rules.
kupcad fmt
Section titled “kupcad fmt”kupcad fmt [--check | --write] [--config <file>] <file|dir>...kupcad fmt --stdin [--check] [--config <file>]Prints the files formatted. --write rewrites the ones that change, in place; --check lists
the ones that aren’t formatted and fails if there are any; --stdin formats the source piped in.
Directories are walked as check walks them. See Formatter.
kupcad doc
Section titled “kupcad doc”kupcad doc <file.kup>Prints the script’s # @title, # @description and # @author comments and its parameters as
JSON, without running it, for a host to build controls from. See
Parameters.
kupcad pkg
Section titled “kupcad pkg”kupcad pkg initkupcad pkg add <alias>=<source>kupcad pkg installkupcad pkg prune [--force]kupcad pkg doctorManages a project’s dependencies (kupcad.json, kupcad.lock) and the shared package store.
See Packages.
kupcad lsp
Section titled “kupcad lsp”kupcad lsp [--stdio] [--viewport-origin <origin>]Starts the language server on stdin and stdout, the only transport (--stdio, which language
clients pass, is accepted). Editors start it themselves. --viewport-origin lets the page at
<origin> (scheme://host[:port], such as tauri://localhost) read the viewport socket,
besides VS Code’s webviews. See Language server.
kupcad version
Section titled “kupcad version”kupcad version [--json]Prints the version, as --version does. With --json it prints a JSON object with the protocol
version front ends check and the platform the binary was built for:
{"version": "0.1.0", "protocolVersion": 1, "os": "macos", "arch": "aarch64"}kupcad dev
Section titled “kupcad dev”kupcad dev ast-dump <file>kupcad dev disasm <file>kupcad dev lex-dump <file>kupcad dev bench <file> [--repeat <n>] [--no-profile] [--no-eval] [--json]kupcad dev crash panic|abortTools for working on KupCAD itself.
| Subcommand | Does |
|---|---|
ast-dump |
Writes the syntax tree (.dump). |
disasm |
Writes the compiled bytecode (.disasm). |
lex-dump |
Writes the token stream (.lex). |
bench |
Times parse, compile, the VM run and the geometry’s evaluation, each from cold, and prints the median of --repeat runs (5 by default). A further run with the profiler gives a table per function (--no-profile skips it); --no-eval skips the geometry; --json prints the medians as JSON. The script’s own output isn’t shown. |
crash |
Ends the process with a panic or an abort, to check that crash reports are written. |
Crash reports
Section titled “Crash reports”With KUPCAD_CRASH_DIR set to a directory, a crash of any command (a panic, or a fatal signal
such as an abort in the geometry kernel) writes kupcad-crash-<seconds>-<pid>.txt there and says
so on stderr. The report holds the version, the platform and build mode, the subcommand, what
happened and, for a panic, the stack, but nothing of the script: not its text, its path or its
other arguments. Without the variable nothing is written. Linux and macOS.