CLI
The Fayz CLI scaffolds projects, validates manifests and architecture boundaries, assists the migration from config-in-code to a manifest, and provisions an app's Supabase database from the installed packages. You run it without installing anything, via npx:
npx @fayz-ai/cli <command>
Commands
| Command | What it does |
|---|---|
fayz create storefront <name> | Scaffolds a storefront (customer-facing shop). |
fayz create admin <name> | Scaffolds a multi-tenant admin app. |
fayz create member <name> | Scaffolds a member/student portal. |
fayz create plugin <name> | Scaffolds an app-local plugin (incubator). |
fayz doctor [dir] | Validates the manifest + architecture boundaries. |
fayz extract [dir] | Assisted migration from config-in-code → manifest. |
fayz db apply [dir] | Provisions Supabase from the installed packages. |
fayz db pool status | Shows the migration ledger for each industry pool (Runner v2). (≥ 0.3.0) |
fayz db pool apply <name> --app <dir> | Applies an app's plan to one pool, always ledger-gated. (≥ 0.3.0) |
fayz db pool move-tenant --from <p> --to <p> --tenant <uuid> [--yes] | Moves a tenant between pools (dry-run unless --yes). (≥ 0.3.0) |
fayz db fan-out --app <dir> | Applies an app's plan across every pool: canary first, then the rest. (≥ 0.3.0) |
fayz login [--token | --status] | Stores the Fayz platform token used by deploy. (≥ 0.3.0, rolling out) |
fayz logout | Removes the stored credential. (≥ 0.3.0, rolling out) |
fayz deploy [dir] [--dry-run | --yes] | Publishes the app to the Fayz platform. (≥ 0.3.0, rolling out) |
fayz --help | Shows help. |
fayz --version | Shows the version. |
The db pool, db fan-out, login, logout and deploy commands require CLI ≥ 0.3.0 — they don't exist in the published 0.2.0. login/logout/deploy are still rolling out to the invited developer network.
create takes a kind and a kebab-case name (^[a-z0-9][a-z0-9-]*$) — no flags. It generates a Vite project with app.manifest.json, src/plugins.generated.ts, src/registry.tsx, AGENTS.md and .env.example. See tutorial 01.
fayz create plugin
Creates an app-local plugin in src/plugins/<name>/, following the same contract as the official plugins (index/data/schema/README). Details in Incubator.
fayz doctor
Validates the app in the current directory: manifest structure, referenced plugins, locale coverage and the architecture boundaries (provider imports + supported surface). Structural manifest problems exit with an error (exit 1); boundary problems are warnings (soft enforcement). An app without an app.manifest.json but with a package.json is treated as code-first — only the boundaries run, and it passes. See Test and debug.
fayz db apply
Builds the migration order — core first, then each plugin's versioned modules, then the incubator ones — from the installed packages, and applies it to your Supabase project via the Management API. The current CLI labels the steps spine → drizzle → seed → plugins → incubator (the first three are the core; the label changes in the industry pools wave).
Flags
| Flag | Effect |
|---|---|
--dry-run | Prints the ordered plan only; no network calls. |
--yes, -y | Skips confirmation (required in non-interactive shells). |
--spine-only | Applies only the @fayz-ai/db core (the flag keeps the spine label in the current wave). |
--plugins-only | Applies only plugin + incubator migrations. |
--only-plugins a,b | Restricts the plugins step to the named ids. |
Env (required for a real apply; never for --dry-run)
| Variable | Description |
|---|---|
SUPABASE_PROJECT_REF | Project ref (alias: SUPABASE_REF). Dashboard → Project Settings → General. |
SUPABASE_PAT | Personal access token (alias: SUPABASE_ACCESS_TOKEN). Dashboard → Account → Access Tokens. |
The command reads from the process environment first, then <app>/.env.local, then <app>/.env — and the files never override the environment. Without these variables, a real apply stops with a clear error; --dry-run doesn't need them.
# plan without touching the database npx @fayz-ai/cli db apply --dry-run # apply (asks for confirmation; use --yes in CI) npx @fayz-ai/cli db apply
The full connection flow is in Supabase.
fayz extract
Assists the migration of a code-first app (config in src/App.tsx / defineSaas) to app.manifest.json. Run it at the root of an existing app; it reads the config code and proposes the equivalent manifest.
fayz db pool and fayz db fan-out (industry pools — Runner v2) BetaRequires CLI ≥ 0.3.0 — these commands don't exist in the published 0.2.0.
Requires CLI ≥ 0.3.0 — these commands don't exist in the published 0.2.0.
While db apply provisions one Supabase project, Runner v2 operates over a fleet of industry pools — the Supabase projects shared per vertical. It reads the pool registry from cli/pools.config.json (use --pools-file to point at another file) and takes the token from SUPABASE_PAT / SUPABASE_ACCESS_TOKEN (each pool's ref comes from the pools file, not the environment).
| Command | What it does |
|---|---|
fayz db pool status | Prints each pool's migration ledger: what's already applied and what's pending. |
fayz db pool apply <name> --app <dir> | Applies the app's plan (derived from the packages installed in <dir>) to one named pool. |
fayz db pool move-tenant --from <p> --to <p> --tenant <uuid> [--yes] | Moves a tenant from one pool to another. |
fayz db fan-out --app <dir> | Applies the app's plan across every pool: the canary first, then the rest. |
Applies are always ledger-gated
Every apply goes through each pool's ledger. A file that's already applied and unchanged is skipped. A file that's already applied but whose checksum changed is a HARD STOP — the runner halts instead of reapplying. The rule is absolute: never edit an applied migration; write the next one. This keeps each pool's history reproducible and auditable.
Fan-out: canary first
db fan-out doesn't apply everywhere at once. It applies to the pool marked as canary first (--canary <pool> to force another), and only then to the rest — so an error surfaces in one pool before it touches the whole fleet. Pools in PROVISIONING state are skipped during fan-out unless named explicitly; a pool marked dataCritical requires --allow-critical (alongside --yes).
move-tenant is safe by construction
move-tenant is dry-run by default — without --yes it only prints the plan. With --yes, it: backs up to JSON before any write, inserts the records into the destination (parents-first), verifies the counts (a mismatch is a HARD STOP and the source stays intact), and only then deletes from the source (children-first). The destination pool can't be in PROVISIONING.
fayz login / fayz logout / fayz deploy ExperimentalRequires CLI ≥ 0.3.0 and is rolling out to the invited developer network. If deploy returns an authorization error, your token doesn't have CLI access enabled yet — the static host gets the same app live in the meantime.
Requires CLI ≥ 0.3.0 and is rolling out to the invited developer network. If deploy returns an authorization error, your token doesn't have CLI access enabled yet — the static host gets the same app live in the meantime.
This trio publishes an app straight to the Fayz platform, with no CI of your own.
fayz login [--token <fayz_...> | --status]— stores the platform access token (prefixfayz_) in~/.fayz/credentials.json(mode0600, owner-readable only). Without--token, it reads theFAYZ_TOKENenv var or prompts interactively (in a non-interactive shell with no token, it fails fast with instructions).--statusshows the masked credential, with no network call. Login performs no network validation — the token is validated on the first deploy.fayz logout— deletes the stored credential.fayz deploy [dir] [--dry-run | --yes]— collects the app's source files, creates/links a project on the platform and triggers the server-side build with static hosting. The project link lives in<app>/.fayz/project.json(add.fayz/to your.gitignore). The published app lands athttps://<app>.live.fayz.ai.--dry-runmakes no network calls; a real deploy asks for confirmation unless you pass--yes.
Token and URL resolution: the token comes from FAYZ_TOKEN (env, takes priority) → ~/.fayz/credentials.json. The API URL comes from FAYZ_API_URL (default https://beta.fayz.ai/api). The step-by-step walkthrough with screenshots is in Fayz deploy.
Next: the fields doctor validates, in Plugin manifest — reference.