fayzfayz sdk
PTEN

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

CommandWhat 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 statusShows 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 logoutRemoves 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 --helpShows help.
fayz --versionShows 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

FlagEffect
--dry-runPrints the ordered plan only; no network calls.
--yes, -ySkips confirmation (required in non-interactive shells).
--spine-onlyApplies only the @fayz-ai/db core (the flag keeps the spine label in the current wave).
--plugins-onlyApplies only plugin + incubator migrations.
--only-plugins a,bRestricts the plugins step to the named ids.

Env (required for a real apply; never for --dry-run)

VariableDescription
SUPABASE_PROJECT_REFProject ref (alias: SUPABASE_REF). Dashboard → Project Settings → General.
SUPABASE_PATPersonal 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.

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).

CommandWhat it does
fayz db pool statusPrints 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.

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 (prefix fayz_) in ~/.fayz/credentials.json (mode 0600, owner-readable only). Without --token, it reads the FAYZ_TOKEN env var or prompts interactively (in a non-interactive shell with no token, it fails fast with instructions). --status shows 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 at https://<app>.live.fayz.ai. --dry-run makes 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.