Skip to content
ChatfuelSDK
Guides

Run it in CI, or without a terminal

--yes answers every question the wizard asks except two, which have to be in the environment — and it refuses two steps outright.

Every question the wizard asks has a non-interactive answer, and --yes takes it. Two answers are the exception, because they are credentials and a command line is not the place for them: they come from the environment or the run stops.

Stopping is the design. The prompt library exits the process on end-of-input, so a scripted run that fell through to a question nobody could answer would report success and leave nothing behind. A wizard that says CHATFUEL_TOKEN is not set and exits 1 is the version you can put in a pipeline.

Ask the machine what it can see

npx @chatfuel/wizard doctor

One row each: Node against the floor, the outbound proxy it will use, which coding agents are on PATH, whether the bundled content tree is complete, and one line per module skill. A missing agent is a warning; anything else fails and the command exits 1.

Run it as the first job of the pipeline. It asks nothing and reaches nothing, so a red row here is a machine problem rather than a credentials problem, and you find out before spending a token check on it.

Put the two credentials in the environment

NameWhat needs it
CHATFUEL_TOKENAlways. There is no flag for it. Generate one at the token page.
SUPABASE_ACCESS_TOKENOnly with the auth module, and only if you are not passing --supabase-token.

The token is used on the first attempt in place of the prompt, and then checked against the API. Under --yes there is no second attempt: a token that is missing, or one the API rejects, ends the run with a sentence naming which of the two happened.

ADMIN_PASSWORD is read the same way if you install the admin module, but it is not part of this contract — a run that finds neither the flag nor the variable generates a strong password, writes it to .env and prints it once.

Answer the rest with flags

--yes alone gives you a standalone app in ./chatfuel-app with every ready module except the opt-in ones, skills in the project, and the Chatfuel workspace picked for you. The flags that are worth setting anyway:

FlagWhy in CI
--dir <path>The default is ./chatfuel-app relative to where you started. A directory that exists and is not empty is refused outright.
--modules <ids>--yes skips opt-in modules, so auth and admin arrive only if you name them. An unknown id ends the run and lists the ready ones.
--workspace <id>Taken silently when the account owns exactly one. With several and the auth module, --yes refuses — which workspace pays is not a question to answer on somebody's behalf.
--agent <id>With both CLIs on PATH, --yes takes the first one it detected instead of asking. Name the one whose skills layout you want.
--app-name / --logoThe name otherwise falls back to the workspace's title; the mark otherwise stays the shipped one, because --yes never asks for a logo.

--embed is the only thing that chooses embed mode — --yes on its own stays standalone. The full table, including what each flag falls back to, is the CLI reference.

Some things --yes does without asking, worth knowing before you point it at a machine you care about: it adds .env to .gitignore, replaces an existing skill directory, installs no coding agent when none is present, and starts no dev server at the end.

Name the Supabase project up front

The auth module is the one module with a second system behind it, and under --yes it needs to be told which project — a token on its own does not say. There are exactly two accepted shapes:

SUPABASE_ACCESS_TOKEN (or --supabase-token) plus one of:

--supabase-project <ref>     # a project that already exists
--supabase-create <name>     # make one, or reuse the one already called that

--supabase-create reusing by name is what keeps a repeated pipeline from spending the account's other free project on a duplicate. Two projects with that name is an error naming both refs rather than a guess.

Add --supabase-org <slug> when the token sees more than one organization — under --yes that is otherwise a refusal that lists the slugs. --supabase-region defaults to the recommended one.

Neither shape present and the run stops before the scaffold writes anything, with a hint naming every flag that would have worked. A --yes run also never creates a project it was not explicitly told to create — that is a second, deliberate backstop behind the same rule.

Get the calls out of the network

Node's own fetch ignores HTTP_PROXY and HTTPS_PROXY unless the process was started with a flag nobody types, so the wizard reads them itself — https_proxy, HTTPS_PROXY, http_proxy, HTTP_PROXY, all_proxy, ALL_PROXY, honouring NO_PROXY, with loopback always exempt.

export HTTPS_PROXY=http://proxy.example:8080

What has to be reachable, and when:

HostFor
panel.chatfuel.comAlways.
registry.npmjs.orgInstalling anything.
api.supabase.comThe auth module's access-token path.
api.vercel.comDeploying.
api.github.comPushing to GitHub.

doctor prints the proxy it resolved on its own row, which is the cheapest way to find out that the variable is spelled differently than you think.

Rehearse with --dry-run

--dry-run stops account assets, not files. The app is still written to disk and its dependencies still installed; what it holds back are the calls that change something on an account — the Chatfuel trial checkout, the Supabase project creation, the database migrations and the auth-config patches. Each is printed as the call it would have made. A project it would have created does not exist, so there are no keys to read and .env carries empty Supabase values.

So a dry run tells you your flags parse, your tokens work, and your directory is writable, for the price of a scaffold you delete afterwards.

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. On an account that already has a workspace, nothing is created.

Run it, and check what came out

CHATFUEL_TOKEN="$CHATFUEL_TOKEN" \
SUPABASE_ACCESS_TOKEN="$SUPABASE_ACCESS_TOKEN" \
npx @chatfuel/wizard \
  --yes \
  --dir ./chatfuel-app \
  --modules auth,livechat,contacts,deals \
  --workspace 8f3c1d2e-4a5b-6c7d-8e9f-0a1b2c3d4e5f \
  --agent claude \
  --app-name "Acme Concierge" \
  --logo ./brand/acme.svg \
  --supabase-create acme-concierge \
  --app-url https://app.acme.com

A failed run exits 1 with the wizard's own sentence and its hint, so the pipeline step goes red on its own. A successful one leaves an app with its dependencies installed:

cd chatfuel-app
npm run check

tsc passing over the whole app is the check that means the registry, the modules and the vendored trees all agree. Then read .env: every variable the run resolved is in it, and it is the file the deployment's configuration is pushed from.

Two things will not be there, on purpose. No deployment, and no GitHub repository: both steps are interactive-only and skipped under --yes, without a TTY, and under --dry-run. A deployment is a public URL with your Chatfuel token behind it, and a repository under your account holds the source of an app wired to your bot; neither is something a flag should be able to cause. Both are ordinary commands afterwards — npm run deploy and gh repo create --source . --push.

Next: deploy for the step --yes would not take, or the CLI reference for every flag and its fallback.

On this page