| name | camox-cli |
| description | How to read or modify Camox website content via the CLI: pages, routes, block instances, copy, images/files, meta fields, layout assignments, draft/live state, publishing, and dev/prod sync. Use when the user wants to add, remove, rename, reorder, review, publish, or change anything visible on the site, including sections, heroes, footers, headlines, SEO titles, social previews, or what appears at a URL. Trigger on requests like 'add a page', 'change the headline', 'move this section', 'what's on /about', 'show me the live page', 'publish this page', 'fix the meta title', 'push to production', 'pull from production', or 'sync dev with prod', even if they do not mention Camox, CMS, page, block, layout, environment, or CLI. |
Using the Camox CLI
The Camox CLI is the right tool for any CRUD operation on CMS content — pages, block instances, layout assignments, meta fields. Reach for it before writing a custom script or asking the user to click through the dashboard. The camox binary is already installed in this project (it ships with the camox package).
When to use this skill vs. camox-block / camox-layout
This skill (camox-cli) is for content — the actual pages, the actual block instances on those pages, the wording and images visitors see. If the user wants to add a section to a specific page, change copy, reorder blocks, create a new route, swap which layout a page uses, or fix a meta title, you're editing content and you want the CLI.
The camox-block skill is for block definitions — the .tsx files in src/blocks/ that define what kinds of blocks exist (their schema, fields, and rendering). Reach for it only when the user wants to introduce a new type of section that doesn't exist yet (e.g. "we need a pricing-table section and we've never built one"), or change the schema or rendering of an existing block type.
The camox-layout skill is for layout definitions — the .tsx files in src/layouts/ that define the shared shells around page content (which navbar/footer blocks wrap pages, how meta titles are built, OG images, etc.). Reach for it when the user wants a new kind of page wrapper, a different shared structure, or to change how titles or social previews are constructed. Assigning an existing layout to a page is content — that's the CLI.
Rule of thumb: if the change should be visible on the live site without a code deploy, it's content → use the CLI. If it requires editing source files in src/blocks/ or src/layouts/, it's a definition → use camox-block or camox-layout. Some requests need both (e.g. "add a pricing section the site has never had before" = define the block via camox-block, then create an instance on a page via the CLI).
Running the CLI
This project uses pnpm. Always invoke the CLI as:
pnpm camox <command> [options]
For example: pnpm camox pages list, pnpm camox blocks types.
Discover commands with --help
The CLI surface evolves. Don't guess command names or flags from memory — ask the CLI. Run --help at the root and on every subcommand before invoking it, and treat the output as authoritative.
pnpm camox --help
pnpm camox pages --help
pnpm camox pages create --help
The CLI is organised into command groups around the resource types (pages, blocks, layouts, …). Use --help to discover what each group supports — the exact set of subcommands and flags is the CLI's responsibility, not this skill's.
Common recipes
Most content tasks fit into a small number of shapes. Use these as the entry-point template, then verify exact flags with --help. Always look up the page (pages get) before you create or move blocks — you'll need its id and the id / type of any sibling block you're positioning relative to.
Add a new block at a specific spot on a page
pnpm camox pages get --path /
pnpm camox blocks describe --type hero
pnpm camox blocks create --page-id 25 --type hero --content '{...}' --position first
pnpm camox blocks create --page-id 25 --type hero --content '{...}' --before-id 174
pnpm camox blocks create --page-id 25 --type hero --content '{...}' --after-id 174
pnpm camox blocks create --page-id 25 --type hero --content '{...}'
See Block positioning below for the full set of options.
Update copy in an existing block
pnpm camox pages get --path /pricing
pnpm camox blocks edit --id 314 --content '{"headline": "New headline"}'
Update one item inside a repeatable field (one FAQ answer, one feature title, …)
Repeatable fields are an array of items. blocks edit treats the items array as the new truth: any existing item whose _itemId is not in your patch is deleted (cascading to its file references, settings, and child items). To change one item without losing the rest, fetch the block first to learn every item's id, then patch with every _itemId present.
pnpm camox blocks get --id 99
pnpm camox blocks edit --id 99 --content '{
"items": [
{"_itemId": 401},
{"_itemId": 402, "answer": "Updated answer."},
{"_itemId": 403}
]
}'
Same pattern for nested repeatables: each child item also has an id you pass back as _itemId inside the parent item's array field.
When you need to edit repeatable fields in several blocks, prefer fetching them together first:
pnpm camox blocks get-many --id 99 --id 100 --id 101
blocks get-many returns the same bundle shape as blocks get for each block, in the same order as the requested ids.
Create a new page using an existing layout
pnpm camox layouts list
pnpm camox pages create --path-segment about --layout-id 39
Review a draft and publish it to live
Agents should work on drafts first, get the changes reviewed, and only then publish. Draft is the default source for reads and the default target for writes, so do not add --live while editing.
pnpm camox pages get --path /pricing
pnpm camox blocks get --id 314
pnpm camox pages get --path /pricing --live
pnpm camox blocks get --id 314 --live
pnpm camox pages publish --path /pricing
pnpm camox pages publish --path /pricing --no-layout
pages publish accepts exactly one of --id or --path. It publishes the page's current draft. By default it also publishes the page's layout; that layout publish is a no-op when there are no pending layout changes.
To remove a published page from live without deleting its draft:
pnpm camox pages unpublish --path /pricing
To throw away unpublished draft edits and reset the draft to the current live snapshot:
pnpm camox pages discard-changes --path /pricing
pages unpublish and pages discard-changes accept exactly one of --id or --path. pages unpublish leaves the draft untouched. pages discard-changes does not change live content and fails when the page has never been published.
--live is for reading the published snapshot. It is not a write target and it is not how you publish. Live reads error when the page or block has never been published.
Promote dev to production (or pull production back into dev)
The env group replicates content in bulk between your dev environment and production — the same two operations the studio's environment menu exposes. This is separate from draft/live publishing. Use it when the user wants to copy an environment's content to the other environment, or wipe dev and start from production.
pnpm camox env check
pnpm camox env push --yes
pnpm camox env pull --yes
--yes (or -y) is required on push / pull — both replace every page, block, and file in the target environment and the change cannot be undone. See Environments, drafts, and live below for when to use this vs pages publish, --live, and --production.
Block positioning
blocks create and blocks move accept the same set of positioning flags. Pass at most one — combining them is rejected. move requires one (use --position last to send a block to the end); create defaults to appending at the end if you pass none.
| Flag | Meaning |
|---|
--position first | Place at the very top of the page. |
--position last | Place at the very bottom of the page (also the create-time default). |
--after-id <ID> | Place immediately after the sibling block with that id. |
--before-id <ID> | Place immediately before the sibling block with that id. |
--after-position <KEY> | Low-level: insert after a known fractional-index key. |
--before-position <KEY> | Low-level: insert before a known fractional-index key. |
Prefer the high-level flags (--position, --after-id, --before-id) — they read naturally and don't require you to know the fractional-index format. The --after-position / --before-position flags exist for cases where you already have a key in hand (e.g. piping output between commands).
Environments, drafts, and live
Every project has two environments: a per-user, isolated dev environment and the shared production environment. Inside each environment, content has a draft working copy and a live published snapshot.
Draft-first workflow
By default, reads and writes operate on the draft. This is intentional: agents should make content changes in draft, summarize what changed, let the user review, and publish only after approval.
pnpm camox pages get --path /about
pnpm camox blocks edit --id 314 --content '{"headline": "New headline"}'
pnpm camox pages publish --path /about
pnpm camox pages discard-changes --path /about
Use --live only to compare against the published snapshot:
pnpm camox pages get --path /about --live
pnpm camox blocks get --id 314 --live
Per-command: the --production flag
By default, every command runs against the dev environment. Pass --production to target the production environment instead, one command at a time:
pnpm camox pages list --production
pnpm camox blocks edit --id <ID> --production
--production selects the environment; it does not mean "published". Production still has draft and live state. To read production's published snapshot, combine --production with --live. To publish a production draft, use pages publish --production.
Only use --production when the user has explicitly asked to operate on the production environment. For everything else — exploration, tentative edits, anything you'd want to be able to throw away — stay on the default dev environment.
Bulk replication: the env group
When the user wants to copy dev to production (or do the inverse — wipe dev and start from production), use the env group instead of running many commands with --production:
pnpm camox env check
pnpm camox env push --yes
pnpm camox env pull --yes
env check returns { push: { compatible, reasons }, pull: { compatible, reasons } }. The reasons array is empty when that direction is safe; otherwise each entry names a divergence (a block type or layout that exists in one env but not the other, or a block-definition schema mismatch). Fix the divergence first — replicate will refuse with FAILED_PRECONDITION and the same reasons in data.reasons if you don't.
env push and env pull require --yes (or -y) because they replace the target environment's entire content. Without it the command refuses and prints what it would have done.
Don't write slop — build understanding first
Anything you create with this CLI ends up on a real website read by real people. Never invent generic filler copy ("Welcome to our amazing platform", "Lorem ipsum"-grade headlines, plausible-sounding-but-fabricated stats, made-up testimonials, fake company names). That kind of content is worse than nothing — it ships, it gets indexed, and the user has to clean it up.
Before writing any block content:
- Read what already exists. Use the CLI to list pages and inspect existing blocks (
pnpm camox pages list, pnpm camox pages get …, pnpm camox blocks describe …, etc. — discover the exact commands via --help). The site's voice, product positioning, naming, and recurring claims are usually already established somewhere; mirror them. A new "About" block on a site that already has hero/feature copy should sound like a continuation of that copy, not a fresh marketing draft.
- Pull real facts from the right source. If the user gave you the content, use it verbatim. If the content describes something external (a person, company, product, paper, event, library), use web search or whatever fetch tools you have to look up actual details before writing. If you genuinely can't get a fact, ask the user — don't paper over it with a guess.
- For
File and Embed fields, do not guess URLs. These point at real assets (PDFs, videos, embeds). A hallucinated URL produces a broken link or, worse, a link to someone else's content. Leave the URL field blank and tell the user the asset still needs to be supplied — the CMS will treat the empty value correctly, and toMarkdown will skip the line.
- Same for
Image. Don't fabricate filenames. If you don't have a real uploaded asset to reference, leave it empty and flag it.
Short version: if you're tempted to "make something up that sounds about right", stop and either go find the real thing or hand the gap back to the user.
Workflow
- If the task matches one of the Common recipes above, start from that template — it's almost always the right shape.
- Otherwise, run
pnpm camox --help to find the right command group, then pnpm camox <group> --help and pnpm camox <group> <command> --help to confirm the exact flags.
- Before writing content, read existing pages/blocks and gather any external facts you need (see above).
- Work on draft first. Omit
--live while editing; use --live only for reading the published snapshot for comparison.
- Get the draft changes reviewed. Summarize the affected page(s), block ids, and notable copy/structure changes.
- Publish with
pnpm camox pages publish --id <ID> or pnpm camox pages publish --path <PATH> only after the user asks or approves.
- Add
--production only when the user has asked to operate on the production environment.