CLI reference¶
Every read command supports --json with a stable, documented schema (coding agents parse it;
/dev/schema/cli serves the schemas in dev mode). -d/--project-dir defaults to the current
directory everywhere.
Project¶
| Command | Options | |
|---|---|---|
tuvl init [NAME] |
--sample, --preset gemini\|openai\|anthropic\|ollama, --decision-model laya\|none, -y/--yes, --multi-tenant, --no-ai-skills |
Scaffold a project. A preset writes llms/default.yaml with a current model id, reading the key from the environment. --sample is a ticket-triage project (spec, TaskPlan, tests, lock) that passes the CI gate as created. --decision-model laya adds llms/laya.yaml, LAYA_API_* in .env and a compose.yaml that runs laya-serve locally (asked interactively, default no). -y accepts every default |
tuvl validate |
--strict, --json |
Contracts, data flow, types, policy, artifacts, lock; prints each workflow's determinism profile and worst-case tokens. --strict fails on warnings. Ends with needs models: every model the workflows use, its provider and the environment variables it reads (or "no LLM required"); V028 = unknown model reference, V029 = undeclared credentials (an error at ship time) |
tuvl codegen [WORKFLOW] |
--check |
Schemas, code-agent stubs (body-preserving merge), prompt placeholders, spec tests. --check writes nothing and exits 1 on drift |
tuvl lock |
--check, --mcp/--no-mcp |
Pin model ids, artifact hashes, judge/decision models and MCP tool schemas in tuvl.lock |
tuvl doctor |
--live, --json |
Are the project's models configured? Lists each model, the variables it needs and which are missing (exit 1 if any). --live makes one minimal call per model (a few tokens; Laya/Jev: their /health). A production server runs the same check at startup and refuses to start on a missing variable; /health reports each model's readiness |
tuvl test |
--live, --allow-uncertain, --strict, -k/--only TEXT, --json |
Run Test documents offline (--live lets unmocked model/tool agents call out). Results are PASS, STUBBED (expectations met only through unmocked pending placeholders — not counted) or FAIL; --strict (CI) also fails on stubbed results and untrusted judge calibration |
tuvl skills update |
--diff |
Refresh AGENTS.md and .agents/skills/ to this tuvl version (removes 1.x skills; mirrors to .claude/skills/) |
Specs¶
| Command | Options | |
|---|---|---|
tuvl spec verify [SPEC_FILE…] |
--strict, --no-tests, --json |
Does the implementation match the spec? Zero tokens; rules R001–R010 and a traceability matrix (step → agent → tests). Exits 1 on a mismatch (--strict: also on unfinished work) |
tuvl spec new NAME |
--owner, --workflow |
Write specs/<name>.md from the template |
tuvl spec check [SPEC_FILE…] |
--strict, --json |
Is the spec complete and consistent? Zero tokens; rules S001–S016 with line numbers, plus P001–P005 on its task list (spec-driven). Exits 1 on a blocking finding (--strict: on warnings too) |
tuvl spec status [SPEC_FILE] |
--strict, --no-tests, --json |
Derived task statuses. --strict exits 1 unless every live task is done and none is blocked or stale |
tuvl spec diff [SPEC_FILE] |
--json |
Stale tasks and spec sections no task covers |
Servers¶
| Command | Options | |
|---|---|---|
tuvl dev |
-p/--port (8885), --auto-login, --show-key, --no-browser, -H/--allow-host |
Dev server with Insight and the dev API, reloading on YAML changes. The session key is stored in .tuvl/.dev-session (0600); --show-key prints it |
tuvl run |
-p/--port, --host, -w/--workers, --role all\|api\|worker, -c/--concurrency (8), -H/--allow-host |
Production server. api serves HTTP and runs synchronous requests inline; worker executes the queue |
tuvl mcp |
--allow-write |
Dev tools for coding agents over MCP (stdio); --allow-write adds codegen_write, run_workflow, pin_fixture. Refuses production |
Runs¶
These talk to a running server: -u/--url (TUVL_URL, default http://localhost:8885) and
-t/--token (TUVL_TOKEN, needs runs:read).
| Command | Options | |
|---|---|---|
tuvl runs list |
-w/--workflow, -s/--status, -n/--limit, --json |
Recent runs, newest first |
tuvl runs get RUN_ID |
One run as JSON | |
tuvl runs tail [RUN_ID] |
-w/--workflow, -p/--payload JSON |
Follow a run's events until it ends (or start one with --workflow); exits 1 if it fails |
tuvl runs pin RUN_ID |
-n/--name |
Export the journal to tests/fixtures/<workflow>/<name>.journal.json |
tuvl runs replay FIXTURES… |
--json |
Re-run pinned journals offline; fail if the end or output differ |
Shipping and operations¶
See Shipping to production for a walkthrough.
| Command | Options | |
|---|---|---|
tuvl ship |
-t/--tag, --no-build, --push, --force, --strict, --with-laya/--without-laya |
Gate (validate, no pending agents — V010 is an error at ship time, current lock), then .dockerignore as an allowlist (only models, workflows, agents, artifacts, datasources, llms, federation, config, lock and .tuvl/system.yaml / telemetry.yaml enter the image; specs, task lists, tests, agent rules and skills, compose files and anything else stay out — V027 refuses development files), deploy/Dockerfile (pins the locked tuvl version) and a Helm chart (split: true for api + worker Deployments; a Laya Deployment + Service, with LAYA_API_BASE set for the engine, when a model uses provider: laya or with --with-laya — laya.enabled in values.yaml) and docker build |
tuvl keys generate |
-w/--write, -f/--force |
A persistent Ed25519 key for signing access tokens (TUVL_SIGNING_KEY) |
tuvl db generate-rls |
-o/--out |
Idempotent row-level-security SQL for tenant-scoped tables |
tuvl db check-rls |
Exit 1 if a tenant-scoped table lacks its RLS policy |
The CI gate¶
tuvl spec check && tuvl validate --strict && tuvl codegen --check && tuvl lock --check && tuvl test --strict && tuvl spec verify --strict && tuvl spec status --strict