Reference
kawa flow is the command group that runs the SDLC from a promotion repository: a Git repository holding the definition of your workspaces as files. One branch per environment, one file per entity. You describe the environments once in kawa-flow.yml, keep the API keys in a git-ignored .env, and every verb below reads those two files to know where to connect.
Nothing is implicit. A verb either does exactly what its name says or refuses with a reason — it never switches branches, never commits on your behalf, and never deploys a tree that differs from what is checked out.
Install
The CLI ships as a Python package (Python 3.11 or newer) and needs git on the path:
pip install kawa-dsl
kawa flow --helpThe promotion repository
mifid-flow/
├── kawa-flow.yml # the environments — committed
├── .env # the API keys — git-ignored, never committed
├── .gitignore # .env and .kawa/
├── dsl/ # one TOML file per entity (datasources, sheets, views, workflows, …)
├── scripts/ # Python / SQL sources
├── files/ # file-datasource blobs
├── artifacts/ # artifact versions
├── skills/ # skill bundles
└── data/ # editable-datasource rowsEach environment owns a Git branch. The tree on a branch is the definition of that environment's workspace: develop holds what runs in the dev workspace, master what runs in production. The tree carries no credentials and no server ids — entities are addressed by their immutable tags — so the same commit deploys unchanged to any environment.
Two modes, detected by the doctor: remote when the repository has an origin (branches are compared with it before a deploy), local when it has none (everything stays in this repository).
Commands
kawa flow init
Bootstraps the repository: git init, kawa-flow.yml from a template, .env placeholder, .gitignore, first commit, one branch per environment
kawa flow doctor
Preflight: is everything in place for the other verbs to work? Exit code 0 when every check passes
kawa flow seed
Downloads the build workspace into the tree — once, on an empty build branch
kawa flow pull
Re-exports the workspace behind the checked-out branch over the tree; nothing with Git
kawa flow deploy
Pushes the checked-out environment branch onto its workspace: plan, confirmation, apply
Every verb runs from the promotion repository (any directory inside it). --work-dir <path> points it elsewhere, before or after the verb:
A typical first run, from an existing dev workspace to production:
kawa flow init
--template
dev-prod
dev-prod: dev → prod on develop → master. dev: a single dev environment
--name
the directory name
The flow name; it prefixes the workspaces the flow creates
--url
https://try.kawa.ai
The KAWA server of every environment (edit the file for one server per environment)
--dev-workspace
1
The dev workspace id on that server
--prod-workspace
2
The production workspace id on that server
It refuses to run when a kawa-flow.yml already exists, keeps an existing .env, and commits only its own two files:
kawa flow doctor
Read-only. It checks, in order: the Git repository; the mode (remote or local); kawa-flow.yml (every problem is listed, not just the first); one branch per environment; every URL answers GET /health as a KAWA instance (--timeout, default 5 seconds each); .env holds every key variable in use; the tree is seeded; every override fits its target. Exit code 1 when any check fails, and the last line counts the problems:
kawa flow seed
Starts the build branch from the build environment's live workspace: the workspace is exported — dsl/, scripts/, files/, artifacts/, skills/, data/ — over the tree, and the verb stops there. You review the result and commit it yourself.
It runs once. It refuses when the build branch already holds a tree (on the branch tip, or on disk), and when the build branch is not the one checked out — seed never switches branches.
kawa flow pull
The checked-out branch says which workspace: an environment's branch pulls that environment's workspace (develop → dev, master → prod, per kawa-flow.yml). The workspace is exported over the tree, each root replaced whole. That is all — pull does nothing with Git: no check, no commit, no checkout. git diff shows what changed on the server since the last commit.
kawa flow deploy
Takes no argument: the checked-out branch says which environment receives the tree (master → prod). The checkout is the deployment, so it is refused when:
the branch is not an environment's branch;
the working tree has uncommitted changes — deploy pushes the committed tree only;
in remote mode, the branch is behind or ahead of
origin— what deploys is what was merged;the tree holds no entities.
Then the environment's overrides are applied (see overrides below), the plan is computed against the live workspace and shown, and you confirm it. --yes skips the question. A declined plan deploys nothing. Files and data travel with the definition.
Exit code 0 when the plan was applied, 1 otherwise.
kawa-flow.yml
The environment registry, at the root of the promotion repository and committed with it. The environments form a tree rooted at the build environment: every other environment names the one it descends from.
Keys
Top level:
name
yes
The flow name. It prefixes the workspaces the flow creates
environments
yes
The list of environments, one mapping each
Per environment:
name
yes
Unique. Letters, digits, ., _, -
url
yes
The KAWA server, http(s)://…, no trailing slash
workspace
yes
The numeric workspace id on that server
branch
yes
Unique. The Git branch this environment deploys — flat, no slash (a slash marks a feature branch)
build
no
true on exactly one environment: the root of the tree, the one kawa flow seed exports. Defaults to false
predecessor
all but the build one
The environment this one descends from. One predecessor each, any number of successors
api_key
no
The name of the .env variable holding this environment's key. Defaults to KAWA_API_KEY. Never the key itself
overrides
no
What a datasource of the tree is on this environment — see below
Rules
kawa flow doctor reports every violation at once:
the file is a mapping with a non-empty
nameand a list of environment mappings, and nothing else;names and branches are unique across environments;
exactly one environment has
build: true, and it has nopredecessor;every other environment names a
predecessorthat exists in the file; no cycle, no isolated environment — everything descends from the build one;api_keyis an uppercase variable name (KAWA_PROD_API_KEY), never a value starting withkawa-.
Overrides
An override says that a datasource of the tree is a live connect on that environment. Nothing else travels — in particular, no query: the tree never sees the real one.
Three cases at deploy time, all explicit:
The target…
kawa flow deploy
does not hold that tag in the tree
Refuses, before connecting. The doctor names it too
lacks the datasource
Creates it as a live connect from a placeholder query reproducing the tree's columns, the datasource tag and every column tag imposed. Someone then puts the real query in, on the target, outside the DSL
already holds it
Checks containment: every column of the tree, by tag, with a compatible type. Compatible → left exactly as it is, data untouched. Not compatible → refused, naming the columns
The datasource is then left as the target holds it; the rest of the tree deploys around it.
.env
The keys live in a .env file at the root of the promotion repository. kawa flow init creates the placeholder and git-ignores it; it is never committed, and kawa-flow.yml only ever names its variables.
KAWA_API_KEYis the default for every environment that names noapi_key.Every variable an environment names must be present, with a value starting with
kawa-. The doctor lists each one it expects and which environments use it:
Last updated
Was this helpful?

