Every command, flag, and example

CLI reference

One static binary drives your whole stack — deploys, environments and secrets, databases, and copy-on-write branches. The grammar is usually flicker <noun> <verb> [name] (a few verbs like deploy are top-level); branch ensure and deploy are idempotent, and every command exits non-zero on failure, so a pipeline never leaks a preview database or hides a broken step.

This page mirrors the CLI's own help — run flicker help <topic> or flicker <noun> <verb> --help for the same content in your terminal. New here? Walk through Getting started first.

Getting started

flicker quickstart

from zero to a deployed app and a forked DB in five commands

Get a working setup end-to-end. You need a Flicker API token (mint one in the web UI under Settings → API Keys) and a database to act on: authenticate the CLI, point at a database, fork a branch, deploy, and tear the branch down.

$ flicker auth login flk_xxx
# org resolved from the key; stored in ~/.config/flicker/config.toml
$ flicker database set my-app
# write database = "my-app" to ./flicker.toml
$ flicker branch create pr-1234 --ttl 2h --label pr=1234
# ephemeral CI fork
$ flicker deploy --from-local
# tar cwd + build on Flicker + rolling, health-gated deploy
$ flicker branch delete pr-1234 -y
# or let the TTL reaper handle it

flicker auth

authenticate the CLI with API keys

flicker auth <login|list> [key]

Keys are the unit of identity. `auth login <key>` asks the server which organization the key belongs to — you never type an org slug — then stores the key under that org in the global config (~/.config/flicker/config.toml, 0600) and makes it current. Mint a key in the web UI under your org's Settings → API Keys; the plaintext is shown once. In CI, set FLICKER_TOKEN instead — it takes priority over stored keys.

$ flicker auth login flk_live_abc123
# org resolved from the key, stored, made current
$ flicker auth list
# stored keys + the org each maps to
$ FLICKER_TOKEN=flk_live_abc123 flicker database list
# one-off override (CI)

flicker context

how flicker resolves which org and database a command acts on

Every command needs to know which org and database it acts on. Org is auth-centric — `auth login <key>` resolves it from the key. Resolution order (earlier wins): --org flag, ./flicker.toml, FLICKER_ORG, then the current org in the global config. Database is named per call or set as a default with the same precedence. Commit flicker.toml so the whole team and CI share one context without remembering flags.

$ flicker auth login flk_live_abc123
# org inherited from the key
$ flicker database set my-app
# writes database = "my-app" to ./flicker.toml
$ flicker org set acme --local
# per-directory org override in ./flicker.toml
$ flicker --database other branch list
# one-off override
$ FLICKER_DATABASE=other flicker branch list
# env-var override (CI)

Projects

flicker project

the umbrella that owns your databases + apps

flicker project <list|create|show|use|delete|restore|merge> [name|slug]

A project is the container that owns Databases + Apps + environments + secrets — it is NOT a Postgres instance (that's `database`). Put an app and its database in the SAME project and Flicker auto-wires DATABASE_URL (the branch's internal connection string) at deploy — never hand-set it. Every project has a `main` environment (its root, ≈ production); other envs branch from it. `project use` sets the default project in ./flicker.toml so `database create` and `app create` land in it without --project. `project delete` is a SOFT delete: an empty project (no apps, no databases) is marked archived and drops out of `project list`, but its row, environments and scoped secrets are kept — find them with `project list --archived` and bring one back with `project restore`.

Flag Description
--archived list archived (soft-deleted) projects instead of live ones
--yes confirm `project delete`
$ flicker project create my-app
# create the umbrella (name only; mints its main env)
$ flicker project list
# all projects in the current org
$ flicker project show my-app
# its databases, apps, and environments
$ flicker project use my-app
# set as default in ./flicker.toml
$ flicker project delete my-app --yes
# archive an empty project
$ flicker project list --archived
# the archived ones
$ flicker project restore my-app
# bring an archived project back

Tickets & memory

flicker ticket

manage Flicker Tickets from the terminal

flicker ticket <list|tree|show|stats|create|tag|close|checkout|pull|push|select-for-dev|start|complete|reopen|defer|gate|document> ...

Tickets are Flicker's work units. They belong to a project, can nest under a parent, move through a fixed workflow (backlog → selected_for_dev → in_progress → done), and carry versioned markdown documents. Inspect them with `list`, `tree`, and `show`; add work with `create` (`--parent` makes it a child of another ticket). Move a ticket with named transitions rather than setting a status directly: `select-for-dev`, `start`, and `complete` move it forward; `reopen` sends a done ticket back to the backlog to pick up again; `defer` parks an active ticket back in the backlog. `document` writes and reads a ticket's markdown documents by kind, and `checkout` / `pull` / `push` sync those documents to and from local files so an agent can edit them in the working tree.

Flag Description
--project <slug> project to operate on when omitted positionally
--parent <id> create a child ticket under a parent ticket
--body <text> ticket body or document body
--title <text> document title
--history with document read: show every version
--out <dir> with checkout/pull: output directory (default flicker-tickets)
--force with checkout/pull: replace existing local ticket markdown files
--json machine-readable output for skills
$ flicker ticket list my-project
# board-order ticket list
$ flicker ticket tree --project my-project
# recursive execution tree
$ flicker ticket create "Implement checkout" --project my-project --body "Acceptance notes"
# create work
$ flicker ticket create "Write tests" --project my-project --parent 42
# create child work
$ flicker ticket checkout my-project --out .flicker/tickets
# write local markdown files with lock_version metadata
$ flicker ticket push .flicker/tickets/000042-implement-checkout.md
# push markdown edits with optimistic concurrency
$ flicker ticket select-for-dev 42
# backlog → selected_for_dev
$ flicker ticket start 42
# selected_for_dev → in_progress
$ flicker ticket complete 42
# in_progress → done
$ flicker ticket reopen 42
# done → backlog (pick a finished ticket back up)
$ flicker ticket defer 42
# park an active ticket back in the backlog
$ flicker ticket document write 42 task_contract --body "$(cat plan.md)"
# write a versioned document
$ flicker ticket document read 42 task_contract --history
# read document history

flicker memory

add and search project memory

flicker memory <add|search> ...

Memory is searchable evidence for agents and humans. Search is project-scoped by default (when a project context exists) and can span every project in the org with --all-projects. V1 uses Postgres full-text search only; search returns labels such as current_ticket, current_document, historical_event, and superseded_event. Cross-project hits include project_id and project_slug.

Flag Description
--project <slug> project to operate on when omitted positionally
--all-projects search every project in the org (memory search only)
--title <text> title for memory add
--body <text> body for memory add
--json machine-readable output for skills
$ flicker memory search "regression evidence" --project my-project
# search tickets, documents, and events
$ flicker memory search "cross-project decision" --all-projects
# search every project in the org
$ flicker memory add "Release was held for QA" --project my-project --title "Release note"
# append a project memory note
$ flicker memory search "task contract" --json
# JSON output for skills

Databases & branches

flicker database

manage your databases

flicker database <create|list|set|delete|import|disk|resize> [name]

A database is an isolated Postgres environment — its own instance, with a main branch and any number of forks. Provisioning is async (~1–5s on a warm host); the CLI blocks until active by default. `database import` loads an existing database into main from a connection URL (pg_dump | pg_restore, run on Flicker) — create an empty database first, then import into it.

Flag Description
--no-wait return immediately with status = pending instead of polling
$ flicker database create my-app
# provision, wait until active
$ flicker database list
# all databases in the current org
$ flicker database set my-app
# set as default in ./flicker.toml
$ flicker database import postgresql://user:pw@host/db --database my-app
# import an external database

flicker branch

fork, reset, and tear down database branches

flicker branch <create|list|reset|delete|ensure|destroy> [name] [flags]

Branches are copy-on-write Postgres clones of a parent (typically main) that come up in seconds and share storage until they diverge. The killer use case is per-PR test databases. `--from` clones any branch, including a non-main branch (nested forks). Branching is OPT-IN (branch-rules v2): `branch create` defaults to an EMPTY rule — nothing forks or deploys, but secrets still inherit so `flicker secrets pull` yields a working DATABASE_URL. Opt entities IN with `--copy <entity>[:method]` (repeatable), where entity is `db` (the branch's own database) or an app slug, and method overrides the type default — db: clone (default) | empty; app: fork (default) | fork+copy-files | fork+empty-files | shared. `--copy-all` opts in the project's full composition (db + every app). `branch create` with no `--copy` on a terminal shows an interactive picker (entities + methods); piped/CI input falls through to the empty default. `branch create` is idempotent on the name. `branch reset` re-forks from the parent (discards changes) and re-stamps a fresh app password so the connection string keeps working; `branch delete` removes it permanently. Protected branches (main by default) cannot be deleted or reset. `branch ensure` / `branch destroy` provision or tear down a git-bound preview in one idempotent call — `--base` is the git base to diff, `--from` is the data fork-parent. By default `ensure` INHERITS the parent env's rule (a preview off main gets main's full composition); `--copy` / `--copy-all` OVERRIDE it, but only when ensure first creates the env — an existing env keeps its persisted rule, so CI never undoes a local override.

Flag Description
--from <branch> branch to clone (default: the database's default branch); any branch, incl. nested forks
--ref <ref> git ref for ensure/destroy (e.g. feat/x); main = prod deploy
--base <ref> git base ref to diff against (ensure; default: main)
--sha <sha> exact commit to pin on ensure
--ttl <dur> auto-expire after duration, e.g. 2h, 30m, 1d — reaped server-side
--label k=v metadata tag, repeatable (e.g. --label pr=1234)
--copy <entity>[:method] opt an entity INTO the branch, repeatable (db[:clone|empty], <app>[:fork|fork+copy-files|fork+empty-files|shared]); create defaults to empty, TTY prompts if omitted
--copy-all opt in the project's full composition (db + every app at type defaults)
--idempotency-key <k> safe-retry key (defaults to the branch name)
--no-wait return immediately with status = creating
$ flicker branch create dev
# empty rule — secrets only (nothing forks; TTY shows a picker)
$ flicker branch create dev --copy db
# fork only the database
$ flicker branch create dev --copy db --copy web:shared
# fork the DB; reference web without forking it
$ flicker branch create dev --copy-all
# full composition (db + every app)
$ flicker branch create pr-1234 --copy-all --from main --ttl 2h --label pr=1234
# ephemeral CI fork of the full stack
$ flicker branch list
# show all branches + connection strings
$ flicker branch reset dev
# re-fork from main + fresh app password (destroys changes in dev)
$ flicker branch delete dev -y
# permanent delete, skip confirmation
$ flicker branch ensure --ref feat/x --base main --ttl 48h --label pr=42
# PR preview env, inheriting main's rule (CI)
$ flicker branch ensure --ref feat/x --copy db
# override inherited rule: fork only the DB
$ flicker branch destroy --ref feat/x
# tear down on PR merge/close (CI)

flicker ext

enable/disable PostgreSQL extensions

flicker ext <list|enable|disable> [name]

Extensions are baked into the Flicker Postgres image, so enabling one is just a CREATE EXTENSION away — no rebuild. The setting lives on the database and applies to every branch automatically: new branches get it on clone, existing branches are reconciled by a background job. Only runtime extensions (no container restart) are exposed.

$ flicker ext list
# catalog + enabled state for the current database
$ flicker ext enable vector
# turn on pgvector across all branches
$ flicker ext disable hstore
# remove an extension from all branches

flicker preview

opt-in per-ticket preview environments

flicker preview <ensure|down> --ref <ref> [flags]

Give a ticket or PR a live, prod-shaped environment: a copy-on-write database fork plus (for source-bound apps) forked app deploys, provisioned in seconds and TTL-reaped like any git-bound branch. `preview ensure` provisions or redeploys the environment for a ref (idempotent per ref); `preview down` tears it down. Both are thin wrappers over the same machinery as `branch ensure` / `branch destroy`. Previews are OPT-IN per repo and DEFAULT OFF — they cost real compute, so nothing is provisioned implicitly. Enable them by committing `preview_envs = true` to the repo's ./flicker.toml; without the opt-in, both verbs refuse with an explanation.

Flag Description
--ref <ref> git ref for the preview (e.g. pr-42); required
--ttl <dur> auto-expire after a duration, e.g. 48h — reaped server-side
--label k=v metadata tag, repeatable (e.g. --label pr=42)
$ flicker preview ensure --ref pr-42 --ttl 48h --label pr=42
# provision (or redeploy) the PR's preview environment
$ flicker preview down --ref pr-42
# tear down the forked resources on merge/close

Apps & deploy

flicker app

manage hosted web apps (containers)

flicker app <scaffold|create|update|list|deploy|attach-db|logs|builds|build-logs|exec|delete> [name] [flags]

An app is a container image running on Flicker, optionally reachable at a domain over HTTPS (the platform terminates TLS and routes traffic to it). Source builds and prebuilt images are both supported. Use `flicker deploy` for normal deploys — the verbs here are for explicit app management. App and database lists show observed HEALTH and CHECKED separately from LIFECYCLE. New HTTP apps with an explicit port default to TCP readiness; legacy apps stay unenrolled. Use `--readiness http` with an explicit path for HTTP readiness. Probe changes take effect on the next deploy. Flicker does not add an automatic liveness probe. Note the two log verbs are different: `app logs` is the RUNNING app's container output, while `app build-logs` is the BuildKit output from the build that produced its image. Build secrets are redacted from a build log before it is stored.

Flag Description
--image <ref> registry image, e.g. myorg/web:v2 (alternative to --build)
--port <N> container's listening port (default 8080; explicit HTTP app ports default to TCP readiness)
--readiness <mode> disabled, tcp, or http; persists now and takes effect on next deploy
--readiness-path <path> absolute HTTP readiness path; required with --readiness http
--domain <host> domain to route over HTTPS w/ TLS (e.g. web.flicker.dev)
--env k=v environment variable, repeatable (stored encrypted at rest)
--build-secret KEY=VALUE secret for build time only, repeatable (Fly parity, e.g. FLUXON_LICENSE_KEY)
--release-command <cmd> run once before cutover, e.g. /app/bin/migrate
$ flicker app scaffold web
# scaffold an [app] table in flicker.toml
$ flicker app create web --image traefik/whoami --port 80
# explicit port defaults this HTTP app to TCP readiness
$ flicker app create web --image myorg/web --port 4000 --readiness http --readiness-path /health
# explicit HTTP readiness
$ flicker app update web --readiness disabled
# disable readiness on the next deploy
$ flicker app list
$ flicker app deploy web --image myorg/web:v3
# re-deploy with a new image
$ flicker app logs web
# tail the running app's container logs
$ flicker app builds web
# list recent builds with status + duration
$ flicker app build-logs web
# the latest build's captured BuildKit output
$ flicker app delete web -y

flicker deploy

deploy the [app] in flicker.toml — manifest-driven or local-source

flicker deploy [--from-local]

Two deploy modes, one command. Manifest mode (`flicker deploy`) reads [app] (+ optional [build], [config]) from ./flicker.toml and deploys exactly what's pinned — a registry image, or a git repo + ref the platform builds for you. Reproducible and reviewable in a PR — the right primary for CI. Local mode (`flicker deploy --from-local`) tars the working dir, POSTs it to the app's /push endpoint, and the platform builds the image for you (BuildKit), including uncommitted changes. Pass `--build-secret KEY=VALUE` (repeatable) to expose a secret to the build only (Fly parity, e.g. FLUXON_LICENSE_KEY) — it reaches BuildKit as a --secret mount and never lands in the runtime image. Both modes converge on the same rolling cutover; the new version takes traffic only once it's up, so a failed release leaves the old version serving.

Flag Description
--from-local tar cwd, upload, build on Flicker (dev mode)
--image <ref> override the manifest's image (manifest mode only)
--build-secret KEY=VALUE build-time-only secret, repeatable (Fly parity, e.g. FLUXON_LICENSE_KEY)
--no-wait return immediately instead of polling to running
--release-command <cmd> run once before cutover, e.g. /app/bin/migrate
$ flicker deploy
# manifest mode — pin image or [build] repo in flicker.toml
$ flicker deploy --from-local
# tar cwd, build on Flicker, deploy
$ flicker deploy --from-local --build-secret FLUXON_LICENSE_KEY=...
# expose a build-only secret
$ flicker deploy --image myorg/web:v3
# manifest mode w/ image override (CI on a SHA)

flicker manifest

flicker.toml — context + the [app] / [build] / [config] tables

Per-repo config file. Holds context (top-level `org` / `database`) and the app spec — [app] plus an optional [build] table for source builds (repo/ref/dockerfile/context) and a [config] manifest ($ref-ing the per-environment secret pool). flicker.toml is meant to be committed: edit it, `flicker deploy`, done.

$ flicker app scaffold web
# scaffold the [app] table
$ flicker database set my-app
# write the database context
$ flicker org set acme --local
# optional per-directory org override

flicker mail

manage sending domains and wire an app to managed transactional email

flicker mail <domains list|domains add <domain>|domains verify <domain>|enable|disable|status> [--app <app>]

Two halves: sending DOMAINS (org-wide) and an app's mail WIRING. `mail domains add <domain>` registers a sending domain and prints the DKIM / SPF / DMARC records to publish; `mail domains verify <domain>` runs a live DNS check; `mail domains list` shows each domain's verification state. `mail enable --app <app>` wires the app to Flicker's managed mail credential (a `:mail` edge, mirroring how DATABASE_URL works) — the credential is minted server-side and injected as `FLICKER_MAIL_API_KEY` at deploy, and the CLI never prints it, so redeploy to pick it up. `mail disable --app <app>` removes the edge and revokes the credential. `mail status --app <app>` shows whether the edge is present, whether the from-domain is verified, and the last send time.

Flag Description
--app <app> with enable / disable / status: the target app (slug or name)
$ flicker mail domains add mail.acme.com
# register a sending domain; prints the DNS records
$ flicker mail domains verify mail.acme.com
# live DNS check of DKIM/SPF/DMARC
$ flicker mail enable --app web
# wire the app to managed mail (redeploy to apply)
$ flicker mail status --app web
# edge present? domain verified? last send?

Environments & secrets

flicker env

manage named environments and sync their secrets to .env files

flicker env <list|create|delete|policy|pull|diff> [name] [flags]

Environments are named configs (production, preview/pr-42, dev/giovanni) holding governed secrets. Apps bind to one; deploys resolve it. `env pull` downloads the environment's fully resolved snapshot (inheritance flattened, restricted keys excluded) into a local .env — by default your personal config dev/<user>, auto-created on first pull. Pulled files carry a provenance header; a .env without it is presumed hand-maintained and pull refuses to overwrite it unless --force. Values are never printed to stdout. `env diff` prints key-level status (added/removed/changed) — names only, never values. Env names are unique PER PROJECT, so `main`/`dev`/`staging` name one environment in each project: `env delete` and `env policy` scope to the current project (flicker.toml `project` or --project) and the server refuses with a 409 rather than guessing when a bare name matches several projects.

Flag Description
--environment <name> target a specific environment instead of personal dev/<user>
--project <slug> which project's environment to act on (delete/policy)
--out <path> the local .env path (default ./.env)
--force overwrite a .env that lacks the flicker provenance header
$ flicker env pull
# personal config dev/<user> → ./.env (created on first pull)
$ flicker env pull --environment production --out .env.prod
# explicit env + path
$ flicker env diff
# what would change locally if you pulled now
$ flicker env list
# all environments in the org
$ flicker env create preview/pr-42
$ flicker env delete preview/pr-42 -y

flicker secrets

set, unset, list, and read individual secrets in an environment

flicker secrets <set|unset|promote|list|get|pull|diff> [KEY[=VALUE] ...] [flags]

Operates on one environment's secrets — by default your personal config dev/<user>, or pass --environment <name>. `set` upserts KEY=VALUE pairs and `unset` deletes keys; each command is one versioned change (one bundle, at most one redeploy of bound apps). Values are never echoed back. `list` shows names + metadata (visibility, version, updated time) — always allowed. `get` is the one deliberate value read: governed (only the org-wide key or an environment-scoped key bound to this exact environment may read), and access-logged. Restricted secrets never return a value to anyone.

Flag Description
--environment <name> target environment (default: personal dev/<user>)
--plain with get: print the bare value only (for scripting)
$ flicker secrets set STRIPE_KEY=sk_test_123 --environment production
$ flicker secrets unset OLD_FLAG --environment production
$ flicker secrets list --environment production
# names + metadata, never values
$ flicker secrets get DATABASE_URL --plain
# governed value read (access-logged)

Config

flicker org

select which connected organization commands act as

flicker org <list|set|unset|current|remove> [slug]

An organization is the tenant boundary — databases, branches, apps, and API keys all belong to one. Connecting an org is `auth login <key>` (the org is inherited from the key); the org verbs only SELECT among the orgs you're already authenticated to. `--local` writes a per-directory override into ./flicker.toml. Orgs are created in the web UI, not via the CLI.

Flag Description
--local with set/unset: act on the ./flicker.toml override, not the global current org
$ flicker org list
$ flicker org set acme
# switch the global current org
$ flicker org set acme --local
# pin this directory to acme via flicker.toml
$ flicker org current
$ flicker org remove acme
# forget acme's key on this machine

flicker current

show the fully-resolved context for this invocation

flicker current

Prints every selectable axis at once — org, database, environment, API base, and key status. With a stored token it also asks the server which org and key scope the token resolves to: organization (org-wide), app (single-app deploy token), or environment (environment-read-scoped secrets token). An unreachable server degrades to the local view instead of failing.

$ flicker current
$ flicker current --json
# machine-readable, incl. whoami when reachable

flicker skill

install the portable Flicker agent skill into your AI harness

flicker skill <print|install|update> [--workflow] [--agent cc|codex|pi] [--all] [--global] [--json]

Ships the operating knowledge an agent needs to drive Flicker correctly — the project/app/database model, the wiring rules, and the common footguns — into whatever AI coding harness you run. The skill body is embedded in the CLI binary, so it works with no repo and no network. `skill print` writes it to stdout. `skill install` places it where a harness reads it; with no `--agent` it auto-detects, and `--all` installs to every harness. Re-running is idempotent. `skill update` reinstalls the embedded bundle at user scope (never in the background). Pass `--workflow` for the Tickets lifecycle bundle (shared contract + plan/implement/test/release/ship/recall). Layout: Pi and Claude Code get real skill dirs under `.pi` / `.claude`; Codex gets a short managed pointer block in `AGENTS.md` plus the full contract at `.flicker-agent/shared/flicker-workflow.md` — the full bundle is never inlined into `AGENTS.md`, and content outside the managed markers is preserved. After install/update run `flicker doctor` and restart the harness.

Flag Description
--workflow install the workflow stage skills instead of the platform skill
--agent cc|codex|pi target a specific harness (default: auto-detect)
--all install to every known harness
--global install at user scope (~/.claude, ~/.pi/agent, ~/AGENTS.md) instead of the repo
--json machine-readable output
$ flicker skill install
# auto-detect harnesses and install the platform skill
$ flicker skill install --workflow --global
# install the plan→ship workflow skills globally
$ flicker skill update --workflow --global
# refresh all harness installs from this CLI embed
$ flicker skill print
# write the skill to stdout

Global flags

Accepted by every command:

Flag Description
--org <slug> override default org (else flicker.toml > FLICKER_ORG > global config)
--project <slug> target an existing project (for app/database create)
--database <slug> override default database
--token <key> override API token
--api <url> override API base URL
--json machine-readable JSON output
--no-wait return immediately instead of polling to ready/running
--yes, -y skip confirmation prompts