Pass arguments into a script
Values from the command line reaching your script, with the types you expect.
Why bother
Section titled “Why bother”A script with its inputs hard-coded is a script you edit to test. Parameterising it turns one file into something you can run against every case you care about.
| Without this | With this |
|---|---|
| Edit the file, run, edit back | Run it again with different arguments |
| Testing three cases means three copies | One file, three commands |
| The script cannot move into a flow unchanged | The same calling convention as a flow’s script: task |
The data the job acts on
Section titled “The data the job acts on”A flow takes its inputs as run variables, set with -v or loaded from a file with -e:
name: ordervars: name: widget qty: 1tasks: - name: total print: message: "{{name}} x {{qty}}"kis flow -f order.yaml -v name=widget -v qty=3widget x 3Declaring them under vars: with defaults is what makes the flow self-documenting: the values
someone will want to change are at the top, not buried in a node.
Anything after the filename becomes a positional argument to the entry point.
function main(name, qty) { return { name: name, qty: qty, total: qty * 10 };}kis script run order.js widget 3 --debugResult: {"name":"widget","qty":3,"total":30}Note total: 30, not "33333333333". Script arguments are JSON-parsed best-effort, so 3
arrives as a number and arithmetic works. A value that does not parse as JSON falls back to a string, which is
why widget arrives as text without quoting.
That fallback is the thing to watch: true, null and 12 become their JSON types, so a product
code that happens to be all digits arrives as a number. Quote it if you need the string —
'"0012"'.
The repeatable --args flag does the same thing and combines with positionals:
kis script run order.js --args widget --args 3Types differ between the surfaces
Section titled “Types differ between the surfaces”This is the one that catches people moving between them. A flow template writes the value in literally, so quoting in the payload is how you choose the JSON type:
payload: '{"name":"{{name}}","qty":{{qty}}}'{{name}} is quoted so it lands as a string; {{qty}} is not, so it lands as a number. Get that
wrong and the receiving API sees "3" where it wanted 3.
Ambient configuration
Section titled “Ambient configuration”Both surfaces separate what this run is about from where it is running.
Everything is a run variable, so the separation is a convention rather than a mechanism: put the
values that change per run at the top of vars:, and load the rest from an environment file.
kis flow -f deploy.yaml -e production.yaml -v service=api-e carries the environment; -v carries this run’s subject. Keeping them in separate places is
what lets one flow serve every environment.
--vars puts a value in scope as a bare global rather than passing it as a parameter.
function main() { return { who: typeof name !== "undefined" ? name : "unset" };}kis script run greet.js --vars name=anand --debugResult: {"who":"anand"}Use this for ambient configuration — an environment name, a threshold — rather than for the thing the script operates on. A parameter is visible in the signature; a global is not.
--env file.yaml loads a whole file of them, and it is the same mechanism as a flow’s vars:
block — which is why a script moves between the two unchanged.
Getting results out
Section titled “Getting results out”A node writes into the run with setvar, and later nodes read it back with {{ }}:
list: truetasks: - name: count shell: script: ls -1 | wc -l setvar: files
- name: report print: message: "{{files}} files"The value outlives the node. Anything after it in the run can read {{files}}.
The return value is the result. At the CLI it prints with --debug; in a flow it lands wherever
the script: task’s setvar points.
function main() { const r = shell.execute({ script: 'ls -1 | wc -l', capture: true }); return { files: Number(r.output.trim()) };}Return a map rather than a scalar when a caller might later want more than one thing: adding a field breaks nothing, changing a number into a map breaks everyone.
A different entry point
Section titled “A different entry point”function handler(a, b) { return a + b;}kis script run math.js --func handler 3 4 --debugResult: 7Useful when one file holds several related operations and you want to exercise one.
Choosing
Section titled “Choosing”| Input | Flow | Script |
|---|---|---|
| The data the job acts on | -v k=v | positional arguments |
| Ambient configuration | -e env.yaml | --vars, --env |
| One of several operations in a file | -n <flow-name> | --func |
| Tenancy identity | run context | --cpet customer,product,environment,tenant |
Verify
Section titled “Verify”Print the arguments back before trusting the types:
function main(a, b) { return { a: a, typeA: typeof a, b: b, typeB: typeof b };}That one line settles every “why is my number a string” question.