The CLI
Every command and flag of npx @chatfuel/wizard, what each one falls back to when you omit it, and the two things --yes refuses to do.
Every option is declared on the program rather than on a subcommand, so --dir, --yes,
--dry-run and --verbose work on auth as well as on the scaffold.
Commands
| Command | What it does |
|---|---|
npx @chatfuel/wizard | Scaffolds the app. No command is the scaffold. |
npx @chatfuel/wizard doctor | Prints what the wizard can see before it asks anything: Node against the floor, the outbound proxy, which coding agents are on PATH, whether the bundled content is complete, and one row per module skill. A missing agent is a warning; everything else is a hard stop, and the command exits 1. |
npx @chatfuel/wizard auth | Rotates the Chatfuel token in an app that already exists. It identifies the app by the line it is about to rewrite — a .env that declares CHATFUEL_TOKEN — checks the new token against the API before writing, and rewrites the file at mode 0600. Runs in the current directory unless --dir says otherwise. |
Flags
| Flag | What it does | When you omit it |
|---|---|---|
-v, --version | Prints the version. | — |
-h, --help | Prints the usage. | — |
-y, --yes | Accepts all defaults and skips confirmations. | false — every question is asked. |
--dry-run | Stops before creating account assets. | false |
--verbose | Adds the transport's own message under the wizard's, for a failure that came from a network call. | false — you get the wizard's sentence and its hint. |
--embed | Copies the selected modules into the project you are standing in instead of scaffolding a new app. | false. --yes alone stays standalone; only --embed chooses embed. |
--dir <path> | Where to write the app, resolved against the directory you started the wizard in. | Prompted, defaulting to ./chatfuel-app; ./chatfuel-app under --yes. In embed mode and for auth, the current directory. |
--modules <ids> | Comma-separated module ids to install without prompting. An unknown id, or one that is not ready in this build, ends the run and lists the ones that are. | Prompted. Under --yes: every ready module except the opt-in ones, which are auth and admin — name those explicitly to get them. |
--agent <id> | claude or codex: whose skills layout the run is written for. Anything else is refused before the first prompt. | Whichever CLI is on PATH; the picker appears only when both are. Claude Code reads .claude/skills, Codex reads .agents/skills, and neither reads the other's. |
--app-name <name> | The app's own name: browser tab, top bar, sign-in screen. 1–60 characters, one line. | Prompted, defaulting to the Chatfuel workspace's title, then to Chatfuel App. |
--logo <path> | An image file that becomes the app's logo and tab icon. | Prompted; an empty answer keeps the mark the template ships, which is a real logo and not a placeholder. |
--workspace <id> | The Chatfuel workspace this deployment starts in. An id that is not on the account ends the run and lists the ones that are. | Prompted. Taken silently when the account owns exactly one. Under --yes without the auth module: the first workspace that holds a bot. Under --yes with auth: refused, because which workspace pays is not a question to answer on somebody's behalf. |
--supabase-token <pat> | Supabase personal access token for the Management API path. Used once, kept in memory, written nowhere. | SUPABASE_ACCESS_TOKEN from the environment, else prompted. |
--supabase-project <ref> | An existing Supabase project ref; skips the project picker. | The picker. Cannot be combined with --supabase-create. |
--supabase-create <name> | Creates a Supabase project with this name, or reuses the one already called that — so re-running a script leaves one project, not two. | The picker. Cannot be combined with --supabase-project. |
--supabase-org <slug> | Which organization --supabase-create puts the project in. | The only organization the token sees; a prompt when it sees several; under --yes with several, a refusal that names the slugs. |
--supabase-region <code> | Where --supabase-create places the project. | Prompted, preselecting the recommended region; that recommended one under --yes. |
--supabase-url <url> | Manual path: the project URL, https://<ref>.supabase.co. | The access-token path. |
--supabase-anon-key <key> | Manual path: the anon / publishable key. Set with --supabase-url; the pair selects the manual path, which makes no Supabase API call and ships the SQL for you to run. | The access-token path. |
--app-url <url> | An https origin added to the Supabase redirect allowlist, so sign-in works on that domain. | Prompted, and skippable. The deploy step adds the deployed origin itself when it knows it. |
--admin-password <value> | The admin module's password. Sixteen characters at least, no spaces, checked before the first prompt. | ADMIN_PASSWORD from the environment, else a generated one: 24 random bytes as base64url, printed once at the end and written only to .env. |
The two variables read instead of prompted
These are what make --yes usable in CI: a run that asks nothing still needs the answers, and
these two are the ones that cannot go on a command line safely.
| Name | Read by | What happens without it |
|---|---|---|
CHATFUEL_TOKEN | The token step, on its first attempt. | Under --yes, or with no TTY, the run stops and says so rather than falling through to a prompt nobody can answer: the prompt library closes the process on end-of-input, which would report success and leave no app behind. |
SUPABASE_ACCESS_TOKEN | The auth step, when --supabase-token is absent. | Under --yes the auth module refuses unless --supabase-url and --supabase-anon-key are both given. A token on its own is not enough either: it does not say which project to use, so pair it with --supabase-project or --supabase-create. |
Two more are read the same way but are not part of that contract: ADMIN_PASSWORD, before the
admin step generates one, and SUPABASE_SERVICE_ROLE_KEY, which the manual Supabase path takes
from the environment rather than asking twice. The wizard's own outbound calls read the proxy
variables too — see the environment page.
What --yes will not do
Two steps are skipped entirely under --yes, and for the same reason: a deployment is a public
URL with your Chatfuel token behind it, and a repository under your GitHub account holds the source
of an app wired to your bot. Neither is something a non-interactive flag should be able to cause.
| Step | Also skipped when |
|---|---|
| Deploy to Vercel | --dry-run, no TTY, or the app has no vercel.json. |
| Push to GitHub | --dry-run, or no TTY. |
Embed mode's dependency install is refused on the same grounds: an unattended run must not write to
a project it did not create. Under --yes the wizard also starts no agent, offers to install none,
starts no dev server, replaces an existing skill directory without asking, and adds the .env line
to .gitignore without asking.
What --dry-run stops
It stops account assets, not files. The scaffold still runs: the app is written to disk and its
dependencies installed. What it holds back is the trial checkout session, the Supabase project
creation, the database migrations and the auth-config PATCH — each printed as the call it would
have made, with the .env then carrying empty Supabase values.
One Chatfuel write has no --dry-run branch. If the token's account owns no workspace at all,
the workspace step creates one before anything else can continue — under --dry-run as well.
What is in the reference
Every command, flag, wizard step, environment variable and generated script, as lists you can check a value against.
What the wizard does, step by step
The wizard's step sequence in order — what each step asks, what it writes, when it is skipped, and which ones reach your Chatfuel account.