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
sign the CLI in, as a person or as a machine
`flicker auth login` with NO arguments signs you in through a browser — device authorization (RFC 8628), the same flow as `gh auth login`. It prints a one-time code, opens the verification page, and waits while you approve the request; what it stores is a USER token covering EVERY organization you belong to, so the organization becomes CONTEXT you pick with `org set <slug>` rather than a property of the credential. It still works with no browser: over SSH, in a container, or with --no-browser, the URL and code are printed for entry on any other machine and the CLI polls exactly the same. There are TWO deliberate kinds of credential. A USER token (`auth login`) is for humans at a terminal and is valid only for /whoami and the agent-config routes — it cannot deploy, read a secret, or touch a database. A MACHINE key (`auth login <key>`, an ORG API KEY `flk_` minted under your org's Settings → API Keys) acts as the ORGANIZATION, is long-lived and scopable, and is what CI uses; it is unchanged — the org is resolved from the key, the key is stored under that org in ~/.config/flicker/config.toml (0600), and that org becomes current. In CI set FLICKER_TOKEN instead of running login; it takes priority over stored keys. `auth logout` forgets the browser login on this machine only — it does not touch org API keys (use `org remove <slug>`) and does not revoke anything server-side; revoke a lost machine under Account Settings → CLI access, which kills it without rotating any other credential. `auth user <token>` is the older single-organization personal token (`flk_usr_`, minted under Account Settings → CLI access); it still works and is the answer for a machine that cannot reach a browser at all. FLICKER_USER_TOKEN is the CI form of either — an org key is never used in its place. `auth list` shows whether this machine holds a browser login, plus every org it holds a key for.
$ flicker auth login # browser sign-in; covers every org you belong to $ flicker auth login --no-browser # print the URL + code instead of launching a browser $ flicker auth login flk_live_abc123 # machine key: org resolved from the key, stored, made current $ flicker auth logout # forget the browser login on this machine $ flicker auth list # what this machine is signed in as $ 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
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
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` atomically transfers one or more tickets to another project in the same organization, carries documents and event history, and detaches parent links that would cross project scope. Move workflow state 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 backlog; `defer` parks active work. `document` reads and writes markdown documents by kind, and `checkout` / `pull` / `push` sync them to local files.
| Flag | Description |
|---|---|
--project <slug> |
project to operate on when omitted positionally |
--parent <id> |
create a child ticket under a parent ticket |
--to-project <slug|id> |
with move: destination project in the same organization |
--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 move 42 43 --to-project new-project # move tickets atomically and detach cross-project parent links $ 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
write, search, and traverse project memory
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. Ranking is Postgres full-text search; there are no embedding claims. Every result carries a temporal state: current when nothing supersedes it, historical when something does (the replacement is shown), and unknown when it was superseded but the replacement cannot be read. Superseded results are shown and labeled rather than hidden, because "what did we decide" often has an answer that was later replaced; pass --current-only to drop them. --as-of answers as of a past instant. This is valid time with provenance, not a bitemporal store. expand walks the citation graph one or two hops from a node and prints each neighbour with the direction of the edge that reached it. write records a deliberate note, anchored to --ticket or to the project's memory journal.
| Flag | Description |
|---|---|
--project <slug> |
project to operate on when omitted positionally |
--all-projects |
search every project in the org (memory search only) |
--current-only |
drop superseded results (they are shown and labeled by default) |
--as-of <iso8601> |
answer as of a past instant |
--depth <n> |
hops to walk with memory expand (capped at 2) |
--ticket <id> |
anchor a memory write to a ticket |
--title <text> |
title for memory write or add |
--body <text> |
body for memory write or 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 search "retry policy" --current-only # hide superseded results $ flicker memory write "Session pooler pins a backend per connection" --ticket 1274 # record a durable learning $ flicker memory expand ticket 1274 --depth 2 # walk the citation graph around a ticket $ flicker memory search "task contract" --json # JSON output for skills
Databases & branches
flicker database
manage your databases
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
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
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
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)
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
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
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?
flicker suggestions
wire an app to a project's suggestion inbox
Let an app submit its users' bug reports and feature requests to a project without anyone handling a bearer token. `suggestions enable --app <app>` creates a `:suggestions` edge from the app to a project — the same managed-dependency shape as DATABASE_URL and mail. Flicker mints a credential scoped to THAT ONE PROJECT's suggestion routes, stores it server-side, and injects it as `FLICKER_API_KEY` plus `FLICKER_SUGGESTIONS_PROJECT_ID` at deploy time, so redeploy to pick them up. `--project` targets a project other than the app's own. `suggestions disable --app <app>` removes the edge and revokes the credential after a short grace window, so an in-flight deploy keeps working. `suggestions status --app <app>` shows whether the edge is present, which project receives the reports, and when that project last received one. There is no key-minting command by design: the injected key cannot reach any other project or any other resource.
| Flag | Description |
|---|---|
--app <app> |
the target app (slug or name); required |
--project <project> |
project that receives the suggestions (default: the app's own project) |
$ flicker suggestions enable --app enventory # wire the app to its project's inbox $ flicker suggestions status --app enventory # edge present? which project? last report? $ flicker suggestions disable --app enventory # remove the edge + revoke the credential
Environments & secrets
flicker env
manage named environments and sync their secrets to .env files
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
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
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
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
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/triage). 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
flicker harness
org skill library + machine profile, written into every agent harness
Org library of skills, MCP specs, rules. A PROFILE is a bag of enabled entries: own membership plus, for non-org-base profiles, every same-org org-base source not opted out. Inherited entries stay on and locked while any enabled source supplies them; disable those sources to unlock. This machine picks one profile and `sync` writes the effective bag into whichever agent harnesses are present in the working copy. Daily path: `harness use-profile <name>` once per machine, `harness sync` per repo (or `--check` in CI), `harness list` to see the library and what is in effect. Registering or publishing still puts content into the library; membership and per-source inheritance live on the profile in the web UI (the old assign/unassign project grid is RETIRED, #1528). (`skill install` ships Flicker's own embedded platform/workflow skill; `harness` is the other direction — your library projected out.) Where things land: Claude Code `.claude/skills/<name>/SKILL.md` with MCP servers merged into `.mcp.json`; Codex files under `.flicker-agent/agent-config/` plus an index block in `AGENTS.md`; Pi `.pi/skills/<name>/SKILL.md`; opencode `.opencode/skills/<name>/SKILL.md`. Rules project into `AGENTS.md` only when the profile enables them — a profile with zero rules leaves a hand-written AGENTS.md alone. Sync is a sync, not an append: each harness gets a manifest under `.flicker-agent/harness/`, files Flicker never wrote are never touched, and `--check` is the CI probe (exit 0 fresh, exit 1 stale, no writes). Profile precedence: `--profile` > `.flicker/local.toml` > `flicker.local.toml` > global `harness_profile`. An entry with no description is a DRAFT and never projects. `harness doctor` checks declared-vs-actual on disk: drift, MCP server registration, scope, groups with no members, and the description-index budget. `harness adopt` reads what this machine already has (`~/.claude/skills`, `~/.agents/skills`, repo lockfiles) and proposes a library — a dry run until `--apply`. `harness pack import` registers each skill in a directory as its own library entry; `--as-group` fronts a pack with one group skill. `--curate` has a model write or tighten descriptions. `harness install skill --source <uri> --ref <pin>` declares machine-fetched delivery (hash-verified on every sync). When sync cannot deliver it writes what it can, names what is missing, and exits non-zero; it never writes a stub for content it could not get.
| Flag | Description |
|---|---|
--profile <name> |
one-shot profile override (else .flicker/local.toml, flicker.local.toml, global harness_profile) |
--personal |
act as YOU: uses the personal CLI token, writes user-owned config |
--harness <name> |
repeatable: cc|codex|pi|opencode — target one harness |
--pack <name> |
group entry into a named pack (default: directory's name) |
--curate |
with pack import/skill publish/adopt: an LLM writes or tightens the DESCRIPTION |
--as-group |
with pack import: front the pack with ONE group skill; members go off-index |
--group-name <name> |
with --as-group: the group entry's name (default: pack's) |
--group-description <t> |
with --as-group: the one line the session index pays for |
--skill-dir <dir> |
with doctor: repeatable — measure THESE index paths, not user-scope ones |
--apply |
with adopt: WRITE the plan (adopt is a dry run without it) |
--dry-run |
with adopt: default — print the plan, write nothing |
--to <seq> |
with revert: version to restore (default: one before the latest) |
--check |
with sync: report staleness, write nothing (exit 1 = stale) |
--source <uri> |
with install skill: git+https://…//path or npm:pkg — machine fetches, Flicker stores no bytes |
--ref <pin> |
with --source: commit, tag or version to install (required) |
--offline |
with sync/doctor: install delivery may use its cache and must not touch the network |
--overlay |
with import: render to .flicker-agent/, never to repo's AGENTS.md |
--title <t> |
with rule add: rule's heading, if the body has none |
--body <text> |
with rule add: rule's markdown, instead of a file or stdin |
--yes |
with delete: skip the confirmation prompt |
--no-apply |
with install: publish and assign, but don't sync |
--out <dir> |
with export/skill new: output directory |
--json |
machine-readable output |
$ flicker harness use-profile giovanni-dev # select this machine's profile (global) $ flicker harness sync # project the selected profile into harnesses here $ flicker harness sync --check # CI: exit 1 when stale, writes nothing $ flicker harness sync --profile staging # one-shot profile override $ flicker harness list # the library, plus what is in effect here $ flicker harness publish ./commit-style # register it, or append a version $ flicker harness pack import ~/.agents/skills --pack ios # one library entry per skill, tagged ios $ flicker harness pack import ./skills --curate # import and tighten every description by model $ flicker harness pack import ~/.agents/skills/ios --pack ios --as-group # 84 skills behind ONE description in the index $ flicker harness adopt # read this machine's real setup; print the plan, write nothing $ flicker harness adopt --apply # same, then register it all $ flicker harness import # adopt this repo's AGENTS.md: it becomes generated $ flicker harness import --overlay # same, without ever writing repo's AGENTS.md $ flicker harness rule add acme.review ./review.md # register a prose rule and re-render $ flicker harness doctor # is the declared config actually on disk, complete? $ flicker harness doctor --json # the same findings, machine-readable $ flicker harness export --out agent-config # plain files, no harness dialect $ flicker harness install skill ./mine --personal # your own config, not the org's
flicker update
replace this binary from the control plane
Downloads the same binary `curl -fsSL https://flickercloud.com/install.sh | sh` installs (`/download/cli/<os>-<arch>`) and replaces the current executable in place. CLI versions ship with every control-plane deploy — there is no separate release pipeline. `FLICKER_INSTALL_DIR` overrides the destination (install.sh parity). After updating, refresh workflow skills if needed: `flicker skill update --workflow --global`, then `flicker doctor`.
| Flag | Description |
|---|---|
--json |
print planned download/path; do not rewrite the binary |
$ flicker update # replace the binary from the API host $ flicker version # show running binary's version stamp
flicker version
print this binary's version stamp and install path
Shows the link-time version (git SHA on deploy builds, "dev" for a local `go build`), GOOS/GOARCH, and the resolved path of the executable.
| Flag | Description |
|---|---|
--json |
machine-readable output |
$ flicker version # human-readable $ flicker version --json # for scripts
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 |
--user-token <token> |
override the personal CLI token used by --personal |
--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 |