@koda-sl/baker-cli 0.182.0-dev.c8185c1b5 → 0.182.1-dev.c8185c1b5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4989,7 +4989,7 @@ baker landing inspiration code <section id> # the standalone bundle
4989
4989
  baker landing inspiration page <source id> # a whole page as a section sequence
4990
4990
  baker landing inspiration add https://linear.app --note "client likes this density"
4991
4991
  baker landing inspiration favorites # what this company has saved
4992
- baker landing inspiration scrape <url> --out <dir> # run the capture locally (ops/debug)
4992
+ baker landing inspiration scrape <url> --out <dir> # capture any page now, synchronously
4993
4993
  ```
4994
4994
 
4995
4995
  - **Hybrid search over three signals** — keywords, meaning, and *appearance* (the screenshot is embedded, so a query like "dark developer hero with a terminal" can match a section whose text never says "terminal"). Filters: `--type --composition --register --interaction --motion --media --device --theme --max-rank --min-craft --min-fidelity --domain --similar-to --scope --limit`.
@@ -4997,7 +4997,8 @@ baker landing inspiration scrape <url> --out <dir> # run the capture locally (
4997
4997
  - **`fidelity` says how much to trust the code.** A measured 0–1 match between the live section and our standalone re-render, always reported. Above ~0.95 the markup renders like the original; below ~0.75 the section is scroll- or JS-driven and it does not.
4998
4998
  - **`used_on_pages`** appears when a section shows up on more than one of that site's pages — a nav or footer they ship everywhere, which is a stronger reference than a one-off.
4999
4999
  - **The corpus is shared across companies; favorites are per-company**, and search defaults to this company's saved sections.
5000
- - **Inspiration, never a clipboard.** `code` records what was consulted, and `critique`'s `originality` family blocks a publish that reuses a reference's headline, subhead, or CTA verbatim.
5000
+ - **`add` studies in the background; `scrape` returns with the page on disk.** `add` grows the shared library and takes minutes, so it can never answer "build our page like this one" within the same turn. `scrape` runs the identical capture locally and blocks until it finishes, writing section screenshots, standalone markup, a whole-page reproduction and `report.html`. `--no-motion` roughly halves the runtime; `--no-mobile`, `--no-code` and `--no-report` skip further passes.
5001
+ - **Inspiration, never a clipboard.** Both `code` and `scrape` record what was consulted, and `critique`'s `originality` family blocks a publish that reuses a reference's copy verbatim.
5001
5002
 
5002
5003
  ### `baker landing critique`
5003
5004
 
package/dist/cli.js CHANGED
@@ -8125,11 +8125,11 @@ function rawTextEntries(value) {
8125
8125
  const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
8126
8126
  return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
8127
8127
  }
8128
- function rawFileEntries(path34) {
8129
- if (typeof path34 !== "string" || path34.length === 0) {
8128
+ function rawFileEntries(path35) {
8129
+ if (typeof path35 !== "string" || path35.length === 0) {
8130
8130
  return [];
8131
8131
  }
8132
- return readFileSync2(path34, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
8132
+ return readFileSync2(path35, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
8133
8133
  }
8134
8134
  function keywordEntries(args) {
8135
8135
  const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
@@ -8152,19 +8152,19 @@ function keywordEntries(args) {
8152
8152
  }
8153
8153
  return entries;
8154
8154
  }
8155
- function loadJsonFileArg(path34) {
8156
- if (typeof path34 !== "string" || path34.length === 0) {
8155
+ function loadJsonFileArg(path35) {
8156
+ if (typeof path35 !== "string" || path35.length === 0) {
8157
8157
  return {};
8158
8158
  }
8159
8159
  try {
8160
- const parsed = JSON.parse(readFileSync2(path34, "utf8"));
8160
+ const parsed = JSON.parse(readFileSync2(path35, "utf8"));
8161
8161
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
8162
- failWriteValidation(`${path34} must contain a JSON object`);
8162
+ failWriteValidation(`${path35} must contain a JSON object`);
8163
8163
  }
8164
8164
  return parsed;
8165
8165
  } catch (err) {
8166
8166
  if (err instanceof SyntaxError) {
8167
- failWriteValidation(`${path34} is not valid JSON: ${err.message}`);
8167
+ failWriteValidation(`${path35} is not valid JSON: ${err.message}`);
8168
8168
  }
8169
8169
  throw err;
8170
8170
  }
@@ -8294,10 +8294,10 @@ async function stageUpdate(kind, customerId, target, payload, hints) {
8294
8294
  async function stageTarget(kind, customerId, target, hints) {
8295
8295
  await stageGoogleOp({ kind, customerId, target }, hints);
8296
8296
  }
8297
- async function draftAction(path34, body, chat) {
8297
+ async function draftAction(path35, body, chat) {
8298
8298
  try {
8299
8299
  const chatId = resolveChatId(chat);
8300
- const response = await apiPost(path34, { chatId, ...body });
8300
+ const response = await apiPost(path35, { chatId, ...body });
8301
8301
  writeJsonEnvelope(response);
8302
8302
  } catch (err) {
8303
8303
  handleGoogleError(err);
@@ -10965,19 +10965,19 @@ function failWriteValidation2(message) {
10965
10965
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
10966
10966
  process.exit(1);
10967
10967
  }
10968
- function loadJsonFileArg2(path34) {
10969
- if (typeof path34 !== "string" || path34.length === 0) {
10968
+ function loadJsonFileArg2(path35) {
10969
+ if (typeof path35 !== "string" || path35.length === 0) {
10970
10970
  return {};
10971
10971
  }
10972
10972
  try {
10973
- const parsed = JSON.parse(readFileSync4(path34, "utf8"));
10973
+ const parsed = JSON.parse(readFileSync4(path35, "utf8"));
10974
10974
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
10975
- failWriteValidation2(`${path34} must contain a JSON object`);
10975
+ failWriteValidation2(`${path35} must contain a JSON object`);
10976
10976
  }
10977
10977
  return parsed;
10978
10978
  } catch (err) {
10979
10979
  if (err instanceof SyntaxError) {
10980
- failWriteValidation2(`${path34} is not valid JSON: ${err.message}`);
10980
+ failWriteValidation2(`${path35} is not valid JSON: ${err.message}`);
10981
10981
  }
10982
10982
  throw err;
10983
10983
  }
@@ -11062,15 +11062,15 @@ function parseLocaleFlag(value) {
11062
11062
  }
11063
11063
  return { language: match[1], country: match[2].toUpperCase() };
11064
11064
  }
11065
- function loadTargetingFileArg(path34) {
11066
- if (typeof path34 !== "string" || path34.length === 0) {
11065
+ function loadTargetingFileArg(path35) {
11066
+ if (typeof path35 !== "string" || path35.length === 0) {
11067
11067
  return void 0;
11068
11068
  }
11069
- const parsed = loadJsonFileArg2(path34);
11069
+ const parsed = loadJsonFileArg2(path35);
11070
11070
  const criteria = parsed.targetingCriteria ?? parsed;
11071
11071
  if (!criteria.include) {
11072
11072
  failWriteValidation2(
11073
- `${path34} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
11073
+ `${path35} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
11074
11074
  );
11075
11075
  }
11076
11076
  return criteria;
@@ -11105,14 +11105,14 @@ function parseCsvLine(line) {
11105
11105
  cells.push(current);
11106
11106
  return cells.map((cell) => cell.trim());
11107
11107
  }
11108
- function parseListFileArg(path34, maxRows) {
11109
- if (typeof path34 !== "string" || path34.length === 0) {
11108
+ function parseListFileArg(path35, maxRows) {
11109
+ if (typeof path35 !== "string" || path35.length === 0) {
11110
11110
  return void 0;
11111
11111
  }
11112
- const raw = readFileSync4(path34, "utf8");
11112
+ const raw = readFileSync4(path35, "utf8");
11113
11113
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
11114
11114
  if (lines.length < 2) {
11115
- failWriteValidation2(`${path34} needs a header row and at least one data row`);
11115
+ failWriteValidation2(`${path35} needs a header row and at least one data row`);
11116
11116
  }
11117
11117
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
11118
11118
  const rows = [];
@@ -11131,7 +11131,7 @@ function parseListFileArg(path34, maxRows) {
11131
11131
  }
11132
11132
  }
11133
11133
  if (rows.length > maxRows) {
11134
- failWriteValidation2(`${path34} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
11134
+ failWriteValidation2(`${path35} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
11135
11135
  }
11136
11136
  return { columns, rows };
11137
11137
  }
@@ -11227,11 +11227,11 @@ function readPositionals(args) {
11227
11227
  function splitIdList(raw) {
11228
11228
  return raw.split(",").map((id) => id.trim()).filter(Boolean);
11229
11229
  }
11230
- function idsFileEntries(path34) {
11231
- if (typeof path34 !== "string" || path34.length === 0) {
11230
+ function idsFileEntries(path35) {
11231
+ if (typeof path35 !== "string" || path35.length === 0) {
11232
11232
  return [];
11233
11233
  }
11234
- return readFileSync4(path34, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
11234
+ return readFileSync4(path35, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
11235
11235
  }
11236
11236
  function requireTargets(args, entity) {
11237
11237
  const positionals = readPositionals(args);
@@ -13854,9 +13854,9 @@ function compactRow(row) {
13854
13854
  ...destination.postUrn ? { postUrn: destination.postUrn } : {}
13855
13855
  };
13856
13856
  }
13857
- function readPath(row, path34) {
13857
+ function readPath(row, path35) {
13858
13858
  let current = row;
13859
- for (const segment of path34.split(".")) {
13859
+ for (const segment of path35.split(".")) {
13860
13860
  const record = asRecord2(current);
13861
13861
  if (!record) return void 0;
13862
13862
  current = record[segment];
@@ -13866,10 +13866,10 @@ function readPath(row, path34) {
13866
13866
  function projectFields(rows, paths) {
13867
13867
  return rows.map((row) => {
13868
13868
  const projected = {};
13869
- for (const path34 of paths) {
13870
- const value = readPath(row, path34);
13869
+ for (const path35 of paths) {
13870
+ const value = readPath(row, path35);
13871
13871
  if (value !== void 0) {
13872
- projected[path34] = value;
13872
+ projected[path35] = value;
13873
13873
  }
13874
13874
  }
13875
13875
  return projected;
@@ -15076,11 +15076,11 @@ var updateStatusSchema = z18.enum(UPDATE_STATUSES);
15076
15076
  function currencyMinimums2(currencyCode) {
15077
15077
  return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
15078
15078
  }
15079
- function validateDailyBudgetFloor(money, ctx, path34) {
15079
+ function validateDailyBudgetFloor(money, ctx, path35) {
15080
15080
  if (money?.currencyCode) {
15081
15081
  const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
15082
15082
  if (Number(money.amount) < min) {
15083
- ctx.addIssue({ code: "custom", path: path34, message: `below the ${min} ${money.currencyCode} daily minimum` });
15083
+ ctx.addIssue({ code: "custom", path: path35, message: `below the ${min} ${money.currencyCode} daily minimum` });
15084
15084
  }
15085
15085
  }
15086
15086
  }
@@ -15723,19 +15723,19 @@ function failWriteValidation3(message) {
15723
15723
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
15724
15724
  process.exit(1);
15725
15725
  }
15726
- function loadJsonFileArg3(path34) {
15727
- if (typeof path34 !== "string" || path34.length === 0) {
15726
+ function loadJsonFileArg3(path35) {
15727
+ if (typeof path35 !== "string" || path35.length === 0) {
15728
15728
  return {};
15729
15729
  }
15730
15730
  try {
15731
- const parsed = JSON.parse(readFileSync8(path34, "utf8"));
15731
+ const parsed = JSON.parse(readFileSync8(path35, "utf8"));
15732
15732
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
15733
- failWriteValidation3(`${path34} must contain a JSON object`);
15733
+ failWriteValidation3(`${path35} must contain a JSON object`);
15734
15734
  }
15735
15735
  return parsed;
15736
15736
  } catch (err) {
15737
15737
  if (err instanceof SyntaxError) {
15738
- failWriteValidation3(`${path34} is not valid JSON: ${err.message}`);
15738
+ failWriteValidation3(`${path35} is not valid JSON: ${err.message}`);
15739
15739
  }
15740
15740
  throw err;
15741
15741
  }
@@ -26531,12 +26531,12 @@ function listFlowSlugs() {
26531
26531
  return readdirSync2(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith("_") && entry.name !== ".gitkeep").map((entry) => entry.name).sort();
26532
26532
  }
26533
26533
  function readFlowTree(slug) {
26534
- const path34 = join3(flowsDir(), slug, "_data.json");
26535
- if (!existsSync4(path34)) {
26534
+ const path35 = join3(flowsDir(), slug, "_data.json");
26535
+ if (!existsSync4(path35)) {
26536
26536
  failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
26537
26537
  }
26538
26538
  try {
26539
- return JSON.parse(readFileSync9(path34, "utf-8"));
26539
+ return JSON.parse(readFileSync9(path35, "utf-8"));
26540
26540
  } catch (error) {
26541
26541
  failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
26542
26542
  }
@@ -26949,10 +26949,10 @@ async function stageOps(ops) {
26949
26949
  handleError(err);
26950
26950
  }
26951
26951
  }
26952
- async function draftAction2(path34, body, chat) {
26952
+ async function draftAction2(path35, body, chat) {
26953
26953
  const chatId = resolveChatId(chat);
26954
26954
  try {
26955
- const data = await apiPost(path34, { chatId, ...body });
26955
+ const data = await apiPost(path35, { chatId, ...body });
26956
26956
  writeJsonEnvelope({ ok: true, data });
26957
26957
  return data;
26958
26958
  } catch (err) {
@@ -28976,9 +28976,9 @@ async function readImageBuffer(pathOrUrl) {
28976
28976
  }
28977
28977
  return readFile19(pathOrUrl);
28978
28978
  }
28979
- async function isDirectory(path34) {
28979
+ async function isDirectory(path35) {
28980
28980
  try {
28981
- const s = await stat4(path34);
28981
+ const s = await stat4(path35);
28982
28982
  return s.isDirectory();
28983
28983
  } catch {
28984
28984
  return false;
@@ -32870,9 +32870,14 @@ async function readReferences(projectRoot) {
32870
32870
  }
32871
32871
  }
32872
32872
  async function recordReference(projectRoot, reference) {
32873
+ return await recordReferences(projectRoot, [reference]);
32874
+ }
32875
+ async function recordReferences(projectRoot, references) {
32876
+ if (references.length === 0) return true;
32873
32877
  try {
32874
32878
  const existing = await readReferences(projectRoot);
32875
- const merged = [...existing.filter((entry) => entry.sectionId !== reference.sectionId), reference];
32879
+ const replaced = new Set(references.map((reference) => reference.sectionId));
32880
+ const merged = [...existing.filter((entry) => !replaced.has(entry.sectionId)), ...references];
32876
32881
  const file = path25.join(projectRoot, REFERENCES_FILE);
32877
32882
  await mkdir8(path25.dirname(file), { recursive: true });
32878
32883
  await writeFile11(file, `${JSON.stringify(merged, null, 2)}
@@ -33419,8 +33424,25 @@ var pageCommand = defineCommand146({
33419
33424
  });
33420
33425
 
33421
33426
  // src/commands/landing/inspiration/scrape.ts
33427
+ import { readFile as readFile24 } from "fs/promises";
33428
+ import path32 from "path";
33422
33429
  import { defineCommand as defineCommand147 } from "citty";
33423
33430
 
33431
+ // src/engine/landing/lib/capturedReferences.ts
33432
+ var MAX_STRINGS_PER_SECTION = 40;
33433
+ function bodyOf(markup) {
33434
+ const body = markup.indexOf("<body");
33435
+ return body === -1 ? markup : markup.slice(body);
33436
+ }
33437
+ function capturedCopyStrings(markup) {
33438
+ const seen = /* @__PURE__ */ new Set();
33439
+ for (const { value } of extractVisibleStrings(bodyOf(markup))) {
33440
+ seen.add(value);
33441
+ if (seen.size >= MAX_STRINGS_PER_SECTION) break;
33442
+ }
33443
+ return [...seen];
33444
+ }
33445
+
33424
33446
  // src/engine/landing-library/blocked.ts
33425
33447
  var CHALLENGE_PHRASES = [
33426
33448
  "just a moment",
@@ -34995,53 +35017,74 @@ async function scrapeLanding(options) {
34995
35017
  }
34996
35018
 
34997
35019
  // src/commands/landing/inspiration/scrape.ts
35020
+ async function recordCapture(manifest, outDir) {
35021
+ const consultedAt = (/* @__PURE__ */ new Date()).toISOString();
35022
+ const references = [];
35023
+ for (const section of manifest.sections) {
35024
+ if (!section.bundle) continue;
35025
+ try {
35026
+ const markup = await readFile24(path32.join(outDir, section.bundle), "utf8");
35027
+ const copyStrings = capturedCopyStrings(markup);
35028
+ if (copyStrings.length === 0) continue;
35029
+ references.push({
35030
+ sectionId: `local:${manifest.finalUrl}#${section.index}`,
35031
+ sourceUrl: manifest.finalUrl,
35032
+ copyStrings,
35033
+ consultedAt
35034
+ });
35035
+ } catch {
35036
+ }
35037
+ }
35038
+ return await recordReferences(process.cwd(), references);
35039
+ }
34998
35040
  registerSchema({
34999
35041
  command: "landing.inspiration.scrape",
35000
- description: "Internal/ops: capture one landing page into a directory of section screenshots, standalone HTML bundles and motion filmstrips. The ingest job runs this; use it locally to debug a page that studied badly.",
35042
+ description: "Start here when the user points at a specific page and wants it now: capture one landing page into a directory of section screenshots, standalone HTML bundles, a whole-page reproduction and motion filmstrips. Returns when the capture is done, unlike `add`. Read the screenshots. Also records every captured section for the originality check.",
35001
35043
  args: {
35002
35044
  url: { type: "string", description: "Page to capture", required: true },
35003
35045
  out: { type: "string", description: "Output directory", required: true },
35004
- "no-mobile": { type: "boolean", description: "Skip the phone-viewport pass", required: false },
35005
- "no-code": {
35046
+ mobile: { type: "boolean", description: "Phone-viewport pass. `--no-mobile` to skip", required: false },
35047
+ code: {
35006
35048
  type: "boolean",
35007
- description: "Segment and screenshot only \u2014 no bundles, no fidelity",
35049
+ description: "Standalone HTML+CSS bundles and fidelity scores. `--no-code` to segment and screenshot only",
35008
35050
  required: false
35009
35051
  },
35010
- "no-motion": {
35052
+ motion: {
35011
35053
  type: "boolean",
35012
- description: "Skip filming sections that move (roughly halves runtime)",
35054
+ description: "Film sections that move. `--no-motion` to skip \u2014 roughly halves runtime",
35013
35055
  required: false
35014
35056
  },
35015
- "no-report": { type: "boolean", description: "Skip writing report.html", required: false }
35057
+ report: { type: "boolean", description: "Write report.html. `--no-report` to skip", required: false }
35016
35058
  }
35017
35059
  });
35018
35060
  var scrapeCommand = defineCommand147({
35019
35061
  meta: {
35020
35062
  name: "scrape",
35021
- description: "Internal/ops: capture a landing page to a directory. Example: baker landing inspiration scrape https://linear.app --out /tmp/linear"
35063
+ description: "Capture a landing page to a directory, now. Example: baker landing inspiration scrape https://linear.app --out .baker/inspiration/linear.app"
35022
35064
  },
35023
35065
  args: {
35024
35066
  url: { type: "positional", description: "Page to capture", required: true },
35025
35067
  out: { type: "string", description: "Output directory", required: true },
35026
- "no-mobile": { type: "boolean", description: "Skip the phone-viewport pass", required: false, default: false },
35027
- "no-code": { type: "boolean", description: "Segment and screenshot only", required: false, default: false },
35028
- "no-motion": { type: "boolean", description: "Skip filming sections that move", required: false, default: false },
35029
- "no-report": { type: "boolean", description: "Skip writing report.html", required: false, default: false }
35068
+ mobile: { type: "boolean", description: "Phone-viewport pass (--no-mobile to skip)", required: false, default: true },
35069
+ code: { type: "boolean", description: "Bundles + fidelity (--no-code to skip)", required: false, default: true },
35070
+ motion: { type: "boolean", description: "Film moving sections (--no-motion to skip)", required: false, default: true },
35071
+ report: { type: "boolean", description: "Write report.html (--no-report to skip)", required: false, default: true }
35030
35072
  },
35031
35073
  run: async ({ args }) => {
35032
35074
  try {
35033
35075
  const manifest = await scrapeLanding({
35034
35076
  url: args.url,
35035
35077
  outDir: args.out,
35036
- mobile: !args["no-mobile"],
35037
- code: !args["no-code"],
35038
- motion: !args["no-motion"],
35039
- report: !args["no-report"],
35078
+ mobile: args.mobile,
35079
+ code: args.code,
35080
+ motion: args.motion,
35081
+ report: args.report,
35040
35082
  // Progress goes to stderr so stdout stays a clean JSON envelope.
35041
35083
  onProgress: (message) => process.stderr.write(`${message}
35042
35084
  `)
35043
35085
  });
35044
35086
  const scored = manifest.sections.map((section) => section.fidelity).filter((value) => value !== null).sort((a, b) => a - b);
35087
+ const recorded = await recordCapture(manifest, args.out);
35045
35088
  writeJson({
35046
35089
  ok: true,
35047
35090
  data: {
@@ -35050,8 +35093,13 @@ var scrapeCommand = defineCommand147({
35050
35093
  medianFidelity: scored.length > 0 ? scored[Math.floor(scored.length / 2)] : null,
35051
35094
  pageFidelity: manifest.page.fidelity,
35052
35095
  out: args.out,
35053
- report: args["no-report"] ? null : `${args.out}/report.html`
35054
- }
35096
+ report: args.report ? `${args.out}/report.html` : null
35097
+ },
35098
+ hints: [
35099
+ INSPIRATION_HINTS.structureNotCopy,
35100
+ INSPIRATION_HINTS.adapt,
35101
+ recorded ? "These sections are recorded for the originality check \u2014 `baker landing critique` will block a publish that ships their copy." : "Could not record this capture, so the originality check cannot see it. Be especially careful not to reuse its copy."
35102
+ ]
35055
35103
  });
35056
35104
  } catch (error) {
35057
35105
  if (error instanceof BlockedPageError) {
@@ -35065,7 +35113,7 @@ var scrapeCommand = defineCommand147({
35065
35113
 
35066
35114
  // src/commands/landing/inspiration/search.ts
35067
35115
  import { mkdir as mkdir12, writeFile as writeFile16 } from "fs/promises";
35068
- import path32 from "path";
35116
+ import path33 from "path";
35069
35117
  import { defineCommand as defineCommand148 } from "citty";
35070
35118
  registerSchema({
35071
35119
  command: "landing.inspiration.search",
@@ -35147,7 +35195,7 @@ function buildSearchBody(args) {
35147
35195
  return body;
35148
35196
  }
35149
35197
  async function downloadShots(results) {
35150
- const dir = path32.join(process.cwd(), ".baker", "inspiration");
35198
+ const dir = path33.join(process.cwd(), ".baker", "inspiration");
35151
35199
  await mkdir12(dir, { recursive: true });
35152
35200
  const saved = /* @__PURE__ */ new Map();
35153
35201
  await Promise.all(
@@ -35156,9 +35204,9 @@ async function downloadShots(results) {
35156
35204
  try {
35157
35205
  const response = await fetch(result.desktopShotUrl);
35158
35206
  if (!response.ok) return;
35159
- const file = path32.join(dir, `${result.id}.png`);
35207
+ const file = path33.join(dir, `${result.id}.png`);
35160
35208
  await writeFile16(file, Buffer.from(await response.arrayBuffer()));
35161
- saved.set(result.id, path32.relative(process.cwd(), file));
35209
+ saved.set(result.id, path33.relative(process.cwd(), file));
35162
35210
  } catch {
35163
35211
  }
35164
35212
  })
@@ -35245,7 +35293,7 @@ var searchCommand2 = defineCommand148({
35245
35293
 
35246
35294
  // src/commands/landing/inspiration/view.ts
35247
35295
  import { mkdir as mkdir13, writeFile as writeFile17 } from "fs/promises";
35248
- import path33 from "path";
35296
+ import path34 from "path";
35249
35297
  import { defineCommand as defineCommand149 } from "citty";
35250
35298
  registerSchema({
35251
35299
  command: "landing.inspiration.view",
@@ -35257,9 +35305,9 @@ async function download(url, file) {
35257
35305
  try {
35258
35306
  const response = await fetch(url);
35259
35307
  if (!response.ok) return null;
35260
- await mkdir13(path33.dirname(file), { recursive: true });
35308
+ await mkdir13(path34.dirname(file), { recursive: true });
35261
35309
  await writeFile17(file, Buffer.from(await response.arrayBuffer()));
35262
- return path33.relative(process.cwd(), file);
35310
+ return path34.relative(process.cwd(), file);
35263
35311
  } catch {
35264
35312
  return null;
35265
35313
  }
@@ -35275,11 +35323,11 @@ var viewCommand2 = defineCommand149({
35275
35323
  const id = args.id;
35276
35324
  const data = await apiGet("/api/landing-inspiration/section", { id });
35277
35325
  const section = data.section;
35278
- const dir = path33.join(process.cwd(), ".baker", "inspiration", id);
35326
+ const dir = path34.join(process.cwd(), ".baker", "inspiration", id);
35279
35327
  const [desktop, mobile, filmstrip] = await Promise.all([
35280
- download(section.desktopShotUrl, path33.join(dir, "desktop.png")),
35281
- download(section.mobileShotUrl, path33.join(dir, "mobile.png")),
35282
- download(section.motionFilmstripUrl, path33.join(dir, "motion-filmstrip.png"))
35328
+ download(section.desktopShotUrl, path34.join(dir, "desktop.png")),
35329
+ download(section.mobileShotUrl, path34.join(dir, "mobile.png")),
35330
+ download(section.motionFilmstripUrl, path34.join(dir, "motion-filmstrip.png"))
35283
35331
  ]);
35284
35332
  const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
35285
35333
  const fidelity = fidelityHint(section.fidelity);
@@ -37108,10 +37156,10 @@ async function stageOp4(op) {
37108
37156
  handleError4(err);
37109
37157
  }
37110
37158
  }
37111
- async function draftAction3(path34, body, chat) {
37159
+ async function draftAction3(path35, body, chat) {
37112
37160
  const chatId = resolveChatId(chat);
37113
37161
  try {
37114
- const data = await apiPost(path34, { chatId, ...body });
37162
+ const data = await apiPost(path35, { chatId, ...body });
37115
37163
  writeJsonEnvelope({ ok: true, data });
37116
37164
  return data;
37117
37165
  } catch (err) {
@@ -38130,7 +38178,7 @@ var searchCommand4 = defineCommand183({
38130
38178
  var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
38131
38179
 
38132
38180
  // src/commands/videos/upload.ts
38133
- import { readFile as readFile24, stat as stat7 } from "fs/promises";
38181
+ import { readFile as readFile25, stat as stat7 } from "fs/promises";
38134
38182
  import { extname as extname3 } from "path";
38135
38183
  import { defineCommand as defineCommand184 } from "citty";
38136
38184
  var MIME_MAP = {
@@ -38195,7 +38243,7 @@ var uploadCommand2 = defineCommand184({
38195
38243
  return;
38196
38244
  }
38197
38245
  const { uploadUrl, videoId } = await apiPost("/api/videos/upload", {});
38198
- const fileBuffer = await readFile24(filePath);
38246
+ const fileBuffer = await readFile25(filePath);
38199
38247
  const uploadResponse = await fetch(uploadUrl, {
38200
38248
  method: "PUT",
38201
38249
  headers: { "Content-Type": contentType },