@koda-sl/baker-cli 0.286.0-dev.93be96120 → 0.290.1
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/README.md +33 -29
- package/dist/{chunk-LN5O53BG.js → chunk-V7BIRLPU.js} +4 -4
- package/dist/chunk-V7BIRLPU.js.map +1 -0
- package/dist/cli.js +1776 -687
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-LN5O53BG.js.map +0 -1
package/README.md
CHANGED
|
@@ -1256,10 +1256,15 @@ baker analytics tracking # do the ad URLs carry the campaign, a
|
|
|
1256
1256
|
baker analytics tracking --platform meta # the same for one platform, read from their own ad account
|
|
1257
1257
|
baker analytics map --platform google --set kw=keyword # name a parameter, seen or not yet
|
|
1258
1258
|
baker analytics map --platform google --remove kw # take that answer back
|
|
1259
|
-
baker analytics conversions # what counts
|
|
1259
|
+
baker analytics conversions # what counts, what each produced, and which Forms count nothing
|
|
1260
1260
|
baker analytics conversions --candidates # everything these pages do, and which of it is counted
|
|
1261
|
+
baker analytics conversions --flow contact # one Form's endings as event keys, traffic or not
|
|
1261
1262
|
baker analytics conversions --event page:request_demo --name "Demo requested"
|
|
1263
|
+
baker analytics conversions --event page:a --event submit:b --name "Lead" # both, as one number
|
|
1264
|
+
baker analytics conversions --event page:a --count-mode every_time # re-mode, keeping its name
|
|
1265
|
+
baker analytics conversions --rename "Lead form" --to "Lead" # merge two into one row
|
|
1262
1266
|
baker analytics conversions --remove page:request_demo
|
|
1267
|
+
baker analytics conversions --remove-name "Lead"
|
|
1263
1268
|
baker analytics delivery --page 2 # the next page of a long list
|
|
1264
1269
|
baker analytics submissions --flow contact # every attempt at a Form, delivered or not
|
|
1265
1270
|
```
|
|
@@ -1274,7 +1279,11 @@ Shared flags: `--days <n>` (default 30) or `--start-date` / `--end-date` (`YYYY-
|
|
|
1274
1279
|
|
|
1275
1280
|
**Paging the list reports.** `people`, `submissions` and `delivery` are lists of individual things rather than breakdowns — `delivery` and `submissions` are the ones the CLI exposes, `people` backs the People section of the dashboard's landing Analytics screen over the same wire — and only they take `--page <n>` (1-based) and `--page-size <n>` (up to 200, default 50). The response carries `pageInfo` with `hasMore` — when it is true there **are** more rows, so a total must never be reported from one page. Pass neither flag and a list comes back at the size it always did.
|
|
1276
1281
|
|
|
1277
|
-
**A conversion is a company-level named event, not a property of a Form.** `baker analytics conversions` is the only place "what counts" is decided, and an empty `definitions` list means every conversion number in every other report is zero — not because nobody converted, but because nothing is named as an outcome and Baker never guesses which event is the point of a page. `--candidates` lists every event these pages actually produced — each Form step and trigger, every `data-baker-*` event, every outbound destination — with volume and whether it is already counted; that list is where an event key comes from, so never invent one. `--event <key> --name "Booked a call"` starts counting it **immediately and retroactively**: the whole stored history is rescored, so naming the right event today also fixes last month. Nothing here is staged and publishing is not involved. Two events given the same `--name` become one row and one number, which is how a call booked on three different Forms reads as one outcome. `--count-mode every_time` is for the outcomes people genuinely repeat (a guide downloaded twice is two downloads); the default counts once per visit.
|
|
1282
|
+
**A conversion is a company-level named event, not a property of a Form.** `baker analytics conversions` is the only place "what counts" is decided, and an empty `definitions` list means every conversion number in every other report is zero — not because nobody converted, but because nothing is named as an outcome and Baker never guesses which event is the point of a page. `--candidates` lists every event these pages actually produced — each Form step and trigger, every `data-baker-*` event, every outbound destination — with volume and whether it is already counted; that list is where an event key comes from, so never invent one. `--event <key> --name "Booked a call"` starts counting it **immediately and retroactively**: the whole stored history is rescored, so naming the right event today also fixes last month. Nothing here is staged and publishing is not involved. Two events given the same `--name` become one row and one number, which is how a call booked on three different Forms reads as one outcome. `--count-mode every_time` is for the outcomes people genuinely repeat (a guide downloaded twice is two downloads); the default counts once per visit.
|
|
1283
|
+
|
|
1284
|
+
**The name is the grouping, so the CLI defends it.** Repeat `--event` to count several events under one `--name` in a single call; `--rename "<old>" --to "<new>"` renames every event under an outcome, and renaming *onto* a name that already exists **merges** them into one row and one number — the fix for a company whose Forms each invented their own word for the same thing. `--remove-name` drops an outcome entirely, `--remove` a single event key. A name that differs from one already counted only by case, accent, punctuation or a plural is **refused**: Baker groups by exact name, so "Booked a Call" beside "Booked a call" is a number split in half with both halves plausible. Every answer leads with the names already in use, and a company that has named nothing gets a standard set to start from — after which the rule is reuse, in that company's own language.
|
|
1285
|
+
|
|
1286
|
+
**`--flow <slug>` reads it from the Form's side**, listing that Form's endings already spelled as event keys with the name each is counted under, built from the Form's own file so it works before a single visitor arrives. With no `--flow`, the answer carries `flows[]` — every Form in the workspace with the step that counts for it, or nothing — which exists nowhere else: on every other report a Form that counts nothing looks exactly like a Form nobody converts on. The list of definitions is read from the store rather than from the reporting mirror, so an outcome named a second ago is in the reply that named it.
|
|
1278
1287
|
|
|
1279
1288
|
**Campaign parameters are per platform, and so are the numbers.** `baker analytics ads` returns `adPlatformTraffic` (visits, conversions and *tagged* visits for each of the nine platforms), `adParams` for the platform in `--platform` only, and `adParamsUnattributed` for names arriving on visits with no click id and no recognisable source. Read `adPlatformTraffic` first: a platform with visits and zero tagged visits has untagged ad URLs, and no mapping can fix that from Baker's side. `baker analytics map` needs `--platform` for any change, accepts a parameter name **nobody has sent yet** — which is how a tracking template is configured before its campaign runs — and takes an answer back with `--remove`. `--set <name>=ignore` says a parameter is not campaign information at all, so Baker stops storing it and stops listing it.
|
|
1280
1289
|
|
|
@@ -1311,45 +1320,37 @@ Data is retained for 400 days; a window reaching further back comes back with a
|
|
|
1311
1320
|
|
|
1312
1321
|
### A/B tests (`baker experiment`)
|
|
1313
1322
|
|
|
1314
|
-
Two versions of one landing page, split 50/50 at the edge, decided by a verdict rather than by two rates somebody reads.
|
|
1323
|
+
Two versions of one landing page, split 50/50 at the edge, read on one of the conversions the company already counts, and decided by a person on a verdict rather than by two rates somebody reads.
|
|
1315
1324
|
|
|
1316
1325
|
```bash
|
|
1317
1326
|
baker experiment plan --landing oferta --variant oferta--1 # FIRST — can this page settle the question at all?
|
|
1318
|
-
baker experiment plan --landing oferta --variant oferta--1 --goal
|
|
1319
|
-
baker experiment plan --landing oferta --variant oferta--1 --days 21 # what could 21 days settle?
|
|
1327
|
+
baker experiment plan --landing oferta --variant oferta--1 --goal submit:book-a-call
|
|
1320
1328
|
baker experiment start --landing oferta --variant oferta--1 --because "60% of visitors never scroll past the hero" --change "put the price in the headline"
|
|
1329
|
+
baker experiment update --id temp_exp_1 --goal submit:book-a-call # a staged test can still change what it measures
|
|
1330
|
+
baker experiment update --id a3f91c2b --because "…" # a live one can only change its wording
|
|
1321
1331
|
baker experiment status # the verdict on every test
|
|
1322
|
-
baker experiment status --id a3f91c2b --full # one test, with the posteriors behind it
|
|
1323
|
-
baker experiment
|
|
1324
|
-
baker experiment
|
|
1325
|
-
baker experiment
|
|
1332
|
+
baker experiment status --id a3f91c2b --full # one test, with the confidence and posteriors behind it
|
|
1333
|
+
baker experiment history --landing oferta # every finished test on a page: claim, numbers, decision, learning
|
|
1334
|
+
baker experiment pause --id a3f91c2b # everyone sees the original for now
|
|
1335
|
+
baker experiment resume --id a3f91c2b # the split picks up with the same sides
|
|
1336
|
+
baker experiment finish --id a3f91c2b --keep variant --learning "…" # end it now; say which version stays and what it taught
|
|
1337
|
+
baker experiment cancel --id a3f91c2b # call it off: staged → gone, live → ended, original kept
|
|
1338
|
+
baker experiment fold # make the page's own content the version that was kept
|
|
1326
1339
|
```
|
|
1327
1340
|
|
|
1328
|
-
**A page has variants. A variant is never a page.** The variant is a real built folder at `src/pages/oferta--1/`, so it gets every quality gate a page gets — which matters, because it is about to be shown to half the client's visitors. What it does not get is a public address: it is absent from the Landings list and the sitemap,
|
|
1341
|
+
**A page has variants. A variant is never a page.** The variant is a real built folder at `src/pages/oferta--1/`, so it gets every quality gate a page gets — which matters, because it is about to be shown to half the client's visitors. What it does not get is a public address: it is absent from the Landings list and the sitemap, names the page's URL as its canonical, and `/oferta--1/` returns **404** at the edge. It is as indexable as the page it is a version of, deliberately — half the crawls of `/oferta/` are served the variant, so a `noindex` on it is a `noindex` on the live page. Both versions answer at `/oferta/`. Assignment happens while the HTML is served, so there is no flicker and nothing for an ad blocker to suppress, and the split is a path rewrite and never a redirect. To look at one side deliberately, `/oferta/?_bkr_preview=a` and `?_bkr_preview=b` serve it exactly, with no assignment and no cookie.
|
|
1329
1342
|
|
|
1330
|
-
**
|
|
1343
|
+
**The goal is one event, named by its key.** `--goal submit:book-a-call` — the same vocabulary the event stream uses (`form:<flow>:<node>:<trigger>`, `submit:<flow>`, `page:<name>`, `exit:<host>`), and `baker analytics conversions --candidates` lists the keys these pages produce. Not a conversion *name*, which groups several keys: a variant that swaps the page's Form for a shorter one converts on a different key, and a name would either count both endings as one outcome or count the new version as never converting at all — `--variant-goal` gives the new version its own event when it has one. The goal is fixed for the life of the test and the verdict is read on it alone. Every other conversion the company counts comes back under `secondary` on every result, with the same interval and a one-word reading, and decides nothing. A conversion counts for a visitor wherever it happens after they were shown a version — on the page, on another page, in a delivered lead, or in a deal the CRM posted a week later by email.
|
|
1331
1344
|
|
|
1332
|
-
|
|
1345
|
+
**Nothing ends a test on its own.** `status` returns a verdict; `finish --keep original|variant` is the decision, and it takes effect within seconds with nothing to publish. Ending a `keep_running` test records `inconclusive`. Going against the verdict is allowed and recorded. `pause` and `resume` switch the split off and on without losing the test; `cancel` is `finish --keep original` for a live test and takes a staged one back off the session. `update` changes what a test *says* — `--because`, `--change`, `--evidence` (repeatable, `source:what it showed`, optionally `|link`) — at any time, writes down what a finished one taught (`--learning`), and changes what it *measures* — `--goal`, `--lift`, `--expect` — only while it is still staged.
|
|
1333
1346
|
|
|
1334
|
-
|
|
1347
|
+
**A finished test is a record.** Its counts are frozen when it ends, so it reads the same next year as it did that day; its `learning` is what it taught, in a person's words. `history` returns every finished test — the claim, what was different, the numbers with their interval and confidence, what was kept and whether that went against the numbers, whether the belief held, and the learning — and `plan` returns the same entries as `pastTests` for the page it sizes, so a hypothesis is chosen against the page's record rather than in ignorance of it.
|
|
1335
1348
|
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
| `--goal` | Counts |
|
|
1339
|
-
|---|---|
|
|
1340
|
-
| `leads` (default) | Whatever this company already marks as a conversion |
|
|
1341
|
-
| `leads:<form>` | The same, one Form only |
|
|
1342
|
-
| `event:<name>` | An event the page declares for itself (`data-baker-click="request_demo"`) |
|
|
1343
|
-
| `event:<name>/<key>=<value>` | The same, narrowed by one of its own properties |
|
|
1344
|
-
| `click` / `click:<host>` | Leaving the site, optionally for one destination |
|
|
1349
|
+
**The confidence is anytime-valid.** `--full` carries `evidence.confidence`, how sure the numbers are that the two versions differ at all, read off the same construction as the verdict — so it holds however often it is read, and a winner is called exactly when it crosses 95%. Beside it, `probabilityVariantBetter` is the Bayesian chance the new variant is the better one, which is for printing and never for deciding.
|
|
1345
1350
|
|
|
1346
|
-
`baker
|
|
1351
|
+
**Finishing with the variant takes two beats, and `fold` is the second.** `finish --keep variant` records which version is live and the edge serves it to everyone at once. `baker experiment fold` moves that version into the page's own folder, archives the one that lost as a self-contained snapshot under `src/_variants/<page id>/<n>/`, and deletes the variant folder. Until it runs, the page is served by a rewrite and cannot be tested again. Run `fold` with no arguments after any test ends, then publish; Baker drops the rewrite by itself once the new pages are live.
|
|
1347
1352
|
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
**`--abandon` overrides the verdict.** It stops the test, keeps the original page and records no result — the only way to end one that has not concluded, and it applies even when the test *has*. That is deliberate: the only outcome it can disagree with is a variant win, so deferring to the verdict would mean a flag asking to keep the original page handed all the traffic to the alternative instead. The response reports `discardedVerdict` when a real finding was thrown away.
|
|
1351
|
-
|
|
1352
|
-
Nothing goes live until the session is published: starting stages onto the session, and the person publishing is the review of the variant page.
|
|
1353
|
+
**`plan` before building anything.** At a 3% conversion rate a +20% lift needs roughly 14,000 visitors *per variant*; `plan` says how long that is at this page's traffic, lists what this page's visitors actually went on to do, and what a 14, 28, 56 or 90-day window could settle. The duration is a guide and never a finish line — the test ends when the numbers are clear, and a page with no traffic yet still runs, sized on a stand-in that `warning` names (`--baseline 0.05` states the rate to expect). What `plan` refuses is what cannot be measured: no conversion defined, or a goal the page has demonstrably never produced. `--lift` sets the smallest lift worth detecting (default `0.2`) — halving it roughly quadruples the traffic needed.
|
|
1353
1354
|
|
|
1354
1355
|
### Google Analytics 4 (`baker ga4`)
|
|
1355
1356
|
|
|
@@ -5834,9 +5835,12 @@ Creates a new **version of a page** for an A/B test. It **imports the page's sec
|
|
|
5834
5835
|
|
|
5835
5836
|
```bash
|
|
5836
5837
|
baker landing variant oferta --fork Hero.astro
|
|
5837
|
-
baker landing variant oferta --fork Hero.astro
|
|
5838
|
+
baker landing variant oferta --fork Hero.astro --fork Proof.astro --because "60% of visitors never scroll past the hero" --change "put the price in the headline"
|
|
5839
|
+
baker landing variant oferta --fork Hero.astro,Proof.astro --because "…" --change "…"
|
|
5838
5840
|
```
|
|
5839
5841
|
|
|
5842
|
+
- **`--fork` takes several components, repeated or comma-separated.** Both forms keep every name.
|
|
5843
|
+
|
|
5840
5844
|
- **You do not choose the slug.** It is `<page>--<n>`, numbered per page and never reused — so it cannot collide with an archived version, and it cannot merge with an older variant's analytics history. `--` is also what every tool decides by: which analytics id the page stamps, whether the sitemap lists it, and whether the edge answers the URL. It replaced a `<page>-b` convention that nine live pages across the fleet would have been misread by.
|
|
5841
5845
|
|
|
5842
5846
|
- **Sharing, not copying, is what keeps the test honest.** A duplicated page drifts from its control on every later edit — a price, a typo, a new testimonial — and the test then reports that drift plus the hypothesis as one result. A shared section is one file, so an edit reaches both arms at once. Baker follows the sharing too: both pages redeploy together, and both are re-critiqued when a shared section changes.
|
|
@@ -16,9 +16,9 @@ import {
|
|
|
16
16
|
shouldEscalate
|
|
17
17
|
} from "./chunk-DZUVUGEP.js";
|
|
18
18
|
|
|
19
|
-
//
|
|
19
|
+
// ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
|
|
20
20
|
var require_safe_stable_stringify = __commonJS({
|
|
21
|
-
"
|
|
21
|
+
"../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
|
|
22
22
|
"use strict";
|
|
23
23
|
var { hasOwnProperty } = Object.prototype;
|
|
24
24
|
var stringify = configure2();
|
|
@@ -1092,7 +1092,7 @@ function resolveAdaptFormats(params) {
|
|
|
1092
1092
|
return params.formats ?? [];
|
|
1093
1093
|
}
|
|
1094
1094
|
|
|
1095
|
-
//
|
|
1095
|
+
// ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
|
|
1096
1096
|
var import__ = __toESM(require_safe_stable_stringify(), 1);
|
|
1097
1097
|
var configure = import__.default.configure;
|
|
1098
1098
|
var wrapper_default = import__.default;
|
|
@@ -9153,4 +9153,4 @@ export {
|
|
|
9153
9153
|
defaultRegistry,
|
|
9154
9154
|
createEngineFromEnv
|
|
9155
9155
|
};
|
|
9156
|
-
//# sourceMappingURL=chunk-
|
|
9156
|
+
//# sourceMappingURL=chunk-V7BIRLPU.js.map
|