Automation
These commands make kis act: run a unit of logic (script),
orchestrate multiple steps (flow), schedule work
(cron), and verify services (test). See
Flows, pipelines & scripts in Core Concepts for how the
first two relate.
kis script
Section titled “kis script”What it is. A multi-language script engine. It runs a script file directly, with the language auto-detected by extension.
| Extension | Language |
|---|---|
.js | JavaScript (Goja) |
.lua | Lua |
.go | Go (Yaegi interpreter) |
.star | Starlark |
.cel | CEL |
.expr | expr |
.wasm | WebAssembly (wazero) |
Why it exists. Sometimes a rule engine is overkill and you just want to run a
function. Crucially, kis script uses the same engine and calling convention as a
flow’s script: task, so a script you develop and test standalone runs unchanged
inside a flow.
When to reach for it. Glue logic, transforms, one-off automation, or prototyping a step before embedding it in a flow.
run, execute a script
Section titled “run, execute a script”By default the engine calls main. Data arrives through two channels:
- Positional args (after the file) become function arguments.
--vars key=value/--env file.yamlbecome bare globals, the same ambient scope a flow’svars:block provides.
kis script run greet.js anand 7 # → main("anand", 7)kis script run process.js '[1,2,3]' '{"k":1}' # JSON-parsed → main([1,2,3], {k:1})kis script run hello.js # → main() (no args)kis script run x.js --vars name=anand # main() with bare global 'name'kis script run x.js --func handler 3 4 # call exported handler(3, 4)kis script run plugin.wasmA real script, showing the ambient host helpers (fs, log, now()) available
inside the runtime:
function main(question, answer) { var path = "log.json"; var data = fs.exists(path) ? fs.readJSON(path) : {}; data[question] = (data[question] || 0) + 1; fs.writeJSON(path, data); log.info("logged: " + question);}run flag | Meaning |
|---|---|
-a, --args | Function argument (repeatable; JSON-parsed best-effort) |
-f, --func | Function to call (default main) |
-v, --vars | Variables, bare globals (key=value) |
-e, --env / -n, --name | Environment file + name |
-t, --timeout | Timeout in milliseconds (default 5000) |
-r, --runtime | Force a runtime (e.g. v8, goja for JS) |
--namespaces | Host namespaces to enable (all, none, or a list) |
--root | Product root dir (overrides .kisai discovery) |
-d, --debug | Debug output |
Other script subcommands
Section titled “Other script subcommands”kis script validate transform.js # syntax + does it compile?kis script compile transform.js # test compilation for runtimeskis script bench hello.js --iterations 1000 # measure performancekis script rules transform.js --input ./data --update # batch over a JSON dirkis script version # script-engine version infokis script rules is the scripting counterpart to kis rules: it runs
a script for every JSON file in a directory, optionally injecting facts/bbox and
writing results back. Its flags mirror kis rules (-i, -o, -p, --facts,
-b/--bbox, --with-bbox, -k, -v, --update, -w) plus -f/--func and
-r/--runtime.
kis flow
Section titled “kis flow”What it is. Runs a multi-step workflow defined in YAML. A flow is a list of
tasks; each task does one thing (call a model, run a script, print…) and points to
what runs next. Aliased as kis automate.
Why it exists. Real work is rarely one call, it’s “ask the model, then transform, then store, branching on the result.” A flow expresses that as reviewable, re-runnable YAML instead of a brittle shell script, and adds workers, agent affinity, and restart-on-failure.
When to reach for it. Orchestrating several steps with control flow. For pure
data movement, use datapipes; for a single step, just
script run.
kis flow -f bot_flow.yamlkis flow -f bot_flow.yaml -s ask-llm -v question="Who picks my buddy?"kis flow -f bot_flow.yaml -e env.yaml -n staging --dryrunA minimal flow:
id: bot-flow-001name: onboarding_bot_flowvars: question: "Who chooses my onboarding buddy?"tasks: - name: ask-llm llm-chat: prompt: "Answer briefly: {{question}}" next: go: show - name: show print: "Reached the show step"| Flag | Meaning |
|---|---|
-f, --flow | Flow YAML file |
-s, --start | Start task |
-t, --tasks | Explicit list of tasks to run |
-v, --vars | Variables (key=value) |
-e, --env / -n, --name | Environment file + name |
-d, --dryrun | Validate/plan without executing |
-w, --workers | Worker count (default 1) |
--affinity / --affinity-key | Agent affinity scope and keys |
--pin-agent | Pin all tasks to one agent |
--restart-on-failure | Restart the whole flow on agent failure |
--logfile | Log file path |
kis cron
Section titled “kis cron”What it is. Schedules jobs using human-friendly phrases. Jobs are stored in
~/.kisai/cron/jobs/ and installed into your OS scheduler (crontab on Linux, launchd
on macOS, Task Scheduler on Windows).
Why it exists. It gives you readable schedules (“daily at 2am”) instead of raw cron syntax, plus a managed job store with history and logs, portable across operating systems.
When to reach for it. Recurring local jobs, backups, syncs, scheduled kis
commands.
kis cron add backup "daily at 2am" -- kis encrypt -i data.db -o data.enc -k "$KEY"kis cron add cleanup "every 15 minutes" -- ./cleanup.shkis cron add sync "weekly on mon,wed,fri at 6am" -- ./sync.shkis cron listkis cron show backupkis cron run backup # run it now, output to terminalkis cron logs backupkis cron history --last 20kis cron remove backupRun something once and have it remove itself:
kis cron once "in 30 minutes" --name my-deploy -- ./deploy.shkis cron once "tomorrow at 9am" -- ./morning.shSchedule phrases: every N minutes/hours, hourly [at :30], daily [at 2am],
weekly on monday [at 9am], monthly on 15th [at 3am]. Times accept 2am,
2:30pm, 14:00, noon, midnight. Useful add flags: --cron (raw cron
expression), --dir, --env KEY=VALUE, --capture-env common|all|VARS,
--overlap skip|queue|allow, --timeout 30m. Run kis cron sync to reconcile the
YAML job store with the OS scheduler, and kis cron init to create the cron
directories and validate that your OS scheduler is wired up correctly (optional, directories are created automatically on first add, but init is the way to
troubleshoot a setup).
Full subcommand list: add, list (alias ls), show, run, logs, history,
remove (aliases rm, delete), once, sync, init.
kis test
Section titled “kis test”What it is. The test client, turns API checks, load profiles, and request
collections into declarative YAML you can tag, run in CI, and persist. kis test is
the flag-driven functional runner. Aliased as kis run.
Why it exists. It covers smoke tests through performance testing without a bespoke harness: point it at a folder of test suites and an environment file, and it runs them, records results, and can emit JUnit for CI.
kis test -t tests/seshat.yamlkis test -t tests/ # every *.yaml in the dirkis test -t tests/ -e env.yaml -n staging # multi-env file, pick "staging"kis test -t tests/ --tags smoke # AND within a flag; repeat for ORkis test -t tests/ --db .atc/results.db --junit .atc/junit.xmlkis test -t tests/ --dry-run # validate without HTTP calls- When
-eis omitted, an env file next to--testsis auto-discovered (env.local.yaml→env.yaml→env.<name>.yaml).