Kwisple
Browse the docs

CLI

CLI reference

Every kwisple command and flag, how login and linking work, where credentials are stored, exit codes and the environment variables the CLI reads.

The kwisple CLI ships with @kwisple/sdk. It creates new site projects, signs you in to the dashboard, links a project to a site, keeps the content model in sync while you work, pushes it (also from CI) and moves content in and out as site kits. Its own messages are in Dutch.

Running it

The binary is kwisple, installed with @kwisple/sdk. Run it from the root of the site project (the folder with cms.config.ts and .env):

npx kwisple <command>     # npm, or any project with the SDK installed
pnpm kwisple <command>    # pnpm: the starters (and RANSON.N) have a "kwisple" script

The entry registers tsx, so cms.config.ts runs as TypeScript without a build step. Inside the platform monorepo the CLI runs straight from the SDK's TypeScript sources; an installed package runs its compiled dist/. kwisple, kwisple help, --help and -h print the overview. An unknown command prints it too, after an error.

All commands that fail print ✖ <reason> and exit with code 1. The one exception is kwisple push, which exits with 2 when destructive changes were blocked.

Commands

CommandWhat it doesNeeds
kwisple create [dir]New site from a starter (Astro or Next.js). Alias: kwisple init.Nothing.
kwisple loginSigns this machine in to a dashboard (device flow in the browser).An account.
kwisple logoutRevokes the CLI token on the platform and forgets it here.—
kwisple whoamiWho you are signed in as, on which dashboard.—
kwisple linkPicks agency → client → site and writes .env.Login.
kwisple devSyncs cms.config.ts to the development model and runs the dev server..env
kwisple pushApplies cms.config.ts to the live content model..env or CI variables
kwisple statusCompares the local model with the platform's..env or CI variables
kwisple seed [file]Writes a site kit into the linked site..env
kwisple export [file]Saves the linked site's live content as a site kit..env
kwisple ci-tokenCreates a site token for CI.Login + a linked project or --site

".env" means KWISPLE_URL and KWISPLE_TOKEN, from .env.local, .env or the process environment (see Environment variables). Without them these commands stop with KWISPLE_URL en KWISPLE_TOKEN ontbreken.

Options

OptionUsed byMeaning
--dashboard <url>login, logout, whoami, link, ci-tokenThe dashboard to talk to. A bare host gets https://.
--no-browserloginPrint the approval link instead of opening a browser.
--site <id|slug>link, ci-tokenThe site, without questions.
--client <slug> --name <name>linkCreate a custom-code site for that client first, then link it.
--preview-url <url>linkThe preview URL to set on the site when it has none yet.
--no-serverdevOnly follow the content model; do not start the dev server.
--livedevPush every change to the live model instead of the development model.
--forcepush, seedpush: apply destructive changes. seed: write into a site that already has content.
--dry-runpushShow what would change; apply nothing.
--config <path>dev, push, statusAnother config file than ./cms.config.ts.

Which dashboard

login, logout, whoami, link and ci-token talk to a dashboard. The CLI picks it in this order:

  1. --dashboard <url>;
  2. the environment variable KWISPLE_DASHBOARD_URL;
  3. KWISPLE_DASHBOARD_ORIGIN from the project's .env.local or .env;
  4. the dashboard of your last login;
  5. https://app.kwisple.com.

For the platform running locally, pass --dashboard http://localhost:4100 once at login; later commands follow the last login. Agencies with their own dashboard host log in there: the approval page then shows the agency's identity.

kwisple create

The same program as npm create kwisple-site. It asks what it needs, or takes it from flags:

FlagMeaning
--framework astro|next (-f, also --template/-t, or --astro / --next)The starter.
--pm pnpm|npm|yarn|bun (--package-manager)Package manager; default: the one you started it with.
--install / --no-installInstall dependencies right away or not.
--kit dienstverlener|horeca|geenStarting content (a site kit you later put online with kwisple seed).
--git / --no-gitCreate a git repository or not.
-y, --yesNo questions; defaults for whatever is missing.

See Quick start for the whole path from create to live content.

kwisple login

Signs this machine in with the device authorization flow: no token to copy, and the token is never printed.

  1. The CLI asks the dashboard for a code (POST /api/cli/device) and prints it: Je code: WDJB-MJHT. Codes are eight letters without vowels or look-alikes.
  2. It opens <dashboard>/cli?code=WDJB-MJHT in your browser. It does not open a browser with --no-browser, when CI or SSH_CONNECTION is set, or when the output is not a terminal; it prints the link instead.
  3. On that page (Terminal koppelen), signed in, you see Geef de CLI toegang? with the Code, the Toestel (device, for example MacBook-Robbe · macOS), Aangemeld als and Geldig tot. Check that the code matches your terminal, then click Toegang geven (give access) or Weigeren (refuse).
  4. The CLI polls every 5 seconds (5 seconds more after each slow_down) and, once approved, saves the token and prints ✔ Aangemeld als <name> (<email>) op <dashboard>.

A code is valid for 10 minutes; after that the page shows Code verlopen and the CLI stops with De code is verlopen. Voer kwisple login opnieuw uit. A refused code ends with Toegang geweigerd in de browser. The token is minted at the first poll after approval and can be collected only once. Starting logins is rate limited per address and globally.

The CLI token (kwicli_…) works with your rights: link sites, push content models and create tokens for the sites you may manage, never more. It shows under Koppelingen → Terminal in the dashboard, where you can revoke it. Requests are limited to 120 per minute per token.

Where credentials are stored

One token per dashboard, in credentials.json in the CLI's config folder, readable by you only (file mode 0600, folder 0700):

PlatformFolder
macOS, Linux$XDG_CONFIG_HOME/kwisple, else ~/.config/kwisple
Windows%APPDATA%\kwisple
AnyKWISPLE_CONFIG_DIR overrides the folder

The file remembers which dashboard you used last (current); that is the default for later commands.

kwisple logout and kwisple whoami

logout revokes the token on the platform and removes it locally: Afgemeld op . De sleutel is ingetrokken. If the token was already revoked, or the dashboard is unreachable, it is still forgotten locally (revoke it under Koppelingen if it may still be valid).

whoami prints your name, email, the dashboard and the token's name. It exits with 1 when you are not signed in, and also when the token was revoked in the dashboard (it then forgets it locally).

Connects the project in the current folder to a custom-code site and writes .env.

Interactively (arrow keys) it asks:

  1. Bureau (agency), only when you belong to more than one;
  2. Klant (client), listing only clients where you may link a site;
  3. Website: the client's custom-code sites, staging environments marked (staging), plus + Nieuwe website when you may create sites. A new site asks Naam van de nieuwe website, with a name derived from package.json.

Without questions: kwisple link --site <id|slug>, or kwisple link --client <slug> --name <name> to create the site first. Not in a terminal and no --site? It lists the clients and sites with the flags to use, and stops.

What linking does:

  • creates a site API token with the scopes read + preview + schema, named kwisple link · <machine> · <project>; linking the same project from the same machine again replaces it, other projects keep theirs;
  • creates the site's webhook secret if it has none yet;
  • sets the site's Preview-URL only when it has none, to --preview-url or http://localhost:<port>/api/preview (the port from your dev script, else 4321 for Astro and 3000 otherwise);
  • merges these keys into .env (other lines and comments stay; the file gets mode 0600):
KeyValue
KWISPLE_URLThe platform's delivery API.
KWISPLE_TOKENThe new site token.
KWISPLE_WEBHOOK_SECRETThe site's webhook secret.
KWISPLE_DASHBOARD_ORIGINThe dashboard you linked through (your agency's host when you used it).
KWISPLE_ASSET_ORIGINWhere uploaded files are served from.
KWISPLE_SITEThe site's id (used by kwisple ci-token).
  • adds .env to .gitignore (creating it if needed) unless it is already ignored;
  • warns when .env.local sets one of the same keys, because .env.local wins.

Linking needs the developer-settings right on that client and only works for custom-code sites (Deze website is niet op maat gebouwd. Enkel websites met eigen code kan je koppelen.). The variables are explained in Environment variables and tokens.

kwisple dev

Follows the content model while you work:

  • pushes cms.config.ts to the site's development model on start and on every change (✔ Ontwikkelmodel bijgewerkt … — live blijft op versie N); editors and clients keep the live model until you kwisple push;
  • watches the config's folder recursively for .ts, .mts, .js and .mjs files (so split configs under cms/ count), ignoring node_modules, .next, .astro, dist and anything under src/, with a 250 ms debounce;
  • starts the framework's dev server as <pm> run dev, the package manager detected from the lockfile (pnpm-lock.yaml, yarn.lock, bun.lock/bun.lockb, else npm), with KWISPLE_SCHEMA=dev so the SDK reads with the development model. No dev script, or --no-server: only the model is followed. A failing dev server ends kwisple dev.

A broken model prints the problems and keeps watching. --live pushes to the live model directly, as kwisple push would (without --force). Stop with Ctrl+C. The workflow is in Workflow: dev, push and changes.

kwisple push

Validates cms.config.ts locally (the same checks as the platform, apps and forms included), then sends it to the live model.

OutcomeOutputExit code
Applied✔ Versie N toegepast and the list of changes0
Nothing changed✔ Geen wijzigingen — platform staat op versie N.0
--dry-runℹ Deze wijzigingen zouden worden toegepast: and the changes0, or 2 when a change is destructive
Destructive changes, no --force! Niet toegepast: deze push bevat destructieve wijzigingen., the changes (destructive ones marked (destructief)) and Bevestig met kwisple push --force.2
Invalid model, wrong token, network error✖ <reason>1

Changes are listed as + added, − removed, ~ changed. A destructive change hides existing content (a removed field or section); content is never deleted and comes back when the field does. --force applies them anyway.

--dry-run exits 2 when a change would be destructive (! Destructieve wijzigingen: op main is kwisple push --force nodig.), so a pull request fails on what the push on main would refuse. --dry-run --force exits 0. Pushing needs a token with the schema scope, and only works for custom-code sites.

kwisple status

Prints the platform's model version and where it came from, then runs a dry-run push quietly: Lokaal model is gelijk aan het platform. or the changes a push would make. It needs the schema scope too, because the comparison is a dry run on the platform.

kwisple seed and kwisple export

npx kwisple export                 # live content → cms/seed.json
npx kwisple seed                   # cms/seed.json → the linked site, published
npx kwisple seed kits/demo.json --force

export saves the linked site's live content as a site kit. Images, files and links between pages are left out of a kit. seed writes a kit into the linked site, published; it refuses a site that already has content of its own unless --force, and lists what it could not place. Both default to cms/seed.json and need the schema scope. See Site kits: seed and export.

kwisple ci-token

Creates a site API token for CI with the scopes read + schema and prints it once, with the API address:

npx kwisple ci-token                   # print KWISPLE_URL and KWISPLE_TOKEN
npx kwisple ci-token --gh              # store them as GitHub Actions secrets with the gh CLI
npx kwisple ci-token --site acme-site  # another site than the linked one

The site comes from --site, else KWISPLE_SITE (written by kwisple link). --gh runs gh secret set KWISPLE_URL and gh secret set KWISPLE_TOKEN for the current repository, passing values over stdin; if that fails it prints the values instead. The token is named CI (GitHub Actions); creating a new one revokes the previous CI token you made for that site. Details in CI and automation.

Environment variables

VariableRead byMeaning
KWISPLE_URL, KWISPLE_TOKENdev, push, status, seed, exportDelivery API and site token. Read from .env.local, then .env, in the current folder; variables already set in the environment win (CI).
KWISPLE_DASHBOARD_URLdashboard commandsDashboard to use (step 2 above).
KWISPLE_DASHBOARD_ORIGINdashboard commandsRead from the project's .env.local / .env only (step 3 above).
KWISPLE_SITEci-tokenThe linked site, from .env.local / .env or the environment.
KWISPLE_CONFIG_DIR, XDG_CONFIG_HOME, APPDATAcredentialsWhere credentials.json lives.
CI, SSH_CONNECTIONloginWhen set, no browser is opened.

kwisple dev sets KWISPLE_SCHEMA=dev for the dev server it starts. Never set it in production. All variables of a site project are listed in Environment variables and tokens.

Last updated 2026-10-30