Skip to content

CLI

Warden ships a batteries-included command-line tool that handles the repetitive parts of building a Discord bot — spinning up a new project, generating class files, registering commands with Discord. It’s distributed as @warden/console, a dev dependency that installs the warden binary into your project. If you scaffolded your project with create-@warden it’s already there; if not, pnpm add -D @warden/console drops it in.

The first thing to know is what you’ve got:

Terminal window
pnpm warden --help

That prints every console command the binary knows about, including the make:* generators, sync, sync:clean, and anything your project or your plugins have contributed.

Before we go any further, a moment on vocabulary — because Warden has two different things called “commands” and you’ll want to keep them straight as you read through the rest of these docs.

Console commandsSlash commands
Run fromYour terminalDiscord client
Looks likewarden sync, warden make:command Warn/warn @user reason, /mod ban @user
Authored with@cli + ConsoleCommand@command + Command interface
Lives insrc/console/ or @warden/consolesrc/commands/
This section— (see Commands)

Everything in this section of the docs is about console commands — the warden binary, the generators it exposes, the sync and sync:clean commands, and how to write your own. When we say “the CLI”, we mean the whole console-command surface.

Ship with @warden/drizzle. Warden owns the DB workflow end-to-end — drizzle-kit stays out of sight.

CommandDoes
warden db:migrateApply pending migrations. Shows a preview; confirms in prod (use --force in CI).
warden db:migrate:statusPrint applied + pending migrations. Never prompts.
warden db:migrate:fresh [--seed]Drop all tables, re-apply migrations. Optionally run seeders after. Destructive; confirmation rules apply.
warden db:wipeDrop all tables. No re-apply. Destructive.
warden db:seed [--class=Name]Run registered seeders (classes decorated with @seeder() in src/db/seeders/). Explicit only — never runs implicitly.
warden make:migration <name> [--no-framework-schemas]Generate a new migration. Auto-includes schemas from installed @warden/* packages (audit, cache, permissions) — prints what it included.
warden make:seeder <name>Scaffold a seeder class.

Three ideas show up throughout the CLI, and once you’ve seen them in one place you’ll see them everywhere.

The authoring surface — single-string signature declarations, this.* helpers on a base class, inline markup tags, auto-registered convention flags like --force and --dry-run — is built around one idea: the shape of a command should be visible at a glance. You declare what your command takes; the runtime handles parsing, validation, and dispatch. If you’ve never written CLI tooling this way, you’re about to learn a lovely pattern for it.

The same @cli decorator and ConsoleCommand base class power Warden’s built-in make:* and sync commands, your project’s own src/console/ commands, and the commands any plugin ships in its node_modules/@warden/*/dist/commands/ directory. There’s no first-party/third-party distinction here — plugins get exactly the same primitives the framework uses for itself.

Every built-in flag comes with every command

Section titled “Every built-in flag comes with every command”

--force, --dry-run, --verbose, and --no-interaction are registered automatically on every ConsoleCommand. You consume them via this.isForce() / this.isDryRun() / this.isVerbose() / this.isInteractive() — no per-command boilerplate. That means your users get a consistent experience regardless of which console command they’re running: --force always skips the confirmation, --dry-run always prints the plan without executing, and so on.

A normal day working with Warden looks roughly like this:

Terminal window
# Start a new project
pnpm create @warden my-mod-bot
cd my-mod-bot
# Generate the slash-command boilerplate
pnpm warden make:command Warn
pnpm warden make:event MemberJoinLog --event guildMemberAdd
pnpm warden make:middleware IsModerator
# Run the bot in dev
pnpm dev
# Ship the commands to Discord when you're ready
pnpm warden sync --guild $DEV_GUILD_ID

Everything beyond that — a project-local seed command, a plugin-contributed make:migration, a custom deploy:prod wrapper you run before shipping — is just another @cli class. Keep reading to see how to write them.