Command line
Kasm Session Runtime is one binary, kasm-session-runtime. Its first argument picks what it does. Most settings come from the environment; see Environment variables.
| Invocation | What it does | Needs a model |
|---|---|---|
kasm-session-runtime run <scenario.yaml> [more.yaml ...] |
Runs one or more scenario files in the session and writes a report for each | No. Steps that need visual judgement are recorded as not judged; a goal: needs one |
kasm-session-runtime mcp |
Serves the MCP method surface so an outside agent can drive the running session | No. The model-backed methods need one |
kasm-session-runtime compile-plan <run output dir> [flags] |
Turns a finished agentic run’s report into a plan: block |
No. It runs offline |
kasm-session-runtime (no arguments, or arguments that are not a subcommand) |
Runs one scenario taken from KASM_RUNTIME_SCENARIO_B64, or the default scenario when that is empty |
No, as for run |
kasm-session-runtime --version |
Prints the binary version and the report schema, then exits | No |
--version (or -version) counts only when it is the whole argument list. It prints a line of this form:
kasm-session-runtime 0.0.0-dev (report schema nix-testbench-report/1)kasm-session-runtime run login.yaml checkout.yamlRuns each scenario file in turn in the same session, with no reset between them. A scenario that needs a clean state sets it up with its own steps.
KASM_RUNTIME_APPis required. It fills in each scenario’sapp,windowandprocesswhen the file leaves them out.KASM_RUNTIME_SCENARIO_B64is ignored; the scenarios come from the files.KASM_RUNTIME_DEADLINE_Sbounds the whole invocation. Each scenario gets whatever time is left, and a later scenario may be refused with “session deadline exhausted before this scenario could start”.- Each scenario writes to its own directory,
$KASM_RUNTIME_OUT/<name>/, where<name>is the file’s base name without its extension. Two files with the same base name get<name>,<name>-2, and so on. - After the last scenario,
runwritessummary.jsonand thenDONEat the top of the output directory. The top-level verdict is the worst of the scenario verdicts. See Report for the layout. - A file that cannot be read or does not parse gets a
test-errorreport in its own directory, and the rest still run. SIGTERMorSIGINT(Ctrl-C) stops the scenario in progress. It still writes its report, with verdicttest-errorand outcomeinterrupted. Scenarios not yet started get a report saying so, andsummary.jsonstill lands.- With
KASM_RUNTIME_OBSERVE=true, the run also serves the read-only observe routes the sidebar watches. See Sidebar protocol.
With no scenario files, run writes a test-error report saying it needs at least one, and exits 2.
kasm-session-runtime mcpServes the runtime’s methods over MCP so an outside agent, such as Claude Code, can drive whatever is on screen. It takes no arguments and runs no scenario.
- With
KASM_RUNTIME_SESSION_TOKENempty, it speaks MCP over stdin and stdout and ends when the client closes stdin. - With
KASM_RUNTIME_SESSION_TOKENset, it serves HTTP onKASM_RUNTIME_BIND_ADDR:KASM_SESSION_RUNTIME_PORT(default0.0.0.0:9434). Every acting request must carry the token in theX-Kasm-Runtime-Session-Tokenheader. The same listener serves the observe routes, the HTTP API, and, withKASM_ENABLE_CDP=true, a raw DevTools proxy at/cdp/. KASM_RUNTIME_APPis optional; it defaults tosession.KASM_RUNTIME_SCENARIO_B64may still carry a scenario. It is not run; it only supplies declared names that the input and accessibility methods can resolve.- There is no deadline unless
KASM_RUNTIME_DEADLINE_Sis set explicitly. When it is set, the server stops itself at that point. - It waits up to
timing.lifecycle.mcp_boot_timeout_s(30 seconds by default) for the X display before it fails. - On exit it writes
report.json,report.md,trace.jsonlandDONEtoKASM_RUNTIME_OUT. With no scenario, the verdict reflects the runtime’s own health:passfor a clean stop (a signal or the client closing stdin),test-errorfor a start-up or transport failure.
The methods are listed in MCP methods and the HTTP routes in HTTP API.
compile-plan
Section titled “compile-plan”kasm-session-runtime compile-plan out/login --scenario login.yaml > login-with-plan.yamlReads report.json (and, if present, trace.jsonl for the run id) from a finished agentic run’s output directory and prints a plan: block to stdout: the actions the model took, in order, each with a postcondition inferred from what the model checked afterwards. It makes no model call and needs no session, though the run it reads came from a goal: scenario and did need one. See Plans and postconditions.
| Flag | Default | What it does |
|---|---|---|
--scenario <file> |
none | Prints this base scenario with the compiled plan appended, and checks that the result parses. The base scenario must have a goal: and must not already have a plan: |
--allow-incomplete |
false |
Compiles even when the run’s model verdict was not goal-met. Without it, such a run is refused |
Flags may come before or after the directory argument.
The output lists, in a comment header, the transcript rows it left out and why. A plan step whose postcondition could not be inferred is printed with a TODO for you to fill in.
Exit codes
Section titled “Exit codes”| Code | run and no-argument invocation |
mcp |
compile-plan |
|---|---|---|---|
0 |
Verdict pass or pass-with-concerns |
Clean stop | Plan printed |
1 |
Verdict app-failed |
Not used | Refused or incomplete: model verdict not goal-met, a step with no inferable postcondition, no compilable rows, or the combined scenario does not parse. What could be compiled is still printed |
2 |
Verdict test-error, a configuration or scenario error, or a failure to write the report or DONE |
Start-up or transport failure, or a failure to write the report | Bad arguments, or a file that cannot be read or parsed |
For run with several files the code follows the worst verdict. If any scenario’s evidence is incomplete, or summary.json or DONE cannot be written, the code is 2 whatever the verdicts were.