@koda-sl/baker-cli 0.375.0-dev.7b550440d → 0.375.0-dev.8dac6def3

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
@@ -133,7 +133,7 @@ import {
133
133
  } from "./chunk-7YNOGIWQ.js";
134
134
 
135
135
  // src/cli.ts
136
- import { defineCommand as defineCommand251, runMain } from "citty";
136
+ import { defineCommand as defineCommand250, runMain } from "citty";
137
137
 
138
138
  // src/cache-flag.ts
139
139
  var NO_CACHE_ARG = {
@@ -9802,7 +9802,7 @@ import { defineCommand as defineCommand19 } from "citty";
9802
9802
  function listed(resources) {
9803
9803
  return resources.map((resource) => resource.label ? `${resource.id} (${resource.label})` : resource.id).join("; ");
9804
9804
  }
9805
- function connectedResourceHints({ plural: plural2, singular, flag: flag3, resources }) {
9805
+ function connectedResourceHints({ plural, singular, flag: flag3, resources }) {
9806
9806
  if (resources.length === 0) {
9807
9807
  return [];
9808
9808
  }
@@ -9810,7 +9810,7 @@ function connectedResourceHints({ plural: plural2, singular, flag: flag3, resour
9810
9810
  return [`This company connected one ${singular}: ${listed(resources)}. Commands use it unless you pass ${flag3}.`];
9811
9811
  }
9812
9812
  return [
9813
- `This company connected ${resources.length} ${plural2}: ${listed(resources)}. Each command works on one, so pass ${flag3} \u2014 nothing is picked for you. A question about the whole business covers all ${resources.length}: answering from one and reporting it as the total is wrong.`
9813
+ `This company connected ${resources.length} ${plural}: ${listed(resources)}. Each command works on one, so pass ${flag3} \u2014 nothing is picked for you. A question about the whole business covers all ${resources.length}: answering from one and reporting it as the total is wrong.`
9814
9814
  ];
9815
9815
  }
9816
9816
 
@@ -12102,11 +12102,11 @@ function parseKeywordEntry(raw, defaultMatch) {
12102
12102
  function rawTextEntries(value, rawArgs) {
12103
12103
  return repeatedValues(rawArgs, "text", value).flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
12104
12104
  }
12105
- function rawFileEntries(path49) {
12106
- if (typeof path49 !== "string" || path49.length === 0) {
12105
+ function rawFileEntries(path48) {
12106
+ if (typeof path48 !== "string" || path48.length === 0) {
12107
12107
  return [];
12108
12108
  }
12109
- return readFileSync2(path49, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
12109
+ return readFileSync2(path48, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
12110
12110
  }
12111
12111
  function keywordEntries(args5, rawArgs) {
12112
12112
  const defaultMatch = typeof args5["match-type"] === "string" ? args5["match-type"].toUpperCase() : void 0;
@@ -12129,14 +12129,14 @@ function keywordEntries(args5, rawArgs) {
12129
12129
  }
12130
12130
  return entries;
12131
12131
  }
12132
- function loadJsonFileArg(path49) {
12133
- if (typeof path49 !== "string" || path49.length === 0) {
12132
+ function loadJsonFileArg(path48) {
12133
+ if (typeof path48 !== "string" || path48.length === 0) {
12134
12134
  return {};
12135
12135
  }
12136
- const inline = path49.trimStart().startsWith("{");
12137
- const source = inline ? "inline JSON" : path49;
12136
+ const inline = path48.trimStart().startsWith("{");
12137
+ const source = inline ? "inline JSON" : path48;
12138
12138
  try {
12139
- const parsed = JSON.parse(inline ? path49 : readFileSync2(path49, "utf8"));
12139
+ const parsed = JSON.parse(inline ? path48 : readFileSync2(path48, "utf8"));
12140
12140
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
12141
12141
  failWriteValidation(`${source} must contain a JSON object`);
12142
12142
  }
@@ -12273,10 +12273,10 @@ async function stageUpdate(kind, customerId, target2, payload, hints2) {
12273
12273
  async function stageTarget(kind, customerId, target2, hints2) {
12274
12274
  await stageGoogleOp({ kind, customerId, target: target2 }, hints2);
12275
12275
  }
12276
- async function draftAction(path49, body, chat) {
12276
+ async function draftAction(path48, body, chat) {
12277
12277
  try {
12278
12278
  const chatId = resolveChatId(chat);
12279
- const response = await apiPost(path49, { chatId, ...body });
12279
+ const response = await apiPost(path48, { chatId, ...body });
12280
12280
  writeJsonEnvelope(response);
12281
12281
  } catch (err) {
12282
12282
  handleGoogleError(err);
@@ -14694,14 +14694,14 @@ function mappingRowProblem(row) {
14694
14694
 
14695
14695
  // ../api/src/event-sources/template.ts
14696
14696
  var MENTION = /\{\{\s*([^{}]+?)\s*\}\}/g;
14697
- function mentionOf(path49) {
14698
- return `{{${path49}}}`;
14697
+ function mentionOf(path48) {
14698
+ return `{{${path48}}}`;
14699
14699
  }
14700
14700
  function templateMentions(template) {
14701
14701
  const seen = [];
14702
14702
  for (const match of template.matchAll(MENTION)) {
14703
- const path49 = (match[1] ?? "").trim();
14704
- if (path49 !== "" && !seen.includes(path49)) seen.push(path49);
14703
+ const path48 = (match[1] ?? "").trim();
14704
+ if (path48 !== "" && !seen.includes(path48)) seen.push(path48);
14705
14705
  }
14706
14706
  return seen;
14707
14707
  }
@@ -18071,17 +18071,17 @@ function ignoredColumnHints(columns) {
18071
18071
  `Ignored ${columns.length} column(s) that are not part of a conversion: ${columns.join(", ")}. A conversion carries an order id, a date, and something to match on: a click id (gclid / gbraid / wbraid), an email, a phone, or all four of givenName + familyName + country + postalCode. Optionally a value + currency, conversionCount, and eventSource (WEB / APP / IN_STORE / PHONE / OTHER). A column named just \`Name\` is ignored on purpose \u2014 Google needs the first and last name separately, so split it before re-running.`
18072
18072
  ];
18073
18073
  }
18074
- function readRowsFile(path49) {
18075
- const inline = path49.trimStart().startsWith("[") || path49.trimStart().startsWith("{");
18074
+ function readRowsFile(path48) {
18075
+ const inline = path48.trimStart().startsWith("[") || path48.trimStart().startsWith("{");
18076
18076
  let text2;
18077
18077
  try {
18078
- text2 = inline ? path49 : readFileSync4(path49, "utf8");
18078
+ text2 = inline ? path48 : readFileSync4(path48, "utf8");
18079
18079
  } catch (err) {
18080
- failWriteValidation(`could not read ${path49}: ${err instanceof Error ? err.message : String(err)}`);
18080
+ failWriteValidation(`could not read ${path48}: ${err instanceof Error ? err.message : String(err)}`);
18081
18081
  }
18082
18082
  const parsed = parseConversionRowsText(text2);
18083
18083
  if (!parsed.ok) {
18084
- failWriteValidation(`${inline ? "the conversions passed inline" : path49}: ${parsed.error}`);
18084
+ failWriteValidation(`${inline ? "the conversions passed inline" : path48}: ${parsed.error}`);
18085
18085
  }
18086
18086
  return { rows: parsed.rows, ignoredColumns: parsed.ignoredColumns };
18087
18087
  }
@@ -19956,19 +19956,19 @@ function failWriteValidation2(message) {
19956
19956
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
19957
19957
  process.exit(1);
19958
19958
  }
19959
- function loadJsonFileArg2(path49) {
19960
- if (typeof path49 !== "string" || path49.length === 0) {
19959
+ function loadJsonFileArg2(path48) {
19960
+ if (typeof path48 !== "string" || path48.length === 0) {
19961
19961
  return {};
19962
19962
  }
19963
19963
  try {
19964
- const parsed = JSON.parse(readFileSync5(path49, "utf8"));
19964
+ const parsed = JSON.parse(readFileSync5(path48, "utf8"));
19965
19965
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
19966
- failWriteValidation2(`${path49} must contain a JSON object`);
19966
+ failWriteValidation2(`${path48} must contain a JSON object`);
19967
19967
  }
19968
19968
  return parsed;
19969
19969
  } catch (err) {
19970
19970
  if (err instanceof SyntaxError) {
19971
- failWriteValidation2(`${path49} is not valid JSON: ${err.message}`);
19971
+ failWriteValidation2(`${path48} is not valid JSON: ${err.message}`);
19972
19972
  }
19973
19973
  throw err;
19974
19974
  }
@@ -20053,15 +20053,15 @@ function parseLocaleFlag(value) {
20053
20053
  }
20054
20054
  return { language: match[1], country: match[2].toUpperCase() };
20055
20055
  }
20056
- function loadTargetingFileArg(path49) {
20057
- if (typeof path49 !== "string" || path49.length === 0) {
20056
+ function loadTargetingFileArg(path48) {
20057
+ if (typeof path48 !== "string" || path48.length === 0) {
20058
20058
  return void 0;
20059
20059
  }
20060
- const parsed = loadJsonFileArg2(path49);
20060
+ const parsed = loadJsonFileArg2(path48);
20061
20061
  const criteria = parsed.targetingCriteria ?? parsed;
20062
20062
  if (!criteria.include) {
20063
20063
  failWriteValidation2(
20064
- `${path49} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
20064
+ `${path48} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
20065
20065
  );
20066
20066
  }
20067
20067
  return criteria;
@@ -20096,14 +20096,14 @@ function parseCsvLine(line) {
20096
20096
  cells.push(current);
20097
20097
  return cells.map((cell3) => cell3.trim());
20098
20098
  }
20099
- function parseListFileArg(path49, maxRows) {
20100
- if (typeof path49 !== "string" || path49.length === 0) {
20099
+ function parseListFileArg(path48, maxRows) {
20100
+ if (typeof path48 !== "string" || path48.length === 0) {
20101
20101
  return void 0;
20102
20102
  }
20103
- const raw = readFileSync5(path49, "utf8");
20103
+ const raw = readFileSync5(path48, "utf8");
20104
20104
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
20105
20105
  if (lines.length < 2) {
20106
- failWriteValidation2(`${path49} needs a header row and at least one data row`);
20106
+ failWriteValidation2(`${path48} needs a header row and at least one data row`);
20107
20107
  }
20108
20108
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
20109
20109
  const rows = [];
@@ -20122,7 +20122,7 @@ function parseListFileArg(path49, maxRows) {
20122
20122
  }
20123
20123
  }
20124
20124
  if (rows.length > maxRows) {
20125
- failWriteValidation2(`${path49} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
20125
+ failWriteValidation2(`${path48} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
20126
20126
  }
20127
20127
  return { columns, rows };
20128
20128
  }
@@ -20218,11 +20218,11 @@ function readPositionals(args5) {
20218
20218
  function splitIdList(raw) {
20219
20219
  return raw.split(",").map((id) => id.trim()).filter(Boolean);
20220
20220
  }
20221
- function idsFileEntries(path49) {
20222
- if (typeof path49 !== "string" || path49.length === 0) {
20221
+ function idsFileEntries(path48) {
20222
+ if (typeof path48 !== "string" || path48.length === 0) {
20223
20223
  return [];
20224
20224
  }
20225
- return readFileSync5(path49, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
20225
+ return readFileSync5(path48, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
20226
20226
  }
20227
20227
  function requireTargets(args5, entity) {
20228
20228
  const positionals = readPositionals(args5);
@@ -23022,9 +23022,9 @@ function compactRow(row) {
23022
23022
  ...destination.postUrn ? { postUrn: destination.postUrn } : {}
23023
23023
  };
23024
23024
  }
23025
- function readPath2(row, path49) {
23025
+ function readPath2(row, path48) {
23026
23026
  let current = row;
23027
- for (const segment of path49.split(".")) {
23027
+ for (const segment of path48.split(".")) {
23028
23028
  const record = asRecord(current);
23029
23029
  if (!record) return void 0;
23030
23030
  current = record[segment];
@@ -23034,10 +23034,10 @@ function readPath2(row, path49) {
23034
23034
  function projectFields(rows, paths) {
23035
23035
  return rows.map((row) => {
23036
23036
  const projected = {};
23037
- for (const path49 of paths) {
23038
- const value = readPath2(row, path49);
23037
+ for (const path48 of paths) {
23038
+ const value = readPath2(row, path48);
23039
23039
  if (value !== void 0) {
23040
- projected[path49] = value;
23040
+ projected[path48] = value;
23041
23041
  }
23042
23042
  }
23043
23043
  return projected;
@@ -24188,54 +24188,54 @@ function buildCustomConversionRule(input) {
24188
24188
  function customConversionRuleRefusal(rule) {
24189
24189
  return ruleNodeRefusal(rule, "rule");
24190
24190
  }
24191
- function branchRefusal(key, value, path49) {
24191
+ function branchRefusal(key, value, path48) {
24192
24192
  if (!Array.isArray(value) || value.length === 0) {
24193
- return `${path49}.${key} must be a non-empty array of conditions \u2014 an empty one counts every event the pixel sends`;
24193
+ return `${path48}.${key} must be a non-empty array of conditions \u2014 an empty one counts every event the pixel sends`;
24194
24194
  }
24195
24195
  for (const [index, child] of value.entries()) {
24196
- const refusal = ruleNodeRefusal(child, `${path49}.${key}[${index}]`);
24196
+ const refusal = ruleNodeRefusal(child, `${path48}.${key}[${index}]`);
24197
24197
  if (refusal) {
24198
24198
  return refusal;
24199
24199
  }
24200
24200
  }
24201
24201
  return void 0;
24202
24202
  }
24203
- function conditionRefusal(key, value, path49) {
24204
- return key === "and" || key === "or" ? branchRefusal(key, value, path49) : leafRefusal(key, value, path49);
24203
+ function conditionRefusal(key, value, path48) {
24204
+ return key === "and" || key === "or" ? branchRefusal(key, value, path48) : leafRefusal(key, value, path48);
24205
24205
  }
24206
- function ruleNodeRefusal(node, path49) {
24206
+ function ruleNodeRefusal(node, path48) {
24207
24207
  if (!isRecord2(node)) {
24208
- return `${path49} must be an object like {"URL":{"i_contains":"/thank-you"}}`;
24208
+ return `${path48} must be an object like {"URL":{"i_contains":"/thank-you"}}`;
24209
24209
  }
24210
24210
  const entries = Object.entries(node);
24211
24211
  if (entries.length === 0) {
24212
- return `${path49} is empty \u2014 a rule with no condition counts every event the pixel sends`;
24212
+ return `${path48} is empty \u2014 a rule with no condition counts every event the pixel sends`;
24213
24213
  }
24214
24214
  if (entries.length > 1) {
24215
- return `${path49} names ${entries.length} conditions side by side (${entries.map(([key]) => key).join(", ")}) \u2014 Meta reads one branch or one field test per object, so combine them with {"and":[\u2026]}`;
24215
+ return `${path48} names ${entries.length} conditions side by side (${entries.map(([key]) => key).join(", ")}) \u2014 Meta reads one branch or one field test per object, so combine them with {"and":[\u2026]}`;
24216
24216
  }
24217
24217
  for (const [key, value] of entries) {
24218
- const refusal = conditionRefusal(key, value, path49);
24218
+ const refusal = conditionRefusal(key, value, path48);
24219
24219
  if (refusal) {
24220
24220
  return refusal;
24221
24221
  }
24222
24222
  }
24223
24223
  return void 0;
24224
24224
  }
24225
- function leafRefusal(field, condition, path49) {
24225
+ function leafRefusal(field, condition, path48) {
24226
24226
  if (!isRecord2(condition)) {
24227
- return `${path49}.${field} must be a test like {"i_contains":"/thank-you"}, not a bare value`;
24227
+ return `${path48}.${field} must be a test like {"i_contains":"/thank-you"}, not a bare value`;
24228
24228
  }
24229
24229
  const tests = Object.entries(condition);
24230
24230
  if (tests.length === 0) {
24231
- return `${path49}.${field} names no test \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")}`;
24231
+ return `${path48}.${field} names no test \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")}`;
24232
24232
  }
24233
24233
  if (tests.length > 1) {
24234
- return `${path49}.${field} names ${tests.length} operators at once (${tests.map(([operator]) => operator).join(", ")}) \u2014 test a field once per condition and combine them with {"and":[\u2026]}`;
24234
+ return `${path48}.${field} names ${tests.length} operators at once (${tests.map(([operator]) => operator).join(", ")}) \u2014 test a field once per condition and combine them with {"and":[\u2026]}`;
24235
24235
  }
24236
24236
  for (const [operator] of tests) {
24237
24237
  if (!RULE_OPERATORS[operator]) {
24238
- return `${path49}.${field} uses "${operator}", which is not a Meta rule operator \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")} (URL matching is i_contains, not contains or includes)`;
24238
+ return `${path48}.${field} uses "${operator}", which is not a Meta rule operator \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")} (URL matching is i_contains, not contains or includes)`;
24239
24239
  }
24240
24240
  }
24241
24241
  return void 0;
@@ -24950,11 +24950,11 @@ var updateStatusSchema = z36.enum(UPDATE_STATUSES);
24950
24950
  function currencyMinimums2(currencyCode) {
24951
24951
  return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
24952
24952
  }
24953
- function validateDailyBudgetFloor(money, ctx, path49) {
24953
+ function validateDailyBudgetFloor(money, ctx, path48) {
24954
24954
  if (money?.currencyCode) {
24955
24955
  const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
24956
24956
  if (Number(money.amount) < min) {
24957
- ctx.addIssue({ code: "custom", path: path49, message: `below the ${min} ${money.currencyCode} daily minimum` });
24957
+ ctx.addIssue({ code: "custom", path: path48, message: `below the ${min} ${money.currencyCode} daily minimum` });
24958
24958
  }
24959
24959
  }
24960
24960
  }
@@ -25816,19 +25816,19 @@ function failWriteValidation3(message) {
25816
25816
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
25817
25817
  process.exit(1);
25818
25818
  }
25819
- function loadJsonFileArg3(path49) {
25820
- if (typeof path49 !== "string" || path49.length === 0) {
25819
+ function loadJsonFileArg3(path48) {
25820
+ if (typeof path48 !== "string" || path48.length === 0) {
25821
25821
  return {};
25822
25822
  }
25823
25823
  try {
25824
- const parsed = JSON.parse(readFileSync9(path49, "utf8"));
25824
+ const parsed = JSON.parse(readFileSync9(path48, "utf8"));
25825
25825
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
25826
- failWriteValidation3(`${path49} must contain a JSON object`);
25826
+ failWriteValidation3(`${path48} must contain a JSON object`);
25827
25827
  }
25828
25828
  return parsed;
25829
25829
  } catch (err) {
25830
25830
  if (err instanceof SyntaxError) {
25831
- failWriteValidation3(`${path49} is not valid JSON: ${err.message}`);
25831
+ failWriteValidation3(`${path48} is not valid JSON: ${err.message}`);
25832
25832
  }
25833
25833
  throw err;
25834
25834
  }
@@ -31429,12 +31429,12 @@ function flowExists(slug) {
31429
31429
  return existsSync3(join2(flowsDir(), slug, "_data.json"));
31430
31430
  }
31431
31431
  function readFlowTree(slug) {
31432
- const path49 = join2(flowsDir(), slug, "_data.json");
31433
- if (!existsSync3(path49)) {
31432
+ const path48 = join2(flowsDir(), slug, "_data.json");
31433
+ if (!existsSync3(path48)) {
31434
31434
  failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
31435
31435
  }
31436
31436
  try {
31437
- return JSON.parse(readFileSync11(path49, "utf-8"));
31437
+ return JSON.parse(readFileSync11(path48, "utf-8"));
31438
31438
  } catch (error) {
31439
31439
  failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
31440
31440
  }
@@ -32327,12 +32327,12 @@ function readPeopleFile(args5) {
32327
32327
  }
32328
32328
  function unreadablePeopleFile(args5) {
32329
32329
  if (!args5["people-file"]) return void 0;
32330
- const path49 = String(args5["people-file"]);
32330
+ const path48 = String(args5["people-file"]);
32331
32331
  try {
32332
- readFileSync12(path49, "utf8");
32332
+ readFileSync12(path48, "utf8");
32333
32333
  return void 0;
32334
32334
  } catch {
32335
- return `Couldn't read --people-file ${path49}. Check the path, or pass the people inline with --person.`;
32335
+ return `Couldn't read --people-file ${path48}. Check the path, or pass the people inline with --person.`;
32336
32336
  }
32337
32337
  }
32338
32338
  function peopleLimitError(args5) {
@@ -33304,11 +33304,11 @@ function parseFieldArgs(argv) {
33304
33304
  for (const pair of parseRepeated(argv, "--field")) {
33305
33305
  const eq = pair.indexOf("=");
33306
33306
  const field = eq === -1 ? pair : pair.slice(0, eq);
33307
- const path49 = eq === -1 ? "" : pair.slice(eq + 1).trim();
33307
+ const path48 = eq === -1 ? "" : pair.slice(eq + 1).trim();
33308
33308
  const problem = mappingRowProblem(field);
33309
33309
  if (problem !== null) throw new ConversionArgsError(problem);
33310
- if (path49 === "") throw new ConversionArgsError(`--field ${field} needs a path: --field ${field}=<dotted.path>.`);
33311
- mapping[field] = path49;
33310
+ if (path48 === "") throw new ConversionArgsError(`--field ${field} needs a path: --field ${field}=<dotted.path>.`);
33311
+ mapping[field] = path48;
33312
33312
  }
33313
33313
  return mapping;
33314
33314
  }
@@ -34905,11 +34905,11 @@ function unwrap(response) {
34905
34905
  }
34906
34906
  return response.data;
34907
34907
  }
34908
- async function readAvatars(path49, params2) {
34909
- return unwrap(await apiGet(path49, params2));
34908
+ async function readAvatars(path48, params2) {
34909
+ return unwrap(await apiGet(path48, params2));
34910
34910
  }
34911
- async function writeAvatars(path49, body) {
34912
- return unwrap(await apiPost(path49, body));
34911
+ async function writeAvatars(path48, body) {
34912
+ return unwrap(await apiPost(path48, body));
34913
34913
  }
34914
34914
 
34915
34915
  // src/commands/avatars/create.ts
@@ -35818,12 +35818,12 @@ function missingFontFiles(urls, available) {
35818
35818
  function planFontAdoption(sources, families) {
35819
35819
  const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
35820
35820
  const byFamily = /* @__PURE__ */ new Map();
35821
- for (const { path: path49, source } of sources) {
35822
- const dir = posix.dirname(path49);
35821
+ for (const { path: path48, source } of sources) {
35822
+ const dir = posix.dirname(path48);
35823
35823
  for (const face of declaredFontFaces(source)) {
35824
35824
  if (!wanted.has(face.family)) continue;
35825
35825
  const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
35826
- perFile.set(path49, [...perFile.get(path49) ?? [], rebaseFontFaceSrc(face.block, dir)]);
35826
+ perFile.set(path48, [...perFile.get(path48) ?? [], rebaseFontFaceSrc(face.block, dir)]);
35827
35827
  byFamily.set(face.family, perFile);
35828
35828
  }
35829
35829
  }
@@ -36023,9 +36023,9 @@ function fontsourceFamilies(css) {
36023
36023
  return out;
36024
36024
  }
36025
36025
  function asAuthored(css, normalized) {
36026
- const escaped2 = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36026
+ const escaped = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36027
36027
  const text2 = stripCssComments(css);
36028
- return text2.match(new RegExp(`["']${escaped2}["']`, "i"))?.[0]?.slice(1, -1) ?? text2.match(new RegExp(`(?<![\\w-])${escaped2}(?![\\w-])`, "i"))?.[0] ?? normalized;
36028
+ return text2.match(new RegExp(`["']${escaped}["']`, "i"))?.[0]?.slice(1, -1) ?? text2.match(new RegExp(`(?<![\\w-])${escaped}(?![\\w-])`, "i"))?.[0] ?? normalized;
36029
36029
  }
36030
36030
  function unresolvedBrandFamilies(css) {
36031
36031
  const declared = [...parseBrandTokens(css, "").fonts].filter((family) => !GENERIC_FAMILIES.has(family));
@@ -41015,10 +41015,10 @@ function runDirsToPrune(entries, keep, currentRunId) {
41015
41015
  return runs.slice(0, Math.max(0, runs.length - keep));
41016
41016
  }
41017
41017
  async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
41018
- const { readdir: readdir17 } = await import("fs/promises");
41018
+ const { readdir: readdir16 } = await import("fs/promises");
41019
41019
  let entries;
41020
41020
  try {
41021
- entries = await readdir17(outputsDir);
41021
+ entries = await readdir16(outputsDir);
41022
41022
  } catch {
41023
41023
  return;
41024
41024
  }
@@ -48607,10 +48607,10 @@ function parseValueExpression(raw) {
48607
48607
  return parts.map(parsePart);
48608
48608
  }
48609
48609
  function trackingFieldIds() {
48610
- const path49 = join4(flowsDir(), "..", "tracking.ts");
48611
- if (!existsSync6(path49)) return null;
48610
+ const path48 = join4(flowsDir(), "..", "tracking.ts");
48611
+ if (!existsSync6(path48)) return null;
48612
48612
  try {
48613
- const source = readFileSync14(path49, "utf-8");
48613
+ const source = readFileSync14(path48, "utf-8");
48614
48614
  const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
48615
48615
  if (!block2) return null;
48616
48616
  const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
@@ -49184,13 +49184,13 @@ function specsFromFile(parsed) {
49184
49184
  return `${destField}${type}=${entry?.value ?? ""}`;
49185
49185
  });
49186
49186
  }
49187
- function readSpecFile(path49) {
49187
+ function readSpecFile(path48) {
49188
49188
  let raw;
49189
49189
  try {
49190
- raw = path49 === "-" ? readFileSync15(0, "utf-8") : readFileSync15(path49, "utf-8");
49190
+ raw = path48 === "-" ? readFileSync15(0, "utf-8") : readFileSync15(path48, "utf-8");
49191
49191
  } catch (error) {
49192
49192
  refuse(
49193
- `Could not read ${path49 === "-" ? "the mapping from stdin" : `"${path49}"`}: ${error instanceof Error ? error.message : String(error)}`
49193
+ `Could not read ${path48 === "-" ? "the mapping from stdin" : `"${path48}"`}: ${error instanceof Error ? error.message : String(error)}`
49194
49194
  );
49195
49195
  }
49196
49196
  let parsed;
@@ -49198,7 +49198,7 @@ function readSpecFile(path49) {
49198
49198
  parsed = JSON.parse(raw);
49199
49199
  } catch (error) {
49200
49200
  refuse(
49201
- `${path49 === "-" ? "stdin" : `"${path49}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
49201
+ `${path48 === "-" ? "stdin" : `"${path48}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
49202
49202
  'Expected { "map": { "<destField>": "<value>", \u2026 } }'
49203
49203
  );
49204
49204
  }
@@ -49497,21 +49497,21 @@ var ARRAY_FIELDS = [
49497
49497
  "tagIds"
49498
49498
  ];
49499
49499
  var ARRAY_OWNERS = ["", "body"];
49500
- function dropUnsetOptionals(sideEffect, path49) {
49500
+ function dropUnsetOptionals(sideEffect, path48) {
49501
49501
  return OPTIONAL_STRINGS.flatMap((key) => {
49502
49502
  if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
49503
49503
  delete sideEffect[key];
49504
- return [{ path: path49, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
49504
+ return [{ path: path48, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
49505
49505
  });
49506
49506
  }
49507
- function fillNulledArrays(target2, prefix, path49) {
49507
+ function fillNulledArrays(target2, prefix, path48) {
49508
49508
  return ARRAY_FIELDS.flatMap((key) => {
49509
49509
  if (!(key in target2) || target2[key] !== null) return [];
49510
49510
  target2[key] = [];
49511
- return [{ path: path49, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
49511
+ return [{ path: path48, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
49512
49512
  });
49513
49513
  }
49514
- function tidyEmailRecipients(sideEffect, path49) {
49514
+ function tidyEmailRecipients(sideEffect, path48) {
49515
49515
  if (sideEffect.type !== "email") return [];
49516
49516
  const config = sideEffect.encryptedConfig;
49517
49517
  if (!config || typeof config !== "object" || Array.isArray(config)) return [];
@@ -49522,7 +49522,7 @@ function tidyEmailRecipients(sideEffect, path49) {
49522
49522
  const tidied = to.join(", ");
49523
49523
  if (tidied === raw) return [];
49524
49524
  config.email = tidied;
49525
- return [{ path: path49, change: "tidied the recipient list's spacing and separators" }];
49525
+ return [{ path: path48, change: "tidied the recipient list's spacing and separators" }];
49526
49526
  }
49527
49527
  function sideEffectsOf(node) {
49528
49528
  if (!Array.isArray(node.sideEffects)) return [];
@@ -49531,13 +49531,13 @@ function sideEffectsOf(node) {
49531
49531
  );
49532
49532
  }
49533
49533
  function normalizeSideEffect(sideEffect, where) {
49534
- const path49 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
49534
+ const path48 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
49535
49535
  const arrays = ARRAY_OWNERS.flatMap((owner) => {
49536
49536
  const target2 = owner ? sideEffect[owner] : sideEffect;
49537
49537
  if (!target2 || typeof target2 !== "object") return [];
49538
- return fillNulledArrays(target2, owner ? `${owner}.` : "", path49);
49538
+ return fillNulledArrays(target2, owner ? `${owner}.` : "", path48);
49539
49539
  });
49540
- return [...dropUnsetOptionals(sideEffect, path49), ...arrays, ...tidyEmailRecipients(sideEffect, path49)];
49540
+ return [...dropUnsetOptionals(sideEffect, path48), ...arrays, ...tidyEmailRecipients(sideEffect, path48)];
49541
49541
  }
49542
49542
  function normalizeFlowTree(tree) {
49543
49543
  const changes = [];
@@ -50927,10 +50927,10 @@ async function stageOps(ops) {
50927
50927
  handleError5(err);
50928
50928
  }
50929
50929
  }
50930
- async function draftAction2(path49, body, chat) {
50930
+ async function draftAction2(path48, body, chat) {
50931
50931
  const chatId = resolveChatId(chat);
50932
50932
  try {
50933
- const data = await apiPost(path49, { chatId, ...body });
50933
+ const data = await apiPost(path48, { chatId, ...body });
50934
50934
  writeJsonEnvelope({ ok: true, data });
50935
50935
  return data;
50936
50936
  } catch (err) {
@@ -53459,9 +53459,9 @@ async function readImageBuffer(pathOrUrl) {
53459
53459
  }
53460
53460
  return readFile28(pathOrUrl);
53461
53461
  }
53462
- async function isDirectory(path49) {
53462
+ async function isDirectory(path48) {
53463
53463
  try {
53464
- const s = await stat7(path49);
53464
+ const s = await stat7(path48);
53465
53465
  return s.isDirectory();
53466
53466
  } catch {
53467
53467
  return false;
@@ -53889,13 +53889,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
53889
53889
  }
53890
53890
  function disambiguate(paths) {
53891
53891
  const taken = /* @__PURE__ */ new Set();
53892
- return paths.map((path49) => {
53893
- if (!taken.has(path49)) {
53894
- taken.add(path49);
53895
- return path49;
53892
+ return paths.map((path48) => {
53893
+ if (!taken.has(path48)) {
53894
+ taken.add(path48);
53895
+ return path48;
53896
53896
  }
53897
- const ext = extname3(path49);
53898
- const stem = path49.slice(0, path49.length - ext.length);
53897
+ const ext = extname3(path48);
53898
+ const stem = path48.slice(0, path48.length - ext.length);
53899
53899
  let n = 2;
53900
53900
  while (taken.has(`${stem}-${n}${ext}`)) n += 1;
53901
53901
  const unique = `${stem}-${n}${ext}`;
@@ -54021,10 +54021,10 @@ async function runDownloads(plan) {
54021
54021
  const paths = disambiguate(fetched.map((item) => item.path));
54022
54022
  const downloaded = [];
54023
54023
  for (const [index, item] of fetched.entries()) {
54024
- const path49 = paths[index] ?? item.path;
54024
+ const path48 = paths[index] ?? item.path;
54025
54025
  try {
54026
- await atomicWrite(path49, item.buffer);
54027
- downloaded.push({ input: item.input, output: path49, bytes: item.buffer.length, contentType: item.contentType });
54026
+ await atomicWrite(path48, item.buffer);
54027
+ downloaded.push({ input: item.input, output: path48, bytes: item.buffer.length, contentType: item.contentType });
54028
54028
  } catch (err) {
54029
54029
  failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
54030
54030
  }
@@ -64623,7 +64623,7 @@ var schemaCommand2 = defineCommand208({
64623
64623
  });
64624
64624
 
64625
64625
  // src/commands/shopify/index.ts
64626
- import { defineCommand as defineCommand211 } from "citty";
64626
+ import { defineCommand as defineCommand210 } from "citty";
64627
64627
 
64628
64628
  // src/commands/shopify/buyers.ts
64629
64629
  import { defineCommand as defineCommand209 } from "citty";
@@ -65931,8 +65931,7 @@ function timingHints(answer) {
65931
65931
  const peak = [...answer.rows].sort((a, b) => b.orders - a.orders)[0];
65932
65932
  if (!peak || peak.orders === 0) return [];
65933
65933
  const zone = answer.window.timezone ? `, ${answer.window.timezone}` : "";
65934
- const when = answer.by === "hour" ? `at ${peak.label}` : answer.by === "month_of_year" ? `in ${peak.label}` : `on ${peak.label}`;
65935
- return [`Most orders are placed ${when} (store time${zone}): weight budgets and sends towards it.`];
65934
+ return [`Most orders are placed on ${peak.label} (store time${zone}): weight budgets and sends towards it.`];
65936
65935
  }
65937
65936
  function salesHints(answer) {
65938
65937
  const hints2 = [];
@@ -66271,245 +66270,6 @@ var segmentsCommand = defineCommand209({
66271
66270
  }
66272
66271
  });
66273
66272
 
66274
- // src/commands/shopify/promotions.ts
66275
- import { defineCommand as defineCommand210 } from "citty";
66276
-
66277
- // src/commands/shopify/landingLinks.ts
66278
- import { readdir as readdir16, readFile as readFile33, stat as stat11 } from "fs/promises";
66279
- import path47 from "path";
66280
- var PAGES_MAX = 300;
66281
- var FILE_BYTES_MAX = 256 * 1024;
66282
- function escaped(text2) {
66283
- return text2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
66284
- }
66285
- function evidenceIn(text2, keys) {
66286
- const evidence = [];
66287
- if (keys.buyUrls.some((url) => url && text2.includes(url))) evidence.push("buy_link");
66288
- const page = new RegExp(`/products/${escaped(keys.handle)}(?![A-Za-z0-9_-])`, "i");
66289
- if (keys.handle && page.test(text2)) evidence.push("product_page");
66290
- const option = keys.variantIds.some(
66291
- (id) => new RegExp(`(?:/cart/(?:\\d+:\\d+,)*${id}:|variant=${id}(?!\\d))`).test(text2)
66292
- );
66293
- if (option) evidence.push("variant_id");
66294
- return evidence;
66295
- }
66296
- function landingLinksOf(pages, keys) {
66297
- const bySlug = /* @__PURE__ */ new Map();
66298
- for (const page of pages) {
66299
- const found = new Set(page.files.flatMap((file) => evidenceIn(file.text, keys)));
66300
- if (found.size === 0) continue;
66301
- const slug = page.slug.replace(/--\d+$/, "");
66302
- const held = bySlug.get(slug) ?? /* @__PURE__ */ new Set();
66303
- for (const evidence of found) held.add(evidence);
66304
- bySlug.set(slug, held);
66305
- }
66306
- const order = ["buy_link", "product_page", "variant_id"];
66307
- return [...bySlug].map(([slug, evidence]) => ({ slug, evidence: order.filter((entry) => evidence.has(entry)) }));
66308
- }
66309
- async function isDir4(target2) {
66310
- try {
66311
- return (await stat11(target2)).isDirectory();
66312
- } catch {
66313
- return false;
66314
- }
66315
- }
66316
- async function readWorkspacePages(root) {
66317
- const dir = path47.join(root, "src/pages");
66318
- if (!await isDir4(dir)) return null;
66319
- let entries;
66320
- try {
66321
- entries = await readdir16(dir, { withFileTypes: true });
66322
- } catch {
66323
- return null;
66324
- }
66325
- const slugs = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("_")).map((entry) => entry.name);
66326
- const pages = [];
66327
- for (const slug of slugs.slice(0, PAGES_MAX)) {
66328
- const files = [];
66329
- for (const file of await landingGraphFiles(root, slug)) {
66330
- try {
66331
- const absolute = path47.join(root, file);
66332
- if ((await stat11(absolute)).size > FILE_BYTES_MAX) continue;
66333
- files.push({ path: file, text: await readFile33(absolute, "utf8") });
66334
- } catch {
66335
- }
66336
- }
66337
- pages.push({ slug, files });
66338
- }
66339
- return { pages, skipped: Math.max(0, slugs.length - PAGES_MAX) };
66340
- }
66341
-
66342
- // src/commands/shopify/promotionHints.ts
66343
- var PLATFORM = { "google-ads": "Google Ads", meta: "Meta" };
66344
- function plural(count2, one, many = `${one}s`) {
66345
- return `${count2} ${count2 === 1 ? one : many}`;
66346
- }
66347
- function promotionHints(answer, scan) {
66348
- const hints2 = [];
66349
- const active = answer.ads.filter((ad) => ad.status === "active");
66350
- const out = answer.product.stock !== "in_stock";
66351
- if (out && active.length > 0) {
66352
- hints2.push(
66353
- `${plural(active.length, "active ad")} still send people to \u201C${answer.product.title}\u201D, which is out of stock. Stage pausing them \u2014 Google: \`baker ads google ads pause <resource> --customer-id <account_id>\`; Meta: \`baker ads meta ads pause <id>\` (\`--full\` shows each one's id, resource and account). A pause is remembered for this product only because you read its promotions here.`
66354
- );
66355
- }
66356
- if (answer.shopping.length > 0 || answer.catalog_ads > 0) {
66357
- hints2.push(
66358
- "Shopping campaigns and catalog ads stop showing a product nobody can buy by themselves \u2014 never pause them for one product."
66359
- );
66360
- }
66361
- for (const missed of answer.checked.not_checked) {
66362
- hints2.push(
66363
- `${PLATFORM[missed.platform] ?? missed.platform} could not be checked (${missed.reason}); say so rather than that nothing runs there.`
66364
- );
66365
- }
66366
- for (const landing of answer.landings.filter((entry) => !entry.published)) {
66367
- hints2.push(`/${landing.slug} links to this product but is not live; no ad can send people to it yet.`);
66368
- }
66369
- if (answer.ads.length === 0 && answer.landings.length === 0 && answer.shopping.length === 0) {
66370
- hints2.push(`Nothing advertises \u201C${answer.product.title}\u201D that Baker can see: nothing to pause.`);
66371
- }
66372
- if (!scan.scanned) {
66373
- hints2.push(
66374
- "This workspace's pages were not read (no src/pages here), so landings are from Baker's last scan and measured visits only."
66375
- );
66376
- } else if (scan.skippedPages > 0) {
66377
- hints2.push(`${plural(scan.skippedPages, "page")} not checked for links to this product (past the 300-page bound).`);
66378
- }
66379
- if (!answer.remembered) {
66380
- hints2.push(
66381
- "This read was not remembered for a Session (no chat): a pause staged from it will not be undone when the product is back."
66382
- );
66383
- }
66384
- return hints2;
66385
- }
66386
- function holdName(hold) {
66387
- return `${PLATFORM[hold.platform]} ${hold.level.replace("_", " ")} ${hold.name ? `\u201C${hold.name}\u201D` : hold.entity_id}`;
66388
- }
66389
- function stockHoldHints(answer) {
66390
- const hints2 = [];
66391
- const held = answer.holds.filter((hold) => hold.state === "held");
66392
- if (answer.holds.length === 0)
66393
- hints2.push("Nothing was paused because this product ran out: there is nothing to resume.");
66394
- const resumable = held.filter((hold) => hold.verdict === "resumable");
66395
- if (resumable.length > 0) {
66396
- hints2.push(
66397
- `${resumable.length} can be resumed: stage it with \`baker ads google ads resume <resource> --customer-id <account_id>\` (Google) or \`baker ads meta ads resume <entity_id>\` (Meta; \`adsets\`/\`campaigns\` for those levels). Resume nothing else.`
66398
- );
66399
- }
66400
- for (const hold of held) {
66401
- if (hold.verdict === "changed_since") {
66402
- hints2.push(`${holdName(hold)} was changed by someone after Baker paused it: leave it, and tell the user.`);
66403
- } else if (hold.verdict === "still_promotes_out_of_stock") {
66404
- hints2.push(
66405
- `${holdName(hold)} still sends people to \u201C${hold.verdict_detail ?? "another product"}\u201D, which is out: leave it until that is back.`
66406
- );
66407
- } else if (hold.verdict === "cannot_confirm") {
66408
- hints2.push(
66409
- `${holdName(hold)} could not be confirmed as untouched since Baker paused it: leave it, and tell the user to check it.`
66410
- );
66411
- } else if (hold.verdict === "already_active") {
66412
- hints2.push(`${holdName(hold)} is already running again: nothing to do.`);
66413
- }
66414
- }
66415
- for (const session of answer.pending_sessions) {
66416
- hints2.push(
66417
- `The out-of-stock work \u201C${session.title}\u201D is still waiting for review and would pause ${plural(session.staged_pauses, "ad")} for this product: tell the user to discard it.`
66418
- );
66419
- }
66420
- return hints2;
66421
- }
66422
-
66423
- // src/commands/shopify/promotions.ts
66424
- registerSchema({
66425
- command: "shopify.promotions",
66426
- description: "Start here when a product runs out of stock or comes back: what is advertising it \u2014 ads on Google Ads and Meta that lead to its store page, its buy link or a landing that links to it (`via`), the landings themselves (from this workspace's pages, and from measured visits), and the Shopping campaigns and catalog ads that show it (they stop by themselves when it runs out \u2014 never pause them). Read it in the Session that pauses: a pause is remembered \u2014 and undone when the product is back in stock \u2014 only for a product whose promotions that Session read. `checked.not_checked` names a platform Baker could not read.",
66427
- args: {
66428
- product: { type: "positional", description: "Product id, handle, or a link to the product", required: true },
66429
- full: {
66430
- ...fullArg,
66431
- description: "Add each ad's id, account, campaign and ad group or ad set, its Google resource name and its URL"
66432
- }
66433
- }
66434
- });
66435
- registerSchema({
66436
- command: "shopify.stock-holds",
66437
- description: "Start here when a product is back in stock: the ads Baker paused because it ran out, each with a `verdict` \u2014 `resumable` (resume it), `still_out_of_stock`, `changed_since` (someone changed it after Baker paused it: leave it), `already_active`, `still_promotes_out_of_stock` (it also sends people to another product that is still out: `verdict_detail` names it), `cannot_confirm`. Resume only what is resumable. `pending_sessions` lists out-of-stock work still waiting for review that would pause this product's ads: tell the user to discard it.",
66438
- args: {
66439
- product: { type: "string", description: "Only one product's holds: its id, handle or link", required: false },
66440
- all: { type: "boolean", description: "Resolved holds too (resumed or released)", required: false, default: false },
66441
- full: fullArg
66442
- }
66443
- });
66444
- var promotionsCommand = defineCommand210({
66445
- meta: {
66446
- name: "promotions",
66447
- description: "What advertises one product: ads that lead to it, landings that link to it, Shopping that shows it. Example: baker shopify promotions 10310413942969"
66448
- },
66449
- args: {
66450
- product: { type: "positional", description: "Product id, handle, or a link to the product", required: true },
66451
- full: {
66452
- type: "boolean",
66453
- description: "Add ids, accounts, resource names and URLs",
66454
- required: false,
66455
- default: false
66456
- }
66457
- },
66458
- run: async ({ args: args5 }) => {
66459
- try {
66460
- const positionals = Array.isArray(args5._) ? args5._ : [];
66461
- if (positionals.length > 1) {
66462
- throw new ApiError("VALIDATION_ERROR", "product: Pass one product id, handle or product link.");
66463
- }
66464
- const { product, store } = await apiGet(
66465
- "/api/shopify/product",
66466
- params({ ref: args5.product })
66467
- );
66468
- const scan = await readWorkspacePages(process.cwd());
66469
- const linked = scan ? landingLinksOf(scan.pages, {
66470
- handle: product.handle,
66471
- variantIds: product.variants.map((variant) => variant.variantId),
66472
- buyUrls: product.variants.flatMap((variant) => variant.buyUrl ? [variant.buyUrl] : [])
66473
- }) : void 0;
66474
- const answer = await apiPost("/api/shopify/promotions", {
66475
- product: product.productId,
66476
- ...linked ? { linked_landings: linked.slice(0, 50) } : {},
66477
- scanned: scan !== null,
66478
- ...args5.full ? { full: true } : {}
66479
- });
66480
- emit2(answer, { store }, [
66481
- ...storeStateHints(store),
66482
- ...promotionHints(answer, { scanned: scan !== null, skippedPages: scan?.skipped ?? 0 })
66483
- ]);
66484
- } catch (err) {
66485
- fail9(err);
66486
- }
66487
- }
66488
- });
66489
- var stockHoldsCommand = defineCommand210({
66490
- meta: {
66491
- name: "stock-holds",
66492
- description: "The ads Baker paused because a product ran out, and whether each may be resumed now. Example: baker shopify stock-holds --product 10310413942969"
66493
- },
66494
- args: {
66495
- product: { type: "string", description: "Only one product: its id, handle or link", required: false },
66496
- all: { type: "boolean", description: "Resolved holds too", required: false, default: false },
66497
- full: { type: "boolean", description: "Everything Baker keeps", required: false, default: false }
66498
- },
66499
- run: async ({ args: args5 }) => {
66500
- try {
66501
- const answer = await apiGet(
66502
- "/api/shopify/stock-holds",
66503
- params({ product: args5.product, all: args5.all, full: args5.full })
66504
- );
66505
- const { store, ...data } = answer;
66506
- emit2(data, { store, count: answer.holds.length }, [...storeStateHints(store), ...stockHoldHints(answer)]);
66507
- } catch (err) {
66508
- fail9(err);
66509
- }
66510
- }
66511
- });
66512
-
66513
66273
  // src/commands/shopify/index.ts
66514
66274
  registerSchema({
66515
66275
  command: "shopify.store",
@@ -66638,7 +66398,7 @@ registerSchema({
66638
66398
  }
66639
66399
  }
66640
66400
  });
66641
- var salesCommand = defineCommand211({
66401
+ var salesCommand = defineCommand210({
66642
66402
  meta: {
66643
66403
  name: "sales",
66644
66404
  description: "What the store sold: orders, sales, refunds and net, by day, product, campaign or landing \u2014 or when buyers order (weekday, hour, month). Example: baker shopify sales --days 7 --by campaign"
@@ -66676,7 +66436,7 @@ var salesCommand = defineCommand211({
66676
66436
  }
66677
66437
  }
66678
66438
  });
66679
- var storeCommand = defineCommand211({
66439
+ var storeCommand = defineCommand210({
66680
66440
  meta: {
66681
66441
  name: "store",
66682
66442
  description: "The connected Shopify store: currency, countries, how many products, what is out of stock. Example: baker shopify store"
@@ -66693,7 +66453,7 @@ var storeCommand = defineCommand211({
66693
66453
  }
66694
66454
  }
66695
66455
  });
66696
- var productsCommand = defineCommand211({
66456
+ var productsCommand = defineCommand210({
66697
66457
  meta: {
66698
66458
  name: "products",
66699
66459
  description: 'What the store sells, with price and stock. Example: baker shopify products --search "snowboard" --stock out_of_stock'
@@ -66739,7 +66499,7 @@ var productsCommand = defineCommand211({
66739
66499
  }
66740
66500
  }
66741
66501
  });
66742
- var productCommand = defineCommand211({
66502
+ var productCommand = defineCommand210({
66743
66503
  meta: {
66744
66504
  name: "product",
66745
66505
  description: "One product: options with buy links, prices by country, stock, photo imageIds, video playbackIds. Accepts an id, handle or link. Example: baker shopify product the-complete-snowboard --content"
@@ -66802,7 +66562,7 @@ var productCommand = defineCommand211({
66802
66562
  }
66803
66563
  }
66804
66564
  });
66805
- var collectionsCommand = defineCommand211({
66565
+ var collectionsCommand = defineCommand210({
66806
66566
  meta: {
66807
66567
  name: "collections",
66808
66568
  description: "The store's collections, with the handles --collection takes. Example: baker shopify collections --full"
@@ -66827,7 +66587,7 @@ var collectionsCommand = defineCommand211({
66827
66587
  }
66828
66588
  }
66829
66589
  });
66830
- var stockCommand2 = defineCommand211({
66590
+ var stockCommand2 = defineCommand210({
66831
66591
  meta: {
66832
66592
  name: "stock",
66833
66593
  description: "Every product with options out of stock, naming them. Example: baker shopify stock"
@@ -66851,12 +66611,11 @@ var stockCommand2 = defineCommand211({
66851
66611
  }
66852
66612
  }
66853
66613
  });
66854
- var shopifyCommand = defineCommand211({
66614
+ var shopifyCommand = defineCommand210({
66855
66615
  meta: {
66856
66616
  name: "shopify",
66857
66617
  description: `Read the connected Shopify store as Baker keeps it \u2014 products, prices by country, stock, collections,
66858
- product photos, what it sold, who buys, where and what, and what advertises each product. Read-only:
66859
- nothing here changes the store.
66618
+ product photos, what it sold, and who buys, where and what. Read-only: nothing here changes the store.
66860
66619
 
66861
66620
  Examples:
66862
66621
  baker shopify store # currency, countries, how many products, what is out of stock
@@ -66878,8 +66637,6 @@ Examples:
66878
66637
  baker shopify buyer 1042 # one numbered customer's orders
66879
66638
  baker shopify segments # best, loyal, at risk, new, one-time \u2014 and who to find more of
66880
66639
  baker shopify cohorts --months 12 # buyers by first-order month: who came back
66881
- baker shopify promotions <product> # what advertises it: ads, landings, Shopping (read before pausing)
66882
- baker shopify stock-holds --product <product> # what Baker paused because it ran out, and what may be resumed
66883
66640
 
66884
66641
  Product photos are already in the image library: place them by imageId
66885
66642
  (baker images download <imageIds> --out src/pages/<page>/_images/), never by a cdn.shopify.com link.
@@ -66902,17 +66659,15 @@ Full guide: __tooling__/docs/tools/baker/shopify.md`
66902
66659
  countries: countriesCommand2,
66903
66660
  "best-sellers": bestSellersCommand,
66904
66661
  cohorts: cohortsCommand,
66905
- segments: segmentsCommand,
66906
- promotions: promotionsCommand,
66907
- "stock-holds": stockHoldsCommand
66662
+ segments: segmentsCommand
66908
66663
  }
66909
66664
  });
66910
66665
 
66911
66666
  // src/commands/studio/index.ts
66912
- import { defineCommand as defineCommand220 } from "citty";
66667
+ import { defineCommand as defineCommand219 } from "citty";
66913
66668
 
66914
66669
  // src/commands/studio/animate.ts
66915
- import { defineCommand as defineCommand212 } from "citty";
66670
+ import { defineCommand as defineCommand211 } from "citty";
66916
66671
 
66917
66672
  // src/commands/studio/spokenPace.ts
66918
66673
  var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
@@ -67138,7 +66893,7 @@ function parseImageRefs(spec) {
67138
66893
  }
67139
66894
  var defaultDeps = {
67140
66895
  ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
67141
- upload: (path49) => uploadLocalImage({ file: path49, contentType: detectImageContentType(path49), source: "uploaded" })
66896
+ upload: (path48) => uploadLocalImage({ file: path48, contentType: detectImageContentType(path48), source: "uploaded" })
67142
66897
  };
67143
66898
  async function resolveLibraryImageIds(spec, limit2, deps = defaultDeps) {
67144
66899
  const refs = parseImageRefs(spec);
@@ -67158,10 +66913,10 @@ async function resolveLibraryImageIds(spec, limit2, deps = defaultDeps) {
67158
66913
  }
67159
66914
  return { imageIds, added };
67160
66915
  }
67161
- function uploadFailure(path49) {
66916
+ function uploadFailure(path48) {
67162
66917
  return (error) => {
67163
66918
  if (error instanceof ApiError) throw error;
67164
- throw new ApiError("VALIDATION_ERROR", `Could not read "${path49}" as an image.`);
66919
+ throw new ApiError("VALIDATION_ERROR", `Could not read "${path48}" as an image.`);
67165
66920
  };
67166
66921
  }
67167
66922
 
@@ -67425,7 +67180,7 @@ async function adByHandHintFor(body) {
67425
67180
  return null;
67426
67181
  }
67427
67182
  }
67428
- var animateCommand = defineCommand212({
67183
+ var animateCommand = defineCommand211({
67429
67184
  meta: {
67430
67185
  name: "animate",
67431
67186
  description: "Render a clip. With an image the look is already fixed, so the prompt describes MOVEMENT \u2014 what the camera does, what the subject does, in what order. With --from text there is no image and the prompt is the whole shot.\n\nA rendered clip is NOT usable anywhere until you keep it: `baker studio keep <id> --slot N` is what puts it in the video library. Takes nobody keeps are never ingested, which is what makes a rejected batch cheap.\n\nFor anything longer than 15 seconds, or to build on footage that already exists, use --model bytedance/seedance-2.5: it renders 4-30s and is the only model that reads an existing clip or an existing soundtrack.\n\nExamples:\n baker studio animate 'slow push in, model turns to camera and smiles' --image j57abc123def456ghi789\n baker studio animate 'she looks to camera and says: \"Hola, soy Elena\"' --avatar elena --quality 720p --aspect-ratio 9:16\n baker studio animate 'handheld drift right, steam rising from the cup' --image './out/hero.png' --duration 6 --quality 1080p\n baker studio animate 'product rotates once on a turntable' --image j57abc\u2026,j57def\u2026 --from references\n baker studio animate 'she keeps walking, camera stays with her, then she stops and looks up' --image j57abc\u2026 --from references --from-clip j57batch\u2026:0 --model bytedance/seedance-2.5 --duration 20\n baker studio animate 'hold on the product, then a slow push-in' --from references --from-video j57vid\u2026 --model bytedance/seedance-2.5\n baker studio animate 'slow drone pull-back over a solar farm at golden hour, no people' --from text --model bytedance/seedance-2.5 --duration 12"
@@ -67550,7 +67305,7 @@ var animateCommand = defineCommand212({
67550
67305
  });
67551
67306
 
67552
67307
  // src/commands/studio/generate.ts
67553
- import { defineCommand as defineCommand213 } from "citty";
67308
+ import { defineCommand as defineCommand212 } from "citty";
67554
67309
  var MODEL_LIST2 = IMAGE_MODEL_IDS;
67555
67310
  var DEFAULT_MAX_WAIT_MS2 = 24e4;
67556
67311
  registerSchema({
@@ -67686,7 +67441,7 @@ function buildGenerateBody(args5, prompt) {
67686
67441
  }
67687
67442
  return body;
67688
67443
  }
67689
- var generateCommand = defineCommand213({
67444
+ var generateCommand = defineCommand212({
67690
67445
  meta: {
67691
67446
  name: "generate",
67692
67447
  description: "Start here to make an image. Renders 1-8 takes of one brief, ingests each into the media library as it lands, and shows the batch in the dashboard Studio next to the ones the client ran.\n\nModel choice: google/gemini-3.1-flash-image-preview (default \u2014 fast, best at editing a reference and at extreme ratios), google/gemini-3-pro-image-preview (highest fidelity, slower), openai/gpt-image-2 (photoreal and the cleanest in-image text \u2014 no --image-size, no 4:5 / 5:4), recraft/recraft-v4.1-pro-vector (vector/flat marks with palette control).\n\n--reference is the biggest quality lever there is: a real logo, product shot, Pinterest pin or sandbox screenshot beats any amount of adjectives.\n\nExamples:\n baker studio generate 'matte black bottle on wet marble, hard studio light, 35mm' --aspect-ratio 3:2 --count 3\n baker studio generate 'this bottle on a sunlit kitchen counter' --reference './src/brand/product.png,https://\u2026/kitchen.jpg'\n baker studio generate 'founder-style selfie, kitchen background, natural light' --skill ugc-selfie-hook\n baker studio generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
@@ -67769,7 +67524,7 @@ var generateCommand = defineCommand213({
67769
67524
  });
67770
67525
 
67771
67526
  // src/commands/studio/get.ts
67772
- import { defineCommand as defineCommand214 } from "citty";
67527
+ import { defineCommand as defineCommand213 } from "citty";
67773
67528
  registerSchema({
67774
67529
  command: "studio.get",
67775
67530
  description: "Read one Studio batch: every take, where it lives, and why a take is missing. This is how you pick up a batch that was still rendering when the start command returned.",
@@ -67778,7 +67533,7 @@ registerSchema({
67778
67533
  full: { type: "boolean", description: "Include settings, references and attribution", required: false }
67779
67534
  }
67780
67535
  });
67781
- var getCommand5 = defineCommand214({
67536
+ var getCommand5 = defineCommand213({
67782
67537
  meta: {
67783
67538
  name: "get",
67784
67539
  description: "Read one Studio batch \u2014 the takes, their urls, whether each is in the library, and the reason for any that failed.\n\nExample: baker studio get j57abc123def456ghi789\nExample: baker studio get j57abc123def456ghi789 --full"
@@ -67807,7 +67562,7 @@ var getCommand5 = defineCommand214({
67807
67562
  });
67808
67563
 
67809
67564
  // src/commands/studio/improve.ts
67810
- import { defineCommand as defineCommand215 } from "citty";
67565
+ import { defineCommand as defineCommand214 } from "citty";
67811
67566
  var DESCRIPTION2 = "Sharpen a rough brief into directed art direction \u2014 the same rewrite the client gets from the wand in the Studio prompt bar. Reach for it when you are relaying the CLIENT's own words and want them shaped without substituting your voice; when you are writing the art direction yourself, just write it, because you will do a better job than this does.";
67812
67567
  registerSchema({
67813
67568
  command: "studio.improve",
@@ -67832,7 +67587,7 @@ registerSchema({
67832
67587
  }
67833
67588
  }
67834
67589
  });
67835
- var improveCommand = defineCommand215({
67590
+ var improveCommand = defineCommand214({
67836
67591
  meta: {
67837
67592
  name: "improve",
67838
67593
  description: `${DESCRIPTION2}
@@ -67876,7 +67631,7 @@ Examples:
67876
67631
  });
67877
67632
 
67878
67633
  // src/commands/studio/keep.ts
67879
- import { defineCommand as defineCommand216 } from "citty";
67634
+ import { defineCommand as defineCommand215 } from "citty";
67880
67635
  registerSchema({
67881
67636
  command: "studio.keep",
67882
67637
  description: "Mark one take as the keeper. For an image this stars it, so the client reviewing the batch sees which one you used. For a CLIP it is the step that puts it in the video library \u2014 until then the clip cannot be used in a canvas, a landing, or an ad.",
@@ -67886,7 +67641,7 @@ registerSchema({
67886
67641
  undo: { type: "boolean", description: "Un-star an image, or take a kept clip back out", required: false }
67887
67642
  }
67888
67643
  });
67889
- var keepCommand = defineCommand216({
67644
+ var keepCommand = defineCommand215({
67890
67645
  meta: {
67891
67646
  name: "keep",
67892
67647
  description: "Mark one take as the keeper. An image gets starred (it was already in the library); a clip gets INGESTED into the video library, which is what makes it usable anywhere else.\n\nExample: baker studio keep j57abc123def456ghi789 --slot 2\nExample: baker studio keep j57abc123def456ghi789 --slot 2 --undo"
@@ -67937,7 +67692,7 @@ var keepCommand = defineCommand216({
67937
67692
  });
67938
67693
 
67939
67694
  // src/commands/studio/list.ts
67940
- import { defineCommand as defineCommand217 } from "citty";
67695
+ import { defineCommand as defineCommand216 } from "citty";
67941
67696
  registerSchema({
67942
67697
  command: "studio.list",
67943
67698
  description: "Recent Studio batches for THIS conversation, newest first \u2014 what you have already generated, so you re-use a take instead of paying for it twice. `--all` widens it to everything the company generated, including what people ran themselves in the dashboard.",
@@ -67948,7 +67703,7 @@ registerSchema({
67948
67703
  full: { type: "boolean", description: "Include settings, references and attribution", required: false }
67949
67704
  }
67950
67705
  });
67951
- var listCommand18 = defineCommand217({
67706
+ var listCommand18 = defineCommand216({
67952
67707
  meta: {
67953
67708
  name: "list",
67954
67709
  description: "Recent Studio batches, newest first. Scoped to this conversation unless you pass --all.\n\nExample: baker studio list\nExample: baker studio list --kind video --limit 5\nExample: baker studio list --all # includes batches the client ran in the dashboard"
@@ -67982,7 +67737,7 @@ var listCommand18 = defineCommand217({
67982
67737
  });
67983
67738
 
67984
67739
  // src/commands/studio/models.ts
67985
- import { defineCommand as defineCommand218 } from "citty";
67740
+ import { defineCommand as defineCommand217 } from "citty";
67986
67741
  var DESCRIPTION3 = "What each Studio model actually accepts: its shapes, resolutions, clip lengths, prompt character cap, how many reference images it takes, and which knobs it has. Read this before a batch you care about \u2014 the models disagree far more than they look like they do, and a setting the chosen model does not have is REFUSED, not ignored.";
67987
67742
  registerSchema({
67988
67743
  command: "studio.models",
@@ -68069,7 +67824,7 @@ function buildModelCards(kind, model) {
68069
67824
  const selected = model ? ids.filter((id) => id === model) : ids;
68070
67825
  return selected.map((id) => build(id));
68071
67826
  }
68072
- var modelsCommand = defineCommand218({
67827
+ var modelsCommand = defineCommand217({
68073
67828
  meta: {
68074
67829
  name: "models",
68075
67830
  description: `${DESCRIPTION3}
@@ -68116,13 +67871,13 @@ Examples:
68116
67871
  });
68117
67872
 
68118
67873
  // src/commands/studio/skills.ts
68119
- import { defineCommand as defineCommand219 } from "citty";
67874
+ import { defineCommand as defineCommand218 } from "citty";
68120
67875
  registerSchema({
68121
67876
  command: "studio.skills",
68122
67877
  description: "The craft directions `studio generate --skill <id>` accepts. Each one carries directed art direction plus the model, shape and take count it wants, so you pick a look by name instead of writing the boilerplate yourself.",
68123
67878
  args: {}
68124
67879
  });
68125
- var skillsCommand = defineCommand219({
67880
+ var skillsCommand = defineCommand218({
68126
67881
  meta: {
68127
67882
  name: "skills",
68128
67883
  description: "List the craft directions available to `baker studio generate --skill <id>` \u2014 what each one is for, whether it wants a reference image, and the model/shape/count it defaults to.\n\nExample: baker studio skills"
@@ -68146,7 +67901,7 @@ var skillsCommand = defineCommand219({
68146
67901
  });
68147
67902
 
68148
67903
  // src/commands/studio/index.ts
68149
- var studioCommand = defineCommand220({
67904
+ var studioCommand = defineCommand219({
68150
67905
  meta: {
68151
67906
  name: "studio",
68152
67907
  description: `Make new imagery and clips. Every batch is recorded and shows up in the dashboard Studio for the client to review, labelled with this conversation.
@@ -68189,10 +67944,10 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
68189
67944
  });
68190
67945
 
68191
67946
  // src/commands/tag-manager/index.ts
68192
- import { defineCommand as defineCommand224 } from "citty";
67947
+ import { defineCommand as defineCommand223 } from "citty";
68193
67948
 
68194
67949
  // src/commands/tag-manager/draft.ts
68195
- import { defineCommand as defineCommand221 } from "citty";
67950
+ import { defineCommand as defineCommand220 } from "citty";
68196
67951
 
68197
67952
  // src/commands/tag-manager/shared.ts
68198
67953
  import { readFileSync as readFileSync20 } from "fs";
@@ -68259,10 +68014,10 @@ async function stageOp4(op) {
68259
68014
  handleError8(err);
68260
68015
  }
68261
68016
  }
68262
- async function draftAction3(path49, body, chat) {
68017
+ async function draftAction3(path48, body, chat) {
68263
68018
  const chatId = resolveChatId(chat);
68264
68019
  try {
68265
- const data = await apiPost(path49, { chatId, ...body });
68020
+ const data = await apiPost(path48, { chatId, ...body });
68266
68021
  writeJsonEnvelope({ ok: true, data });
68267
68022
  return data;
68268
68023
  } catch (err) {
@@ -68315,13 +68070,13 @@ registerSchema({
68315
68070
  chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
68316
68071
  }
68317
68072
  });
68318
- var draftCommand5 = defineCommand221({
68073
+ var draftCommand5 = defineCommand220({
68319
68074
  meta: {
68320
68075
  name: "draft",
68321
68076
  description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
68322
68077
  },
68323
68078
  subCommands: {
68324
- list: defineCommand221({
68079
+ list: defineCommand220({
68325
68080
  meta: {
68326
68081
  name: "list",
68327
68082
  description: "Review everything staged on this chat (--json for the raw envelope)"
@@ -68334,7 +68089,7 @@ var draftCommand5 = defineCommand221({
68334
68089
  await draftList2(args5.json === true, args5.chat);
68335
68090
  }
68336
68091
  }),
68337
- show: defineCommand221({
68092
+ show: defineCommand220({
68338
68093
  meta: {
68339
68094
  name: "show",
68340
68095
  description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
@@ -68351,7 +68106,7 @@ var draftCommand5 = defineCommand221({
68351
68106
  );
68352
68107
  }
68353
68108
  }),
68354
- amend: defineCommand221({
68109
+ amend: defineCommand220({
68355
68110
  meta: {
68356
68111
  name: "amend",
68357
68112
  description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-validates. Use this instead of remove + re-create."
@@ -68368,7 +68123,7 @@ var draftCommand5 = defineCommand221({
68368
68123
  });
68369
68124
  }
68370
68125
  }),
68371
- remove: defineCommand221({
68126
+ remove: defineCommand220({
68372
68127
  meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
68373
68128
  args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
68374
68129
  run: async ({ args: args5 }) => {
@@ -68377,7 +68132,7 @@ var draftCommand5 = defineCommand221({
68377
68132
  });
68378
68133
  }
68379
68134
  }),
68380
- clear: defineCommand221({
68135
+ clear: defineCommand220({
68381
68136
  meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
68382
68137
  run: async () => {
68383
68138
  await draftAction3("/api/tag-manager/draft/clear", {});
@@ -68387,7 +68142,7 @@ var draftCommand5 = defineCommand221({
68387
68142
  });
68388
68143
 
68389
68144
  // src/commands/tag-manager/read.ts
68390
- import { defineCommand as defineCommand222 } from "citty";
68145
+ import { defineCommand as defineCommand221 } from "citty";
68391
68146
  registerSchema({
68392
68147
  command: "tagManager.containers",
68393
68148
  description: "List the Google Tag Manager containers this company's connection can reach. Every container the company connected is flagged `connected: true` \u2014 there can be several, and Baker may read and change all of them. Start here to confirm which containers you are managing.",
@@ -68428,7 +68183,7 @@ function containersHints(containers) {
68428
68183
  }))
68429
68184
  });
68430
68185
  }
68431
- var containersCommand = defineCommand222({
68186
+ var containersCommand = defineCommand221({
68432
68187
  meta: {
68433
68188
  name: "containers",
68434
68189
  description: `List Tag Manager containers reachable by this company's connection.
@@ -68445,7 +68200,7 @@ Start here:
68445
68200
  }
68446
68201
  }
68447
68202
  });
68448
- var readCommand = defineCommand222({
68203
+ var readCommand = defineCommand221({
68449
68204
  meta: {
68450
68205
  name: "read",
68451
68206
  description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
@@ -68487,7 +68242,7 @@ Examples:
68487
68242
  });
68488
68243
 
68489
68244
  // src/commands/tag-manager/write-commands.ts
68490
- import { defineCommand as defineCommand223 } from "citty";
68245
+ import { defineCommand as defineCommand222 } from "citty";
68491
68246
  var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
68492
68247
  var ENTITIES = [
68493
68248
  {
@@ -68543,10 +68298,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
68543
68298
  });
68544
68299
  }
68545
68300
  function entityCommand(entity, noun, example) {
68546
- return defineCommand223({
68301
+ return defineCommand222({
68547
68302
  meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
68548
68303
  subCommands: {
68549
- create: defineCommand223({
68304
+ create: defineCommand222({
68550
68305
  meta: {
68551
68306
  name: "create",
68552
68307
  description: `Stage a new ${noun}
@@ -68568,7 +68323,7 @@ Examples:
68568
68323
  });
68569
68324
  }
68570
68325
  }),
68571
- update: defineCommand223({
68326
+ update: defineCommand222({
68572
68327
  meta: {
68573
68328
  name: "update",
68574
68329
  description: `Stage an update to an existing ${noun} (pass its id or path)`
@@ -68588,7 +68343,7 @@ Examples:
68588
68343
  });
68589
68344
  }
68590
68345
  }),
68591
- delete: defineCommand223({
68346
+ delete: defineCommand222({
68592
68347
  meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
68593
68348
  args: {
68594
68349
  id: { type: "positional", description: `${noun} id or path`, required: false },
@@ -68629,7 +68384,7 @@ function builtinTypes(args5) {
68629
68384
  }
68630
68385
  return raw.split(",").map((entry) => entry.trim());
68631
68386
  }
68632
- var builtinCommand = defineCommand223({
68387
+ var builtinCommand = defineCommand222({
68633
68388
  meta: {
68634
68389
  name: "builtin",
68635
68390
  description: `Enable or disable built-in variables
@@ -68639,7 +68394,7 @@ Examples:
68639
68394
  baker tag-manager builtin disable --types formId`
68640
68395
  },
68641
68396
  subCommands: {
68642
- enable: defineCommand223({
68397
+ enable: defineCommand222({
68643
68398
  meta: { name: "enable", description: "Stage enabling built-in variables" },
68644
68399
  args: {
68645
68400
  types: { type: "string", description: "Comma-separated types", required: false },
@@ -68653,7 +68408,7 @@ Examples:
68653
68408
  });
68654
68409
  }
68655
68410
  }),
68656
- disable: defineCommand223({
68411
+ disable: defineCommand222({
68657
68412
  meta: { name: "disable", description: "Stage disabling built-in variables" },
68658
68413
  args: {
68659
68414
  types: { type: "string", description: "Comma-separated types", required: false },
@@ -68671,7 +68426,7 @@ Examples:
68671
68426
  });
68672
68427
 
68673
68428
  // src/commands/tag-manager/index.ts
68674
- var tagManagerCommand = defineCommand224({
68429
+ var tagManagerCommand = defineCommand223({
68675
68430
  meta: {
68676
68431
  name: "tag-manager",
68677
68432
  description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
@@ -68708,7 +68463,7 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
68708
68463
  });
68709
68464
 
68710
68465
  // src/commands/tags/index.ts
68711
- import { defineCommand as defineCommand225 } from "citty";
68466
+ import { defineCommand as defineCommand224 } from "citty";
68712
68467
 
68713
68468
  // src/commands/tags/shared.ts
68714
68469
  function failApi3(err) {
@@ -68788,7 +68543,7 @@ async function listTags(json) {
68788
68543
  var listArgs11 = {
68789
68544
  json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
68790
68545
  };
68791
- var listCommand19 = defineCommand225({
68546
+ var listCommand19 = defineCommand224({
68792
68547
  meta: {
68793
68548
  name: "list",
68794
68549
  description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
@@ -68807,7 +68562,7 @@ async function listDraft4(chat) {
68807
68562
  failApi3(err);
68808
68563
  }
68809
68564
  }
68810
- var draftCommand6 = defineCommand225({
68565
+ var draftCommand6 = defineCommand224({
68811
68566
  meta: {
68812
68567
  name: "draft",
68813
68568
  description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create). Takes --chat <id> to read an earlier chat's staged changes instead."
@@ -68817,7 +68572,7 @@ var draftCommand6 = defineCommand225({
68817
68572
  await listDraft4(args5.chat);
68818
68573
  }
68819
68574
  });
68820
- var tagsCommand4 = defineCommand225({
68575
+ var tagsCommand4 = defineCommand224({
68821
68576
  meta: {
68822
68577
  name: "tags",
68823
68578
  description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
@@ -68846,10 +68601,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
68846
68601
  });
68847
68602
 
68848
68603
  // src/commands/testimonials/index.ts
68849
- import { defineCommand as defineCommand229 } from "citty";
68604
+ import { defineCommand as defineCommand228 } from "citty";
68850
68605
 
68851
68606
  // src/commands/testimonials/get.ts
68852
- import { defineCommand as defineCommand226 } from "citty";
68607
+ import { defineCommand as defineCommand225 } from "citty";
68853
68608
  registerSchema({
68854
68609
  command: "testimonials.get",
68855
68610
  description: "Get a single testimonial by ID",
@@ -68857,7 +68612,7 @@ registerSchema({
68857
68612
  id: { type: "string", description: "Testimonial ID", required: true }
68858
68613
  }
68859
68614
  });
68860
- var getCommand6 = defineCommand226({
68615
+ var getCommand6 = defineCommand225({
68861
68616
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
68862
68617
  args: {
68863
68618
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -68894,7 +68649,7 @@ var getCommand6 = defineCommand226({
68894
68649
  });
68895
68650
 
68896
68651
  // src/commands/testimonials/list.ts
68897
- import { defineCommand as defineCommand227 } from "citty";
68652
+ import { defineCommand as defineCommand226 } from "citty";
68898
68653
 
68899
68654
  // src/commands/testimonials/emptyCorpusHints.ts
68900
68655
  function resolveEmptyReason({
@@ -69051,7 +68806,7 @@ function buildListParams(args5) {
69051
68806
  }
69052
68807
  return params2;
69053
68808
  }
69054
- var listCommand20 = defineCommand227({
68809
+ var listCommand20 = defineCommand226({
69055
68810
  meta: {
69056
68811
  name: "list",
69057
68812
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -69111,7 +68866,7 @@ var listCommand20 = defineCommand227({
69111
68866
  });
69112
68867
 
69113
68868
  // src/commands/testimonials/search.ts
69114
- import { defineCommand as defineCommand228 } from "citty";
68869
+ import { defineCommand as defineCommand227 } from "citty";
69115
68870
  var FILTER_FLAGS2 = ["source", "rating-min", "rating-max", "status", "sentiment", "language", "tags"];
69116
68871
  function languageBiasHint(results, requestedLanguage) {
69117
68872
  if (requestedLanguage) {
@@ -69190,7 +68945,7 @@ function buildSearchRequest(query, args5) {
69190
68945
  }
69191
68946
  return body;
69192
68947
  }
69193
- var searchCommand3 = defineCommand228({
68948
+ var searchCommand3 = defineCommand227({
69194
68949
  meta: {
69195
68950
  name: "search",
69196
68951
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -69254,7 +69009,7 @@ var searchCommand3 = defineCommand228({
69254
69009
  var tagsCommand5 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
69255
69010
 
69256
69011
  // src/commands/testimonials/index.ts
69257
- var testimonialsCommand = defineCommand229({
69012
+ var testimonialsCommand = defineCommand228({
69258
69013
  meta: {
69259
69014
  name: "testimonials",
69260
69015
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -69276,10 +69031,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
69276
69031
  });
69277
69032
 
69278
69033
  // src/commands/videos/index.ts
69279
- import { defineCommand as defineCommand237 } from "citty";
69034
+ import { defineCommand as defineCommand236 } from "citty";
69280
69035
 
69281
69036
  // src/commands/videos/delete.ts
69282
- import { defineCommand as defineCommand230 } from "citty";
69037
+ import { defineCommand as defineCommand229 } from "citty";
69283
69038
  registerSchema({
69284
69039
  command: "videos.delete",
69285
69040
  description: "Delete a video by ID",
@@ -69293,7 +69048,7 @@ registerSchema({
69293
69048
  }
69294
69049
  }
69295
69050
  });
69296
- var deleteCommand4 = defineCommand230({
69051
+ var deleteCommand4 = defineCommand229({
69297
69052
  meta: {
69298
69053
  name: "delete",
69299
69054
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -69334,7 +69089,7 @@ var deleteCommand4 = defineCommand230({
69334
69089
  });
69335
69090
 
69336
69091
  // src/commands/videos/describe.ts
69337
- import { defineCommand as defineCommand231 } from "citty";
69092
+ import { defineCommand as defineCommand230 } from "citty";
69338
69093
  var DESCRIPTION_HELP2 = "What the clip actually shows, in the words someone would search for it by. This is what `baker videos search` retrieves on.";
69339
69094
  registerSchema({
69340
69095
  command: "videos.describe",
@@ -69351,7 +69106,7 @@ registerSchema({
69351
69106
  full: { type: "boolean", description: "Return the whole library row, not just what changed", required: false }
69352
69107
  }
69353
69108
  });
69354
- var describeCommand2 = defineCommand231({
69109
+ var describeCommand2 = defineCommand230({
69355
69110
  meta: {
69356
69111
  name: "describe",
69357
69112
  description: `Correct what the library says a video is. Only the fields you pass change; the rest keep their current values.
@@ -69409,7 +69164,7 @@ Example: baker videos describe j571abc123 --description "Customer explaining how
69409
69164
  });
69410
69165
 
69411
69166
  // src/commands/videos/get.ts
69412
- import { defineCommand as defineCommand232 } from "citty";
69167
+ import { defineCommand as defineCommand231 } from "citty";
69413
69168
  registerSchema({
69414
69169
  command: "videos.get",
69415
69170
  description: "Get a single video by ID",
@@ -69417,7 +69172,7 @@ registerSchema({
69417
69172
  id: { type: "string", description: "Video ID", required: true }
69418
69173
  }
69419
69174
  });
69420
- var getCommand7 = defineCommand232({
69175
+ var getCommand7 = defineCommand231({
69421
69176
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
69422
69177
  args: {
69423
69178
  id: { type: "positional", description: "Video ID", required: false },
@@ -69454,7 +69209,7 @@ var getCommand7 = defineCommand232({
69454
69209
  });
69455
69210
 
69456
69211
  // src/commands/videos/group.ts
69457
- import { defineCommand as defineCommand233 } from "citty";
69212
+ import { defineCommand as defineCommand232 } from "citty";
69458
69213
  registerSchema({
69459
69214
  command: "videos.group",
69460
69215
  description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
@@ -69463,7 +69218,7 @@ registerSchema({
69463
69218
  "group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
69464
69219
  }
69465
69220
  });
69466
- var groupCommand2 = defineCommand233({
69221
+ var groupCommand2 = defineCommand232({
69467
69222
  meta: {
69468
69223
  name: "group",
69469
69224
  description: "List every asset that arrived in the same set as this clip \u2014 the other slides of the Instagram post it came from, stills included. A carousel is authored to be read in order, so a clip pulled out of one is usually missing half its meaning. Example: baker videos group <videoId>"
@@ -69483,10 +69238,10 @@ var groupCommand2 = defineCommand233({
69483
69238
  });
69484
69239
 
69485
69240
  // src/commands/videos/ingest.ts
69486
- import { mkdtemp as mkdtemp3, rm as rm9, stat as stat12 } from "fs/promises";
69241
+ import { mkdtemp as mkdtemp3, rm as rm9, stat as stat11 } from "fs/promises";
69487
69242
  import { tmpdir as tmpdir4 } from "os";
69488
- import path48 from "path";
69489
- import { defineCommand as defineCommand234 } from "citty";
69243
+ import path47 from "path";
69244
+ import { defineCommand as defineCommand233 } from "citty";
69490
69245
 
69491
69246
  // src/lib/streamUpload.ts
69492
69247
  import { createHash as createHash2 } from "crypto";
@@ -69650,7 +69405,7 @@ registerSchema({
69650
69405
  "dry-run": { type: "boolean", description: "Preview the operation without executing", required: false }
69651
69406
  }
69652
69407
  });
69653
- var ingestCommand2 = defineCommand234({
69408
+ var ingestCommand2 = defineCommand233({
69654
69409
  meta: {
69655
69410
  name: "ingest",
69656
69411
  description: "Add a video to the library from a URL. A direct file URL is handed straight to Baker, which fetches it. A page URL (YouTube, TikTok, Vimeo, Instagram) is downloaded here first, then uploaded \u2014 and a direct URL that Baker cannot fetch falls back to that same path automatically.\n\nExample: baker videos ingest https://www.youtube.com/watch?v=abc123"
@@ -69836,7 +69591,7 @@ function ingestUrl(args5) {
69836
69591
  }
69837
69592
  async function downloadThenIngest(args5, country) {
69838
69593
  const vimeoCookie = captureVimeoCookie();
69839
- const workDir = await mkdtemp3(path48.join(tmpdir4(), "videos-ingest-"));
69594
+ const workDir = await mkdtemp3(path47.join(tmpdir4(), "videos-ingest-"));
69840
69595
  try {
69841
69596
  const probe = await probeYtDlp({ url: args5.url, country, vimeoCookie, cookieDir: workDir });
69842
69597
  if (isAudioOnly(probe.info)) {
@@ -69867,7 +69622,7 @@ async function downloadThenIngest(args5, country) {
69867
69622
  // we allow to fetch it cannot drift apart.
69868
69623
  timeoutMs: downloadTimeoutMs(durationSeconds(probe.info))
69869
69624
  });
69870
- const stats = await stat12(filePath);
69625
+ const stats = await stat11(filePath);
69871
69626
  if (stats.size > MAX_VIDEO_INGEST_BYTES) {
69872
69627
  throw new ApiError(
69873
69628
  "VALIDATION_ERROR",
@@ -69912,7 +69667,7 @@ async function uploadToAssetStore(filePath, sizeBytes) {
69912
69667
  }
69913
69668
 
69914
69669
  // src/commands/videos/search.ts
69915
- import { defineCommand as defineCommand235 } from "citty";
69670
+ import { defineCommand as defineCommand234 } from "citty";
69916
69671
  registerSchema({
69917
69672
  command: "videos.search",
69918
69673
  description: "Search videos by text query. Only returns ready videos.",
@@ -69922,7 +69677,7 @@ registerSchema({
69922
69677
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
69923
69678
  }
69924
69679
  });
69925
- var searchCommand4 = defineCommand235({
69680
+ var searchCommand4 = defineCommand234({
69926
69681
  meta: {
69927
69682
  name: "search",
69928
69683
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -69972,9 +69727,9 @@ var searchCommand4 = defineCommand235({
69972
69727
  var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
69973
69728
 
69974
69729
  // src/commands/videos/upload.ts
69975
- import { readFile as readFile34, stat as stat13 } from "fs/promises";
69730
+ import { readFile as readFile33, stat as stat12 } from "fs/promises";
69976
69731
  import { basename as basename3, extname as extname4 } from "path";
69977
- import { defineCommand as defineCommand236 } from "citty";
69732
+ import { defineCommand as defineCommand235 } from "citty";
69978
69733
  var MIME_MAP = {
69979
69734
  ".mp4": "video/mp4",
69980
69735
  ".mov": "video/quicktime",
@@ -70016,7 +69771,7 @@ function detectContentType(filePath) {
70016
69771
  function isRemoteUrl3(value) {
70017
69772
  return /^https?:\/\//i.test(value);
70018
69773
  }
70019
- var uploadCommand2 = defineCommand236({
69774
+ var uploadCommand2 = defineCommand235({
70020
69775
  meta: {
70021
69776
  name: "upload",
70022
69777
  description: "Upload a video to Baker \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: auto-detects content type and uploads via Mux direct upload.\nRemote: hands off to `videos ingest` (direct fetch, or download-then-upload for a YouTube/TikTok/Vimeo page).\n\nExamples:\n baker videos upload ./demo.mp4\n baker videos upload https://www.youtube.com/watch?v=abc123"
@@ -70056,7 +69811,7 @@ var uploadCommand2 = defineCommand236({
70056
69811
  const originalFilename = basename3(filePath);
70057
69812
  const descriptionContext = args5.context;
70058
69813
  if (args5["dry-run"]) {
70059
- const fileStats = await stat13(filePath);
69814
+ const fileStats = await stat12(filePath);
70060
69815
  writeJson({
70061
69816
  ok: true,
70062
69817
  dryRun: true,
@@ -70069,7 +69824,7 @@ var uploadCommand2 = defineCommand236({
70069
69824
  originalFilename,
70070
69825
  descriptionContext
70071
69826
  });
70072
- const fileBuffer = await readFile34(filePath);
69827
+ const fileBuffer = await readFile33(filePath);
70073
69828
  const uploadResponse = await fetch(uploadUrl, {
70074
69829
  method: "PUT",
70075
69830
  headers: { "Content-Type": contentType },
@@ -70100,7 +69855,7 @@ var uploadCommand2 = defineCommand236({
70100
69855
  });
70101
69856
 
70102
69857
  // src/commands/videos/index.ts
70103
- var videosCommand = defineCommand237({
69858
+ var videosCommand = defineCommand236({
70104
69859
  meta: {
70105
69860
  name: "videos",
70106
69861
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, describe, delete, tags.
@@ -70129,10 +69884,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
70129
69884
  });
70130
69885
 
70131
69886
  // src/commands/winning-ads/index.ts
70132
- import { defineCommand as defineCommand250 } from "citty";
69887
+ import { defineCommand as defineCommand249 } from "citty";
70133
69888
 
70134
69889
  // src/commands/winning-ads/advertisers.ts
70135
- import { defineCommand as defineCommand238 } from "citty";
69890
+ import { defineCommand as defineCommand237 } from "citty";
70136
69891
 
70137
69892
  // src/commands/winning-ads/shared.ts
70138
69893
  function splitList3(value) {
@@ -70185,7 +69940,7 @@ function advertiserNormalizer(record, full) {
70185
69940
  last_synced_at: record.last_synced_at ?? null
70186
69941
  };
70187
69942
  }
70188
- var advertisersCommand2 = defineCommand238({
69943
+ var advertisersCommand2 = defineCommand237({
70189
69944
  meta: {
70190
69945
  name: "advertisers",
70191
69946
  description: 'List corpus advertisers by name or domain. Find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id / winners. Example: baker winning-ads advertisers "Deel" --output md'
@@ -70243,7 +69998,7 @@ var advertisersCommand2 = defineCommand238({
70243
69998
  });
70244
69999
 
70245
70000
  // src/commands/winning-ads/brief.ts
70246
- import { defineCommand as defineCommand239 } from "citty";
70001
+ import { defineCommand as defineCommand238 } from "citty";
70247
70002
  registerSchema({
70248
70003
  command: "winning-ads.brief",
70249
70004
  description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
@@ -70289,7 +70044,7 @@ function parseDna(raw) {
70289
70044
  }
70290
70045
  return parsed;
70291
70046
  }
70292
- var briefCommand = defineCommand239({
70047
+ var briefCommand = defineCommand238({
70293
70048
  meta: {
70294
70049
  name: "brief",
70295
70050
  description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
@@ -70325,7 +70080,7 @@ var briefCommand = defineCommand239({
70325
70080
  });
70326
70081
 
70327
70082
  // src/commands/winning-ads/content.ts
70328
- import { defineCommand as defineCommand240 } from "citty";
70083
+ import { defineCommand as defineCommand239 } from "citty";
70329
70084
  registerSchema({
70330
70085
  command: "winning-ads.content",
70331
70086
  description: "Read what's INSIDE one winning ad: the spoken transcript, the on-screen text, and the ad copy. Use this after `search`/`winners`/`feed` return a shortlist \u2014 pass an ad_id to understand a reference before reproducing it. Add --full for speech, pacing, and soundtrack detail. Video ads carry the transcript/on-screen text; static ads carry only the copy.",
@@ -70338,7 +70093,7 @@ registerSchema({
70338
70093
  }
70339
70094
  }
70340
70095
  });
70341
- var contentCommand = defineCommand240({
70096
+ var contentCommand = defineCommand239({
70342
70097
  meta: {
70343
70098
  name: "content",
70344
70099
  description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
@@ -70387,7 +70142,7 @@ var contentCommand = defineCommand240({
70387
70142
  });
70388
70143
 
70389
70144
  // src/commands/winning-ads/feed.ts
70390
- import { defineCommand as defineCommand241 } from "citty";
70145
+ import { defineCommand as defineCommand240 } from "citty";
70391
70146
  function buildFeedParams(input) {
70392
70147
  const params2 = {};
70393
70148
  const advertiser = splitList3(input.advertiser);
@@ -70439,7 +70194,7 @@ registerSchema({
70439
70194
  format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
70440
70195
  }
70441
70196
  });
70442
- var feedCommand2 = defineCommand241({
70197
+ var feedCommand2 = defineCommand240({
70443
70198
  meta: {
70444
70199
  name: "feed",
70445
70200
  description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
@@ -70524,7 +70279,7 @@ var feedCommand2 = defineCommand241({
70524
70279
  });
70525
70280
 
70526
70281
  // src/commands/winning-ads/follow.ts
70527
- import { defineCommand as defineCommand242 } from "citty";
70282
+ import { defineCommand as defineCommand241 } from "citty";
70528
70283
  var PLATFORMS = adLibraryPlatformSchema.options;
70529
70284
  registerSchema({
70530
70285
  command: "winning-ads.follow",
@@ -70539,7 +70294,7 @@ registerSchema({
70539
70294
  label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
70540
70295
  }
70541
70296
  });
70542
- var followCommand = defineCommand242({
70297
+ var followCommand = defineCommand241({
70543
70298
  meta: {
70544
70299
  name: "follow",
70545
70300
  description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks every platform we can resolve. Example: baker winning-ads follow "deel.com" --platform meta'
@@ -70586,7 +70341,7 @@ var followCommand = defineCommand242({
70586
70341
  });
70587
70342
 
70588
70343
  // src/commands/winning-ads/follow-competitors.ts
70589
- import { defineCommand as defineCommand243 } from "citty";
70344
+ import { defineCommand as defineCommand242 } from "citty";
70590
70345
  var PLATFORMS2 = adLibraryPlatformSchema.options;
70591
70346
  var BATCH_TIMEOUT_MS = 3e5;
70592
70347
  function buildFollowBatchBody(input) {
@@ -70619,7 +70374,7 @@ registerSchema({
70619
70374
  }
70620
70375
  }
70621
70376
  });
70622
- var followCompetitorsCommand = defineCommand243({
70377
+ var followCompetitorsCommand = defineCommand242({
70623
70378
  meta: {
70624
70379
  name: "follow-competitors",
70625
70380
  description: 'Follow many brands at once by domain \u2014 add every competitor in one call. Example: baker winning-ads follow-competitors "deel.com,notion.so,hubspot.com"'
@@ -70694,7 +70449,7 @@ var followCompetitorsCommand = defineCommand243({
70694
70449
  });
70695
70450
 
70696
70451
  // src/commands/winning-ads/following.ts
70697
- import { defineCommand as defineCommand244 } from "citty";
70452
+ import { defineCommand as defineCommand243 } from "citty";
70698
70453
  registerSchema({
70699
70454
  command: "winning-ads.following",
70700
70455
  description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts. A brand still adding has counts that are a lie in progress; one with `discovery_failed` has counts that are short because we couldn't finish looking, which is not the same as it running no ads.",
@@ -70748,7 +70503,7 @@ function followingNormalizer(record, full) {
70748
70503
  platforms: Array.isArray(record.platforms) ? record.platforms : []
70749
70504
  };
70750
70505
  }
70751
- var followingCommand = defineCommand244({
70506
+ var followingCommand = defineCommand243({
70752
70507
  meta: {
70753
70508
  name: "following",
70754
70509
  description: "List brands you follow, with status (ready / adding\u2026) and cached counts. A brand's counts are only final once it is ready. Example: baker winning-ads following --output md"
@@ -70784,7 +70539,7 @@ var followingCommand = defineCommand244({
70784
70539
  });
70785
70540
 
70786
70541
  // src/commands/winning-ads/patterns.ts
70787
- import { defineCommand as defineCommand245 } from "citty";
70542
+ import { defineCommand as defineCommand244 } from "citty";
70788
70543
  registerSchema({
70789
70544
  command: "winning-ads.patterns",
70790
70545
  description: "Mine what separates two cohorts of ads: pass a comma-list of winning ad ids (--winners) and a comma-list of weaker ad ids (--duds). Returns the discriminating DNA fields.",
@@ -70823,7 +70578,7 @@ function discriminatorRow(record) {
70823
70578
  top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
70824
70579
  };
70825
70580
  }
70826
- var patternsCommand = defineCommand245({
70581
+ var patternsCommand = defineCommand244({
70827
70582
  meta: {
70828
70583
  name: "patterns",
70829
70584
  description: "Discover what separates winning ads from weak ones. Example: baker winning-ads patterns --winners a_1,a_2,a_3 --duds a_9,a_8 --output md"
@@ -70879,7 +70634,7 @@ var patternsCommand = defineCommand245({
70879
70634
  });
70880
70635
 
70881
70636
  // src/commands/winning-ads/search.ts
70882
- import { defineCommand as defineCommand246 } from "citty";
70637
+ import { defineCommand as defineCommand245 } from "citty";
70883
70638
  registerSchema({
70884
70639
  command: "winning-ads.search",
70885
70640
  description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
@@ -71017,7 +70772,7 @@ function reportSearchError(err) {
71017
70772
  }
71018
70773
  reportError2(err);
71019
70774
  }
71020
- var searchCommand5 = defineCommand246({
70775
+ var searchCommand5 = defineCommand245({
71021
70776
  meta: {
71022
70777
  name: "search",
71023
70778
  description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
@@ -71137,7 +70892,7 @@ var searchCommand5 = defineCommand246({
71137
70892
  });
71138
70893
 
71139
70894
  // src/commands/winning-ads/seeds.ts
71140
- import { defineCommand as defineCommand247 } from "citty";
70895
+ import { defineCommand as defineCommand246 } from "citty";
71141
70896
  function leanRow(r) {
71142
70897
  return {
71143
70898
  key: r.key,
@@ -71165,7 +70920,7 @@ function makeSeedCommand(opts) {
71165
70920
  limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
71166
70921
  }
71167
70922
  });
71168
- return defineCommand247({
70923
+ return defineCommand246({
71169
70924
  meta: { name: opts.name, description: opts.description },
71170
70925
  args: {
71171
70926
  platform: { type: "string", description: "Single platform to segment on", required: false },
@@ -71214,7 +70969,7 @@ var formatsCommand = makeSeedCommand({
71214
70969
  });
71215
70970
 
71216
70971
  // src/commands/winning-ads/unfollow.ts
71217
- import { defineCommand as defineCommand248 } from "citty";
70972
+ import { defineCommand as defineCommand247 } from "citty";
71218
70973
  registerSchema({
71219
70974
  command: "winning-ads.unfollow",
71220
70975
  description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
@@ -71222,7 +70977,7 @@ registerSchema({
71222
70977
  advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
71223
70978
  }
71224
70979
  });
71225
- var unfollowCommand = defineCommand248({
70980
+ var unfollowCommand = defineCommand247({
71226
70981
  meta: {
71227
70982
  name: "unfollow",
71228
70983
  description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
@@ -71243,7 +70998,7 @@ var unfollowCommand = defineCommand248({
71243
70998
  });
71244
70999
 
71245
71000
  // src/commands/winning-ads/winners.ts
71246
- import { defineCommand as defineCommand249 } from "citty";
71001
+ import { defineCommand as defineCommand248 } from "citty";
71247
71002
  registerSchema({
71248
71003
  command: "winning-ads.winners",
71249
71004
  description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
@@ -71253,7 +71008,7 @@ registerSchema({
71253
71008
  platform: { type: "string", description: "Filter to a single platform: meta|linkedin|tiktok", required: false }
71254
71009
  }
71255
71010
  });
71256
- var winnersCommand = defineCommand249({
71011
+ var winnersCommand = defineCommand248({
71257
71012
  meta: {
71258
71013
  name: "winners",
71259
71014
  description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
@@ -71303,7 +71058,7 @@ var winnersCommand = defineCommand249({
71303
71058
  });
71304
71059
 
71305
71060
  // src/commands/winning-ads/index.ts
71306
- var winningAdsCommand = defineCommand250({
71061
+ var winningAdsCommand = defineCommand249({
71307
71062
  meta: {
71308
71063
  name: "winning-ads",
71309
71064
  description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce, and manage the brands your library tracks. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
@@ -71529,7 +71284,7 @@ function unknownFlagEnvelope(unknown, commandPath, suggestion, hasSchema) {
71529
71284
  };
71530
71285
  }
71531
71286
  function commandPathOf(root, argv) {
71532
- const path49 = [];
71287
+ const path48 = [];
71533
71288
  let command = root;
71534
71289
  for (const token of argv) {
71535
71290
  if (token === "--" || token.startsWith("-")) {
@@ -71540,10 +71295,10 @@ function commandPathOf(root, argv) {
71540
71295
  if (next === void 0 || typeof next !== "object") {
71541
71296
  break;
71542
71297
  }
71543
- path49.push(token);
71298
+ path48.push(token);
71544
71299
  command = next;
71545
71300
  }
71546
- return path49.join(" ");
71301
+ return path48.join(" ");
71547
71302
  }
71548
71303
  function refuseUnknownFlags(root, argv) {
71549
71304
  const unknown = findUnknownFlags(root, argv);
@@ -71553,9 +71308,9 @@ function refuseUnknownFlags(root, argv) {
71553
71308
  const command = commandFor(root, argv);
71554
71309
  const first = unknown[0];
71555
71310
  const suggestion = command && first ? suggestFlag(first, command) : null;
71556
- const path49 = commandPathOf(root, argv);
71311
+ const path48 = commandPathOf(root, argv);
71557
71312
  process.stdout.write(
71558
- `${JSON.stringify(unknownFlagEnvelope(unknown, path49, suggestion, findSchema(path49.split(" ")) !== void 0), null, 2)}
71313
+ `${JSON.stringify(unknownFlagEnvelope(unknown, path48, suggestion, findSchema(path48.split(" ")) !== void 0), null, 2)}
71559
71314
  `
71560
71315
  );
71561
71316
  process.exit(1);
@@ -71630,7 +71385,7 @@ function getCliVersion() {
71630
71385
  }
71631
71386
 
71632
71387
  // src/cli.ts
71633
- var main = defineCommand251({
71388
+ var main = defineCommand250({
71634
71389
  meta: {
71635
71390
  name: "baker",
71636
71391
  version: getCliVersion(),