Commands
Five subcommands. run is the one you use while writing; validate is the one to put in CI.
kis script run <script>.<js|lua|go|star|wasm> [args...] [flags]The extension selects the runtime; --runtime overrides it. .expr and .cel are accepted
too, though those are expression languages rather than script files — see
Languages.
| Flag | Effect |
|---|---|
-f, --func | Entry point. Default main |
-a, --args | An argument, repeatable. Appends to positional arguments |
-v, --vars | A variable as k=v, repeatable. Becomes a bare global |
-e, --env | A YAML file of variables |
-r, --runtime | Force a language instead of detecting from the extension |
-t, --timeout | Milliseconds. Default 5000 |
--namespaces | all, none, or a list |
--cpet | Tenancy identity, as customer,product,environment,tenant |
--root | Product root, instead of walking up for .kisai/ |
-d, --debug | Print the compiled language, timings and the return value |
--debug is worth reaching for by default while developing. Without it the return value is not
printed, which makes a working script look like it did nothing.
validate
Section titled “validate”kis script validate transform.js✓ Syntax valid✓ Compiles successfully
Validation: PASSEDIt parses and compiles. It does not run, so it needs no input, no credentials and no environment — which is exactly what makes it usable as a gate.
It exits non-zero when validation fails, so it works directly in CI:
find . -name '*.js' -path '*/scripts/*' -exec kis script validate {} \;A failure names the position:
syntax error: JavaScript syntax error: SyntaxError: bad.js: Line 2:1 Unexpected end of inputValidating against the language you will actually configure matters. --namespaces is accepted
here too, which lets you check that a script compiles under the grant it will be given rather than
under the full one.
compile
Section titled “compile”kis script compile transform.js --runtime javascriptCompiling with javascript runtime...✓ Compilation successful (95.377µs)Source size: 59 bytesThe difference from validate is --runtime: compile is for asking “does this file compile as
Lua?” when you are choosing a language, or confirming that a .txt file is valid Starlark. Like
validate, it exits non-zero on failure.
kis script bench transform.js -n 1000 -w 100 -i '{"rows":200}'Runtime: javascriptFunction: mainIterations: 200Warmup: 20
Results: Min: 77.32µs Max: 633.671µs Mean: 154.341µs Median: 134.231µs P95: 343.066µs P99: 568.418µs
Throughput: 6479 ops/sec| Flag | Effect |
|---|---|
-n, --iterations | How many runs. Default 1000 |
-w, --warmup | Runs before measuring. Default 100 |
-i, --input | Input JSON, inline or a file path |
-f, --func | Entry point |
-r, --runtime | Which runtime to measure |
Setting a timeout from a measurement
Section titled “Setting a timeout from a measurement”This is what bench is for. The default timeout is five seconds; the right value is derived from
the distribution rather than guessed.
Read P95 and P99, not the mean. A timeout set from the mean fires on the slow tail — which arrives at the worst possible moment, because tail latency and system load correlate. Take P99 and leave headroom:
kis script run transform.js --timeout 5 # P99 ≈ 0.57ms, so 5ms is generousBenchmark with input that resembles production. A transform measured on an empty object tells you about the engine’s call overhead, not about your script.
The gap between Min and Max is also worth reading. A wide spread on identical input means the
work is not doing the same thing each time — usually a cache, a lazily-built structure, or
something reaching outside the process that should not be in a benchmark.
Runs one script over a directory of JSON files.
kis script rules transform.js --input ./data --updatekis script rules classify.js --input ./in --output ./out --pattern '*.json'kis script rules extract.lua --input ./docs --bbox invoice=ocr.json --update| Flag | Effect |
|---|---|
--input | Directory to read |
--output | Directory to write results to |
--update | Write results back in place |
--pattern | Which files to match. Default *.json |
-f, --func | Entry point |
--facts | Extra JSON files merged in, as [key=]path |
-b, --bbox | Document files to load, as [name=]path |
-e, --env | Variables from a YAML file |
--debug | Verbose output |
Each file is passed through the script, with any --facts and variables merged in. Use --output
first and --update once you trust the result — --update rewrites the inputs.
This is the batch shape for one-off data work: reshaping a directory of exports, classifying
scanned documents, backfilling a field. For anything recurring, a flow with a map: node gives
the same fan-out plus a record of what completed.
See also
Section titled “See also”- Calling convention — arguments, globals, results
- What a script can reach — the
--namespacesgrant - Languages — what
--runtimeaccepts