# Zalify CLI Plain-text reference for developers and AI agents. Canonical URL: https://www.zalify.com/cli.txt Package: @zalify/cli (npm) — bin name "zalify". Wrapper package "zalify" lets you run `npx zalify …` or `npm i -g zalify`. Requires Node >= 20. Source of truth for behavior is always `zalify --help` and `zalify --help` of your installed version. The Zalify CLI authors a commerce brand, launches its hosted site, and keeps the site's theme up to date — the full lifecycle of a Zalify storefront, from empty folder to live domain, without holding any infrastructure credentials on your machine. ## INSTALL npm i -g zalify # or: pnpm add -g zalify / npx zalify … zalify self-update # later updates (auto-detects pnpm/bun/npm) ## THE COMMAND MODEL — THREE NOUNS, THREE OBJECTS brand = the DATA a brand folder on disk: product catalog, brand voice guide, image manifest. Authoring happens here, before any account exists. site = the SITE the Zalify-hosted deployment: GitHub repo + hosting + domain, provisioned server-side. theme = the CODE the storefront source code, distributed like a Shopify theme: a versioned copy you own, with tool-assisted upgrades that keep your edits. Rules of thumb: - Anything that reads or writes a brand folder is `zalify brand …` and the folder argument defaults to the current directory. - Anything about the live deployment is `zalify site …`; inside a scaffolded site repo (or a brand folder), site commands need no argument — the directory identifies the site. - Anything about source code and versions is `zalify theme …`. ## THE GOLDEN PATH (empty folder → live site) 1. zalify brand init my-brand # author the data (no login) # fill in brand.md, catalog.json, images/manifest.json zalify brand validate my-brand 2. zalify login zalify workspace set 3. zalify site create my-brand-site # repo + hosting + domain + deploy (~4 min) 4. cd my-brand && zalify brand push --prune 5. zalify brand images generate && zalify brand images attach 6. zalify site open # see it live Later: zalify theme status # what have I edited? zalify theme upgrade # new theme version, edits kept ## AUTHENTICATION zalify login Opens the browser (app.zalify.com), mints a user-scoped API key stored in ~/.zalify/config.json (0600). One login covers every workspace you belong to. Keys expire after 90 days. zalify logout Deletes the stored credentials. zalify whoami Verifies the key; shows user, workspace, plan, key age. zalify workspace Lists your workspaces (* = active). zalify workspace set Switches the active workspace — the Shopify store all commands target. Local only, no re-login. This is the ONLY sticky state the CLI keeps; sites resolve from context, not from a mode. Credential model: the CLI holds only your Zalify user key. Shopify Admin access, GitHub, and hosting credentials live server-side at Zalify — Shopify calls go through Zalify's authenticated Admin proxy, repo pushes use short-lived (1 hour) repo-scoped tokens minted per push, and the site's cache-refresh secret never leaves the server. ## zalify brand — THE DATA zalify brand init [dir] [--name ] [--vertical ] [--currency USD] Scaffolds a brand folder. No login needed. Creates: brand.md brand voice guide (template) catalog.json products + collections (worked example, plus the mandatory best-sellers and sale collections) images/manifest.json one entry per shot + shared style/ modelStyle/bannerStyle art-direction prefixes. Product shots carry a handle; "type": "banner" entries (hero slides, editorial banners — hero-1.png + hero-1-mobile.png naming) have no handle and set "size" ("1536x1024" landscape / "1024x1536" portrait; default "1024x1024"). Theme templates reference banners by their images/assets.json URL. store.json the Shopify store this brand connects to AUTHORING.md THE RULES — complete authoring contract (catalog schema, collection-tag mechanics, naming and pricing conventions, image prompt-safety). An agent can produce a complete brand from AUTHORING.md alone. zalify brand validate [dir] Lints the folder against the rules: unique kebab-case handles, 2-decimal string prices, variant/option arity, every collection tag resolves to a collection rule, sale products carry real compare-at prices, manifest entries map to real products, alt text present. Exit code 1 on problems. zalify brand push [dir] [--prune] [--site ] Pushes catalog.json to the active workspace's Shopify store via Zalify's Admin proxy: products (idempotent by handle), smart collections (tag rules), Online Store publication. --prune deletes store products (matching the catalog vendor) that are absent from catalog.json. Afterwards auto-refreshes every ready site matching the brand's slug (--site limits it to one). zalify brand images generate [dir] Generates the manifest's missing images on Zalify's infrastructure as a durable background job; the CLI polls and downloads results. Resumable: re-run to retry only failures — produced files are checksummed against the asset library, never re-billed. Finished masters land in the Zalify asset library and locally under images/; images/assets.json is the committed index (the PNG masters themselves stay out of git). zalify brand images attach [dir] [--site ] Attaches generated images to their Shopify products per the manifest. Idempotent — already-attached files are skipped and "banner" entries (no product) are ignored. Auto-refreshes matching sites afterwards. zalify brand images push [dir] zalify brand images pull [dir] Sync image masters with the Zalify asset library (sha256 dedup). push uploads local masters; pull restores them on a fresh clone. ## zalify site — THE HOSTED SITE zalify site create [-t nextjs] [--editor] [--to ] [--no-install] [--no-git] One-command launch. Zalify's server provisions everything (no infra credentials on your machine): mints a Shopify Storefront API token via the workspace's store connection, creates a private GitHub repo, a hosting project linked to it (with env vars and a server-held cache-refresh secret), and the domain .myzalify.com. The CLI then scaffolds the theme locally, writes .zalify/site.json (linking the folder to its site), pushes with a short-lived repo token, and waits for the first deployment to serve. The slug is the directory basename. Name the directory after the brand's slug so auto-refresh links brand pushes to this site. Requires: active workspace with a connected Shopify store (409 NO_CONNECTION otherwise), paid plan (402), unique slug (409 SLUG_TAKEN). zalify site [list] Lists the workspace's sites: status, URL, repo. zalify site refresh [slug-or-dir] Refreshes the live site's data cache (products, collections, menus, content) so Shopify-side changes appear immediately. The refresh secret stays server-side. Argument optional: inside a site repo or brand folder the site is inferred; with exactly one site in the workspace it is assumed; otherwise name it. zalify site open [slug-or-dir] Opens the live site in your browser. Same resolution rules. Deploys happen on git push (the repo is linked to hosting). A redeploy does NOT clear the data cache — that is what refresh is for, and brand push / brand images attach do it automatically. ## zalify theme — THE CODE The theme is distributed the way Shopify themes are: you own a copy of the source, and upgrades are tool-assisted rather than forced. Every scaffold carries .zalify/theme.json — a checksum manifest of each theme-owned file as shipped. Your customizations belong in: theme/ settings_data.json, templates/*.json, locales/*.json — the merchant-owned surface, NEVER touched by upgrades .env store credentials, never touched anything you add (public/ assets, new files) — untouched zalify theme create [-t liquid|hydrogen|nextjs] [--editor] [--store-domain ] [--storefront-token ] [--to ] [--no-install] [--no-git] Scaffold ONLY — the self-host path (deploy anywhere you like). `site create` is the fully-hosted launch and uses this internally. Without store credentials the scaffold runs against mock.shop demo data. No login needed. zalify theme status [dir] Which theme-owned files have you edited? Checksums the working tree against the manifest: clean / edited / missing. zalify theme upgrade [dir] [--to ] [--dry-run] [--install] Moves the copy to a newer theme release: - files you never touched are overwritten with the new version - files you edited are 3-way-merged (base = your current version's original); conflicts leave standard markers - files added/deleted upstream are applied when safe - theme/, .env, and your own files are never touched - package.json is merged per-key (your added deps kept) --dry-run reports the classification without writing. The manifest is rewritten to the new version; `theme status` shows drift again afterwards. ## MAINTENANCE zalify self-update Update the CLI in place. zalify version Version + update check. zalify --help Full surface; every group has --help too. ## FILE CONTRACTS (quick reference) Brand folder (created by `brand init`, consumed by brand push/images): brand.md, catalog.json, catalog/ (generated), images/manifest.json, images/assets.json (committed index), images/*.png (not committed), store.json, AUTHORING.md Site scaffold (created by `site create` / `theme create`): .zalify/theme.json upgrade contract (checksums; do not edit) .zalify/site.json link to the hosted site (site create only) theme/ YOUR settings/templates/locales overrides .env store credentials (NEXT_PUBLIC_STORE_DOMAIN, NEXT_PUBLIC_STOREFRONT_API_TOKEN) catalog.json essentials (full rules in the scaffolded AUTHORING.md): products[]: handle (unique kebab-case), title, descriptionHtml, type, tags, options (0-3), variants[] (options match arity, price "29.00" strings, optional compareAtPrice), optional seo collections[]: smart collections — a product joins collection X by carrying tag "collection:X"; the collection rule is { "tag": "collection:X" }. best-sellers and sale are mandatory; sale products need a real compareAtPrice and the collection:sale tag. pages[]: the standard store pages ({handle, title, bodyHtml}) — about, shipping-delivery, returns-exchanges, faq, privacy-policy, terms-of-service. Upserted by brand push, linked from the footer menu. /pages/contact ships with every store — link it, don't author it. discounts[]: code discounts ({code, percentOff, title?}) created by brand push — keep the scaffold's WELCOME20: it's the code the theme's cart voucher banner shows, so Apply actually works. menus: {"main-menu": [...], "footer": [...]} — items are { title, url, items? }, relative URLs, max 3 levels; URLs must reference handles that exist in this file. brand push upserts them (full item tree replaced — the catalog is the source of truth). Nested main-menu items open the theme's mega panel; nested footer items become footer columns (Shop / Help / Company is the standard trio). ## ERRORS AND TROUBLESHOOTING 401 Unauthorized (suddenly, mid-batch) Bursty commands can trip the per-key rate limit; it clears in about a minute. All push/attach commands are idempotent — re-run. 402 UPGRADE_REQUIRED The feature (asset library, site hosting) needs a paid plan. 409 NO_CONNECTION The workspace has no connected Shopify store — connect it in the Zalify dashboard first. 409 SLUG_TAKEN Site slugs are global; pick another directory name. 428 SCOPES_MISSING The workspace's Shopify connection predates the CLI scopes — the error includes a reconnect URL. Image generation rejected (safety_violations) Reword the prompt in images/manifest.json and re-run `brand images generate` — see AUTHORING.md's prompt-safety rules (applies to human-model shots; layered/covered styling, no "young …" phrasing, chin crops). Stale data on the live site `zalify site refresh` — deploys alone never clear the data cache. Old command spellings (store …, shopify import, images generate, assets push/pull, storefront …) still work for one release and print their new home. — Generated for www.zalify.com. Questions: ryan@zalify.com