@drip-apex/apex-cli 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/README.md +125 -30
- package/dist/cli.js +6890 -3911
- package/package.json +14 -2
- package/skills/apex-cli/SKILL.md +43 -0
package/AGENTS.md
CHANGED
|
@@ -89,7 +89,8 @@ the first writes: `apex experiments create`, `apex goals create`,
|
|
|
89
89
|
- Edit experiment files, variation code, metrics, and targeting only through supported paths.
|
|
90
90
|
- Do not bypass the variation artifact persistence path with direct API writes.
|
|
91
91
|
- Keep generated evidence outside `qa.json`; attach it through QA commands.
|
|
92
|
-
- Author commerce drafts in `commerce/price.json`, `commerce/shipping.json`, `commerce/offer.json`, or `commerce/post-purchase.json`; never edit their `serverOwned` sections.
|
|
92
|
+
- Author commerce drafts in `commerce/price.json`, `commerce/shipping.json`, `commerce/offer.json`, `commerce/discount-codes.json`, or `commerce/post-purchase.json`; never edit their `serverOwned` sections.
|
|
93
|
+
- Checkout messages use `{ "action": "checkoutBlock", "checkoutBlock": { "heading": "Free returns for 30 days" } }`: one per A/B arm, flat mutations only (`variations/<slug>/mutations.json` or workspace `src/mutations.json`), never URL blocks or a test with post-purchase. Money copy is refused. Run each message arm's QA checkout from its `apex preview <id> <variation-id>` link or the dashboard, then launch in the dashboard.
|
|
93
94
|
|
|
94
95
|
## Project code
|
|
95
96
|
|
package/README.md
CHANGED
|
@@ -1,4 +1,46 @@
|
|
|
1
|
-
# Apex CLI
|
|
1
|
+
# Apex CLI: run A/B tests on your online shop from the terminal or an AI coding agent
|
|
2
|
+
|
|
3
|
+
Apex by DRIP is an A/B testing platform for online shops that predicts which tests will win before they go live, built on one of the largest A/B test databases in e-commerce.
|
|
4
|
+
|
|
5
|
+
This package is the `apex` command line. Developers and AI coding agents (Claude Code, Codex, Cursor) use it to build and run Apex A/B tests as code: list tests and read results, pull a test into local files, edit the variation, review a plan and apply it, open preview links for QA, check tracking, and push goals, targeting and feature flags from a config file. Launching a test to live traffic happens in the Apex app.
|
|
6
|
+
|
|
7
|
+
- Website: https://www.drip-apex.com
|
|
8
|
+
- Docs: https://docs.drip-apex.com
|
|
9
|
+
- CLI install and sign-in: https://docs.drip-apex.com/docs/cli/install-auth
|
|
10
|
+
- Command reference: https://docs.drip-apex.com/docs/cli/commands-output
|
|
11
|
+
|
|
12
|
+
Want Apex inside ChatGPT, Claude or Cursor without a terminal? Connect the hosted MCP server at `https://app.drip-apex.com/api/mcp` (OAuth). Setup: https://docs.drip-apex.com/docs/mcp/install-configure and the [`@drip-apex/mcp-server`](https://www.npmjs.com/package/@drip-apex/mcp-server) package.
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g @drip-apex/apex-cli
|
|
18
|
+
apex login
|
|
19
|
+
apex experiments list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g @drip-apex/apex-cli
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Install the CLI once, then call `apex` directly. `apex --help` and `apex schema --json` answer without network access. Do not run `npx @drip-apex/apex-cli@latest` for every command: npx asks the npm registry for the package before the CLI starts, so it prints nothing and hangs when the registry is slow or blocked, which is common in agent sandboxes. Update with `npm install -g @drip-apex/apex-cli@latest`.
|
|
29
|
+
|
|
30
|
+
## Authenticate
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
apex login
|
|
34
|
+
apex whoami
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`apex login` opens the default browser OAuth flow at Apex `/cli/login`. For
|
|
38
|
+
headless environments, use an existing API key:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
apex login --api-key apx_your_key_here
|
|
42
|
+
APEX_API_KEY=apx_your_key_here apex experiments list --json
|
|
43
|
+
```
|
|
2
44
|
|
|
3
45
|
## Choosing a workflow
|
|
4
46
|
|
|
@@ -50,32 +92,6 @@ change the stored login. Use `apex login --api-key apx_uk_...` for a headless
|
|
|
50
92
|
account login or `apex login --api-key apx_...` to store a shop key. The old
|
|
51
93
|
`apex login --user` spelling is a deprecated alias for `apex login`.
|
|
52
94
|
|
|
53
|
-
Command-line tools for Apex experiments, draft workspaces, GitOps pushes, QA
|
|
54
|
-
evidence, tracking checks, and agent handoffs.
|
|
55
|
-
|
|
56
|
-
## Install
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
npm install -g @drip-apex/apex-cli
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Install the CLI once, then call `apex` directly. `apex --help` and `apex schema --json` answer without network access. Do not run `npx @drip-apex/apex-cli@latest` for every command: npx asks the npm registry for the package before the CLI starts, so it prints nothing and hangs when the registry is slow or blocked, which is common in agent sandboxes. Update with `npm install -g @drip-apex/apex-cli@latest`.
|
|
63
|
-
|
|
64
|
-
## Authenticate
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
apex login
|
|
68
|
-
apex whoami
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
`apex login` opens the default browser OAuth flow at Apex `/cli/login`. For
|
|
72
|
-
headless environments, use an existing API key:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
apex login --api-key apx_your_key_here
|
|
76
|
-
APEX_API_KEY=apx_your_key_here apex experiments list --json
|
|
77
|
-
```
|
|
78
|
-
|
|
79
95
|
## Common usage
|
|
80
96
|
|
|
81
97
|
```bash
|
|
@@ -204,6 +220,8 @@ including every subcommand, argument, option, and alias.
|
|
|
204
220
|
- `apex workspace` — check out, preview, and publish draft workspace files.
|
|
205
221
|
- `apex goals` — manage conversion and revenue goals. Create/update accept `--page-id <id>` (UUID only, no lookup) or `--page <id-or-key>` (keys need `pages:read` for lookup); use one option.
|
|
206
222
|
- `apex flags` — manage feature flags.
|
|
223
|
+
- `apex forms` — track storefront forms and read form and checkout analytics: list, add, remove,
|
|
224
|
+
summary, fields, field, errors, sessions, label, merge, unmerge and detect. Needs the shop's form analytics switch.
|
|
207
225
|
- `apex surveys` — list, get, create, update, start, pause, complete, duplicate, and delete surveys.
|
|
208
226
|
Use `apex surveys list --status live` to filter, and `apex surveys create @survey.json`
|
|
209
227
|
or `apex surveys update <id> <body>` with inline JSON, `@file`, or a file path.
|
|
@@ -279,6 +297,18 @@ command inventory:
|
|
|
279
297
|
| `apex admin shops settings get --shop <uuid-or-domain> --key <key>` | Read one setting; unknown keys list the available registry keys. |
|
|
280
298
|
| `apex admin shops settings set --shop <uuid-or-domain> --key <key> --value <value>` | Resolve and pin the shop, then make an audited write. Booleans accept on/off/true/false; numbers must be finite; null clears nullable settings. Sensitive writes require `--confirm`; optional `--reason` and `--expected-version` preserve audit context and concurrency. |
|
|
281
299
|
|
|
300
|
+
## Consent setup warnings
|
|
301
|
+
|
|
302
|
+
`apex consent get`, `set`, and `off` include setup warnings in JSON output and print
|
|
303
|
+
them on stderr in human output. Custom consent without a getter waits for the site
|
|
304
|
+
to call `Drip.setConsent(true)`. A configured consent provider with consent mode off
|
|
305
|
+
does not gate tracking or storage.
|
|
306
|
+
|
|
307
|
+
`apex shops doctor` runs `unbound_hosts`, `dev_pollution`, `cmp_mismatch`,
|
|
308
|
+
`consent_gate`, `stale_served_config`, `goal_reachability`, `consent_rate`, and
|
|
309
|
+
`purchase_capture`, in that order. `consent_gate` warns about consent setup, passes
|
|
310
|
+
when the API returns no warnings, and skips older servers without warning support.
|
|
311
|
+
|
|
282
312
|
## Landing pages built outside Apex
|
|
283
313
|
|
|
284
314
|
A landing page is built in a checkout folder by any tool (Claude Code, Codex,
|
|
@@ -323,7 +353,7 @@ folder belongs to `apex experiments pull/plan/apply`, `landing-page.json` means
|
|
|
323
353
|
an `apex landing-pages` checkout, while `session.json`
|
|
324
354
|
means it is an `apex workspace checkout/status/publish` workspace. Keep the two
|
|
325
355
|
formats in different folders; when the wrong command is run, Apex points to the
|
|
326
|
-
matching status command.
|
|
356
|
+
matching status command. In a workspace folder, a checkout message goes in `src/mutations.json`.
|
|
327
357
|
|
|
328
358
|
## Page targeting: URL rules and Pages
|
|
329
359
|
|
|
@@ -360,6 +390,39 @@ In a pulled `targeting.json`, `url` is the expanded rule set and `authorUrl` is
|
|
|
360
390
|
the authored subset, always present. Edit `url` and `pages`; treat `authorUrl`
|
|
361
391
|
and `pageRules` as output.
|
|
362
392
|
|
|
393
|
+
## Checkout messages
|
|
394
|
+
|
|
395
|
+
A checkout message adds text to the Apex block in Shopify checkout, as a typed change on an A/B test arm. Add `[{ "action": "checkoutBlock", "checkoutBlock": { "heading": "Free returns for 30 days", "body": "Not the right fit? Send it back for free.", "tone": "info" } }]` to the arm's flat mutations.
|
|
396
|
+
|
|
397
|
+
The required `heading` is trimmed and must contain visible text in 1–120 characters. Optional `eyebrow`, `body` and `disclosure` allow up to 60, 500 and 300 characters. `tone` defaults to `info`; it also accepts `success`, `warning` or `critical`. `placement` accepts only `checkout`, the default. Unknown keys are refused at both levels. Omit deprecated `enabled`; `false` hides the message.
|
|
398
|
+
|
|
399
|
+
Use at most one message per arm (`duplicate_checkout_block`), in `variations/<slug>/mutations.json` for a pulled experiment or `src/mutations.json` for a workspace folder, never `url-blocks.json`. Messages cannot share a test with `commerce/post-purchase.json`, and personalizations refuse them. Omit `surface` and `checkoutBlock` from `targeting.json`; those retired keys return `409 checkout_mode_retired`.
|
|
400
|
+
|
|
401
|
+
Copy cannot state a money amount: a number next to a currency symbol, ISO code or currency word, or a percent next to a discount word such as off, save, sale or Rabatt. Apply returns `422 checkout_copy_states_money` (CLI exit 3). A plain percent only warns at launch.
|
|
402
|
+
|
|
403
|
+
Pause a running test before changing its message, run its QA checkout again, then resume. On paused or running tests, adding the first message to a test with no storefront change or removing the last message is refused (`checkout_exposure_owner_frozen`).
|
|
404
|
+
|
|
405
|
+
Messages may share an arm with DOM mutations, CSS, JS and commerce levers other than post-purchase. Combined tests count visitors on the storefront and show their storefront change only while Apex can confirm the message is live at checkout. Tests whose arms change only messages count visitors at checkout and show messages only to buyers who allow analytics, marketing and sale-of-data processing; QA testers must grant that consent too. Apex recommends a revenue primary goal for these tests. Control may carry a message, but it does not count as treatment work.
|
|
406
|
+
|
|
407
|
+
From nothing to a saved draft:
|
|
408
|
+
|
|
409
|
+
1. Run `apex login`, then `apex use <org>/<shop>`. Alternatively set `APEX_API_KEY` with `DRIP_ORG`/`DRIP_SHOP` or pass `--org`/`--shop`. With only `APEX_API_KEY`, `apex use` cannot persist context; a shop-scoped key needs no selection.
|
|
410
|
+
2. Run `apex experiments create --name "Checkout message" --page-url <url> --yes --json` and read `.data.experiment.id`. A fresh draft has `control` and `variation-b` arms.
|
|
411
|
+
3. Run `apex experiments pull <id> --out <folder> --json`.
|
|
412
|
+
4. Put the entry above in `<folder>/variations/variation-b/mutations.json`; leave `variations/control/mutations.json` as `[]`.
|
|
413
|
+
5. Run `apex experiments plan <folder> --json`. Blocking issues return exit 3; plan lists the rules above except apply-only refusals.
|
|
414
|
+
6. Run `apex experiments apply <folder> --json`. If the test already holds QA approval, add `--accept-qa-invalidation`; without it, exit 4 requests confirmation.
|
|
415
|
+
7. Apply stores the entry with `"placement": "checkout"` added; run `apex experiments apply <folder> --sync` so the folder matches the stored bytes. `apex experiments status <folder> --json` shows the QA checklist and file state, not launch blockers; the Apex dashboard shows those. The CLI validates file names; the server validates contents. `apex schema --json` prints the contract offline.
|
|
416
|
+
|
|
417
|
+
Before launch:
|
|
418
|
+
|
|
419
|
+
- Use Shopify Plus (development stores with "development" or "plus" in their plan name also pass), with the Apex app connected.
|
|
420
|
+
- Ask your Apex contact at Drip for the Checkout extension tests add-on and to switch on checkout tests for the store. The Apex team sets both.
|
|
421
|
+
- Add the Apex Checkout Experiment block in the Shopify checkout editor, normally at the information step. Apex cannot see placement directly; an unplaced block appears as a missing QA checkout. If the store offers Shop Pay, turn on "Include block in Shop Pay" for the block.
|
|
422
|
+
- Use production or the store's active environment and keep the store's checkout messages within Shopify's size budget.
|
|
423
|
+
- Open each message arm's QA link in a real checkout: `apex preview <id> <variation-id> --json --no-open` prints a signed link (treat it as a secret), or use "Preview links" in the experiment's Check panel. Add a product, go to checkout, allow analytics, marketing and sale-of-data processing if the store asks, and wait for the message. The receipt must match the current message text and test epoch. A customer approval link does not count.
|
|
424
|
+
- Mark QA done and launch in the dashboard. API and CLI launch are unavailable. Apex confirms delivery after launch and pauses the test if it cannot confirm the message within 30 minutes.
|
|
425
|
+
|
|
363
426
|
## Push config format
|
|
364
427
|
|
|
365
428
|
Run `apex push -c <config>` to load a JavaScript or TypeScript config. The
|
|
@@ -452,12 +515,13 @@ experiments reject these metadata changes.
|
|
|
452
515
|
|
|
453
516
|
Experiment references accept an ID, slug, or test key (for example `BIO-085`). Test keys resolve within the selected shop; use `--shop <shop-id>` to change it. Bare lowercase references remain slugs.
|
|
454
517
|
|
|
455
|
-
Price, shipping, offer, and post-purchase drafts use typed `commerce
|
|
518
|
+
Price, shipping, offer, discount-code, and post-purchase drafts use typed `commerce/price.json`, `commerce/shipping.json`, `commerce/offer.json`, `commerce/discount-codes.json`, and `commerce/post-purchase.json` files. Each file defines the lever once and maps every variation to values or `sameAsControl`; its `serverOwned` section is informational and read-only. A checkout message cannot share a test with `commerce/post-purchase.json`.
|
|
456
519
|
|
|
457
520
|
Filesystem apply preserves authored local bytes by default. Use
|
|
458
521
|
`apex experiments apply <folder> --sync` to refresh them from stored server bytes.
|
|
459
|
-
The receipt's `files`
|
|
522
|
+
The receipt's `files` includes per-file `normalizations` and `submitted_sha256` (null for unsubmitted files), alongside SHA-256 digests for every stored pull path; `synced` reports
|
|
460
523
|
whether a full refresh succeeded. Server-owned QA and launch files are healed.
|
|
524
|
+
JSON bodies and checkout JSON files accept a leading UTF-8 BOM, including PowerShell-written files.
|
|
461
525
|
Create/get return `dashboard_url`; apply returns `dashboardUrl`. These links
|
|
462
526
|
switch the signed-in dashboard user's active shop before opening the experiment.
|
|
463
527
|
|
|
@@ -644,6 +708,37 @@ store ID (or null), invitation results and partial delivery status.
|
|
|
644
708
|
|
|
645
709
|
Upload CSV or JSON exports with `apex results import --file results.csv --dry-run`. Apex suggests column and outcome-value mappings from the file; use repeated `--map 'Column=field'` and `--outcome-value 'Source value=won|lost|inconclusive'` overrides, then pass `--yes` for non-interactive confirmation. Files are inspected and previewed before any rows are written. `--source <name>` applies to the confirmed rows; the preview shows the uploaded file name.
|
|
646
710
|
|
|
711
|
+
### Read past test results
|
|
712
|
+
|
|
713
|
+
`apex results list [--source import|native|all] [--limit <n>] [--all] [--json]` lists past results for the selected shop (default source `all`, page size 50, maximum 200). Use `--all` to follow every page. The table shows legacy ID (or UUID), title, outcome, metric, lift, sample size, dates, and source. Empty lists print `No test results.`
|
|
714
|
+
|
|
715
|
+
`apex results get <legacy-id-or-id> [--json]` opens a result by legacy ID, test key, or UUID, including its full learning, confidence, dates, page, and device. Missing results exit with code 1 through the existing API failure path. Both commands use shop or user keys with `experiments:read` and verify each row belongs to the selected shop. Imports show their source name and original date range, falling back to import time; native results show source `apex` and creation time.
|
|
716
|
+
|
|
717
|
+
`apex results delete <legacy-id-or-id> [--yes] [--json]` permanently removes one imported result with `experiments:write`. It first reads the result and, outside `--json`, prints its title, outcome, dates, source, and legacy ID; with `--json --yes` it removes without printing a preview, so check the ID first (for example with `apex results get`). Native results are refused locally (exit 3). Confirm the prompt or pass `--yes`; non-TTY callers without `--yes` receive exit 4 with the exact rerun hint. Removed results cannot be restored in Apex; the full record remains in the audit log. JSON output wraps the API `{ data }` response and verifies the echoed shop.
|
|
718
|
+
|
|
719
|
+
JSON uses the standard CLI envelope: its `data` contains `{ data, pagination }` for lists (merged rows and final pagination with `--all`) or `{ data: result }` for a single result. Invalid `--source` or `--limit` exits 3 before an HTTP request.
|
|
720
|
+
|
|
647
721
|
### Tracking health
|
|
648
722
|
|
|
649
723
|
`apex tracking health [--json]` reads one tracking-health report for the current shop: every check with pass, warn, fail or unknown, a plain summary and the deciding numbers, plus each running test's first-hour verdict and traffic split overall and per device (`--json` carries visitors per arm per day). Exit code 0 is pass, 1 is warn or fail, 3 is unknown.
|
|
724
|
+
|
|
725
|
+
### Forms
|
|
726
|
+
|
|
727
|
+
`apex forms list` lists tracked forms and their collection status. Add a storefront form with
|
|
728
|
+
`apex forms add newsletter --url https://shop.example/newsletter --selector '#newsletter' --complete-on-call`.
|
|
729
|
+
Choose exactly one of `--complete-on-goal <goal>`, `--complete-on-page <path>`, or `--complete-on-call`.
|
|
730
|
+
`apex forms remove <key>` soft-removes it. Checkout is tracked automatically on Shopify.
|
|
731
|
+
|
|
732
|
+
Read analytics with `apex forms summary <key>`, `apex forms fields <key>`,
|
|
733
|
+
`apex forms field <key> <identity>`, `apex forms errors <key>`, or `apex forms sessions <key>`.
|
|
734
|
+
Reads accept `--range`, `--split`, `--device`, `--country`, `--include-qa`, and `--include-removed`.
|
|
735
|
+
Sessions also accept `--outcome all|completed|abandoned|in_progress`, `--field`, `--with-replay`, `--limit`, and `--cursor`.
|
|
736
|
+
Fields, errors, and sessions accept `--format csv|json|table`. Every command accepts `--json`.
|
|
737
|
+
Unavailable values print `–` (empty in CSV); `*` marks a denominator below 50.
|
|
738
|
+
|
|
739
|
+
`apex forms label <key> <identity> <text>` attaches a label; `apex forms label <key> <identity> --clear` clears it.
|
|
740
|
+
`apex forms merge <key> <old> <new>` combines an old identity with its replacement;
|
|
741
|
+
`apex forms unmerge <key> <identity>` undoes it. `apex forms detect <url>` scans a shop page without returning values.
|
|
742
|
+
`apex tracking manifest [manifest]` includes the shop's form definitions in a schemaVersion 1 manifest.
|
|
743
|
+
|
|
744
|
+
Flag goals: `apex flags create --key banner --name "Banner" --goal <uuid> --goal <uuid> --primary-goal <uuid>`. The same options work on `flags update <id>`; `--goal` replaces the attached set. `flags get <id>` prints goals and marks the primary goal. JSON input can clear the set with `{"goal_ids":[]}`.
|