Scaffolding
zever new, zever add, zever generate, zever extract. See the command table.
Flags-only toolkit shell with exact CLI invocations for every command.
Scaffolding
zever new, zever add, zever generate, zever extract. See the command table.
Inspection
zever compile, check, breaking, fmt, doctor, config show, routes, explain, check-boundaries, graph. See the command table.
Runtime
zever serve, dev, queue:work, schedule:run, tinker. See the command table and dev and tinker rules.
Database
zever db migrate, db rollback, db seed. See the command table.
zever is a flags-only toolkit shell. Every command has an exact CLI
invocation; run zever --help for the grouped command map.
When to use: scaffold, inspect, run, migrate, and document a Zever
project. When not to use: project code stays in Go and .zen; the CLI
drives it, never hosts logic.
go install .../cmd/zever@vX.Y.Z also works from v0.7.2 on). See Installation:curl -fsSL https://raw.githubusercontent.com/zenta-dev/zever/main/install.sh | shzever --help prints the grouped map (Scaffolding / Inspection /
Runtime / Database / Operations).Global flags apply to every command:
zever --quiet <command> # suppress hints/tips on stderr; errors still printzever --no-color <command> # disable styled outputzever --json <command> # machine-readable JSON envelope (also ZEVER_JSON=1)zever -V # print the CLI version (alias for --version)zever --help --agent prints the command map in an agent-friendly form.
Structured --json data is emitted by the inspection commands
(compile, check, explain, doctor, routes, config show,
graph, breaking, check-boundaries) plus outbox, upgrade, and
uninstall; every other command emits a JSON error envelope on failure.
doctor --json reports ok:false with a nonzero exit when any battery
fails.
Most commands that write files or touch the database (new, add,
extract, generate *, db migrate, db rollback, upgrade,
uninstall) accept --dry-run to preview without applying.
--no-color is also honored via ambient NO_COLOR / TERM=dumb. Guided
prompts for one-shot commands: -i / --interactive (before or after the
subcommand) or ZEVER_INTERACTIVE=1|true|yes enables huh prompts.
zever <command> -h always prints flags without running anything.
Bare-command contract: bare zever (no subcommand, TTY or not) prints
usage to stderr plus zever: missing subcommand and exits 1, so scripts
never hang. All errors go to stderr; stdout stays clean for command
output.
No resolver step: pick the command, pass flags, check the exit code.
| Code | Meaning |
|---|---|
0 |
success |
1 |
runtime error (message on stderr) |
2 |
flag misuse (error on stderr, no usage dump) |
--help output goes to stdout; errors and bare-invocation usage go to
stderr.
zever --helpzever completion bash > /tmp/zever.bashzever docs --dir /tmp/zever-docsls /tmp/zever-docsecho exit:$?Expected output:
grouped command map on stdout (Scaffolding / Inspection / Runtime / Database / Operations)completion script at /tmp/zever.bashone man page plus one markdown file per command under /tmp/zever-docsexit:0Schema loop example:
zever fmt --write schema/zever check schema/zever compile --out ./generatedecho exit:$?Expected output:
fmt: normalized files listed, if anycheck: silent on successcompile: per-backend output under ./generatedexit:0| Group | Equivalent CLI |
|---|---|
| Scaffold | zever new (battery picker adds beyond the log, router floor; --profile minimal|api|full presets) |
| Scaffold | zever add <battery>[/<adapter>] (adds a battery to an existing project; zever add -h prints flags) |
| Scaffold | zever generate |
| Scaffold | zever generate tinker |
| Scaffold | zever extract |
| Inspect | zever compile (--check gates drift: exit 1 when committed output differs; runs go mod tidy when generated code imports modules go.mod lacks, skip with --no-tidy) |
| Inspect | zever check |
| Inspect | zever breaking |
| Inspect | zever fmt |
| Inspect | zever doctor |
| Inspect | zever config show |
| Inspect | zever routes |
| Inspect | zever explain |
| Inspect | zever check-boundaries |
| Inspect | zever graph |
| Runtime | zever serve |
| Runtime | zever dev |
| Runtime | zever queue:work |
| Runtime | zever schedule:run |
| Runtime | zever tinker |
| Database | zever db migrate |
| Database | zever db rollback |
| Database | zever db seed |
| Operations | zever outbox (status, dlq list, dlq requeue, dlq purge, purge; see Outbox Ops) |
| Operations | zever uninstall (remove the zever and zever-lsp binaries; --dry-run, --keep-lsp, --yes/--force) |
| Operations | zever upgrade (upgrade the zever binary to the latest release; --version, --check, --dry-run, --yes/--force) |
| Tooling | zever completion <bash|zsh|fish|powershell> |
| Tooling | zever docs --dir <dir> |
| Flag | Effect |
|---|---|
--quiet |
suppress hints/tips on stderr |
--no-color |
disable styled output |
--json |
machine-readable JSON envelope output (also ZEVER_JSON=1) |
-V |
print the CLI version (alias for --version) |
--dry-run |
preview file edits / SQL / removals without applying (where supported) |
-i, --interactive |
guided huh prompts for one-shot commands |
--batteries a,b |
zever new: extra batteries to scaffold beyond the floor (skips the battery prompt) |
--profile minimal|api|full |
zever new: start-small preset (explicit --batteries add to it) |
--check |
zever compile: verify committed output matches a fresh compile, write nothing (exit 1 on drift) |
--no-tidy |
zever compile: print a hint instead of running go mod tidy when go.mod misses modules the generated code imports |
--adapters b=a,... |
zever new: per-battery adapter overrides (implies the battery, skips its adapter prompt) |
-y, --yes |
zever new: skip all prompts, scaffold floor plus flags only |
--list-batteries |
zever new: print the battery/default-adapter table to stdout and exit |
--module PATH |
zever new: Go module path for the new project (default: the app name itself) |
--dir PATH |
zever new: output directory (default ./<name>) |
--framework-version V |
zever new: depend on a published Zever version instead of a local replace directive |
--force |
zever new: scaffold into a non-empty directory anyway |
-h |
print flags without running |
zever addAdds one core battery to an existing project. Synopsis (exactly one positional, no prompting):
zever add <battery>[/<adapter>] [--adapter NAME] [--force] [--module PATH[@VERSION]] [--dry-run]--adapter overrides the slash form, --force overwrites an existing
wiring.go registration, --module names a plugin battery’s Go module
(required for plugin batteries), and --dry-run prints the edits
without writing them.
The adapter may be omitted (zever add cache selects
config.Default()’s own pick, e.g. memory) or pinned explicitly
(zever add cache/redis). Empty halves, extra slashes, and unknown
batteries are errors. Run it from the project root (the directory
holding go.mod); without one it fails.
Effects (two append-only edits, never overwriting hand-written code):
go.mod: adds require entries for the battery’s core and adapter
modules at the version pinned by the framework require (falling back
to the CLI’s built-in framework version). For local checkouts (a
replace github.com/zenta-dev/zever => <local-dir> marker), matching
local replaces are derived for both modules. Paths already required
(any version) or already replaced are left untouched.internal/app/app.go: splices in the adapter’s named import plus its
Register() call (gofmt-normalized). Either half already present is
skipped, so re-adding the same battery is a no-op. Fails if the file
has no import block or no func New, scaffold it with
zever generate server first.zever add does not run go mod tidy, run it afterwards so go.sum
catches up, then serve:
zever add cache/redisgo mod tidyzever servezever outboxInspects and repairs the outbox dead-letter queue without starting the
relay. Every subcommand takes --dsn and --table;
without --dsn/--table the values come from environment variables
(OUTBOX_DSN, OUTBOX_TABLE) plus environment overrides. --json gives
machine-readable output on every one.
| Command | Effect |
|---|---|
zever outbox status |
Relay counters (pending, processed, failed, last_error, stalled) |
zever outbox dlq list [--limit N] |
Failed messages, oldest first (0 uses the adapter default page size) |
zever outbox dlq requeue --id X |
Requeue one failed message, resetting its attempt count and lock |
zever outbox dlq requeue --all |
Requeue every failed message |
zever outbox dlq purge --id X |
Delete one failed message by id |
zever outbox purge --before 168h |
Delete processed messages older than the given duration |
--id and --all on requeue are mutually exclusive and exactly one
is required. purge --before takes a Go duration and must be
non-negative. dlq purge needs an adapter that implements
outbox.Deleter; only db does, so an unsupported adapter reports
does not support message deletion rather than deleting nothing. Run
these from a deploy box with database access, not from every replica.
Metrics, alert rules, and the full runbook are in
Outbox Ops.
zever uninstallRemoves the running zever binary (resolved via os.Executable(),
symlinks followed) plus every zever-lsp binary found on PATH.
Binaries only: projects, caches, profiles, and config are never touched.
zever uninstall --dry-run # print the removal plan, delete nothingzever uninstall --yes # confirm without promptingzever uninstall --keep-lsp --yes # leave zever-lsp in placeWithout --yes/--force, a terminal gets a [y/N] prompt defaulting
to No; without a terminal the command fails and prints the exact
zever uninstall --yes re-run. On Windows the running binary cannot
delete itself, so self-delete becomes a printed del "<path>" step
while zever-lsp removals stay automatic. --json emits the
machine-readable envelope instead of the human plan.
zever upgradeUpgrades the running zever binary to the latest stable release (or
--version X for an explicit target). The current version is the
compiled cliVersion; the default target comes from
api.github.com/repos/zenta-dev/zever/releases/latest.
zever upgrade --check # print the available version, exit 0zever upgrade --dry-run # print the upgrade plan, download nothingzever upgrade --yes # confirm without promptingzever upgrade --version v0.7.0 --yesVersions compare with golang.org/x/mod/semver: an already-current
target prints already current and exits 0, and a target older than
the installed binary refuses the downgrade unless --version
requested it explicitly. The runtime.GOOS/runtime.GOARCH asset
(.exe suffixed on Windows) plus SHA256SUMS.txt downloads from the
release, the asset is verified with crypto/sha256, and any mismatch
or network error aborts before anything is replaced. POSIX installs
atomically (temp file in the binary directory, chmod +x, rename over
the running binary); Windows stages zever.new.exe beside the binary
and spawns a detached cmd /C helper that moves it into place after
our PID exits — restart the shell to complete. Confirmation follows
the same TTY rules as uninstall; --json emits the envelope.
zever dev is local watch-only: it prints
zever dev: watching <schemaDir> and <serverEntry> … (Ctrl-C to stop)
to stdout and restarts the server entrypoint on change. Ctrl-C stops the
watcher and the server. Never a deployment path.zever tinker is dev-only: every start prints
WARNING: Zever tinker is development-only: it evaluates arbitrary Go against a live container, so run it against a development database only.
to stderr. The REPL talks to the real container via the per-project shim
(project.tinker_entry, default cmd/tinker-shim; scaffold with
zever generate tinker). Never point it at production data.zever completion <shell> prints that shell’s completion script to
stdout; redirect into the completions dir, e.g.
zever completion bash > /etc/bash_completion.d/zever. The scripts
complete dynamically: .zen files for the schema commands, the
generate kinds, --backend (comma lists), --profile, --adapters
(battery=adapter for new, battery or battery/adapter for build).zever docs --dir <dir> writes one man page plus one markdown file per
command into <dir>; build stripped release binaries with
make build-release (-trimpath -ldflags="-s -w").migrate / rollback mask the DSN (--dsn ***) in display and output.0 / 1 / 2 are the
contract; hint wording may change (and --quiet suppresses hints).$(...) capture stay clean.dev and tinker never run in prod: dev is watch-only, tinker
evaluates arbitrary Go. Gate both out of deployment images.zever exits 1: expected; it prints usage to stderr with
zever: missing subcommand. Pass a subcommand or --help.zever <command> -h; only the error prints.tinker warns on every start: by design, the dev-only warning goes
to stderr each launch. Do not silence it; do not aim it at prod data.dev does not restart on edits: it watches the schema dir and the
server entrypoint only. Edits outside those paths need a manual restart.--no-color or set
NO_COLOR=1; TERM=dumb is honored the same way.zever outbox reports empty counters: the resolved --table does
not match the table the relay writes. Compare against
OUTBOX_TABLE environment variable.zever outbox dlq purge says the adapter does not support deletion:
only the db adapter implements outbox.Deleter. Switch the
connection, not the command.config show outputcompile outputszever outbox in context