## types
```bash
mercemur types --lang ts -o src/mercemur.d.ts
mercemur types --lang go --package mercemur -o internal/mercemur/types.go
mercemur types --lang ts --prefix /api/v1/products
```
Generates type declarations for all 567 operations from the published spec, so a request body or a
response is checked by your compiler rather than at runtime. With no `-o` it writes to stdout.
**Types only, deliberately.** A generated request layer has to decide auth, retries, pagination
and error handling, and shipping a second opinion on those is how two clients in one codebase
start disagreeing. Types are the part with no opinion in them.
The output carries no timestamp and is byte-identical between runs, so regenerating produces a
diff only when the API actually changed. `--spec` reads a local file instead of fetching.
## doctor
```bash
mercemur doctor
```
Checks the things that stop the CLI working, in the order they fail: config, credential,
connectivity, the key itself, and clock skew. Every failing check says how to fix it, and the
command exits non-zero so CI can gate on it.
Clock skew is worth the check: webhook signatures verify inside a few minutes' tolerance, so a
drifted machine fails with an error naming the signature, and nobody thinks to look at the clock.
## content
```bash
mercemur content pull
mercemur content status
mercemur content push
```
Pulls your pages and blog posts into local files so you can edit them in your editor and review
changes in git.
| Content | File | Why |
|---|---|---|
| Pages | `content/pages/.md` | The body genuinely is markdown |
| Blog posts | `content/blog/.json` | The body is a rich-text document |
A blog body is structured (`{"type":"doc","content":[...]}`), not markdown. Rendering it to
markdown and parsing it back works on a paragraph of plain text and silently drops every other
node type, so it round-trips as JSON instead. Two formats because there are two formats.
`push` creates a file with no `id` as a **draft** and patches one that has an id. It never
publishes and never deletes: making content visible to shoppers stays a separate act, and a
deleted local file is far more often a mistake than an instruction. A field absent from a file is
absent from the request, so editing a body cannot blank a meta description you never pulled.
## products
```bash
mercemur products export -o catalogue.csv
mercemur products import catalogue.csv --dry-run
mercemur products import catalogue.csv
```
One row per variant with the product columns repeated, which is the shape a spreadsheet can
actually edit.
Import **only updates**. Rows are matched by `product_id` and `variant_id`; a row naming something
the store does not have is refused rather than turned into a new product, because a flat file
cannot express the option matrix a product needs to be created correctly.
Only the cells that **differ** are sent, so an untouched column is never rewritten and a stale
export cannot quietly revert someone else's dashboard edit.
`price_minor` is integer minor units: `1999` means 19.99. A decimal is refused rather than
guessed at, because guessing is how a catalogue gets repriced by a factor of a hundred.
## orders
```bash
mercemur orders list --status paid --limit 20
mercemur orders watch
```
`watch` polls and prints each order once when it appears, then again each time its status changes,
which is the event worth seeing during a checkout debug. The first poll is your existing backlog
and is not labelled as new. A failed poll retries rather than ending the session.
`--json` is refused on `watch`, as on `theme dev` and `logs tail`; run `orders list --json` in your
own loop for scripted output.