Skip to content
Talk to our solutions team

Commands

Five subcommands. run is the one you use while writing; validate is the one to put in CI.

Terminal window
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.

FlagEffect
-f, --funcEntry point. Default main
-a, --argsAn argument, repeatable. Appends to positional arguments
-v, --varsA variable as k=v, repeatable. Becomes a bare global
-e, --envA YAML file of variables
-r, --runtimeForce a language instead of detecting from the extension
-t, --timeoutMilliseconds. Default 5000
--namespacesall, none, or a list
--cpetTenancy identity, as customer,product,environment,tenant
--rootProduct root, instead of walking up for .kisai/
-d, --debugPrint 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.

Terminal window
kis script validate transform.js
✓ Syntax valid
✓ Compiles successfully
Validation: PASSED

It 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:

Terminal window
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 input

Validating 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.

Terminal window
kis script compile transform.js --runtime javascript
Compiling with javascript runtime...
✓ Compilation successful (95.377µs)
Source size: 59 bytes

The 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.

Terminal window
kis script bench transform.js -n 1000 -w 100 -i '{"rows":200}'
Runtime: javascript
Function: main
Iterations: 200
Warmup: 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
FlagEffect
-n, --iterationsHow many runs. Default 1000
-w, --warmupRuns before measuring. Default 100
-i, --inputInput JSON, inline or a file path
-f, --funcEntry point
-r, --runtimeWhich runtime to measure

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:

Terminal window
kis script run transform.js --timeout 5 # P99 ≈ 0.57ms, so 5ms is generous

Benchmark 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.

Terminal window
kis script rules transform.js --input ./data --update
kis script rules classify.js --input ./in --output ./out --pattern '*.json'
kis script rules extract.lua --input ./docs --bbox invoice=ocr.json --update
FlagEffect
--inputDirectory to read
--outputDirectory to write results to
--updateWrite results back in place
--patternWhich files to match. Default *.json
-f, --funcEntry point
--factsExtra JSON files merged in, as [key=]path
-b, --bboxDocument files to load, as [name=]path
-e, --envVariables from a YAML file
--debugVerbose 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.