AvelonDocs

Guide 08

reeve

08. reeve

The CLI. Built with Ink, running on Bun, compiled to a single binary.

Bare ./reeve opens a TUI. Any subcommand with arguments skips it entirely.


The TUI

┌─ avelon ────────────────────────────── my-app · supabase · next · local ─┐
│                                                                           │
│   Make        model, controller, request, policy, ward, event, listener,  │
│               errand, action, command, middleware, view, driver, package  │
│   Database    migrate, rollback, fresh, seed, schema:pull                 │
│   Wards       list, sync, check, explain                                  │
│   Routes      list, sync                                                  │
│   Errands     work, failed, retry, flush                                  │
│   Inspect     event:list, config:show, capabilities, about                │
│   Doctor      bailiff, docs:check, ward:check, types:check, env:check     │
│                                                                           │
│   ↑↓ navigate · ⏎ select · / search · q quit                              │
└───────────────────────────────────────────────────────────────────────────┘

Rules:

  • Every TUI path prints the equivalent non-interactive command before running it. People learn

the scriptable form by using the friendly one.

  • Any subcommand invoked with arguments skips the TUI. CI never sees an interactive prompt.
  • --no-tui and a non-TTY stdout both force plain mode.
  • The header always shows app name, database driver, adapter, and environment. "Which database am I

pointed at" is the question that precedes most disasters.

  • Destructive commands name what they will destroy and require typing the environment name when it

is not local.


Generators

reeve make:model Post -mfcpw     # model + migration + factory + controller + policy + ward
reeve make:controller PostController --resource
reeve make:request StorePostRequest
reeve make:policy PostPolicy --model=Post
reeve make:ward PostWard --model=Post
reeve make:event PostPublished
reeve make:listener NotifySubscribers --event=PostPublished --queued
reeve make:errand GenerateThumbnail
reeve make:action PublishPost
reeve make:middleware EnsureSubscribed
reeve make:command PruneDrafts
reeve make:view posts/Index
reeve make:auth                  # routes, controllers, requests, views for sign in and up
reeve make:driver storage r2     # driver package with conformance suite wired
reeve make:package billing       # package skeleton with README in house style

reeve stub:publish ejects the generator templates into stubs/ so a team can change the shape of generated code without forking the framework.


Database and wards

reeve migrate
reeve migrate:rollback
reeve migrate:fresh --seed
reeve migrate:status
reeve make:migration create_posts_table
reeve schema:pull                # regenerate database/types.ts from the live schema
reeve db:seed

reeve ward:list                  # every model, its ward, and enforcement paths
reeve ward:sync                  # compile wards into a migration
reeve ward:check                 # fail on missing wards or drift
reeve ward:explain Post read     # print the predicate and the SQL it compiles to

ward:explain exists because a compiled policy you cannot read is a policy you cannot trust.


Routes and events

reeve route:list                 # method, URI, name, action, middleware
reeve route:sync                 # regenerate the adapter's router
reeve event:list                 # events, listeners, delivery modes, priorities

Errands

reeve errand:work                # drain loop, local
reeve errand:failed
reeve errand:retry <id|all>
reeve errand:flush

Serverless functions cannot hold a daemon, so the deployed worker is a drain-and-exit route handler invoked on a schedule. errand:work runs the same drain logic in a real loop locally, so the code path is identical in both places.


Doctor

reeve doctor

Aggregates everything that should be true before a push:

  • Bailiff clean
  • Ward drift
  • Type drift between models and the live schema
  • Missing environment variables
  • Migration status
  • Capability matrix for the resolved config, diffed against the previous environment

One command, one exit code.

reeve capabilities

Prints what the configured drivers can and cannot do, which is the fastest answer to "why does DB.transaction not exist."


Inspect

reeve tinker                     # REPL with models, DB, and helpers preloaded
reeve config:show                # resolved config with secrets redacted
reeve about                      # versions, adapter, drivers, runtime

Documentation

reeve docs:check
reeve docs:check packages/orm
reeve docs:check --workspace

Lints package READMEs against the house style in 10-conventions.md. A package fails when a required section is missing, a TypeScript or JSON code block does not parse, or a public export is absent from the Method Reference table. Waive a section or export with <!-- docs:check-waiver: section Testing --> or <!-- docs:check-waiver: export name -->. make:package scaffolds a README that already passes.