artbucket CLI reads and writes a brand folder
through the sync API, and uploads the files
under assets/ the library doesn’t have yet. It works against any Artbucket
server, Artbucket Cloud or your own.
Install and sign in
The CLI is theartbucket package on npm, for Node 22 and later:
login signs in through the browser and keeps a key in
~/.config/artbucket/credentials.json, with that server as the default. It
asks for write, since pushing a brand edits it; the consent screen never
offers more than you have. artbucket logout forgets the key; disconnect it
on the Connections page to revoke it.
Without signing in, two variables say where and as whom:
A key for CI is made by a workspace admin, in the app (Agents) or with
POST /api/v1/keys. Pushing takes write on the workspace; --publish
also takes sharing, which a grant can switch off.
The brand a command acts on
Everybrand command acts on the brand --brand names, or else the one the
slug: in the folder’s brand.yaml names. Never the workspace’s default:
a folder pushed without either is refused. pull writes slug:, so after
the first pull the folder says which brand it is.
The folder is the command’s first argument, brand when left out.
brand pull
- Only files whose meaning changed are written: one that says the same keeps its comments and layout.
- A file of
rules/orpages/the brand no longer has is removed. - A file you named
.ymlkeeps its name. --assetsgives every asset the brand points at a path underassets/, named after its filename, and downloads the ones whose bytes the folder doesn’t already hold. A folder whoseassets/already holds files pulls this way without the flag.- A file already in
assets/keeps its path, wherever it sits, matched by the SHA-256 of its bytes: references to it stay paths, never ids.
--assets and with an empty assets/, assets are written as asset
ids, unless the brand’s Git integration holds them as files.
brand diff
+ (added), - (removed), ~ (changed) or > (a page
moved in the tree); ! is a warning or a conflict. It exits 1 on any error
in the files, each printed at its file and line:
assets/ the server doesn’t have yet is not a problem: push
uploads it. diff lists it and exits 0, and shows the rest of the change
once the file is in the library:
brand push
- Hashes every file under
assets/, checks the files, and uploads each file they point at that the library doesn’t have yet. - Writes the brand as one version of its history, so it is undone like any
other edit, or prints
nothing changed. - Publishes, if asked.
What a push overwrites
A push merges with the app’s edits only when the brand has a sync base: the files both sides last agreed on, which a Git integration records at each commit. A brand synced only by the CLI or CI has none, so a push takes the files whole, and an edit made in the app since your last pull is undone (it stays in the brand’s history).diff shows it first, as a
change back to what the files say:
The brand holds changes these files lack: artbucket brand pull brings them in.
Pull before you push when people also edit the brand in the app, or keep
edits on one side: the repository, with CI pushing it.
From CI
A CI job checks the folder on pull requests and pushes it from the main branch. Keep the key as a secret, with the server’s address beside it.ARTBUCKET_URLis your own server when you host one. On GitLab,ARTBUCKET_URLandARTBUCKET_KEYare CI/CD variables, the key masked.- With
--note, each push to main is released with its commit’s first line. Leave--noteout to update the draft only, and release it from the app. - The check on a pull request reads the brand with the key, so it needs the secret: pull requests from forks, which get no secrets, can’t run it.
- A pull request that adds a file under
assets/passes the check:difflists the file, and the push on main uploads it. - A CI push has no sync base, so the repository is the source of truth: edits made in the app are undone by the next push. For both sides at once, use a Git integration.