@koda-sl/baker-cli 0.245.0 → 0.246.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/dist/cli.js CHANGED
@@ -9408,8 +9408,8 @@ function countStaccato(text2) {
9408
9408
  let first = "";
9409
9409
  let runStart = 0;
9410
9410
  for (const [i, s] of sentences.entries()) {
9411
- const words3 = s.split(/\s+/).filter(Boolean).length;
9412
- if (words3 > 0 && words3 <= STACCATO_MAX_WORDS) {
9411
+ const words2 = s.split(/\s+/).filter(Boolean).length;
9412
+ if (words2 > 0 && words2 <= STACCATO_MAX_WORDS) {
9413
9413
  if (run === 0) runStart = i;
9414
9414
  run++;
9415
9415
  if (run === STACCATO_RUN) {
@@ -9427,10 +9427,10 @@ function countTitleCaseHeadings(text2) {
9427
9427
  let first = "";
9428
9428
  for (const m of text2.matchAll(/^\s{0,3}#{1,6}\s+(.+)$/gm)) {
9429
9429
  const heading = (m[1] ?? "").trim();
9430
- const words3 = heading.split(/\s+/).filter((w) => new RegExp("\\p{L}", "u").test(w));
9431
- if (words3.length < 4) continue;
9432
- const capitalized = words3.filter((w) => new RegExp("^\\p{Lu}", "u").test(w)).length;
9433
- if (capitalized / words3.length < 0.8) continue;
9430
+ const words2 = heading.split(/\s+/).filter((w) => new RegExp("\\p{L}", "u").test(w));
9431
+ if (words2.length < 4) continue;
9432
+ const capitalized = words2.filter((w) => new RegExp("^\\p{Lu}", "u").test(w)).length;
9433
+ if (capitalized / words2.length < 0.8) continue;
9434
9434
  count++;
9435
9435
  if (!first) first = heading;
9436
9436
  }
@@ -9779,11 +9779,11 @@ function rawTextEntries(value) {
9779
9779
  const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
9780
9780
  return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
9781
9781
  }
9782
- function rawFileEntries(path40) {
9783
- if (typeof path40 !== "string" || path40.length === 0) {
9782
+ function rawFileEntries(path38) {
9783
+ if (typeof path38 !== "string" || path38.length === 0) {
9784
9784
  return [];
9785
9785
  }
9786
- return readFileSync2(path40, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
9786
+ return readFileSync2(path38, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
9787
9787
  }
9788
9788
  function keywordEntries(args) {
9789
9789
  const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
@@ -9806,19 +9806,19 @@ function keywordEntries(args) {
9806
9806
  }
9807
9807
  return entries;
9808
9808
  }
9809
- function loadJsonFileArg(path40) {
9810
- if (typeof path40 !== "string" || path40.length === 0) {
9809
+ function loadJsonFileArg(path38) {
9810
+ if (typeof path38 !== "string" || path38.length === 0) {
9811
9811
  return {};
9812
9812
  }
9813
9813
  try {
9814
- const parsed = JSON.parse(readFileSync2(path40, "utf8"));
9814
+ const parsed = JSON.parse(readFileSync2(path38, "utf8"));
9815
9815
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
9816
- failWriteValidation(`${path40} must contain a JSON object`);
9816
+ failWriteValidation(`${path38} must contain a JSON object`);
9817
9817
  }
9818
9818
  return parsed;
9819
9819
  } catch (err) {
9820
9820
  if (err instanceof SyntaxError) {
9821
- failWriteValidation(`${path40} is not valid JSON: ${err.message}`);
9821
+ failWriteValidation(`${path38} is not valid JSON: ${err.message}`);
9822
9822
  }
9823
9823
  throw err;
9824
9824
  }
@@ -9948,10 +9948,10 @@ async function stageUpdate(kind, customerId, target, payload, hints) {
9948
9948
  async function stageTarget(kind, customerId, target, hints) {
9949
9949
  await stageGoogleOp({ kind, customerId, target }, hints);
9950
9950
  }
9951
- async function draftAction(path40, body, chat) {
9951
+ async function draftAction(path38, body, chat) {
9952
9952
  try {
9953
9953
  const chatId = resolveChatId(chat);
9954
- const response = await apiPost(path40, { chatId, ...body });
9954
+ const response = await apiPost(path38, { chatId, ...body });
9955
9955
  writeJsonEnvelope(response);
9956
9956
  } catch (err) {
9957
9957
  handleGoogleError(err);
@@ -15136,19 +15136,19 @@ function failWriteValidation2(message) {
15136
15136
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
15137
15137
  process.exit(1);
15138
15138
  }
15139
- function loadJsonFileArg2(path40) {
15140
- if (typeof path40 !== "string" || path40.length === 0) {
15139
+ function loadJsonFileArg2(path38) {
15140
+ if (typeof path38 !== "string" || path38.length === 0) {
15141
15141
  return {};
15142
15142
  }
15143
15143
  try {
15144
- const parsed = JSON.parse(readFileSync4(path40, "utf8"));
15144
+ const parsed = JSON.parse(readFileSync4(path38, "utf8"));
15145
15145
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
15146
- failWriteValidation2(`${path40} must contain a JSON object`);
15146
+ failWriteValidation2(`${path38} must contain a JSON object`);
15147
15147
  }
15148
15148
  return parsed;
15149
15149
  } catch (err) {
15150
15150
  if (err instanceof SyntaxError) {
15151
- failWriteValidation2(`${path40} is not valid JSON: ${err.message}`);
15151
+ failWriteValidation2(`${path38} is not valid JSON: ${err.message}`);
15152
15152
  }
15153
15153
  throw err;
15154
15154
  }
@@ -15233,15 +15233,15 @@ function parseLocaleFlag(value) {
15233
15233
  }
15234
15234
  return { language: match[1], country: match[2].toUpperCase() };
15235
15235
  }
15236
- function loadTargetingFileArg(path40) {
15237
- if (typeof path40 !== "string" || path40.length === 0) {
15236
+ function loadTargetingFileArg(path38) {
15237
+ if (typeof path38 !== "string" || path38.length === 0) {
15238
15238
  return void 0;
15239
15239
  }
15240
- const parsed = loadJsonFileArg2(path40);
15240
+ const parsed = loadJsonFileArg2(path38);
15241
15241
  const criteria = parsed.targetingCriteria ?? parsed;
15242
15242
  if (!criteria.include) {
15243
15243
  failWriteValidation2(
15244
- `${path40} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
15244
+ `${path38} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
15245
15245
  );
15246
15246
  }
15247
15247
  return criteria;
@@ -15276,14 +15276,14 @@ function parseCsvLine(line) {
15276
15276
  cells.push(current);
15277
15277
  return cells.map((cell2) => cell2.trim());
15278
15278
  }
15279
- function parseListFileArg(path40, maxRows) {
15280
- if (typeof path40 !== "string" || path40.length === 0) {
15279
+ function parseListFileArg(path38, maxRows) {
15280
+ if (typeof path38 !== "string" || path38.length === 0) {
15281
15281
  return void 0;
15282
15282
  }
15283
- const raw = readFileSync4(path40, "utf8");
15283
+ const raw = readFileSync4(path38, "utf8");
15284
15284
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
15285
15285
  if (lines.length < 2) {
15286
- failWriteValidation2(`${path40} needs a header row and at least one data row`);
15286
+ failWriteValidation2(`${path38} needs a header row and at least one data row`);
15287
15287
  }
15288
15288
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
15289
15289
  const rows = [];
@@ -15302,7 +15302,7 @@ function parseListFileArg(path40, maxRows) {
15302
15302
  }
15303
15303
  }
15304
15304
  if (rows.length > maxRows) {
15305
- failWriteValidation2(`${path40} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
15305
+ failWriteValidation2(`${path38} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
15306
15306
  }
15307
15307
  return { columns, rows };
15308
15308
  }
@@ -15398,11 +15398,11 @@ function readPositionals(args) {
15398
15398
  function splitIdList(raw) {
15399
15399
  return raw.split(",").map((id) => id.trim()).filter(Boolean);
15400
15400
  }
15401
- function idsFileEntries(path40) {
15402
- if (typeof path40 !== "string" || path40.length === 0) {
15401
+ function idsFileEntries(path38) {
15402
+ if (typeof path38 !== "string" || path38.length === 0) {
15403
15403
  return [];
15404
15404
  }
15405
- return readFileSync4(path40, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
15405
+ return readFileSync4(path38, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
15406
15406
  }
15407
15407
  function requireTargets(args, entity) {
15408
15408
  const positionals = readPositionals(args);
@@ -18023,9 +18023,9 @@ function compactRow(row) {
18023
18023
  ...destination.postUrn ? { postUrn: destination.postUrn } : {}
18024
18024
  };
18025
18025
  }
18026
- function readPath(row, path40) {
18026
+ function readPath(row, path38) {
18027
18027
  let current = row;
18028
- for (const segment of path40.split(".")) {
18028
+ for (const segment of path38.split(".")) {
18029
18029
  const record = asRecord2(current);
18030
18030
  if (!record) return void 0;
18031
18031
  current = record[segment];
@@ -18035,10 +18035,10 @@ function readPath(row, path40) {
18035
18035
  function projectFields(rows, paths) {
18036
18036
  return rows.map((row) => {
18037
18037
  const projected = {};
18038
- for (const path40 of paths) {
18039
- const value = readPath(row, path40);
18038
+ for (const path38 of paths) {
18039
+ const value = readPath(row, path38);
18040
18040
  if (value !== void 0) {
18041
- projected[path40] = value;
18041
+ projected[path38] = value;
18042
18042
  }
18043
18043
  }
18044
18044
  return projected;
@@ -19338,11 +19338,11 @@ var updateStatusSchema = z25.enum(UPDATE_STATUSES);
19338
19338
  function currencyMinimums2(currencyCode) {
19339
19339
  return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
19340
19340
  }
19341
- function validateDailyBudgetFloor(money, ctx, path40) {
19341
+ function validateDailyBudgetFloor(money, ctx, path38) {
19342
19342
  if (money?.currencyCode) {
19343
19343
  const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
19344
19344
  if (Number(money.amount) < min) {
19345
- ctx.addIssue({ code: "custom", path: path40, message: `below the ${min} ${money.currencyCode} daily minimum` });
19345
+ ctx.addIssue({ code: "custom", path: path38, message: `below the ${min} ${money.currencyCode} daily minimum` });
19346
19346
  }
19347
19347
  }
19348
19348
  }
@@ -20011,19 +20011,19 @@ function failWriteValidation3(message) {
20011
20011
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
20012
20012
  process.exit(1);
20013
20013
  }
20014
- function loadJsonFileArg3(path40) {
20015
- if (typeof path40 !== "string" || path40.length === 0) {
20014
+ function loadJsonFileArg3(path38) {
20015
+ if (typeof path38 !== "string" || path38.length === 0) {
20016
20016
  return {};
20017
20017
  }
20018
20018
  try {
20019
- const parsed = JSON.parse(readFileSync8(path40, "utf8"));
20019
+ const parsed = JSON.parse(readFileSync8(path38, "utf8"));
20020
20020
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
20021
- failWriteValidation3(`${path40} must contain a JSON object`);
20021
+ failWriteValidation3(`${path38} must contain a JSON object`);
20022
20022
  }
20023
20023
  return parsed;
20024
20024
  } catch (err) {
20025
20025
  if (err instanceof SyntaxError) {
20026
- failWriteValidation3(`${path40} is not valid JSON: ${err.message}`);
20026
+ failWriteValidation3(`${path38} is not valid JSON: ${err.message}`);
20027
20027
  }
20028
20028
  throw err;
20029
20029
  }
@@ -24621,11 +24621,11 @@ function unwrap(response) {
24621
24621
  }
24622
24622
  return response.data;
24623
24623
  }
24624
- async function readAvatars(path40, params) {
24625
- return unwrap(await apiGet(path40, params));
24624
+ async function readAvatars(path38, params) {
24625
+ return unwrap(await apiGet(path38, params));
24626
24626
  }
24627
- async function writeAvatars(path40, body) {
24628
- return unwrap(await apiPost(path40, body));
24627
+ async function writeAvatars(path38, body) {
24628
+ return unwrap(await apiPost(path38, body));
24629
24629
  }
24630
24630
 
24631
24631
  // src/commands/avatars/create.ts
@@ -25371,14 +25371,14 @@ function suggestFamilies(wanted, catalogue, limit = 5) {
25371
25371
  const key = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
25372
25372
  const target = key(wanted);
25373
25373
  if (!target) return [];
25374
- const words3 = target.split(" ");
25374
+ const words2 = target.split(" ");
25375
25375
  const scored = catalogue.map((family) => {
25376
25376
  const candidate = key(family);
25377
25377
  if (candidate === target) return { family, score: 0 };
25378
25378
  if (candidate.startsWith(target)) return { family, score: 1 };
25379
25379
  if (candidate.includes(target)) return { family, score: 2 };
25380
- const shared = words3.filter((w) => w.length > 2 && candidate.includes(w)).length;
25381
- return { family, score: shared > 0 ? 3 + (words3.length - shared) : Number.POSITIVE_INFINITY };
25380
+ const shared = words2.filter((w) => w.length > 2 && candidate.includes(w)).length;
25381
+ return { family, score: shared > 0 ? 3 + (words2.length - shared) : Number.POSITIVE_INFINITY };
25382
25382
  }).filter((c) => Number.isFinite(c.score)).sort((a, b) => a.score - b.score || a.family.localeCompare(b.family));
25383
25383
  return scored.slice(0, limit).map((c) => c.family);
25384
25384
  }
@@ -25459,12 +25459,12 @@ function missingFontFiles(urls, available) {
25459
25459
  function planFontAdoption(sources, families) {
25460
25460
  const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
25461
25461
  const byFamily = /* @__PURE__ */ new Map();
25462
- for (const { path: path40, source } of sources) {
25463
- const dir = posix.dirname(path40);
25462
+ for (const { path: path38, source } of sources) {
25463
+ const dir = posix.dirname(path38);
25464
25464
  for (const face of declaredFontFaces(source)) {
25465
25465
  if (!wanted.has(face.family)) continue;
25466
25466
  const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
25467
- perFile.set(path40, [...perFile.get(path40) ?? [], rebaseFontFaceSrc(face.block, dir)]);
25467
+ perFile.set(path38, [...perFile.get(path38) ?? [], rebaseFontFaceSrc(face.block, dir)]);
25468
25468
  byFamily.set(face.family, perFile);
25469
25469
  }
25470
25470
  }
@@ -26872,10 +26872,10 @@ function estSpeechS(text2) {
26872
26872
  var OBSERVED_WPS_MIN = 1;
26873
26873
  var OBSERVED_WPS_MAX = 6;
26874
26874
  function estSpeechWindowS(text2, startS, endS) {
26875
- const words3 = wordCount(text2);
26875
+ const words2 = wordCount(text2);
26876
26876
  const window2 = (endS ?? 0) - (startS ?? 0);
26877
- if (words3 > 0 && window2 > 0.3) {
26878
- const wps = words3 / window2;
26877
+ if (words2 > 0 && window2 > 0.3) {
26878
+ const wps = words2 / window2;
26879
26879
  if (wps >= OBSERVED_WPS_MIN && wps <= OBSERVED_WPS_MAX) return window2;
26880
26880
  }
26881
26881
  return estSpeechS(text2);
@@ -27731,10 +27731,10 @@ function scrubFloatSentences(text2, floatDescs) {
27731
27731
  if (floatDescs.length === 0 || !text2) return text2;
27732
27732
  const tokenSets = floatDescs.map((d) => new Set(floatTokens(d)));
27733
27733
  const kept = text2.split(/(?<=[.!?])\s+/).filter((sentence) => {
27734
- const words3 = new Set(floatTokens(sentence));
27734
+ const words2 = new Set(floatTokens(sentence));
27735
27735
  return !tokenSets.some((ts) => {
27736
27736
  let hits = 0;
27737
- for (const w of words3) if (ts.has(w)) hits++;
27737
+ for (const w of words2) if (ts.has(w)) hits++;
27738
27738
  return hits >= 2;
27739
27739
  });
27740
27740
  }).join(" ").trim();
@@ -33659,12 +33659,12 @@ function collectSideEffects(tree) {
33659
33659
  );
33660
33660
  }
33661
33661
  function readFlowTree(slug) {
33662
- const path40 = join3(flowsDir(), slug, "_data.json");
33663
- if (!existsSync5(path40)) {
33662
+ const path38 = join3(flowsDir(), slug, "_data.json");
33663
+ if (!existsSync5(path38)) {
33664
33664
  failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
33665
33665
  }
33666
33666
  try {
33667
- return JSON.parse(readFileSync9(path40, "utf-8"));
33667
+ return JSON.parse(readFileSync9(path38, "utf-8"));
33668
33668
  } catch (error) {
33669
33669
  failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
33670
33670
  }
@@ -34056,10 +34056,10 @@ function parseValueExpression(raw) {
34056
34056
  return parts.map(parsePart);
34057
34057
  }
34058
34058
  function trackingFieldIds() {
34059
- const path40 = join4(flowsDir(), "..", "tracking.ts");
34060
- if (!existsSync6(path40)) return null;
34059
+ const path38 = join4(flowsDir(), "..", "tracking.ts");
34060
+ if (!existsSync6(path38)) return null;
34061
34061
  try {
34062
- const source = readFileSync10(path40, "utf-8");
34062
+ const source = readFileSync10(path38, "utf-8");
34063
34063
  const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
34064
34064
  if (!block2) return null;
34065
34065
  const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
@@ -34611,13 +34611,13 @@ function specsFromFile(parsed) {
34611
34611
  return `${destField}${type}=${entry?.value ?? ""}`;
34612
34612
  });
34613
34613
  }
34614
- function readSpecFile(path40) {
34614
+ function readSpecFile(path38) {
34615
34615
  let raw;
34616
34616
  try {
34617
- raw = path40 === "-" ? readFileSync11(0, "utf-8") : readFileSync11(path40, "utf-8");
34617
+ raw = path38 === "-" ? readFileSync11(0, "utf-8") : readFileSync11(path38, "utf-8");
34618
34618
  } catch (error) {
34619
34619
  refuse(
34620
- `Could not read ${path40 === "-" ? "the mapping from stdin" : `"${path40}"`}: ${error instanceof Error ? error.message : String(error)}`
34620
+ `Could not read ${path38 === "-" ? "the mapping from stdin" : `"${path38}"`}: ${error instanceof Error ? error.message : String(error)}`
34621
34621
  );
34622
34622
  }
34623
34623
  let parsed;
@@ -34625,7 +34625,7 @@ function readSpecFile(path40) {
34625
34625
  parsed = JSON.parse(raw);
34626
34626
  } catch (error) {
34627
34627
  refuse(
34628
- `${path40 === "-" ? "stdin" : `"${path40}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
34628
+ `${path38 === "-" ? "stdin" : `"${path38}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
34629
34629
  'Expected { "map": { "<destField>": "<value>", \u2026 } }'
34630
34630
  );
34631
34631
  }
@@ -34879,18 +34879,18 @@ var ARRAY_FIELDS = [
34879
34879
  "tagIds"
34880
34880
  ];
34881
34881
  var ARRAY_OWNERS = ["", "body"];
34882
- function dropUnsetOptionals(sideEffect, path40) {
34882
+ function dropUnsetOptionals(sideEffect, path38) {
34883
34883
  return OPTIONAL_STRINGS.flatMap((key) => {
34884
34884
  if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
34885
34885
  delete sideEffect[key];
34886
- return [{ path: path40, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
34886
+ return [{ path: path38, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
34887
34887
  });
34888
34888
  }
34889
- function fillNulledArrays(target, prefix, path40) {
34889
+ function fillNulledArrays(target, prefix, path38) {
34890
34890
  return ARRAY_FIELDS.flatMap((key) => {
34891
34891
  if (!(key in target) || target[key] !== null) return [];
34892
34892
  target[key] = [];
34893
- return [{ path: path40, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
34893
+ return [{ path: path38, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
34894
34894
  });
34895
34895
  }
34896
34896
  function sideEffectsOf(node) {
@@ -34900,13 +34900,13 @@ function sideEffectsOf(node) {
34900
34900
  );
34901
34901
  }
34902
34902
  function normalizeSideEffect(sideEffect, where) {
34903
- const path40 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
34903
+ const path38 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
34904
34904
  const arrays = ARRAY_OWNERS.flatMap((owner) => {
34905
34905
  const target = owner ? sideEffect[owner] : sideEffect;
34906
34906
  if (!target || typeof target !== "object") return [];
34907
- return fillNulledArrays(target, owner ? `${owner}.` : "", path40);
34907
+ return fillNulledArrays(target, owner ? `${owner}.` : "", path38);
34908
34908
  });
34909
- return [...dropUnsetOptionals(sideEffect, path40), ...arrays];
34909
+ return [...dropUnsetOptionals(sideEffect, path38), ...arrays];
34910
34910
  }
34911
34911
  function normalizeFlowTree(tree) {
34912
34912
  const changes = [];
@@ -35444,10 +35444,10 @@ async function stageOps(ops) {
35444
35444
  handleError2(err);
35445
35445
  }
35446
35446
  }
35447
- async function draftAction2(path40, body, chat) {
35447
+ async function draftAction2(path38, body, chat) {
35448
35448
  const chatId = resolveChatId(chat);
35449
35449
  try {
35450
- const data = await apiPost(path40, { chatId, ...body });
35450
+ const data = await apiPost(path38, { chatId, ...body });
35451
35451
  writeJsonEnvelope({ ok: true, data });
35452
35452
  return data;
35453
35453
  } catch (err) {
@@ -37879,9 +37879,9 @@ async function readImageBuffer(pathOrUrl) {
37879
37879
  }
37880
37880
  return readFile20(pathOrUrl);
37881
37881
  }
37882
- async function isDirectory(path40) {
37882
+ async function isDirectory(path38) {
37883
37883
  try {
37884
- const s = await stat4(path40);
37884
+ const s = await stat4(path38);
37885
37885
  return s.isDirectory();
37886
37886
  } catch {
37887
37887
  return false;
@@ -38183,13 +38183,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
38183
38183
  }
38184
38184
  function disambiguate(paths) {
38185
38185
  const taken = /* @__PURE__ */ new Set();
38186
- return paths.map((path40) => {
38187
- if (!taken.has(path40)) {
38188
- taken.add(path40);
38189
- return path40;
38186
+ return paths.map((path38) => {
38187
+ if (!taken.has(path38)) {
38188
+ taken.add(path38);
38189
+ return path38;
38190
38190
  }
38191
- const ext = extname3(path40);
38192
- const stem = path40.slice(0, path40.length - ext.length);
38191
+ const ext = extname3(path38);
38192
+ const stem = path38.slice(0, path38.length - ext.length);
38193
38193
  let n = 2;
38194
38194
  while (taken.has(`${stem}-${n}${ext}`)) n += 1;
38195
38195
  const unique = `${stem}-${n}${ext}`;
@@ -38316,10 +38316,10 @@ async function runDownloads(plan) {
38316
38316
  const paths = disambiguate(fetched.map((item) => item.path));
38317
38317
  const downloaded = [];
38318
38318
  for (const [index, item] of fetched.entries()) {
38319
- const path40 = paths[index] ?? item.path;
38319
+ const path38 = paths[index] ?? item.path;
38320
38320
  try {
38321
- await atomicWrite(path40, item.buffer);
38322
- downloaded.push({ input: item.input, output: path40, bytes: item.buffer.length, contentType: item.contentType });
38321
+ await atomicWrite(path38, item.buffer);
38322
+ downloaded.push({ input: item.input, output: path38, bytes: item.buffer.length, contentType: item.contentType });
38323
38323
  } catch (err) {
38324
38324
  failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
38325
38325
  }
@@ -41279,7 +41279,7 @@ import { defineCommand as defineCommand166 } from "citty";
41279
41279
 
41280
41280
  // src/commands/landing/critique.ts
41281
41281
  import { readdir as readdir9, stat as stat6 } from "fs/promises";
41282
- import path29 from "path";
41282
+ import path28 from "path";
41283
41283
  import { defineCommand as defineCommand156 } from "citty";
41284
41284
 
41285
41285
  // src/engine/landing/lib/constants.ts
@@ -41482,11 +41482,6 @@ var RULE_META = {
41482
41482
  severity: "block",
41483
41483
  note: "Gradient text is a top AI tell. Emphasis comes from weight or size, not a clipped gradient fill."
41484
41484
  },
41485
- "copied-reference-copy": {
41486
- family: "originality",
41487
- severity: "block",
41488
- note: "This line is lifted from a section you consulted in the inspiration library. Reference sections are for structure and mechanism, never words \u2014 a visitor who has seen the original reads this as a clone, and the claim is not yours to make. Rewrite it from the client's own offer."
41489
- },
41490
41485
  "broken-image": {
41491
41486
  family: "integrity",
41492
41487
  severity: "block",
@@ -41667,64 +41662,6 @@ var SEVERITY_WEIGHT = {
41667
41662
  advisory: 0.05
41668
41663
  };
41669
41664
 
41670
- // src/engine/landing/lib/originality.ts
41671
- var MIN_COMPARABLE_LENGTH = 12;
41672
- var NEAR_MATCH_RATIO = 0.8;
41673
- function normalize(value) {
41674
- return value.toLowerCase().replace(/[‘’“”]/g, "'").replace(/[^a-z0-9']+/g, " ").trim();
41675
- }
41676
- function words2(value) {
41677
- return normalize(value).split(" ").filter(Boolean);
41678
- }
41679
- function copyOverlapRatio(candidate, reference) {
41680
- const referenceWords = words2(reference);
41681
- if (referenceWords.length === 0) return 0;
41682
- const candidateWords = new Set(words2(candidate));
41683
- const shared = referenceWords.filter((word) => candidateWords.has(word)).length;
41684
- return shared / referenceWords.length;
41685
- }
41686
- function isVerbatimReuse(candidate, reference) {
41687
- const normalizedCandidate = normalize(candidate);
41688
- const normalizedReference = normalize(reference);
41689
- if (normalizedReference.length < MIN_COMPARABLE_LENGTH) return false;
41690
- if (normalizedCandidate.includes(normalizedReference)) return true;
41691
- return copyOverlapRatio(candidate, reference) >= NEAR_MATCH_RATIO;
41692
- }
41693
- function extractVisibleStrings(text2) {
41694
- const found = [];
41695
- const lines = text2.split("\n");
41696
- for (const [index, line] of lines.entries()) {
41697
- for (const match of line.matchAll(/>([^<>{}]{12,200})</g)) {
41698
- const value = match[1]?.trim();
41699
- if (value && /[a-zA-Z]{3}/.test(value)) found.push({ value, line: index + 1 });
41700
- }
41701
- }
41702
- return found;
41703
- }
41704
- function detectOriginality(sources, references) {
41705
- if (references.length === 0) return [];
41706
- const findings = [];
41707
- const seen = /* @__PURE__ */ new Set();
41708
- for (const source of sources) {
41709
- for (const { value, line } of extractVisibleStrings(source.text)) {
41710
- for (const reference of references) {
41711
- const hit = reference.copyStrings.find((copy) => isVerbatimReuse(value, copy));
41712
- if (!hit) continue;
41713
- const key = `${source.path}:${line}:${normalize(hit)}`;
41714
- if (seen.has(key)) continue;
41715
- seen.add(key);
41716
- findings.push({
41717
- id: "copied-reference-copy",
41718
- snippet: value.slice(0, 120),
41719
- file: source.path,
41720
- line
41721
- });
41722
- }
41723
- }
41724
- }
41725
- return findings;
41726
- }
41727
-
41728
41665
  // src/engine/landing/lib/rules.ts
41729
41666
  var cap2 = (m, i) => m[i] ?? "";
41730
41667
  var num2 = (m, i) => Number(m[i] ?? 0);
@@ -42252,16 +42189,7 @@ function dedupe(findings) {
42252
42189
  }
42253
42190
 
42254
42191
  // src/engine/landing/lib/critique.ts
42255
- var FAMILIES = [
42256
- "typography",
42257
- "color",
42258
- "borders_depth",
42259
- "motion",
42260
- "spacing",
42261
- "copy",
42262
- "integrity",
42263
- "originality"
42264
- ];
42192
+ var FAMILIES = ["typography", "color", "borders_depth", "motion", "spacing", "copy", "integrity"];
42265
42193
  function round4(n) {
42266
42194
  return Math.round(n * 100) / 100;
42267
42195
  }
@@ -42280,7 +42208,6 @@ function critiqueLanding(input) {
42280
42208
  const raws = [];
42281
42209
  for (const source of sources) raws.push(...detectSource(source));
42282
42210
  raws.push(...detectPage(sources));
42283
- raws.push(...detectOriginality(sources, input.references ?? []));
42284
42211
  for (const raw of raws) {
42285
42212
  const meta = RULE_META[raw.id];
42286
42213
  if (!meta) continue;
@@ -42318,82 +42245,41 @@ function describeCounts(findings) {
42318
42245
  return [b ? `${b} block` : "", w ? `${w} warn` : "", a ? `${a} advisory` : ""].filter(Boolean).join(", ");
42319
42246
  }
42320
42247
 
42321
- // src/engine/landing/lib/referenceStore.ts
42322
- import { mkdir as mkdir8, readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
42323
- import path26 from "path";
42324
- var REFERENCES_FILE = ".cache/inspiration-refs.json";
42325
- var REFERENCE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
42326
- async function readReferences(projectRoot) {
42327
- try {
42328
- const raw = await readFile21(path26.join(projectRoot, REFERENCES_FILE), "utf8");
42329
- const parsed = JSON.parse(raw);
42330
- if (!Array.isArray(parsed)) return [];
42331
- const cutoff = Date.now() - REFERENCE_TTL_MS;
42332
- return parsed.filter((entry) => {
42333
- if (typeof entry !== "object" || entry === null) return false;
42334
- const candidate = entry;
42335
- if (typeof candidate.sectionId !== "string" || !Array.isArray(candidate.copyStrings)) return false;
42336
- const at = Date.parse(candidate.consultedAt ?? "");
42337
- return Number.isNaN(at) ? true : at >= cutoff;
42338
- });
42339
- } catch {
42340
- return [];
42341
- }
42342
- }
42343
- async function recordReference(projectRoot, reference) {
42344
- return await recordReferences(projectRoot, [reference]);
42345
- }
42346
- async function recordReferences(projectRoot, references) {
42347
- if (references.length === 0) return true;
42348
- try {
42349
- const existing = await readReferences(projectRoot);
42350
- const replaced = new Set(references.map((reference) => reference.sectionId));
42351
- const merged = [...existing.filter((entry) => !replaced.has(entry.sectionId)), ...references];
42352
- const file = path26.join(projectRoot, REFERENCES_FILE);
42353
- await mkdir8(path26.dirname(file), { recursive: true });
42354
- await writeFile12(file, `${JSON.stringify(merged, null, 2)}
42355
- `);
42356
- return true;
42357
- } catch {
42358
- return false;
42359
- }
42360
- }
42361
-
42362
42248
  // src/commands/landing/snapshot.ts
42363
- import { mkdir as mkdir9, rename as rename2, writeFile as writeFile13 } from "fs/promises";
42364
- import path27 from "path";
42249
+ import { mkdir as mkdir8, rename as rename2, writeFile as writeFile12 } from "fs/promises";
42250
+ import path26 from "path";
42365
42251
  var CRITIC_VERSION = "2";
42366
42252
  function critiqueCacheDir(projectRoot) {
42367
- return path27.join(projectRoot, ".cache", "landing-critique");
42253
+ return path26.join(projectRoot, ".cache", "landing-critique");
42368
42254
  }
42369
42255
  function snapshotPath(projectRoot, slug) {
42370
- return path27.join(critiqueCacheDir(projectRoot), `${slug}.json`);
42256
+ return path26.join(critiqueCacheDir(projectRoot), `${slug}.json`);
42371
42257
  }
42372
42258
  async function writeCritiqueSnapshot(projectRoot, snapshot) {
42373
- await mkdir9(critiqueCacheDir(projectRoot), { recursive: true });
42259
+ await mkdir8(critiqueCacheDir(projectRoot), { recursive: true });
42374
42260
  const dest = snapshotPath(projectRoot, snapshot.slug);
42375
42261
  const tmp = `${dest}.tmp`;
42376
- await writeFile13(tmp, `${JSON.stringify(snapshot, null, 2)}
42262
+ await writeFile12(tmp, `${JSON.stringify(snapshot, null, 2)}
42377
42263
  `, "utf8");
42378
42264
  await rename2(tmp, dest);
42379
42265
  }
42380
42266
 
42381
42267
  // src/commands/landing/source-version.ts
42382
- import { readdir as readdir8, readFile as readFile22, stat as stat5 } from "fs/promises";
42383
- import path28 from "path";
42268
+ import { readdir as readdir8, readFile as readFile21, stat as stat5 } from "fs/promises";
42269
+ import path27 from "path";
42384
42270
  async function landingSourceRelPaths(landingDir) {
42385
42271
  const rel = [];
42386
- if (await isFile(path28.join(landingDir, "index.astro"))) rel.push("index.astro");
42387
- const componentsDir = path28.join(landingDir, "_components");
42272
+ if (await isFile(path27.join(landingDir, "index.astro"))) rel.push("index.astro");
42273
+ const componentsDir = path27.join(landingDir, "_components");
42388
42274
  for (const abs of await walkAstro(componentsDir)) {
42389
- rel.push(path28.relative(landingDir, abs).split(path28.sep).join("/"));
42275
+ rel.push(path27.relative(landingDir, abs).split(path27.sep).join("/"));
42390
42276
  }
42391
42277
  return rel.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
42392
42278
  }
42393
42279
  async function readLandingSources(landingDir) {
42394
42280
  const rel = await landingSourceRelPaths(landingDir);
42395
42281
  const out = [];
42396
- for (const r of rel) out.push({ path: r, text: await readFile22(path28.join(landingDir, r), "utf8") });
42282
+ for (const r of rel) out.push({ path: r, text: await readFile21(path27.join(landingDir, r), "utf8") });
42397
42283
  return out;
42398
42284
  }
42399
42285
  async function computeLandingSourceSha(landingDir) {
@@ -42402,7 +42288,7 @@ async function computeLandingSourceSha(landingDir) {
42402
42288
  for (const r of rel) {
42403
42289
  let bytes;
42404
42290
  try {
42405
- bytes = await readFile22(path28.join(landingDir, r));
42291
+ bytes = await readFile21(path27.join(landingDir, r));
42406
42292
  } catch {
42407
42293
  bytes = Buffer.alloc(0);
42408
42294
  }
@@ -42426,7 +42312,7 @@ async function walkAstro(dir) {
42426
42312
  }
42427
42313
  const out = [];
42428
42314
  for (const entry of entries) {
42429
- const abs = path28.join(dir, entry.name);
42315
+ const abs = path27.join(dir, entry.name);
42430
42316
  if (entry.isDirectory()) out.push(...await walkAstro(abs));
42431
42317
  else if (entry.isFile() && entry.name.endsWith(".astro")) out.push(abs);
42432
42318
  }
@@ -42487,14 +42373,14 @@ var critiqueCommand2 = defineCommand156({
42487
42373
  { availableSlugs: await listLandingSlugs(projectRoot) }
42488
42374
  );
42489
42375
  }
42490
- if (!await isDir(path29.resolve(projectRoot, "src", "pages", slug))) {
42376
+ if (!await isDir(path28.resolve(projectRoot, "src", "pages", slug))) {
42491
42377
  fail5("NOT_FOUND", `No landing at src/pages/${slug}/`, {
42492
42378
  availableSlugs: await listLandingSlugs(projectRoot)
42493
42379
  });
42494
42380
  }
42495
42381
  }
42496
- const [brand, references] = await Promise.all([loadBrandTokens(projectRoot), readReferences(projectRoot)]);
42497
- const results = await Promise.all(slugs.map((slug) => critiqueOne(projectRoot, slug, brand, references)));
42382
+ const brand = await loadBrandTokens(projectRoot);
42383
+ const results = await Promise.all(slugs.map((slug) => critiqueOne(projectRoot, slug, brand)));
42498
42384
  const landings = results.map(({ slug, report }) => ({
42499
42385
  slug,
42500
42386
  overall: report.overall,
@@ -42525,10 +42411,10 @@ var critiqueCommand2 = defineCommand156({
42525
42411
  );
42526
42412
  }
42527
42413
  });
42528
- async function critiqueOne(projectRoot, slug, brand, references) {
42529
- const landingDir = path29.resolve(projectRoot, "src", "pages", slug);
42414
+ async function critiqueOne(projectRoot, slug, brand) {
42415
+ const landingDir = path28.resolve(projectRoot, "src", "pages", slug);
42530
42416
  const [sources, sourceSha] = await Promise.all([readLandingSources(landingDir), computeLandingSourceSha(landingDir)]);
42531
- const report = critiqueLanding({ slug, sources, brand, references });
42417
+ const report = critiqueLanding({ slug, sources, brand });
42532
42418
  let snapshotFailed = false;
42533
42419
  try {
42534
42420
  await writeCritiqueSnapshot(projectRoot, {
@@ -42546,7 +42432,7 @@ async function critiqueOne(projectRoot, slug, brand, references) {
42546
42432
  }
42547
42433
  async function listLandingSlugs(projectRoot) {
42548
42434
  try {
42549
- const entries = await readdir9(path29.join(projectRoot, "src", "pages"), { withFileTypes: true });
42435
+ const entries = await readdir9(path28.join(projectRoot, "src", "pages"), { withFileTypes: true });
42550
42436
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).map((e) => e.name).sort();
42551
42437
  } catch {
42552
42438
  return [];
@@ -42579,7 +42465,7 @@ import { defineCommand as defineCommand157 } from "citty";
42579
42465
 
42580
42466
  // src/commands/landing/inspiration/shared.ts
42581
42467
  var INSPIRATION_HINTS = {
42582
- adapt: "Reference only. Re-express this in the client's BRAND.md palette, type and imagery register. Reusing a headline, subhead or CTA verbatim is a Tier 0 message-match failure (references/gotchas.md) and `baker landing critique` will block the publish.",
42468
+ adapt: "Reference only. Re-express this in the client's BRAND.md palette, type and imagery register. Reusing a headline, subhead or CTA verbatim is a Tier 0 message-match failure (references/gotchas.md).",
42583
42469
  structureNotCopy: "Take the structural decision, not the furniture: what the eye hits first, the grid ratio, what was deliberately left out. Your copy must come from the client's own offer."
42584
42470
  };
42585
42471
  function favoritesScopeHints(health, resultCount) {
@@ -42697,12 +42583,12 @@ var addCommand = defineCommand157({
42697
42583
  });
42698
42584
 
42699
42585
  // src/commands/landing/inspiration/code.ts
42700
- import { mkdir as mkdir10, writeFile as writeFile14 } from "fs/promises";
42701
- import path30 from "path";
42586
+ import { mkdir as mkdir9, writeFile as writeFile13 } from "fs/promises";
42587
+ import path29 from "path";
42702
42588
  import { defineCommand as defineCommand158 } from "citty";
42703
42589
  registerSchema({
42704
42590
  command: "landing.inspiration.code",
42705
- description: "Write a reference section's standalone HTML+CSS to .baker/inspiration/<id>/ so you can read how it is built. Reference only \u2014 the structure is the lesson, the words are not yours to reuse. Consulting a section records it, and `baker landing critique` blocks a publish that ships its copy verbatim.",
42591
+ description: "Write a reference section's standalone HTML+CSS to .baker/inspiration/<id>/ so you can read how it is built. Reference only \u2014 the structure is the lesson, the words are not yours to reuse.",
42706
42592
  args: {
42707
42593
  id: { type: "string", description: "Section id from search", required: true },
42708
42594
  full: { type: "boolean", description: "Print the markup inline as well as writing it", required: false }
@@ -42721,30 +42607,19 @@ var codeCommand = defineCommand158({
42721
42607
  try {
42722
42608
  const id = args.id;
42723
42609
  const data = await apiGet("/api/landing-inspiration/section-code", { id });
42724
- const dir = path30.join(process.cwd(), ".baker", "inspiration", id);
42725
- await mkdir10(dir, { recursive: true });
42726
- const file = path30.join(dir, "section.html");
42727
- await writeFile14(file, data.html);
42728
- const recorded = await recordReference(process.cwd(), {
42729
- sectionId: id,
42730
- sourceUrl: data.sourceUrl,
42731
- copyStrings: data.copyStrings,
42732
- consultedAt: (/* @__PURE__ */ new Date()).toISOString()
42733
- });
42610
+ const dir = path29.join(process.cwd(), ".baker", "inspiration", id);
42611
+ await mkdir9(dir, { recursive: true });
42612
+ const file = path29.join(dir, "section.html");
42613
+ await writeFile13(file, data.html);
42734
42614
  const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
42735
42615
  const fidelity = fidelityHint(data.fidelity);
42736
42616
  if (fidelity) hints.push(fidelity);
42737
42617
  if (data.fidelityNote) hints.push(data.fidelityNote);
42738
- if (!recorded) {
42739
- hints.push(
42740
- "Could not record this reference (.cache/ not writable?) \u2014 the originality check at publish will not be able to see it, so be especially careful not to reuse its copy."
42741
- );
42742
- }
42743
42618
  writeJson({
42744
42619
  ok: true,
42745
42620
  data: {
42746
42621
  id,
42747
- file: path30.relative(process.cwd(), file),
42622
+ file: path29.relative(process.cwd(), file),
42748
42623
  bytes: data.html.length,
42749
42624
  fidelity: data.fidelity,
42750
42625
  reproduction_notes: data.reproductionNotes,
@@ -42999,25 +42874,8 @@ var pageCommand2 = defineCommand160({
42999
42874
  });
43000
42875
 
43001
42876
  // src/commands/landing/inspiration/scrape.ts
43002
- import { readFile as readFile23 } from "fs/promises";
43003
- import path34 from "path";
43004
42877
  import { defineCommand as defineCommand161 } from "citty";
43005
42878
 
43006
- // src/engine/landing/lib/capturedReferences.ts
43007
- var MAX_STRINGS_PER_SECTION = 40;
43008
- function bodyOf(markup) {
43009
- const body = markup.indexOf("<body");
43010
- return body === -1 ? markup : markup.slice(body);
43011
- }
43012
- function capturedCopyStrings(markup) {
43013
- const seen = /* @__PURE__ */ new Set();
43014
- for (const { value } of extractVisibleStrings(bodyOf(markup))) {
43015
- seen.add(value);
43016
- if (seen.size >= MAX_STRINGS_PER_SECTION) break;
43017
- }
43018
- return [...seen];
43019
- }
43020
-
43021
42879
  // src/engine/landing-library/proxyFailure.ts
43022
42880
  var PROXY_STATUS = 407;
43023
42881
  var PROXY_NET_ERRORS = [
@@ -43192,8 +43050,8 @@ function classifyCaptureFailure(error) {
43192
43050
  }
43193
43051
 
43194
43052
  // src/engine/landing-library/run.ts
43195
- import { mkdir as mkdir11, writeFile as writeFile16 } from "fs/promises";
43196
- import path32 from "path";
43053
+ import { mkdir as mkdir10, writeFile as writeFile15 } from "fs/promises";
43054
+ import path31 from "path";
43197
43055
 
43198
43056
  // ../proxy/src/preflight.ts
43199
43057
  import http from "http";
@@ -44608,11 +44466,11 @@ async function renderBundleToPng(browser, html, viewportWidth, options = {}) {
44608
44466
  }
44609
44467
 
44610
44468
  // src/engine/landing-library/report.ts
44611
- import { writeFile as writeFile15 } from "fs/promises";
44612
- import path31 from "path";
44469
+ import { writeFile as writeFile14 } from "fs/promises";
44470
+ import path30 from "path";
44613
44471
  async function writeCaptureReport(manifest, outDir) {
44614
- const file = path31.join(outDir, "report.html");
44615
- await writeFile15(file, renderReport(manifest));
44472
+ const file = path30.join(outDir, "report.html");
44473
+ await writeFile14(file, renderReport(manifest));
44616
44474
  return file;
44617
44475
  }
44618
44476
  function escapeHtml3(value) {
@@ -44790,32 +44648,32 @@ async function reproducePage(args) {
44790
44648
  const { browser, page, outDir, pageUrl, livePageShot } = args;
44791
44649
  const built = await buildSectionBundle(page, "body", pageUrl).catch(() => null);
44792
44650
  if (!built) return { bundle: null, fidelity: null };
44793
- await writeFile16(path32.join(outDir, "page.html"), built.html);
44651
+ await writeFile15(path31.join(outDir, "page.html"), built.html);
44794
44652
  const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width, {
44795
44653
  wholePage: true,
44796
44654
  timeoutMs: 6e4
44797
44655
  });
44798
44656
  if (!rendered || !livePageShot) return { bundle: "page.html", fidelity: null };
44799
- await writeFile16(path32.join(outDir, "page-rendered.png"), rendered);
44657
+ await writeFile15(path31.join(outDir, "page-rendered.png"), rendered);
44800
44658
  const { score, note } = await scoreFidelity(livePageShot, rendered);
44801
44659
  return { bundle: "page.html", fidelity: score, ...note ? { fidelityNote: note } : {} };
44802
44660
  }
44803
44661
  async function captureOneSection(args) {
44804
44662
  const { browser, page, candidate, sectionsDir, outDir, pageUrl, withCode } = args;
44805
- const dir = path32.join(sectionsDir, String(candidate.index).padStart(2, "0"));
44806
- await mkdir11(dir, { recursive: true });
44663
+ const dir = path31.join(sectionsDir, String(candidate.index).padStart(2, "0"));
44664
+ await mkdir10(dir, { recursive: true });
44807
44665
  const desktop = await captureSection(page, candidate);
44808
- if (desktop) await writeFile16(path32.join(dir, "desktop.png"), desktop);
44666
+ if (desktop) await writeFile15(path31.join(dir, "desktop.png"), desktop);
44809
44667
  const visualHash = desktop ? await perceptualHash(desktop) : null;
44810
44668
  const motion = await collectMotion(page, candidate.selector);
44811
44669
  const built = withCode ? await buildSectionBundle(page, candidate.selector, pageUrl) : null;
44812
44670
  let fidelity = null;
44813
44671
  let fidelityNote;
44814
44672
  if (built) {
44815
- await writeFile16(path32.join(dir, "section.html"), built.html);
44673
+ await writeFile15(path31.join(dir, "section.html"), built.html);
44816
44674
  const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width);
44817
44675
  if (rendered && desktop) {
44818
- await writeFile16(path32.join(dir, "section-rendered.png"), rendered);
44676
+ await writeFile15(path31.join(dir, "section-rendered.png"), rendered);
44819
44677
  const result = await scoreFidelity(desktop, rendered);
44820
44678
  fidelity = result.score;
44821
44679
  fidelityNote = result.note;
@@ -44823,9 +44681,9 @@ async function captureOneSection(args) {
44823
44681
  }
44824
44682
  return {
44825
44683
  ...candidate,
44826
- desktopShot: desktop ? path32.relative(outDir, path32.join(dir, "desktop.png")) : null,
44684
+ desktopShot: desktop ? path31.relative(outDir, path31.join(dir, "desktop.png")) : null,
44827
44685
  mobileShot: null,
44828
- bundle: built ? path32.relative(outDir, path32.join(dir, "section.html")) : null,
44686
+ bundle: built ? path31.relative(outDir, path31.join(dir, "section.html")) : null,
44829
44687
  fidelity,
44830
44688
  ...fidelityNote ? { fidelityNote } : {},
44831
44689
  ...built ? { cssStats: built.stats } : {},
@@ -44844,9 +44702,9 @@ async function captureMobileShots(args) {
44844
44702
  for (const section of sections) {
44845
44703
  const shot = await captureSectionOnMobile(mobile.page, section);
44846
44704
  if (!shot) continue;
44847
- const file = path32.join(sectionsDir, String(section.index).padStart(2, "0"), "mobile.png");
44848
- await writeFile16(file, shot);
44849
- section.mobileShot = path32.relative(outDir, file);
44705
+ const file = path31.join(sectionsDir, String(section.index).padStart(2, "0"), "mobile.png");
44706
+ await writeFile15(file, shot);
44707
+ section.mobileShot = path31.relative(outDir, file);
44850
44708
  }
44851
44709
  } finally {
44852
44710
  await mobile.context.close();
@@ -44861,10 +44719,10 @@ async function captureMotionTakes(args) {
44861
44719
  const filmOne = async (section) => {
44862
44720
  const take = await captureMotionTake(browser, pageUrl, section.selector).catch(() => null);
44863
44721
  if (!take) return;
44864
- const dir = path32.join(sectionsDir, String(section.index).padStart(2, "0"));
44865
- const file = path32.join(dir, "motion-filmstrip.png");
44866
- await writeFile16(file, take.filmstrip);
44867
- section.motionFilmstrip = path32.relative(outDir, file);
44722
+ const dir = path31.join(sectionsDir, String(section.index).padStart(2, "0"));
44723
+ const file = path31.join(dir, "motion-filmstrip.png");
44724
+ await writeFile15(file, take.filmstrip);
44725
+ section.motionFilmstrip = path31.relative(outDir, file);
44868
44726
  log(` [${section.index}] ${section.motion.summary}`);
44869
44727
  };
44870
44728
  const queue = [...moving];
@@ -44921,7 +44779,7 @@ async function captureAlternateViews(args) {
44921
44779
  async function reproduceWholePage(args) {
44922
44780
  const { browser, page, outDir, pageUrl, withCode, log } = args;
44923
44781
  const fullPage = await page.screenshot({ type: "png", fullPage: true }).catch(() => null);
44924
- if (fullPage) await writeFile16(path32.join(outDir, "full-page.png"), fullPage);
44782
+ if (fullPage) await writeFile15(path31.join(outDir, "full-page.png"), fullPage);
44925
44783
  if (!withCode) return { bundle: null, fidelity: null };
44926
44784
  const reproduction = await reproducePage({ browser, page, outDir, pageUrl, livePageShot: fullPage });
44927
44785
  log(`page reproduction: ${reproduction.fidelity === null ? "unavailable" : reproduction.fidelity.toFixed(2)}`);
@@ -44992,7 +44850,7 @@ async function openViaLadder(args) {
44992
44850
  async function scrapeLanding(options) {
44993
44851
  const timeoutMs = options.timeoutMs ?? 45e3;
44994
44852
  const log = options.onProgress ?? (() => void 0);
44995
- const sectionsDir = path32.join(options.outDir, "sections");
44853
+ const sectionsDir = path31.join(options.outDir, "sections");
44996
44854
  const nonPublic = refuseNonPublicUrl(options.url);
44997
44855
  if (nonPublic) {
44998
44856
  throw new BlockedPageError({
@@ -45012,7 +44870,7 @@ async function scrapeLanding(options) {
45012
44870
  const withMotion = options.motion !== false && !escalated;
45013
44871
  const renderBrowser = options.code === false ? null : await launchBrowser();
45014
44872
  try {
45015
- await mkdir11(sectionsDir, { recursive: true });
44873
+ await mkdir10(sectionsDir, { recursive: true });
45016
44874
  const sections = await captureSections({
45017
44875
  browser: renderBrowser ?? browser,
45018
44876
  page,
@@ -45054,7 +44912,7 @@ async function scrapeLanding(options) {
45054
44912
  security: prepared.security,
45055
44913
  captureTier: tier
45056
44914
  };
45057
- await writeFile16(path32.join(options.outDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
44915
+ await writeFile15(path31.join(options.outDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
45058
44916
  `);
45059
44917
  if (options.report !== false) {
45060
44918
  const reportPath = await writeCaptureReport(manifest, options.outDir);
@@ -45069,28 +44927,28 @@ async function scrapeLanding(options) {
45069
44927
 
45070
44928
  // src/commands/landing/inspiration/captureOut.ts
45071
44929
  import { existsSync as existsSync9 } from "fs";
45072
- import path33 from "path";
44930
+ import path32 from "path";
45073
44931
  var SCRATCH_DIR = ".baker";
45074
44932
  function isWithin(parent, target) {
45075
- const relative = path33.relative(parent, target);
45076
- return relative === "" || !relative.startsWith("..") && !path33.isAbsolute(relative);
44933
+ const relative = path32.relative(parent, target);
44934
+ return relative === "" || !relative.startsWith("..") && !path32.isAbsolute(relative);
45077
44935
  }
45078
44936
  function findRepoRoot(from) {
45079
- let dir = path33.resolve(from);
44937
+ let dir = path32.resolve(from);
45080
44938
  for (; ; ) {
45081
- if (existsSync9(path33.join(dir, ".git"))) return dir;
45082
- const parent = path33.dirname(dir);
44939
+ if (existsSync9(path32.join(dir, ".git"))) return dir;
44940
+ const parent = path32.dirname(dir);
45083
44941
  if (parent === dir) return null;
45084
44942
  dir = parent;
45085
44943
  }
45086
44944
  }
45087
44945
  function checkCaptureOut(out, options) {
45088
44946
  const { cwd, repoRoot } = options;
45089
- const resolved = path33.resolve(cwd, out);
44947
+ const resolved = path32.resolve(cwd, out);
45090
44948
  if (repoRoot === null || !isWithin(repoRoot, resolved)) return { ok: true };
45091
- const scratch = path33.join(repoRoot, SCRATCH_DIR);
44949
+ const scratch = path32.join(repoRoot, SCRATCH_DIR);
45092
44950
  if (isWithin(scratch, resolved)) return { ok: true };
45093
- const suggestion = path33.posix.join(SCRATCH_DIR, "teardowns", path33.basename(resolved) || "capture");
44951
+ const suggestion = path32.posix.join(SCRATCH_DIR, "teardowns", path32.basename(resolved) || "capture");
45094
44952
  return {
45095
44953
  ok: false,
45096
44954
  error: {
@@ -45113,29 +44971,8 @@ var RETRYABLE_FAILURES = /* @__PURE__ */ new Set([
45113
44971
  // would blacklist a page that was never actually judged.
45114
44972
  "PROXY_UNAVAILABLE"
45115
44973
  ]);
45116
- async function recordCapture(manifest, outDir) {
45117
- const consultedAt = (/* @__PURE__ */ new Date()).toISOString();
45118
- const references = [];
45119
- for (const section of manifest.sections) {
45120
- if (!section.bundle) continue;
45121
- try {
45122
- const markup = await readFile23(path34.join(outDir, section.bundle), "utf8");
45123
- const copyStrings = capturedCopyStrings(markup);
45124
- if (copyStrings.length === 0) continue;
45125
- references.push({
45126
- sectionId: `local:${manifest.finalUrl}#${section.index}`,
45127
- sourceUrl: manifest.finalUrl,
45128
- copyStrings,
45129
- consultedAt
45130
- });
45131
- } catch {
45132
- }
45133
- }
45134
- const written = await recordReferences(process.cwd(), references);
45135
- return written ? references.length : 0;
45136
- }
45137
44974
  function captureHints(args) {
45138
- const { manifest, outDir, report, recorded } = args;
44975
+ const { manifest, outDir, report } = args;
45139
44976
  const shots = manifest.sections.filter((section) => section.desktopShot !== null).length;
45140
44977
  const anyScored = manifest.sections.some((section) => section.fidelity !== null);
45141
44978
  const hints = [];
@@ -45155,14 +44992,11 @@ function captureHints(args) {
45155
44992
  );
45156
44993
  }
45157
44994
  hints.push(INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt);
45158
- hints.push(
45159
- recorded > 0 ? `${recorded} sections are recorded for the originality check \u2014 \`baker landing critique\` will block a publish that ships their copy.` : "Nothing from this capture is recorded for the originality check, so it cannot see this page. Be especially careful not to reuse its copy."
45160
- );
45161
44995
  return hints;
45162
44996
  }
45163
44997
  registerSchema({
45164
44998
  command: "landing.inspiration.scrape",
45165
- description: "Start here when the user points at a specific page and wants it now: capture one landing page into a directory of section screenshots, standalone HTML bundles, a whole-page reproduction and motion filmstrips. Returns when the capture is done, unlike `add`. Read the screenshots. Also records every captured section for the originality check.",
44999
+ description: "Start here when the user points at a specific page and wants it now: capture one landing page into a directory of section screenshots, standalone HTML bundles, a whole-page reproduction and motion filmstrips. Returns when the capture is done, unlike `add`. Read the screenshots.",
45166
45000
  args: {
45167
45001
  url: { type: "string", description: "Page to capture", required: true },
45168
45002
  out: { type: "string", description: "Output directory under .baker/", required: true },
@@ -45230,7 +45064,6 @@ var scrapeCommand = defineCommand161({
45230
45064
  `)
45231
45065
  });
45232
45066
  const scored = manifest.sections.map((section) => section.fidelity).filter((value) => value !== null).sort((a, b) => a - b);
45233
- const recorded = await recordCapture(manifest, args.out);
45234
45067
  writeJson({
45235
45068
  ok: true,
45236
45069
  data: {
@@ -45251,7 +45084,7 @@ var scrapeCommand = defineCommand161({
45251
45084
  certificate_verified: false,
45252
45085
  ...manifest.security.certificateNotes.length > 0 ? { certificate_notes: manifest.security.certificateNotes } : {}
45253
45086
  },
45254
- hints: captureHints({ manifest, outDir: args.out, report: args.report, recorded })
45087
+ hints: captureHints({ manifest, outDir: args.out, report: args.report })
45255
45088
  });
45256
45089
  } catch (error) {
45257
45090
  const failure = classifyCaptureFailure(error);
@@ -45289,12 +45122,12 @@ var scrapeCommand = defineCommand161({
45289
45122
  });
45290
45123
 
45291
45124
  // src/commands/landing/inspiration/search.ts
45292
- import path36 from "path";
45125
+ import path34 from "path";
45293
45126
  import { defineCommand as defineCommand162 } from "citty";
45294
45127
 
45295
45128
  // src/commands/landing/inspiration/shot.ts
45296
- import { mkdir as mkdir12, writeFile as writeFile17 } from "fs/promises";
45297
- import path35 from "path";
45129
+ import { mkdir as mkdir11, writeFile as writeFile16 } from "fs/promises";
45130
+ import path33 from "path";
45298
45131
  import sharp6 from "sharp";
45299
45132
  var READABLE_SHOT = {
45300
45133
  maxWidth: 1440,
@@ -45320,9 +45153,9 @@ async function downloadReadableShot(url, file) {
45320
45153
  const response = await fetch(url);
45321
45154
  if (!response.ok) return null;
45322
45155
  const shot = await toReadableShot(Buffer.from(await response.arrayBuffer()));
45323
- await mkdir12(path35.dirname(file), { recursive: true });
45324
- await writeFile17(file, shot);
45325
- return path35.relative(process.cwd(), file);
45156
+ await mkdir11(path33.dirname(file), { recursive: true });
45157
+ await writeFile16(file, shot);
45158
+ return path33.relative(process.cwd(), file);
45326
45159
  } catch {
45327
45160
  return null;
45328
45161
  }
@@ -45414,13 +45247,13 @@ function buildSearchBody(args) {
45414
45247
  return body;
45415
45248
  }
45416
45249
  async function downloadShots(results) {
45417
- const dir = path36.join(process.cwd(), ".baker", "inspiration");
45250
+ const dir = path34.join(process.cwd(), ".baker", "inspiration");
45418
45251
  const saved = /* @__PURE__ */ new Map();
45419
45252
  await Promise.all(
45420
45253
  results.map(async (result) => {
45421
45254
  const file = await downloadReadableShot(
45422
45255
  result.desktopShotUrl,
45423
- path36.join(dir, `${result.id}.${READABLE_SHOT.extension}`)
45256
+ path34.join(dir, `${result.id}.${READABLE_SHOT.extension}`)
45424
45257
  );
45425
45258
  if (file) saved.set(result.id, file);
45426
45259
  })
@@ -45648,7 +45481,7 @@ var sequencesCommand = defineCommand163({
45648
45481
  });
45649
45482
 
45650
45483
  // src/commands/landing/inspiration/view.ts
45651
- import path37 from "path";
45484
+ import path35 from "path";
45652
45485
  import { defineCommand as defineCommand164 } from "citty";
45653
45486
  registerSchema({
45654
45487
  command: "landing.inspiration.view",
@@ -45681,12 +45514,12 @@ var viewCommand2 = defineCommand164({
45681
45514
  const id = args.id;
45682
45515
  const data = await apiGet("/api/landing-inspiration/section", { id });
45683
45516
  const section = data.section;
45684
- const dir = path37.join(process.cwd(), ".baker", "inspiration", id);
45517
+ const dir = path35.join(process.cwd(), ".baker", "inspiration", id);
45685
45518
  const ext = READABLE_SHOT.extension;
45686
45519
  const [desktop, mobile, filmstrip] = await Promise.all([
45687
- downloadReadableShot(section.desktopShotUrl, path37.join(dir, `desktop.${ext}`)),
45688
- downloadReadableShot(section.mobileShotUrl, path37.join(dir, `mobile.${ext}`)),
45689
- downloadReadableShot(section.motionFilmstripUrl, path37.join(dir, `motion-filmstrip.${ext}`))
45520
+ downloadReadableShot(section.desktopShotUrl, path35.join(dir, `desktop.${ext}`)),
45521
+ downloadReadableShot(section.mobileShotUrl, path35.join(dir, `mobile.${ext}`)),
45522
+ downloadReadableShot(section.motionFilmstripUrl, path35.join(dir, `motion-filmstrip.${ext}`))
45690
45523
  ]);
45691
45524
  const full = args.full;
45692
45525
  const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
@@ -45753,7 +45586,7 @@ var inspirationCommand = defineCommand165({
45753
45586
 
45754
45587
  Start here: \`baker landing inspiration search "<what you want to see>"\` during research, BEFORE you write the Direction Contract.
45755
45588
 
45756
- This is inspiration, never a clipboard. Take the mechanism \u2014 what the eye hits first, what proof arrives before the ask, how the grid is split. The words are never yours to reuse: shipping a reference's headline is a Tier 0 message-match failure and \`baker landing critique\` will block the publish.
45589
+ This is inspiration, never a clipboard. Take the mechanism \u2014 what the eye hits first, what proof arrives before the ask, how the grid is split. The words are never yours to reuse: shipping a reference's headline is a Tier 0 message-match failure.
45757
45590
 
45758
45591
  Subcommands:
45759
45592
  baker landing inspiration search "<query>" \u2014 search by look, section type, composition, register or motion; saves screenshots you can Read
@@ -47535,8 +47368,8 @@ var listCommand15 = defineCommand183({
47535
47368
  });
47536
47369
 
47537
47370
  // src/commands/scheduled-actions/templates.ts
47538
- import { readFile as readFile24 } from "fs/promises";
47539
- import path38 from "path";
47371
+ import { readFile as readFile22 } from "fs/promises";
47372
+ import path36 from "path";
47540
47373
  import { defineCommand as defineCommand184 } from "citty";
47541
47374
  registerSchema({
47542
47375
  command: "scheduled-actions.templates",
@@ -47639,7 +47472,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
47639
47472
  }
47640
47473
  if (save.length > 0) {
47641
47474
  const briefFile = flag("brief-file");
47642
- const brief = briefFile.length > 0 ? await readFile24(path38.resolve(briefFile), "utf8") : flag("brief");
47475
+ const brief = briefFile.length > 0 ? await readFile22(path36.resolve(briefFile), "utf8") : flag("brief");
47643
47476
  if (brief.trim().length === 0) {
47644
47477
  failValidation4("--brief-file (preferred) or --brief is required: the brief is the recipe.");
47645
47478
  }
@@ -48110,7 +47943,7 @@ function parseImageRefs(spec) {
48110
47943
  }
48111
47944
  var defaultDeps = {
48112
47945
  ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
48113
- upload: (path40) => uploadLocalImage({ file: path40, contentType: detectImageContentType(path40), source: "uploaded" })
47946
+ upload: (path38) => uploadLocalImage({ file: path38, contentType: detectImageContentType(path38), source: "uploaded" })
48114
47947
  };
48115
47948
  async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
48116
47949
  const refs = parseImageRefs(spec);
@@ -48130,10 +47963,10 @@ async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
48130
47963
  }
48131
47964
  return { imageIds, added };
48132
47965
  }
48133
- function uploadFailure(path40) {
47966
+ function uploadFailure(path38) {
48134
47967
  return (error) => {
48135
47968
  if (error instanceof ApiError) throw error;
48136
- throw new ApiError("VALIDATION_ERROR", `Could not read "${path40}" as an image.`);
47969
+ throw new ApiError("VALIDATION_ERROR", `Could not read "${path38}" as an image.`);
48137
47970
  };
48138
47971
  }
48139
47972
 
@@ -49195,10 +49028,10 @@ async function stageOp4(op) {
49195
49028
  handleError5(err);
49196
49029
  }
49197
49030
  }
49198
- async function draftAction3(path40, body, chat) {
49031
+ async function draftAction3(path38, body, chat) {
49199
49032
  const chatId = resolveChatId(chat);
49200
49033
  try {
49201
- const data = await apiPost(path40, { chatId, ...body });
49034
+ const data = await apiPost(path38, { chatId, ...body });
49202
49035
  writeJsonEnvelope({ ok: true, data });
49203
49036
  return data;
49204
49037
  } catch (err) {
@@ -50305,7 +50138,7 @@ var groupCommand2 = defineCommand209({
50305
50138
  // src/commands/videos/ingest.ts
50306
50139
  import { mkdtemp as mkdtemp2, rm as rm7, stat as stat7 } from "fs/promises";
50307
50140
  import { tmpdir as tmpdir3 } from "os";
50308
- import path39 from "path";
50141
+ import path37 from "path";
50309
50142
  import { defineCommand as defineCommand210 } from "citty";
50310
50143
 
50311
50144
  // src/lib/streamUpload.ts
@@ -50656,7 +50489,7 @@ function ingestUrl(args) {
50656
50489
  }
50657
50490
  async function downloadThenIngest(args, country) {
50658
50491
  const vimeoCookie = captureVimeoCookie();
50659
- const workDir = await mkdtemp2(path39.join(tmpdir3(), "videos-ingest-"));
50492
+ const workDir = await mkdtemp2(path37.join(tmpdir3(), "videos-ingest-"));
50660
50493
  try {
50661
50494
  const probe = await probeYtDlp({ url: args.url, country, vimeoCookie, cookieDir: workDir });
50662
50495
  if (isAudioOnly(probe.info)) {
@@ -50792,7 +50625,7 @@ var searchCommand4 = defineCommand211({
50792
50625
  var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
50793
50626
 
50794
50627
  // src/commands/videos/upload.ts
50795
- import { readFile as readFile25, stat as stat8 } from "fs/promises";
50628
+ import { readFile as readFile23, stat as stat8 } from "fs/promises";
50796
50629
  import { basename as basename3, extname as extname4 } from "path";
50797
50630
  import { defineCommand as defineCommand212 } from "citty";
50798
50631
  var MIME_MAP = {
@@ -50889,7 +50722,7 @@ var uploadCommand2 = defineCommand212({
50889
50722
  originalFilename,
50890
50723
  descriptionContext
50891
50724
  });
50892
- const fileBuffer = await readFile25(filePath);
50725
+ const fileBuffer = await readFile23(filePath);
50893
50726
  const uploadResponse = await fetch(uploadUrl, {
50894
50727
  method: "PUT",
50895
50728
  headers: { "Content-Type": contentType },
@@ -52276,7 +52109,7 @@ function unknownFlagEnvelope(unknown, commandPath, suggestion) {
52276
52109
  };
52277
52110
  }
52278
52111
  function commandPathOf(root, argv) {
52279
- const path40 = [];
52112
+ const path38 = [];
52280
52113
  let command = root;
52281
52114
  for (const token of argv) {
52282
52115
  if (token === "--" || token.startsWith("-")) {
@@ -52287,10 +52120,10 @@ function commandPathOf(root, argv) {
52287
52120
  if (next === void 0 || typeof next !== "object") {
52288
52121
  break;
52289
52122
  }
52290
- path40.push(token);
52123
+ path38.push(token);
52291
52124
  command = next;
52292
52125
  }
52293
- return path40.join(" ");
52126
+ return path38.join(" ");
52294
52127
  }
52295
52128
  function refuseUnknownFlags(root, argv) {
52296
52129
  const unknown = findUnknownFlags(root, argv);