lua test compiles the project and executes one primitive in a local sandbox with your input. No model is involved, so the output is exactly what your code returns. Nothing is pushed and nothing changes for end users.
Verified against lua-cli 3.33.0.
Synopsis
Description
The command compiles locally, loads the artifact, and runs it. Your code runs for real: calls toData, User, Products, Jobs, Workflows, and the other runtime objects reach the platform with your credential and the project’s agent, so a tool that writes data writes it. Secrets come from the shell environment and the project’s .env, which env('KEY') reads. Tools see the request channel dev.
Local runs only.
lua test executes the SDK’s typed behavior, so Data.create(…, { index }), Data.collections(), and Voice.createSession work here but are not accepted by the deployed runtime yet.--name without a type exits 2. Pass both in automation and add --ci so any remaining prompt fails instead of waiting. lua test skill without --name opens a tool picker that --ci does not intercept (with stdin closed the command ends with exit 0 and runs nothing), so always pass --name. --name is the entity’s name, and for skill that is the tool’s name field (lookup_tickets), not the skill’s. --input is a JSON string whose shape depends on the type; without it the command prompts, an empty answer means {}, and under --ci the prompt exits 1 with Interactive prompt required but --ci flag is set, so pass --input '{}' for a tool that takes no fields:
Plural forms, and
tool for skill, are accepted. If execute throws, the run still completes: the result is { status: 'error', error: '<message>' } and the exit code is 0, so scripts must read the status field.
Text output prints a shape line such as Tool returned: Array[3] of DataEntryInstance — fields: id, data, … and then the value. --json prints only the returned value as JSON on stdout and routes progress to stderr, so lua test … --json | jq works.
Workflows
lua test workflow runs the workflow through the offline driver: code steps execute your code, agent steps return fake output unless --agents live, approvals and signals are answered from flags or prompts, and timers are fast-forwarded. Its compile skips server reconciliation, so nothing is registered on the agent. --step-output, --approve, --deny, and --park take the step id from your createStep or .approval() call (a foreach child such as review[2] falls back to its base id), never the wfa_ approval id that lua workflows approve --approval takes. An approval, signal, or resume with no flag answer is prompted for in a terminal; with stdin closed or under --json it exits 2 with APPROVAL_UNANSWERED, SIGNAL_UNANSWERED, or RESUME_UNANSWERED, and under --ci in a terminal the prompt exits 1. --json prints { "success": <status is completed>, "data": { "status", "output", "exitCode", "error", "ledger" } } on stdout, where status is completed, failed, or cancelled, error is { code, message, stepId } when present, and the compile chrome goes to stderr. The same flags work on lua workflows run, which also accepts --env KEY=value for a local env.template() overlay. See Test workflows offline.
Arguments
Options
Workflow flags:
Examples
Run a tool with its input and read the result:Output
Exit codes
See also
- Test an agent before you release
- Test workflows offline
lua chat— test with the model in the sandboxlua workflows—runand the platform verbs

