farmacia
Agent-first CLI over VTEX pharmacy catalogs. First store: Farmacity (AR). A store is config, not code.
Setup
cd ~/Programming/railly/farmacia && bun link # exposes `farmacia`
Commands
farmacia search <term> [--limit 1-50] [--page N] [--sort price-asc|price-desc] [--store farmacity]
farmacia product get <productId>
farmacia product ean <barcode>
farmacia schema # full machine-readable surface, versioned
farmacia search is shorthand for farmacia product search.
Contract
- stdout: one JSON envelope
{ ok, command, store, data, meta } (JSON is automatic when piped; --json forces it). Human tables when TTY.
- stderr: NDJSON
{type:"next-step", command, description} hints + notes. Never data.
- Errors:
{ ok:false, code, error, hint } on stdout in JSON mode. Exit 0 ok / 1 user error / 2 system.
- Product:
id, name, brand, url, ean, price, listPrice, currency, available, stock, saleType, category, promos. price is null when unavailable.
- saleType:
otc | prescription | general, derived from the VTEX category tree (Medicamentos Venta Libre / Venta Bajo Receta).
Gotchas the agent should know
- Prices/stock come from a CDN cache up to 300s old (
meta.cacheMaxAgeSeconds). Do not promise real-time stock.
- Pagination: window max 50, offset max 2500 (VTEX hard limits, enforced client-side with typed errors
WINDOW_LIMIT / PAGINATION_LIMIT). Refine the term instead of paging deep.
stock 99999 means "not tracked per unit", not literal inventory.
- This CLI reads a public catalog. It cannot buy, reserve, or check per-branch stock.
Composition
farmacia search ibuprofeno --sort price-asc --limit 5 --json | jq '.data[0]'
farmacia product ean "$(barcode)" --json | jq -r '.data.url'
1---2name: farmacia3description: Query pharmacy catalogs (Farmacity Argentina, VTEX) from the terminal. Use when the user wants to search medicine or skincare prices, check stock at Farmacity, look up a product by EAN barcode, compare pharmacy prices, or asks "cuanto sale X en farmacity", "busca Y en la farmacia", "hay stock de Z". Read-only catalog; no purchases.4---56# farmacia78Agent-first CLI over VTEX pharmacy catalogs. First store: Farmacity (AR). A store is config, not code.910## Setup1112```bash13cd ~/Programming/railly/farmacia && bun link # exposes `farmacia`14```1516## Commands1718```bash19farmacia search <term> [--limit 1-50] [--page N] [--sort price-asc|price-desc] [--store farmacity]20farmacia product get <productId>21farmacia product ean <barcode>22farmacia schema # full machine-readable surface, versioned23```2425`farmacia search` is shorthand for `farmacia product search`.2627## Contract2829- **stdout**: one JSON envelope `{ ok, command, store, data, meta }` (JSON is automatic when piped; `--json` forces it). Human tables when TTY.30- **stderr**: NDJSON `{type:"next-step", command, description}` hints + notes. Never data.31- **Errors**: `{ ok:false, code, error, hint }` on stdout in JSON mode. Exit 0 ok / 1 user error / 2 system.32- **Product**: `id, name, brand, url, ean, price, listPrice, currency, available, stock, saleType, category, promos`. `price` is `null` when unavailable.33- **saleType**: `otc` | `prescription` | `general`, derived from the VTEX category tree (`Medicamentos Venta Libre` / `Venta Bajo Receta`).3435## Gotchas the agent should know3637- Prices/stock come from a CDN cache up to **300s old** (`meta.cacheMaxAgeSeconds`). Do not promise real-time stock.38- Pagination: window max 50, offset max 2500 (VTEX hard limits, enforced client-side with typed errors `WINDOW_LIMIT` / `PAGINATION_LIMIT`). Refine the term instead of paging deep.39- `stock` 99999 means "not tracked per unit", not literal inventory.40- This CLI reads a public catalog. It cannot buy, reserve, or check per-branch stock.4142## Composition4344```bash45farmacia search ibuprofeno --sort price-asc --limit 5 --json | jq '.data[0]'46farmacia product ean "$(barcode)" --json | jq -r '.data.url'47```