@koda-sl/baker-cli 0.245.0 → 0.246.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -4
- package/dist/cli.js +222 -360
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -9408,8 +9408,8 @@ function countStaccato(text2) {
|
|
|
9408
9408
|
let first = "";
|
|
9409
9409
|
let runStart = 0;
|
|
9410
9410
|
for (const [i, s] of sentences.entries()) {
|
|
9411
|
-
const
|
|
9412
|
-
if (
|
|
9411
|
+
const words2 = s.split(/\s+/).filter(Boolean).length;
|
|
9412
|
+
if (words2 > 0 && words2 <= STACCATO_MAX_WORDS) {
|
|
9413
9413
|
if (run === 0) runStart = i;
|
|
9414
9414
|
run++;
|
|
9415
9415
|
if (run === STACCATO_RUN) {
|
|
@@ -9427,10 +9427,10 @@ function countTitleCaseHeadings(text2) {
|
|
|
9427
9427
|
let first = "";
|
|
9428
9428
|
for (const m of text2.matchAll(/^\s{0,3}#{1,6}\s+(.+)$/gm)) {
|
|
9429
9429
|
const heading = (m[1] ?? "").trim();
|
|
9430
|
-
const
|
|
9431
|
-
if (
|
|
9432
|
-
const capitalized =
|
|
9433
|
-
if (capitalized /
|
|
9430
|
+
const words2 = heading.split(/\s+/).filter((w) => new RegExp("\\p{L}", "u").test(w));
|
|
9431
|
+
if (words2.length < 4) continue;
|
|
9432
|
+
const capitalized = words2.filter((w) => new RegExp("^\\p{Lu}", "u").test(w)).length;
|
|
9433
|
+
if (capitalized / words2.length < 0.8) continue;
|
|
9434
9434
|
count++;
|
|
9435
9435
|
if (!first) first = heading;
|
|
9436
9436
|
}
|
|
@@ -9779,11 +9779,11 @@ function rawTextEntries(value) {
|
|
|
9779
9779
|
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
9780
9780
|
return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
9781
9781
|
}
|
|
9782
|
-
function rawFileEntries(
|
|
9783
|
-
if (typeof
|
|
9782
|
+
function rawFileEntries(path38) {
|
|
9783
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
9784
9784
|
return [];
|
|
9785
9785
|
}
|
|
9786
|
-
return readFileSync2(
|
|
9786
|
+
return readFileSync2(path38, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
9787
9787
|
}
|
|
9788
9788
|
function keywordEntries(args) {
|
|
9789
9789
|
const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
|
|
@@ -9806,19 +9806,19 @@ function keywordEntries(args) {
|
|
|
9806
9806
|
}
|
|
9807
9807
|
return entries;
|
|
9808
9808
|
}
|
|
9809
|
-
function loadJsonFileArg(
|
|
9810
|
-
if (typeof
|
|
9809
|
+
function loadJsonFileArg(path38) {
|
|
9810
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
9811
9811
|
return {};
|
|
9812
9812
|
}
|
|
9813
9813
|
try {
|
|
9814
|
-
const parsed = JSON.parse(readFileSync2(
|
|
9814
|
+
const parsed = JSON.parse(readFileSync2(path38, "utf8"));
|
|
9815
9815
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
9816
|
-
failWriteValidation(`${
|
|
9816
|
+
failWriteValidation(`${path38} must contain a JSON object`);
|
|
9817
9817
|
}
|
|
9818
9818
|
return parsed;
|
|
9819
9819
|
} catch (err) {
|
|
9820
9820
|
if (err instanceof SyntaxError) {
|
|
9821
|
-
failWriteValidation(`${
|
|
9821
|
+
failWriteValidation(`${path38} is not valid JSON: ${err.message}`);
|
|
9822
9822
|
}
|
|
9823
9823
|
throw err;
|
|
9824
9824
|
}
|
|
@@ -9948,10 +9948,10 @@ async function stageUpdate(kind, customerId, target, payload, hints) {
|
|
|
9948
9948
|
async function stageTarget(kind, customerId, target, hints) {
|
|
9949
9949
|
await stageGoogleOp({ kind, customerId, target }, hints);
|
|
9950
9950
|
}
|
|
9951
|
-
async function draftAction(
|
|
9951
|
+
async function draftAction(path38, body, chat) {
|
|
9952
9952
|
try {
|
|
9953
9953
|
const chatId = resolveChatId(chat);
|
|
9954
|
-
const response = await apiPost(
|
|
9954
|
+
const response = await apiPost(path38, { chatId, ...body });
|
|
9955
9955
|
writeJsonEnvelope(response);
|
|
9956
9956
|
} catch (err) {
|
|
9957
9957
|
handleGoogleError(err);
|
|
@@ -12593,8 +12593,24 @@ var analyticsTotalsSchema = z24.object({
|
|
|
12593
12593
|
/** Counted from `session_start`. */
|
|
12594
12594
|
sessions: z24.number().int().nonnegative(),
|
|
12595
12595
|
pageViews: z24.number().int().nonnegative(),
|
|
12596
|
+
/**
|
|
12597
|
+
* Every conversion, counting a visit twice when it converted twice.
|
|
12598
|
+
*
|
|
12599
|
+
* A Form's author can mark an outcome as counting every time it happens — a
|
|
12600
|
+
* download, a repeatable action — so this legitimately runs ahead of
|
|
12601
|
+
* {@link convertingSessions}, and of `sessions`.
|
|
12602
|
+
*/
|
|
12596
12603
|
conversions: z24.number().int().nonnegative(),
|
|
12597
|
-
/**
|
|
12604
|
+
/** Visits that produced at least one conversion. Never above `sessions`. */
|
|
12605
|
+
convertingSessions: z24.number().int().nonnegative(),
|
|
12606
|
+
/**
|
|
12607
|
+
* Converting visits per visit, 0–1. Null when there were no visits.
|
|
12608
|
+
*
|
|
12609
|
+
* Over converting visits rather than over conversions, because the second
|
|
12610
|
+
* ratio passes 1 the moment one visit converts twice — and a headline card
|
|
12611
|
+
* reading "125%" is read as a broken report, not as a visitor who did the
|
|
12612
|
+
* thing twice. The count above still says how often it happened.
|
|
12613
|
+
*/
|
|
12598
12614
|
conversionRate: z24.number().min(0).max(1).nullable(),
|
|
12599
12615
|
avgEngagementMs: z24.number().nonnegative().nullable(),
|
|
12600
12616
|
/** Page views per session. At or near 1 means visitors leave from the page they land on. */
|
|
@@ -12640,8 +12656,14 @@ var analyticsLandingRowSchema = z24.object({
|
|
|
12640
12656
|
entrances: z24.number().int().nonnegative(),
|
|
12641
12657
|
visitors: z24.number().int().nonnegative(),
|
|
12642
12658
|
conversions: z24.number().int().nonnegative(),
|
|
12659
|
+
/** Visits that converted on this page at least once. */
|
|
12660
|
+
convertingSessions: z24.number().int().nonnegative(),
|
|
12643
12661
|
outboundClicks: z24.number().int().nonnegative(),
|
|
12644
|
-
/**
|
|
12662
|
+
/**
|
|
12663
|
+
* Converting visits per entrance. Null when nobody entered here at all.
|
|
12664
|
+
*
|
|
12665
|
+
* Converting visits, not conversions: see {@link analyticsTotalsSchema}.
|
|
12666
|
+
*/
|
|
12645
12667
|
conversionRate: z24.number().min(0).max(1).nullable(),
|
|
12646
12668
|
avgEngagementMs: z24.number().nonnegative().nullable(),
|
|
12647
12669
|
/**
|
|
@@ -12677,6 +12699,9 @@ var analyticsTagRowSchema = z24.object({
|
|
|
12677
12699
|
sessions: z24.number().int().nonnegative(),
|
|
12678
12700
|
entrances: z24.number().int().nonnegative(),
|
|
12679
12701
|
conversions: z24.number().int().nonnegative(),
|
|
12702
|
+
/** Visits that converted on one of this tag's pages. */
|
|
12703
|
+
convertingSessions: z24.number().int().nonnegative(),
|
|
12704
|
+
/** Converting visits per entrance. */
|
|
12680
12705
|
conversionRate: z24.number().min(0).max(1).nullable()
|
|
12681
12706
|
});
|
|
12682
12707
|
var analyticsCustomEventRowSchema = z24.object({
|
|
@@ -12743,7 +12768,9 @@ var analyticsPageRowSchema = z24.object({
|
|
|
12743
12768
|
/** Sessions that began on this page — its value as a landing page. */
|
|
12744
12769
|
entrances: z24.number().int().nonnegative(),
|
|
12745
12770
|
conversions: z24.number().int().nonnegative(),
|
|
12746
|
-
/**
|
|
12771
|
+
/** Visits that converted on this page at least once. */
|
|
12772
|
+
convertingSessions: z24.number().int().nonnegative(),
|
|
12773
|
+
/** Converting visits per entrance, 0–1. Null when nobody landed here. */
|
|
12747
12774
|
conversionRate: z24.number().min(0).max(1).nullable(),
|
|
12748
12775
|
avgEngagementMs: z24.number().nonnegative().nullable()
|
|
12749
12776
|
});
|
|
@@ -12938,7 +12965,9 @@ var analyticsReleaseRowSchema = z24.object({
|
|
|
12938
12965
|
sessions: z24.number().int().nonnegative(),
|
|
12939
12966
|
pageViews: z24.number().int().nonnegative(),
|
|
12940
12967
|
conversions: z24.number().int().nonnegative(),
|
|
12941
|
-
/**
|
|
12968
|
+
/** Visits that converted on this build at least once. */
|
|
12969
|
+
convertingSessions: z24.number().int().nonnegative(),
|
|
12970
|
+
/** Converting visits per session, 0–1. Null below a usable sample. */
|
|
12942
12971
|
conversionRate: z24.number().min(0).max(1).nullable()
|
|
12943
12972
|
});
|
|
12944
12973
|
var analyticsGeoRowSchema = z24.object({
|
|
@@ -15136,19 +15165,19 @@ function failWriteValidation2(message) {
|
|
|
15136
15165
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
15137
15166
|
process.exit(1);
|
|
15138
15167
|
}
|
|
15139
|
-
function loadJsonFileArg2(
|
|
15140
|
-
if (typeof
|
|
15168
|
+
function loadJsonFileArg2(path38) {
|
|
15169
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
15141
15170
|
return {};
|
|
15142
15171
|
}
|
|
15143
15172
|
try {
|
|
15144
|
-
const parsed = JSON.parse(readFileSync4(
|
|
15173
|
+
const parsed = JSON.parse(readFileSync4(path38, "utf8"));
|
|
15145
15174
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
15146
|
-
failWriteValidation2(`${
|
|
15175
|
+
failWriteValidation2(`${path38} must contain a JSON object`);
|
|
15147
15176
|
}
|
|
15148
15177
|
return parsed;
|
|
15149
15178
|
} catch (err) {
|
|
15150
15179
|
if (err instanceof SyntaxError) {
|
|
15151
|
-
failWriteValidation2(`${
|
|
15180
|
+
failWriteValidation2(`${path38} is not valid JSON: ${err.message}`);
|
|
15152
15181
|
}
|
|
15153
15182
|
throw err;
|
|
15154
15183
|
}
|
|
@@ -15233,15 +15262,15 @@ function parseLocaleFlag(value) {
|
|
|
15233
15262
|
}
|
|
15234
15263
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
15235
15264
|
}
|
|
15236
|
-
function loadTargetingFileArg(
|
|
15237
|
-
if (typeof
|
|
15265
|
+
function loadTargetingFileArg(path38) {
|
|
15266
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
15238
15267
|
return void 0;
|
|
15239
15268
|
}
|
|
15240
|
-
const parsed = loadJsonFileArg2(
|
|
15269
|
+
const parsed = loadJsonFileArg2(path38);
|
|
15241
15270
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
15242
15271
|
if (!criteria.include) {
|
|
15243
15272
|
failWriteValidation2(
|
|
15244
|
-
`${
|
|
15273
|
+
`${path38} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
15245
15274
|
);
|
|
15246
15275
|
}
|
|
15247
15276
|
return criteria;
|
|
@@ -15276,14 +15305,14 @@ function parseCsvLine(line) {
|
|
|
15276
15305
|
cells.push(current);
|
|
15277
15306
|
return cells.map((cell2) => cell2.trim());
|
|
15278
15307
|
}
|
|
15279
|
-
function parseListFileArg(
|
|
15280
|
-
if (typeof
|
|
15308
|
+
function parseListFileArg(path38, maxRows) {
|
|
15309
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
15281
15310
|
return void 0;
|
|
15282
15311
|
}
|
|
15283
|
-
const raw = readFileSync4(
|
|
15312
|
+
const raw = readFileSync4(path38, "utf8");
|
|
15284
15313
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
15285
15314
|
if (lines.length < 2) {
|
|
15286
|
-
failWriteValidation2(`${
|
|
15315
|
+
failWriteValidation2(`${path38} needs a header row and at least one data row`);
|
|
15287
15316
|
}
|
|
15288
15317
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
15289
15318
|
const rows = [];
|
|
@@ -15302,7 +15331,7 @@ function parseListFileArg(path40, maxRows) {
|
|
|
15302
15331
|
}
|
|
15303
15332
|
}
|
|
15304
15333
|
if (rows.length > maxRows) {
|
|
15305
|
-
failWriteValidation2(`${
|
|
15334
|
+
failWriteValidation2(`${path38} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
15306
15335
|
}
|
|
15307
15336
|
return { columns, rows };
|
|
15308
15337
|
}
|
|
@@ -15398,11 +15427,11 @@ function readPositionals(args) {
|
|
|
15398
15427
|
function splitIdList(raw) {
|
|
15399
15428
|
return raw.split(",").map((id) => id.trim()).filter(Boolean);
|
|
15400
15429
|
}
|
|
15401
|
-
function idsFileEntries(
|
|
15402
|
-
if (typeof
|
|
15430
|
+
function idsFileEntries(path38) {
|
|
15431
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
15403
15432
|
return [];
|
|
15404
15433
|
}
|
|
15405
|
-
return readFileSync4(
|
|
15434
|
+
return readFileSync4(path38, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
|
|
15406
15435
|
}
|
|
15407
15436
|
function requireTargets(args, entity) {
|
|
15408
15437
|
const positionals = readPositionals(args);
|
|
@@ -18023,9 +18052,9 @@ function compactRow(row) {
|
|
|
18023
18052
|
...destination.postUrn ? { postUrn: destination.postUrn } : {}
|
|
18024
18053
|
};
|
|
18025
18054
|
}
|
|
18026
|
-
function readPath(row,
|
|
18055
|
+
function readPath(row, path38) {
|
|
18027
18056
|
let current = row;
|
|
18028
|
-
for (const segment of
|
|
18057
|
+
for (const segment of path38.split(".")) {
|
|
18029
18058
|
const record = asRecord2(current);
|
|
18030
18059
|
if (!record) return void 0;
|
|
18031
18060
|
current = record[segment];
|
|
@@ -18035,10 +18064,10 @@ function readPath(row, path40) {
|
|
|
18035
18064
|
function projectFields(rows, paths) {
|
|
18036
18065
|
return rows.map((row) => {
|
|
18037
18066
|
const projected = {};
|
|
18038
|
-
for (const
|
|
18039
|
-
const value = readPath(row,
|
|
18067
|
+
for (const path38 of paths) {
|
|
18068
|
+
const value = readPath(row, path38);
|
|
18040
18069
|
if (value !== void 0) {
|
|
18041
|
-
projected[
|
|
18070
|
+
projected[path38] = value;
|
|
18042
18071
|
}
|
|
18043
18072
|
}
|
|
18044
18073
|
return projected;
|
|
@@ -19338,11 +19367,11 @@ var updateStatusSchema = z25.enum(UPDATE_STATUSES);
|
|
|
19338
19367
|
function currencyMinimums2(currencyCode) {
|
|
19339
19368
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
19340
19369
|
}
|
|
19341
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
19370
|
+
function validateDailyBudgetFloor(money, ctx, path38) {
|
|
19342
19371
|
if (money?.currencyCode) {
|
|
19343
19372
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
19344
19373
|
if (Number(money.amount) < min) {
|
|
19345
|
-
ctx.addIssue({ code: "custom", path:
|
|
19374
|
+
ctx.addIssue({ code: "custom", path: path38, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
19346
19375
|
}
|
|
19347
19376
|
}
|
|
19348
19377
|
}
|
|
@@ -20011,19 +20040,19 @@ function failWriteValidation3(message) {
|
|
|
20011
20040
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
20012
20041
|
process.exit(1);
|
|
20013
20042
|
}
|
|
20014
|
-
function loadJsonFileArg3(
|
|
20015
|
-
if (typeof
|
|
20043
|
+
function loadJsonFileArg3(path38) {
|
|
20044
|
+
if (typeof path38 !== "string" || path38.length === 0) {
|
|
20016
20045
|
return {};
|
|
20017
20046
|
}
|
|
20018
20047
|
try {
|
|
20019
|
-
const parsed = JSON.parse(readFileSync8(
|
|
20048
|
+
const parsed = JSON.parse(readFileSync8(path38, "utf8"));
|
|
20020
20049
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20021
|
-
failWriteValidation3(`${
|
|
20050
|
+
failWriteValidation3(`${path38} must contain a JSON object`);
|
|
20022
20051
|
}
|
|
20023
20052
|
return parsed;
|
|
20024
20053
|
} catch (err) {
|
|
20025
20054
|
if (err instanceof SyntaxError) {
|
|
20026
|
-
failWriteValidation3(`${
|
|
20055
|
+
failWriteValidation3(`${path38} is not valid JSON: ${err.message}`);
|
|
20027
20056
|
}
|
|
20028
20057
|
throw err;
|
|
20029
20058
|
}
|
|
@@ -24621,11 +24650,11 @@ function unwrap(response) {
|
|
|
24621
24650
|
}
|
|
24622
24651
|
return response.data;
|
|
24623
24652
|
}
|
|
24624
|
-
async function readAvatars(
|
|
24625
|
-
return unwrap(await apiGet(
|
|
24653
|
+
async function readAvatars(path38, params) {
|
|
24654
|
+
return unwrap(await apiGet(path38, params));
|
|
24626
24655
|
}
|
|
24627
|
-
async function writeAvatars(
|
|
24628
|
-
return unwrap(await apiPost(
|
|
24656
|
+
async function writeAvatars(path38, body) {
|
|
24657
|
+
return unwrap(await apiPost(path38, body));
|
|
24629
24658
|
}
|
|
24630
24659
|
|
|
24631
24660
|
// src/commands/avatars/create.ts
|
|
@@ -25371,14 +25400,14 @@ function suggestFamilies(wanted, catalogue, limit = 5) {
|
|
|
25371
25400
|
const key = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
|
|
25372
25401
|
const target = key(wanted);
|
|
25373
25402
|
if (!target) return [];
|
|
25374
|
-
const
|
|
25403
|
+
const words2 = target.split(" ");
|
|
25375
25404
|
const scored = catalogue.map((family) => {
|
|
25376
25405
|
const candidate = key(family);
|
|
25377
25406
|
if (candidate === target) return { family, score: 0 };
|
|
25378
25407
|
if (candidate.startsWith(target)) return { family, score: 1 };
|
|
25379
25408
|
if (candidate.includes(target)) return { family, score: 2 };
|
|
25380
|
-
const shared =
|
|
25381
|
-
return { family, score: shared > 0 ? 3 + (
|
|
25409
|
+
const shared = words2.filter((w) => w.length > 2 && candidate.includes(w)).length;
|
|
25410
|
+
return { family, score: shared > 0 ? 3 + (words2.length - shared) : Number.POSITIVE_INFINITY };
|
|
25382
25411
|
}).filter((c) => Number.isFinite(c.score)).sort((a, b) => a.score - b.score || a.family.localeCompare(b.family));
|
|
25383
25412
|
return scored.slice(0, limit).map((c) => c.family);
|
|
25384
25413
|
}
|
|
@@ -25459,12 +25488,12 @@ function missingFontFiles(urls, available) {
|
|
|
25459
25488
|
function planFontAdoption(sources, families) {
|
|
25460
25489
|
const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
|
|
25461
25490
|
const byFamily = /* @__PURE__ */ new Map();
|
|
25462
|
-
for (const { path:
|
|
25463
|
-
const dir = posix.dirname(
|
|
25491
|
+
for (const { path: path38, source } of sources) {
|
|
25492
|
+
const dir = posix.dirname(path38);
|
|
25464
25493
|
for (const face of declaredFontFaces(source)) {
|
|
25465
25494
|
if (!wanted.has(face.family)) continue;
|
|
25466
25495
|
const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
|
|
25467
|
-
perFile.set(
|
|
25496
|
+
perFile.set(path38, [...perFile.get(path38) ?? [], rebaseFontFaceSrc(face.block, dir)]);
|
|
25468
25497
|
byFamily.set(face.family, perFile);
|
|
25469
25498
|
}
|
|
25470
25499
|
}
|
|
@@ -26872,10 +26901,10 @@ function estSpeechS(text2) {
|
|
|
26872
26901
|
var OBSERVED_WPS_MIN = 1;
|
|
26873
26902
|
var OBSERVED_WPS_MAX = 6;
|
|
26874
26903
|
function estSpeechWindowS(text2, startS, endS) {
|
|
26875
|
-
const
|
|
26904
|
+
const words2 = wordCount(text2);
|
|
26876
26905
|
const window2 = (endS ?? 0) - (startS ?? 0);
|
|
26877
|
-
if (
|
|
26878
|
-
const wps =
|
|
26906
|
+
if (words2 > 0 && window2 > 0.3) {
|
|
26907
|
+
const wps = words2 / window2;
|
|
26879
26908
|
if (wps >= OBSERVED_WPS_MIN && wps <= OBSERVED_WPS_MAX) return window2;
|
|
26880
26909
|
}
|
|
26881
26910
|
return estSpeechS(text2);
|
|
@@ -27731,10 +27760,10 @@ function scrubFloatSentences(text2, floatDescs) {
|
|
|
27731
27760
|
if (floatDescs.length === 0 || !text2) return text2;
|
|
27732
27761
|
const tokenSets = floatDescs.map((d) => new Set(floatTokens(d)));
|
|
27733
27762
|
const kept = text2.split(/(?<=[.!?])\s+/).filter((sentence) => {
|
|
27734
|
-
const
|
|
27763
|
+
const words2 = new Set(floatTokens(sentence));
|
|
27735
27764
|
return !tokenSets.some((ts) => {
|
|
27736
27765
|
let hits = 0;
|
|
27737
|
-
for (const w of
|
|
27766
|
+
for (const w of words2) if (ts.has(w)) hits++;
|
|
27738
27767
|
return hits >= 2;
|
|
27739
27768
|
});
|
|
27740
27769
|
}).join(" ").trim();
|
|
@@ -33659,12 +33688,12 @@ function collectSideEffects(tree) {
|
|
|
33659
33688
|
);
|
|
33660
33689
|
}
|
|
33661
33690
|
function readFlowTree(slug) {
|
|
33662
|
-
const
|
|
33663
|
-
if (!existsSync5(
|
|
33691
|
+
const path38 = join3(flowsDir(), slug, "_data.json");
|
|
33692
|
+
if (!existsSync5(path38)) {
|
|
33664
33693
|
failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
|
|
33665
33694
|
}
|
|
33666
33695
|
try {
|
|
33667
|
-
return JSON.parse(readFileSync9(
|
|
33696
|
+
return JSON.parse(readFileSync9(path38, "utf-8"));
|
|
33668
33697
|
} catch (error) {
|
|
33669
33698
|
failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
|
|
33670
33699
|
}
|
|
@@ -34056,10 +34085,10 @@ function parseValueExpression(raw) {
|
|
|
34056
34085
|
return parts.map(parsePart);
|
|
34057
34086
|
}
|
|
34058
34087
|
function trackingFieldIds() {
|
|
34059
|
-
const
|
|
34060
|
-
if (!existsSync6(
|
|
34088
|
+
const path38 = join4(flowsDir(), "..", "tracking.ts");
|
|
34089
|
+
if (!existsSync6(path38)) return null;
|
|
34061
34090
|
try {
|
|
34062
|
-
const source = readFileSync10(
|
|
34091
|
+
const source = readFileSync10(path38, "utf-8");
|
|
34063
34092
|
const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
|
|
34064
34093
|
if (!block2) return null;
|
|
34065
34094
|
const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
|
|
@@ -34611,13 +34640,13 @@ function specsFromFile(parsed) {
|
|
|
34611
34640
|
return `${destField}${type}=${entry?.value ?? ""}`;
|
|
34612
34641
|
});
|
|
34613
34642
|
}
|
|
34614
|
-
function readSpecFile(
|
|
34643
|
+
function readSpecFile(path38) {
|
|
34615
34644
|
let raw;
|
|
34616
34645
|
try {
|
|
34617
|
-
raw =
|
|
34646
|
+
raw = path38 === "-" ? readFileSync11(0, "utf-8") : readFileSync11(path38, "utf-8");
|
|
34618
34647
|
} catch (error) {
|
|
34619
34648
|
refuse(
|
|
34620
|
-
`Could not read ${
|
|
34649
|
+
`Could not read ${path38 === "-" ? "the mapping from stdin" : `"${path38}"`}: ${error instanceof Error ? error.message : String(error)}`
|
|
34621
34650
|
);
|
|
34622
34651
|
}
|
|
34623
34652
|
let parsed;
|
|
@@ -34625,7 +34654,7 @@ function readSpecFile(path40) {
|
|
|
34625
34654
|
parsed = JSON.parse(raw);
|
|
34626
34655
|
} catch (error) {
|
|
34627
34656
|
refuse(
|
|
34628
|
-
`${
|
|
34657
|
+
`${path38 === "-" ? "stdin" : `"${path38}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
34629
34658
|
'Expected { "map": { "<destField>": "<value>", \u2026 } }'
|
|
34630
34659
|
);
|
|
34631
34660
|
}
|
|
@@ -34879,18 +34908,18 @@ var ARRAY_FIELDS = [
|
|
|
34879
34908
|
"tagIds"
|
|
34880
34909
|
];
|
|
34881
34910
|
var ARRAY_OWNERS = ["", "body"];
|
|
34882
|
-
function dropUnsetOptionals(sideEffect,
|
|
34911
|
+
function dropUnsetOptionals(sideEffect, path38) {
|
|
34883
34912
|
return OPTIONAL_STRINGS.flatMap((key) => {
|
|
34884
34913
|
if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
|
|
34885
34914
|
delete sideEffect[key];
|
|
34886
|
-
return [{ path:
|
|
34915
|
+
return [{ path: path38, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
|
|
34887
34916
|
});
|
|
34888
34917
|
}
|
|
34889
|
-
function fillNulledArrays(target, prefix,
|
|
34918
|
+
function fillNulledArrays(target, prefix, path38) {
|
|
34890
34919
|
return ARRAY_FIELDS.flatMap((key) => {
|
|
34891
34920
|
if (!(key in target) || target[key] !== null) return [];
|
|
34892
34921
|
target[key] = [];
|
|
34893
|
-
return [{ path:
|
|
34922
|
+
return [{ path: path38, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
|
|
34894
34923
|
});
|
|
34895
34924
|
}
|
|
34896
34925
|
function sideEffectsOf(node) {
|
|
@@ -34900,13 +34929,13 @@ function sideEffectsOf(node) {
|
|
|
34900
34929
|
);
|
|
34901
34930
|
}
|
|
34902
34931
|
function normalizeSideEffect(sideEffect, where) {
|
|
34903
|
-
const
|
|
34932
|
+
const path38 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
|
|
34904
34933
|
const arrays = ARRAY_OWNERS.flatMap((owner) => {
|
|
34905
34934
|
const target = owner ? sideEffect[owner] : sideEffect;
|
|
34906
34935
|
if (!target || typeof target !== "object") return [];
|
|
34907
|
-
return fillNulledArrays(target, owner ? `${owner}.` : "",
|
|
34936
|
+
return fillNulledArrays(target, owner ? `${owner}.` : "", path38);
|
|
34908
34937
|
});
|
|
34909
|
-
return [...dropUnsetOptionals(sideEffect,
|
|
34938
|
+
return [...dropUnsetOptionals(sideEffect, path38), ...arrays];
|
|
34910
34939
|
}
|
|
34911
34940
|
function normalizeFlowTree(tree) {
|
|
34912
34941
|
const changes = [];
|
|
@@ -35444,10 +35473,10 @@ async function stageOps(ops) {
|
|
|
35444
35473
|
handleError2(err);
|
|
35445
35474
|
}
|
|
35446
35475
|
}
|
|
35447
|
-
async function draftAction2(
|
|
35476
|
+
async function draftAction2(path38, body, chat) {
|
|
35448
35477
|
const chatId = resolveChatId(chat);
|
|
35449
35478
|
try {
|
|
35450
|
-
const data = await apiPost(
|
|
35479
|
+
const data = await apiPost(path38, { chatId, ...body });
|
|
35451
35480
|
writeJsonEnvelope({ ok: true, data });
|
|
35452
35481
|
return data;
|
|
35453
35482
|
} catch (err) {
|
|
@@ -37879,9 +37908,9 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
37879
37908
|
}
|
|
37880
37909
|
return readFile20(pathOrUrl);
|
|
37881
37910
|
}
|
|
37882
|
-
async function isDirectory(
|
|
37911
|
+
async function isDirectory(path38) {
|
|
37883
37912
|
try {
|
|
37884
|
-
const s = await stat4(
|
|
37913
|
+
const s = await stat4(path38);
|
|
37885
37914
|
return s.isDirectory();
|
|
37886
37915
|
} catch {
|
|
37887
37916
|
return false;
|
|
@@ -38183,13 +38212,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
|
|
|
38183
38212
|
}
|
|
38184
38213
|
function disambiguate(paths) {
|
|
38185
38214
|
const taken = /* @__PURE__ */ new Set();
|
|
38186
|
-
return paths.map((
|
|
38187
|
-
if (!taken.has(
|
|
38188
|
-
taken.add(
|
|
38189
|
-
return
|
|
38215
|
+
return paths.map((path38) => {
|
|
38216
|
+
if (!taken.has(path38)) {
|
|
38217
|
+
taken.add(path38);
|
|
38218
|
+
return path38;
|
|
38190
38219
|
}
|
|
38191
|
-
const ext = extname3(
|
|
38192
|
-
const stem =
|
|
38220
|
+
const ext = extname3(path38);
|
|
38221
|
+
const stem = path38.slice(0, path38.length - ext.length);
|
|
38193
38222
|
let n = 2;
|
|
38194
38223
|
while (taken.has(`${stem}-${n}${ext}`)) n += 1;
|
|
38195
38224
|
const unique = `${stem}-${n}${ext}`;
|
|
@@ -38316,10 +38345,10 @@ async function runDownloads(plan) {
|
|
|
38316
38345
|
const paths = disambiguate(fetched.map((item) => item.path));
|
|
38317
38346
|
const downloaded = [];
|
|
38318
38347
|
for (const [index, item] of fetched.entries()) {
|
|
38319
|
-
const
|
|
38348
|
+
const path38 = paths[index] ?? item.path;
|
|
38320
38349
|
try {
|
|
38321
|
-
await atomicWrite(
|
|
38322
|
-
downloaded.push({ input: item.input, output:
|
|
38350
|
+
await atomicWrite(path38, item.buffer);
|
|
38351
|
+
downloaded.push({ input: item.input, output: path38, bytes: item.buffer.length, contentType: item.contentType });
|
|
38323
38352
|
} catch (err) {
|
|
38324
38353
|
failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
|
|
38325
38354
|
}
|
|
@@ -41279,7 +41308,7 @@ import { defineCommand as defineCommand166 } from "citty";
|
|
|
41279
41308
|
|
|
41280
41309
|
// src/commands/landing/critique.ts
|
|
41281
41310
|
import { readdir as readdir9, stat as stat6 } from "fs/promises";
|
|
41282
|
-
import
|
|
41311
|
+
import path28 from "path";
|
|
41283
41312
|
import { defineCommand as defineCommand156 } from "citty";
|
|
41284
41313
|
|
|
41285
41314
|
// src/engine/landing/lib/constants.ts
|
|
@@ -41482,11 +41511,6 @@ var RULE_META = {
|
|
|
41482
41511
|
severity: "block",
|
|
41483
41512
|
note: "Gradient text is a top AI tell. Emphasis comes from weight or size, not a clipped gradient fill."
|
|
41484
41513
|
},
|
|
41485
|
-
"copied-reference-copy": {
|
|
41486
|
-
family: "originality",
|
|
41487
|
-
severity: "block",
|
|
41488
|
-
note: "This line is lifted from a section you consulted in the inspiration library. Reference sections are for structure and mechanism, never words \u2014 a visitor who has seen the original reads this as a clone, and the claim is not yours to make. Rewrite it from the client's own offer."
|
|
41489
|
-
},
|
|
41490
41514
|
"broken-image": {
|
|
41491
41515
|
family: "integrity",
|
|
41492
41516
|
severity: "block",
|
|
@@ -41667,64 +41691,6 @@ var SEVERITY_WEIGHT = {
|
|
|
41667
41691
|
advisory: 0.05
|
|
41668
41692
|
};
|
|
41669
41693
|
|
|
41670
|
-
// src/engine/landing/lib/originality.ts
|
|
41671
|
-
var MIN_COMPARABLE_LENGTH = 12;
|
|
41672
|
-
var NEAR_MATCH_RATIO = 0.8;
|
|
41673
|
-
function normalize(value) {
|
|
41674
|
-
return value.toLowerCase().replace(/[‘’“”]/g, "'").replace(/[^a-z0-9']+/g, " ").trim();
|
|
41675
|
-
}
|
|
41676
|
-
function words2(value) {
|
|
41677
|
-
return normalize(value).split(" ").filter(Boolean);
|
|
41678
|
-
}
|
|
41679
|
-
function copyOverlapRatio(candidate, reference) {
|
|
41680
|
-
const referenceWords = words2(reference);
|
|
41681
|
-
if (referenceWords.length === 0) return 0;
|
|
41682
|
-
const candidateWords = new Set(words2(candidate));
|
|
41683
|
-
const shared = referenceWords.filter((word) => candidateWords.has(word)).length;
|
|
41684
|
-
return shared / referenceWords.length;
|
|
41685
|
-
}
|
|
41686
|
-
function isVerbatimReuse(candidate, reference) {
|
|
41687
|
-
const normalizedCandidate = normalize(candidate);
|
|
41688
|
-
const normalizedReference = normalize(reference);
|
|
41689
|
-
if (normalizedReference.length < MIN_COMPARABLE_LENGTH) return false;
|
|
41690
|
-
if (normalizedCandidate.includes(normalizedReference)) return true;
|
|
41691
|
-
return copyOverlapRatio(candidate, reference) >= NEAR_MATCH_RATIO;
|
|
41692
|
-
}
|
|
41693
|
-
function extractVisibleStrings(text2) {
|
|
41694
|
-
const found = [];
|
|
41695
|
-
const lines = text2.split("\n");
|
|
41696
|
-
for (const [index, line] of lines.entries()) {
|
|
41697
|
-
for (const match of line.matchAll(/>([^<>{}]{12,200})</g)) {
|
|
41698
|
-
const value = match[1]?.trim();
|
|
41699
|
-
if (value && /[a-zA-Z]{3}/.test(value)) found.push({ value, line: index + 1 });
|
|
41700
|
-
}
|
|
41701
|
-
}
|
|
41702
|
-
return found;
|
|
41703
|
-
}
|
|
41704
|
-
function detectOriginality(sources, references) {
|
|
41705
|
-
if (references.length === 0) return [];
|
|
41706
|
-
const findings = [];
|
|
41707
|
-
const seen = /* @__PURE__ */ new Set();
|
|
41708
|
-
for (const source of sources) {
|
|
41709
|
-
for (const { value, line } of extractVisibleStrings(source.text)) {
|
|
41710
|
-
for (const reference of references) {
|
|
41711
|
-
const hit = reference.copyStrings.find((copy) => isVerbatimReuse(value, copy));
|
|
41712
|
-
if (!hit) continue;
|
|
41713
|
-
const key = `${source.path}:${line}:${normalize(hit)}`;
|
|
41714
|
-
if (seen.has(key)) continue;
|
|
41715
|
-
seen.add(key);
|
|
41716
|
-
findings.push({
|
|
41717
|
-
id: "copied-reference-copy",
|
|
41718
|
-
snippet: value.slice(0, 120),
|
|
41719
|
-
file: source.path,
|
|
41720
|
-
line
|
|
41721
|
-
});
|
|
41722
|
-
}
|
|
41723
|
-
}
|
|
41724
|
-
}
|
|
41725
|
-
return findings;
|
|
41726
|
-
}
|
|
41727
|
-
|
|
41728
41694
|
// src/engine/landing/lib/rules.ts
|
|
41729
41695
|
var cap2 = (m, i) => m[i] ?? "";
|
|
41730
41696
|
var num2 = (m, i) => Number(m[i] ?? 0);
|
|
@@ -42252,16 +42218,7 @@ function dedupe(findings) {
|
|
|
42252
42218
|
}
|
|
42253
42219
|
|
|
42254
42220
|
// src/engine/landing/lib/critique.ts
|
|
42255
|
-
var FAMILIES = [
|
|
42256
|
-
"typography",
|
|
42257
|
-
"color",
|
|
42258
|
-
"borders_depth",
|
|
42259
|
-
"motion",
|
|
42260
|
-
"spacing",
|
|
42261
|
-
"copy",
|
|
42262
|
-
"integrity",
|
|
42263
|
-
"originality"
|
|
42264
|
-
];
|
|
42221
|
+
var FAMILIES = ["typography", "color", "borders_depth", "motion", "spacing", "copy", "integrity"];
|
|
42265
42222
|
function round4(n) {
|
|
42266
42223
|
return Math.round(n * 100) / 100;
|
|
42267
42224
|
}
|
|
@@ -42280,7 +42237,6 @@ function critiqueLanding(input) {
|
|
|
42280
42237
|
const raws = [];
|
|
42281
42238
|
for (const source of sources) raws.push(...detectSource(source));
|
|
42282
42239
|
raws.push(...detectPage(sources));
|
|
42283
|
-
raws.push(...detectOriginality(sources, input.references ?? []));
|
|
42284
42240
|
for (const raw of raws) {
|
|
42285
42241
|
const meta = RULE_META[raw.id];
|
|
42286
42242
|
if (!meta) continue;
|
|
@@ -42318,82 +42274,41 @@ function describeCounts(findings) {
|
|
|
42318
42274
|
return [b ? `${b} block` : "", w ? `${w} warn` : "", a ? `${a} advisory` : ""].filter(Boolean).join(", ");
|
|
42319
42275
|
}
|
|
42320
42276
|
|
|
42321
|
-
// src/engine/landing/lib/referenceStore.ts
|
|
42322
|
-
import { mkdir as mkdir8, readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
|
|
42323
|
-
import path26 from "path";
|
|
42324
|
-
var REFERENCES_FILE = ".cache/inspiration-refs.json";
|
|
42325
|
-
var REFERENCE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
42326
|
-
async function readReferences(projectRoot) {
|
|
42327
|
-
try {
|
|
42328
|
-
const raw = await readFile21(path26.join(projectRoot, REFERENCES_FILE), "utf8");
|
|
42329
|
-
const parsed = JSON.parse(raw);
|
|
42330
|
-
if (!Array.isArray(parsed)) return [];
|
|
42331
|
-
const cutoff = Date.now() - REFERENCE_TTL_MS;
|
|
42332
|
-
return parsed.filter((entry) => {
|
|
42333
|
-
if (typeof entry !== "object" || entry === null) return false;
|
|
42334
|
-
const candidate = entry;
|
|
42335
|
-
if (typeof candidate.sectionId !== "string" || !Array.isArray(candidate.copyStrings)) return false;
|
|
42336
|
-
const at = Date.parse(candidate.consultedAt ?? "");
|
|
42337
|
-
return Number.isNaN(at) ? true : at >= cutoff;
|
|
42338
|
-
});
|
|
42339
|
-
} catch {
|
|
42340
|
-
return [];
|
|
42341
|
-
}
|
|
42342
|
-
}
|
|
42343
|
-
async function recordReference(projectRoot, reference) {
|
|
42344
|
-
return await recordReferences(projectRoot, [reference]);
|
|
42345
|
-
}
|
|
42346
|
-
async function recordReferences(projectRoot, references) {
|
|
42347
|
-
if (references.length === 0) return true;
|
|
42348
|
-
try {
|
|
42349
|
-
const existing = await readReferences(projectRoot);
|
|
42350
|
-
const replaced = new Set(references.map((reference) => reference.sectionId));
|
|
42351
|
-
const merged = [...existing.filter((entry) => !replaced.has(entry.sectionId)), ...references];
|
|
42352
|
-
const file = path26.join(projectRoot, REFERENCES_FILE);
|
|
42353
|
-
await mkdir8(path26.dirname(file), { recursive: true });
|
|
42354
|
-
await writeFile12(file, `${JSON.stringify(merged, null, 2)}
|
|
42355
|
-
`);
|
|
42356
|
-
return true;
|
|
42357
|
-
} catch {
|
|
42358
|
-
return false;
|
|
42359
|
-
}
|
|
42360
|
-
}
|
|
42361
|
-
|
|
42362
42277
|
// src/commands/landing/snapshot.ts
|
|
42363
|
-
import { mkdir as
|
|
42364
|
-
import
|
|
42278
|
+
import { mkdir as mkdir8, rename as rename2, writeFile as writeFile12 } from "fs/promises";
|
|
42279
|
+
import path26 from "path";
|
|
42365
42280
|
var CRITIC_VERSION = "2";
|
|
42366
42281
|
function critiqueCacheDir(projectRoot) {
|
|
42367
|
-
return
|
|
42282
|
+
return path26.join(projectRoot, ".cache", "landing-critique");
|
|
42368
42283
|
}
|
|
42369
42284
|
function snapshotPath(projectRoot, slug) {
|
|
42370
|
-
return
|
|
42285
|
+
return path26.join(critiqueCacheDir(projectRoot), `${slug}.json`);
|
|
42371
42286
|
}
|
|
42372
42287
|
async function writeCritiqueSnapshot(projectRoot, snapshot) {
|
|
42373
|
-
await
|
|
42288
|
+
await mkdir8(critiqueCacheDir(projectRoot), { recursive: true });
|
|
42374
42289
|
const dest = snapshotPath(projectRoot, snapshot.slug);
|
|
42375
42290
|
const tmp = `${dest}.tmp`;
|
|
42376
|
-
await
|
|
42291
|
+
await writeFile12(tmp, `${JSON.stringify(snapshot, null, 2)}
|
|
42377
42292
|
`, "utf8");
|
|
42378
42293
|
await rename2(tmp, dest);
|
|
42379
42294
|
}
|
|
42380
42295
|
|
|
42381
42296
|
// src/commands/landing/source-version.ts
|
|
42382
|
-
import { readdir as readdir8, readFile as
|
|
42383
|
-
import
|
|
42297
|
+
import { readdir as readdir8, readFile as readFile21, stat as stat5 } from "fs/promises";
|
|
42298
|
+
import path27 from "path";
|
|
42384
42299
|
async function landingSourceRelPaths(landingDir) {
|
|
42385
42300
|
const rel = [];
|
|
42386
|
-
if (await isFile(
|
|
42387
|
-
const componentsDir =
|
|
42301
|
+
if (await isFile(path27.join(landingDir, "index.astro"))) rel.push("index.astro");
|
|
42302
|
+
const componentsDir = path27.join(landingDir, "_components");
|
|
42388
42303
|
for (const abs of await walkAstro(componentsDir)) {
|
|
42389
|
-
rel.push(
|
|
42304
|
+
rel.push(path27.relative(landingDir, abs).split(path27.sep).join("/"));
|
|
42390
42305
|
}
|
|
42391
42306
|
return rel.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
42392
42307
|
}
|
|
42393
42308
|
async function readLandingSources(landingDir) {
|
|
42394
42309
|
const rel = await landingSourceRelPaths(landingDir);
|
|
42395
42310
|
const out = [];
|
|
42396
|
-
for (const r of rel) out.push({ path: r, text: await
|
|
42311
|
+
for (const r of rel) out.push({ path: r, text: await readFile21(path27.join(landingDir, r), "utf8") });
|
|
42397
42312
|
return out;
|
|
42398
42313
|
}
|
|
42399
42314
|
async function computeLandingSourceSha(landingDir) {
|
|
@@ -42402,7 +42317,7 @@ async function computeLandingSourceSha(landingDir) {
|
|
|
42402
42317
|
for (const r of rel) {
|
|
42403
42318
|
let bytes;
|
|
42404
42319
|
try {
|
|
42405
|
-
bytes = await
|
|
42320
|
+
bytes = await readFile21(path27.join(landingDir, r));
|
|
42406
42321
|
} catch {
|
|
42407
42322
|
bytes = Buffer.alloc(0);
|
|
42408
42323
|
}
|
|
@@ -42426,7 +42341,7 @@ async function walkAstro(dir) {
|
|
|
42426
42341
|
}
|
|
42427
42342
|
const out = [];
|
|
42428
42343
|
for (const entry of entries) {
|
|
42429
|
-
const abs =
|
|
42344
|
+
const abs = path27.join(dir, entry.name);
|
|
42430
42345
|
if (entry.isDirectory()) out.push(...await walkAstro(abs));
|
|
42431
42346
|
else if (entry.isFile() && entry.name.endsWith(".astro")) out.push(abs);
|
|
42432
42347
|
}
|
|
@@ -42487,14 +42402,14 @@ var critiqueCommand2 = defineCommand156({
|
|
|
42487
42402
|
{ availableSlugs: await listLandingSlugs(projectRoot) }
|
|
42488
42403
|
);
|
|
42489
42404
|
}
|
|
42490
|
-
if (!await isDir(
|
|
42405
|
+
if (!await isDir(path28.resolve(projectRoot, "src", "pages", slug))) {
|
|
42491
42406
|
fail5("NOT_FOUND", `No landing at src/pages/${slug}/`, {
|
|
42492
42407
|
availableSlugs: await listLandingSlugs(projectRoot)
|
|
42493
42408
|
});
|
|
42494
42409
|
}
|
|
42495
42410
|
}
|
|
42496
|
-
const
|
|
42497
|
-
const results = await Promise.all(slugs.map((slug) => critiqueOne(projectRoot, slug, brand
|
|
42411
|
+
const brand = await loadBrandTokens(projectRoot);
|
|
42412
|
+
const results = await Promise.all(slugs.map((slug) => critiqueOne(projectRoot, slug, brand)));
|
|
42498
42413
|
const landings = results.map(({ slug, report }) => ({
|
|
42499
42414
|
slug,
|
|
42500
42415
|
overall: report.overall,
|
|
@@ -42525,10 +42440,10 @@ var critiqueCommand2 = defineCommand156({
|
|
|
42525
42440
|
);
|
|
42526
42441
|
}
|
|
42527
42442
|
});
|
|
42528
|
-
async function critiqueOne(projectRoot, slug, brand
|
|
42529
|
-
const landingDir =
|
|
42443
|
+
async function critiqueOne(projectRoot, slug, brand) {
|
|
42444
|
+
const landingDir = path28.resolve(projectRoot, "src", "pages", slug);
|
|
42530
42445
|
const [sources, sourceSha] = await Promise.all([readLandingSources(landingDir), computeLandingSourceSha(landingDir)]);
|
|
42531
|
-
const report = critiqueLanding({ slug, sources, brand
|
|
42446
|
+
const report = critiqueLanding({ slug, sources, brand });
|
|
42532
42447
|
let snapshotFailed = false;
|
|
42533
42448
|
try {
|
|
42534
42449
|
await writeCritiqueSnapshot(projectRoot, {
|
|
@@ -42546,7 +42461,7 @@ async function critiqueOne(projectRoot, slug, brand, references) {
|
|
|
42546
42461
|
}
|
|
42547
42462
|
async function listLandingSlugs(projectRoot) {
|
|
42548
42463
|
try {
|
|
42549
|
-
const entries = await readdir9(
|
|
42464
|
+
const entries = await readdir9(path28.join(projectRoot, "src", "pages"), { withFileTypes: true });
|
|
42550
42465
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
42551
42466
|
} catch {
|
|
42552
42467
|
return [];
|
|
@@ -42579,7 +42494,7 @@ import { defineCommand as defineCommand157 } from "citty";
|
|
|
42579
42494
|
|
|
42580
42495
|
// src/commands/landing/inspiration/shared.ts
|
|
42581
42496
|
var INSPIRATION_HINTS = {
|
|
42582
|
-
adapt: "Reference only. Re-express this in the client's BRAND.md palette, type and imagery register. Reusing a headline, subhead or CTA verbatim is a Tier 0 message-match failure (references/gotchas.md)
|
|
42497
|
+
adapt: "Reference only. Re-express this in the client's BRAND.md palette, type and imagery register. Reusing a headline, subhead or CTA verbatim is a Tier 0 message-match failure (references/gotchas.md).",
|
|
42583
42498
|
structureNotCopy: "Take the structural decision, not the furniture: what the eye hits first, the grid ratio, what was deliberately left out. Your copy must come from the client's own offer."
|
|
42584
42499
|
};
|
|
42585
42500
|
function favoritesScopeHints(health, resultCount) {
|
|
@@ -42697,12 +42612,12 @@ var addCommand = defineCommand157({
|
|
|
42697
42612
|
});
|
|
42698
42613
|
|
|
42699
42614
|
// src/commands/landing/inspiration/code.ts
|
|
42700
|
-
import { mkdir as
|
|
42701
|
-
import
|
|
42615
|
+
import { mkdir as mkdir9, writeFile as writeFile13 } from "fs/promises";
|
|
42616
|
+
import path29 from "path";
|
|
42702
42617
|
import { defineCommand as defineCommand158 } from "citty";
|
|
42703
42618
|
registerSchema({
|
|
42704
42619
|
command: "landing.inspiration.code",
|
|
42705
|
-
description: "Write a reference section's standalone HTML+CSS to .baker/inspiration/<id>/ so you can read how it is built. Reference only \u2014 the structure is the lesson, the words are not yours to reuse.
|
|
42620
|
+
description: "Write a reference section's standalone HTML+CSS to .baker/inspiration/<id>/ so you can read how it is built. Reference only \u2014 the structure is the lesson, the words are not yours to reuse.",
|
|
42706
42621
|
args: {
|
|
42707
42622
|
id: { type: "string", description: "Section id from search", required: true },
|
|
42708
42623
|
full: { type: "boolean", description: "Print the markup inline as well as writing it", required: false }
|
|
@@ -42721,30 +42636,19 @@ var codeCommand = defineCommand158({
|
|
|
42721
42636
|
try {
|
|
42722
42637
|
const id = args.id;
|
|
42723
42638
|
const data = await apiGet("/api/landing-inspiration/section-code", { id });
|
|
42724
|
-
const dir =
|
|
42725
|
-
await
|
|
42726
|
-
const file =
|
|
42727
|
-
await
|
|
42728
|
-
const recorded = await recordReference(process.cwd(), {
|
|
42729
|
-
sectionId: id,
|
|
42730
|
-
sourceUrl: data.sourceUrl,
|
|
42731
|
-
copyStrings: data.copyStrings,
|
|
42732
|
-
consultedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
42733
|
-
});
|
|
42639
|
+
const dir = path29.join(process.cwd(), ".baker", "inspiration", id);
|
|
42640
|
+
await mkdir9(dir, { recursive: true });
|
|
42641
|
+
const file = path29.join(dir, "section.html");
|
|
42642
|
+
await writeFile13(file, data.html);
|
|
42734
42643
|
const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
|
|
42735
42644
|
const fidelity = fidelityHint(data.fidelity);
|
|
42736
42645
|
if (fidelity) hints.push(fidelity);
|
|
42737
42646
|
if (data.fidelityNote) hints.push(data.fidelityNote);
|
|
42738
|
-
if (!recorded) {
|
|
42739
|
-
hints.push(
|
|
42740
|
-
"Could not record this reference (.cache/ not writable?) \u2014 the originality check at publish will not be able to see it, so be especially careful not to reuse its copy."
|
|
42741
|
-
);
|
|
42742
|
-
}
|
|
42743
42647
|
writeJson({
|
|
42744
42648
|
ok: true,
|
|
42745
42649
|
data: {
|
|
42746
42650
|
id,
|
|
42747
|
-
file:
|
|
42651
|
+
file: path29.relative(process.cwd(), file),
|
|
42748
42652
|
bytes: data.html.length,
|
|
42749
42653
|
fidelity: data.fidelity,
|
|
42750
42654
|
reproduction_notes: data.reproductionNotes,
|
|
@@ -42999,25 +42903,8 @@ var pageCommand2 = defineCommand160({
|
|
|
42999
42903
|
});
|
|
43000
42904
|
|
|
43001
42905
|
// src/commands/landing/inspiration/scrape.ts
|
|
43002
|
-
import { readFile as readFile23 } from "fs/promises";
|
|
43003
|
-
import path34 from "path";
|
|
43004
42906
|
import { defineCommand as defineCommand161 } from "citty";
|
|
43005
42907
|
|
|
43006
|
-
// src/engine/landing/lib/capturedReferences.ts
|
|
43007
|
-
var MAX_STRINGS_PER_SECTION = 40;
|
|
43008
|
-
function bodyOf(markup) {
|
|
43009
|
-
const body = markup.indexOf("<body");
|
|
43010
|
-
return body === -1 ? markup : markup.slice(body);
|
|
43011
|
-
}
|
|
43012
|
-
function capturedCopyStrings(markup) {
|
|
43013
|
-
const seen = /* @__PURE__ */ new Set();
|
|
43014
|
-
for (const { value } of extractVisibleStrings(bodyOf(markup))) {
|
|
43015
|
-
seen.add(value);
|
|
43016
|
-
if (seen.size >= MAX_STRINGS_PER_SECTION) break;
|
|
43017
|
-
}
|
|
43018
|
-
return [...seen];
|
|
43019
|
-
}
|
|
43020
|
-
|
|
43021
42908
|
// src/engine/landing-library/proxyFailure.ts
|
|
43022
42909
|
var PROXY_STATUS = 407;
|
|
43023
42910
|
var PROXY_NET_ERRORS = [
|
|
@@ -43192,8 +43079,8 @@ function classifyCaptureFailure(error) {
|
|
|
43192
43079
|
}
|
|
43193
43080
|
|
|
43194
43081
|
// src/engine/landing-library/run.ts
|
|
43195
|
-
import { mkdir as
|
|
43196
|
-
import
|
|
43082
|
+
import { mkdir as mkdir10, writeFile as writeFile15 } from "fs/promises";
|
|
43083
|
+
import path31 from "path";
|
|
43197
43084
|
|
|
43198
43085
|
// ../proxy/src/preflight.ts
|
|
43199
43086
|
import http from "http";
|
|
@@ -44608,11 +44495,11 @@ async function renderBundleToPng(browser, html, viewportWidth, options = {}) {
|
|
|
44608
44495
|
}
|
|
44609
44496
|
|
|
44610
44497
|
// src/engine/landing-library/report.ts
|
|
44611
|
-
import { writeFile as
|
|
44612
|
-
import
|
|
44498
|
+
import { writeFile as writeFile14 } from "fs/promises";
|
|
44499
|
+
import path30 from "path";
|
|
44613
44500
|
async function writeCaptureReport(manifest, outDir) {
|
|
44614
|
-
const file =
|
|
44615
|
-
await
|
|
44501
|
+
const file = path30.join(outDir, "report.html");
|
|
44502
|
+
await writeFile14(file, renderReport(manifest));
|
|
44616
44503
|
return file;
|
|
44617
44504
|
}
|
|
44618
44505
|
function escapeHtml3(value) {
|
|
@@ -44790,32 +44677,32 @@ async function reproducePage(args) {
|
|
|
44790
44677
|
const { browser, page, outDir, pageUrl, livePageShot } = args;
|
|
44791
44678
|
const built = await buildSectionBundle(page, "body", pageUrl).catch(() => null);
|
|
44792
44679
|
if (!built) return { bundle: null, fidelity: null };
|
|
44793
|
-
await
|
|
44680
|
+
await writeFile15(path31.join(outDir, "page.html"), built.html);
|
|
44794
44681
|
const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width, {
|
|
44795
44682
|
wholePage: true,
|
|
44796
44683
|
timeoutMs: 6e4
|
|
44797
44684
|
});
|
|
44798
44685
|
if (!rendered || !livePageShot) return { bundle: "page.html", fidelity: null };
|
|
44799
|
-
await
|
|
44686
|
+
await writeFile15(path31.join(outDir, "page-rendered.png"), rendered);
|
|
44800
44687
|
const { score, note } = await scoreFidelity(livePageShot, rendered);
|
|
44801
44688
|
return { bundle: "page.html", fidelity: score, ...note ? { fidelityNote: note } : {} };
|
|
44802
44689
|
}
|
|
44803
44690
|
async function captureOneSection(args) {
|
|
44804
44691
|
const { browser, page, candidate, sectionsDir, outDir, pageUrl, withCode } = args;
|
|
44805
|
-
const dir =
|
|
44806
|
-
await
|
|
44692
|
+
const dir = path31.join(sectionsDir, String(candidate.index).padStart(2, "0"));
|
|
44693
|
+
await mkdir10(dir, { recursive: true });
|
|
44807
44694
|
const desktop = await captureSection(page, candidate);
|
|
44808
|
-
if (desktop) await
|
|
44695
|
+
if (desktop) await writeFile15(path31.join(dir, "desktop.png"), desktop);
|
|
44809
44696
|
const visualHash = desktop ? await perceptualHash(desktop) : null;
|
|
44810
44697
|
const motion = await collectMotion(page, candidate.selector);
|
|
44811
44698
|
const built = withCode ? await buildSectionBundle(page, candidate.selector, pageUrl) : null;
|
|
44812
44699
|
let fidelity = null;
|
|
44813
44700
|
let fidelityNote;
|
|
44814
44701
|
if (built) {
|
|
44815
|
-
await
|
|
44702
|
+
await writeFile15(path31.join(dir, "section.html"), built.html);
|
|
44816
44703
|
const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width);
|
|
44817
44704
|
if (rendered && desktop) {
|
|
44818
|
-
await
|
|
44705
|
+
await writeFile15(path31.join(dir, "section-rendered.png"), rendered);
|
|
44819
44706
|
const result = await scoreFidelity(desktop, rendered);
|
|
44820
44707
|
fidelity = result.score;
|
|
44821
44708
|
fidelityNote = result.note;
|
|
@@ -44823,9 +44710,9 @@ async function captureOneSection(args) {
|
|
|
44823
44710
|
}
|
|
44824
44711
|
return {
|
|
44825
44712
|
...candidate,
|
|
44826
|
-
desktopShot: desktop ?
|
|
44713
|
+
desktopShot: desktop ? path31.relative(outDir, path31.join(dir, "desktop.png")) : null,
|
|
44827
44714
|
mobileShot: null,
|
|
44828
|
-
bundle: built ?
|
|
44715
|
+
bundle: built ? path31.relative(outDir, path31.join(dir, "section.html")) : null,
|
|
44829
44716
|
fidelity,
|
|
44830
44717
|
...fidelityNote ? { fidelityNote } : {},
|
|
44831
44718
|
...built ? { cssStats: built.stats } : {},
|
|
@@ -44844,9 +44731,9 @@ async function captureMobileShots(args) {
|
|
|
44844
44731
|
for (const section of sections) {
|
|
44845
44732
|
const shot = await captureSectionOnMobile(mobile.page, section);
|
|
44846
44733
|
if (!shot) continue;
|
|
44847
|
-
const file =
|
|
44848
|
-
await
|
|
44849
|
-
section.mobileShot =
|
|
44734
|
+
const file = path31.join(sectionsDir, String(section.index).padStart(2, "0"), "mobile.png");
|
|
44735
|
+
await writeFile15(file, shot);
|
|
44736
|
+
section.mobileShot = path31.relative(outDir, file);
|
|
44850
44737
|
}
|
|
44851
44738
|
} finally {
|
|
44852
44739
|
await mobile.context.close();
|
|
@@ -44861,10 +44748,10 @@ async function captureMotionTakes(args) {
|
|
|
44861
44748
|
const filmOne = async (section) => {
|
|
44862
44749
|
const take = await captureMotionTake(browser, pageUrl, section.selector).catch(() => null);
|
|
44863
44750
|
if (!take) return;
|
|
44864
|
-
const dir =
|
|
44865
|
-
const file =
|
|
44866
|
-
await
|
|
44867
|
-
section.motionFilmstrip =
|
|
44751
|
+
const dir = path31.join(sectionsDir, String(section.index).padStart(2, "0"));
|
|
44752
|
+
const file = path31.join(dir, "motion-filmstrip.png");
|
|
44753
|
+
await writeFile15(file, take.filmstrip);
|
|
44754
|
+
section.motionFilmstrip = path31.relative(outDir, file);
|
|
44868
44755
|
log(` [${section.index}] ${section.motion.summary}`);
|
|
44869
44756
|
};
|
|
44870
44757
|
const queue = [...moving];
|
|
@@ -44921,7 +44808,7 @@ async function captureAlternateViews(args) {
|
|
|
44921
44808
|
async function reproduceWholePage(args) {
|
|
44922
44809
|
const { browser, page, outDir, pageUrl, withCode, log } = args;
|
|
44923
44810
|
const fullPage = await page.screenshot({ type: "png", fullPage: true }).catch(() => null);
|
|
44924
|
-
if (fullPage) await
|
|
44811
|
+
if (fullPage) await writeFile15(path31.join(outDir, "full-page.png"), fullPage);
|
|
44925
44812
|
if (!withCode) return { bundle: null, fidelity: null };
|
|
44926
44813
|
const reproduction = await reproducePage({ browser, page, outDir, pageUrl, livePageShot: fullPage });
|
|
44927
44814
|
log(`page reproduction: ${reproduction.fidelity === null ? "unavailable" : reproduction.fidelity.toFixed(2)}`);
|
|
@@ -44992,7 +44879,7 @@ async function openViaLadder(args) {
|
|
|
44992
44879
|
async function scrapeLanding(options) {
|
|
44993
44880
|
const timeoutMs = options.timeoutMs ?? 45e3;
|
|
44994
44881
|
const log = options.onProgress ?? (() => void 0);
|
|
44995
|
-
const sectionsDir =
|
|
44882
|
+
const sectionsDir = path31.join(options.outDir, "sections");
|
|
44996
44883
|
const nonPublic = refuseNonPublicUrl(options.url);
|
|
44997
44884
|
if (nonPublic) {
|
|
44998
44885
|
throw new BlockedPageError({
|
|
@@ -45012,7 +44899,7 @@ async function scrapeLanding(options) {
|
|
|
45012
44899
|
const withMotion = options.motion !== false && !escalated;
|
|
45013
44900
|
const renderBrowser = options.code === false ? null : await launchBrowser();
|
|
45014
44901
|
try {
|
|
45015
|
-
await
|
|
44902
|
+
await mkdir10(sectionsDir, { recursive: true });
|
|
45016
44903
|
const sections = await captureSections({
|
|
45017
44904
|
browser: renderBrowser ?? browser,
|
|
45018
44905
|
page,
|
|
@@ -45054,7 +44941,7 @@ async function scrapeLanding(options) {
|
|
|
45054
44941
|
security: prepared.security,
|
|
45055
44942
|
captureTier: tier
|
|
45056
44943
|
};
|
|
45057
|
-
await
|
|
44944
|
+
await writeFile15(path31.join(options.outDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
45058
44945
|
`);
|
|
45059
44946
|
if (options.report !== false) {
|
|
45060
44947
|
const reportPath = await writeCaptureReport(manifest, options.outDir);
|
|
@@ -45069,28 +44956,28 @@ async function scrapeLanding(options) {
|
|
|
45069
44956
|
|
|
45070
44957
|
// src/commands/landing/inspiration/captureOut.ts
|
|
45071
44958
|
import { existsSync as existsSync9 } from "fs";
|
|
45072
|
-
import
|
|
44959
|
+
import path32 from "path";
|
|
45073
44960
|
var SCRATCH_DIR = ".baker";
|
|
45074
44961
|
function isWithin(parent, target) {
|
|
45075
|
-
const relative =
|
|
45076
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
44962
|
+
const relative = path32.relative(parent, target);
|
|
44963
|
+
return relative === "" || !relative.startsWith("..") && !path32.isAbsolute(relative);
|
|
45077
44964
|
}
|
|
45078
44965
|
function findRepoRoot(from) {
|
|
45079
|
-
let dir =
|
|
44966
|
+
let dir = path32.resolve(from);
|
|
45080
44967
|
for (; ; ) {
|
|
45081
|
-
if (existsSync9(
|
|
45082
|
-
const parent =
|
|
44968
|
+
if (existsSync9(path32.join(dir, ".git"))) return dir;
|
|
44969
|
+
const parent = path32.dirname(dir);
|
|
45083
44970
|
if (parent === dir) return null;
|
|
45084
44971
|
dir = parent;
|
|
45085
44972
|
}
|
|
45086
44973
|
}
|
|
45087
44974
|
function checkCaptureOut(out, options) {
|
|
45088
44975
|
const { cwd, repoRoot } = options;
|
|
45089
|
-
const resolved =
|
|
44976
|
+
const resolved = path32.resolve(cwd, out);
|
|
45090
44977
|
if (repoRoot === null || !isWithin(repoRoot, resolved)) return { ok: true };
|
|
45091
|
-
const scratch =
|
|
44978
|
+
const scratch = path32.join(repoRoot, SCRATCH_DIR);
|
|
45092
44979
|
if (isWithin(scratch, resolved)) return { ok: true };
|
|
45093
|
-
const suggestion =
|
|
44980
|
+
const suggestion = path32.posix.join(SCRATCH_DIR, "teardowns", path32.basename(resolved) || "capture");
|
|
45094
44981
|
return {
|
|
45095
44982
|
ok: false,
|
|
45096
44983
|
error: {
|
|
@@ -45113,29 +45000,8 @@ var RETRYABLE_FAILURES = /* @__PURE__ */ new Set([
|
|
|
45113
45000
|
// would blacklist a page that was never actually judged.
|
|
45114
45001
|
"PROXY_UNAVAILABLE"
|
|
45115
45002
|
]);
|
|
45116
|
-
async function recordCapture(manifest, outDir) {
|
|
45117
|
-
const consultedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
45118
|
-
const references = [];
|
|
45119
|
-
for (const section of manifest.sections) {
|
|
45120
|
-
if (!section.bundle) continue;
|
|
45121
|
-
try {
|
|
45122
|
-
const markup = await readFile23(path34.join(outDir, section.bundle), "utf8");
|
|
45123
|
-
const copyStrings = capturedCopyStrings(markup);
|
|
45124
|
-
if (copyStrings.length === 0) continue;
|
|
45125
|
-
references.push({
|
|
45126
|
-
sectionId: `local:${manifest.finalUrl}#${section.index}`,
|
|
45127
|
-
sourceUrl: manifest.finalUrl,
|
|
45128
|
-
copyStrings,
|
|
45129
|
-
consultedAt
|
|
45130
|
-
});
|
|
45131
|
-
} catch {
|
|
45132
|
-
}
|
|
45133
|
-
}
|
|
45134
|
-
const written = await recordReferences(process.cwd(), references);
|
|
45135
|
-
return written ? references.length : 0;
|
|
45136
|
-
}
|
|
45137
45003
|
function captureHints(args) {
|
|
45138
|
-
const { manifest, outDir, report
|
|
45004
|
+
const { manifest, outDir, report } = args;
|
|
45139
45005
|
const shots = manifest.sections.filter((section) => section.desktopShot !== null).length;
|
|
45140
45006
|
const anyScored = manifest.sections.some((section) => section.fidelity !== null);
|
|
45141
45007
|
const hints = [];
|
|
@@ -45155,14 +45021,11 @@ function captureHints(args) {
|
|
|
45155
45021
|
);
|
|
45156
45022
|
}
|
|
45157
45023
|
hints.push(INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt);
|
|
45158
|
-
hints.push(
|
|
45159
|
-
recorded > 0 ? `${recorded} sections are recorded for the originality check \u2014 \`baker landing critique\` will block a publish that ships their copy.` : "Nothing from this capture is recorded for the originality check, so it cannot see this page. Be especially careful not to reuse its copy."
|
|
45160
|
-
);
|
|
45161
45024
|
return hints;
|
|
45162
45025
|
}
|
|
45163
45026
|
registerSchema({
|
|
45164
45027
|
command: "landing.inspiration.scrape",
|
|
45165
|
-
description: "Start here when the user points at a specific page and wants it now: capture one landing page into a directory of section screenshots, standalone HTML bundles, a whole-page reproduction and motion filmstrips. Returns when the capture is done, unlike `add`. Read the screenshots.
|
|
45028
|
+
description: "Start here when the user points at a specific page and wants it now: capture one landing page into a directory of section screenshots, standalone HTML bundles, a whole-page reproduction and motion filmstrips. Returns when the capture is done, unlike `add`. Read the screenshots.",
|
|
45166
45029
|
args: {
|
|
45167
45030
|
url: { type: "string", description: "Page to capture", required: true },
|
|
45168
45031
|
out: { type: "string", description: "Output directory under .baker/", required: true },
|
|
@@ -45230,7 +45093,6 @@ var scrapeCommand = defineCommand161({
|
|
|
45230
45093
|
`)
|
|
45231
45094
|
});
|
|
45232
45095
|
const scored = manifest.sections.map((section) => section.fidelity).filter((value) => value !== null).sort((a, b) => a - b);
|
|
45233
|
-
const recorded = await recordCapture(manifest, args.out);
|
|
45234
45096
|
writeJson({
|
|
45235
45097
|
ok: true,
|
|
45236
45098
|
data: {
|
|
@@ -45251,7 +45113,7 @@ var scrapeCommand = defineCommand161({
|
|
|
45251
45113
|
certificate_verified: false,
|
|
45252
45114
|
...manifest.security.certificateNotes.length > 0 ? { certificate_notes: manifest.security.certificateNotes } : {}
|
|
45253
45115
|
},
|
|
45254
|
-
hints: captureHints({ manifest, outDir: args.out, report: args.report
|
|
45116
|
+
hints: captureHints({ manifest, outDir: args.out, report: args.report })
|
|
45255
45117
|
});
|
|
45256
45118
|
} catch (error) {
|
|
45257
45119
|
const failure = classifyCaptureFailure(error);
|
|
@@ -45289,12 +45151,12 @@ var scrapeCommand = defineCommand161({
|
|
|
45289
45151
|
});
|
|
45290
45152
|
|
|
45291
45153
|
// src/commands/landing/inspiration/search.ts
|
|
45292
|
-
import
|
|
45154
|
+
import path34 from "path";
|
|
45293
45155
|
import { defineCommand as defineCommand162 } from "citty";
|
|
45294
45156
|
|
|
45295
45157
|
// src/commands/landing/inspiration/shot.ts
|
|
45296
|
-
import { mkdir as
|
|
45297
|
-
import
|
|
45158
|
+
import { mkdir as mkdir11, writeFile as writeFile16 } from "fs/promises";
|
|
45159
|
+
import path33 from "path";
|
|
45298
45160
|
import sharp6 from "sharp";
|
|
45299
45161
|
var READABLE_SHOT = {
|
|
45300
45162
|
maxWidth: 1440,
|
|
@@ -45320,9 +45182,9 @@ async function downloadReadableShot(url, file) {
|
|
|
45320
45182
|
const response = await fetch(url);
|
|
45321
45183
|
if (!response.ok) return null;
|
|
45322
45184
|
const shot = await toReadableShot(Buffer.from(await response.arrayBuffer()));
|
|
45323
|
-
await
|
|
45324
|
-
await
|
|
45325
|
-
return
|
|
45185
|
+
await mkdir11(path33.dirname(file), { recursive: true });
|
|
45186
|
+
await writeFile16(file, shot);
|
|
45187
|
+
return path33.relative(process.cwd(), file);
|
|
45326
45188
|
} catch {
|
|
45327
45189
|
return null;
|
|
45328
45190
|
}
|
|
@@ -45414,13 +45276,13 @@ function buildSearchBody(args) {
|
|
|
45414
45276
|
return body;
|
|
45415
45277
|
}
|
|
45416
45278
|
async function downloadShots(results) {
|
|
45417
|
-
const dir =
|
|
45279
|
+
const dir = path34.join(process.cwd(), ".baker", "inspiration");
|
|
45418
45280
|
const saved = /* @__PURE__ */ new Map();
|
|
45419
45281
|
await Promise.all(
|
|
45420
45282
|
results.map(async (result) => {
|
|
45421
45283
|
const file = await downloadReadableShot(
|
|
45422
45284
|
result.desktopShotUrl,
|
|
45423
|
-
|
|
45285
|
+
path34.join(dir, `${result.id}.${READABLE_SHOT.extension}`)
|
|
45424
45286
|
);
|
|
45425
45287
|
if (file) saved.set(result.id, file);
|
|
45426
45288
|
})
|
|
@@ -45648,7 +45510,7 @@ var sequencesCommand = defineCommand163({
|
|
|
45648
45510
|
});
|
|
45649
45511
|
|
|
45650
45512
|
// src/commands/landing/inspiration/view.ts
|
|
45651
|
-
import
|
|
45513
|
+
import path35 from "path";
|
|
45652
45514
|
import { defineCommand as defineCommand164 } from "citty";
|
|
45653
45515
|
registerSchema({
|
|
45654
45516
|
command: "landing.inspiration.view",
|
|
@@ -45681,12 +45543,12 @@ var viewCommand2 = defineCommand164({
|
|
|
45681
45543
|
const id = args.id;
|
|
45682
45544
|
const data = await apiGet("/api/landing-inspiration/section", { id });
|
|
45683
45545
|
const section = data.section;
|
|
45684
|
-
const dir =
|
|
45546
|
+
const dir = path35.join(process.cwd(), ".baker", "inspiration", id);
|
|
45685
45547
|
const ext = READABLE_SHOT.extension;
|
|
45686
45548
|
const [desktop, mobile, filmstrip] = await Promise.all([
|
|
45687
|
-
downloadReadableShot(section.desktopShotUrl,
|
|
45688
|
-
downloadReadableShot(section.mobileShotUrl,
|
|
45689
|
-
downloadReadableShot(section.motionFilmstripUrl,
|
|
45549
|
+
downloadReadableShot(section.desktopShotUrl, path35.join(dir, `desktop.${ext}`)),
|
|
45550
|
+
downloadReadableShot(section.mobileShotUrl, path35.join(dir, `mobile.${ext}`)),
|
|
45551
|
+
downloadReadableShot(section.motionFilmstripUrl, path35.join(dir, `motion-filmstrip.${ext}`))
|
|
45690
45552
|
]);
|
|
45691
45553
|
const full = args.full;
|
|
45692
45554
|
const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
|
|
@@ -45753,7 +45615,7 @@ var inspirationCommand = defineCommand165({
|
|
|
45753
45615
|
|
|
45754
45616
|
Start here: \`baker landing inspiration search "<what you want to see>"\` during research, BEFORE you write the Direction Contract.
|
|
45755
45617
|
|
|
45756
|
-
This is inspiration, never a clipboard. Take the mechanism \u2014 what the eye hits first, what proof arrives before the ask, how the grid is split. The words are never yours to reuse: shipping a reference's headline is a Tier 0 message-match failure
|
|
45618
|
+
This is inspiration, never a clipboard. Take the mechanism \u2014 what the eye hits first, what proof arrives before the ask, how the grid is split. The words are never yours to reuse: shipping a reference's headline is a Tier 0 message-match failure.
|
|
45757
45619
|
|
|
45758
45620
|
Subcommands:
|
|
45759
45621
|
baker landing inspiration search "<query>" \u2014 search by look, section type, composition, register or motion; saves screenshots you can Read
|
|
@@ -47535,8 +47397,8 @@ var listCommand15 = defineCommand183({
|
|
|
47535
47397
|
});
|
|
47536
47398
|
|
|
47537
47399
|
// src/commands/scheduled-actions/templates.ts
|
|
47538
|
-
import { readFile as
|
|
47539
|
-
import
|
|
47400
|
+
import { readFile as readFile22 } from "fs/promises";
|
|
47401
|
+
import path36 from "path";
|
|
47540
47402
|
import { defineCommand as defineCommand184 } from "citty";
|
|
47541
47403
|
registerSchema({
|
|
47542
47404
|
command: "scheduled-actions.templates",
|
|
@@ -47639,7 +47501,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
|
|
|
47639
47501
|
}
|
|
47640
47502
|
if (save.length > 0) {
|
|
47641
47503
|
const briefFile = flag("brief-file");
|
|
47642
|
-
const brief = briefFile.length > 0 ? await
|
|
47504
|
+
const brief = briefFile.length > 0 ? await readFile22(path36.resolve(briefFile), "utf8") : flag("brief");
|
|
47643
47505
|
if (brief.trim().length === 0) {
|
|
47644
47506
|
failValidation4("--brief-file (preferred) or --brief is required: the brief is the recipe.");
|
|
47645
47507
|
}
|
|
@@ -48110,7 +47972,7 @@ function parseImageRefs(spec) {
|
|
|
48110
47972
|
}
|
|
48111
47973
|
var defaultDeps = {
|
|
48112
47974
|
ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
|
|
48113
|
-
upload: (
|
|
47975
|
+
upload: (path38) => uploadLocalImage({ file: path38, contentType: detectImageContentType(path38), source: "uploaded" })
|
|
48114
47976
|
};
|
|
48115
47977
|
async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
48116
47978
|
const refs = parseImageRefs(spec);
|
|
@@ -48130,10 +47992,10 @@ async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
|
48130
47992
|
}
|
|
48131
47993
|
return { imageIds, added };
|
|
48132
47994
|
}
|
|
48133
|
-
function uploadFailure(
|
|
47995
|
+
function uploadFailure(path38) {
|
|
48134
47996
|
return (error) => {
|
|
48135
47997
|
if (error instanceof ApiError) throw error;
|
|
48136
|
-
throw new ApiError("VALIDATION_ERROR", `Could not read "${
|
|
47998
|
+
throw new ApiError("VALIDATION_ERROR", `Could not read "${path38}" as an image.`);
|
|
48137
47999
|
};
|
|
48138
48000
|
}
|
|
48139
48001
|
|
|
@@ -49195,10 +49057,10 @@ async function stageOp4(op) {
|
|
|
49195
49057
|
handleError5(err);
|
|
49196
49058
|
}
|
|
49197
49059
|
}
|
|
49198
|
-
async function draftAction3(
|
|
49060
|
+
async function draftAction3(path38, body, chat) {
|
|
49199
49061
|
const chatId = resolveChatId(chat);
|
|
49200
49062
|
try {
|
|
49201
|
-
const data = await apiPost(
|
|
49063
|
+
const data = await apiPost(path38, { chatId, ...body });
|
|
49202
49064
|
writeJsonEnvelope({ ok: true, data });
|
|
49203
49065
|
return data;
|
|
49204
49066
|
} catch (err) {
|
|
@@ -50305,7 +50167,7 @@ var groupCommand2 = defineCommand209({
|
|
|
50305
50167
|
// src/commands/videos/ingest.ts
|
|
50306
50168
|
import { mkdtemp as mkdtemp2, rm as rm7, stat as stat7 } from "fs/promises";
|
|
50307
50169
|
import { tmpdir as tmpdir3 } from "os";
|
|
50308
|
-
import
|
|
50170
|
+
import path37 from "path";
|
|
50309
50171
|
import { defineCommand as defineCommand210 } from "citty";
|
|
50310
50172
|
|
|
50311
50173
|
// src/lib/streamUpload.ts
|
|
@@ -50656,7 +50518,7 @@ function ingestUrl(args) {
|
|
|
50656
50518
|
}
|
|
50657
50519
|
async function downloadThenIngest(args, country) {
|
|
50658
50520
|
const vimeoCookie = captureVimeoCookie();
|
|
50659
|
-
const workDir = await mkdtemp2(
|
|
50521
|
+
const workDir = await mkdtemp2(path37.join(tmpdir3(), "videos-ingest-"));
|
|
50660
50522
|
try {
|
|
50661
50523
|
const probe = await probeYtDlp({ url: args.url, country, vimeoCookie, cookieDir: workDir });
|
|
50662
50524
|
if (isAudioOnly(probe.info)) {
|
|
@@ -50792,7 +50654,7 @@ var searchCommand4 = defineCommand211({
|
|
|
50792
50654
|
var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
50793
50655
|
|
|
50794
50656
|
// src/commands/videos/upload.ts
|
|
50795
|
-
import { readFile as
|
|
50657
|
+
import { readFile as readFile23, stat as stat8 } from "fs/promises";
|
|
50796
50658
|
import { basename as basename3, extname as extname4 } from "path";
|
|
50797
50659
|
import { defineCommand as defineCommand212 } from "citty";
|
|
50798
50660
|
var MIME_MAP = {
|
|
@@ -50889,7 +50751,7 @@ var uploadCommand2 = defineCommand212({
|
|
|
50889
50751
|
originalFilename,
|
|
50890
50752
|
descriptionContext
|
|
50891
50753
|
});
|
|
50892
|
-
const fileBuffer = await
|
|
50754
|
+
const fileBuffer = await readFile23(filePath);
|
|
50893
50755
|
const uploadResponse = await fetch(uploadUrl, {
|
|
50894
50756
|
method: "PUT",
|
|
50895
50757
|
headers: { "Content-Type": contentType },
|
|
@@ -52276,7 +52138,7 @@ function unknownFlagEnvelope(unknown, commandPath, suggestion) {
|
|
|
52276
52138
|
};
|
|
52277
52139
|
}
|
|
52278
52140
|
function commandPathOf(root, argv) {
|
|
52279
|
-
const
|
|
52141
|
+
const path38 = [];
|
|
52280
52142
|
let command = root;
|
|
52281
52143
|
for (const token of argv) {
|
|
52282
52144
|
if (token === "--" || token.startsWith("-")) {
|
|
@@ -52287,10 +52149,10 @@ function commandPathOf(root, argv) {
|
|
|
52287
52149
|
if (next === void 0 || typeof next !== "object") {
|
|
52288
52150
|
break;
|
|
52289
52151
|
}
|
|
52290
|
-
|
|
52152
|
+
path38.push(token);
|
|
52291
52153
|
command = next;
|
|
52292
52154
|
}
|
|
52293
|
-
return
|
|
52155
|
+
return path38.join(" ");
|
|
52294
52156
|
}
|
|
52295
52157
|
function refuseUnknownFlags(root, argv) {
|
|
52296
52158
|
const unknown = findUnknownFlags(root, argv);
|