cwp bricks pull
shipped 1.0.0cwp bricks pull [env] [flags]
This name is an alias. The work moved to cwp pull --only bricks, and that page documents it. This spelling still runs for one minor cycle.
Acts on the local site. Name an environment to act there instead.
| Argument | What it is | Default |
|---|---|---|
[env] | environment to pull from (default: default_environment in cwp.yml) |
| Flag | What it does | Default |
|---|---|---|
--type <type...> | restrict to these transfer types (default: everything with content) | |
--sensitive | does nothing since 2.0: credentials never enter the tree, and customCss travels on its own | off |
--no-assets | do not fetch font files the export could not embed from an environment | on |
--with-agent | with —dry-run on a host with no shell: install and remove the PHP agent so the plan is real | off |
Plus the shared flags --json, -v, --verbose, -q, --quiet and --dry-run.
What it does
cwp bricks pull writes Bricks’ own transfer package into
builder.options.export_dir as a tree of JSON. The default directory is
bricks/. The tree holds manifest.json, styles/classes/classes.json and
structure/templates/template-*.json.
You commit that tree. The ZIP Bricks produces is transient. The tree is what you read a diff on, and it makes an upward design change reproducible.
The builder’s settings travel by a rule per key. The run names every key it held back. This tree goes into git, so no flag opens a credential. What stays out, and why:
| what | keys | why |
|---|---|---|
| per environment | maintenanceMode | owned by the access: map, applied by cwp access |
| credentials | the API keys, the licence key, the template passwords | never in a repository |
| code execution | the code toggles and the three script slots | never over a push |
| post ids | login_page, maintenanceTemplate and seven more | travel as { kind: post, type, slug, uid } rather than a number that means another post on the other side |
– settings — 2 key(s) held back from the tree — maintenanceMode (per environment, owned by access:), myTemplatesPassword (credential)
The pull does not hold a post id back. It translates the id, the way a
settings: group with as: post-reference carries page_on_front, and
cwp bricks push resolves it on the target. An id the site cannot
describe stays a number.
Everything else in the six tabs is design and travels. That includes a key
Bricks adds in a later release. The pull treats an unknown key as design unless
it looks like a credential (apiKey*, apiSecretKey*, *Token, *Password).
The api-keys and custom-code tabs never enter the tree. The one design key
inside them, the custom CSS, travels as its own file (below). --sensitive has
nothing left to switch on and says so when you pass it.
The scope is always explicit. The pull names every item by ID and writes
["all"] only for single-value types such as breakpoints.
The tree is the same from every environment
What Bricks exports describes the export as much as the design system. The package carries a timestamp, the exporting site’s URL and the post ID of every font and template. Its file name has today’s date on it. Pulled verbatim, that tree grows a new set of templates every day. It never matches the same design system pulled from another environment.
So cwp writes a committed form of the package instead:
- cwp names font files by family:
styles/custom-fonts/kulachat-hc.json, with its faces underassets/kulachat-hc/. cwp names each face after its weight and subset:400.woff2, or400-subset0.woff2where a weight is split. Both names come out of the font’s own face map, which is the same on every environment. The path Bricks writes is not: it has carried the font’s post id, each file’s attachment id and whatever WordPress called the upload; - templates lose the export date:
structure/templates/template-header.json; - the export timestamp, the site block, and every post and attachment ID come out;
- cwp rewrites every JSON file with sorted keys and two-space indent, so a diff shows the element that changed rather than the file that did.
cwp reshapes nothing. Every field it removes is one Bricks’ importer never
reads or falls back from. The importer matches fonts by family and templates by
title and type. So the committed tree is still a package the importer accepts,
and cwp bricks push sends it as it stands.
Pull twice and the second run reports 0 written, 18 unchanged. A pull that
changes nothing leaves git status empty.
The first pull after upgrading writes the new names beside the old ones. A
pull never deletes from a git-tracked directory. It reports the files it no
longer produces and leaves them in place. git rm the dated templates and the
id-suffixed font once, and the tree settles.
Custom fonts, and the files behind them
A Bricks custom font is a record and a binary in the media library. Bricks
embeds the binary into the package by reading it off the local disk. On a
workspace with pull.uploads: proxy the binary is not on disk. That is
the uploads proxy working as designed. The export
would drop every face, and the tree would record a font with no faces.
So the pull fetches the binary. When a font comes back empty, cwp asks
Bricks which files that font needs, downloads those files from your environment
into wp-content/uploads/, and exports again:
✓ font files — 1 fetched from dev into public/wp-content/uploads — 2026/02/example.woff
That is a handful of files, not the whole media library. The font then travels
in the tree as styles/custom-fonts/assets/<family>/…. It is the one place
where bricks/ is not JSON.
Nothing extra happens when nothing is missing. cwp reads the loss out of the package, not out of the site. The manifest counts the faces the database holds. The file counts the faces Bricks embedded. A gap between the two counts triggers the fetch.
--no-assets switches the fetch off. So does having nowhere to fetch from. If
the project has several environments and none of them is dev, cwp says so
rather than picking one. The pull reports the loss instead:
! Example Sans — 1 of 1 face(s) not embedded — styles/custom-fonts/example-sans-170.json
That tree is still usable for everything else. cwp bricks push
refuses to send the font from it. The manual equivalent is:
cwp media pull dev --uploads sync
cwp pull --only bricks
Example
cwp bricks pull # everything with content, from local
cwp bricks pull --type classes --type variables
cwp bricks pull prod # read a remote instead
Templates leave once the content tree claims them
A Bricks template is a post. cwp content carries posts without rewriting
their element ids. The design-system package cannot promise that, because
Bricks’ importer regenerates every id when it upserts a template.
So the moment a content group declares bricks_template, the design system
stops exporting the templates type. There is nothing to switch on: cwp reads
it off content: in cwp.yml. The first pull after that reports the old files
as left in place. git rm them and commit the move.
A project with no such group keeps exporting templates as before.
The options the builder’s own transfer leaves behind
Bricks stores two project-wide decisions in an option its export package does
not carry: the colour mode (light, dark, or the visitor’s system
preference) and the root font size behind every rem in the design
system. settings: refuses both as belonging to the page builder.
cwp carries them in bricks/cwp-options.json. That is cwp’s own file in the
builder’s tree: every pull writes it and every push reads it. You commit and
diff it like everything else there. Bricks’ importer has no use for it. The
push keeps it out of the archive on the way up.
Five more options the package omits travel in the same file:
- the element manager (
bricks_element_manager): which element is active, hidden or disabled; - the pseudo-classes the builder offers;
- the locks on global classes;
- the widget areas Bricks registers;
- the global elements from before components.
A lock names a class by id. The package import can give a class a new id on the target. The push leaves out a lock on an id the target has no class for. The run names it.
The custom CSS is the second such file, bricks/custom.css. Bricks stores
it under the custom-code tab beside the script slots, and its importer
refuses that tab outright. The package can export the key and never import it.
It is design all the same: on a real project it holds the light/dark switch for
every image. The pull writes it as a CSS file. The push writes it back as one
key. A diff shows lines of CSS rather than one JSON string. A site that has
never saved custom CSS gets no file, and a tree with no file leaves the site’s
CSS alone.
The run names two values under the same prefix that it does not carry. Absent never means overlooked:
– bricks_font_face_rules — not carried — generated by Bricks and regenerated on import
– bricks_mcp_settings — not carried — per environment
Hosts and attachments travel as placeholders
A class, a component or a template can name an image. The site names the image
by its own host and its own attachment id. Neither means the same thing on
another environment. The pull writes both as the content tree writes them: the
host as {{site}}, the attachment as media:<upload path>. A tree pulled from
dev and one pulled from prod are then the same bytes. The pull leaves the
manifest and the font binaries alone.
An image on another host is not the site’s attachment. A reference a template library left behind, with an id and a URL under some other domain, travels as it is. The id means nothing on any site, and the URL is what renders.
What it does not do
It deletes nothing. Like cwp push without --delete, it is
additive. The pull reports files in bricks/ that this export no longer
contains and leaves them alone. Removing a git-tracked file is not a side
effect of an export.
It writes nothing to the site it read from. Reading a remote is safe, so an environment argument here carries no guard ladder.