@koda-sl/baker-cli 0.355.0 → 0.357.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/README.md +7 -2
- package/dist/{chunk-4HRJQGVW.js → chunk-H3SAAHZA.js} +2 -1
- package/dist/chunk-H3SAAHZA.js.map +1 -0
- package/dist/cli.js +102 -12
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4HRJQGVW.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
clipDurationsFor,
|
|
29
29
|
clipParamRecipe,
|
|
30
30
|
clipProfileFor,
|
|
31
|
+
coercePathUrlToUrl,
|
|
31
32
|
collectAssetRefLikes,
|
|
32
33
|
createEngineFromEnv,
|
|
33
34
|
defaultRegistry,
|
|
@@ -68,7 +69,7 @@ import {
|
|
|
68
69
|
validateCanvasDeep,
|
|
69
70
|
withoutCastName,
|
|
70
71
|
ytDlpBlockSignal
|
|
71
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-H3SAAHZA.js";
|
|
72
73
|
import {
|
|
73
74
|
csvOrJson,
|
|
74
75
|
daysAgoIso,
|
|
@@ -36809,7 +36810,7 @@ function rewriteTarget(value, workspaceRoot) {
|
|
|
36809
36810
|
}
|
|
36810
36811
|
return null;
|
|
36811
36812
|
}
|
|
36812
|
-
function
|
|
36813
|
+
function normalizeCanvasPaths(canvas, canvasDir, workspaceRoot) {
|
|
36813
36814
|
if (!canvas || typeof canvas !== "object") return { canvas, rewrites: [] };
|
|
36814
36815
|
const c = canvas;
|
|
36815
36816
|
if (!Array.isArray(c.nodes)) return { canvas, rewrites: [] };
|
|
@@ -36822,6 +36823,10 @@ function normalizeAbsoluteCanvasPaths(canvas, canvasDir, workspaceRoot) {
|
|
|
36822
36823
|
const params = n.params;
|
|
36823
36824
|
if (!params || typeof params !== "object") return node;
|
|
36824
36825
|
const nodeId = typeof n.id === "string" ? n.id : "?";
|
|
36826
|
+
if (n.type === "ingest" && params.source === "path" && looksLikeHttpUrl(params.path)) {
|
|
36827
|
+
rewrites.push({ nodeId, param: "source", from: "path", to: "url" });
|
|
36828
|
+
return { ...node, params: coercePathUrlToUrl(params) };
|
|
36829
|
+
}
|
|
36825
36830
|
const key = n.type === "ingest" && params.source === "path" ? "path" : n.type === "hyperframe_render" ? "composition" : null;
|
|
36826
36831
|
if (!key) return node;
|
|
36827
36832
|
const target2 = rewriteTarget(params[key], root);
|
|
@@ -36832,11 +36837,11 @@ function normalizeAbsoluteCanvasPaths(canvas, canvasDir, workspaceRoot) {
|
|
|
36832
36837
|
});
|
|
36833
36838
|
return rewrites.length === 0 ? { canvas, rewrites } : { canvas: { ...canvas, nodes }, rewrites };
|
|
36834
36839
|
}
|
|
36835
|
-
async function
|
|
36840
|
+
async function healCanvasPaths(filePath, canvas) {
|
|
36836
36841
|
const canvasDir = path5.dirname(filePath);
|
|
36837
36842
|
const workspaceRoot = findWorkspaceRoot(canvasDir);
|
|
36838
36843
|
if (!workspaceRoot) return { canvas, rewrites: [], text: null };
|
|
36839
|
-
const normalized =
|
|
36844
|
+
const normalized = normalizeCanvasPaths(canvas, canvasDir, workspaceRoot);
|
|
36840
36845
|
if (normalized.rewrites.length === 0) return { ...normalized, text: null };
|
|
36841
36846
|
const text2 = `${JSON.stringify(normalized.canvas, null, 2)}
|
|
36842
36847
|
`;
|
|
@@ -41778,12 +41783,12 @@ async function executeCanvasRun(opts) {
|
|
|
41778
41783
|
}
|
|
41779
41784
|
const attemptedSlug = creativeSlugFromCanvasPath(filePath);
|
|
41780
41785
|
if (attemptedSlug) await clearCreativeDirty(attemptedSlug);
|
|
41781
|
-
const healed = await
|
|
41786
|
+
const healed = await healCanvasPaths(filePath, parsed);
|
|
41782
41787
|
parsed = healed.canvas;
|
|
41783
41788
|
const canvasText = healed.text ?? raw;
|
|
41784
41789
|
if (healed.rewrites.length > 0) {
|
|
41785
41790
|
process.stderr.write(
|
|
41786
|
-
`[canvas] rewrote ${healed.rewrites.length}
|
|
41791
|
+
`[canvas] rewrote ${healed.rewrites.length} asset reference(s) in the canvas file so it says what runs (absolute paths \u2192 canvas-relative, a URL in an ingest path \u2192 source "url"):
|
|
41787
41792
|
${describeRewrites(healed.rewrites)}
|
|
41788
41793
|
`
|
|
41789
41794
|
);
|
|
@@ -45376,7 +45381,7 @@ var validateCommand = defineCommand118({
|
|
|
45376
45381
|
`);
|
|
45377
45382
|
process.exit(2);
|
|
45378
45383
|
}
|
|
45379
|
-
const healed = await
|
|
45384
|
+
const healed = await healCanvasPaths(filePath, parsed);
|
|
45380
45385
|
parsed = healed.canvas;
|
|
45381
45386
|
parsed = resolveRelativeCanvasPaths(parsed, path28.dirname(filePath));
|
|
45382
45387
|
let styleProjection = "not_applicable";
|
|
@@ -47295,6 +47300,80 @@ async function declarationsOf(root, files) {
|
|
|
47295
47300
|
return sources.flatMap(eventDeclarationsIn);
|
|
47296
47301
|
}
|
|
47297
47302
|
|
|
47303
|
+
// src/commands/experiment/readout.ts
|
|
47304
|
+
function isoMoment(ms) {
|
|
47305
|
+
return ms === null ? null : new Date(ms).toISOString();
|
|
47306
|
+
}
|
|
47307
|
+
function isoDay2(ms) {
|
|
47308
|
+
return ms === null ? null : new Date(ms).toISOString().slice(0, 10);
|
|
47309
|
+
}
|
|
47310
|
+
function compactArm(arm) {
|
|
47311
|
+
return { visitors: arm.visitors, conversions: arm.conversions, rate: Math.round(arm.rate * 1e4) / 1e4 };
|
|
47312
|
+
}
|
|
47313
|
+
function compactMetric(metric) {
|
|
47314
|
+
return {
|
|
47315
|
+
name: metric.name,
|
|
47316
|
+
reading: metric.reading,
|
|
47317
|
+
control: metric.control.conversions,
|
|
47318
|
+
variant: metric.variant.conversions
|
|
47319
|
+
};
|
|
47320
|
+
}
|
|
47321
|
+
function fullArm(arm) {
|
|
47322
|
+
return {
|
|
47323
|
+
...arm,
|
|
47324
|
+
...arm.snapshotCapturedAt === void 0 ? {} : { snapshotCapturedAt: isoMoment(arm.snapshotCapturedAt) }
|
|
47325
|
+
};
|
|
47326
|
+
}
|
|
47327
|
+
function statusReadout(row, { full, now }) {
|
|
47328
|
+
const decisionWhen = {
|
|
47329
|
+
earliestDecisionAt: isoDay2(row.earliestDecisionAt),
|
|
47330
|
+
...row.earliestDecisionAt === null ? {} : { earliestDecisionIn: describeWait(row.earliestDecisionAt, now) }
|
|
47331
|
+
};
|
|
47332
|
+
const moments = {
|
|
47333
|
+
startedAt: isoMoment(row.startedAt),
|
|
47334
|
+
pausedAt: isoMoment(row.pausedAt),
|
|
47335
|
+
finishedAt: isoMoment(row.finishedAt)
|
|
47336
|
+
};
|
|
47337
|
+
if (full) {
|
|
47338
|
+
return {
|
|
47339
|
+
...row,
|
|
47340
|
+
...moments,
|
|
47341
|
+
...decisionWhen,
|
|
47342
|
+
control: fullArm(row.control),
|
|
47343
|
+
variant: fullArm(row.variant)
|
|
47344
|
+
};
|
|
47345
|
+
}
|
|
47346
|
+
return {
|
|
47347
|
+
experimentId: row.experimentId,
|
|
47348
|
+
landingSlug: row.landingSlug,
|
|
47349
|
+
variantSlug: row.variantSlug,
|
|
47350
|
+
status: row.status,
|
|
47351
|
+
verdict: row.verdict,
|
|
47352
|
+
summary: row.summary,
|
|
47353
|
+
...row.winner === null ? {} : { winner: row.winner },
|
|
47354
|
+
...row.invalidReason === null ? {} : { invalidReason: row.invalidReason },
|
|
47355
|
+
stillNeeded: row.stillNeeded,
|
|
47356
|
+
...decisionWhen,
|
|
47357
|
+
willNotConclude: row.willNotConclude,
|
|
47358
|
+
control: compactArm(row.control),
|
|
47359
|
+
variant: compactArm(row.variant),
|
|
47360
|
+
secondary: row.secondary.map(compactMetric),
|
|
47361
|
+
hypothesisStatement: row.hypothesisStatement,
|
|
47362
|
+
minDetectableRelativeLift: row.minDetectableRelativeLift,
|
|
47363
|
+
goal: row.goal,
|
|
47364
|
+
...row.variantGoal === null ? {} : { variantGoal: row.variantGoal },
|
|
47365
|
+
goalLabel: row.goalLabel,
|
|
47366
|
+
...moments,
|
|
47367
|
+
...row.status === "finished" ? {
|
|
47368
|
+
survivor: row.survivor,
|
|
47369
|
+
hypothesisOutcome: row.hypothesisOutcome,
|
|
47370
|
+
fold: row.fold,
|
|
47371
|
+
learning: row.learning,
|
|
47372
|
+
endReason: row.endReason
|
|
47373
|
+
} : {}
|
|
47374
|
+
};
|
|
47375
|
+
}
|
|
47376
|
+
|
|
47298
47377
|
// src/commands/experiment/update.ts
|
|
47299
47378
|
function buildUpdateRequest(args5, rawArgs) {
|
|
47300
47379
|
const expect = args5.expect === void 0 ? void 0 : String(args5.expect);
|
|
@@ -47536,18 +47615,26 @@ registerSchema({
|
|
|
47536
47615
|
args: {
|
|
47537
47616
|
id: { type: "string", description: "One test, by its id", required: false },
|
|
47538
47617
|
landing: LANDING_FILTER_ARG,
|
|
47539
|
-
full: {
|
|
47618
|
+
full: {
|
|
47619
|
+
type: "boolean",
|
|
47620
|
+
description: "Every field the dashboard reads too \u2014 the hypothesis in parts, what each version owns, the preview pictures and the posteriors behind the verdict",
|
|
47621
|
+
required: false
|
|
47622
|
+
}
|
|
47540
47623
|
}
|
|
47541
47624
|
});
|
|
47542
47625
|
var statusCommand6 = defineCommand124({
|
|
47543
47626
|
meta: {
|
|
47544
47627
|
name: "status",
|
|
47545
|
-
description: "The verdict on each test. Read `verdict` and nothing else to decide: keep_running | winner | no_difference | cannot_win | invalid. `cannot_win` means even the best case is under the lift the test was looking for \u2014 end it and keep the original. `stillNeeded` is the data (visitors, conversions) the test still needs; a test is gated on data, never on days. `summary` is one sentence you can show the client, and `secondary` lists every other conversion the company counts on the same two arms \u2014 context, never a second decision. The numbers under `--full` are for printing, never for deciding \u2014 a test that says keep_running has not finished, however good its numbers look."
|
|
47628
|
+
description: "The verdict on each test. Read `verdict` and nothing else to decide: keep_running | winner | no_difference | cannot_win | invalid. `cannot_win` means even the best case is under the lift the test was looking for \u2014 end it and keep the original. `stillNeeded` is the data (visitors, conversions) the test still needs; a test is gated on data, never on days. `earliestDecisionAt` is the day this page's traffic would get it there (YYYY-MM-DD) and `earliestDecisionIn` how far off that is \u2014 say those, never work a date out yourself. `summary` is one sentence you can show the client, and `secondary` lists every other conversion the company counts on the same two arms \u2014 context, never a second decision. The numbers under `--full` are for printing, never for deciding \u2014 a test that says keep_running has not finished, however good its numbers look."
|
|
47546
47629
|
},
|
|
47547
47630
|
args: {
|
|
47548
47631
|
id: { type: "string", description: "One test, by its id", required: false },
|
|
47549
47632
|
landing: LANDING_FILTER_ARG,
|
|
47550
|
-
full: {
|
|
47633
|
+
full: {
|
|
47634
|
+
type: "boolean",
|
|
47635
|
+
description: "Every field the dashboard reads too \u2014 the hypothesis in parts, what each version owns, the preview pictures and the posteriors behind the verdict",
|
|
47636
|
+
required: false
|
|
47637
|
+
}
|
|
47551
47638
|
},
|
|
47552
47639
|
run: async ({ args: args5 }) => {
|
|
47553
47640
|
try {
|
|
@@ -47556,10 +47643,13 @@ var statusCommand6 = defineCommand124({
|
|
|
47556
47643
|
...args5.landing ? { landingSlug: String(args5.landing) } : {},
|
|
47557
47644
|
...args5.full === true ? { full: true } : {}
|
|
47558
47645
|
});
|
|
47646
|
+
const now = Date.now();
|
|
47559
47647
|
writeJsonEnvelope({
|
|
47560
47648
|
ok: true,
|
|
47561
|
-
data:
|
|
47562
|
-
|
|
47649
|
+
data: {
|
|
47650
|
+
experiments: response.data.experiments.map((row) => statusReadout(row, { full: args5.full === true, now }))
|
|
47651
|
+
},
|
|
47652
|
+
hints: buildStatusHints(response.data.experiments, now)
|
|
47563
47653
|
});
|
|
47564
47654
|
} catch (error) {
|
|
47565
47655
|
reportApiError(error);
|