@koda-sl/baker-cli 0.253.0 → 0.259.0-dev.dcbb0c10b
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 +9 -1
- package/dist/{chunk-P6ZNIFAQ.js → chunk-2VM2J6MB.js} +4 -4
- package/dist/{chunk-3FBQKD7O.js → chunk-ECPNYXOA.js} +3 -3
- package/dist/{chunk-2IB3IL4K.js → chunk-GXRUZ4LP.js} +2 -2
- package/dist/{chunk-DZUVUGEP.js → chunk-POYXIDOD.js} +5 -1
- package/dist/{chunk-DZUVUGEP.js.map → chunk-POYXIDOD.js.map} +1 -1
- package/dist/{chunk-SJPRTSGY.js → chunk-R4MBS2OI.js} +149 -36
- package/dist/chunk-R4MBS2OI.js.map +1 -0
- package/dist/{chunk-5I66YT7A.js → chunk-TBEVU7XF.js} +3 -3
- package/dist/cli.js +858 -678
- package/dist/cli.js.map +1 -1
- package/dist/client-7QIDRQXG.js +15 -0
- package/dist/engine/index.js +3 -3
- package/dist/{env-FWMZXMQK.js → env-HZNFGXAR.js} +4 -2
- package/dist/{output-WRHUJR74.js → output-MWMAXN4M.js} +5 -5
- package/dist/{shared-T66YQ6MB.js → shared-NFLXWGHK.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-SJPRTSGY.js.map +0 -1
- package/dist/client-32DO7WEZ.js +0 -15
- /package/dist/{chunk-P6ZNIFAQ.js.map → chunk-2VM2J6MB.js.map} +0 -0
- /package/dist/{chunk-3FBQKD7O.js.map → chunk-ECPNYXOA.js.map} +0 -0
- /package/dist/{chunk-2IB3IL4K.js.map → chunk-GXRUZ4LP.js.map} +0 -0
- /package/dist/{chunk-5I66YT7A.js.map → chunk-TBEVU7XF.js.map} +0 -0
- /package/dist/{client-32DO7WEZ.js.map → client-7QIDRQXG.js.map} +0 -0
- /package/dist/{env-FWMZXMQK.js.map → env-HZNFGXAR.js.map} +0 -0
- /package/dist/{output-WRHUJR74.js.map → output-MWMAXN4M.js.map} +0 -0
- /package/dist/{shared-T66YQ6MB.js.map → shared-NFLXWGHK.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
ulid,
|
|
59
59
|
validateCanvasDeep,
|
|
60
60
|
ytDlpBlockSignal
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-R4MBS2OI.js";
|
|
62
62
|
import {
|
|
63
63
|
csvOrJson,
|
|
64
64
|
daysAgoIso,
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
resolveAccountIdArg,
|
|
68
68
|
resolveEffectiveStatus,
|
|
69
69
|
todayIso
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-2VM2J6MB.js";
|
|
71
71
|
import {
|
|
72
72
|
buildQueryCacheKey,
|
|
73
73
|
cacheGet,
|
|
@@ -83,17 +83,17 @@ import {
|
|
|
83
83
|
writeAdsJson,
|
|
84
84
|
writeAdsOutput,
|
|
85
85
|
writeJsonEnvelope
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-TBEVU7XF.js";
|
|
87
87
|
import {
|
|
88
88
|
ApiError,
|
|
89
89
|
apiGet,
|
|
90
90
|
apiPost,
|
|
91
91
|
validateConvexId
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-ECPNYXOA.js";
|
|
93
93
|
import {
|
|
94
94
|
installStreamTaps,
|
|
95
95
|
logInvocation
|
|
96
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-GXRUZ4LP.js";
|
|
97
97
|
import {
|
|
98
98
|
captureBudgetMs,
|
|
99
99
|
captureProxyCredentials,
|
|
@@ -105,10 +105,10 @@ import {
|
|
|
105
105
|
requireChatId,
|
|
106
106
|
resolveChatId,
|
|
107
107
|
shouldEscalate
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-POYXIDOD.js";
|
|
109
109
|
|
|
110
110
|
// src/cli.ts
|
|
111
|
-
import { defineCommand as
|
|
111
|
+
import { defineCommand as defineCommand228, runMain } from "citty";
|
|
112
112
|
|
|
113
113
|
// src/cache-flag.ts
|
|
114
114
|
var NO_CACHE_ARG = {
|
|
@@ -3682,6 +3682,7 @@ var avatarProfileSchema = z7.object({
|
|
|
3682
3682
|
subjectDescription: z7.string().trim().min(1).max(2e3),
|
|
3683
3683
|
persona: z7.string().trim().max(2e3).optional(),
|
|
3684
3684
|
speech: z7.string().trim().max(2e3).optional(),
|
|
3685
|
+
accent: z7.string().trim().max(2e3).optional(),
|
|
3685
3686
|
motion: z7.string().trim().max(2e3).optional(),
|
|
3686
3687
|
wardrobe: z7.string().trim().max(2e3).optional(),
|
|
3687
3688
|
setting: z7.string().trim().max(2e3).optional(),
|
|
@@ -3697,7 +3698,6 @@ var avatarSummarySchema = z7.object({
|
|
|
3697
3698
|
/** The identity sheet to wire into `--reference`. Absent until the build settles. */
|
|
3698
3699
|
sheetUrl: z7.string().optional(),
|
|
3699
3700
|
coverUrl: z7.string().optional(),
|
|
3700
|
-
hasVoice: z7.boolean(),
|
|
3701
3701
|
errorMessage: z7.string().optional()
|
|
3702
3702
|
});
|
|
3703
3703
|
var avatarDetailSchema = avatarSummarySchema.extend({
|
|
@@ -4292,7 +4292,7 @@ var FLOW_NODE_CATALOG = [
|
|
|
4292
4292
|
}
|
|
4293
4293
|
}
|
|
4294
4294
|
},
|
|
4295
|
-
gotcha: "`fieldtype` is one of: checkbox, date_picker, date_time_range, email, hidden, input, multi_select, number, phone, select, textarea. `select`/`multi_select` need non-empty `options`; `phone` needs `defaultCountry`; a field rendered by your own code is declared `hidden`. A field your page validates itself (postal code against a service area, VAT number, order reference) also needs `testValue` \u2014 the Form's own checks invent `TestValue` otherwise and never get past that step.
|
|
4295
|
+
gotcha: "`fieldtype` is one of: checkbox, date_picker, date_time_range, email, hidden, input, multi_select, number, phone, select, textarea. `select`/`multi_select` need non-empty `options`; `phone` needs `defaultCountry`; a field rendered by your own code is declared `hidden`. A field your page validates itself (postal code against a service area, VAT number, order reference) also needs `testValue` \u2014 the Form's own checks invent `TestValue` otherwise and never get past that step.",
|
|
4296
4296
|
reference: NODE_REF("customForm")
|
|
4297
4297
|
},
|
|
4298
4298
|
{
|
|
@@ -7411,7 +7411,11 @@ registerSchema({
|
|
|
7411
7411
|
command: "actions.status",
|
|
7412
7412
|
description: "Resolve one or more Work Action refs by real action ID or temp_* ref in a single batch call. When BAKER_CHAT_ID is set, a temp_* ref still staged in THIS chat resolves to status 'draft' (not 'not_found') \u2014 staged ops only become published actions on chat publish.",
|
|
7413
7413
|
args: {
|
|
7414
|
-
|
|
7414
|
+
ref: {
|
|
7415
|
+
type: "positional",
|
|
7416
|
+
description: "One or more action refs: real action IDs or temp_* refs (space-separated)",
|
|
7417
|
+
required: true
|
|
7418
|
+
}
|
|
7415
7419
|
}
|
|
7416
7420
|
});
|
|
7417
7421
|
var statusCommand = defineCommand11({
|
|
@@ -9780,11 +9784,11 @@ function rawTextEntries(value) {
|
|
|
9780
9784
|
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
9781
9785
|
return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
9782
9786
|
}
|
|
9783
|
-
function rawFileEntries(
|
|
9784
|
-
if (typeof
|
|
9787
|
+
function rawFileEntries(path39) {
|
|
9788
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
9785
9789
|
return [];
|
|
9786
9790
|
}
|
|
9787
|
-
return readFileSync2(
|
|
9791
|
+
return readFileSync2(path39, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
9788
9792
|
}
|
|
9789
9793
|
function keywordEntries(args) {
|
|
9790
9794
|
const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
|
|
@@ -9807,19 +9811,19 @@ function keywordEntries(args) {
|
|
|
9807
9811
|
}
|
|
9808
9812
|
return entries;
|
|
9809
9813
|
}
|
|
9810
|
-
function loadJsonFileArg(
|
|
9811
|
-
if (typeof
|
|
9814
|
+
function loadJsonFileArg(path39) {
|
|
9815
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
9812
9816
|
return {};
|
|
9813
9817
|
}
|
|
9814
9818
|
try {
|
|
9815
|
-
const parsed = JSON.parse(readFileSync2(
|
|
9819
|
+
const parsed = JSON.parse(readFileSync2(path39, "utf8"));
|
|
9816
9820
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
9817
|
-
failWriteValidation(`${
|
|
9821
|
+
failWriteValidation(`${path39} must contain a JSON object`);
|
|
9818
9822
|
}
|
|
9819
9823
|
return parsed;
|
|
9820
9824
|
} catch (err) {
|
|
9821
9825
|
if (err instanceof SyntaxError) {
|
|
9822
|
-
failWriteValidation(`${
|
|
9826
|
+
failWriteValidation(`${path39} is not valid JSON: ${err.message}`);
|
|
9823
9827
|
}
|
|
9824
9828
|
throw err;
|
|
9825
9829
|
}
|
|
@@ -9949,10 +9953,10 @@ async function stageUpdate(kind, customerId, target, payload, hints) {
|
|
|
9949
9953
|
async function stageTarget(kind, customerId, target, hints) {
|
|
9950
9954
|
await stageGoogleOp({ kind, customerId, target }, hints);
|
|
9951
9955
|
}
|
|
9952
|
-
async function draftAction(
|
|
9956
|
+
async function draftAction(path39, body, chat) {
|
|
9953
9957
|
try {
|
|
9954
9958
|
const chatId = resolveChatId(chat);
|
|
9955
|
-
const response = await apiPost(
|
|
9959
|
+
const response = await apiPost(path39, { chatId, ...body });
|
|
9956
9960
|
writeJsonEnvelope(response);
|
|
9957
9961
|
} catch (err) {
|
|
9958
9962
|
handleGoogleError(err);
|
|
@@ -12316,10 +12320,10 @@ var analyticsPresetSchema = z24.enum([
|
|
|
12316
12320
|
*/
|
|
12317
12321
|
"geo",
|
|
12318
12322
|
/**
|
|
12319
|
-
* Which machines are fetching this site.
|
|
12323
|
+
* Which machines are fetching this site, and whether they are genuine.
|
|
12320
12324
|
*
|
|
12321
|
-
* Every other preset here
|
|
12322
|
-
*
|
|
12325
|
+
* Every other preset here ends "and exclude the bots", which is correct — a
|
|
12326
|
+
* crawler is not an audience. The rows are kept, though, and this is what
|
|
12323
12327
|
* they are kept for: whether Google is still crawling a page that was
|
|
12324
12328
|
* republished, whether Meta fetched the link preview before spend went
|
|
12325
12329
|
* behind the URL, and how much of the traffic is now AI answer engines.
|
|
@@ -12989,6 +12993,12 @@ var analyticsBotRowSchema = z24.object({
|
|
|
12989
12993
|
bot: z24.string(),
|
|
12990
12994
|
/** `search` | `ai` | `social` | `seo` | `monitoring` | `tool` | `automation`. */
|
|
12991
12995
|
category: z24.string(),
|
|
12996
|
+
/**
|
|
12997
|
+
* Cloudflare confirmed it by the network it came from, rather than believing
|
|
12998
|
+
* its user agent. A page fetched only by unverified self-declared Googlebots
|
|
12999
|
+
* was not crawled by Google.
|
|
13000
|
+
*/
|
|
13001
|
+
verified: z24.boolean(),
|
|
12992
13002
|
hits: z24.number().int().nonnegative(),
|
|
12993
13003
|
pages: z24.number().int().nonnegative(),
|
|
12994
13004
|
lastSeen: z24.string(),
|
|
@@ -15160,19 +15170,19 @@ function failWriteValidation2(message) {
|
|
|
15160
15170
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
15161
15171
|
process.exit(1);
|
|
15162
15172
|
}
|
|
15163
|
-
function loadJsonFileArg2(
|
|
15164
|
-
if (typeof
|
|
15173
|
+
function loadJsonFileArg2(path39) {
|
|
15174
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
15165
15175
|
return {};
|
|
15166
15176
|
}
|
|
15167
15177
|
try {
|
|
15168
|
-
const parsed = JSON.parse(readFileSync4(
|
|
15178
|
+
const parsed = JSON.parse(readFileSync4(path39, "utf8"));
|
|
15169
15179
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
15170
|
-
failWriteValidation2(`${
|
|
15180
|
+
failWriteValidation2(`${path39} must contain a JSON object`);
|
|
15171
15181
|
}
|
|
15172
15182
|
return parsed;
|
|
15173
15183
|
} catch (err) {
|
|
15174
15184
|
if (err instanceof SyntaxError) {
|
|
15175
|
-
failWriteValidation2(`${
|
|
15185
|
+
failWriteValidation2(`${path39} is not valid JSON: ${err.message}`);
|
|
15176
15186
|
}
|
|
15177
15187
|
throw err;
|
|
15178
15188
|
}
|
|
@@ -15257,15 +15267,15 @@ function parseLocaleFlag(value) {
|
|
|
15257
15267
|
}
|
|
15258
15268
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
15259
15269
|
}
|
|
15260
|
-
function loadTargetingFileArg(
|
|
15261
|
-
if (typeof
|
|
15270
|
+
function loadTargetingFileArg(path39) {
|
|
15271
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
15262
15272
|
return void 0;
|
|
15263
15273
|
}
|
|
15264
|
-
const parsed = loadJsonFileArg2(
|
|
15274
|
+
const parsed = loadJsonFileArg2(path39);
|
|
15265
15275
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
15266
15276
|
if (!criteria.include) {
|
|
15267
15277
|
failWriteValidation2(
|
|
15268
|
-
`${
|
|
15278
|
+
`${path39} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
15269
15279
|
);
|
|
15270
15280
|
}
|
|
15271
15281
|
return criteria;
|
|
@@ -15300,14 +15310,14 @@ function parseCsvLine(line) {
|
|
|
15300
15310
|
cells.push(current);
|
|
15301
15311
|
return cells.map((cell2) => cell2.trim());
|
|
15302
15312
|
}
|
|
15303
|
-
function parseListFileArg(
|
|
15304
|
-
if (typeof
|
|
15313
|
+
function parseListFileArg(path39, maxRows) {
|
|
15314
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
15305
15315
|
return void 0;
|
|
15306
15316
|
}
|
|
15307
|
-
const raw = readFileSync4(
|
|
15317
|
+
const raw = readFileSync4(path39, "utf8");
|
|
15308
15318
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
15309
15319
|
if (lines.length < 2) {
|
|
15310
|
-
failWriteValidation2(`${
|
|
15320
|
+
failWriteValidation2(`${path39} needs a header row and at least one data row`);
|
|
15311
15321
|
}
|
|
15312
15322
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
15313
15323
|
const rows = [];
|
|
@@ -15326,7 +15336,7 @@ function parseListFileArg(path38, maxRows) {
|
|
|
15326
15336
|
}
|
|
15327
15337
|
}
|
|
15328
15338
|
if (rows.length > maxRows) {
|
|
15329
|
-
failWriteValidation2(`${
|
|
15339
|
+
failWriteValidation2(`${path39} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
15330
15340
|
}
|
|
15331
15341
|
return { columns, rows };
|
|
15332
15342
|
}
|
|
@@ -15422,11 +15432,11 @@ function readPositionals(args) {
|
|
|
15422
15432
|
function splitIdList(raw) {
|
|
15423
15433
|
return raw.split(",").map((id) => id.trim()).filter(Boolean);
|
|
15424
15434
|
}
|
|
15425
|
-
function idsFileEntries(
|
|
15426
|
-
if (typeof
|
|
15435
|
+
function idsFileEntries(path39) {
|
|
15436
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
15427
15437
|
return [];
|
|
15428
15438
|
}
|
|
15429
|
-
return readFileSync4(
|
|
15439
|
+
return readFileSync4(path39, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
|
|
15430
15440
|
}
|
|
15431
15441
|
function requireTargets(args, entity) {
|
|
15432
15442
|
const positionals = readPositionals(args);
|
|
@@ -18047,9 +18057,9 @@ function compactRow(row) {
|
|
|
18047
18057
|
...destination.postUrn ? { postUrn: destination.postUrn } : {}
|
|
18048
18058
|
};
|
|
18049
18059
|
}
|
|
18050
|
-
function readPath(row,
|
|
18060
|
+
function readPath(row, path39) {
|
|
18051
18061
|
let current = row;
|
|
18052
|
-
for (const segment of
|
|
18062
|
+
for (const segment of path39.split(".")) {
|
|
18053
18063
|
const record = asRecord2(current);
|
|
18054
18064
|
if (!record) return void 0;
|
|
18055
18065
|
current = record[segment];
|
|
@@ -18059,10 +18069,10 @@ function readPath(row, path38) {
|
|
|
18059
18069
|
function projectFields(rows, paths) {
|
|
18060
18070
|
return rows.map((row) => {
|
|
18061
18071
|
const projected = {};
|
|
18062
|
-
for (const
|
|
18063
|
-
const value = readPath(row,
|
|
18072
|
+
for (const path39 of paths) {
|
|
18073
|
+
const value = readPath(row, path39);
|
|
18064
18074
|
if (value !== void 0) {
|
|
18065
|
-
projected[
|
|
18075
|
+
projected[path39] = value;
|
|
18066
18076
|
}
|
|
18067
18077
|
}
|
|
18068
18078
|
return projected;
|
|
@@ -19260,14 +19270,6 @@ var CTA_TYPES2 = [
|
|
|
19260
19270
|
"BUY_TICKETS",
|
|
19261
19271
|
"NO_BUTTON"
|
|
19262
19272
|
];
|
|
19263
|
-
var LEAD_FORM_CTA_TYPES = [
|
|
19264
|
-
"APPLY_NOW",
|
|
19265
|
-
"DOWNLOAD",
|
|
19266
|
-
"GET_QUOTE",
|
|
19267
|
-
"LEARN_MORE",
|
|
19268
|
-
"SIGN_UP",
|
|
19269
|
-
"SUBSCRIBE"
|
|
19270
|
-
];
|
|
19271
19273
|
var AD_FORMATS2 = ["SINGLE_IMAGE", "CAROUSEL", "SINGLE_VIDEO"];
|
|
19272
19274
|
var ENROLL_STATUSES = ["OPT_IN", "OPT_OUT"];
|
|
19273
19275
|
var STAGEABLE_CREATE_STATUSES3 = ["ACTIVE", "PAUSED"];
|
|
@@ -19370,11 +19372,11 @@ var updateStatusSchema = z25.enum(UPDATE_STATUSES);
|
|
|
19370
19372
|
function currencyMinimums2(currencyCode) {
|
|
19371
19373
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
19372
19374
|
}
|
|
19373
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
19375
|
+
function validateDailyBudgetFloor(money, ctx, path39) {
|
|
19374
19376
|
if (money?.currencyCode) {
|
|
19375
19377
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
19376
19378
|
if (Number(money.amount) < min) {
|
|
19377
|
-
ctx.addIssue({ code: "custom", path:
|
|
19379
|
+
ctx.addIssue({ code: "custom", path: path39, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
19378
19380
|
}
|
|
19379
19381
|
}
|
|
19380
19382
|
}
|
|
@@ -19690,23 +19692,7 @@ var descriptionSchema = z25.string().min(1).max(META_LIMITS.creative.description
|
|
|
19690
19692
|
var callToActionSchema = z25.object({
|
|
19691
19693
|
type: z25.enum(CTA_TYPES2),
|
|
19692
19694
|
/** Overrides the base link for the CTA button; defaults to the ad's link. */
|
|
19693
|
-
link: httpsUrlSchema3.optional()
|
|
19694
|
-
/**
|
|
19695
|
-
* The instant form the button opens — Meta's `call_to_action.value.lead_gen_form_id`.
|
|
19696
|
-
* This is the ONLY place an instant form is named: the ad set says leads open
|
|
19697
|
-
* on the ad (`destination_type: ON_AD`), and the creative says which form.
|
|
19698
|
-
* Without it Meta refuses every ad in that ad set with subcode 3390001,
|
|
19699
|
-
* "Choose or create an instant form for your leads campaign".
|
|
19700
|
-
*/
|
|
19701
|
-
lead_gen_form_id: z25.string().regex(NUMERIC_ID_REGEX3).optional()
|
|
19702
|
-
}).superRefine((p, ctx) => {
|
|
19703
|
-
if (p.lead_gen_form_id && !LEAD_FORM_CTA_TYPES.some((allowed) => allowed === p.type)) {
|
|
19704
|
-
ctx.addIssue({
|
|
19705
|
-
code: "custom",
|
|
19706
|
-
path: ["type"],
|
|
19707
|
-
message: `${p.type} cannot open an instant form \u2014 Meta refuses it (subcode 1856030). Use one of ${LEAD_FORM_CTA_TYPES.join(", ")}, or drop lead_gen_form_id if this ad should go to the website.`
|
|
19708
|
-
});
|
|
19709
|
-
}
|
|
19695
|
+
link: httpsUrlSchema3.optional()
|
|
19710
19696
|
});
|
|
19711
19697
|
var creativeEnhancementsSchema = z25.object({
|
|
19712
19698
|
standardEnhancements: z25.enum(ENROLL_STATUSES).optional(),
|
|
@@ -19804,19 +19790,6 @@ var carouselCreativeSchema2 = z25.object({
|
|
|
19804
19790
|
link: httpsUrlSchema3.optional(),
|
|
19805
19791
|
call_to_action: callToActionSchema.optional(),
|
|
19806
19792
|
cards: z25.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
|
|
19807
|
-
}).superRefine((p, ctx) => {
|
|
19808
|
-
const forms = new Set(
|
|
19809
|
-
[p.call_to_action?.lead_gen_form_id, ...p.cards.map((card) => card.call_to_action?.lead_gen_form_id)].filter(
|
|
19810
|
-
Boolean
|
|
19811
|
-
)
|
|
19812
|
-
);
|
|
19813
|
-
if (forms.size > 1) {
|
|
19814
|
-
ctx.addIssue({
|
|
19815
|
-
code: "custom",
|
|
19816
|
-
path: ["cards"],
|
|
19817
|
-
message: `every card of a carousel must open the SAME instant form \u2014 this one names ${[...forms].join(" and ")}`
|
|
19818
|
-
});
|
|
19819
|
-
}
|
|
19820
19793
|
});
|
|
19821
19794
|
var dynamicImageSchema = z25.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
|
|
19822
19795
|
var dynamicVideoSchema = z25.object({
|
|
@@ -20072,19 +20045,19 @@ function failWriteValidation3(message) {
|
|
|
20072
20045
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
20073
20046
|
process.exit(1);
|
|
20074
20047
|
}
|
|
20075
|
-
function loadJsonFileArg3(
|
|
20076
|
-
if (typeof
|
|
20048
|
+
function loadJsonFileArg3(path39) {
|
|
20049
|
+
if (typeof path39 !== "string" || path39.length === 0) {
|
|
20077
20050
|
return {};
|
|
20078
20051
|
}
|
|
20079
20052
|
try {
|
|
20080
|
-
const parsed = JSON.parse(readFileSync8(
|
|
20053
|
+
const parsed = JSON.parse(readFileSync8(path39, "utf8"));
|
|
20081
20054
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20082
|
-
failWriteValidation3(`${
|
|
20055
|
+
failWriteValidation3(`${path39} must contain a JSON object`);
|
|
20083
20056
|
}
|
|
20084
20057
|
return parsed;
|
|
20085
20058
|
} catch (err) {
|
|
20086
20059
|
if (err instanceof SyntaxError) {
|
|
20087
|
-
failWriteValidation3(`${
|
|
20060
|
+
failWriteValidation3(`${path39} is not valid JSON: ${err.message}`);
|
|
20088
20061
|
}
|
|
20089
20062
|
throw err;
|
|
20090
20063
|
}
|
|
@@ -20323,10 +20296,7 @@ var adSetWriteArgs = {
|
|
|
20323
20296
|
"daily-budget": { type: "string", description: "Daily budget (ABO; omit if the campaign uses CBO)" },
|
|
20324
20297
|
"lifetime-budget": { type: "string", description: "Lifetime budget (needs --end)" },
|
|
20325
20298
|
"bid-amount": { type: "string", description: "Bid amount (required for COST_CAP / bid-cap strategies)" },
|
|
20326
|
-
"bid-strategy": {
|
|
20327
|
-
type: "string",
|
|
20328
|
-
description: "LOWEST_COST_WITHOUT_CAP (auto-bid) | LOWEST_COST_WITH_BID_CAP | COST_CAP \u2014 needs --bid-amount. Omit and Baker sets auto-bid; never leave it to Meta, whose default is a bid cap that then fails without an amount."
|
|
20329
|
-
},
|
|
20299
|
+
"bid-strategy": { type: "string", description: "Bid strategy override" },
|
|
20330
20300
|
currency: { type: "string", description: "3-letter currency (defaults to the account currency)" },
|
|
20331
20301
|
start: { type: "string", description: "Start time" },
|
|
20332
20302
|
end: { type: "string", description: "End time" },
|
|
@@ -20393,7 +20363,7 @@ function creativePayloadFromFlags(args) {
|
|
|
20393
20363
|
headline: args.headline,
|
|
20394
20364
|
description: args.description,
|
|
20395
20365
|
caption: args.caption,
|
|
20396
|
-
call_to_action:
|
|
20366
|
+
call_to_action: args.cta ? { type: upper(args.cta) } : void 0,
|
|
20397
20367
|
imageHash: args["image-hash"],
|
|
20398
20368
|
imageRef: args["image-ref"],
|
|
20399
20369
|
videoId: args["video-id"],
|
|
@@ -20403,26 +20373,6 @@ function creativePayloadFromFlags(args) {
|
|
|
20403
20373
|
enhancements
|
|
20404
20374
|
};
|
|
20405
20375
|
}
|
|
20406
|
-
function ctaPatchFromFlags(args) {
|
|
20407
|
-
const patch = {
|
|
20408
|
-
...args.cta ? { type: String(upper(args.cta)) } : {},
|
|
20409
|
-
...args["lead-form"] === void 0 ? {} : { lead_gen_form_id: String(args["lead-form"]) }
|
|
20410
|
-
};
|
|
20411
|
-
return Object.keys(patch).length > 0 ? patch : void 0;
|
|
20412
|
-
}
|
|
20413
|
-
function creativeCta(args) {
|
|
20414
|
-
const patch = ctaPatchFromFlags(args);
|
|
20415
|
-
return patch ? { type: "SIGN_UP", ...patch } : void 0;
|
|
20416
|
-
}
|
|
20417
|
-
function creativeContentPatch2(file, args) {
|
|
20418
|
-
const cta = ctaPatchFromFlags(args);
|
|
20419
|
-
if (!cta) {
|
|
20420
|
-
return void 0;
|
|
20421
|
-
}
|
|
20422
|
-
const fileContent = file.content ?? {};
|
|
20423
|
-
const fileCta = fileContent.call_to_action ?? {};
|
|
20424
|
-
return { ...fileContent, call_to_action: { ...fileCta, ...cta } };
|
|
20425
|
-
}
|
|
20426
20376
|
function parseEnroll(value) {
|
|
20427
20377
|
const raw = String(value).toLowerCase();
|
|
20428
20378
|
if (raw === "on" || raw === "true" || raw === "opt_in") return "OPT_IN";
|
|
@@ -20449,10 +20399,6 @@ Example: baker ads meta creatives create --page 555 --message "Save now" --link
|
|
|
20449
20399
|
description: { type: "string", description: "Description" },
|
|
20450
20400
|
caption: { type: "string", description: "Display URL / caption" },
|
|
20451
20401
|
cta: { type: "string", description: "Call-to-action type (SHOP_NOW|LEARN_MORE|SIGN_UP|\u2026)" },
|
|
20452
|
-
"lead-form": {
|
|
20453
|
-
type: "string",
|
|
20454
|
-
description: "Instant form id the button opens \u2014 REQUIRED for an ad set that collects leads on the ad. List them with `baker ads meta lead-forms`. With a form, --cta must be APPLY_NOW|DOWNLOAD|GET_QUOTE|LEARN_MORE|SIGN_UP|SUBSCRIBE"
|
|
20455
|
-
},
|
|
20456
20402
|
"image-hash": { type: "string", description: "Meta ad-image hash (already uploaded)" },
|
|
20457
20403
|
"image-ref": { type: "string", description: "meta_temp_* ref of a staged media upload" },
|
|
20458
20404
|
"video-id": { type: "string", description: "Meta video id (already uploaded)" },
|
|
@@ -20486,11 +20432,6 @@ Amending a staged (meta_temp_*) creative merges fields into the create. Example:
|
|
|
20486
20432
|
...accountArgs2,
|
|
20487
20433
|
name: { type: "string", description: "New name" },
|
|
20488
20434
|
status: { type: "string", description: "ACTIVE|PAUSED|ARCHIVED" },
|
|
20489
|
-
cta: { type: "string", description: "Call-to-action type (staged creatives only)" },
|
|
20490
|
-
"lead-form": {
|
|
20491
|
-
type: "string",
|
|
20492
|
-
description: "Instant form id the button opens (staged creatives only) \u2014 `baker ads meta lead-forms` lists them"
|
|
20493
|
-
},
|
|
20494
20435
|
file: {
|
|
20495
20436
|
type: "string",
|
|
20496
20437
|
description: "JSON file with fields to change (content only merges into a staged creative)"
|
|
@@ -20498,15 +20439,7 @@ Amending a staged (meta_temp_*) creative merges fields into the create. Example:
|
|
|
20498
20439
|
},
|
|
20499
20440
|
run: async ({ args }) => {
|
|
20500
20441
|
const accountId = bareAccountId2(args);
|
|
20501
|
-
const
|
|
20502
|
-
const payload = mergePayload3(file, {
|
|
20503
|
-
name: args.name,
|
|
20504
|
-
status: upper(args.status),
|
|
20505
|
-
// A creative's content is immutable on Meta, so this only ever lands on a
|
|
20506
|
-
// creative still staged in this chat — which is exactly the fix path when
|
|
20507
|
-
// staging an ad refuses it for naming no instant form.
|
|
20508
|
-
content: creativeContentPatch2(file, args)
|
|
20509
|
-
});
|
|
20442
|
+
const payload = mergePayload3(loadJsonFileArg3(args.file), { name: args.name, status: upper(args.status) });
|
|
20510
20443
|
await stageOp2({
|
|
20511
20444
|
kind: "adCreative.update",
|
|
20512
20445
|
accountId,
|
|
@@ -20677,10 +20610,10 @@ function duplicateCommand2(entity, label) {
|
|
|
20677
20610
|
replace: { type: "boolean", description: "Pause the original once the copy publishes" }
|
|
20678
20611
|
},
|
|
20679
20612
|
run: async ({ args }) => {
|
|
20680
|
-
const { apiPost: apiPost2 } = await import("./client-
|
|
20681
|
-
const { requireChatId: requireChatId2 } = await import("./env-
|
|
20682
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
20683
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
20613
|
+
const { apiPost: apiPost2 } = await import("./client-7QIDRQXG.js");
|
|
20614
|
+
const { requireChatId: requireChatId2 } = await import("./env-HZNFGXAR.js");
|
|
20615
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-MWMAXN4M.js");
|
|
20616
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-NFLXWGHK.js");
|
|
20684
20617
|
try {
|
|
20685
20618
|
const accountId = bareAccountId2(args);
|
|
20686
20619
|
const chatId = requireChatId2();
|
|
@@ -23696,7 +23629,7 @@ var ANALYTICS_PRESET_INFO = [
|
|
|
23696
23629
|
},
|
|
23697
23630
|
{
|
|
23698
23631
|
name: "flow",
|
|
23699
|
-
description: "One Form in depth: conversions counted at the node that produced them, step-to-step paths for a branching Form, the per-step table, every trigger raised, and each marked conversion by name. Read convertedSessions rather than submits \u2014 a Form whose scheduling widget sits mid-flow never emits a submit and reports zero on every other report. An empty `conversions` array means nobody has marked what this Form is for, so the numbers rest on a built-in guess; mark it in the Forms builder or with `conversions: [{ triggerId }]` on the node.
|
|
23632
|
+
description: "One Form in depth: conversions counted at the node that produced them, step-to-step paths for a branching Form, the per-step table, every trigger raised, and each marked conversion by name. Read convertedSessions rather than submits \u2014 a Form whose scheduling widget sits mid-flow never emits a submit and reports zero on every other report. An empty `conversions` array means nobody has marked what this Form is for, so the numbers rest on a built-in guess; mark it in the Forms builder or with `conversions: [{ triggerId }]` on the node.",
|
|
23700
23633
|
playbook: "flow-builder \u2014 fix the branch or the step that loses people"
|
|
23701
23634
|
},
|
|
23702
23635
|
{
|
|
@@ -23731,7 +23664,7 @@ var ANALYTICS_PRESET_INFO = [
|
|
|
23731
23664
|
},
|
|
23732
23665
|
{
|
|
23733
23666
|
name: "bots",
|
|
23734
|
-
description: "Which machines fetch this site. Every other report here excludes them; this one reads them. Answers whether Google is still crawling a page after it was republished, whether Meta fetched a link preview before spend went behind the URL, and how much of the traffic is now AI answer engines.",
|
|
23667
|
+
description: "Which machines fetch this site and whether they are genuine. Every other report here excludes them; this one reads them. Answers whether Google is still crawling a page after it was republished, whether Meta fetched a link preview before spend went behind the URL, and how much of the traffic is now AI answer engines.",
|
|
23735
23668
|
playbook: "landing \u2014 a page that stopped being crawled stops ranking, weeks before the traffic shows it"
|
|
23736
23669
|
},
|
|
23737
23670
|
{
|
|
@@ -24175,7 +24108,7 @@ var funnelCommand = presetCommand({
|
|
|
24175
24108
|
var flowCommand = presetCommand({
|
|
24176
24109
|
name: "flow",
|
|
24177
24110
|
preset: "flow",
|
|
24178
|
-
description: "One Form in depth: how many people it converted, where they went between steps, the per-step table, and every trigger it raised. Every count is DISTINCT VISITS, so quote shares against `funnels[].visits` \u2014 the visits that opened the Form \u2014 and never against `starts`, which is only the visits that touched it. The gap between the two is people who read the Form and left, and on most Forms it is the largest loss there is. Read `flowSummary.convertedSessions`, not `submits` \u2014 a Form that books a call on a scheduling node in the MIDDLE of the flow never emits a submit, so it reports zero submits and every one of its real bookings as conversions. `flowPaths` is the flow as edges between steps, bracketed by __flow_start__, __flow_converted__ and __flow_exit__, which is how a branching Form is read at all: a per-step table cannot say that of the people who left step two, forty went to the booking branch and ninety went nowhere.
|
|
24111
|
+
description: "One Form in depth: how many people it converted, where they went between steps, the per-step table, and every trigger it raised. Every count is DISTINCT VISITS, so quote shares against `funnels[].visits` \u2014 the visits that opened the Form \u2014 and never against `starts`, which is only the visits that touched it. The gap between the two is people who read the Form and left, and on most Forms it is the largest loss there is. Read `flowSummary.convertedSessions`, not `submits` \u2014 a Form that books a call on a scheduling node in the MIDDLE of the flow never emits a submit, so it reports zero submits and every one of its real bookings as conversions. `flowPaths` is the flow as edges between steps, bracketed by __flow_start__, __flow_converted__ and __flow_exit__, which is how a branching Form is read at all: a per-step table cannot say that of the people who left step two, forty went to the booking branch and ninety went nowhere.",
|
|
24179
24112
|
extraArgs: { flow: { type: "string", description: "Form slug (default: every Form)", required: false } },
|
|
24180
24113
|
resolve: (args) => ({ preset: "flow", flowSlug: args.flow ? String(args.flow) : void 0 })
|
|
24181
24114
|
});
|
|
@@ -24517,7 +24450,8 @@ import { defineCommand as defineCommand94 } from "citty";
|
|
|
24517
24450
|
import { defineCommand as defineCommand89 } from "citty";
|
|
24518
24451
|
|
|
24519
24452
|
// src/commands/avatars/casting.ts
|
|
24520
|
-
var
|
|
24453
|
+
var CAST_FLAG_RULE = "Cast with `--avatar <handle>` on `baker studio generate` and `baker studio animate`. Do NOT hand-roll it by pasting `subjectDescription` into the prompt or by passing the sheet through `--reference` \u2014 both render something that merely resembles them. `--avatar` is also the ONLY thing that carries their pinned VOICE and how they speak into a clip; without it the video model invents a different voice, and no later step can put theirs back.";
|
|
24454
|
+
var VERBATIM_RULE = "When you do write the description yourself \u2014 a canvas node, a landing image, anywhere `--avatar` does not exist \u2014 copy `subjectDescription` VERBATIM, word for word. Re-phrasing it per generation is the other reason a face drifts across a set.";
|
|
24521
24455
|
var VIDEO_ROUTING = "In video, a photoreal presenter renders on `google/veo-3.1` (or `google/veo-3.1-fast`), never `bytedance/seedance-2.0` \u2014 it refuses photoreal human faces, AI-generated ones included. Scaffolding a video creative: `baker canvas scaffold-video \u2026 --real-face`.";
|
|
24522
24456
|
function castingHints(avatar) {
|
|
24523
24457
|
if (avatar.status === "generating") {
|
|
@@ -24541,7 +24475,8 @@ function castingHints(avatar) {
|
|
|
24541
24475
|
];
|
|
24542
24476
|
}
|
|
24543
24477
|
return [
|
|
24544
|
-
`Ready to cast
|
|
24478
|
+
`Ready to cast: \`baker studio generate "<your scene>" --avatar ${avatar.handle}\` for a still, \`baker studio animate "<the motion, and the line they say>" --avatar ${avatar.handle}\` for a clip.`,
|
|
24479
|
+
CAST_FLAG_RULE,
|
|
24545
24480
|
VERBATIM_RULE,
|
|
24546
24481
|
VIDEO_ROUTING
|
|
24547
24482
|
];
|
|
@@ -24553,7 +24488,6 @@ function rosterRow(avatar) {
|
|
|
24553
24488
|
status: avatar.status,
|
|
24554
24489
|
likeness: avatar.likeness,
|
|
24555
24490
|
sheetUrl: avatar.sheetUrl ?? null,
|
|
24556
|
-
hasVoice: avatar.hasVoice,
|
|
24557
24491
|
avatarId: avatar.avatarId,
|
|
24558
24492
|
...avatar.errorMessage ? { errorMessage: avatar.errorMessage } : {}
|
|
24559
24493
|
};
|
|
@@ -24581,10 +24515,19 @@ function rosterHints(roster, statusFilter) {
|
|
|
24581
24515
|
}
|
|
24582
24516
|
return hints;
|
|
24583
24517
|
}
|
|
24584
|
-
function
|
|
24518
|
+
function thinProfileHint(profile, handle) {
|
|
24519
|
+
const missing = ["motion", "persona", "speech", "accent", "wardrobe", "setting"].filter(
|
|
24520
|
+
(field) => !profile?.[field]?.trim()
|
|
24521
|
+
);
|
|
24522
|
+
if (missing.length === 0) return null;
|
|
24523
|
+
return `MISSING ${missing.map((field) => `--${field}`).join(" ")}. A bare subject description holds the face still and nothing else, so clips of @${handle} come out stiff and generic \u2014 measured, filling these in nearly doubled the movement in the same brief. --accent is the one nobody guesses and the only one that fails silently: it decides the accent the avatar SPEAKS with in every clip, so name the region the user is writing to you from ("Spanish from Spain, Madrid accent") \u2014 "Spanish" on its own renders as no accent at all. The user almost certainly told you how this person talks and carries themselves; put it in: \`baker avatars update ${handle} ${missing.map((field) => `--${field} "\u2026"`).join(" ")}\`.`;
|
|
24524
|
+
}
|
|
24525
|
+
function creationHints(created, profile) {
|
|
24526
|
+
const thin = thinProfileHint(profile, created.handle);
|
|
24585
24527
|
const hints = [
|
|
24528
|
+
...thin ? [thin] : [],
|
|
24586
24529
|
...castingHints({ handle: created.handle, status: created.status }),
|
|
24587
|
-
`Once it is ready,
|
|
24530
|
+
`Once it is ready, cast it with \`--avatar ${created.handle}\` on \`baker studio generate\` / \`baker studio animate\` \u2014 that flag is what grounds the render on its identity sheet and, for a clip, what makes it speak in this avatar's own voice.`
|
|
24588
24531
|
];
|
|
24589
24532
|
if (created.likeness === "licensed") {
|
|
24590
24533
|
hints.push(
|
|
@@ -24670,6 +24613,7 @@ var TEXT_FIELDS = [
|
|
|
24670
24613
|
["subject", "subjectDescription"],
|
|
24671
24614
|
["persona", "persona"],
|
|
24672
24615
|
["speech", "speech"],
|
|
24616
|
+
["accent", "accent"],
|
|
24673
24617
|
["motion", "motion"],
|
|
24674
24618
|
["wardrobe", "wardrobe"],
|
|
24675
24619
|
["setting", "setting"]
|
|
@@ -24722,11 +24666,11 @@ function unwrap(response) {
|
|
|
24722
24666
|
}
|
|
24723
24667
|
return response.data;
|
|
24724
24668
|
}
|
|
24725
|
-
async function readAvatars(
|
|
24726
|
-
return unwrap(await apiGet(
|
|
24669
|
+
async function readAvatars(path39, params) {
|
|
24670
|
+
return unwrap(await apiGet(path39, params));
|
|
24727
24671
|
}
|
|
24728
|
-
async function writeAvatars(
|
|
24729
|
-
return unwrap(await apiPost(
|
|
24672
|
+
async function writeAvatars(path39, body) {
|
|
24673
|
+
return unwrap(await apiPost(path39, body));
|
|
24730
24674
|
}
|
|
24731
24675
|
|
|
24732
24676
|
// src/commands/avatars/create.ts
|
|
@@ -24758,7 +24702,12 @@ registerSchema({
|
|
|
24758
24702
|
required: true
|
|
24759
24703
|
},
|
|
24760
24704
|
persona: { type: "string", description: "Who they are on camera \u2014 role, attitude, energy", required: false },
|
|
24761
|
-
speech: { type: "string", description: "How they speak \u2014 pace, register,
|
|
24705
|
+
speech: { type: "string", description: "How they speak \u2014 pace, register, verbal habits", required: false },
|
|
24706
|
+
accent: {
|
|
24707
|
+
type: "string",
|
|
24708
|
+
description: "Where their voice is FROM, as a place: 'Spanish from Spain, Madrid accent', 'Mexican Spanish', 'British English, London'. Name the region \u2014 an adjective like 'clear Spanish accent' is read by the video model as NO accent, and the clip comes out sounding like nowhere. Set it whenever the avatar will speak; the user's own language is the default to assume, not English.",
|
|
24709
|
+
required: false
|
|
24710
|
+
},
|
|
24762
24711
|
motion: { type: "string", description: "Body language and gesture in video", required: false },
|
|
24763
24712
|
wardrobe: { type: "string", description: "Default outfit when the brief does not name one", required: false },
|
|
24764
24713
|
setting: { type: "string", description: "Default surroundings when the brief leaves them open", required: false },
|
|
@@ -24792,6 +24741,11 @@ var createCommand2 = defineCommand89({
|
|
|
24792
24741
|
subject: { type: "string", description: "The person, plainly described \u2014 reused verbatim", required: false },
|
|
24793
24742
|
persona: { type: "string", description: "Who they are on camera", required: false },
|
|
24794
24743
|
speech: { type: "string", description: "How they speak", required: false },
|
|
24744
|
+
accent: {
|
|
24745
|
+
type: "string",
|
|
24746
|
+
description: "Where their voice is FROM \u2014 name the region, e.g. 'Spanish from Spain, Madrid accent'",
|
|
24747
|
+
required: false
|
|
24748
|
+
},
|
|
24795
24749
|
motion: { type: "string", description: "Body language in video", required: false },
|
|
24796
24750
|
wardrobe: { type: "string", description: "Default outfit", required: false },
|
|
24797
24751
|
setting: { type: "string", description: "Default surroundings", required: false },
|
|
@@ -24854,7 +24808,7 @@ var createCommand2 = defineCommand89({
|
|
|
24854
24808
|
...chatIdFromEnv() ? { chatId: chatIdFromEnv() } : {}
|
|
24855
24809
|
};
|
|
24856
24810
|
const data = await writeAvatars("/api/avatars", body);
|
|
24857
|
-
writeJson({ ok: true, data, hints: creationHints(data) });
|
|
24811
|
+
writeJson({ ok: true, data, hints: creationHints(data, body.profile) });
|
|
24858
24812
|
} catch (err) {
|
|
24859
24813
|
failAvatarApi(err, handle);
|
|
24860
24814
|
}
|
|
@@ -25560,12 +25514,12 @@ function missingFontFiles(urls, available) {
|
|
|
25560
25514
|
function planFontAdoption(sources, families) {
|
|
25561
25515
|
const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
|
|
25562
25516
|
const byFamily = /* @__PURE__ */ new Map();
|
|
25563
|
-
for (const { path:
|
|
25564
|
-
const dir = posix.dirname(
|
|
25517
|
+
for (const { path: path39, source } of sources) {
|
|
25518
|
+
const dir = posix.dirname(path39);
|
|
25565
25519
|
for (const face of declaredFontFaces(source)) {
|
|
25566
25520
|
if (!wanted.has(face.family)) continue;
|
|
25567
25521
|
const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
|
|
25568
|
-
perFile.set(
|
|
25522
|
+
perFile.set(path39, [...perFile.get(path39) ?? [], rebaseFontFaceSrc(face.block, dir)]);
|
|
25569
25523
|
byFamily.set(face.family, perFile);
|
|
25570
25524
|
}
|
|
25571
25525
|
}
|
|
@@ -26287,7 +26241,7 @@ Subcommands:
|
|
|
26287
26241
|
});
|
|
26288
26242
|
|
|
26289
26243
|
// src/commands/canvas/index.ts
|
|
26290
|
-
import { defineCommand as
|
|
26244
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
26291
26245
|
|
|
26292
26246
|
// src/commands/canvas/catalog.ts
|
|
26293
26247
|
import { defineCommand as defineCommand97 } from "citty";
|
|
@@ -29986,7 +29940,7 @@ function buildVideoTodo(report, overlayCount, floatingCount, opts, blueprint) {
|
|
|
29986
29940
|
]
|
|
29987
29941
|
},
|
|
29988
29942
|
transitions: "Scene-to-scene cuts the deconstruct flagged as fade/whip/zoom/dissolve/swipe are reproduced as an ffmpeg xfade at the boundary (everything else stays a hard cut). The overlap is consumed from extra generated footage, so the picture stays exactly on the audio timeline. To change a transition, edit the scene's `transition_out.type` in prompt.json and re-scaffold, or hand-edit the `spine` node's ffmpeg args. For a richer HERO cut (whip-pan, glitch, light-leak, gravitational-lens\u2026), the overlay layer can run a Hyperframes shader/CSS transition instead \u2014 see references/hyperframes/blueprints-and-transitions.md (pick 2\u20133 transition types total; the motion IS the handoff).",
|
|
29989
|
-
overlay_capabilities: 'The overlay layer (video-overlay-composition/index.html) is a REAL Hyperframes composition, not a plain text layer \u2014 our hyperframe_render node runs the genuine `npx hyperframes` renderer. So it can do far more than fade/slide/pop: (1) PULL a ready-made block \u2014 `npx hyperframes catalog --type block` then `npx hyperframes add <id>` into the composition dir, and nest it with a <div data-composition-src="compositions/<id>.html" data-start data-track-index data-width data-height> clip (~
|
|
29943
|
+
overlay_capabilities: 'The overlay layer (video-overlay-composition/index.html) is a REAL Hyperframes composition, not a plain text layer \u2014 our hyperframe_render node runs the genuine `npx hyperframes` renderer. So it can do far more than fade/slide/pop: (1) PULL a ready-made block \u2014 `npx hyperframes catalog --type block` then `npx hyperframes add <id>` into the composition dir, and nest it with a <div data-composition-src="compositions/<id>.html" data-start data-track-index data-width data-height> clip (~154 blocks: lower-thirds, social-proof cards, stat counters, charts, code, logo stings); (2) animate with the named GSAP motion-rule vocabulary (kinetic-beat-slam, svg-path-draw, counting-dynamic-scale, multi-phase-camera\u2026); (3) frame a talking head as a video-call/PIP/split. The whole engine + how to build new effects is documented in references/hyperframes/ (start at README.md \u2192 catalog.md, motion-rules.md). Reach for this whenever the reference\'s graphics are richer than plain text.',
|
|
29990
29944
|
caption_system: "Sound-off feed = burned-in captions carry the message. The deconstruct produced a word-level transcript \u2014 drive a real caption track off it (karaoke highlight \u2192 themed \u2192 kinetic), not hand-typed text. Floor: `npx hyperframes add caption-highlight` (TikTok karaoke); escalate by content register (caption-kinetic-slam for hype, caption-editorial-emphasis for premium, caption-neon-glow for AI/crypto). Group on meaning, sync within 80ms. Full ladder + transcript contract: references/hyperframes/captions-and-audio.md.",
|
|
29991
29945
|
talking_head_overlay: "For a scene where a presenter shows something (screen-share, app demo, product, a 'video call' look), frame the talking-head clip in the overlay composition: presenter full-bleed \u2192 shrinks to a rounded corner PIP pill while a content card takes the stage (or split/stack/overlay-glass-card). The pattern, the #video-wrap\u2192corner-pill tween, the glass call card, and the corner-coord presets are in references/hyperframes/talking-head-and-overlays.md. A ready exemplar ships as the `video-call-composition` move \u2014 copy it next to your canvas, drop brand fonts in the dir, point a `hyperframe_render` at it with the presenter clip as its `background`.",
|
|
29992
29946
|
text_overlays: {
|
|
@@ -32189,11 +32143,241 @@ var scaffoldStaticAdCommand = defineCommand103({
|
|
|
32189
32143
|
}
|
|
32190
32144
|
});
|
|
32191
32145
|
|
|
32146
|
+
// src/commands/canvas/scaffold-ad.ts
|
|
32147
|
+
import { cp, mkdir as mkdir7, readFile as readFile14, writeFile as writeFile9 } from "fs/promises";
|
|
32148
|
+
import path22 from "path";
|
|
32149
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
32150
|
+
|
|
32151
|
+
// src/engine/scaffold/ad-spec.ts
|
|
32152
|
+
import { z as z29 } from "zod";
|
|
32153
|
+
var oneClause = (line) => (line.match(/[.!?](\s|$)/g) ?? []).length <= 1;
|
|
32154
|
+
var Beat = z29.object({
|
|
32155
|
+
/**
|
|
32156
|
+
* The line the voice says in this beat — ONE clause, ending in its own
|
|
32157
|
+
* punctuation. It becomes the caption card verbatim.
|
|
32158
|
+
*/
|
|
32159
|
+
say: z29.string().min(1).refine(oneClause, "a beat is one clause: split a second sentence into its own beat"),
|
|
32160
|
+
/** What is on screen while it is said, as a shot brief for the video model. */
|
|
32161
|
+
show: z29.string().min(1),
|
|
32162
|
+
/**
|
|
32163
|
+
* Set only when this beat's subject is talking to camera. Off by default, and
|
|
32164
|
+
* the default is load-bearing: a person visibly speaking under a voice that is
|
|
32165
|
+
* not theirs reads as bad dubbing, which is what sank the first cut of this.
|
|
32166
|
+
*/
|
|
32167
|
+
on_camera: z29.boolean().optional()
|
|
32168
|
+
});
|
|
32169
|
+
var AdSpec = z29.object({
|
|
32170
|
+
format: z29.object({
|
|
32171
|
+
aspect_ratio: z29.string().default("9:16"),
|
|
32172
|
+
resolution: z29.string().default("720p")
|
|
32173
|
+
}).default({ aspect_ratio: "9:16", resolution: "720p" }),
|
|
32174
|
+
brand: z29.object({
|
|
32175
|
+
name: z29.string().optional(),
|
|
32176
|
+
/** Figures to lift typographically — the one gold number every ad has. */
|
|
32177
|
+
highlight: z29.array(z29.string()).optional()
|
|
32178
|
+
}).optional(),
|
|
32179
|
+
voice: z29.object({
|
|
32180
|
+
description: z29.string().min(1),
|
|
32181
|
+
language: z29.string().optional()
|
|
32182
|
+
}).optional(),
|
|
32183
|
+
/**
|
|
32184
|
+
* A bed, described in words. Omitted leaves the ad dry — the engine only wires
|
|
32185
|
+
* music when asked, and silence is a legitimate choice.
|
|
32186
|
+
*
|
|
32187
|
+
* The bed never plays over the first beat: the opening line is the
|
|
32188
|
+
* scroll-stopper and has to read clean. That is the engine's rule, not this
|
|
32189
|
+
* one, and it is why the prompt is all this needs to carry.
|
|
32190
|
+
*/
|
|
32191
|
+
music: z29.string().min(1).optional(),
|
|
32192
|
+
beats: z29.array(Beat).min(2)
|
|
32193
|
+
});
|
|
32194
|
+
function narrativeRole(index, total) {
|
|
32195
|
+
if (index === 0) return "hook";
|
|
32196
|
+
if (index === total - 1) return "cta";
|
|
32197
|
+
return index < total / 2 ? "problem" : "proof";
|
|
32198
|
+
}
|
|
32199
|
+
function estimateSeconds(line) {
|
|
32200
|
+
const words2 = line.trim().split(/\s+/).length;
|
|
32201
|
+
return Math.max(1.6, Math.round(words2 / 2.6 * 10) / 10);
|
|
32202
|
+
}
|
|
32203
|
+
function adSpecToBlueprint(spec) {
|
|
32204
|
+
const total = spec.beats.length;
|
|
32205
|
+
let clock = 0;
|
|
32206
|
+
const scenes = spec.beats.map((beat, i) => {
|
|
32207
|
+
const duration = estimateSeconds(beat.say);
|
|
32208
|
+
const start = clock;
|
|
32209
|
+
clock += duration;
|
|
32210
|
+
return {
|
|
32211
|
+
start_s: Math.round(start * 100) / 100,
|
|
32212
|
+
end_s: Math.round(clock * 100) / 100,
|
|
32213
|
+
duration_s: duration,
|
|
32214
|
+
summary: beat.say,
|
|
32215
|
+
narrative_role: narrativeRole(i, total),
|
|
32216
|
+
// The read is built from per-scene dialogue, not from the global
|
|
32217
|
+
// transcript: emitting only the transcript scaffolds a SILENT ad. And
|
|
32218
|
+
// `on_camera` is the engine's own switch for "this line is narration" —
|
|
32219
|
+
// absent, it guesses from who is in frame, which is how a still photograph
|
|
32220
|
+
// once got lip-synced.
|
|
32221
|
+
dialogue: [
|
|
32222
|
+
{
|
|
32223
|
+
line: beat.say,
|
|
32224
|
+
start_s: Math.round(start * 100) / 100,
|
|
32225
|
+
end_s: Math.round(clock * 100) / 100,
|
|
32226
|
+
on_camera: beat.on_camera === true,
|
|
32227
|
+
...spec.voice?.description ? { voice_description: spec.voice.description } : {}
|
|
32228
|
+
}
|
|
32229
|
+
],
|
|
32230
|
+
motion_prompt: beat.on_camera ? beat.show : (
|
|
32231
|
+
// The subject must not be forming words: the voice belongs to the
|
|
32232
|
+
// narration, and a mouth moving under it reads as dubbing.
|
|
32233
|
+
`${beat.show} Nobody in frame is speaking \u2014 mouths closed, no dialogue.`
|
|
32234
|
+
),
|
|
32235
|
+
start_frame_prompt: beat.show
|
|
32236
|
+
};
|
|
32237
|
+
});
|
|
32238
|
+
return {
|
|
32239
|
+
global: {
|
|
32240
|
+
transcript: spec.beats.map((b) => b.say).join(" "),
|
|
32241
|
+
voiceover: {
|
|
32242
|
+
// Narration over the picture. Never `on_camera`: that is what tells the
|
|
32243
|
+
// engine a mouth is a lip-sync candidate.
|
|
32244
|
+
mode: "voiceover",
|
|
32245
|
+
...spec.voice?.description ? { voice_description: spec.voice.description } : {}
|
|
32246
|
+
},
|
|
32247
|
+
...spec.brand?.name ? { brand: { name: spec.brand.name } } : {},
|
|
32248
|
+
...spec.music ? { music: { music_prompt: spec.music } } : {}
|
|
32249
|
+
},
|
|
32250
|
+
scenes
|
|
32251
|
+
};
|
|
32252
|
+
}
|
|
32253
|
+
|
|
32254
|
+
// src/commands/canvas/composition-path.ts
|
|
32255
|
+
import { existsSync as existsSync4 } from "fs";
|
|
32256
|
+
import path21 from "path";
|
|
32257
|
+
function resolveShippedCanvasDir(name, startDir, exists = existsSync4, maxDepth = 8) {
|
|
32258
|
+
const rel = path21.join("canvas", name);
|
|
32259
|
+
let dir = startDir;
|
|
32260
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
32261
|
+
const candidate = path21.join(dir, rel);
|
|
32262
|
+
if (exists(path21.join(candidate, "meta.json"))) return candidate;
|
|
32263
|
+
const parent = path21.dirname(dir);
|
|
32264
|
+
if (parent === dir) break;
|
|
32265
|
+
dir = parent;
|
|
32266
|
+
}
|
|
32267
|
+
return path21.resolve(startDir, "../../../", rel);
|
|
32268
|
+
}
|
|
32269
|
+
|
|
32270
|
+
// src/commands/canvas/scaffold-ad.ts
|
|
32271
|
+
var SHIPPED_COMPOSITION_DIR = resolveShippedCanvasDir("video-overlay-composition", import.meta.dirname);
|
|
32272
|
+
var SHIPPED_CAPTIONS_DIR = resolveShippedCanvasDir("tiktok-captions-composition", import.meta.dirname);
|
|
32273
|
+
registerSchema({
|
|
32274
|
+
command: "canvas.scaffold-ad",
|
|
32275
|
+
description: "Build a captioned vertical ad from a WRITTEN SPEC \u2014 no reference video. Start here when someone asks for an ad, a promo or a UGC-style clip and there is nothing to copy: `scaffold-video` reproduces a video you already have, this one writes a new one. You supply a spec of BEATS, and a beat is one line the voice says plus one shot the viewer sees while it is said. Everything else \u2014 the read, the caption cards, the clips, the music, the render \u2014 is derived from that pair, so the ad cannot drift out of sync with itself.",
|
|
32276
|
+
args: {
|
|
32277
|
+
spec: {
|
|
32278
|
+
type: "string",
|
|
32279
|
+
required: true,
|
|
32280
|
+
description: "Path to the ad spec JSON. Shape: { format?, brand?, voice?, beats: [{ say, show, on_camera? }] }. `say` is ONE clause ending in its own punctuation \u2014 it becomes a caption card verbatim, so two sentences in one beat produce a card holding both. `show` is the shot brief for that line. Set `on_camera` ONLY when that beat's subject talks to camera."
|
|
32281
|
+
},
|
|
32282
|
+
slug: {
|
|
32283
|
+
type: "string",
|
|
32284
|
+
required: false,
|
|
32285
|
+
description: "Creative slug \u2014 writes to src/creatives/<slug>/<slug>.canvas.json"
|
|
32286
|
+
},
|
|
32287
|
+
out: {
|
|
32288
|
+
type: "string",
|
|
32289
|
+
required: false,
|
|
32290
|
+
description: "Output canvas path (default <spec-dir>/<name>.canvas.json)"
|
|
32291
|
+
}
|
|
32292
|
+
}
|
|
32293
|
+
});
|
|
32294
|
+
var scaffoldAdCommand = defineCommand104({
|
|
32295
|
+
meta: {
|
|
32296
|
+
name: "scaffold-ad",
|
|
32297
|
+
description: 'Build a captioned vertical ad from a written spec, with no reference video to copy.\n\nA spec is a list of BEATS. One beat = one line the voice says + one shot on screen while it is said. That pairing is what keeps the ad honest: the caption card IS the line, so it can never end mid-sentence, and the picture can never drift from the read.\n\nTwo rules the spec enforces for you, both learned the expensive way:\n \u2022 `say` is ONE clause with its own punctuation. Two sentences in a beat is rejected.\n \u2022 Nobody in shot is speaking unless you set `on_camera` on that beat. A person visibly talking under a voice that is not theirs reads as bad dubbing.\n\nExample spec:\n { "beats": [\n { "say": "Mientras t\xFA sigues pagando la luz a precio de oro,", "show": "Aerial over Spanish rooftops at golden hour." },\n { "say": "Haz clic en el enlace y reserva tu estudio gratuito.", "show": "A couple walking home at sunset." } ] }\n\nThen: baker canvas run <the canvas it writes>'
|
|
32298
|
+
},
|
|
32299
|
+
args: {
|
|
32300
|
+
spec: { type: "string", required: true, description: "Path to the ad spec JSON" },
|
|
32301
|
+
slug: {
|
|
32302
|
+
type: "string",
|
|
32303
|
+
required: false,
|
|
32304
|
+
description: "Creative slug \u2014 writes to src/creatives/<slug>/<slug>.canvas.json"
|
|
32305
|
+
},
|
|
32306
|
+
out: { type: "string", required: false, description: "Output canvas path" }
|
|
32307
|
+
},
|
|
32308
|
+
async run({ args }) {
|
|
32309
|
+
const specPath = args.spec;
|
|
32310
|
+
let parsed;
|
|
32311
|
+
try {
|
|
32312
|
+
parsed = JSON.parse(await readFile14(specPath, "utf-8"));
|
|
32313
|
+
} catch (e) {
|
|
32314
|
+
writeJson({
|
|
32315
|
+
ok: false,
|
|
32316
|
+
error: {
|
|
32317
|
+
code: "VALIDATION_ERROR",
|
|
32318
|
+
message: `Could not read the ad spec at ${specPath}: ${e instanceof Error ? e.message : String(e)}`,
|
|
32319
|
+
fix: "Write the spec first \u2014 a JSON file with a `beats` array, each beat holding `say` (one clause) and `show` (the shot)."
|
|
32320
|
+
}
|
|
32321
|
+
});
|
|
32322
|
+
process.exit(1);
|
|
32323
|
+
return;
|
|
32324
|
+
}
|
|
32325
|
+
const spec = AdSpec.safeParse(parsed);
|
|
32326
|
+
if (!spec.success) {
|
|
32327
|
+
writeJson({
|
|
32328
|
+
ok: false,
|
|
32329
|
+
error: {
|
|
32330
|
+
code: "VALIDATION_ERROR",
|
|
32331
|
+
message: `That ad spec is not usable: ${spec.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`,
|
|
32332
|
+
fix: "A beat is ONE line and ONE shot. If a beat holds two sentences, split it into two beats \u2014 the line becomes a caption card verbatim, and a card holding two sentences is the defect this refuses."
|
|
32333
|
+
}
|
|
32334
|
+
});
|
|
32335
|
+
process.exit(1);
|
|
32336
|
+
return;
|
|
32337
|
+
}
|
|
32338
|
+
const blueprint = adSpecToBlueprint(spec.data);
|
|
32339
|
+
const slug = args.slug ?? path22.basename(specPath).replace(/\.[^.]+$/, "");
|
|
32340
|
+
const outPath = args.out ?? (args.slug ? path22.join("src/creatives", slug, `${slug}.canvas.json`) : path22.join(path22.dirname(specPath), `${slug}.canvas.json`));
|
|
32341
|
+
const outDir = path22.dirname(outPath);
|
|
32342
|
+
await mkdir7(outDir, { recursive: true });
|
|
32343
|
+
const compositionDest = path22.join(outDir, "video-overlay-composition");
|
|
32344
|
+
const captionsDest = path22.join(outDir, "tiktok-captions-composition");
|
|
32345
|
+
await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
|
|
32346
|
+
await cp(SHIPPED_CAPTIONS_DIR, captionsDest, { recursive: true });
|
|
32347
|
+
const blueprintPath = path22.join(outDir, "prompt.json");
|
|
32348
|
+
const blueprintStylePath = path22.join(outDir, "prompt.style.json");
|
|
32349
|
+
await writeSceneFiles(outDir, blueprint);
|
|
32350
|
+
await writeFile9(blueprintStylePath, renderStyleProjectionFromValue(blueprint), "utf8");
|
|
32351
|
+
const opts = {
|
|
32352
|
+
imageModel: DEFAULT_IMAGE_GENERATE_MODEL,
|
|
32353
|
+
videoModel: DEFAULT_VIDEO_GENERATE_MODEL,
|
|
32354
|
+
overlayCompositionPath: path22.relative(outDir, compositionDest),
|
|
32355
|
+
captionsCompositionPath: path22.relative(outDir, captionsDest),
|
|
32356
|
+
blueprintPath: path22.relative(outDir, blueprintPath),
|
|
32357
|
+
blueprintStylePath: path22.relative(outDir, blueprintStylePath),
|
|
32358
|
+
aspect: spec.data.format.aspect_ratio,
|
|
32359
|
+
resolution: spec.data.format.resolution
|
|
32360
|
+
};
|
|
32361
|
+
const canvas = scaffoldVideoCanvas(blueprint, [], opts);
|
|
32362
|
+
await writeFile9(outPath, `${JSON.stringify(canvas, null, 2)}
|
|
32363
|
+
`, "utf-8");
|
|
32364
|
+
writeJson({
|
|
32365
|
+
ok: true,
|
|
32366
|
+
data: { canvas: outPath, beats: spec.data.beats.length, slug },
|
|
32367
|
+
hints: [
|
|
32368
|
+
`Wrote ${spec.data.beats.length} beats to ${outPath}. Run it with \`baker canvas run ${outPath}\`.`,
|
|
32369
|
+
"The caption cards are your `say` lines verbatim \u2014 read them back before running; that is the copy the viewer sees.",
|
|
32370
|
+
"Every clip renders with nobody speaking unless a beat set `on_camera`. If a beat needs a presenter talking, set it there rather than describing it in `show`."
|
|
32371
|
+
]
|
|
32372
|
+
});
|
|
32373
|
+
}
|
|
32374
|
+
});
|
|
32375
|
+
|
|
32192
32376
|
// src/commands/canvas/scaffold-video.ts
|
|
32193
|
-
import { access as access2, cp, mkdir as
|
|
32377
|
+
import { access as access2, cp as cp2, mkdir as mkdir8, readFile as readFile17, rm as rm6, writeFile as writeFile10 } from "fs/promises";
|
|
32194
32378
|
import { tmpdir as tmpdir2 } from "os";
|
|
32195
|
-
import
|
|
32196
|
-
import { defineCommand as
|
|
32379
|
+
import path24 from "path";
|
|
32380
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
32197
32381
|
|
|
32198
32382
|
// src/engine/scaffold/lib/model-router.ts
|
|
32199
32383
|
var SEEDANCE = "bytedance/seedance-2.0";
|
|
@@ -32232,7 +32416,7 @@ function routeVideoModel(input) {
|
|
|
32232
32416
|
|
|
32233
32417
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
32234
32418
|
import { execFile as execFile2 } from "child_process";
|
|
32235
|
-
import { mkdtemp, readdir as readdir7, readFile as
|
|
32419
|
+
import { mkdtemp, readdir as readdir7, readFile as readFile15, rm as rm5 } from "fs/promises";
|
|
32236
32420
|
import { tmpdir } from "os";
|
|
32237
32421
|
import { join as join2 } from "path";
|
|
32238
32422
|
import { promisify as promisify2 } from "util";
|
|
@@ -32308,7 +32492,7 @@ async function runSceneDetectOnce(filePath, threshold, minSceneLenS, timeoutMs)
|
|
|
32308
32492
|
);
|
|
32309
32493
|
const csvName = (await readdir7(outDir)).find((f) => f.toLowerCase().endsWith(".csv"));
|
|
32310
32494
|
if (!csvName) return [];
|
|
32311
|
-
return parsePySceneDetectCsvCuts(await
|
|
32495
|
+
return parsePySceneDetectCsvCuts(await readFile15(join2(outDir, csvName), "utf-8"));
|
|
32312
32496
|
} finally {
|
|
32313
32497
|
await rm5(outDir, { recursive: true, force: true });
|
|
32314
32498
|
}
|
|
@@ -32331,25 +32515,9 @@ async function detectSceneCutsPySceneDetect(filePath, opts = {}) {
|
|
|
32331
32515
|
return cuts;
|
|
32332
32516
|
}
|
|
32333
32517
|
|
|
32334
|
-
// src/commands/canvas/composition-path.ts
|
|
32335
|
-
import { existsSync as existsSync4 } from "fs";
|
|
32336
|
-
import path21 from "path";
|
|
32337
|
-
function resolveShippedCanvasDir(name, startDir, exists = existsSync4, maxDepth = 8) {
|
|
32338
|
-
const rel = path21.join("canvas", name);
|
|
32339
|
-
let dir = startDir;
|
|
32340
|
-
for (let i = 0; i < maxDepth; i++) {
|
|
32341
|
-
const candidate = path21.join(dir, rel);
|
|
32342
|
-
if (exists(path21.join(candidate, "meta.json"))) return candidate;
|
|
32343
|
-
const parent = path21.dirname(dir);
|
|
32344
|
-
if (parent === dir) break;
|
|
32345
|
-
dir = parent;
|
|
32346
|
-
}
|
|
32347
|
-
return path21.resolve(startDir, "../../../", rel);
|
|
32348
|
-
}
|
|
32349
|
-
|
|
32350
32518
|
// src/commands/canvas/gitignore.ts
|
|
32351
|
-
import { appendFile, readFile as
|
|
32352
|
-
import
|
|
32519
|
+
import { appendFile, readFile as readFile16 } from "fs/promises";
|
|
32520
|
+
import path23 from "path";
|
|
32353
32521
|
function missingGitignoreEntries(existing, entries) {
|
|
32354
32522
|
const present2 = new Set(
|
|
32355
32523
|
existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
|
|
@@ -32357,10 +32525,10 @@ function missingGitignoreEntries(existing, entries) {
|
|
|
32357
32525
|
return entries.filter((e) => !present2.has(e.trim().replace(/\/+$/, "")));
|
|
32358
32526
|
}
|
|
32359
32527
|
async function ensureGitignore(dir, entries) {
|
|
32360
|
-
const file =
|
|
32528
|
+
const file = path23.join(dir, ".gitignore");
|
|
32361
32529
|
let existing;
|
|
32362
32530
|
try {
|
|
32363
|
-
existing = await
|
|
32531
|
+
existing = await readFile16(file, "utf8");
|
|
32364
32532
|
} catch {
|
|
32365
32533
|
return;
|
|
32366
32534
|
}
|
|
@@ -32374,8 +32542,8 @@ ${missing.join("\n")}
|
|
|
32374
32542
|
}
|
|
32375
32543
|
|
|
32376
32544
|
// src/commands/canvas/scaffold-video.ts
|
|
32377
|
-
var
|
|
32378
|
-
var
|
|
32545
|
+
var SHIPPED_COMPOSITION_DIR2 = resolveShippedCanvasDir("video-overlay-composition", import.meta.dirname);
|
|
32546
|
+
var SHIPPED_CAPTIONS_DIR2 = resolveShippedCanvasDir("tiktok-captions-composition", import.meta.dirname);
|
|
32379
32547
|
function resolveModel2(kind, preferred) {
|
|
32380
32548
|
const ids = Object.keys(MODEL_REGISTRY[kind]);
|
|
32381
32549
|
return ids.includes(preferred) ? preferred : ids[0] ?? preferred;
|
|
@@ -32399,7 +32567,7 @@ ONE PERSON, MULTIPLE LOOKS: if a single individual plays MULTIPLE personas or wa
|
|
|
32399
32567
|
For each kept element return: { "type": one of person|animal|product|logo|badge|location, "label": a short UPPER_SNAKE_CASE name (e.g. HERO, CREATOR_SKEPTIC, INSURANCE_CARD, LOGO), "description": a concrete reusable description to source/shoot the real asset \u2014 for a person/animal give a NEUTRAL castable role (e.g. "hero pet-owner, woman in her 30s" or "a small beagle"), NOT the original individual's literal face/identity: we RECAST with a FRESH person/animal, so never tell the agent to reuse the original. "expression": a living subject's typical expression or null, "cast_id": the global.cast id if it maps to one else null, "same_as": the label of another element this is the SAME individual as (different wardrobe/persona) else null, "scenes": the 0-based indices of ONLY the scenes where the element is ACTUALLY VISIBLE ON SCREEN \u2014 judged from that scene's start_frame_prompt / end_frame_prompt subjects and its action_detail, NOT from who is merely speaking. A narrator heard over b-roll is NOT present in that b-roll scene; a dog-running cutaway does NOT contain the couch creator just because she talks across it. Do NOT pad the list \u2014 an element wrongly listed in a scene makes the reproduction render the wrong subject there (e.g. the creator appearing in a pure-dog b-roll). When in doubt, leave a scene OUT. Output ONLY the JSON object.`;
|
|
32400
32568
|
async function loadAssetText2(ref, label) {
|
|
32401
32569
|
const r = ref;
|
|
32402
|
-
if (typeof r?.path === "string") return
|
|
32570
|
+
if (typeof r?.path === "string") return readFile17(r.path, "utf8");
|
|
32403
32571
|
if (typeof r?.url === "string") {
|
|
32404
32572
|
const res = await fetch(r.url);
|
|
32405
32573
|
if (!res.ok) throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
@@ -32418,8 +32586,8 @@ async function loadTranscriptBestEffort(ref) {
|
|
|
32418
32586
|
async function stageCaptions(outDir, transcript) {
|
|
32419
32587
|
const text2 = transcript?.trim();
|
|
32420
32588
|
if (!text2 || text2 === "[]") return {};
|
|
32421
|
-
const compositionPath =
|
|
32422
|
-
await
|
|
32589
|
+
const compositionPath = path24.join(outDir, "tiktok-captions-composition");
|
|
32590
|
+
await cp2(SHIPPED_CAPTIONS_DIR2, compositionPath, { recursive: true });
|
|
32423
32591
|
return { compositionPath };
|
|
32424
32592
|
}
|
|
32425
32593
|
function patchCompositionMeta(metaJson, dims) {
|
|
@@ -32436,12 +32604,12 @@ function patchCompositionHtml(html, dims) {
|
|
|
32436
32604
|
return html.replace(/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+(")/i, `$1${dims.w}$2${dims.h}$3`).replace(/(width:\s*)\d+(px;\s*height:\s*)\d+(px;)/i, `$1${dims.w}$2${dims.h}$3`).replace(/(data-width=")\d+(")/i, `$1${dims.w}$2`).replace(/(data-height=")\d+(")/i, `$1${dims.h}$2`);
|
|
32437
32605
|
}
|
|
32438
32606
|
async function stampCompositionDims(compositionDir, dims) {
|
|
32439
|
-
const metaPath =
|
|
32440
|
-
const rawMeta = await
|
|
32441
|
-
await
|
|
32442
|
-
const htmlPath =
|
|
32443
|
-
const rawHtml = await
|
|
32444
|
-
await
|
|
32607
|
+
const metaPath = path24.join(compositionDir, "meta.json");
|
|
32608
|
+
const rawMeta = await readFile17(metaPath, "utf8");
|
|
32609
|
+
await writeFile10(metaPath, patchCompositionMeta(rawMeta, dims), "utf8");
|
|
32610
|
+
const htmlPath = path24.join(compositionDir, "index.html");
|
|
32611
|
+
const rawHtml = await readFile17(htmlPath, "utf8");
|
|
32612
|
+
await writeFile10(htmlPath, patchCompositionHtml(rawHtml, dims), "utf8");
|
|
32445
32613
|
}
|
|
32446
32614
|
function parseElements2(raw) {
|
|
32447
32615
|
const parsed = JSON.parse(raw);
|
|
@@ -32488,7 +32656,7 @@ var VIDEO_EXT_BY_MIME = {
|
|
|
32488
32656
|
"video/x-matroska": ".mkv"
|
|
32489
32657
|
};
|
|
32490
32658
|
function referenceVideoExt(url, contentType) {
|
|
32491
|
-
const fromPath =
|
|
32659
|
+
const fromPath = path24.extname(new URL(url).pathname).toLowerCase();
|
|
32492
32660
|
if (fromPath && fromPath.length <= 5) return fromPath;
|
|
32493
32661
|
const mime = (contentType ?? "").split(";")[0]?.trim().toLowerCase();
|
|
32494
32662
|
return mime && VIDEO_EXT_BY_MIME[mime] || ".mp4";
|
|
@@ -32514,7 +32682,7 @@ function videoDefinitionDescription(blueprint) {
|
|
|
32514
32682
|
return typeof product === "string" && product.trim() ? product.trim() : void 0;
|
|
32515
32683
|
}
|
|
32516
32684
|
async function materializeReferenceVideo(fileArg2) {
|
|
32517
|
-
if (!/^https?:\/\//i.test(fileArg2)) return
|
|
32685
|
+
if (!/^https?:\/\//i.test(fileArg2)) return path24.resolve(fileArg2);
|
|
32518
32686
|
let bytes;
|
|
32519
32687
|
let contentType;
|
|
32520
32688
|
try {
|
|
@@ -32526,11 +32694,11 @@ async function materializeReferenceVideo(fileArg2) {
|
|
|
32526
32694
|
throw new Error(`failed to download reference video: ${e instanceof Error ? e.message : String(e)}`);
|
|
32527
32695
|
}
|
|
32528
32696
|
if (bytes.length === 0) throw new Error("reference video download was empty");
|
|
32529
|
-
const dest =
|
|
32697
|
+
const dest = path24.join(
|
|
32530
32698
|
tmpdir2(),
|
|
32531
32699
|
`baker-ref-${sha256Hex(bytes).slice(0, 16)}${referenceVideoExt(fileArg2, contentType)}`
|
|
32532
32700
|
);
|
|
32533
|
-
await
|
|
32701
|
+
await writeFile10(dest, bytes);
|
|
32534
32702
|
return dest;
|
|
32535
32703
|
}
|
|
32536
32704
|
function resolveSeamDedup(raw) {
|
|
@@ -32654,7 +32822,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
32654
32822
|
return fail4("deconstruct", e instanceof Error ? e.message : String(e));
|
|
32655
32823
|
}
|
|
32656
32824
|
}
|
|
32657
|
-
var scaffoldVideoCommand =
|
|
32825
|
+
var scaffoldVideoCommand = defineCommand105({
|
|
32658
32826
|
meta: {
|
|
32659
32827
|
name: "scaffold-video",
|
|
32660
32828
|
description: "Turn a reference video into a runnable reproduction canvas in one command. Runs billed passes \u2014 video_deconstruct (the full scene-by-scene blueprint + transcript, baked to a split, editable blueprint: a global prompt.json plus one small scenes/sNN.json per scene) and an AI selection of the video's RECURRING identity elements (person/animal/product/logo) \u2014 then scaffolds a pipeline where every scene boundary is a static-ad-grade frame (the blueprint as target_blueprint, a reference legend, the real frame as anchor) and each recurring element gets ONE shared [TODO] ingest slot wired into every frame it appears in. The clips feed Seedance an ultra-detailed motion brief (action, camera, dialogue, transcript). Edit a scene's scenes/sNN.json (or prompt.json for global cast/palette/brand), drop the real source images, then `baker canvas run`."
|
|
@@ -32746,11 +32914,11 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32746
32914
|
} catch (e) {
|
|
32747
32915
|
return fail4("download", e instanceof Error ? e.message : String(e));
|
|
32748
32916
|
}
|
|
32749
|
-
const base =
|
|
32750
|
-
const outPath = args.out ?
|
|
32751
|
-
const outDir =
|
|
32752
|
-
const blueprintPath =
|
|
32753
|
-
const blueprintStylePath =
|
|
32917
|
+
const base = path24.basename(videoPath, path24.extname(videoPath));
|
|
32918
|
+
const outPath = args.out ? path24.resolve(String(args.out)) : slug ? path24.join(process.cwd(), "src", "creatives", slug, `${slug}.canvas.json`) : path24.join(path24.dirname(videoPath), `${base}.video.canvas.json`);
|
|
32919
|
+
const outDir = path24.dirname(outPath);
|
|
32920
|
+
const blueprintPath = path24.join(outDir, "prompt.json");
|
|
32921
|
+
const blueprintStylePath = path24.join(outDir, "prompt.style.json");
|
|
32754
32922
|
const frames = args.frames === "reuse" ? "reuse" : "generate";
|
|
32755
32923
|
const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
|
|
32756
32924
|
if (Number.isFinite(maxScenes)) {
|
|
@@ -32774,10 +32942,10 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32774
32942
|
process.stderr.write(`\u{1F3AC} Photoreal on-camera cast detected \u2192 generating clips on ${videoModel} (dodges Seedance's real-person filter).
|
|
32775
32943
|
`);
|
|
32776
32944
|
}
|
|
32777
|
-
await
|
|
32945
|
+
await mkdir8(outDir, { recursive: true });
|
|
32778
32946
|
const annotated = annotateBlueprintWithElements(blueprint, elements);
|
|
32779
32947
|
await writeSceneFiles(outDir, annotated);
|
|
32780
|
-
await
|
|
32948
|
+
await writeFile10(blueprintStylePath, renderStyleProjectionFromValue(annotated), "utf8");
|
|
32781
32949
|
let aspect;
|
|
32782
32950
|
try {
|
|
32783
32951
|
aspect = resolveAspect(
|
|
@@ -32795,12 +32963,12 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32795
32963
|
`
|
|
32796
32964
|
);
|
|
32797
32965
|
}
|
|
32798
|
-
const compositionDest =
|
|
32799
|
-
await
|
|
32966
|
+
const compositionDest = path24.join(outDir, "video-overlay-composition");
|
|
32967
|
+
await cp2(SHIPPED_COMPOSITION_DIR2, compositionDest, { recursive: true });
|
|
32800
32968
|
await stampCompositionDims(compositionDest, outDims);
|
|
32801
|
-
const indexPath =
|
|
32969
|
+
const indexPath = path24.join(compositionDest, "index.html");
|
|
32802
32970
|
const overlayHtml = buildOverlayHtml(blueprint, { captionsActive: Boolean(transcript) });
|
|
32803
|
-
const indexHtml = await
|
|
32971
|
+
const indexHtml = await readFile17(indexPath, "utf8");
|
|
32804
32972
|
const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
|
|
32805
32973
|
if (injected === indexHtml && overlayHtml.trim()) {
|
|
32806
32974
|
fail4(
|
|
@@ -32808,16 +32976,16 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32808
32976
|
`video-overlay-composition/index.html is missing the <!--OVERLAYS--> marker \u2014 cannot inject the overlay layer`
|
|
32809
32977
|
);
|
|
32810
32978
|
}
|
|
32811
|
-
await
|
|
32979
|
+
await writeFile10(indexPath, injected, "utf8");
|
|
32812
32980
|
const captions = await stageCaptions(outDir, transcript);
|
|
32813
32981
|
if (captions.compositionPath) await stampCompositionDims(captions.compositionPath, outDims);
|
|
32814
32982
|
const opts = {
|
|
32815
32983
|
imageModel,
|
|
32816
32984
|
videoModel,
|
|
32817
|
-
overlayCompositionPath:
|
|
32818
|
-
captionsCompositionPath: captions.compositionPath ?
|
|
32819
|
-
blueprintPath:
|
|
32820
|
-
blueprintStylePath:
|
|
32985
|
+
overlayCompositionPath: path24.relative(outDir, compositionDest),
|
|
32986
|
+
captionsCompositionPath: captions.compositionPath ? path24.relative(outDir, captions.compositionPath) : void 0,
|
|
32987
|
+
blueprintPath: path24.relative(outDir, blueprintPath),
|
|
32988
|
+
blueprintStylePath: path24.relative(outDir, blueprintStylePath),
|
|
32821
32989
|
frames,
|
|
32822
32990
|
ambient: Boolean(args.ambient),
|
|
32823
32991
|
seamDedup: resolveSeamDedup(args["seam-dedup"]),
|
|
@@ -32842,10 +33010,10 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32842
33010
|
todo.blocking_validation_issues = validation.issues;
|
|
32843
33011
|
meta.todo = todo;
|
|
32844
33012
|
}
|
|
32845
|
-
await
|
|
33013
|
+
await writeFile10(outPath, `${JSON.stringify(canvas, null, 2)}
|
|
32846
33014
|
`, "utf8");
|
|
32847
|
-
await
|
|
32848
|
-
|
|
33015
|
+
await writeFile10(
|
|
33016
|
+
path24.join(outDir, REBUILD_FILE),
|
|
32849
33017
|
`${JSON.stringify({ elements, opts }, null, 2)}
|
|
32850
33018
|
`,
|
|
32851
33019
|
"utf8"
|
|
@@ -32870,9 +33038,9 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32870
33038
|
await ensureGitignore(process.cwd(), ["canvas/", ".context/"]);
|
|
32871
33039
|
const sourceRef = videoSourceReference(blueprint, fileArg2);
|
|
32872
33040
|
if (slug) {
|
|
32873
|
-
const definitionPath =
|
|
33041
|
+
const definitionPath = path24.join(outDir, "_definition.md");
|
|
32874
33042
|
if (!await fileExists2(definitionPath)) {
|
|
32875
|
-
await
|
|
33043
|
+
await writeFile10(
|
|
32876
33044
|
definitionPath,
|
|
32877
33045
|
buildCreativeDefinition({
|
|
32878
33046
|
title: titleFromSlug(slug),
|
|
@@ -32925,7 +33093,7 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32925
33093
|
graph: canvas.metadata?.video?.graph_stats
|
|
32926
33094
|
},
|
|
32927
33095
|
checklist: {
|
|
32928
|
-
edit_prompt: `The blueprint is split so you edit ONE small file at a time \u2014 never a giant one. Per-scene content (a scene's dialogue, action, frame prompts, overlays) lives in \`scenes/sNN.json\` \u2014 edit the single scene you want to change. Global cast/palette/brand/copy lives in \`${
|
|
33096
|
+
edit_prompt: `The blueprint is split so you edit ONE small file at a time \u2014 never a giant one. Per-scene content (a scene's dialogue, action, frame prompts, overlays) lives in \`scenes/sNN.json\` \u2014 edit the single scene you want to change. Global cast/palette/brand/copy lives in \`${path24.basename(blueprintPath)}\`. \`baker canvas validate\`/\`run\` re-assemble the blueprint and re-flow every edited scene back into the render (and regenerate ${path24.basename(blueprintStylePath)}, the projection each frame's target_blueprint reads) \u2014 so your scene edits reach the render automatically. Never hand-edit the inlined node prompts in the canvas or the derived ${path24.basename(blueprintStylePath)}; both are regenerated.`,
|
|
32929
33097
|
recurring_elements_to_supply: report.elements,
|
|
32930
33098
|
voices_to_confirm: report.dialogue.map((d) => ({
|
|
32931
33099
|
scene: d.scene,
|
|
@@ -32962,9 +33130,9 @@ var scaffoldVideoCommand = defineCommand104({
|
|
|
32962
33130
|
});
|
|
32963
33131
|
|
|
32964
33132
|
// src/commands/canvas/set-prompt.ts
|
|
32965
|
-
import { readFile as
|
|
32966
|
-
import
|
|
32967
|
-
import { defineCommand as
|
|
33133
|
+
import { readFile as readFile18, writeFile as writeFile11 } from "fs/promises";
|
|
33134
|
+
import path25 from "path";
|
|
33135
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
32968
33136
|
function setNodePrompt(canvas, nodeId, text2) {
|
|
32969
33137
|
const nodes = canvas?.nodes;
|
|
32970
33138
|
if (!Array.isArray(nodes)) throw new Error("canvas has no nodes array");
|
|
@@ -32979,7 +33147,7 @@ function setNodePrompt(canvas, nodeId, text2) {
|
|
|
32979
33147
|
newNodes[idx] = newNode;
|
|
32980
33148
|
return { ...canvas, nodes: newNodes };
|
|
32981
33149
|
}
|
|
32982
|
-
var setPromptCommand =
|
|
33150
|
+
var setPromptCommand = defineCommand106({
|
|
32983
33151
|
meta: {
|
|
32984
33152
|
name: "set-prompt",
|
|
32985
33153
|
description: "Safely set a node's params.prompt (a frame description, motion prompt, etc.) without hand-editing the JSON. Prefer --text-file for multi-line/accented copy \u2014 it preserves UTF-8 exactly, unlike shell-quoted jq."
|
|
@@ -32991,17 +33159,17 @@ var setPromptCommand = defineCommand105({
|
|
|
32991
33159
|
"text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
|
|
32992
33160
|
},
|
|
32993
33161
|
async run({ args }) {
|
|
32994
|
-
const filePath =
|
|
33162
|
+
const filePath = path25.resolve(String(args.file));
|
|
32995
33163
|
let canvas;
|
|
32996
33164
|
try {
|
|
32997
|
-
canvas = JSON.parse(await
|
|
33165
|
+
canvas = JSON.parse(await readFile18(filePath, "utf8"));
|
|
32998
33166
|
} catch (e) {
|
|
32999
33167
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "parse", message: String(e) } }, null, 2)}
|
|
33000
33168
|
`);
|
|
33001
33169
|
process.exit(2);
|
|
33002
33170
|
}
|
|
33003
33171
|
let text2;
|
|
33004
|
-
if (args["text-file"]) text2 = await
|
|
33172
|
+
if (args["text-file"]) text2 = await readFile18(path25.resolve(String(args["text-file"])), "utf8");
|
|
33005
33173
|
else if (args.text !== void 0) text2 = String(args.text);
|
|
33006
33174
|
else {
|
|
33007
33175
|
process.stderr.write(
|
|
@@ -33022,14 +33190,14 @@ var setPromptCommand = defineCommand105({
|
|
|
33022
33190
|
process.exit(2);
|
|
33023
33191
|
return;
|
|
33024
33192
|
}
|
|
33025
|
-
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated,
|
|
33193
|
+
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path25.dirname(filePath)), defaultRegistry());
|
|
33026
33194
|
if (!validation.ok) {
|
|
33027
33195
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
|
|
33028
33196
|
`);
|
|
33029
33197
|
process.exit(2);
|
|
33030
33198
|
return;
|
|
33031
33199
|
}
|
|
33032
|
-
await
|
|
33200
|
+
await writeFile11(filePath, `${JSON.stringify(updated, null, 2)}
|
|
33033
33201
|
`, "utf8");
|
|
33034
33202
|
process.stdout.write(`${JSON.stringify({ ok: true, node: String(args.node), bytes: text2.length }, null, 2)}
|
|
33035
33203
|
`);
|
|
@@ -33037,18 +33205,18 @@ var setPromptCommand = defineCommand105({
|
|
|
33037
33205
|
});
|
|
33038
33206
|
|
|
33039
33207
|
// src/commands/canvas/validate.ts
|
|
33040
|
-
import { readFile as
|
|
33041
|
-
import
|
|
33042
|
-
import { defineCommand as
|
|
33043
|
-
var validateCommand =
|
|
33208
|
+
import { readFile as readFile19 } from "fs/promises";
|
|
33209
|
+
import path26 from "path";
|
|
33210
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
33211
|
+
var validateCommand = defineCommand107({
|
|
33044
33212
|
meta: {
|
|
33045
33213
|
name: "validate",
|
|
33046
33214
|
description: "Validate a canvas JSON file (no execution). Includes a per-node cost preview and runs each node's deep validators (composition meta checks for hyperframe_render/_snapshot)."
|
|
33047
33215
|
},
|
|
33048
33216
|
args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
|
|
33049
33217
|
async run({ args }) {
|
|
33050
|
-
const filePath =
|
|
33051
|
-
const raw = await
|
|
33218
|
+
const filePath = path26.resolve(String(args.file));
|
|
33219
|
+
const raw = await readFile19(filePath, "utf8");
|
|
33052
33220
|
let parsed;
|
|
33053
33221
|
try {
|
|
33054
33222
|
parsed = JSON.parse(raw);
|
|
@@ -33060,7 +33228,7 @@ var validateCommand = defineCommand106({
|
|
|
33060
33228
|
}
|
|
33061
33229
|
const healed = await healAbsoluteCanvasPaths(filePath, parsed);
|
|
33062
33230
|
parsed = healed.canvas;
|
|
33063
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
33231
|
+
parsed = resolveRelativeCanvasPaths(parsed, path26.dirname(filePath));
|
|
33064
33232
|
let styleProjection = "not_applicable";
|
|
33065
33233
|
try {
|
|
33066
33234
|
styleProjection = await syncStyleProjection(parsed, (line) => process.stderr.write(`${line}
|
|
@@ -33113,7 +33281,7 @@ var validateCommand = defineCommand106({
|
|
|
33113
33281
|
});
|
|
33114
33282
|
|
|
33115
33283
|
// src/commands/canvas/index.ts
|
|
33116
|
-
var canvasCommand =
|
|
33284
|
+
var canvasCommand = defineCommand108({
|
|
33117
33285
|
meta: {
|
|
33118
33286
|
name: "canvas",
|
|
33119
33287
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -33128,7 +33296,8 @@ Subcommands:
|
|
|
33128
33296
|
baker canvas sync-definition <path> \u2014 push a creative's current node-graph + input thumbnails to the dashboard without rendering (runs automatically on canvas/prompt edits)
|
|
33129
33297
|
baker canvas catalog \u2014 print the agent-facing node + composition catalog (JSON Schema)
|
|
33130
33298
|
baker canvas inspect <run_id> \u2014 one-page summary of a completed run
|
|
33131
|
-
baker canvas scaffold-
|
|
33299
|
+
baker canvas scaffold-ad --spec <spec.json> \u2014 DEFAULT for a new ad: write beats (one spoken line + one shot each), get the whole runnable canvas
|
|
33300
|
+
baker canvas scaffold-video <video> \u2014 reproduce a video the USER gave you (an ad you found is inspiration, not a copy target)
|
|
33132
33301
|
baker canvas scaffold-static-ad <image> \u2014 turn a source image into a runnable static-ad canvas (describe + element detection)
|
|
33133
33302
|
Full guide: __tooling__/docs/tools/baker/canvas.md`
|
|
33134
33303
|
},
|
|
@@ -33139,6 +33308,7 @@ Full guide: __tooling__/docs/tools/baker/canvas.md`
|
|
|
33139
33308
|
critique: critiqueCommand,
|
|
33140
33309
|
catalog: catalogCommand,
|
|
33141
33310
|
inspect: inspectCommand,
|
|
33311
|
+
"scaffold-ad": scaffoldAdCommand,
|
|
33142
33312
|
"scaffold-video": scaffoldVideoCommand,
|
|
33143
33313
|
"scaffold-static-ad": scaffoldStaticAdCommand,
|
|
33144
33314
|
"set-prompt": setPromptCommand,
|
|
@@ -33147,7 +33317,7 @@ Full guide: __tooling__/docs/tools/baker/canvas.md`
|
|
|
33147
33317
|
});
|
|
33148
33318
|
|
|
33149
33319
|
// src/commands/capabilities/index.ts
|
|
33150
|
-
import { defineCommand as
|
|
33320
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
33151
33321
|
registerSchema({
|
|
33152
33322
|
command: "capabilities",
|
|
33153
33323
|
description: "Start here, before promising the user anything on an ad platform, in Analytics, or in Tag Manager. Answers three questions in one call: what is connected and with what access, what a write on each surface actually does when it lands, and what CANNOT be done here and why. Run it with no arguments for every surface; name one surface to also get the exact fields every change on it accepts.",
|
|
@@ -33190,7 +33360,7 @@ function capabilityHints(surfaces) {
|
|
|
33190
33360
|
}
|
|
33191
33361
|
return hints;
|
|
33192
33362
|
}
|
|
33193
|
-
var runCapabilities =
|
|
33363
|
+
var runCapabilities = defineCommand109({
|
|
33194
33364
|
meta: {
|
|
33195
33365
|
name: "capabilities",
|
|
33196
33366
|
description: `What Baker can and cannot do for this company, before any work starts.
|
|
@@ -33246,7 +33416,7 @@ Full guide: __tooling__/docs/tools/baker/capabilities.md`
|
|
|
33246
33416
|
var capabilitiesCommand = runCapabilities;
|
|
33247
33417
|
|
|
33248
33418
|
// src/commands/chats/index.ts
|
|
33249
|
-
import { defineCommand as
|
|
33419
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
33250
33420
|
var STATUS_GROUPS = ["active", "archived", "all"];
|
|
33251
33421
|
var REPO_SURFACES = ["knowledge", "company", "brand", "landings", "flows", "creatives"];
|
|
33252
33422
|
function parseBoundedInt(raw, name, min, max) {
|
|
@@ -33268,7 +33438,7 @@ registerSchema({
|
|
|
33268
33438
|
full: { type: "boolean", description: "Include each Session's full change list", required: false, default: false }
|
|
33269
33439
|
}
|
|
33270
33440
|
});
|
|
33271
|
-
var listCommand11 =
|
|
33441
|
+
var listCommand11 = defineCommand110({
|
|
33272
33442
|
meta: { name: "list", description: "List other Sessions on this account, newest first." },
|
|
33273
33443
|
args: {
|
|
33274
33444
|
status: { type: "string", description: "Filter: active|archived|all (default: all)", required: false },
|
|
@@ -33323,7 +33493,7 @@ registerSchema({
|
|
|
33323
33493
|
}
|
|
33324
33494
|
}
|
|
33325
33495
|
});
|
|
33326
|
-
var viewCommand =
|
|
33496
|
+
var viewCommand = defineCommand110({
|
|
33327
33497
|
meta: {
|
|
33328
33498
|
name: "view",
|
|
33329
33499
|
description: "Inspect one Session's full effects \u2014 git content + actions/tags/ads, kickoff, commits."
|
|
@@ -33367,7 +33537,7 @@ registerSchema({
|
|
|
33367
33537
|
}
|
|
33368
33538
|
}
|
|
33369
33539
|
});
|
|
33370
|
-
var transcriptCommand =
|
|
33540
|
+
var transcriptCommand = defineCommand110({
|
|
33371
33541
|
meta: { name: "transcript", description: "Read another Session's conversation." },
|
|
33372
33542
|
args: {
|
|
33373
33543
|
id: { type: "positional", description: "The Session id", required: true },
|
|
@@ -33419,7 +33589,7 @@ registerSchema({
|
|
|
33419
33589
|
}
|
|
33420
33590
|
}
|
|
33421
33591
|
});
|
|
33422
|
-
var diffCommand =
|
|
33592
|
+
var diffCommand = defineCommand110({
|
|
33423
33593
|
meta: { name: "diff", description: "See a published Session's real file-level changes." },
|
|
33424
33594
|
args: {
|
|
33425
33595
|
id: { type: "positional", description: "The Session id", required: true },
|
|
@@ -33463,7 +33633,7 @@ var diffCommand = defineCommand109({
|
|
|
33463
33633
|
}
|
|
33464
33634
|
}
|
|
33465
33635
|
});
|
|
33466
|
-
var chatsCommand =
|
|
33636
|
+
var chatsCommand = defineCommand110({
|
|
33467
33637
|
meta: {
|
|
33468
33638
|
name: "chats",
|
|
33469
33639
|
description: `Inspect other Sessions on this account (read-only): list them, view what they produced, read their conversation, and see their real file changes \u2014 so you can reuse past work for a new goal.
|
|
@@ -33478,13 +33648,13 @@ Full guide: __tooling__/docs/tools/baker/chats.md`
|
|
|
33478
33648
|
});
|
|
33479
33649
|
|
|
33480
33650
|
// src/commands/creatives/index.ts
|
|
33481
|
-
import { defineCommand as
|
|
33651
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
33482
33652
|
|
|
33483
33653
|
// src/commands/creatives/publish.ts
|
|
33484
|
-
import { defineCommand as
|
|
33654
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
33485
33655
|
|
|
33486
33656
|
// src/commands/images/api.ts
|
|
33487
|
-
import { readFile as
|
|
33657
|
+
import { readFile as readFile20 } from "fs/promises";
|
|
33488
33658
|
import { basename, extname } from "path";
|
|
33489
33659
|
var imageProcessingTimeoutMs = 18e4;
|
|
33490
33660
|
var imageReadyPollIntervalMs = 2e3;
|
|
@@ -33498,7 +33668,7 @@ var mimeMap = {
|
|
|
33498
33668
|
".avif": "image/avif"
|
|
33499
33669
|
};
|
|
33500
33670
|
var defaultImageApiDeps = {
|
|
33501
|
-
readFile:
|
|
33671
|
+
readFile: readFile20,
|
|
33502
33672
|
post: apiPost,
|
|
33503
33673
|
get: apiGet,
|
|
33504
33674
|
sleep: (ms) => new Promise((resolve5) => setTimeout(resolve5, ms))
|
|
@@ -33628,7 +33798,7 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
33628
33798
|
chatId: chatIdFromEnv2()
|
|
33629
33799
|
});
|
|
33630
33800
|
}
|
|
33631
|
-
var publishCommand =
|
|
33801
|
+
var publishCommand = defineCommand111({
|
|
33632
33802
|
meta: {
|
|
33633
33803
|
name: "publish",
|
|
33634
33804
|
description: "Publish a final static creative image to Baker Creatives and print the creative reference JSON."
|
|
@@ -33686,7 +33856,7 @@ var publishCommand = defineCommand110({
|
|
|
33686
33856
|
});
|
|
33687
33857
|
|
|
33688
33858
|
// src/commands/creatives/index.ts
|
|
33689
|
-
var creativesCommand3 =
|
|
33859
|
+
var creativesCommand3 = defineCommand112({
|
|
33690
33860
|
meta: {
|
|
33691
33861
|
name: "creatives",
|
|
33692
33862
|
description: `Publish static ad creatives as first-class Baker outputs.
|
|
@@ -33703,11 +33873,11 @@ Full guide: __tooling__/docs/tools/baker/creatives.md`
|
|
|
33703
33873
|
});
|
|
33704
33874
|
|
|
33705
33875
|
// src/commands/flows/index.ts
|
|
33706
|
-
import { defineCommand as
|
|
33876
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
33707
33877
|
|
|
33708
33878
|
// src/commands/flows/add.ts
|
|
33709
33879
|
import { randomUUID } from "crypto";
|
|
33710
|
-
import { defineCommand as
|
|
33880
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
33711
33881
|
|
|
33712
33882
|
// src/commands/flows/shared.ts
|
|
33713
33883
|
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -33760,12 +33930,12 @@ function collectSideEffects(tree) {
|
|
|
33760
33930
|
);
|
|
33761
33931
|
}
|
|
33762
33932
|
function readFlowTree(slug) {
|
|
33763
|
-
const
|
|
33764
|
-
if (!existsSync5(
|
|
33933
|
+
const path39 = join3(flowsDir(), slug, "_data.json");
|
|
33934
|
+
if (!existsSync5(path39)) {
|
|
33765
33935
|
failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
|
|
33766
33936
|
}
|
|
33767
33937
|
try {
|
|
33768
|
-
return JSON.parse(readFileSync9(
|
|
33938
|
+
return JSON.parse(readFileSync9(path39, "utf-8"));
|
|
33769
33939
|
} catch (error) {
|
|
33770
33940
|
failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
|
|
33771
33941
|
}
|
|
@@ -33917,7 +34087,7 @@ registerSchema({
|
|
|
33917
34087
|
parent: { type: "string", description: "Parent node id. Omit to append to the root's children.", required: false }
|
|
33918
34088
|
}
|
|
33919
34089
|
});
|
|
33920
|
-
var addNodeCommand =
|
|
34090
|
+
var addNodeCommand = defineCommand113({
|
|
33921
34091
|
meta: {
|
|
33922
34092
|
name: "add-node",
|
|
33923
34093
|
description: 'Add a step to a form, with the skeleton its type requires. Example: baker flows add-node contact --type customForm --name "Contact Info"'
|
|
@@ -34013,7 +34183,7 @@ registerSchema({
|
|
|
34013
34183
|
}
|
|
34014
34184
|
}
|
|
34015
34185
|
});
|
|
34016
|
-
var addSideEffectCommand =
|
|
34186
|
+
var addSideEffectCommand = defineCommand113({
|
|
34017
34187
|
meta: {
|
|
34018
34188
|
name: "add-side-effect",
|
|
34019
34189
|
description: "Add a side effect to a step, with the skeleton its type requires. Example: baker flows add-side-effect contact --node <id> --type googleSpreadsheet"
|
|
@@ -34095,7 +34265,7 @@ var addSideEffectCommand = defineCommand112({
|
|
|
34095
34265
|
|
|
34096
34266
|
// src/commands/flows/map.ts
|
|
34097
34267
|
import { readFileSync as readFileSync11 } from "fs";
|
|
34098
|
-
import { defineCommand as
|
|
34268
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
34099
34269
|
|
|
34100
34270
|
// src/commands/flows/value-expression.ts
|
|
34101
34271
|
import { existsSync as existsSync6, readFileSync as readFileSync10 } from "fs";
|
|
@@ -34157,10 +34327,10 @@ function parseValueExpression(raw) {
|
|
|
34157
34327
|
return parts.map(parsePart);
|
|
34158
34328
|
}
|
|
34159
34329
|
function trackingFieldIds() {
|
|
34160
|
-
const
|
|
34161
|
-
if (!existsSync6(
|
|
34330
|
+
const path39 = join4(flowsDir(), "..", "tracking.ts");
|
|
34331
|
+
if (!existsSync6(path39)) return null;
|
|
34162
34332
|
try {
|
|
34163
|
-
const source = readFileSync10(
|
|
34333
|
+
const source = readFileSync10(path39, "utf-8");
|
|
34164
34334
|
const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
|
|
34165
34335
|
if (!block2) return null;
|
|
34166
34336
|
const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
|
|
@@ -34712,13 +34882,13 @@ function specsFromFile(parsed) {
|
|
|
34712
34882
|
return `${destField}${type}=${entry?.value ?? ""}`;
|
|
34713
34883
|
});
|
|
34714
34884
|
}
|
|
34715
|
-
function readSpecFile(
|
|
34885
|
+
function readSpecFile(path39) {
|
|
34716
34886
|
let raw;
|
|
34717
34887
|
try {
|
|
34718
|
-
raw =
|
|
34888
|
+
raw = path39 === "-" ? readFileSync11(0, "utf-8") : readFileSync11(path39, "utf-8");
|
|
34719
34889
|
} catch (error) {
|
|
34720
34890
|
refuse(
|
|
34721
|
-
`Could not read ${
|
|
34891
|
+
`Could not read ${path39 === "-" ? "the mapping from stdin" : `"${path39}"`}: ${error instanceof Error ? error.message : String(error)}`
|
|
34722
34892
|
);
|
|
34723
34893
|
}
|
|
34724
34894
|
let parsed;
|
|
@@ -34726,7 +34896,7 @@ function readSpecFile(path38) {
|
|
|
34726
34896
|
parsed = JSON.parse(raw);
|
|
34727
34897
|
} catch (error) {
|
|
34728
34898
|
refuse(
|
|
34729
|
-
`${
|
|
34899
|
+
`${path39 === "-" ? "stdin" : `"${path39}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
34730
34900
|
'Expected { "map": { "<destField>": "<value>", \u2026 } }'
|
|
34731
34901
|
);
|
|
34732
34902
|
}
|
|
@@ -34868,7 +35038,7 @@ async function mapOptions(args, fromFile, into) {
|
|
|
34868
35038
|
destinationFields: hubspotForm ? await hubspotFieldCatalog(hubspotForm) : void 0
|
|
34869
35039
|
};
|
|
34870
35040
|
}
|
|
34871
|
-
var mapCommand2 =
|
|
35041
|
+
var mapCommand2 = defineCommand114({
|
|
34872
35042
|
meta: {
|
|
34873
35043
|
name: "map",
|
|
34874
35044
|
description: "Map form fields onto any value a side effect sends \u2014 never hand-write a mapping. Start here: baker flows map contact --from map.json --write"
|
|
@@ -34966,7 +35136,7 @@ var mapCommand2 = defineCommand113({
|
|
|
34966
35136
|
});
|
|
34967
35137
|
|
|
34968
35138
|
// src/commands/flows/normalize.ts
|
|
34969
|
-
import { defineCommand as
|
|
35139
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
34970
35140
|
var OPTIONAL_STRINGS = ["oauthProviderId"];
|
|
34971
35141
|
var ARRAY_FIELDS = [
|
|
34972
35142
|
"fieldMapping",
|
|
@@ -34980,18 +35150,18 @@ var ARRAY_FIELDS = [
|
|
|
34980
35150
|
"tagIds"
|
|
34981
35151
|
];
|
|
34982
35152
|
var ARRAY_OWNERS = ["", "body"];
|
|
34983
|
-
function dropUnsetOptionals(sideEffect,
|
|
35153
|
+
function dropUnsetOptionals(sideEffect, path39) {
|
|
34984
35154
|
return OPTIONAL_STRINGS.flatMap((key) => {
|
|
34985
35155
|
if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
|
|
34986
35156
|
delete sideEffect[key];
|
|
34987
|
-
return [{ path:
|
|
35157
|
+
return [{ path: path39, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
|
|
34988
35158
|
});
|
|
34989
35159
|
}
|
|
34990
|
-
function fillNulledArrays(target, prefix,
|
|
35160
|
+
function fillNulledArrays(target, prefix, path39) {
|
|
34991
35161
|
return ARRAY_FIELDS.flatMap((key) => {
|
|
34992
35162
|
if (!(key in target) || target[key] !== null) return [];
|
|
34993
35163
|
target[key] = [];
|
|
34994
|
-
return [{ path:
|
|
35164
|
+
return [{ path: path39, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
|
|
34995
35165
|
});
|
|
34996
35166
|
}
|
|
34997
35167
|
function sideEffectsOf(node) {
|
|
@@ -35001,13 +35171,13 @@ function sideEffectsOf(node) {
|
|
|
35001
35171
|
);
|
|
35002
35172
|
}
|
|
35003
35173
|
function normalizeSideEffect(sideEffect, where) {
|
|
35004
|
-
const
|
|
35174
|
+
const path39 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
|
|
35005
35175
|
const arrays = ARRAY_OWNERS.flatMap((owner) => {
|
|
35006
35176
|
const target = owner ? sideEffect[owner] : sideEffect;
|
|
35007
35177
|
if (!target || typeof target !== "object") return [];
|
|
35008
|
-
return fillNulledArrays(target, owner ? `${owner}.` : "",
|
|
35178
|
+
return fillNulledArrays(target, owner ? `${owner}.` : "", path39);
|
|
35009
35179
|
});
|
|
35010
|
-
return [...dropUnsetOptionals(sideEffect,
|
|
35180
|
+
return [...dropUnsetOptionals(sideEffect, path39), ...arrays];
|
|
35011
35181
|
}
|
|
35012
35182
|
function normalizeFlowTree(tree) {
|
|
35013
35183
|
const changes = [];
|
|
@@ -35035,7 +35205,7 @@ registerSchema({
|
|
|
35035
35205
|
}
|
|
35036
35206
|
}
|
|
35037
35207
|
});
|
|
35038
|
-
var normalizeCommand =
|
|
35208
|
+
var normalizeCommand = defineCommand115({
|
|
35039
35209
|
meta: {
|
|
35040
35210
|
name: "normalize",
|
|
35041
35211
|
description: "Repair the shapes a form file is allowed to get slightly wrong. Example: baker flows normalize contact --write"
|
|
@@ -35066,7 +35236,7 @@ var normalizeCommand = defineCommand114({
|
|
|
35066
35236
|
});
|
|
35067
35237
|
|
|
35068
35238
|
// src/commands/flows/schema.ts
|
|
35069
|
-
import { defineCommand as
|
|
35239
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
35070
35240
|
registerSchema({
|
|
35071
35241
|
command: "flows.schema",
|
|
35072
35242
|
description: "The shape of one node or side-effect type: a pasteable skeleton, who fills each part, and the reference file with the craft. Start here before authoring anything in a form's _data.json.",
|
|
@@ -35091,7 +35261,7 @@ function triggerHints(triggers) {
|
|
|
35091
35261
|
`A side effect on this step carries \`triggerId: "${triggers.completion}"\`, and \`baker flows add-side-effect\` writes it for you. The trigger belongs to the STEP, not to the side-effect type: one that does not match is valid, ships, and never runs.` + (others.length > 0 ? ` Other moments this step raises: ${others.join(", ")}.` : "")
|
|
35092
35262
|
];
|
|
35093
35263
|
}
|
|
35094
|
-
var schemaCommand =
|
|
35264
|
+
var schemaCommand = defineCommand116({
|
|
35095
35265
|
meta: {
|
|
35096
35266
|
name: "schema",
|
|
35097
35267
|
description: "Show a node or side-effect type's shape. Start here: baker flows schema node customForm \xB7 baker flows schema side-effect googleSpreadsheet \xB7 baker flows schema (lists both)"
|
|
@@ -35225,7 +35395,7 @@ function displayName(slug) {
|
|
|
35225
35395
|
const name = tree.displayName;
|
|
35226
35396
|
return typeof name === "string" && name.trim() ? name.trim() : slug;
|
|
35227
35397
|
}
|
|
35228
|
-
var listCommand12 =
|
|
35398
|
+
var listCommand12 = defineCommand117({
|
|
35229
35399
|
meta: {
|
|
35230
35400
|
name: "list",
|
|
35231
35401
|
description: "List Forms in this workspace with the count of confidential fields still needing setup. Example: baker flows list"
|
|
@@ -35246,7 +35416,7 @@ var listCommand12 = defineCommand116({
|
|
|
35246
35416
|
});
|
|
35247
35417
|
}
|
|
35248
35418
|
});
|
|
35249
|
-
var showCommand3 =
|
|
35419
|
+
var showCommand3 = defineCommand117({
|
|
35250
35420
|
meta: {
|
|
35251
35421
|
name: "show",
|
|
35252
35422
|
description: "Show a Form's confidential fields and their configuration status (never secret values). Example: baker flows show contact"
|
|
@@ -35274,7 +35444,7 @@ var showCommand3 = defineCommand116({
|
|
|
35274
35444
|
});
|
|
35275
35445
|
}
|
|
35276
35446
|
});
|
|
35277
|
-
var flowsCommand =
|
|
35447
|
+
var flowsCommand = defineCommand117({
|
|
35278
35448
|
meta: {
|
|
35279
35449
|
name: "flows",
|
|
35280
35450
|
description: `Read and shape this workspace's Forms (flows).
|
|
@@ -35308,10 +35478,10 @@ Full guide: __tooling__/docs/tools/baker/flows.md`
|
|
|
35308
35478
|
});
|
|
35309
35479
|
|
|
35310
35480
|
// src/commands/ga4/index.ts
|
|
35311
|
-
import { defineCommand as
|
|
35481
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
35312
35482
|
|
|
35313
35483
|
// src/commands/ga4/audit.ts
|
|
35314
|
-
import { defineCommand as
|
|
35484
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
35315
35485
|
|
|
35316
35486
|
// src/commands/ga4/resolve.ts
|
|
35317
35487
|
async function fetchProperties(useCache = true) {
|
|
@@ -35377,7 +35547,7 @@ registerSchema({
|
|
|
35377
35547
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
35378
35548
|
}
|
|
35379
35549
|
});
|
|
35380
|
-
var auditCommand2 =
|
|
35550
|
+
var auditCommand2 = defineCommand118({
|
|
35381
35551
|
meta: {
|
|
35382
35552
|
name: "audit",
|
|
35383
35553
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -35432,7 +35602,7 @@ Examples:
|
|
|
35432
35602
|
});
|
|
35433
35603
|
|
|
35434
35604
|
// src/commands/ga4/config.ts
|
|
35435
|
-
import { defineCommand as
|
|
35605
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
35436
35606
|
|
|
35437
35607
|
// src/commands/ga4/shared.ts
|
|
35438
35608
|
import { readFileSync as readFileSync12 } from "fs";
|
|
@@ -35545,10 +35715,10 @@ async function stageOps(ops) {
|
|
|
35545
35715
|
handleError2(err);
|
|
35546
35716
|
}
|
|
35547
35717
|
}
|
|
35548
|
-
async function draftAction2(
|
|
35718
|
+
async function draftAction2(path39, body, chat) {
|
|
35549
35719
|
const chatId = resolveChatId(chat);
|
|
35550
35720
|
try {
|
|
35551
|
-
const data = await apiPost(
|
|
35721
|
+
const data = await apiPost(path39, { chatId, ...body });
|
|
35552
35722
|
writeJsonEnvelope({ ok: true, data });
|
|
35553
35723
|
return data;
|
|
35554
35724
|
} catch (err) {
|
|
@@ -35628,7 +35798,7 @@ function configHints(config) {
|
|
|
35628
35798
|
}
|
|
35629
35799
|
return hints;
|
|
35630
35800
|
}
|
|
35631
|
-
var configCommand =
|
|
35801
|
+
var configCommand = defineCommand119({
|
|
35632
35802
|
meta: {
|
|
35633
35803
|
name: "config",
|
|
35634
35804
|
description: `Read how the property is configured to measure \u2014 key events, custom definitions, custom events, retention
|
|
@@ -35660,7 +35830,7 @@ Examples:
|
|
|
35660
35830
|
});
|
|
35661
35831
|
|
|
35662
35832
|
// src/commands/ga4/draft.ts
|
|
35663
|
-
import { defineCommand as
|
|
35833
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
35664
35834
|
registerSchema({
|
|
35665
35835
|
command: "ga4.draft",
|
|
35666
35836
|
description: "Review and undo the Google Analytics changes staged on this chat. Use `list` to see everything staged, `show` to inspect one change in full before the chat completes, `amend` to correct one in place, and `remove`/`clear` to drop them. `list` and `show` take --chat <id> to read an earlier chat's changes instead.",
|
|
@@ -35669,13 +35839,13 @@ registerSchema({
|
|
|
35669
35839
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
35670
35840
|
}
|
|
35671
35841
|
});
|
|
35672
|
-
var draftCommand3 =
|
|
35842
|
+
var draftCommand3 = defineCommand120({
|
|
35673
35843
|
meta: {
|
|
35674
35844
|
name: "draft",
|
|
35675
35845
|
description: "List, show, amend, remove or clear the Google Analytics changes staged on this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
|
|
35676
35846
|
},
|
|
35677
35847
|
subCommands: {
|
|
35678
|
-
list:
|
|
35848
|
+
list: defineCommand120({
|
|
35679
35849
|
meta: { name: "list", description: "Review everything staged on this chat (--json for the raw envelope)" },
|
|
35680
35850
|
args: {
|
|
35681
35851
|
json: { type: "boolean", description: "Print the raw JSON envelope", required: false },
|
|
@@ -35685,7 +35855,7 @@ var draftCommand3 = defineCommand119({
|
|
|
35685
35855
|
await draftList(args.json === true, args.chat);
|
|
35686
35856
|
}
|
|
35687
35857
|
}),
|
|
35688
|
-
show:
|
|
35858
|
+
show: defineCommand120({
|
|
35689
35859
|
meta: {
|
|
35690
35860
|
name: "show",
|
|
35691
35861
|
description: "Print the full staged payload for one change, alongside how the property looks today \u2014 the receipt to verify it before the chat completes (never truncated)."
|
|
@@ -35702,7 +35872,7 @@ var draftCommand3 = defineCommand119({
|
|
|
35702
35872
|
);
|
|
35703
35873
|
}
|
|
35704
35874
|
}),
|
|
35705
|
-
amend:
|
|
35875
|
+
amend: defineCommand120({
|
|
35706
35876
|
meta: {
|
|
35707
35877
|
name: "amend",
|
|
35708
35878
|
description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-runs every check. Use this instead of remove + re-create."
|
|
@@ -35719,7 +35889,7 @@ var draftCommand3 = defineCommand119({
|
|
|
35719
35889
|
});
|
|
35720
35890
|
}
|
|
35721
35891
|
}),
|
|
35722
|
-
remove:
|
|
35892
|
+
remove: defineCommand120({
|
|
35723
35893
|
meta: { name: "remove", description: "Remove one staged change" },
|
|
35724
35894
|
args: { ref: { type: "positional", description: "Staged ref or target id", required: false } },
|
|
35725
35895
|
run: async ({ args }) => {
|
|
@@ -35728,7 +35898,7 @@ var draftCommand3 = defineCommand119({
|
|
|
35728
35898
|
});
|
|
35729
35899
|
}
|
|
35730
35900
|
}),
|
|
35731
|
-
clear:
|
|
35901
|
+
clear: defineCommand120({
|
|
35732
35902
|
meta: { name: "clear", description: "Discard all Google Analytics changes staged on this chat" },
|
|
35733
35903
|
run: async () => {
|
|
35734
35904
|
await draftAction2("/api/ga4/draft/clear", {});
|
|
@@ -35738,7 +35908,7 @@ var draftCommand3 = defineCommand119({
|
|
|
35738
35908
|
});
|
|
35739
35909
|
|
|
35740
35910
|
// src/commands/ga4/properties.ts
|
|
35741
|
-
import { defineCommand as
|
|
35911
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
35742
35912
|
registerSchema({
|
|
35743
35913
|
command: "ga4.properties",
|
|
35744
35914
|
description: "List the GA4 properties this company connected \u2014 there can be several, and every one of them is yours to query. Returns the property IDs the query and audit commands take. Run this first to find property IDs.",
|
|
@@ -35754,7 +35924,7 @@ function propertyHints(properties) {
|
|
|
35754
35924
|
resources: properties.map((property) => ({ id: property.externalId, label: property.name }))
|
|
35755
35925
|
});
|
|
35756
35926
|
}
|
|
35757
|
-
var propertiesCommand =
|
|
35927
|
+
var propertiesCommand = defineCommand121({
|
|
35758
35928
|
meta: {
|
|
35759
35929
|
name: "properties",
|
|
35760
35930
|
description: `List accessible GA4 properties.
|
|
@@ -35804,7 +35974,7 @@ Examples:
|
|
|
35804
35974
|
// src/commands/ga4/query.ts
|
|
35805
35975
|
import { appendFileSync as appendFileSync2, existsSync as existsSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
|
|
35806
35976
|
import { resolve as resolve2 } from "path";
|
|
35807
|
-
import { defineCommand as
|
|
35977
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
35808
35978
|
|
|
35809
35979
|
// src/commands/ga4/presets.ts
|
|
35810
35980
|
var GA4_PRESETS = [
|
|
@@ -35939,7 +36109,7 @@ function handleError3(err) {
|
|
|
35939
36109
|
});
|
|
35940
36110
|
process.exit(1);
|
|
35941
36111
|
}
|
|
35942
|
-
var queryCommand2 =
|
|
36112
|
+
var queryCommand2 = defineCommand122({
|
|
35943
36113
|
meta: {
|
|
35944
36114
|
name: "query",
|
|
35945
36115
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -36010,7 +36180,7 @@ Free-form (escape hatch):
|
|
|
36010
36180
|
});
|
|
36011
36181
|
|
|
36012
36182
|
// src/commands/ga4/write-commands.ts
|
|
36013
|
-
import { defineCommand as
|
|
36183
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
36014
36184
|
var PROPERTY_ARG_DESCRIPTION = "GA4 property id (optional only when one property is connected \u2014 run `baker ga4 properties`)";
|
|
36015
36185
|
var propertyArg = { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false };
|
|
36016
36186
|
function createJsonDescription(noun) {
|
|
@@ -36028,7 +36198,7 @@ registerSchema({
|
|
|
36028
36198
|
"property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
|
|
36029
36199
|
}
|
|
36030
36200
|
});
|
|
36031
|
-
var keyEventCommand =
|
|
36201
|
+
var keyEventCommand = defineCommand123({
|
|
36032
36202
|
meta: {
|
|
36033
36203
|
name: "key-event",
|
|
36034
36204
|
description: `Stage key-event (conversion) changes
|
|
@@ -36041,7 +36211,7 @@ Examples:
|
|
|
36041
36211
|
baker ga4 key-event delete 4185`
|
|
36042
36212
|
},
|
|
36043
36213
|
subCommands: {
|
|
36044
|
-
create:
|
|
36214
|
+
create: defineCommand123({
|
|
36045
36215
|
meta: {
|
|
36046
36216
|
name: "create",
|
|
36047
36217
|
description: "Stage a new key event. Needs eventName and countingMethod (ONCE_PER_EVENT or ONCE_PER_SESSION); defaultValue sets a monetary value when the event does not send one."
|
|
@@ -36062,7 +36232,7 @@ Examples:
|
|
|
36062
36232
|
);
|
|
36063
36233
|
}
|
|
36064
36234
|
}),
|
|
36065
|
-
update:
|
|
36235
|
+
update: defineCommand123({
|
|
36066
36236
|
meta: {
|
|
36067
36237
|
name: "update",
|
|
36068
36238
|
description: "Stage a change to an existing key event (pass its id). Only countingMethod and defaultValue can change \u2014 Google will not rename a key event."
|
|
@@ -36082,7 +36252,7 @@ Examples:
|
|
|
36082
36252
|
});
|
|
36083
36253
|
}
|
|
36084
36254
|
}),
|
|
36085
|
-
delete:
|
|
36255
|
+
delete: defineCommand123({
|
|
36086
36256
|
meta: {
|
|
36087
36257
|
name: "delete",
|
|
36088
36258
|
description: "Stage removing a key event, so the event stops counting as a conversion. The event itself keeps being collected. Irreversible once the chat completes \u2014 confirm with the user first."
|
|
@@ -36130,7 +36300,7 @@ for (const { kind, noun, createHint } of DEFINITIONS) {
|
|
|
36130
36300
|
}
|
|
36131
36301
|
function definitionCommand(definition) {
|
|
36132
36302
|
const { command, kind, noun, example } = definition;
|
|
36133
|
-
return
|
|
36303
|
+
return defineCommand123({
|
|
36134
36304
|
meta: {
|
|
36135
36305
|
name: command,
|
|
36136
36306
|
description: `Stage ${noun} changes
|
|
@@ -36142,7 +36312,7 @@ Examples:
|
|
|
36142
36312
|
baker ga4 ${command} archive 12`
|
|
36143
36313
|
},
|
|
36144
36314
|
subCommands: {
|
|
36145
|
-
create:
|
|
36315
|
+
create: defineCommand123({
|
|
36146
36316
|
meta: { name: "create", description: `Stage a new ${noun} (or a JSON array of them, staged together)` },
|
|
36147
36317
|
args: {
|
|
36148
36318
|
json: { type: "string", description: createJsonDescription(noun), required: false },
|
|
@@ -36160,7 +36330,7 @@ Examples:
|
|
|
36160
36330
|
);
|
|
36161
36331
|
}
|
|
36162
36332
|
}),
|
|
36163
|
-
update:
|
|
36333
|
+
update: defineCommand123({
|
|
36164
36334
|
meta: {
|
|
36165
36335
|
name: "update",
|
|
36166
36336
|
description: `Stage a change to an existing ${noun} (pass its id). The parameter name and scope cannot change \u2014 archive and recreate for that.`
|
|
@@ -36180,7 +36350,7 @@ Examples:
|
|
|
36180
36350
|
});
|
|
36181
36351
|
}
|
|
36182
36352
|
}),
|
|
36183
|
-
archive:
|
|
36353
|
+
archive: defineCommand123({
|
|
36184
36354
|
meta: {
|
|
36185
36355
|
name: "archive",
|
|
36186
36356
|
description: `Stage archiving a ${noun} (pass its id). It stops collecting and leaves reporting; past data stays. Irreversible once the chat completes \u2014 confirm with the user first.`
|
|
@@ -36225,7 +36395,7 @@ var dataStreamArg = {
|
|
|
36225
36395
|
function withStream(args) {
|
|
36226
36396
|
return typeof args["data-stream"] === "string" ? { dataStream: args["data-stream"] } : {};
|
|
36227
36397
|
}
|
|
36228
|
-
var customEventCommand =
|
|
36398
|
+
var customEventCommand = defineCommand123({
|
|
36229
36399
|
meta: {
|
|
36230
36400
|
name: "custom-event",
|
|
36231
36401
|
description: `Stage custom events \u2014 new events built from events the site already sends
|
|
@@ -36236,7 +36406,7 @@ Examples:
|
|
|
36236
36406
|
baker ga4 custom-event delete 7`
|
|
36237
36407
|
},
|
|
36238
36408
|
subCommands: {
|
|
36239
|
-
create:
|
|
36409
|
+
create: defineCommand123({
|
|
36240
36410
|
meta: {
|
|
36241
36411
|
name: "create",
|
|
36242
36412
|
description: "Stage a new custom event. Conditions match the source event: use field `event_name` to match the event itself, or any parameter name to match its value."
|
|
@@ -36259,7 +36429,7 @@ Examples:
|
|
|
36259
36429
|
);
|
|
36260
36430
|
}
|
|
36261
36431
|
}),
|
|
36262
|
-
update:
|
|
36432
|
+
update: defineCommand123({
|
|
36263
36433
|
meta: { name: "update", description: "Stage a change to an existing custom event (pass its id)" },
|
|
36264
36434
|
args: {
|
|
36265
36435
|
id: { type: "positional", description: "Custom event rule id", required: false },
|
|
@@ -36278,7 +36448,7 @@ Examples:
|
|
|
36278
36448
|
});
|
|
36279
36449
|
}
|
|
36280
36450
|
}),
|
|
36281
|
-
delete:
|
|
36451
|
+
delete: defineCommand123({
|
|
36282
36452
|
meta: {
|
|
36283
36453
|
name: "delete",
|
|
36284
36454
|
description: "Stage removing a custom event (pass its id). The event stops being created from then on; data already collected under it stays. Confirm with the user first."
|
|
@@ -36333,7 +36503,7 @@ function booleanArg(input, flag) {
|
|
|
36333
36503
|
if (input === "false") return false;
|
|
36334
36504
|
return failValidation3(`--${flag} must be true or false`);
|
|
36335
36505
|
}
|
|
36336
|
-
var dataRetentionCommand =
|
|
36506
|
+
var dataRetentionCommand = defineCommand123({
|
|
36337
36507
|
meta: {
|
|
36338
36508
|
name: "data-retention",
|
|
36339
36509
|
description: `Stage a change to how long Google Analytics keeps data
|
|
@@ -36343,7 +36513,7 @@ Examples:
|
|
|
36343
36513
|
baker ga4 data-retention set --event-data 14 --user-data 14 --reset-on-activity true`
|
|
36344
36514
|
},
|
|
36345
36515
|
subCommands: {
|
|
36346
|
-
set:
|
|
36516
|
+
set: defineCommand123({
|
|
36347
36517
|
meta: { name: "set", description: "Stage the retention window (months)" },
|
|
36348
36518
|
args: {
|
|
36349
36519
|
"event-data": { type: "string", description: "2, 14, 26, 38 or 50", required: false },
|
|
@@ -36379,7 +36549,7 @@ registerSchema({
|
|
|
36379
36549
|
"property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
|
|
36380
36550
|
}
|
|
36381
36551
|
});
|
|
36382
|
-
var audienceCommand =
|
|
36552
|
+
var audienceCommand = defineCommand123({
|
|
36383
36553
|
meta: {
|
|
36384
36554
|
name: "audience",
|
|
36385
36555
|
description: `Stage audience changes (saved groups of users, for retargeting and analysis)
|
|
@@ -36411,7 +36581,7 @@ Examples:
|
|
|
36411
36581
|
baker ga4 audience archive 8813`
|
|
36412
36582
|
},
|
|
36413
36583
|
subCommands: {
|
|
36414
|
-
create:
|
|
36584
|
+
create: defineCommand123({
|
|
36415
36585
|
meta: { name: "create", description: createJsonDescription("audience") },
|
|
36416
36586
|
args: {
|
|
36417
36587
|
json: { type: "string", description: createJsonDescription("audience"), required: false },
|
|
@@ -36429,7 +36599,7 @@ Examples:
|
|
|
36429
36599
|
);
|
|
36430
36600
|
}
|
|
36431
36601
|
}),
|
|
36432
|
-
update:
|
|
36602
|
+
update: defineCommand123({
|
|
36433
36603
|
meta: {
|
|
36434
36604
|
name: "update",
|
|
36435
36605
|
description: "Stage a new name or description (pass the audience id). Who is in it cannot be changed."
|
|
@@ -36450,7 +36620,7 @@ Examples:
|
|
|
36450
36620
|
});
|
|
36451
36621
|
}
|
|
36452
36622
|
}),
|
|
36453
|
-
archive:
|
|
36623
|
+
archive: defineCommand123({
|
|
36454
36624
|
meta: {
|
|
36455
36625
|
name: "archive",
|
|
36456
36626
|
description: "Stage retiring an audience. Cannot be undone \u2014 the users it gathered do not come back."
|
|
@@ -36479,7 +36649,7 @@ registerSchema({
|
|
|
36479
36649
|
"property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
|
|
36480
36650
|
}
|
|
36481
36651
|
});
|
|
36482
|
-
var propertyCommand =
|
|
36652
|
+
var propertyCommand = defineCommand123({
|
|
36483
36653
|
meta: {
|
|
36484
36654
|
name: "property",
|
|
36485
36655
|
description: `Stage a change to the property's own settings
|
|
@@ -36489,7 +36659,7 @@ Examples:
|
|
|
36489
36659
|
baker ga4 property set --name "Acme \u2014 Web" --industry REAL_ESTATE`
|
|
36490
36660
|
},
|
|
36491
36661
|
subCommands: {
|
|
36492
|
-
set:
|
|
36662
|
+
set: defineCommand123({
|
|
36493
36663
|
meta: { name: "set", description: "Stage the property name and/or industry category" },
|
|
36494
36664
|
args: {
|
|
36495
36665
|
name: { type: "string", description: "New property display name", required: false },
|
|
@@ -36529,7 +36699,7 @@ registerSchema({
|
|
|
36529
36699
|
"property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
|
|
36530
36700
|
}
|
|
36531
36701
|
});
|
|
36532
|
-
var adsLinkCommand =
|
|
36702
|
+
var adsLinkCommand = defineCommand123({
|
|
36533
36703
|
meta: {
|
|
36534
36704
|
name: "ads-link",
|
|
36535
36705
|
description: `Stage linking this property to a Google Ads account
|
|
@@ -36544,7 +36714,7 @@ Examples:
|
|
|
36544
36714
|
baker ga4 ads-link delete L1234`
|
|
36545
36715
|
},
|
|
36546
36716
|
subCommands: {
|
|
36547
|
-
create:
|
|
36717
|
+
create: defineCommand123({
|
|
36548
36718
|
meta: { name: "create", description: "Stage linking the property to a Google Ads account" },
|
|
36549
36719
|
args: {
|
|
36550
36720
|
"customer-id": { type: "string", description: "Google Ads customer id (123-456-7890)", required: false },
|
|
@@ -36563,7 +36733,7 @@ Examples:
|
|
|
36563
36733
|
await stageOp3({ kind: "ga4.googleAdsLink.create", payload, ...withProperty(args) });
|
|
36564
36734
|
}
|
|
36565
36735
|
}),
|
|
36566
|
-
update:
|
|
36736
|
+
update: defineCommand123({
|
|
36567
36737
|
meta: {
|
|
36568
36738
|
name: "update",
|
|
36569
36739
|
description: "Stage the ads-personalisation setting on an existing link (pass its id)"
|
|
@@ -36585,7 +36755,7 @@ Examples:
|
|
|
36585
36755
|
});
|
|
36586
36756
|
}
|
|
36587
36757
|
}),
|
|
36588
|
-
delete:
|
|
36758
|
+
delete: defineCommand123({
|
|
36589
36759
|
meta: {
|
|
36590
36760
|
name: "delete",
|
|
36591
36761
|
description: "Stage unlinking. Stops conversion imports and strands every audience on this property."
|
|
@@ -36636,7 +36806,7 @@ var MEASUREMENT_FLAGS = {
|
|
|
36636
36806
|
"page-changes": "pageChangesEnabled",
|
|
36637
36807
|
"form-interactions": "formInteractionsEnabled"
|
|
36638
36808
|
};
|
|
36639
|
-
var enhancedMeasurementCommand =
|
|
36809
|
+
var enhancedMeasurementCommand = defineCommand123({
|
|
36640
36810
|
meta: {
|
|
36641
36811
|
name: "enhanced-measurement",
|
|
36642
36812
|
description: `Stage the automatic events GA4 collects on a website stream
|
|
@@ -36650,7 +36820,7 @@ Examples:
|
|
|
36650
36820
|
baker ga4 enhanced-measurement set --video false`
|
|
36651
36821
|
},
|
|
36652
36822
|
subCommands: {
|
|
36653
|
-
set:
|
|
36823
|
+
set: defineCommand123({
|
|
36654
36824
|
meta: { name: "set", description: "Stage which automatic events the website stream collects" },
|
|
36655
36825
|
args: {
|
|
36656
36826
|
scrolls: { type: "string", description: "true|false", required: false },
|
|
@@ -36693,7 +36863,7 @@ Examples:
|
|
|
36693
36863
|
});
|
|
36694
36864
|
|
|
36695
36865
|
// src/commands/ga4/index.ts
|
|
36696
|
-
var ga4Command =
|
|
36866
|
+
var ga4Command = defineCommand124({
|
|
36697
36867
|
meta: {
|
|
36698
36868
|
name: "ga4",
|
|
36699
36869
|
description: `Google Analytics 4. Report on a property, audit its config, and change what it measures.
|
|
@@ -36742,12 +36912,12 @@ Full guide: __tooling__/docs/tools/baker/ga4.md`
|
|
|
36742
36912
|
});
|
|
36743
36913
|
|
|
36744
36914
|
// src/commands/gsc/index.ts
|
|
36745
|
-
import { defineCommand as
|
|
36915
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
36746
36916
|
|
|
36747
36917
|
// src/commands/gsc/query.ts
|
|
36748
36918
|
import { appendFileSync as appendFileSync3, existsSync as existsSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync5 } from "fs";
|
|
36749
36919
|
import { resolve as resolve3 } from "path";
|
|
36750
|
-
import { defineCommand as
|
|
36920
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
36751
36921
|
|
|
36752
36922
|
// src/commands/gsc/presets.ts
|
|
36753
36923
|
var GSC_PRESETS = [
|
|
@@ -36941,7 +37111,7 @@ function handleError4(err) {
|
|
|
36941
37111
|
});
|
|
36942
37112
|
process.exit(1);
|
|
36943
37113
|
}
|
|
36944
|
-
var queryCommand3 =
|
|
37114
|
+
var queryCommand3 = defineCommand125({
|
|
36945
37115
|
meta: {
|
|
36946
37116
|
name: "query",
|
|
36947
37117
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -37019,7 +37189,7 @@ Free-form (escape hatch):
|
|
|
37019
37189
|
});
|
|
37020
37190
|
|
|
37021
37191
|
// src/commands/gsc/sitemaps.ts
|
|
37022
|
-
import { defineCommand as
|
|
37192
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
37023
37193
|
registerSchema({
|
|
37024
37194
|
command: "gsc.sitemaps",
|
|
37025
37195
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -37028,7 +37198,7 @@ registerSchema({
|
|
|
37028
37198
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
37029
37199
|
}
|
|
37030
37200
|
});
|
|
37031
|
-
var sitemapsCommand =
|
|
37201
|
+
var sitemapsCommand = defineCommand126({
|
|
37032
37202
|
meta: {
|
|
37033
37203
|
name: "sitemaps",
|
|
37034
37204
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -37081,7 +37251,7 @@ Examples:
|
|
|
37081
37251
|
});
|
|
37082
37252
|
|
|
37083
37253
|
// src/commands/gsc/sites.ts
|
|
37084
|
-
import { defineCommand as
|
|
37254
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
37085
37255
|
registerSchema({
|
|
37086
37256
|
command: "gsc.sites",
|
|
37087
37257
|
description: "List the Search Console sites this company connected \u2014 there can be several, and every one of them is yours to query. Returns the site URLs the query and sitemaps commands take.",
|
|
@@ -37097,7 +37267,7 @@ function siteHints(sites) {
|
|
|
37097
37267
|
resources: sites.map((site) => ({ id: site.siteUrl, label: site.permissionLevel }))
|
|
37098
37268
|
});
|
|
37099
37269
|
}
|
|
37100
|
-
var sitesCommand =
|
|
37270
|
+
var sitesCommand = defineCommand127({
|
|
37101
37271
|
meta: {
|
|
37102
37272
|
name: "sites",
|
|
37103
37273
|
description: `List verified Search Console sites.
|
|
@@ -37145,7 +37315,7 @@ Examples:
|
|
|
37145
37315
|
});
|
|
37146
37316
|
|
|
37147
37317
|
// src/commands/gsc/index.ts
|
|
37148
|
-
var gscCommand =
|
|
37318
|
+
var gscCommand = defineCommand128({
|
|
37149
37319
|
meta: {
|
|
37150
37320
|
name: "gsc",
|
|
37151
37321
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -37169,7 +37339,7 @@ Full guide: __tooling__/docs/tools/baker/gsc.md`
|
|
|
37169
37339
|
});
|
|
37170
37340
|
|
|
37171
37341
|
// src/commands/history/index.ts
|
|
37172
|
-
import { defineCommand as
|
|
37342
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
37173
37343
|
registerSchema({
|
|
37174
37344
|
command: "history.list",
|
|
37175
37345
|
description: "Start here: unified account history (audit log) \u2014 everything that changed on this account, newest first: publishes, chat lifecycle, backlog actions, team changes, setup links, tags, schedules, ad-platform writes, followed advertisers, media, creatives, reports, domains, and integrations. Use it to see what happened recently before planning work. Compact by default; add --full for raw metadata per entry.",
|
|
@@ -37224,7 +37394,7 @@ function parseBoundedInt2(raw, name, min, max) {
|
|
|
37224
37394
|
}
|
|
37225
37395
|
return value;
|
|
37226
37396
|
}
|
|
37227
|
-
var listCommand13 =
|
|
37397
|
+
var listCommand13 = defineCommand129({
|
|
37228
37398
|
meta: {
|
|
37229
37399
|
name: "list",
|
|
37230
37400
|
description: "List recent account changes (unified audit log), newest first."
|
|
@@ -37270,7 +37440,7 @@ var listCommand13 = defineCommand128({
|
|
|
37270
37440
|
}
|
|
37271
37441
|
}
|
|
37272
37442
|
});
|
|
37273
|
-
var historyCommand =
|
|
37443
|
+
var historyCommand = defineCommand129({
|
|
37274
37444
|
meta: {
|
|
37275
37445
|
name: "history",
|
|
37276
37446
|
description: `Unified account history (audit log): what changed, who did it, and when.
|
|
@@ -37280,7 +37450,7 @@ Full guide: __tooling__/docs/tools/baker/history.md`
|
|
|
37280
37450
|
});
|
|
37281
37451
|
|
|
37282
37452
|
// src/commands/hubspot/index.ts
|
|
37283
|
-
import { defineCommand as
|
|
37453
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
37284
37454
|
var EMBED_TYPES = ["legacy", "v4", "unknown"];
|
|
37285
37455
|
function failNotConnected(err) {
|
|
37286
37456
|
if (err instanceof ApiError && err.code === "FORBIDDEN" && err.message.includes(HUBSPOT_MISSING_GRANT_MARKER)) {
|
|
@@ -37434,7 +37604,7 @@ registerSchema({
|
|
|
37434
37604
|
}
|
|
37435
37605
|
}
|
|
37436
37606
|
});
|
|
37437
|
-
var formsListCommand =
|
|
37607
|
+
var formsListCommand = defineCommand130({
|
|
37438
37608
|
meta: {
|
|
37439
37609
|
name: "list",
|
|
37440
37610
|
description: "List HubSpot forms with embed type and post-submit action. Example: baker hubspot forms list --redirecting-only"
|
|
@@ -37479,7 +37649,7 @@ var formsListCommand = defineCommand129({
|
|
|
37479
37649
|
}
|
|
37480
37650
|
}
|
|
37481
37651
|
});
|
|
37482
|
-
var formsViewCommand =
|
|
37652
|
+
var formsViewCommand = defineCommand130({
|
|
37483
37653
|
meta: {
|
|
37484
37654
|
name: "view",
|
|
37485
37655
|
description: "Show one HubSpot form's fields and configuration. Example: baker hubspot forms view 1a2b3c"
|
|
@@ -37531,7 +37701,7 @@ var formsViewCommand = defineCommand129({
|
|
|
37531
37701
|
}
|
|
37532
37702
|
}
|
|
37533
37703
|
});
|
|
37534
|
-
var meetingsListCommand =
|
|
37704
|
+
var meetingsListCommand = defineCommand130({
|
|
37535
37705
|
meta: {
|
|
37536
37706
|
name: "list",
|
|
37537
37707
|
description: "List HubSpot meeting links (calendars). Example: baker hubspot meetings list"
|
|
@@ -37573,7 +37743,7 @@ var meetingsListCommand = defineCommand129({
|
|
|
37573
37743
|
}
|
|
37574
37744
|
}
|
|
37575
37745
|
});
|
|
37576
|
-
var meetingsViewCommand =
|
|
37746
|
+
var meetingsViewCommand = defineCommand130({
|
|
37577
37747
|
meta: {
|
|
37578
37748
|
name: "view",
|
|
37579
37749
|
description: "Show one HubSpot meeting link's booking fields. Example: baker hubspot meetings view discovery-call"
|
|
@@ -37617,7 +37787,7 @@ var meetingsViewCommand = defineCommand129({
|
|
|
37617
37787
|
}
|
|
37618
37788
|
}
|
|
37619
37789
|
});
|
|
37620
|
-
var formsSubmissionsCommand =
|
|
37790
|
+
var formsSubmissionsCommand = defineCommand130({
|
|
37621
37791
|
meta: {
|
|
37622
37792
|
name: "submissions",
|
|
37623
37793
|
description: "How many leads a form received, and when. Example: baker hubspot forms submissions <formId> --days 30"
|
|
@@ -37666,7 +37836,7 @@ var formsSubmissionsCommand = defineCommand129({
|
|
|
37666
37836
|
}
|
|
37667
37837
|
}
|
|
37668
37838
|
});
|
|
37669
|
-
var workflowsListCommand =
|
|
37839
|
+
var workflowsListCommand = defineCommand130({
|
|
37670
37840
|
meta: {
|
|
37671
37841
|
name: "list",
|
|
37672
37842
|
description: "List HubSpot workflows. Example: baker hubspot workflows list --enabled-only"
|
|
@@ -37731,7 +37901,7 @@ function workflowViewHints(workflow) {
|
|
|
37731
37901
|
}
|
|
37732
37902
|
return hints;
|
|
37733
37903
|
}
|
|
37734
|
-
var workflowsViewCommand =
|
|
37904
|
+
var workflowsViewCommand = defineCommand130({
|
|
37735
37905
|
meta: {
|
|
37736
37906
|
name: "view",
|
|
37737
37907
|
description: "Read one workflow's real configuration \u2014 enrolment, branches in order, and what each step writes. Example: baker hubspot workflows view 121183594 --full"
|
|
@@ -37758,7 +37928,7 @@ var workflowsViewCommand = defineCommand129({
|
|
|
37758
37928
|
}
|
|
37759
37929
|
}
|
|
37760
37930
|
});
|
|
37761
|
-
var pipelinesListCommand =
|
|
37931
|
+
var pipelinesListCommand = defineCommand130({
|
|
37762
37932
|
meta: {
|
|
37763
37933
|
name: "list",
|
|
37764
37934
|
description: "List HubSpot deal pipelines and their stages. Example: baker hubspot pipelines list"
|
|
@@ -37775,7 +37945,7 @@ var pipelinesListCommand = defineCommand129({
|
|
|
37775
37945
|
}
|
|
37776
37946
|
}
|
|
37777
37947
|
});
|
|
37778
|
-
var contactsSummaryCommand =
|
|
37948
|
+
var contactsSummaryCommand = defineCommand130({
|
|
37779
37949
|
meta: {
|
|
37780
37950
|
name: "summary",
|
|
37781
37951
|
description: "Whether recent leads are being worked, as counts. Example: baker hubspot contacts summary --days 30"
|
|
@@ -37845,7 +38015,7 @@ function contactLookupHints(data) {
|
|
|
37845
38015
|
}
|
|
37846
38016
|
return hints;
|
|
37847
38017
|
}
|
|
37848
|
-
var contactsLookupCommand =
|
|
38018
|
+
var contactsLookupCommand = defineCommand130({
|
|
37849
38019
|
meta: {
|
|
37850
38020
|
name: "lookup",
|
|
37851
38021
|
description: "Find one contact by email and see whether it was worked. Example: baker hubspot contacts lookup a@b.com"
|
|
@@ -37869,27 +38039,27 @@ var contactsLookupCommand = defineCommand129({
|
|
|
37869
38039
|
}
|
|
37870
38040
|
}
|
|
37871
38041
|
});
|
|
37872
|
-
var contactsCommand =
|
|
38042
|
+
var contactsCommand = defineCommand130({
|
|
37873
38043
|
meta: { name: "contacts", description: "Contacts on the connected HubSpot account." },
|
|
37874
38044
|
subCommands: { summary: contactsSummaryCommand, lookup: contactsLookupCommand }
|
|
37875
38045
|
});
|
|
37876
|
-
var formsCommand =
|
|
38046
|
+
var formsCommand = defineCommand130({
|
|
37877
38047
|
meta: { name: "forms", description: "HubSpot forms on the connected account." },
|
|
37878
38048
|
subCommands: { list: formsListCommand, view: formsViewCommand, submissions: formsSubmissionsCommand }
|
|
37879
38049
|
});
|
|
37880
|
-
var workflowsCommand =
|
|
38050
|
+
var workflowsCommand = defineCommand130({
|
|
37881
38051
|
meta: { name: "workflows", description: "HubSpot workflows on the connected account." },
|
|
37882
38052
|
subCommands: { list: workflowsListCommand, view: workflowsViewCommand }
|
|
37883
38053
|
});
|
|
37884
|
-
var pipelinesCommand =
|
|
38054
|
+
var pipelinesCommand = defineCommand130({
|
|
37885
38055
|
meta: { name: "pipelines", description: "HubSpot deal pipelines on the connected account." },
|
|
37886
38056
|
subCommands: { list: pipelinesListCommand }
|
|
37887
38057
|
});
|
|
37888
|
-
var meetingsCommand =
|
|
38058
|
+
var meetingsCommand = defineCommand130({
|
|
37889
38059
|
meta: { name: "meetings", description: "HubSpot meeting links (calendars) on the connected account." },
|
|
37890
38060
|
subCommands: { list: meetingsListCommand, view: meetingsViewCommand }
|
|
37891
38061
|
});
|
|
37892
|
-
var hubspotCommand =
|
|
38062
|
+
var hubspotCommand = defineCommand130({
|
|
37893
38063
|
meta: {
|
|
37894
38064
|
name: "hubspot",
|
|
37895
38065
|
description: `Read the connected HubSpot account \u2014 forms, the leads they received, workflows, deal pipelines and
|
|
@@ -37927,10 +38097,10 @@ Full guide: __tooling__/docs/tools/baker/hubspot.md`
|
|
|
37927
38097
|
});
|
|
37928
38098
|
|
|
37929
38099
|
// src/commands/images/index.ts
|
|
37930
|
-
import { defineCommand as
|
|
38100
|
+
import { defineCommand as defineCommand156 } from "citty";
|
|
37931
38101
|
|
|
37932
38102
|
// src/commands/images/crop.ts
|
|
37933
|
-
import { defineCommand as
|
|
38103
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
37934
38104
|
|
|
37935
38105
|
// src/lib/image/crop-sprite.ts
|
|
37936
38106
|
import sharp from "sharp";
|
|
@@ -37945,7 +38115,7 @@ function cropSprite(input, region) {
|
|
|
37945
38115
|
|
|
37946
38116
|
// src/lib/image/io.ts
|
|
37947
38117
|
import { randomBytes } from "crypto";
|
|
37948
|
-
import { glob as fsGlob, readFile as
|
|
38118
|
+
import { glob as fsGlob, readFile as readFile21, rename, stat as stat4, writeFile as writeFile12 } from "fs/promises";
|
|
37949
38119
|
import { dirname as dirname2, extname as extname2, join as join5, resolve as resolve4 } from "path";
|
|
37950
38120
|
var REMOTE_RE = /^https?:\/\//i;
|
|
37951
38121
|
var GLOB_RE = /[*?[\]{}]/;
|
|
@@ -37978,11 +38148,11 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
37978
38148
|
const { buffer } = await fetchExternalBytes(pathOrUrl, { maxBytes: MAX_REMOTE_IMAGE_BYTES });
|
|
37979
38149
|
return buffer;
|
|
37980
38150
|
}
|
|
37981
|
-
return
|
|
38151
|
+
return readFile21(pathOrUrl);
|
|
37982
38152
|
}
|
|
37983
|
-
async function isDirectory(
|
|
38153
|
+
async function isDirectory(path39) {
|
|
37984
38154
|
try {
|
|
37985
|
-
const s = await stat4(
|
|
38155
|
+
const s = await stat4(path39);
|
|
37986
38156
|
return s.isDirectory();
|
|
37987
38157
|
} catch {
|
|
37988
38158
|
return false;
|
|
@@ -38001,7 +38171,7 @@ async function atomicWrite(targetPath, data) {
|
|
|
38001
38171
|
const absolute = resolve4(targetPath);
|
|
38002
38172
|
const dir = dirname2(absolute);
|
|
38003
38173
|
const tmp = join5(dir, `.baker-image-${randomBytes(8).toString("hex")}.tmp`);
|
|
38004
|
-
await
|
|
38174
|
+
await writeFile12(tmp, data);
|
|
38005
38175
|
await rename(tmp, absolute);
|
|
38006
38176
|
}
|
|
38007
38177
|
|
|
@@ -38052,7 +38222,7 @@ function emitError2(err) {
|
|
|
38052
38222
|
}
|
|
38053
38223
|
process.exit(1);
|
|
38054
38224
|
}
|
|
38055
|
-
var cropCommand =
|
|
38225
|
+
var cropCommand = defineCommand131({
|
|
38056
38226
|
meta: {
|
|
38057
38227
|
name: "crop",
|
|
38058
38228
|
description: "Crop a rectangular region from an image.\n\nExample: baker images crop sprite.png --x 0 --y 0 --width 64 --height 64 --output icon.png"
|
|
@@ -38088,7 +38258,7 @@ var cropCommand = defineCommand130({
|
|
|
38088
38258
|
});
|
|
38089
38259
|
|
|
38090
38260
|
// src/commands/images/delete.ts
|
|
38091
|
-
import { defineCommand as
|
|
38261
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
38092
38262
|
registerSchema({
|
|
38093
38263
|
command: "images.delete",
|
|
38094
38264
|
description: "Delete an image by ID",
|
|
@@ -38102,7 +38272,7 @@ registerSchema({
|
|
|
38102
38272
|
}
|
|
38103
38273
|
}
|
|
38104
38274
|
});
|
|
38105
|
-
var deleteCommand2 =
|
|
38275
|
+
var deleteCommand2 = defineCommand132({
|
|
38106
38276
|
meta: {
|
|
38107
38277
|
name: "delete",
|
|
38108
38278
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -38143,7 +38313,7 @@ var deleteCommand2 = defineCommand131({
|
|
|
38143
38313
|
});
|
|
38144
38314
|
|
|
38145
38315
|
// src/commands/images/dimensions.ts
|
|
38146
|
-
import { defineCommand as
|
|
38316
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
38147
38317
|
|
|
38148
38318
|
// src/lib/image/dimensions.ts
|
|
38149
38319
|
import { imageSize } from "image-size";
|
|
@@ -38172,7 +38342,7 @@ registerSchema({
|
|
|
38172
38342
|
}
|
|
38173
38343
|
}
|
|
38174
38344
|
});
|
|
38175
|
-
var dimensionsCommand =
|
|
38345
|
+
var dimensionsCommand = defineCommand133({
|
|
38176
38346
|
meta: {
|
|
38177
38347
|
name: "dimensions",
|
|
38178
38348
|
description: "Read image dimensions without decoding the full file.\n\nExample: baker images dimensions ./logo.png\nExample: baker images dimensions https://acme.com/hero.png"
|
|
@@ -38228,7 +38398,7 @@ var dimensionsCommand = defineCommand132({
|
|
|
38228
38398
|
});
|
|
38229
38399
|
|
|
38230
38400
|
// src/commands/images/download.ts
|
|
38231
|
-
import { defineCommand as
|
|
38401
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
38232
38402
|
|
|
38233
38403
|
// src/commands/images/downloadPaths.ts
|
|
38234
38404
|
import { basename as basename2, extname as extname3, join as join6 } from "path";
|
|
@@ -38284,13 +38454,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
|
|
|
38284
38454
|
}
|
|
38285
38455
|
function disambiguate(paths) {
|
|
38286
38456
|
const taken = /* @__PURE__ */ new Set();
|
|
38287
|
-
return paths.map((
|
|
38288
|
-
if (!taken.has(
|
|
38289
|
-
taken.add(
|
|
38290
|
-
return
|
|
38457
|
+
return paths.map((path39) => {
|
|
38458
|
+
if (!taken.has(path39)) {
|
|
38459
|
+
taken.add(path39);
|
|
38460
|
+
return path39;
|
|
38291
38461
|
}
|
|
38292
|
-
const ext = extname3(
|
|
38293
|
-
const stem =
|
|
38462
|
+
const ext = extname3(path39);
|
|
38463
|
+
const stem = path39.slice(0, path39.length - ext.length);
|
|
38294
38464
|
let n = 2;
|
|
38295
38465
|
while (taken.has(`${stem}-${n}${ext}`)) n += 1;
|
|
38296
38466
|
const unique = `${stem}-${n}${ext}`;
|
|
@@ -38417,10 +38587,10 @@ async function runDownloads(plan) {
|
|
|
38417
38587
|
const paths = disambiguate(fetched.map((item) => item.path));
|
|
38418
38588
|
const downloaded = [];
|
|
38419
38589
|
for (const [index, item] of fetched.entries()) {
|
|
38420
|
-
const
|
|
38590
|
+
const path39 = paths[index] ?? item.path;
|
|
38421
38591
|
try {
|
|
38422
|
-
await atomicWrite(
|
|
38423
|
-
downloaded.push({ input: item.input, output:
|
|
38592
|
+
await atomicWrite(path39, item.buffer);
|
|
38593
|
+
downloaded.push({ input: item.input, output: path39, bytes: item.buffer.length, contentType: item.contentType });
|
|
38424
38594
|
} catch (err) {
|
|
38425
38595
|
failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
|
|
38426
38596
|
}
|
|
@@ -38453,7 +38623,7 @@ function emitError3(err) {
|
|
|
38453
38623
|
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
38454
38624
|
process.exit(1);
|
|
38455
38625
|
}
|
|
38456
|
-
var downloadCommand =
|
|
38626
|
+
var downloadCommand = defineCommand134({
|
|
38457
38627
|
meta: {
|
|
38458
38628
|
name: "download",
|
|
38459
38629
|
description: "Download image URLs and/or library images to local files \u2014 the missing first half of `source \u2192 download \u2192 normalize \u2192 place`. Never use `curl` for this.\n\nExamples:\n baker images download https://media.withbaker.com/\u2026/logo.webp\n baker images download j57abc123 j57def456 --out src/pages/pricing/_images/\n baker images download https://\u2026/hero.png --out ./hero.png"
|
|
@@ -38486,7 +38656,7 @@ var downloadCommand = defineCommand133({
|
|
|
38486
38656
|
});
|
|
38487
38657
|
|
|
38488
38658
|
// src/commands/images/extract.ts
|
|
38489
|
-
import { defineCommand as
|
|
38659
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
38490
38660
|
|
|
38491
38661
|
// src/commands/images/autoIngest.ts
|
|
38492
38662
|
var AUTO_INGEST_MAX = {
|
|
@@ -38533,7 +38703,7 @@ registerSchema({
|
|
|
38533
38703
|
}
|
|
38534
38704
|
}
|
|
38535
38705
|
});
|
|
38536
|
-
var extractCommand =
|
|
38706
|
+
var extractCommand = defineCommand135({
|
|
38537
38707
|
meta: {
|
|
38538
38708
|
name: "extract",
|
|
38539
38709
|
description: "Pull every image from a single URL via Firecrawl. ~$0.001/scrape. Cap auto-ingest at 20.\n\nExample: baker images extract https://stripe.com --auto-ingest 5"
|
|
@@ -38588,7 +38758,7 @@ var extractCommand = defineCommand134({
|
|
|
38588
38758
|
});
|
|
38589
38759
|
|
|
38590
38760
|
// src/commands/images/find.ts
|
|
38591
|
-
import { defineCommand as
|
|
38761
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
38592
38762
|
|
|
38593
38763
|
// src/commands/images/providerHits.ts
|
|
38594
38764
|
function asRecord3(value) {
|
|
@@ -38726,7 +38896,7 @@ registerSchema({
|
|
|
38726
38896
|
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
38727
38897
|
}
|
|
38728
38898
|
});
|
|
38729
|
-
var findCommand =
|
|
38899
|
+
var findCommand = defineCommand136({
|
|
38730
38900
|
meta: {
|
|
38731
38901
|
name: "find",
|
|
38732
38902
|
description: "Library-first fanout image search. Opt in to providers with --sources. `--fallback` short-circuits to externals only when library is thin. With --auto-ingest, ingested external hits return Baker-owned URLs.\n\nExample: baker images find 'office' --sources library,magnific --limit 20"
|
|
@@ -38799,7 +38969,7 @@ var findCommand = defineCommand135({
|
|
|
38799
38969
|
});
|
|
38800
38970
|
|
|
38801
38971
|
// src/commands/images/get.ts
|
|
38802
|
-
import { defineCommand as
|
|
38972
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
38803
38973
|
registerSchema({
|
|
38804
38974
|
command: "images.get",
|
|
38805
38975
|
description: "Get a single image by ID",
|
|
@@ -38807,7 +38977,7 @@ registerSchema({
|
|
|
38807
38977
|
id: { type: "string", description: "Image ID", required: true }
|
|
38808
38978
|
}
|
|
38809
38979
|
});
|
|
38810
|
-
var getCommand3 =
|
|
38980
|
+
var getCommand3 = defineCommand137({
|
|
38811
38981
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
38812
38982
|
args: {
|
|
38813
38983
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -38843,7 +39013,7 @@ var getCommand3 = defineCommand136({
|
|
|
38843
39013
|
});
|
|
38844
39014
|
|
|
38845
39015
|
// src/commands/images/gif.ts
|
|
38846
|
-
import { defineCommand as
|
|
39016
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
38847
39017
|
registerSchema({
|
|
38848
39018
|
command: "images.gif",
|
|
38849
39019
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -38875,7 +39045,7 @@ registerSchema({
|
|
|
38875
39045
|
}
|
|
38876
39046
|
}
|
|
38877
39047
|
});
|
|
38878
|
-
var gifCommand =
|
|
39048
|
+
var gifCommand = defineCommand138({
|
|
38879
39049
|
meta: {
|
|
38880
39050
|
name: "gif",
|
|
38881
39051
|
description: "Search Giphy for GIFs / reaction memes \u2014 built for paid-social creative (Meta, TikTok, LinkedIn, X). Free API. Each hit carries WebP + GIF + MP4 URLs in providerMeta so you can pick the right format per platform.\n\nExample: baker images gif 'this is fine' --limit 10\nExample: baker images gif 'office reaction' --rating pg --auto-ingest 2\nExample: baker images gif --trending --limit 25"
|
|
@@ -38922,7 +39092,7 @@ var gifCommand = defineCommand137({
|
|
|
38922
39092
|
});
|
|
38923
39093
|
|
|
38924
39094
|
// src/commands/images/google.ts
|
|
38925
|
-
import { defineCommand as
|
|
39095
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
38926
39096
|
var GOOGLE_ERROR_FIX = {
|
|
38927
39097
|
action: "use_different_resource",
|
|
38928
39098
|
explanation: "Generate the asset instead of retrying Google. Google is the last-resort image provider. Run `baker studio generate` to make the asset. Never sleep-and-retry this command \u2014 the CLI already backs off on rate limits. If no image can be sourced, continue the rest of the task with a placeholder rather than aborting it."
|
|
@@ -38962,7 +39132,7 @@ registerSchema({
|
|
|
38962
39132
|
}
|
|
38963
39133
|
}
|
|
38964
39134
|
});
|
|
38965
|
-
var googleCommand2 =
|
|
39135
|
+
var googleCommand2 = defineCommand139({
|
|
38966
39136
|
meta: {
|
|
38967
39137
|
name: "google",
|
|
38968
39138
|
description: "Google Images via the official Custom Search JSON API ($0.005/query, free 100/day). \u26A0 Source unverified \u2014 watermarks, low-res, mislabeled results are common. Use as last resort. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExample: baker images google 'industrial workshop' --type photo --size large --limit 20"
|
|
@@ -39035,7 +39205,7 @@ var googleCommand2 = defineCommand138({
|
|
|
39035
39205
|
});
|
|
39036
39206
|
|
|
39037
39207
|
// src/commands/images/group.ts
|
|
39038
|
-
import { defineCommand as
|
|
39208
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
39039
39209
|
|
|
39040
39210
|
// src/commands/mediaGroup.ts
|
|
39041
39211
|
async function runMediaGroupLookup(input) {
|
|
@@ -39088,7 +39258,7 @@ registerSchema({
|
|
|
39088
39258
|
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
39089
39259
|
}
|
|
39090
39260
|
});
|
|
39091
|
-
var groupCommand =
|
|
39261
|
+
var groupCommand = defineCommand140({
|
|
39092
39262
|
meta: {
|
|
39093
39263
|
name: "group",
|
|
39094
39264
|
description: "List every asset that arrived in the same set \u2014 the slides of one Instagram carousel, the images off one scraped page. Start here whenever a hit looks like part of a sequence: carousel slides are authored to be read in order and usually only make sense together. Takes an image or a video id, since one carousel can contain both. Example: baker images group <imageId>"
|
|
@@ -39108,7 +39278,7 @@ var groupCommand = defineCommand139({
|
|
|
39108
39278
|
});
|
|
39109
39279
|
|
|
39110
39280
|
// src/commands/images/icon.ts
|
|
39111
|
-
import { defineCommand as
|
|
39281
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
39112
39282
|
|
|
39113
39283
|
// src/commands/images/brandVerification.ts
|
|
39114
39284
|
function brandToken(domain) {
|
|
@@ -39205,7 +39375,7 @@ registerSchema({
|
|
|
39205
39375
|
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
39206
39376
|
}
|
|
39207
39377
|
});
|
|
39208
|
-
var iconCommand =
|
|
39378
|
+
var iconCommand = defineCommand141({
|
|
39209
39379
|
meta: {
|
|
39210
39380
|
name: "icon",
|
|
39211
39381
|
description: "Icon via Iconify (simple-icons, logos, lucide, devicon, heroicons, tabler, phosphor, material-symbols, \u2026). Free CDN, no API key.\n\nExample: baker images icon react --set devicon\nExample: baker images icon lucide:check --color '#0a0a0a'"
|
|
@@ -39275,7 +39445,7 @@ var iconCommand = defineCommand140({
|
|
|
39275
39445
|
});
|
|
39276
39446
|
|
|
39277
39447
|
// src/commands/images/ingest.ts
|
|
39278
|
-
import { defineCommand as
|
|
39448
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
39279
39449
|
var SOURCE_VALUES = imageSourceSchema.options.join(" | ");
|
|
39280
39450
|
registerSchema({
|
|
39281
39451
|
command: "images.ingest",
|
|
@@ -39290,7 +39460,7 @@ registerSchema({
|
|
|
39290
39460
|
fields: { type: "string", description: "Comma-separated field names to include", required: false }
|
|
39291
39461
|
}
|
|
39292
39462
|
});
|
|
39293
|
-
var ingestCommand =
|
|
39463
|
+
var ingestCommand = defineCommand142({
|
|
39294
39464
|
meta: {
|
|
39295
39465
|
name: "ingest",
|
|
39296
39466
|
description: "Download a remote URL and store it in the library. Hash-deduped on bytes + externalId.\n\nExample: baker images ingest https://img.freepik.com/free-photo/xyz.jpg --source magnific --external-id 12345"
|
|
@@ -39359,7 +39529,7 @@ var ingestCommand = defineCommand141({
|
|
|
39359
39529
|
});
|
|
39360
39530
|
|
|
39361
39531
|
// src/commands/images/layerize.ts
|
|
39362
|
-
import { defineCommand as
|
|
39532
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
39363
39533
|
registerSchema({
|
|
39364
39534
|
command: "images.layerize",
|
|
39365
39535
|
description: "Split a library image into editable layers: transparent PNG cutouts for each element, plus any headline recovered as EDITABLE TEXT with its font, size, colour and position. Waits for completion by default. Costs credits.",
|
|
@@ -39423,7 +39593,7 @@ async function pollUntilSettled(imageId, maxWait) {
|
|
|
39423
39593
|
}
|
|
39424
39594
|
return null;
|
|
39425
39595
|
}
|
|
39426
|
-
var layerizeCommand =
|
|
39596
|
+
var layerizeCommand = defineCommand143({
|
|
39427
39597
|
meta: {
|
|
39428
39598
|
name: "layerize",
|
|
39429
39599
|
description: "Split a library image into editable layers \u2014 transparent cutouts per element, plus any baked-in headline recovered as editable text with its typography.\n\nStart here: baker images layerize j571abc123def\nExample: baker images layerize j571abc123def --full\nExample: baker images layerize j571abc123def --instructions 'keep the product and its shadow together'"
|
|
@@ -39492,7 +39662,7 @@ registerSchema({
|
|
|
39492
39662
|
full: { type: "boolean", description: "Include geometry and typography for every layer", required: false }
|
|
39493
39663
|
}
|
|
39494
39664
|
});
|
|
39495
|
-
var layersCommand =
|
|
39665
|
+
var layersCommand = defineCommand143({
|
|
39496
39666
|
meta: {
|
|
39497
39667
|
name: "layers",
|
|
39498
39668
|
description: "Read the layers of an image that has already been split. Free \u2014 no provider call.\n\nStart here: baker images layers j571abc123def\nExample: baker images layers j571abc123def --full"
|
|
@@ -39532,7 +39702,7 @@ var layersCommand = defineCommand142({
|
|
|
39532
39702
|
});
|
|
39533
39703
|
|
|
39534
39704
|
// src/commands/images/library.ts
|
|
39535
|
-
import { defineCommand as
|
|
39705
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
39536
39706
|
registerSchema({
|
|
39537
39707
|
command: "images.library",
|
|
39538
39708
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -39558,7 +39728,7 @@ registerSchema({
|
|
|
39558
39728
|
}
|
|
39559
39729
|
}
|
|
39560
39730
|
});
|
|
39561
|
-
var libraryCommand =
|
|
39731
|
+
var libraryCommand = defineCommand144({
|
|
39562
39732
|
meta: {
|
|
39563
39733
|
name: "library",
|
|
39564
39734
|
description: "Search the company image library (hybrid BM25 + vector + Cohere rerank). Use this BEFORE any external provider.\n\nExample: baker images library 'hero banner' --aspect-ratio 16:9 --source magnific"
|
|
@@ -39621,7 +39791,7 @@ var libraryCommand = defineCommand143({
|
|
|
39621
39791
|
});
|
|
39622
39792
|
|
|
39623
39793
|
// src/commands/images/logo.ts
|
|
39624
|
-
import { defineCommand as
|
|
39794
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
39625
39795
|
registerSchema({
|
|
39626
39796
|
command: "images.logo",
|
|
39627
39797
|
description: "Brand logo lookup via Brandfetch. Auto-ingests by default. Returns `brandMatch` \u2014 Brandfetch's own verdict on whose brand the domain is (confirmed | mismatch | unverified). Branch on it: `mismatch` means the mark is another company's, so do not place it. `confirmed` verifies the record, not the artwork \u2014 read the ingested row back to check the mark itself.",
|
|
@@ -39649,7 +39819,7 @@ registerSchema({
|
|
|
39649
39819
|
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
39650
39820
|
}
|
|
39651
39821
|
});
|
|
39652
|
-
var logoCommand =
|
|
39822
|
+
var logoCommand = defineCommand145({
|
|
39653
39823
|
meta: {
|
|
39654
39824
|
name: "logo",
|
|
39655
39825
|
description: "Brand logo via Brandfetch. Returns up to 5 variants (icon, light/dark logo, light/dark symbol) plus `brandMatch`. Auto-ingests the first variant.\n\nStart here: check `brandMatch.verdict`.\n mismatch \u2192 the mark belongs to `brandMatch.name`, a different company. Do not place it.\n unverified \u2192 nothing confirmed whose logo this is. Treat as unchecked.\n confirmed \u2192 Brandfetch has this brand's record. That verifies the record, NOT the artwork \u2014 a confirmed domain has served another company's logo before.\n\n\u26A0 Whatever the verdict, read the ingested row back with `baker images get <imageId>` and check `textInImage`/`subject` before placing it. That is the only check that looks at the mark.\n\nExample: baker images logo stripe.com --variant logo"
|
|
@@ -39722,7 +39892,7 @@ var logoCommand = defineCommand144({
|
|
|
39722
39892
|
});
|
|
39723
39893
|
|
|
39724
39894
|
// src/commands/images/normalize.ts
|
|
39725
|
-
import { defineCommand as
|
|
39895
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
39726
39896
|
|
|
39727
39897
|
// src/lib/image/color-changer.ts
|
|
39728
39898
|
import quantize from "quantize";
|
|
@@ -40454,7 +40624,7 @@ function coerceRawArgs(args) {
|
|
|
40454
40624
|
"dry-run": bool(args["dry-run"])
|
|
40455
40625
|
};
|
|
40456
40626
|
}
|
|
40457
|
-
var normalizeCommand2 =
|
|
40627
|
+
var normalizeCommand2 = defineCommand146({
|
|
40458
40628
|
meta: {
|
|
40459
40629
|
name: "normalize",
|
|
40460
40630
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -40509,7 +40679,7 @@ Examples:
|
|
|
40509
40679
|
});
|
|
40510
40680
|
|
|
40511
40681
|
// src/commands/images/pinterest.ts
|
|
40512
|
-
import { defineCommand as
|
|
40682
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
40513
40683
|
registerSchema({
|
|
40514
40684
|
command: "images.pinterest",
|
|
40515
40685
|
description: "Pinterest image search via ScrapeCreators. Reference-grade real-world photography, product styling, interiors, fashion, food, and aesthetic mood boards. Inspect before placing \u2014 Pinterest is unverified, trademark-bearing web content.",
|
|
@@ -40529,7 +40699,7 @@ registerSchema({
|
|
|
40529
40699
|
}
|
|
40530
40700
|
}
|
|
40531
40701
|
});
|
|
40532
|
-
var pinterestCommand =
|
|
40702
|
+
var pinterestCommand = defineCommand147({
|
|
40533
40703
|
meta: {
|
|
40534
40704
|
name: "pinterest",
|
|
40535
40705
|
description: "Pinterest image search via ScrapeCreators ($0.00188/request). Best for photo-realistic reference imagery \u2014 lifestyle, interiors, fashion, food, product styling, and mood boards to brief AI generation against. \u26A0 Unverified, trademark-bearing web content \u2014 inspect and respect rights before placing on a customer page. Browse first; auto-ingest only the pins you commit to.\n\nExamples:\n baker images pinterest 'scandinavian living room'\n baker images pinterest 'minimalist skincare product photography' --limit 20\n baker images pinterest 'cozy coffee shop interior' --auto-ingest 2 --context 'Mood reference for hero photography'"
|
|
@@ -40586,7 +40756,7 @@ var pinterestCommand = defineCommand146({
|
|
|
40586
40756
|
});
|
|
40587
40757
|
|
|
40588
40758
|
// src/commands/images/screenshot.ts
|
|
40589
|
-
import { defineCommand as
|
|
40759
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
40590
40760
|
registerSchema({
|
|
40591
40761
|
command: "images.screenshot",
|
|
40592
40762
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -40605,7 +40775,7 @@ registerSchema({
|
|
|
40605
40775
|
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
40606
40776
|
}
|
|
40607
40777
|
});
|
|
40608
|
-
var screenshotCommand =
|
|
40778
|
+
var screenshotCommand = defineCommand148({
|
|
40609
40779
|
meta: {
|
|
40610
40780
|
name: "screenshot",
|
|
40611
40781
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -40669,7 +40839,7 @@ var screenshotCommand = defineCommand147({
|
|
|
40669
40839
|
});
|
|
40670
40840
|
|
|
40671
40841
|
// src/commands/images/search.ts
|
|
40672
|
-
import { defineCommand as
|
|
40842
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
40673
40843
|
registerSchema({
|
|
40674
40844
|
command: "images.search",
|
|
40675
40845
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -40685,7 +40855,7 @@ registerSchema({
|
|
|
40685
40855
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
40686
40856
|
}
|
|
40687
40857
|
});
|
|
40688
|
-
var searchCommand =
|
|
40858
|
+
var searchCommand = defineCommand149({
|
|
40689
40859
|
meta: {
|
|
40690
40860
|
name: "search",
|
|
40691
40861
|
description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
|
|
@@ -40745,7 +40915,7 @@ var searchCommand = defineCommand148({
|
|
|
40745
40915
|
});
|
|
40746
40916
|
|
|
40747
40917
|
// src/commands/images/sticker.ts
|
|
40748
|
-
import { defineCommand as
|
|
40918
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
40749
40919
|
registerSchema({
|
|
40750
40920
|
command: "images.sticker",
|
|
40751
40921
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -40777,7 +40947,7 @@ registerSchema({
|
|
|
40777
40947
|
}
|
|
40778
40948
|
}
|
|
40779
40949
|
});
|
|
40780
|
-
var stickerCommand =
|
|
40950
|
+
var stickerCommand = defineCommand150({
|
|
40781
40951
|
meta: {
|
|
40782
40952
|
name: "sticker",
|
|
40783
40953
|
description: "Search Giphy's sticker corpus \u2014 transparent-background WebPs / GIFs ideal for overlaying on ad creative (Meta, TikTok, Stories). Same Giphy free API as `baker images gif`; results carry WebP + GIF + MP4 URLs in providerMeta.\n\nExample: baker images sticker 'thumbs up' --limit 10\nExample: baker images sticker celebration --rating g --auto-ingest 3\nExample: baker images sticker --trending --limit 25"
|
|
@@ -40824,7 +40994,7 @@ var stickerCommand = defineCommand149({
|
|
|
40824
40994
|
});
|
|
40825
40995
|
|
|
40826
40996
|
// src/commands/images/stock.ts
|
|
40827
|
-
import { defineCommand as
|
|
40997
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
40828
40998
|
var STOCK_ERROR_FIX = {
|
|
40829
40999
|
action: "use_different_resource",
|
|
40830
41000
|
explanation: "Switch provider instead of retrying stock search. Stock search is one of several image sources. Run `baker images find <query> --sources library,pinterest,google` (`--sources` is required \u2014 `find` alone searches the library only) or `baker studio generate` to make the asset. Never sleep-and-retry this command \u2014 the CLI already backs off on rate limits. If no image can be sourced, continue the rest of the task with a placeholder rather than aborting it."
|
|
@@ -40901,7 +41071,7 @@ function buildStockRequest(query, args) {
|
|
|
40901
41071
|
if (args.context) body.descriptionContext = args.context;
|
|
40902
41072
|
return body;
|
|
40903
41073
|
}
|
|
40904
|
-
var stockCommand =
|
|
41074
|
+
var stockCommand = defineCommand151({
|
|
40905
41075
|
meta: {
|
|
40906
41076
|
name: "stock",
|
|
40907
41077
|
description: "Stock search via Magnific \u2014 Freepik's developer API (~250M assets: photos, vectors, illustrations, icons, PSDs). $0.002/req. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExamples:\n baker images stock 'minimalist office'\n baker images stock 'flat office workers' --type vector\n baker images stock 'hero photo of a kitchen' --type photo --orientation landscape --ai exclude\n baker images stock 'brand pattern' --color '#0a0a0a' --license freemium --auto-ingest 2"
|
|
@@ -40974,7 +41144,7 @@ var stockCommand = defineCommand150({
|
|
|
40974
41144
|
});
|
|
40975
41145
|
|
|
40976
41146
|
// src/lib/tags-command.ts
|
|
40977
|
-
import { defineCommand as
|
|
41147
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
40978
41148
|
function makeTagsCommand(command, label, endpoint) {
|
|
40979
41149
|
registerSchema({
|
|
40980
41150
|
command: `${command}.tags`,
|
|
@@ -40983,7 +41153,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
40983
41153
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
40984
41154
|
}
|
|
40985
41155
|
});
|
|
40986
|
-
return
|
|
41156
|
+
return defineCommand152({
|
|
40987
41157
|
meta: {
|
|
40988
41158
|
name: "tags",
|
|
40989
41159
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -41019,7 +41189,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
41019
41189
|
var tagsCommand3 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
41020
41190
|
|
|
41021
41191
|
// src/commands/images/upload.ts
|
|
41022
|
-
import { defineCommand as
|
|
41192
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
41023
41193
|
registerSchema({
|
|
41024
41194
|
command: "images.upload",
|
|
41025
41195
|
description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
|
|
@@ -41057,7 +41227,7 @@ registerSchema({
|
|
|
41057
41227
|
function isRemoteUrl2(value) {
|
|
41058
41228
|
return /^https?:\/\//i.test(value);
|
|
41059
41229
|
}
|
|
41060
|
-
var uploadCommand =
|
|
41230
|
+
var uploadCommand = defineCommand153({
|
|
41061
41231
|
meta: {
|
|
41062
41232
|
name: "upload",
|
|
41063
41233
|
description: "Upload an image to the library \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: reads bytes, sends to /api/images/upload, content-type auto-detected from extension.\nRemote: dispatches to /api/images/ingest with hash-dedup on bytes + externalId.\n\nExamples:\n baker images upload ./logo.png --source uploaded\n baker images upload ./cert.png --context 'ISO 27001 badge \u2014 enterprise tier'\n baker images upload https://acme.com/hero.png --source firecrawl --context 'Acme competitor pricing hero'"
|
|
@@ -41150,7 +41320,7 @@ async function uploadLocal(target, args) {
|
|
|
41150
41320
|
}
|
|
41151
41321
|
|
|
41152
41322
|
// src/commands/images/upscale.ts
|
|
41153
|
-
import { defineCommand as
|
|
41323
|
+
import { defineCommand as defineCommand154 } from "citty";
|
|
41154
41324
|
registerSchema({
|
|
41155
41325
|
command: "images.upscale",
|
|
41156
41326
|
description: "Upscale a library image via the backend (Replicate, cost-tracked). Waits for completion by default. The image must be status 'ready' and raster (not SVG/AVIF).",
|
|
@@ -41165,7 +41335,7 @@ registerSchema({
|
|
|
41165
41335
|
}
|
|
41166
41336
|
});
|
|
41167
41337
|
var POLL_INTERVAL_MS4 = 1500;
|
|
41168
|
-
var upscaleCommand =
|
|
41338
|
+
var upscaleCommand = defineCommand154({
|
|
41169
41339
|
meta: {
|
|
41170
41340
|
name: "upscale",
|
|
41171
41341
|
description: "Upscale a library image via the Convex backend (Replicate, cost-tracked at $0.05/image). Waits for completion by default.\n\nExample: baker images upscale j571abc123def\nExample: baker images upscale j571abc123def --max-wait 0 # fire-and-forget"
|
|
@@ -41220,7 +41390,7 @@ var upscaleCommand = defineCommand153({
|
|
|
41220
41390
|
});
|
|
41221
41391
|
|
|
41222
41392
|
// src/commands/images/use.ts
|
|
41223
|
-
import { defineCommand as
|
|
41393
|
+
import { defineCommand as defineCommand155 } from "citty";
|
|
41224
41394
|
registerSchema({
|
|
41225
41395
|
command: "images.use",
|
|
41226
41396
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -41249,7 +41419,7 @@ function emitReady(ingestResult, doc, args) {
|
|
|
41249
41419
|
args.full === true
|
|
41250
41420
|
);
|
|
41251
41421
|
}
|
|
41252
|
-
var useCommand =
|
|
41422
|
+
var useCommand = defineCommand155({
|
|
41253
41423
|
meta: {
|
|
41254
41424
|
name: "use",
|
|
41255
41425
|
description: "Sugar over `ingest`: download \u2192 store \u2192 wait until describe + embed complete \u2192 return ready library record.\n\nExample: baker images use https://cdn.example.com/hero.png --source uploaded"
|
|
@@ -41298,7 +41468,7 @@ var useCommand = defineCommand154({
|
|
|
41298
41468
|
});
|
|
41299
41469
|
|
|
41300
41470
|
// src/commands/images/index.ts
|
|
41301
|
-
var imagesCommand =
|
|
41471
|
+
var imagesCommand = defineCommand156({
|
|
41302
41472
|
meta: {
|
|
41303
41473
|
name: "images",
|
|
41304
41474
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -41376,12 +41546,12 @@ Full guide: __tooling__/docs/tools/baker/images.md`
|
|
|
41376
41546
|
});
|
|
41377
41547
|
|
|
41378
41548
|
// src/commands/landing/index.ts
|
|
41379
|
-
import { defineCommand as
|
|
41549
|
+
import { defineCommand as defineCommand167 } from "citty";
|
|
41380
41550
|
|
|
41381
41551
|
// src/commands/landing/critique.ts
|
|
41382
41552
|
import { readdir as readdir9, stat as stat6 } from "fs/promises";
|
|
41383
|
-
import
|
|
41384
|
-
import { defineCommand as
|
|
41553
|
+
import path29 from "path";
|
|
41554
|
+
import { defineCommand as defineCommand157 } from "citty";
|
|
41385
41555
|
|
|
41386
41556
|
// src/engine/landing/lib/constants.ts
|
|
41387
41557
|
var OVERUSED_FONTS = /* @__PURE__ */ new Set([
|
|
@@ -42347,40 +42517,40 @@ function describeCounts(findings) {
|
|
|
42347
42517
|
}
|
|
42348
42518
|
|
|
42349
42519
|
// src/commands/landing/snapshot.ts
|
|
42350
|
-
import { mkdir as
|
|
42351
|
-
import
|
|
42520
|
+
import { mkdir as mkdir9, rename as rename2, writeFile as writeFile13 } from "fs/promises";
|
|
42521
|
+
import path27 from "path";
|
|
42352
42522
|
var CRITIC_VERSION = "2";
|
|
42353
42523
|
function critiqueCacheDir(projectRoot) {
|
|
42354
|
-
return
|
|
42524
|
+
return path27.join(projectRoot, ".cache", "landing-critique");
|
|
42355
42525
|
}
|
|
42356
42526
|
function snapshotPath(projectRoot, slug) {
|
|
42357
|
-
return
|
|
42527
|
+
return path27.join(critiqueCacheDir(projectRoot), `${slug}.json`);
|
|
42358
42528
|
}
|
|
42359
42529
|
async function writeCritiqueSnapshot(projectRoot, snapshot) {
|
|
42360
|
-
await
|
|
42530
|
+
await mkdir9(critiqueCacheDir(projectRoot), { recursive: true });
|
|
42361
42531
|
const dest = snapshotPath(projectRoot, snapshot.slug);
|
|
42362
42532
|
const tmp = `${dest}.tmp`;
|
|
42363
|
-
await
|
|
42533
|
+
await writeFile13(tmp, `${JSON.stringify(snapshot, null, 2)}
|
|
42364
42534
|
`, "utf8");
|
|
42365
42535
|
await rename2(tmp, dest);
|
|
42366
42536
|
}
|
|
42367
42537
|
|
|
42368
42538
|
// src/commands/landing/source-version.ts
|
|
42369
|
-
import { readdir as readdir8, readFile as
|
|
42370
|
-
import
|
|
42539
|
+
import { readdir as readdir8, readFile as readFile22, stat as stat5 } from "fs/promises";
|
|
42540
|
+
import path28 from "path";
|
|
42371
42541
|
async function landingSourceRelPaths(landingDir) {
|
|
42372
42542
|
const rel = [];
|
|
42373
|
-
if (await isFile(
|
|
42374
|
-
const componentsDir =
|
|
42543
|
+
if (await isFile(path28.join(landingDir, "index.astro"))) rel.push("index.astro");
|
|
42544
|
+
const componentsDir = path28.join(landingDir, "_components");
|
|
42375
42545
|
for (const abs of await walkAstro(componentsDir)) {
|
|
42376
|
-
rel.push(
|
|
42546
|
+
rel.push(path28.relative(landingDir, abs).split(path28.sep).join("/"));
|
|
42377
42547
|
}
|
|
42378
42548
|
return rel.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
42379
42549
|
}
|
|
42380
42550
|
async function readLandingSources(landingDir) {
|
|
42381
42551
|
const rel = await landingSourceRelPaths(landingDir);
|
|
42382
42552
|
const out = [];
|
|
42383
|
-
for (const r of rel) out.push({ path: r, text: await
|
|
42553
|
+
for (const r of rel) out.push({ path: r, text: await readFile22(path28.join(landingDir, r), "utf8") });
|
|
42384
42554
|
return out;
|
|
42385
42555
|
}
|
|
42386
42556
|
async function computeLandingSourceSha(landingDir) {
|
|
@@ -42389,7 +42559,7 @@ async function computeLandingSourceSha(landingDir) {
|
|
|
42389
42559
|
for (const r of rel) {
|
|
42390
42560
|
let bytes;
|
|
42391
42561
|
try {
|
|
42392
|
-
bytes = await
|
|
42562
|
+
bytes = await readFile22(path28.join(landingDir, r));
|
|
42393
42563
|
} catch {
|
|
42394
42564
|
bytes = Buffer.alloc(0);
|
|
42395
42565
|
}
|
|
@@ -42413,7 +42583,7 @@ async function walkAstro(dir) {
|
|
|
42413
42583
|
}
|
|
42414
42584
|
const out = [];
|
|
42415
42585
|
for (const entry of entries) {
|
|
42416
|
-
const abs =
|
|
42586
|
+
const abs = path28.join(dir, entry.name);
|
|
42417
42587
|
if (entry.isDirectory()) out.push(...await walkAstro(abs));
|
|
42418
42588
|
else if (entry.isFile() && entry.name.endsWith(".astro")) out.push(abs);
|
|
42419
42589
|
}
|
|
@@ -42450,7 +42620,7 @@ function fail5(code, message, fix) {
|
|
|
42450
42620
|
);
|
|
42451
42621
|
process.exit(2);
|
|
42452
42622
|
}
|
|
42453
|
-
var critiqueCommand2 =
|
|
42623
|
+
var critiqueCommand2 = defineCommand157({
|
|
42454
42624
|
meta: {
|
|
42455
42625
|
name: "critique",
|
|
42456
42626
|
description: "Start here: `baker landing critique <slug>` after building or editing a landing. Deterministic design-quality critic (ADVISORY \u2014 findings never fail it). Flags the known AI design tells (gradient text, overused fonts, side-tab borders, cream palettes, buzzword copy, broken images) tiered block/warn/advisory, respecting the client's BRAND.md as the allowlist. Also records the critique that publishing requires \u2014 run it before finishing a landing."
|
|
@@ -42474,7 +42644,7 @@ var critiqueCommand2 = defineCommand156({
|
|
|
42474
42644
|
{ availableSlugs: await listLandingSlugs(projectRoot) }
|
|
42475
42645
|
);
|
|
42476
42646
|
}
|
|
42477
|
-
if (!await isDir(
|
|
42647
|
+
if (!await isDir(path29.resolve(projectRoot, "src", "pages", slug))) {
|
|
42478
42648
|
fail5("NOT_FOUND", `No landing at src/pages/${slug}/`, {
|
|
42479
42649
|
availableSlugs: await listLandingSlugs(projectRoot)
|
|
42480
42650
|
});
|
|
@@ -42513,7 +42683,7 @@ var critiqueCommand2 = defineCommand156({
|
|
|
42513
42683
|
}
|
|
42514
42684
|
});
|
|
42515
42685
|
async function critiqueOne(projectRoot, slug, brand) {
|
|
42516
|
-
const landingDir =
|
|
42686
|
+
const landingDir = path29.resolve(projectRoot, "src", "pages", slug);
|
|
42517
42687
|
const [sources, sourceSha] = await Promise.all([readLandingSources(landingDir), computeLandingSourceSha(landingDir)]);
|
|
42518
42688
|
const report = critiqueLanding({ slug, sources, brand });
|
|
42519
42689
|
let snapshotFailed = false;
|
|
@@ -42533,7 +42703,7 @@ async function critiqueOne(projectRoot, slug, brand) {
|
|
|
42533
42703
|
}
|
|
42534
42704
|
async function listLandingSlugs(projectRoot) {
|
|
42535
42705
|
try {
|
|
42536
|
-
const entries = await readdir9(
|
|
42706
|
+
const entries = await readdir9(path29.join(projectRoot, "src", "pages"), { withFileTypes: true });
|
|
42537
42707
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
42538
42708
|
} catch {
|
|
42539
42709
|
return [];
|
|
@@ -42559,10 +42729,10 @@ async function isDir(p) {
|
|
|
42559
42729
|
}
|
|
42560
42730
|
|
|
42561
42731
|
// src/commands/landing/inspiration/index.ts
|
|
42562
|
-
import { defineCommand as
|
|
42732
|
+
import { defineCommand as defineCommand166 } from "citty";
|
|
42563
42733
|
|
|
42564
42734
|
// src/commands/landing/inspiration/add.ts
|
|
42565
|
-
import { defineCommand as
|
|
42735
|
+
import { defineCommand as defineCommand158 } from "citty";
|
|
42566
42736
|
|
|
42567
42737
|
// src/commands/landing/inspiration/shared.ts
|
|
42568
42738
|
var INSPIRATION_HINTS = {
|
|
@@ -42644,7 +42814,7 @@ registerSchema({
|
|
|
42644
42814
|
note: { type: "string", description: "Why this page is worth keeping", required: false }
|
|
42645
42815
|
}
|
|
42646
42816
|
});
|
|
42647
|
-
var addCommand =
|
|
42817
|
+
var addCommand = defineCommand158({
|
|
42648
42818
|
meta: {
|
|
42649
42819
|
name: "add",
|
|
42650
42820
|
description: "Add someone else's landing page to the reference library. Example: baker landing inspiration add https://linear.app --note 'the client likes this density'"
|
|
@@ -42684,9 +42854,9 @@ var addCommand = defineCommand157({
|
|
|
42684
42854
|
});
|
|
42685
42855
|
|
|
42686
42856
|
// src/commands/landing/inspiration/code.ts
|
|
42687
|
-
import { mkdir as
|
|
42688
|
-
import
|
|
42689
|
-
import { defineCommand as
|
|
42857
|
+
import { mkdir as mkdir10, writeFile as writeFile14 } from "fs/promises";
|
|
42858
|
+
import path30 from "path";
|
|
42859
|
+
import { defineCommand as defineCommand159 } from "citty";
|
|
42690
42860
|
registerSchema({
|
|
42691
42861
|
command: "landing.inspiration.code",
|
|
42692
42862
|
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.",
|
|
@@ -42695,7 +42865,7 @@ registerSchema({
|
|
|
42695
42865
|
full: { type: "boolean", description: "Print the markup inline as well as writing it", required: false }
|
|
42696
42866
|
}
|
|
42697
42867
|
});
|
|
42698
|
-
var codeCommand =
|
|
42868
|
+
var codeCommand = defineCommand159({
|
|
42699
42869
|
meta: {
|
|
42700
42870
|
name: "code",
|
|
42701
42871
|
description: "Write one reference section's standalone markup to disk. Example: baker landing inspiration code k57abc\u2026 \u2014 read it for structure, then build your own."
|
|
@@ -42708,10 +42878,10 @@ var codeCommand = defineCommand158({
|
|
|
42708
42878
|
try {
|
|
42709
42879
|
const id = args.id;
|
|
42710
42880
|
const data = await apiGet("/api/landing-inspiration/section-code", { id });
|
|
42711
|
-
const dir =
|
|
42712
|
-
await
|
|
42713
|
-
const file =
|
|
42714
|
-
await
|
|
42881
|
+
const dir = path30.join(process.cwd(), ".baker", "inspiration", id);
|
|
42882
|
+
await mkdir10(dir, { recursive: true });
|
|
42883
|
+
const file = path30.join(dir, "section.html");
|
|
42884
|
+
await writeFile14(file, data.html);
|
|
42715
42885
|
const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
|
|
42716
42886
|
const fidelity = fidelityHint(data.fidelity);
|
|
42717
42887
|
if (fidelity) hints.push(fidelity);
|
|
@@ -42720,7 +42890,7 @@ var codeCommand = defineCommand158({
|
|
|
42720
42890
|
ok: true,
|
|
42721
42891
|
data: {
|
|
42722
42892
|
id,
|
|
42723
|
-
file:
|
|
42893
|
+
file: path30.relative(process.cwd(), file),
|
|
42724
42894
|
bytes: data.html.length,
|
|
42725
42895
|
fidelity: data.fidelity,
|
|
42726
42896
|
reproduction_notes: data.reproductionNotes,
|
|
@@ -42741,7 +42911,7 @@ var codeCommand = defineCommand158({
|
|
|
42741
42911
|
});
|
|
42742
42912
|
|
|
42743
42913
|
// src/commands/landing/inspiration/favorites.ts
|
|
42744
|
-
import { defineCommand as
|
|
42914
|
+
import { defineCommand as defineCommand160 } from "citty";
|
|
42745
42915
|
registerSchema({
|
|
42746
42916
|
command: "landing.inspiration.favorites",
|
|
42747
42917
|
description: "List the reference sections this company has saved. This is what `search` looks at by default, so it is the client's own taste profile \u2014 read it before proposing a direction.",
|
|
@@ -42755,7 +42925,7 @@ registerSchema({
|
|
|
42755
42925
|
}
|
|
42756
42926
|
}
|
|
42757
42927
|
});
|
|
42758
|
-
var favoritesCommand =
|
|
42928
|
+
var favoritesCommand = defineCommand160({
|
|
42759
42929
|
meta: {
|
|
42760
42930
|
name: "favorites",
|
|
42761
42931
|
description: "List this company's saved reference sections. Example: baker landing inspiration favorites --type hero,pricing"
|
|
@@ -42835,7 +43005,7 @@ registerSchema({
|
|
|
42835
43005
|
note: { type: "string", description: "Why this is worth keeping", required: false }
|
|
42836
43006
|
}
|
|
42837
43007
|
});
|
|
42838
|
-
var favoriteCommand =
|
|
43008
|
+
var favoriteCommand = defineCommand160({
|
|
42839
43009
|
meta: {
|
|
42840
43010
|
name: "favorite",
|
|
42841
43011
|
description: "Save a reference section to this company. Example: baker landing inspiration favorite k57abc\u2026"
|
|
@@ -42873,7 +43043,7 @@ registerSchema({
|
|
|
42873
43043
|
page: { type: "boolean", description: "Treat the id as a page rather than a section", required: false }
|
|
42874
43044
|
}
|
|
42875
43045
|
});
|
|
42876
|
-
var unfavoriteCommand =
|
|
43046
|
+
var unfavoriteCommand = defineCommand160({
|
|
42877
43047
|
meta: {
|
|
42878
43048
|
name: "unfavorite",
|
|
42879
43049
|
description: "Remove a reference section from this company's saved set. Example: baker landing inspiration unfavorite k57abc\u2026"
|
|
@@ -42895,7 +43065,7 @@ var unfavoriteCommand = defineCommand159({
|
|
|
42895
43065
|
});
|
|
42896
43066
|
|
|
42897
43067
|
// src/commands/landing/inspiration/page.ts
|
|
42898
|
-
import { defineCommand as
|
|
43068
|
+
import { defineCommand as defineCommand161 } from "citty";
|
|
42899
43069
|
registerSchema({
|
|
42900
43070
|
command: "landing.inspiration.page",
|
|
42901
43071
|
description: "Show a whole reference page as a sequence: every section top to bottom with its type and the idea behind it. This is the view to use when the question is how a good page is ORDERED rather than what one section looks like.",
|
|
@@ -42912,7 +43082,7 @@ registerSchema({
|
|
|
42912
43082
|
}
|
|
42913
43083
|
}
|
|
42914
43084
|
});
|
|
42915
|
-
var pageCommand2 =
|
|
43085
|
+
var pageCommand2 = defineCommand161({
|
|
42916
43086
|
meta: {
|
|
42917
43087
|
name: "page",
|
|
42918
43088
|
description: "Show how a reference page sequences its sections. Example: baker landing inspiration page j91xyz\u2026 \u2014 the blueprint, not the pixels."
|
|
@@ -42975,7 +43145,7 @@ var pageCommand2 = defineCommand160({
|
|
|
42975
43145
|
});
|
|
42976
43146
|
|
|
42977
43147
|
// src/commands/landing/inspiration/scrape.ts
|
|
42978
|
-
import { defineCommand as
|
|
43148
|
+
import { defineCommand as defineCommand162 } from "citty";
|
|
42979
43149
|
|
|
42980
43150
|
// src/engine/landing-library/proxyFailure.ts
|
|
42981
43151
|
var PROXY_STATUS = 407;
|
|
@@ -43151,8 +43321,8 @@ function classifyCaptureFailure(error) {
|
|
|
43151
43321
|
}
|
|
43152
43322
|
|
|
43153
43323
|
// src/engine/landing-library/run.ts
|
|
43154
|
-
import { mkdir as
|
|
43155
|
-
import
|
|
43324
|
+
import { mkdir as mkdir11, writeFile as writeFile16 } from "fs/promises";
|
|
43325
|
+
import path32 from "path";
|
|
43156
43326
|
|
|
43157
43327
|
// ../proxy/src/preflight.ts
|
|
43158
43328
|
import http from "http";
|
|
@@ -44567,11 +44737,11 @@ async function renderBundleToPng(browser, html, viewportWidth, options = {}) {
|
|
|
44567
44737
|
}
|
|
44568
44738
|
|
|
44569
44739
|
// src/engine/landing-library/report.ts
|
|
44570
|
-
import { writeFile as
|
|
44571
|
-
import
|
|
44740
|
+
import { writeFile as writeFile15 } from "fs/promises";
|
|
44741
|
+
import path31 from "path";
|
|
44572
44742
|
async function writeCaptureReport(manifest, outDir) {
|
|
44573
|
-
const file =
|
|
44574
|
-
await
|
|
44743
|
+
const file = path31.join(outDir, "report.html");
|
|
44744
|
+
await writeFile15(file, renderReport(manifest));
|
|
44575
44745
|
return file;
|
|
44576
44746
|
}
|
|
44577
44747
|
function escapeHtml3(value) {
|
|
@@ -44749,32 +44919,32 @@ async function reproducePage(args) {
|
|
|
44749
44919
|
const { browser, page, outDir, pageUrl, livePageShot } = args;
|
|
44750
44920
|
const built = await buildSectionBundle(page, "body", pageUrl).catch(() => null);
|
|
44751
44921
|
if (!built) return { bundle: null, fidelity: null };
|
|
44752
|
-
await
|
|
44922
|
+
await writeFile16(path32.join(outDir, "page.html"), built.html);
|
|
44753
44923
|
const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width, {
|
|
44754
44924
|
wholePage: true,
|
|
44755
44925
|
timeoutMs: 6e4
|
|
44756
44926
|
});
|
|
44757
44927
|
if (!rendered || !livePageShot) return { bundle: "page.html", fidelity: null };
|
|
44758
|
-
await
|
|
44928
|
+
await writeFile16(path32.join(outDir, "page-rendered.png"), rendered);
|
|
44759
44929
|
const { score, note } = await scoreFidelity(livePageShot, rendered);
|
|
44760
44930
|
return { bundle: "page.html", fidelity: score, ...note ? { fidelityNote: note } : {} };
|
|
44761
44931
|
}
|
|
44762
44932
|
async function captureOneSection(args) {
|
|
44763
44933
|
const { browser, page, candidate, sectionsDir, outDir, pageUrl, withCode } = args;
|
|
44764
|
-
const dir =
|
|
44765
|
-
await
|
|
44934
|
+
const dir = path32.join(sectionsDir, String(candidate.index).padStart(2, "0"));
|
|
44935
|
+
await mkdir11(dir, { recursive: true });
|
|
44766
44936
|
const desktop = await captureSection(page, candidate);
|
|
44767
|
-
if (desktop) await
|
|
44937
|
+
if (desktop) await writeFile16(path32.join(dir, "desktop.png"), desktop);
|
|
44768
44938
|
const visualHash = desktop ? await perceptualHash(desktop) : null;
|
|
44769
44939
|
const motion = await collectMotion(page, candidate.selector);
|
|
44770
44940
|
const built = withCode ? await buildSectionBundle(page, candidate.selector, pageUrl) : null;
|
|
44771
44941
|
let fidelity = null;
|
|
44772
44942
|
let fidelityNote;
|
|
44773
44943
|
if (built) {
|
|
44774
|
-
await
|
|
44944
|
+
await writeFile16(path32.join(dir, "section.html"), built.html);
|
|
44775
44945
|
const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width);
|
|
44776
44946
|
if (rendered && desktop) {
|
|
44777
|
-
await
|
|
44947
|
+
await writeFile16(path32.join(dir, "section-rendered.png"), rendered);
|
|
44778
44948
|
const result = await scoreFidelity(desktop, rendered);
|
|
44779
44949
|
fidelity = result.score;
|
|
44780
44950
|
fidelityNote = result.note;
|
|
@@ -44782,9 +44952,9 @@ async function captureOneSection(args) {
|
|
|
44782
44952
|
}
|
|
44783
44953
|
return {
|
|
44784
44954
|
...candidate,
|
|
44785
|
-
desktopShot: desktop ?
|
|
44955
|
+
desktopShot: desktop ? path32.relative(outDir, path32.join(dir, "desktop.png")) : null,
|
|
44786
44956
|
mobileShot: null,
|
|
44787
|
-
bundle: built ?
|
|
44957
|
+
bundle: built ? path32.relative(outDir, path32.join(dir, "section.html")) : null,
|
|
44788
44958
|
fidelity,
|
|
44789
44959
|
...fidelityNote ? { fidelityNote } : {},
|
|
44790
44960
|
...built ? { cssStats: built.stats } : {},
|
|
@@ -44803,9 +44973,9 @@ async function captureMobileShots(args) {
|
|
|
44803
44973
|
for (const section of sections) {
|
|
44804
44974
|
const shot = await captureSectionOnMobile(mobile.page, section);
|
|
44805
44975
|
if (!shot) continue;
|
|
44806
|
-
const file =
|
|
44807
|
-
await
|
|
44808
|
-
section.mobileShot =
|
|
44976
|
+
const file = path32.join(sectionsDir, String(section.index).padStart(2, "0"), "mobile.png");
|
|
44977
|
+
await writeFile16(file, shot);
|
|
44978
|
+
section.mobileShot = path32.relative(outDir, file);
|
|
44809
44979
|
}
|
|
44810
44980
|
} finally {
|
|
44811
44981
|
await mobile.context.close();
|
|
@@ -44820,10 +44990,10 @@ async function captureMotionTakes(args) {
|
|
|
44820
44990
|
const filmOne = async (section) => {
|
|
44821
44991
|
const take = await captureMotionTake(browser, pageUrl, section.selector).catch(() => null);
|
|
44822
44992
|
if (!take) return;
|
|
44823
|
-
const dir =
|
|
44824
|
-
const file =
|
|
44825
|
-
await
|
|
44826
|
-
section.motionFilmstrip =
|
|
44993
|
+
const dir = path32.join(sectionsDir, String(section.index).padStart(2, "0"));
|
|
44994
|
+
const file = path32.join(dir, "motion-filmstrip.png");
|
|
44995
|
+
await writeFile16(file, take.filmstrip);
|
|
44996
|
+
section.motionFilmstrip = path32.relative(outDir, file);
|
|
44827
44997
|
log(` [${section.index}] ${section.motion.summary}`);
|
|
44828
44998
|
};
|
|
44829
44999
|
const queue = [...moving];
|
|
@@ -44880,7 +45050,7 @@ async function captureAlternateViews(args) {
|
|
|
44880
45050
|
async function reproduceWholePage(args) {
|
|
44881
45051
|
const { browser, page, outDir, pageUrl, withCode, log } = args;
|
|
44882
45052
|
const fullPage = await page.screenshot({ type: "png", fullPage: true }).catch(() => null);
|
|
44883
|
-
if (fullPage) await
|
|
45053
|
+
if (fullPage) await writeFile16(path32.join(outDir, "full-page.png"), fullPage);
|
|
44884
45054
|
if (!withCode) return { bundle: null, fidelity: null };
|
|
44885
45055
|
const reproduction = await reproducePage({ browser, page, outDir, pageUrl, livePageShot: fullPage });
|
|
44886
45056
|
log(`page reproduction: ${reproduction.fidelity === null ? "unavailable" : reproduction.fidelity.toFixed(2)}`);
|
|
@@ -44951,7 +45121,7 @@ async function openViaLadder(args) {
|
|
|
44951
45121
|
async function scrapeLanding(options) {
|
|
44952
45122
|
const timeoutMs = options.timeoutMs ?? 45e3;
|
|
44953
45123
|
const log = options.onProgress ?? (() => void 0);
|
|
44954
|
-
const sectionsDir =
|
|
45124
|
+
const sectionsDir = path32.join(options.outDir, "sections");
|
|
44955
45125
|
const nonPublic = refuseNonPublicUrl(options.url);
|
|
44956
45126
|
if (nonPublic) {
|
|
44957
45127
|
throw new BlockedPageError({
|
|
@@ -44971,7 +45141,7 @@ async function scrapeLanding(options) {
|
|
|
44971
45141
|
const withMotion = options.motion !== false && !escalated;
|
|
44972
45142
|
const renderBrowser = options.code === false ? null : await launchBrowser();
|
|
44973
45143
|
try {
|
|
44974
|
-
await
|
|
45144
|
+
await mkdir11(sectionsDir, { recursive: true });
|
|
44975
45145
|
const sections = await captureSections({
|
|
44976
45146
|
browser: renderBrowser ?? browser,
|
|
44977
45147
|
page,
|
|
@@ -45013,7 +45183,7 @@ async function scrapeLanding(options) {
|
|
|
45013
45183
|
security: prepared.security,
|
|
45014
45184
|
captureTier: tier
|
|
45015
45185
|
};
|
|
45016
|
-
await
|
|
45186
|
+
await writeFile16(path32.join(options.outDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
45017
45187
|
`);
|
|
45018
45188
|
if (options.report !== false) {
|
|
45019
45189
|
const reportPath = await writeCaptureReport(manifest, options.outDir);
|
|
@@ -45028,28 +45198,28 @@ async function scrapeLanding(options) {
|
|
|
45028
45198
|
|
|
45029
45199
|
// src/commands/landing/inspiration/captureOut.ts
|
|
45030
45200
|
import { existsSync as existsSync9 } from "fs";
|
|
45031
|
-
import
|
|
45201
|
+
import path33 from "path";
|
|
45032
45202
|
var SCRATCH_DIR = ".baker";
|
|
45033
45203
|
function isWithin(parent, target) {
|
|
45034
|
-
const relative =
|
|
45035
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
45204
|
+
const relative = path33.relative(parent, target);
|
|
45205
|
+
return relative === "" || !relative.startsWith("..") && !path33.isAbsolute(relative);
|
|
45036
45206
|
}
|
|
45037
45207
|
function findRepoRoot(from) {
|
|
45038
|
-
let dir =
|
|
45208
|
+
let dir = path33.resolve(from);
|
|
45039
45209
|
for (; ; ) {
|
|
45040
|
-
if (existsSync9(
|
|
45041
|
-
const parent =
|
|
45210
|
+
if (existsSync9(path33.join(dir, ".git"))) return dir;
|
|
45211
|
+
const parent = path33.dirname(dir);
|
|
45042
45212
|
if (parent === dir) return null;
|
|
45043
45213
|
dir = parent;
|
|
45044
45214
|
}
|
|
45045
45215
|
}
|
|
45046
45216
|
function checkCaptureOut(out, options) {
|
|
45047
45217
|
const { cwd, repoRoot } = options;
|
|
45048
|
-
const resolved =
|
|
45218
|
+
const resolved = path33.resolve(cwd, out);
|
|
45049
45219
|
if (repoRoot === null || !isWithin(repoRoot, resolved)) return { ok: true };
|
|
45050
|
-
const scratch =
|
|
45220
|
+
const scratch = path33.join(repoRoot, SCRATCH_DIR);
|
|
45051
45221
|
if (isWithin(scratch, resolved)) return { ok: true };
|
|
45052
|
-
const suggestion =
|
|
45222
|
+
const suggestion = path33.posix.join(SCRATCH_DIR, "teardowns", path33.basename(resolved) || "capture");
|
|
45053
45223
|
return {
|
|
45054
45224
|
ok: false,
|
|
45055
45225
|
error: {
|
|
@@ -45115,7 +45285,7 @@ registerSchema({
|
|
|
45115
45285
|
report: { type: "boolean", description: "Write report.html. `--no-report` to skip", required: false }
|
|
45116
45286
|
}
|
|
45117
45287
|
});
|
|
45118
|
-
var scrapeCommand =
|
|
45288
|
+
var scrapeCommand = defineCommand162({
|
|
45119
45289
|
meta: {
|
|
45120
45290
|
name: "scrape",
|
|
45121
45291
|
description: "Capture a landing page to a directory, now. Example: baker landing inspiration scrape https://linear.app --out .baker/inspiration/linear.app"
|
|
@@ -45223,12 +45393,12 @@ var scrapeCommand = defineCommand161({
|
|
|
45223
45393
|
});
|
|
45224
45394
|
|
|
45225
45395
|
// src/commands/landing/inspiration/search.ts
|
|
45226
|
-
import
|
|
45227
|
-
import { defineCommand as
|
|
45396
|
+
import path35 from "path";
|
|
45397
|
+
import { defineCommand as defineCommand163 } from "citty";
|
|
45228
45398
|
|
|
45229
45399
|
// src/commands/landing/inspiration/shot.ts
|
|
45230
|
-
import { mkdir as
|
|
45231
|
-
import
|
|
45400
|
+
import { mkdir as mkdir12, writeFile as writeFile17 } from "fs/promises";
|
|
45401
|
+
import path34 from "path";
|
|
45232
45402
|
import sharp6 from "sharp";
|
|
45233
45403
|
var READABLE_SHOT = {
|
|
45234
45404
|
maxWidth: 1440,
|
|
@@ -45254,9 +45424,9 @@ async function downloadReadableShot(url, file) {
|
|
|
45254
45424
|
const response = await fetch(url);
|
|
45255
45425
|
if (!response.ok) return null;
|
|
45256
45426
|
const shot = await toReadableShot(Buffer.from(await response.arrayBuffer()));
|
|
45257
|
-
await
|
|
45258
|
-
await
|
|
45259
|
-
return
|
|
45427
|
+
await mkdir12(path34.dirname(file), { recursive: true });
|
|
45428
|
+
await writeFile17(file, shot);
|
|
45429
|
+
return path34.relative(process.cwd(), file);
|
|
45260
45430
|
} catch {
|
|
45261
45431
|
return null;
|
|
45262
45432
|
}
|
|
@@ -45348,20 +45518,20 @@ function buildSearchBody(args) {
|
|
|
45348
45518
|
return body;
|
|
45349
45519
|
}
|
|
45350
45520
|
async function downloadShots(results) {
|
|
45351
|
-
const dir =
|
|
45521
|
+
const dir = path35.join(process.cwd(), ".baker", "inspiration");
|
|
45352
45522
|
const saved = /* @__PURE__ */ new Map();
|
|
45353
45523
|
await Promise.all(
|
|
45354
45524
|
results.map(async (result) => {
|
|
45355
45525
|
const file = await downloadReadableShot(
|
|
45356
45526
|
result.desktopShotUrl,
|
|
45357
|
-
|
|
45527
|
+
path35.join(dir, `${result.id}.${READABLE_SHOT.extension}`)
|
|
45358
45528
|
);
|
|
45359
45529
|
if (file) saved.set(result.id, file);
|
|
45360
45530
|
})
|
|
45361
45531
|
);
|
|
45362
45532
|
return saved;
|
|
45363
45533
|
}
|
|
45364
|
-
var searchCommand2 =
|
|
45534
|
+
var searchCommand2 = defineCommand163({
|
|
45365
45535
|
meta: {
|
|
45366
45536
|
name: "search",
|
|
45367
45537
|
description: "Search real landing-page sections for reference. Example: baker landing inspiration search 'dark developer hero with a terminal' --register dev-tool-minimal --scope all"
|
|
@@ -45459,7 +45629,7 @@ var searchCommand2 = defineCommand162({
|
|
|
45459
45629
|
});
|
|
45460
45630
|
|
|
45461
45631
|
// src/commands/landing/inspiration/sequences.ts
|
|
45462
|
-
import { defineCommand as
|
|
45632
|
+
import { defineCommand as defineCommand164 } from "citty";
|
|
45463
45633
|
var COMPACT_TRANSITIONS = 12;
|
|
45464
45634
|
var COMPACT_ENDS = 5;
|
|
45465
45635
|
var MAX_PAGES = 50;
|
|
@@ -45533,7 +45703,7 @@ function sequencesHints(data, { scope, full }) {
|
|
|
45533
45703
|
if (scope === "favorites") hints.push(...favoritesScopeHints(data.favoritesHealth, data.pagesReturned));
|
|
45534
45704
|
return hints;
|
|
45535
45705
|
}
|
|
45536
|
-
var sequencesCommand =
|
|
45706
|
+
var sequencesCommand = defineCommand164({
|
|
45537
45707
|
meta: {
|
|
45538
45708
|
name: "sequences",
|
|
45539
45709
|
description: "What section follows what, across many real pages at once. Example: baker landing inspiration sequences 'developer tool pricing page' --scope all \u2014 the evidence for how to order a page you are about to build."
|
|
@@ -45582,8 +45752,8 @@ var sequencesCommand = defineCommand163({
|
|
|
45582
45752
|
});
|
|
45583
45753
|
|
|
45584
45754
|
// src/commands/landing/inspiration/view.ts
|
|
45585
|
-
import
|
|
45586
|
-
import { defineCommand as
|
|
45755
|
+
import path36 from "path";
|
|
45756
|
+
import { defineCommand as defineCommand165 } from "citty";
|
|
45587
45757
|
registerSchema({
|
|
45588
45758
|
command: "landing.inspiration.view",
|
|
45589
45759
|
description: "Everything known about one section: composition, motion, design tokens, the copy it uses, why it works, and what must change to make it yours. Downloads the desktop and mobile screenshots plus the motion filmstrip so you can look at them.",
|
|
@@ -45596,7 +45766,7 @@ registerSchema({
|
|
|
45596
45766
|
}
|
|
45597
45767
|
}
|
|
45598
45768
|
});
|
|
45599
|
-
var viewCommand2 =
|
|
45769
|
+
var viewCommand2 = defineCommand165({
|
|
45600
45770
|
meta: {
|
|
45601
45771
|
name: "view",
|
|
45602
45772
|
description: "Full detail for one reference section. Example: baker landing inspiration view k57abc\u2026 \u2014 read the screenshots it saves before you build."
|
|
@@ -45615,12 +45785,12 @@ var viewCommand2 = defineCommand164({
|
|
|
45615
45785
|
const id = args.id;
|
|
45616
45786
|
const data = await apiGet("/api/landing-inspiration/section", { id });
|
|
45617
45787
|
const section = data.section;
|
|
45618
|
-
const dir =
|
|
45788
|
+
const dir = path36.join(process.cwd(), ".baker", "inspiration", id);
|
|
45619
45789
|
const ext = READABLE_SHOT.extension;
|
|
45620
45790
|
const [desktop, mobile, filmstrip] = await Promise.all([
|
|
45621
|
-
downloadReadableShot(section.desktopShotUrl,
|
|
45622
|
-
downloadReadableShot(section.mobileShotUrl,
|
|
45623
|
-
downloadReadableShot(section.motionFilmstripUrl,
|
|
45791
|
+
downloadReadableShot(section.desktopShotUrl, path36.join(dir, `desktop.${ext}`)),
|
|
45792
|
+
downloadReadableShot(section.mobileShotUrl, path36.join(dir, `mobile.${ext}`)),
|
|
45793
|
+
downloadReadableShot(section.motionFilmstripUrl, path36.join(dir, `motion-filmstrip.${ext}`))
|
|
45624
45794
|
]);
|
|
45625
45795
|
const full = args.full;
|
|
45626
45796
|
const hints = [INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt];
|
|
@@ -45680,7 +45850,7 @@ var viewCommand2 = defineCommand164({
|
|
|
45680
45850
|
});
|
|
45681
45851
|
|
|
45682
45852
|
// src/commands/landing/inspiration/index.ts
|
|
45683
|
-
var inspirationCommand =
|
|
45853
|
+
var inspirationCommand = defineCommand166({
|
|
45684
45854
|
meta: {
|
|
45685
45855
|
name: "inspiration",
|
|
45686
45856
|
description: `Reference library of real landing-page sections \u2014 look at how good pages actually solve a problem before you design one.
|
|
@@ -45725,7 +45895,7 @@ Full guide: __tooling__/docs/tools/baker/landing.md`
|
|
|
45725
45895
|
});
|
|
45726
45896
|
|
|
45727
45897
|
// src/commands/landing/index.ts
|
|
45728
|
-
var landingCommand =
|
|
45898
|
+
var landingCommand = defineCommand167({
|
|
45729
45899
|
meta: {
|
|
45730
45900
|
name: "landing",
|
|
45731
45901
|
description: `Design-quality tools for landing pages (src/pages/<slug>/).
|
|
@@ -45743,7 +45913,7 @@ Subcommands:
|
|
|
45743
45913
|
});
|
|
45744
45914
|
|
|
45745
45915
|
// src/commands/mcp/index.ts
|
|
45746
|
-
import { defineCommand as
|
|
45916
|
+
import { defineCommand as defineCommand168 } from "citty";
|
|
45747
45917
|
|
|
45748
45918
|
// src/commands/mcp/platforms.ts
|
|
45749
45919
|
function readsKey(label) {
|
|
@@ -45812,7 +45982,7 @@ registerSchema({
|
|
|
45812
45982
|
description: "List everything this chat can reach: managed integrations (Attio, Slack, Gmail, Google Sheets, \u2026), custom MCP servers, and the platforms the company signed in to (HubSpot, Google Ads, GA4, Search Console, Tag Manager) which you read through their own `baker` commands. Start here when the user mentions an external tool or platform.",
|
|
45813
45983
|
args: {}
|
|
45814
45984
|
});
|
|
45815
|
-
var connectedCommand =
|
|
45985
|
+
var connectedCommand = defineCommand168({
|
|
45816
45986
|
meta: {
|
|
45817
45987
|
name: "connected",
|
|
45818
45988
|
description: `Everything this chat can reach \u2014 managed integrations, custom MCP servers, and connected platforms.
|
|
@@ -45871,7 +46041,7 @@ registerSchema({
|
|
|
45871
46041
|
description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
|
|
45872
46042
|
args: {}
|
|
45873
46043
|
});
|
|
45874
|
-
var listCommand14 =
|
|
46044
|
+
var listCommand14 = defineCommand168({
|
|
45875
46045
|
meta: { name: "list", description: "List custom MCP servers visible to this company's chats." },
|
|
45876
46046
|
run: async () => {
|
|
45877
46047
|
try {
|
|
@@ -45908,7 +46078,7 @@ registerSchema({
|
|
|
45908
46078
|
header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
|
|
45909
46079
|
}
|
|
45910
46080
|
});
|
|
45911
|
-
var addCommand2 =
|
|
46081
|
+
var addCommand2 = defineCommand168({
|
|
45912
46082
|
meta: {
|
|
45913
46083
|
name: "add",
|
|
45914
46084
|
description: `Register a custom MCP server. Tools appear as mcp__<name>__* on the NEXT message.
|
|
@@ -45960,7 +46130,7 @@ registerSchema({
|
|
|
45960
46130
|
description: "Remove a company custom MCP server by name.",
|
|
45961
46131
|
args: { name: { type: "string", description: "Server name to remove", required: true } }
|
|
45962
46132
|
});
|
|
45963
|
-
var removeCommand4 =
|
|
46133
|
+
var removeCommand4 = defineCommand168({
|
|
45964
46134
|
meta: {
|
|
45965
46135
|
name: "remove",
|
|
45966
46136
|
description: `Remove a company custom MCP server by name.
|
|
@@ -45982,7 +46152,7 @@ Example:
|
|
|
45982
46152
|
}
|
|
45983
46153
|
}
|
|
45984
46154
|
});
|
|
45985
|
-
var mcpCommand =
|
|
46155
|
+
var mcpCommand = defineCommand168({
|
|
45986
46156
|
meta: {
|
|
45987
46157
|
name: "mcp",
|
|
45988
46158
|
description: `Third-party tools for this company \u2014 see what's connected, register custom HTTPS MCP endpoints.
|
|
@@ -46008,10 +46178,10 @@ Full guide: __tooling__/docs/tools/baker/mcp.md`
|
|
|
46008
46178
|
});
|
|
46009
46179
|
|
|
46010
46180
|
// src/commands/research/index.ts
|
|
46011
|
-
import { defineCommand as
|
|
46181
|
+
import { defineCommand as defineCommand180 } from "citty";
|
|
46012
46182
|
|
|
46013
46183
|
// src/commands/research/advertisers.ts
|
|
46014
|
-
import { defineCommand as
|
|
46184
|
+
import { defineCommand as defineCommand169 } from "citty";
|
|
46015
46185
|
|
|
46016
46186
|
// src/commands/research/hints.ts
|
|
46017
46187
|
var AD_COPY_ROUTE = 'This returns competing DOMAINS and their SERP economics \u2014 no ad copy, no headlines, no creative. For the actual copy of a competitor\'s ads: `baker winning-ads advertisers "<brand>"` \u2192 `baker winning-ads search "<brief>" --advertiser-id <id>` \u2192 `baker winning-ads content <adId>` (`primary_text` / `headline` / `cta`, plus the spoken transcript and on-screen text for video). That corpus is Meta and LinkedIn only \u2014 Google SERP ad copy is not available through any Baker command, so do not keep querying for it here.';
|
|
@@ -46194,7 +46364,7 @@ var FIELDS3 = {
|
|
|
46194
46364
|
etv: "Estimated traffic value (USD)",
|
|
46195
46365
|
visibility: "SERP visibility score (0-1)"
|
|
46196
46366
|
};
|
|
46197
|
-
var advertisersCommand =
|
|
46367
|
+
var advertisersCommand = defineCommand169({
|
|
46198
46368
|
meta: {
|
|
46199
46369
|
name: "advertisers",
|
|
46200
46370
|
description: `Domains competing for a keyword in Google SERPs, with position, relevance, traffic value and visibility. Returns NO ad copy \u2014 for a competitor's headlines and body copy use \`baker winning-ads content <adId>\` (Meta/LinkedIn only).
|
|
@@ -46250,7 +46420,7 @@ Examples:
|
|
|
46250
46420
|
});
|
|
46251
46421
|
|
|
46252
46422
|
// src/commands/research/autocomplete.ts
|
|
46253
|
-
import { defineCommand as
|
|
46423
|
+
import { defineCommand as defineCommand170 } from "citty";
|
|
46254
46424
|
registerSchema({
|
|
46255
46425
|
command: "research.autocomplete",
|
|
46256
46426
|
description: "Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
|
|
@@ -46273,7 +46443,7 @@ registerSchema({
|
|
|
46273
46443
|
var FIELDS4 = {
|
|
46274
46444
|
suggestion: "Autocomplete suggestion from Google"
|
|
46275
46445
|
};
|
|
46276
|
-
var autocompleteCommand =
|
|
46446
|
+
var autocompleteCommand = defineCommand170({
|
|
46277
46447
|
meta: {
|
|
46278
46448
|
name: "autocomplete",
|
|
46279
46449
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -46328,7 +46498,7 @@ Examples:
|
|
|
46328
46498
|
});
|
|
46329
46499
|
|
|
46330
46500
|
// src/commands/research/countries.ts
|
|
46331
|
-
import { defineCommand as
|
|
46501
|
+
import { defineCommand as defineCommand171 } from "citty";
|
|
46332
46502
|
registerSchema({
|
|
46333
46503
|
command: "research.countries",
|
|
46334
46504
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -46385,7 +46555,7 @@ var FIELDS5 = {
|
|
|
46385
46555
|
code: "Country code to pass as --location",
|
|
46386
46556
|
name: "Country name"
|
|
46387
46557
|
};
|
|
46388
|
-
var countriesCommand =
|
|
46558
|
+
var countriesCommand = defineCommand171({
|
|
46389
46559
|
meta: {
|
|
46390
46560
|
name: "countries",
|
|
46391
46561
|
description: "List all supported country codes for --location flag."
|
|
@@ -46396,7 +46566,7 @@ var countriesCommand = defineCommand170({
|
|
|
46396
46566
|
});
|
|
46397
46567
|
|
|
46398
46568
|
// src/commands/research/fetch.ts
|
|
46399
|
-
import { defineCommand as
|
|
46569
|
+
import { defineCommand as defineCommand172 } from "citty";
|
|
46400
46570
|
var CONTENT_PREVIEW_CHARS = 2e4;
|
|
46401
46571
|
var TIMEOUT_MS = 18e4;
|
|
46402
46572
|
registerSchema({
|
|
@@ -46469,7 +46639,7 @@ function fetchFix(code) {
|
|
|
46469
46639
|
explanation: "This read failed. Don't build a retry ladder around it \u2014 finish the rest of the job with what you can reach and name this page as a gap."
|
|
46470
46640
|
};
|
|
46471
46641
|
}
|
|
46472
|
-
var fetchCommand =
|
|
46642
|
+
var fetchCommand = defineCommand172({
|
|
46473
46643
|
meta: {
|
|
46474
46644
|
name: "fetch",
|
|
46475
46645
|
description: `Read a page an ordinary web fetch could not. Bot walls and JavaScript-rendered pages are resolved for you \u2014 you never have to retry, wait, or drive a browser yourself.
|
|
@@ -46546,7 +46716,7 @@ Examples:
|
|
|
46546
46716
|
});
|
|
46547
46717
|
|
|
46548
46718
|
// src/commands/research/intent.ts
|
|
46549
|
-
import { defineCommand as
|
|
46719
|
+
import { defineCommand as defineCommand173 } from "citty";
|
|
46550
46720
|
registerSchema({
|
|
46551
46721
|
command: "research.intent",
|
|
46552
46722
|
description: "Classify Google Search intent for keywords. Determines if someone searching is looking to buy, research, or navigate. IMPORTANT: If --language is omitted, defaults to English (en). The response includes a query_context object showing which language was used.",
|
|
@@ -46569,7 +46739,7 @@ var FIELDS7 = {
|
|
|
46569
46739
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
46570
46740
|
probability: "Confidence score 0.0-1.0"
|
|
46571
46741
|
};
|
|
46572
|
-
var intentCommand =
|
|
46742
|
+
var intentCommand = defineCommand173({
|
|
46573
46743
|
meta: {
|
|
46574
46744
|
name: "intent",
|
|
46575
46745
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -46617,7 +46787,7 @@ Examples:
|
|
|
46617
46787
|
});
|
|
46618
46788
|
|
|
46619
46789
|
// src/commands/research/keyword-gap.ts
|
|
46620
|
-
import { defineCommand as
|
|
46790
|
+
import { defineCommand as defineCommand174 } from "citty";
|
|
46621
46791
|
registerSchema({
|
|
46622
46792
|
command: "research.keyword-gap",
|
|
46623
46793
|
description: "Find keywords a competitor ranks for (organic or paid) that you don't. Discovers expansion opportunities. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
|
|
@@ -46646,7 +46816,7 @@ var FIELDS8 = {
|
|
|
46646
46816
|
cpc: "Cost per click USD",
|
|
46647
46817
|
their_position: "Competitor's ranking position"
|
|
46648
46818
|
};
|
|
46649
|
-
var keywordGapCommand =
|
|
46819
|
+
var keywordGapCommand = defineCommand174({
|
|
46650
46820
|
meta: {
|
|
46651
46821
|
name: "keyword-gap",
|
|
46652
46822
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -46721,7 +46891,7 @@ Examples:
|
|
|
46721
46891
|
});
|
|
46722
46892
|
|
|
46723
46893
|
// src/commands/research/keywords-for-site.ts
|
|
46724
|
-
import { defineCommand as
|
|
46894
|
+
import { defineCommand as defineCommand175 } from "citty";
|
|
46725
46895
|
registerSchema({
|
|
46726
46896
|
command: "research.keywords-for-site",
|
|
46727
46897
|
description: "Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
|
|
@@ -46754,7 +46924,7 @@ var FIELDS9 = {
|
|
|
46754
46924
|
competition: "LOW, MEDIUM, or HIGH",
|
|
46755
46925
|
competition_index: "Competition score 0-100"
|
|
46756
46926
|
};
|
|
46757
|
-
var keywordsForSiteCommand =
|
|
46927
|
+
var keywordsForSiteCommand = defineCommand175({
|
|
46758
46928
|
meta: {
|
|
46759
46929
|
name: "keywords-for-site",
|
|
46760
46930
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -46816,7 +46986,7 @@ Examples:
|
|
|
46816
46986
|
});
|
|
46817
46987
|
|
|
46818
46988
|
// src/commands/research/languages.ts
|
|
46819
|
-
import { defineCommand as
|
|
46989
|
+
import { defineCommand as defineCommand176 } from "citty";
|
|
46820
46990
|
registerSchema({
|
|
46821
46991
|
command: "research.languages",
|
|
46822
46992
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -46846,7 +47016,7 @@ var FIELDS10 = {
|
|
|
46846
47016
|
code: "Language code to pass as --language",
|
|
46847
47017
|
name: "Language name (also accepted by --language)"
|
|
46848
47018
|
};
|
|
46849
|
-
var languagesCommand2 =
|
|
47019
|
+
var languagesCommand2 = defineCommand176({
|
|
46850
47020
|
meta: {
|
|
46851
47021
|
name: "languages",
|
|
46852
47022
|
description: "List all supported language codes for --language flag."
|
|
@@ -46857,7 +47027,7 @@ var languagesCommand2 = defineCommand175({
|
|
|
46857
47027
|
});
|
|
46858
47028
|
|
|
46859
47029
|
// src/commands/research/lighthouse.ts
|
|
46860
|
-
import { defineCommand as
|
|
47030
|
+
import { defineCommand as defineCommand177 } from "citty";
|
|
46861
47031
|
registerSchema({
|
|
46862
47032
|
command: "research.lighthouse",
|
|
46863
47033
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -46876,7 +47046,7 @@ var FIELDS11 = {
|
|
|
46876
47046
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
46877
47047
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
46878
47048
|
};
|
|
46879
|
-
var lighthouseCommand =
|
|
47049
|
+
var lighthouseCommand = defineCommand177({
|
|
46880
47050
|
meta: {
|
|
46881
47051
|
name: "lighthouse",
|
|
46882
47052
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -46914,7 +47084,7 @@ Examples:
|
|
|
46914
47084
|
});
|
|
46915
47085
|
|
|
46916
47086
|
// src/commands/research/relevant-pages.ts
|
|
46917
|
-
import { defineCommand as
|
|
47087
|
+
import { defineCommand as defineCommand178 } from "citty";
|
|
46918
47088
|
registerSchema({
|
|
46919
47089
|
command: "research.relevant-pages",
|
|
46920
47090
|
description: "Get the top pages of a competitor domain with organic traffic and ranking data. Shows which pages drive the most traffic. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
|
|
@@ -46940,7 +47110,7 @@ var FIELDS12 = {
|
|
|
46940
47110
|
keywords: "Total organic keywords the page ranks for",
|
|
46941
47111
|
top_10: "Keywords in positions 1-10"
|
|
46942
47112
|
};
|
|
46943
|
-
var relevantPagesCommand =
|
|
47113
|
+
var relevantPagesCommand = defineCommand178({
|
|
46944
47114
|
meta: {
|
|
46945
47115
|
name: "relevant-pages",
|
|
46946
47116
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -46987,7 +47157,7 @@ Examples:
|
|
|
46987
47157
|
});
|
|
46988
47158
|
|
|
46989
47159
|
// src/commands/research/web.ts
|
|
46990
|
-
import { defineCommand as
|
|
47160
|
+
import { defineCommand as defineCommand179 } from "citty";
|
|
46991
47161
|
registerSchema({
|
|
46992
47162
|
command: "research.web",
|
|
46993
47163
|
description: "Search the web with AI to answer marketing questions \u2014 competitors, ICP, pricing, pain points, market trends. Three depth levels: medium (quick, default), high (thorough), xhigh (exhaustive deep research).",
|
|
@@ -47038,7 +47208,7 @@ async function runDeepResearch(question) {
|
|
|
47038
47208
|
}
|
|
47039
47209
|
throw new Error("Deep research timed out");
|
|
47040
47210
|
}
|
|
47041
|
-
var webCommand =
|
|
47211
|
+
var webCommand = defineCommand179({
|
|
47042
47212
|
meta: {
|
|
47043
47213
|
name: "web",
|
|
47044
47214
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -47100,7 +47270,7 @@ Examples:
|
|
|
47100
47270
|
});
|
|
47101
47271
|
|
|
47102
47272
|
// src/commands/research/index.ts
|
|
47103
|
-
var researchCommand =
|
|
47273
|
+
var researchCommand = defineCommand180({
|
|
47104
47274
|
meta: {
|
|
47105
47275
|
name: "research",
|
|
47106
47276
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -47144,10 +47314,10 @@ Full guide: __tooling__/docs/tools/baker/research.md`
|
|
|
47144
47314
|
});
|
|
47145
47315
|
|
|
47146
47316
|
// src/commands/scheduled-actions/index.ts
|
|
47147
|
-
import { defineCommand as
|
|
47317
|
+
import { defineCommand as defineCommand188 } from "citty";
|
|
47148
47318
|
|
|
47149
47319
|
// src/commands/scheduled-actions/create.ts
|
|
47150
|
-
import { defineCommand as
|
|
47320
|
+
import { defineCommand as defineCommand181 } from "citty";
|
|
47151
47321
|
|
|
47152
47322
|
// src/commands/scheduled-actions/shared.ts
|
|
47153
47323
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -47294,7 +47464,7 @@ registerSchema({
|
|
|
47294
47464
|
}
|
|
47295
47465
|
}
|
|
47296
47466
|
});
|
|
47297
|
-
var createCommand3 =
|
|
47467
|
+
var createCommand3 = defineCommand181({
|
|
47298
47468
|
meta: {
|
|
47299
47469
|
name: "create",
|
|
47300
47470
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -47353,7 +47523,7 @@ var createCommand3 = defineCommand180({
|
|
|
47353
47523
|
});
|
|
47354
47524
|
|
|
47355
47525
|
// src/commands/scheduled-actions/delete.ts
|
|
47356
|
-
import { defineCommand as
|
|
47526
|
+
import { defineCommand as defineCommand182 } from "citty";
|
|
47357
47527
|
registerSchema({
|
|
47358
47528
|
command: "scheduled-actions.delete",
|
|
47359
47529
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -47361,7 +47531,7 @@ registerSchema({
|
|
|
47361
47531
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
47362
47532
|
}
|
|
47363
47533
|
});
|
|
47364
|
-
var deleteCommand3 =
|
|
47534
|
+
var deleteCommand3 = defineCommand182({
|
|
47365
47535
|
meta: {
|
|
47366
47536
|
name: "delete",
|
|
47367
47537
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -47390,7 +47560,7 @@ var deleteCommand3 = defineCommand181({
|
|
|
47390
47560
|
});
|
|
47391
47561
|
|
|
47392
47562
|
// src/commands/scheduled-actions/get.ts
|
|
47393
|
-
import { defineCommand as
|
|
47563
|
+
import { defineCommand as defineCommand183 } from "citty";
|
|
47394
47564
|
registerSchema({
|
|
47395
47565
|
command: "scheduled-actions.get",
|
|
47396
47566
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -47399,7 +47569,7 @@ registerSchema({
|
|
|
47399
47569
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
47400
47570
|
}
|
|
47401
47571
|
});
|
|
47402
|
-
var getCommand4 =
|
|
47572
|
+
var getCommand4 = defineCommand183({
|
|
47403
47573
|
meta: {
|
|
47404
47574
|
name: "get",
|
|
47405
47575
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -47438,7 +47608,7 @@ var getCommand4 = defineCommand182({
|
|
|
47438
47608
|
});
|
|
47439
47609
|
|
|
47440
47610
|
// src/commands/scheduled-actions/list.ts
|
|
47441
|
-
import { defineCommand as
|
|
47611
|
+
import { defineCommand as defineCommand184 } from "citty";
|
|
47442
47612
|
registerSchema({
|
|
47443
47613
|
command: "scheduled-actions.list",
|
|
47444
47614
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set, or --chat <id> to read an earlier chat's staged schedules instead.",
|
|
@@ -47446,7 +47616,7 @@ registerSchema({
|
|
|
47446
47616
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
47447
47617
|
}
|
|
47448
47618
|
});
|
|
47449
|
-
var listCommand15 =
|
|
47619
|
+
var listCommand15 = defineCommand184({
|
|
47450
47620
|
meta: {
|
|
47451
47621
|
name: "list",
|
|
47452
47622
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set, or --chat <id> to read an earlier chat's staged schedules instead."
|
|
@@ -47469,9 +47639,9 @@ var listCommand15 = defineCommand183({
|
|
|
47469
47639
|
});
|
|
47470
47640
|
|
|
47471
47641
|
// src/commands/scheduled-actions/templates.ts
|
|
47472
|
-
import { readFile as
|
|
47473
|
-
import
|
|
47474
|
-
import { defineCommand as
|
|
47642
|
+
import { readFile as readFile23 } from "fs/promises";
|
|
47643
|
+
import path37 from "path";
|
|
47644
|
+
import { defineCommand as defineCommand185 } from "citty";
|
|
47475
47645
|
registerSchema({
|
|
47476
47646
|
command: "scheduled-actions.templates",
|
|
47477
47647
|
description: "The recipes available to this company: the ones Baker ships plus the ones they wrote themselves, each with its id, what it produces and how often it is meant to run. Read this before proposing a company's automation, so every recipe you name is one that exists. Also how a company gets a recipe of its own \u2014 save a brief, prove it runs, then publish it.",
|
|
@@ -47526,7 +47696,7 @@ registerSchema({
|
|
|
47526
47696
|
}
|
|
47527
47697
|
}
|
|
47528
47698
|
});
|
|
47529
|
-
var templatesCommand =
|
|
47699
|
+
var templatesCommand = defineCommand185({
|
|
47530
47700
|
meta: {
|
|
47531
47701
|
name: "templates",
|
|
47532
47702
|
description: `The recipes this company can run \u2014 Baker's own plus theirs, with what each one produces.
|
|
@@ -47573,7 +47743,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
|
|
|
47573
47743
|
}
|
|
47574
47744
|
if (save.length > 0) {
|
|
47575
47745
|
const briefFile = flag("brief-file");
|
|
47576
|
-
const brief = briefFile.length > 0 ? await
|
|
47746
|
+
const brief = briefFile.length > 0 ? await readFile23(path37.resolve(briefFile), "utf8") : flag("brief");
|
|
47577
47747
|
if (brief.trim().length === 0) {
|
|
47578
47748
|
failValidation4("--brief-file (preferred) or --brief is required: the brief is the recipe.");
|
|
47579
47749
|
}
|
|
@@ -47618,7 +47788,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
|
|
|
47618
47788
|
});
|
|
47619
47789
|
|
|
47620
47790
|
// src/commands/scheduled-actions/trigger.ts
|
|
47621
|
-
import { defineCommand as
|
|
47791
|
+
import { defineCommand as defineCommand186 } from "citty";
|
|
47622
47792
|
registerSchema({
|
|
47623
47793
|
command: "scheduled-actions.trigger",
|
|
47624
47794
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -47626,7 +47796,7 @@ registerSchema({
|
|
|
47626
47796
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
47627
47797
|
}
|
|
47628
47798
|
});
|
|
47629
|
-
var triggerCommand =
|
|
47799
|
+
var triggerCommand = defineCommand186({
|
|
47630
47800
|
meta: {
|
|
47631
47801
|
name: "trigger",
|
|
47632
47802
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -47663,7 +47833,7 @@ var triggerCommand = defineCommand185({
|
|
|
47663
47833
|
});
|
|
47664
47834
|
|
|
47665
47835
|
// src/commands/scheduled-actions/update.ts
|
|
47666
|
-
import { defineCommand as
|
|
47836
|
+
import { defineCommand as defineCommand187 } from "citty";
|
|
47667
47837
|
registerSchema({
|
|
47668
47838
|
command: "scheduled-actions.update",
|
|
47669
47839
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -47694,7 +47864,7 @@ registerSchema({
|
|
|
47694
47864
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
47695
47865
|
}
|
|
47696
47866
|
});
|
|
47697
|
-
var updateCommand3 =
|
|
47867
|
+
var updateCommand3 = defineCommand187({
|
|
47698
47868
|
meta: {
|
|
47699
47869
|
name: "update",
|
|
47700
47870
|
description: "Stage a scheduled action update. Examples: baker scheduled-actions update <id> --enabled false | baker scheduled-actions update <id> --mode publish"
|
|
@@ -47772,7 +47942,7 @@ var updateCommand3 = defineCommand186({
|
|
|
47772
47942
|
});
|
|
47773
47943
|
|
|
47774
47944
|
// src/commands/scheduled-actions/index.ts
|
|
47775
|
-
var scheduledActionsCommand =
|
|
47945
|
+
var scheduledActionsCommand = defineCommand188({
|
|
47776
47946
|
meta: {
|
|
47777
47947
|
name: "scheduled-actions",
|
|
47778
47948
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger, templates.
|
|
@@ -47801,14 +47971,14 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
|
|
|
47801
47971
|
});
|
|
47802
47972
|
|
|
47803
47973
|
// src/commands/schema.ts
|
|
47804
|
-
import { defineCommand as
|
|
47974
|
+
import { defineCommand as defineCommand189 } from "citty";
|
|
47805
47975
|
function narrowToFamily(commandName, available) {
|
|
47806
47976
|
const segments = commandName.split(".");
|
|
47807
47977
|
const prefix = segments[0] === "ads" && segments[1] ? `ads.${segments[1]}.` : `${segments[0]}.`;
|
|
47808
47978
|
const siblings = available.filter((name) => name.startsWith(prefix));
|
|
47809
47979
|
return siblings.length > 0 ? siblings : available;
|
|
47810
47980
|
}
|
|
47811
|
-
var schemaCommand2 =
|
|
47981
|
+
var schemaCommand2 = defineCommand189({
|
|
47812
47982
|
meta: {
|
|
47813
47983
|
name: "schema",
|
|
47814
47984
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -47852,10 +48022,10 @@ var schemaCommand2 = defineCommand188({
|
|
|
47852
48022
|
});
|
|
47853
48023
|
|
|
47854
48024
|
// src/commands/studio/index.ts
|
|
47855
|
-
import { defineCommand as
|
|
48025
|
+
import { defineCommand as defineCommand198 } from "citty";
|
|
47856
48026
|
|
|
47857
48027
|
// src/commands/studio/animate.ts
|
|
47858
|
-
import { defineCommand as
|
|
48028
|
+
import { defineCommand as defineCommand190 } from "citty";
|
|
47859
48029
|
|
|
47860
48030
|
// src/commands/studio/batch.ts
|
|
47861
48031
|
function projectBatch(generation, full) {
|
|
@@ -48044,7 +48214,7 @@ function parseImageRefs(spec) {
|
|
|
48044
48214
|
}
|
|
48045
48215
|
var defaultDeps = {
|
|
48046
48216
|
ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
|
|
48047
|
-
upload: (
|
|
48217
|
+
upload: (path39) => uploadLocalImage({ file: path39, contentType: detectImageContentType(path39), source: "uploaded" })
|
|
48048
48218
|
};
|
|
48049
48219
|
async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
48050
48220
|
const refs = parseImageRefs(spec);
|
|
@@ -48064,10 +48234,10 @@ async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
|
48064
48234
|
}
|
|
48065
48235
|
return { imageIds, added };
|
|
48066
48236
|
}
|
|
48067
|
-
function uploadFailure(
|
|
48237
|
+
function uploadFailure(path39) {
|
|
48068
48238
|
return (error) => {
|
|
48069
48239
|
if (error instanceof ApiError) throw error;
|
|
48070
|
-
throw new ApiError("VALIDATION_ERROR", `Could not read "${
|
|
48240
|
+
throw new ApiError("VALIDATION_ERROR", `Could not read "${path39}" as an image.`);
|
|
48071
48241
|
};
|
|
48072
48242
|
}
|
|
48073
48243
|
|
|
@@ -48090,7 +48260,7 @@ registerSchema({
|
|
|
48090
48260
|
},
|
|
48091
48261
|
image: {
|
|
48092
48262
|
type: "string",
|
|
48093
|
-
description: "Comma-separated source images: library image ids, local file paths, and/or image URLs. Required unless --from text. With the default --from frame this must be exactly ONE image (the opening frame) \u2014 several are refused rather than silently reduced to the first. With --from references, up to 9 on Seedance 2.0 and 30 on Seedance 2.5.",
|
|
48263
|
+
description: "Comma-separated source images: library image ids, local file paths, and/or image URLs. Required unless --from text or --avatar (the avatar is the source). With the default --from frame this must be exactly ONE image (the opening frame) \u2014 several are refused rather than silently reduced to the first. With --from references, up to 9 on Seedance 2.0 and 30 on Seedance 2.5.",
|
|
48094
48264
|
required: false
|
|
48095
48265
|
},
|
|
48096
48266
|
from: {
|
|
@@ -48306,13 +48476,18 @@ function costHintsFor(body) {
|
|
|
48306
48476
|
}
|
|
48307
48477
|
return hints;
|
|
48308
48478
|
}
|
|
48309
|
-
var animateCommand =
|
|
48479
|
+
var animateCommand = defineCommand190({
|
|
48310
48480
|
meta: {
|
|
48311
48481
|
name: "animate",
|
|
48312
|
-
description: "Render a clip. With an image the look is already fixed, so the prompt describes MOVEMENT \u2014 what the camera does, what the subject does, in what order. With --from text there is no image and the prompt is the whole shot.\n\nA rendered clip is NOT usable anywhere until you keep it: `baker studio keep <id> --slot N` is what puts it in the video library. Takes nobody keeps are never ingested, which is what makes a rejected batch cheap.\n\nFor anything longer than 15 seconds, or to build on footage that already exists, use --model bytedance/seedance-2.5: it renders 4-30s and is the only model that reads an existing clip or an existing soundtrack.\n\nExamples:\n baker studio animate 'slow push in, model turns to camera and smiles' --image j57abc123def456ghi789\n baker studio animate 'handheld drift right, steam rising from the cup' --image './out/hero.png' --duration 6 --quality 1080p\n baker studio animate 'product rotates once on a turntable' --image j57abc\u2026,j57def\u2026 --from references\n baker studio animate 'she keeps walking, camera stays with her, then she stops and looks up' --image j57abc\u2026 --from references --from-clip j57batch\u2026:0 --model bytedance/seedance-2.5 --duration 20\n baker studio animate 'hold on the product, then a slow push-in' --from references --from-video j57vid\u2026 --model bytedance/seedance-2.5\n baker studio animate 'slow drone pull-back over a solar farm at golden hour, no people' --from text --model bytedance/seedance-2.5 --duration 12"
|
|
48482
|
+
description: "Render a clip. With an image the look is already fixed, so the prompt describes MOVEMENT \u2014 what the camera does, what the subject does, in what order. With --from text there is no image and the prompt is the whole shot.\n\nA rendered clip is NOT usable anywhere until you keep it: `baker studio keep <id> --slot N` is what puts it in the video library. Takes nobody keeps are never ingested, which is what makes a rejected batch cheap.\n\nFor anything longer than 15 seconds, or to build on footage that already exists, use --model bytedance/seedance-2.5: it renders 4-30s and is the only model that reads an existing clip or an existing soundtrack.\n\nExamples:\n baker studio animate 'slow push in, model turns to camera and smiles' --image j57abc123def456ghi789\n baker studio animate 'she looks to camera and says: \"Hola, soy Elena\"' --avatar elena --quality 720p --aspect-ratio 9:16\n baker studio animate 'handheld drift right, steam rising from the cup' --image './out/hero.png' --duration 6 --quality 1080p\n baker studio animate 'product rotates once on a turntable' --image j57abc\u2026,j57def\u2026 --from references\n baker studio animate 'she keeps walking, camera stays with her, then she stops and looks up' --image j57abc\u2026 --from references --from-clip j57batch\u2026:0 --model bytedance/seedance-2.5 --duration 20\n baker studio animate 'hold on the product, then a slow push-in' --from references --from-video j57vid\u2026 --model bytedance/seedance-2.5\n baker studio animate 'slow drone pull-back over a solar farm at golden hour, no people' --from text --model bytedance/seedance-2.5 --duration 12"
|
|
48313
48483
|
},
|
|
48314
48484
|
args: {
|
|
48315
48485
|
prompt: { type: "positional", description: "What MOVES", required: false },
|
|
48486
|
+
avatar: {
|
|
48487
|
+
type: "string",
|
|
48488
|
+
description: "Cast an avatar by short name \u2014 grounds the clip on their identity sheet AND gives it their voice",
|
|
48489
|
+
required: false
|
|
48490
|
+
},
|
|
48316
48491
|
image: {
|
|
48317
48492
|
type: "string",
|
|
48318
48493
|
description: "Comma-separated library image ids, local file paths, and/or image URLs",
|
|
@@ -48377,13 +48552,13 @@ var animateCommand = defineCommand189({
|
|
|
48377
48552
|
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "A prompt is required" } });
|
|
48378
48553
|
process.exit(1);
|
|
48379
48554
|
}
|
|
48380
|
-
if (!args.image && args.from !== "text") {
|
|
48555
|
+
if (!args.image && !args.avatar && args.from !== "text") {
|
|
48381
48556
|
writeJson({
|
|
48382
48557
|
ok: false,
|
|
48383
48558
|
error: {
|
|
48384
48559
|
code: "VALIDATION_ERROR",
|
|
48385
|
-
message: "--image is required unless you pass --from text: a clip normally animates a still, so it needs the image to start from",
|
|
48386
|
-
fix: "Pass --image <id|path|url>, or --from text to render from the prompt alone."
|
|
48560
|
+
message: "--image is required unless you pass --from text or --avatar: a clip normally animates a still, so it needs the image to start from",
|
|
48561
|
+
fix: "Pass --image <id|path|url>, --avatar <handle> to build the shot around one of your avatars, or --from text to render from the prompt alone."
|
|
48387
48562
|
}
|
|
48388
48563
|
});
|
|
48389
48564
|
process.exit(1);
|
|
@@ -48425,7 +48600,7 @@ var animateCommand = defineCommand189({
|
|
|
48425
48600
|
});
|
|
48426
48601
|
|
|
48427
48602
|
// src/commands/studio/generate.ts
|
|
48428
|
-
import { defineCommand as
|
|
48603
|
+
import { defineCommand as defineCommand191 } from "citty";
|
|
48429
48604
|
var MODEL_LIST2 = IMAGE_MODEL_IDS;
|
|
48430
48605
|
var DEFAULT_MAX_WAIT_MS2 = 24e4;
|
|
48431
48606
|
registerSchema({
|
|
@@ -48561,12 +48736,17 @@ function buildGenerateBody(args, prompt) {
|
|
|
48561
48736
|
}
|
|
48562
48737
|
return body;
|
|
48563
48738
|
}
|
|
48564
|
-
var generateCommand =
|
|
48739
|
+
var generateCommand = defineCommand191({
|
|
48565
48740
|
meta: {
|
|
48566
48741
|
name: "generate",
|
|
48567
48742
|
description: "Start here to make an image. Renders 1-8 takes of one brief, ingests each into the media library as it lands, and shows the batch in the dashboard Studio next to the ones the client ran.\n\nModel choice: google/gemini-3.1-flash-image-preview (default \u2014 fast, best at editing a reference and at extreme ratios), google/gemini-3-pro-image-preview (highest fidelity, slower), openai/gpt-image-2 (photoreal and the cleanest in-image text \u2014 no --image-size, no 4:5 / 5:4), recraft/recraft-v4.1-pro-vector (vector/flat marks with palette control).\n\n--reference is the biggest quality lever there is: a real logo, product shot, Pinterest pin or sandbox screenshot beats any amount of adjectives.\n\nExamples:\n baker studio generate 'matte black bottle on wet marble, hard studio light, 35mm' --aspect-ratio 3:2 --count 3\n baker studio generate 'this bottle on a sunlit kitchen counter' --reference './src/brand/product.png,https://\u2026/kitchen.jpg'\n baker studio generate 'founder-style selfie, kitchen background, natural light' --skill ugc-selfie-hook\n baker studio generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
|
|
48568
48743
|
},
|
|
48569
48744
|
args: {
|
|
48745
|
+
avatar: {
|
|
48746
|
+
type: "string",
|
|
48747
|
+
description: "Cast an avatar by short name \u2014 grounds the image on their identity sheet",
|
|
48748
|
+
required: false
|
|
48749
|
+
},
|
|
48570
48750
|
prompt: { type: "positional", description: "What to generate", required: false },
|
|
48571
48751
|
model: { type: "string", description: "Model id (default google/gemini-3.1-flash-image-preview)", required: false },
|
|
48572
48752
|
"aspect-ratio": { type: "string", description: "Aspect ratio (default 1:1)", required: false },
|
|
@@ -48639,7 +48819,7 @@ var generateCommand = defineCommand190({
|
|
|
48639
48819
|
});
|
|
48640
48820
|
|
|
48641
48821
|
// src/commands/studio/get.ts
|
|
48642
|
-
import { defineCommand as
|
|
48822
|
+
import { defineCommand as defineCommand192 } from "citty";
|
|
48643
48823
|
registerSchema({
|
|
48644
48824
|
command: "studio.get",
|
|
48645
48825
|
description: "Read one Studio batch: every take, where it lives, and why a take is missing. This is how you pick up a batch that was still rendering when the start command returned.",
|
|
@@ -48648,7 +48828,7 @@ registerSchema({
|
|
|
48648
48828
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
48649
48829
|
}
|
|
48650
48830
|
});
|
|
48651
|
-
var getCommand5 =
|
|
48831
|
+
var getCommand5 = defineCommand192({
|
|
48652
48832
|
meta: {
|
|
48653
48833
|
name: "get",
|
|
48654
48834
|
description: "Read one Studio batch \u2014 the takes, their urls, whether each is in the library, and the reason for any that failed.\n\nExample: baker studio get j57abc123def456ghi789\nExample: baker studio get j57abc123def456ghi789 --full"
|
|
@@ -48677,7 +48857,7 @@ var getCommand5 = defineCommand191({
|
|
|
48677
48857
|
});
|
|
48678
48858
|
|
|
48679
48859
|
// src/commands/studio/improve.ts
|
|
48680
|
-
import { defineCommand as
|
|
48860
|
+
import { defineCommand as defineCommand193 } from "citty";
|
|
48681
48861
|
var DESCRIPTION = "Sharpen a rough brief into directed art direction \u2014 the same rewrite the client gets from the wand in the Studio prompt bar. Reach for it when you are relaying the CLIENT's own words and want them shaped without substituting your voice; when you are writing the art direction yourself, just write it, because you will do a better job than this does.";
|
|
48682
48862
|
registerSchema({
|
|
48683
48863
|
command: "studio.improve",
|
|
@@ -48702,7 +48882,7 @@ registerSchema({
|
|
|
48702
48882
|
}
|
|
48703
48883
|
}
|
|
48704
48884
|
});
|
|
48705
|
-
var improveCommand =
|
|
48885
|
+
var improveCommand = defineCommand193({
|
|
48706
48886
|
meta: {
|
|
48707
48887
|
name: "improve",
|
|
48708
48888
|
description: `${DESCRIPTION}
|
|
@@ -48746,7 +48926,7 @@ Examples:
|
|
|
48746
48926
|
});
|
|
48747
48927
|
|
|
48748
48928
|
// src/commands/studio/keep.ts
|
|
48749
|
-
import { defineCommand as
|
|
48929
|
+
import { defineCommand as defineCommand194 } from "citty";
|
|
48750
48930
|
registerSchema({
|
|
48751
48931
|
command: "studio.keep",
|
|
48752
48932
|
description: "Mark one take as the keeper. For an image this stars it, so the client reviewing the batch sees which one you used. For a CLIP it is the step that puts it in the video library \u2014 until then the clip cannot be used in a canvas, a landing, or an ad.",
|
|
@@ -48756,7 +48936,7 @@ registerSchema({
|
|
|
48756
48936
|
undo: { type: "boolean", description: "Un-star an image, or take a kept clip back out", required: false }
|
|
48757
48937
|
}
|
|
48758
48938
|
});
|
|
48759
|
-
var keepCommand =
|
|
48939
|
+
var keepCommand = defineCommand194({
|
|
48760
48940
|
meta: {
|
|
48761
48941
|
name: "keep",
|
|
48762
48942
|
description: "Mark one take as the keeper. An image gets starred (it was already in the library); a clip gets INGESTED into the video library, which is what makes it usable anywhere else.\n\nExample: baker studio keep j57abc123def456ghi789 --slot 2\nExample: baker studio keep j57abc123def456ghi789 --slot 2 --undo"
|
|
@@ -48807,7 +48987,7 @@ var keepCommand = defineCommand193({
|
|
|
48807
48987
|
});
|
|
48808
48988
|
|
|
48809
48989
|
// src/commands/studio/list.ts
|
|
48810
|
-
import { defineCommand as
|
|
48990
|
+
import { defineCommand as defineCommand195 } from "citty";
|
|
48811
48991
|
registerSchema({
|
|
48812
48992
|
command: "studio.list",
|
|
48813
48993
|
description: "Recent Studio batches for THIS conversation, newest first \u2014 what you have already generated, so you re-use a take instead of paying for it twice. `--all` widens it to everything the company generated, including what people ran themselves in the dashboard.",
|
|
@@ -48818,7 +48998,7 @@ registerSchema({
|
|
|
48818
48998
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
48819
48999
|
}
|
|
48820
49000
|
});
|
|
48821
|
-
var listCommand16 =
|
|
49001
|
+
var listCommand16 = defineCommand195({
|
|
48822
49002
|
meta: {
|
|
48823
49003
|
name: "list",
|
|
48824
49004
|
description: "Recent Studio batches, newest first. Scoped to this conversation unless you pass --all.\n\nExample: baker studio list\nExample: baker studio list --kind video --limit 5\nExample: baker studio list --all # includes batches the client ran in the dashboard"
|
|
@@ -48852,7 +49032,7 @@ var listCommand16 = defineCommand194({
|
|
|
48852
49032
|
});
|
|
48853
49033
|
|
|
48854
49034
|
// src/commands/studio/models.ts
|
|
48855
|
-
import { defineCommand as
|
|
49035
|
+
import { defineCommand as defineCommand196 } from "citty";
|
|
48856
49036
|
var DESCRIPTION2 = "What each Studio model actually accepts: its shapes, resolutions, clip lengths, prompt character cap, how many reference images it takes, and which knobs it has. Read this before a batch you care about \u2014 the models disagree far more than they look like they do, and a setting the chosen model does not have is REFUSED, not ignored.";
|
|
48857
49037
|
registerSchema({
|
|
48858
49038
|
command: "studio.models",
|
|
@@ -48939,7 +49119,7 @@ function buildModelCards(kind, model) {
|
|
|
48939
49119
|
const selected = model ? ids.filter((id) => id === model) : ids;
|
|
48940
49120
|
return selected.map((id) => build(id));
|
|
48941
49121
|
}
|
|
48942
|
-
var modelsCommand =
|
|
49122
|
+
var modelsCommand = defineCommand196({
|
|
48943
49123
|
meta: {
|
|
48944
49124
|
name: "models",
|
|
48945
49125
|
description: `${DESCRIPTION2}
|
|
@@ -48986,13 +49166,13 @@ Examples:
|
|
|
48986
49166
|
});
|
|
48987
49167
|
|
|
48988
49168
|
// src/commands/studio/skills.ts
|
|
48989
|
-
import { defineCommand as
|
|
49169
|
+
import { defineCommand as defineCommand197 } from "citty";
|
|
48990
49170
|
registerSchema({
|
|
48991
49171
|
command: "studio.skills",
|
|
48992
49172
|
description: "The craft directions `studio generate --skill <id>` accepts. Each one carries directed art direction plus the model, shape and take count it wants, so you pick a look by name instead of writing the boilerplate yourself.",
|
|
48993
49173
|
args: {}
|
|
48994
49174
|
});
|
|
48995
|
-
var skillsCommand =
|
|
49175
|
+
var skillsCommand = defineCommand197({
|
|
48996
49176
|
meta: {
|
|
48997
49177
|
name: "skills",
|
|
48998
49178
|
description: "List the craft directions available to `baker studio generate --skill <id>` \u2014 what each one is for, whether it wants a reference image, and the model/shape/count it defaults to.\n\nExample: baker studio skills"
|
|
@@ -49016,7 +49196,7 @@ var skillsCommand = defineCommand196({
|
|
|
49016
49196
|
});
|
|
49017
49197
|
|
|
49018
49198
|
// src/commands/studio/index.ts
|
|
49019
|
-
var studioCommand =
|
|
49199
|
+
var studioCommand = defineCommand198({
|
|
49020
49200
|
meta: {
|
|
49021
49201
|
name: "studio",
|
|
49022
49202
|
description: `Make new imagery and clips. Every batch is recorded and shows up in the dashboard Studio for the client to review, labelled with this conversation.
|
|
@@ -49059,10 +49239,10 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
49059
49239
|
});
|
|
49060
49240
|
|
|
49061
49241
|
// src/commands/tag-manager/index.ts
|
|
49062
|
-
import { defineCommand as
|
|
49242
|
+
import { defineCommand as defineCommand202 } from "citty";
|
|
49063
49243
|
|
|
49064
49244
|
// src/commands/tag-manager/draft.ts
|
|
49065
|
-
import { defineCommand as
|
|
49245
|
+
import { defineCommand as defineCommand199 } from "citty";
|
|
49066
49246
|
|
|
49067
49247
|
// src/commands/tag-manager/shared.ts
|
|
49068
49248
|
import { readFileSync as readFileSync15 } from "fs";
|
|
@@ -49129,10 +49309,10 @@ async function stageOp4(op) {
|
|
|
49129
49309
|
handleError5(err);
|
|
49130
49310
|
}
|
|
49131
49311
|
}
|
|
49132
|
-
async function draftAction3(
|
|
49312
|
+
async function draftAction3(path39, body, chat) {
|
|
49133
49313
|
const chatId = resolveChatId(chat);
|
|
49134
49314
|
try {
|
|
49135
|
-
const data = await apiPost(
|
|
49315
|
+
const data = await apiPost(path39, { chatId, ...body });
|
|
49136
49316
|
writeJsonEnvelope({ ok: true, data });
|
|
49137
49317
|
return data;
|
|
49138
49318
|
} catch (err) {
|
|
@@ -49185,13 +49365,13 @@ registerSchema({
|
|
|
49185
49365
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
49186
49366
|
}
|
|
49187
49367
|
});
|
|
49188
|
-
var draftCommand4 =
|
|
49368
|
+
var draftCommand4 = defineCommand199({
|
|
49189
49369
|
meta: {
|
|
49190
49370
|
name: "draft",
|
|
49191
49371
|
description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
|
|
49192
49372
|
},
|
|
49193
49373
|
subCommands: {
|
|
49194
|
-
list:
|
|
49374
|
+
list: defineCommand199({
|
|
49195
49375
|
meta: {
|
|
49196
49376
|
name: "list",
|
|
49197
49377
|
description: "Review everything staged on this chat (--json for the raw envelope)"
|
|
@@ -49204,7 +49384,7 @@ var draftCommand4 = defineCommand198({
|
|
|
49204
49384
|
await draftList2(args.json === true, args.chat);
|
|
49205
49385
|
}
|
|
49206
49386
|
}),
|
|
49207
|
-
show:
|
|
49387
|
+
show: defineCommand199({
|
|
49208
49388
|
meta: {
|
|
49209
49389
|
name: "show",
|
|
49210
49390
|
description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
|
|
@@ -49221,7 +49401,7 @@ var draftCommand4 = defineCommand198({
|
|
|
49221
49401
|
);
|
|
49222
49402
|
}
|
|
49223
49403
|
}),
|
|
49224
|
-
amend:
|
|
49404
|
+
amend: defineCommand199({
|
|
49225
49405
|
meta: {
|
|
49226
49406
|
name: "amend",
|
|
49227
49407
|
description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-validates. Use this instead of remove + re-create."
|
|
@@ -49238,7 +49418,7 @@ var draftCommand4 = defineCommand198({
|
|
|
49238
49418
|
});
|
|
49239
49419
|
}
|
|
49240
49420
|
}),
|
|
49241
|
-
remove:
|
|
49421
|
+
remove: defineCommand199({
|
|
49242
49422
|
meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
|
|
49243
49423
|
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
49244
49424
|
run: async ({ args }) => {
|
|
@@ -49247,7 +49427,7 @@ var draftCommand4 = defineCommand198({
|
|
|
49247
49427
|
});
|
|
49248
49428
|
}
|
|
49249
49429
|
}),
|
|
49250
|
-
clear:
|
|
49430
|
+
clear: defineCommand199({
|
|
49251
49431
|
meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
|
|
49252
49432
|
run: async () => {
|
|
49253
49433
|
await draftAction3("/api/tag-manager/draft/clear", {});
|
|
@@ -49257,7 +49437,7 @@ var draftCommand4 = defineCommand198({
|
|
|
49257
49437
|
});
|
|
49258
49438
|
|
|
49259
49439
|
// src/commands/tag-manager/read.ts
|
|
49260
|
-
import { defineCommand as
|
|
49440
|
+
import { defineCommand as defineCommand200 } from "citty";
|
|
49261
49441
|
registerSchema({
|
|
49262
49442
|
command: "tagManager.containers",
|
|
49263
49443
|
description: "List the Google Tag Manager containers this company's connection can reach. Every container the company connected is flagged `connected: true` \u2014 there can be several, and Baker may read and change all of them. Start here to confirm which containers you are managing.",
|
|
@@ -49298,7 +49478,7 @@ function containersHints(containers) {
|
|
|
49298
49478
|
}))
|
|
49299
49479
|
});
|
|
49300
49480
|
}
|
|
49301
|
-
var containersCommand =
|
|
49481
|
+
var containersCommand = defineCommand200({
|
|
49302
49482
|
meta: {
|
|
49303
49483
|
name: "containers",
|
|
49304
49484
|
description: `List Tag Manager containers reachable by this company's connection.
|
|
@@ -49315,7 +49495,7 @@ Start here:
|
|
|
49315
49495
|
}
|
|
49316
49496
|
}
|
|
49317
49497
|
});
|
|
49318
|
-
var readCommand =
|
|
49498
|
+
var readCommand = defineCommand200({
|
|
49319
49499
|
meta: {
|
|
49320
49500
|
name: "read",
|
|
49321
49501
|
description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
|
|
@@ -49357,7 +49537,7 @@ Examples:
|
|
|
49357
49537
|
});
|
|
49358
49538
|
|
|
49359
49539
|
// src/commands/tag-manager/write-commands.ts
|
|
49360
|
-
import { defineCommand as
|
|
49540
|
+
import { defineCommand as defineCommand201 } from "citty";
|
|
49361
49541
|
var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
|
|
49362
49542
|
var ENTITIES = [
|
|
49363
49543
|
{
|
|
@@ -49413,10 +49593,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
|
|
|
49413
49593
|
});
|
|
49414
49594
|
}
|
|
49415
49595
|
function entityCommand(entity, noun, example) {
|
|
49416
|
-
return
|
|
49596
|
+
return defineCommand201({
|
|
49417
49597
|
meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
|
|
49418
49598
|
subCommands: {
|
|
49419
|
-
create:
|
|
49599
|
+
create: defineCommand201({
|
|
49420
49600
|
meta: {
|
|
49421
49601
|
name: "create",
|
|
49422
49602
|
description: `Stage a new ${noun}
|
|
@@ -49438,7 +49618,7 @@ Examples:
|
|
|
49438
49618
|
});
|
|
49439
49619
|
}
|
|
49440
49620
|
}),
|
|
49441
|
-
update:
|
|
49621
|
+
update: defineCommand201({
|
|
49442
49622
|
meta: {
|
|
49443
49623
|
name: "update",
|
|
49444
49624
|
description: `Stage an update to an existing ${noun} (pass its id or path)`
|
|
@@ -49458,7 +49638,7 @@ Examples:
|
|
|
49458
49638
|
});
|
|
49459
49639
|
}
|
|
49460
49640
|
}),
|
|
49461
|
-
delete:
|
|
49641
|
+
delete: defineCommand201({
|
|
49462
49642
|
meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
|
|
49463
49643
|
args: {
|
|
49464
49644
|
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
@@ -49499,7 +49679,7 @@ function builtinTypes(args) {
|
|
|
49499
49679
|
}
|
|
49500
49680
|
return raw.split(",").map((entry) => entry.trim());
|
|
49501
49681
|
}
|
|
49502
|
-
var builtinCommand =
|
|
49682
|
+
var builtinCommand = defineCommand201({
|
|
49503
49683
|
meta: {
|
|
49504
49684
|
name: "builtin",
|
|
49505
49685
|
description: `Enable or disable built-in variables
|
|
@@ -49509,7 +49689,7 @@ Examples:
|
|
|
49509
49689
|
baker tag-manager builtin disable --types formId`
|
|
49510
49690
|
},
|
|
49511
49691
|
subCommands: {
|
|
49512
|
-
enable:
|
|
49692
|
+
enable: defineCommand201({
|
|
49513
49693
|
meta: { name: "enable", description: "Stage enabling built-in variables" },
|
|
49514
49694
|
args: {
|
|
49515
49695
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -49523,7 +49703,7 @@ Examples:
|
|
|
49523
49703
|
});
|
|
49524
49704
|
}
|
|
49525
49705
|
}),
|
|
49526
|
-
disable:
|
|
49706
|
+
disable: defineCommand201({
|
|
49527
49707
|
meta: { name: "disable", description: "Stage disabling built-in variables" },
|
|
49528
49708
|
args: {
|
|
49529
49709
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -49541,7 +49721,7 @@ Examples:
|
|
|
49541
49721
|
});
|
|
49542
49722
|
|
|
49543
49723
|
// src/commands/tag-manager/index.ts
|
|
49544
|
-
var tagManagerCommand =
|
|
49724
|
+
var tagManagerCommand = defineCommand202({
|
|
49545
49725
|
meta: {
|
|
49546
49726
|
name: "tag-manager",
|
|
49547
49727
|
description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
|
|
@@ -49578,7 +49758,7 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
|
|
|
49578
49758
|
});
|
|
49579
49759
|
|
|
49580
49760
|
// src/commands/tags/index.ts
|
|
49581
|
-
import { defineCommand as
|
|
49761
|
+
import { defineCommand as defineCommand203 } from "citty";
|
|
49582
49762
|
|
|
49583
49763
|
// src/commands/tags/shared.ts
|
|
49584
49764
|
function failApi3(err) {
|
|
@@ -49647,7 +49827,7 @@ async function listTags(json) {
|
|
|
49647
49827
|
var listArgs9 = {
|
|
49648
49828
|
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
|
|
49649
49829
|
};
|
|
49650
|
-
var listCommand17 =
|
|
49830
|
+
var listCommand17 = defineCommand203({
|
|
49651
49831
|
meta: {
|
|
49652
49832
|
name: "list",
|
|
49653
49833
|
description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
|
|
@@ -49666,7 +49846,7 @@ async function listDraft3(chat) {
|
|
|
49666
49846
|
failApi3(err);
|
|
49667
49847
|
}
|
|
49668
49848
|
}
|
|
49669
|
-
var draftCommand5 =
|
|
49849
|
+
var draftCommand5 = defineCommand203({
|
|
49670
49850
|
meta: {
|
|
49671
49851
|
name: "draft",
|
|
49672
49852
|
description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create). Takes --chat <id> to read an earlier chat's staged changes instead."
|
|
@@ -49676,7 +49856,7 @@ var draftCommand5 = defineCommand202({
|
|
|
49676
49856
|
await listDraft3(args.chat);
|
|
49677
49857
|
}
|
|
49678
49858
|
});
|
|
49679
|
-
var tagsCommand4 =
|
|
49859
|
+
var tagsCommand4 = defineCommand203({
|
|
49680
49860
|
meta: {
|
|
49681
49861
|
name: "tags",
|
|
49682
49862
|
description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
|
|
@@ -49705,10 +49885,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
49705
49885
|
});
|
|
49706
49886
|
|
|
49707
49887
|
// src/commands/testimonials/index.ts
|
|
49708
|
-
import { defineCommand as
|
|
49888
|
+
import { defineCommand as defineCommand207 } from "citty";
|
|
49709
49889
|
|
|
49710
49890
|
// src/commands/testimonials/get.ts
|
|
49711
|
-
import { defineCommand as
|
|
49891
|
+
import { defineCommand as defineCommand204 } from "citty";
|
|
49712
49892
|
registerSchema({
|
|
49713
49893
|
command: "testimonials.get",
|
|
49714
49894
|
description: "Get a single testimonial by ID",
|
|
@@ -49716,7 +49896,7 @@ registerSchema({
|
|
|
49716
49896
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
49717
49897
|
}
|
|
49718
49898
|
});
|
|
49719
|
-
var getCommand6 =
|
|
49899
|
+
var getCommand6 = defineCommand204({
|
|
49720
49900
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
49721
49901
|
args: {
|
|
49722
49902
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -49753,7 +49933,7 @@ var getCommand6 = defineCommand203({
|
|
|
49753
49933
|
});
|
|
49754
49934
|
|
|
49755
49935
|
// src/commands/testimonials/list.ts
|
|
49756
|
-
import { defineCommand as
|
|
49936
|
+
import { defineCommand as defineCommand205 } from "citty";
|
|
49757
49937
|
|
|
49758
49938
|
// src/commands/testimonials/emptyCorpusHints.ts
|
|
49759
49939
|
function resolveEmptyReason({
|
|
@@ -49888,7 +50068,7 @@ function buildListParams(args) {
|
|
|
49888
50068
|
}
|
|
49889
50069
|
return params;
|
|
49890
50070
|
}
|
|
49891
|
-
var listCommand18 =
|
|
50071
|
+
var listCommand18 = defineCommand205({
|
|
49892
50072
|
meta: {
|
|
49893
50073
|
name: "list",
|
|
49894
50074
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -49940,7 +50120,7 @@ var listCommand18 = defineCommand204({
|
|
|
49940
50120
|
});
|
|
49941
50121
|
|
|
49942
50122
|
// src/commands/testimonials/search.ts
|
|
49943
|
-
import { defineCommand as
|
|
50123
|
+
import { defineCommand as defineCommand206 } from "citty";
|
|
49944
50124
|
var FILTER_FLAGS2 = ["source", "rating-min", "rating-max", "status", "sentiment", "language", "tags"];
|
|
49945
50125
|
function languageBiasHint(results, requestedLanguage) {
|
|
49946
50126
|
if (requestedLanguage) {
|
|
@@ -50019,7 +50199,7 @@ function buildSearchRequest(query, args) {
|
|
|
50019
50199
|
}
|
|
50020
50200
|
return body;
|
|
50021
50201
|
}
|
|
50022
|
-
var searchCommand3 =
|
|
50202
|
+
var searchCommand3 = defineCommand206({
|
|
50023
50203
|
meta: {
|
|
50024
50204
|
name: "search",
|
|
50025
50205
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -50083,7 +50263,7 @@ var searchCommand3 = defineCommand205({
|
|
|
50083
50263
|
var tagsCommand5 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
50084
50264
|
|
|
50085
50265
|
// src/commands/testimonials/index.ts
|
|
50086
|
-
var testimonialsCommand =
|
|
50266
|
+
var testimonialsCommand = defineCommand207({
|
|
50087
50267
|
meta: {
|
|
50088
50268
|
name: "testimonials",
|
|
50089
50269
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -50105,10 +50285,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
|
|
|
50105
50285
|
});
|
|
50106
50286
|
|
|
50107
50287
|
// src/commands/videos/index.ts
|
|
50108
|
-
import { defineCommand as
|
|
50288
|
+
import { defineCommand as defineCommand214 } from "citty";
|
|
50109
50289
|
|
|
50110
50290
|
// src/commands/videos/delete.ts
|
|
50111
|
-
import { defineCommand as
|
|
50291
|
+
import { defineCommand as defineCommand208 } from "citty";
|
|
50112
50292
|
registerSchema({
|
|
50113
50293
|
command: "videos.delete",
|
|
50114
50294
|
description: "Delete a video by ID",
|
|
@@ -50122,7 +50302,7 @@ registerSchema({
|
|
|
50122
50302
|
}
|
|
50123
50303
|
}
|
|
50124
50304
|
});
|
|
50125
|
-
var deleteCommand4 =
|
|
50305
|
+
var deleteCommand4 = defineCommand208({
|
|
50126
50306
|
meta: {
|
|
50127
50307
|
name: "delete",
|
|
50128
50308
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -50163,7 +50343,7 @@ var deleteCommand4 = defineCommand207({
|
|
|
50163
50343
|
});
|
|
50164
50344
|
|
|
50165
50345
|
// src/commands/videos/get.ts
|
|
50166
|
-
import { defineCommand as
|
|
50346
|
+
import { defineCommand as defineCommand209 } from "citty";
|
|
50167
50347
|
registerSchema({
|
|
50168
50348
|
command: "videos.get",
|
|
50169
50349
|
description: "Get a single video by ID",
|
|
@@ -50171,7 +50351,7 @@ registerSchema({
|
|
|
50171
50351
|
id: { type: "string", description: "Video ID", required: true }
|
|
50172
50352
|
}
|
|
50173
50353
|
});
|
|
50174
|
-
var getCommand7 =
|
|
50354
|
+
var getCommand7 = defineCommand209({
|
|
50175
50355
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
50176
50356
|
args: {
|
|
50177
50357
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -50208,7 +50388,7 @@ var getCommand7 = defineCommand208({
|
|
|
50208
50388
|
});
|
|
50209
50389
|
|
|
50210
50390
|
// src/commands/videos/group.ts
|
|
50211
|
-
import { defineCommand as
|
|
50391
|
+
import { defineCommand as defineCommand210 } from "citty";
|
|
50212
50392
|
registerSchema({
|
|
50213
50393
|
command: "videos.group",
|
|
50214
50394
|
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
@@ -50217,7 +50397,7 @@ registerSchema({
|
|
|
50217
50397
|
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
50218
50398
|
}
|
|
50219
50399
|
});
|
|
50220
|
-
var groupCommand2 =
|
|
50400
|
+
var groupCommand2 = defineCommand210({
|
|
50221
50401
|
meta: {
|
|
50222
50402
|
name: "group",
|
|
50223
50403
|
description: "List every asset that arrived in the same set as this clip \u2014 the other slides of the Instagram post it came from, stills included. A carousel is authored to be read in order, so a clip pulled out of one is usually missing half its meaning. Example: baker videos group <videoId>"
|
|
@@ -50239,8 +50419,8 @@ var groupCommand2 = defineCommand209({
|
|
|
50239
50419
|
// src/commands/videos/ingest.ts
|
|
50240
50420
|
import { mkdtemp as mkdtemp2, rm as rm7, stat as stat7 } from "fs/promises";
|
|
50241
50421
|
import { tmpdir as tmpdir3 } from "os";
|
|
50242
|
-
import
|
|
50243
|
-
import { defineCommand as
|
|
50422
|
+
import path38 from "path";
|
|
50423
|
+
import { defineCommand as defineCommand211 } from "citty";
|
|
50244
50424
|
|
|
50245
50425
|
// src/lib/streamUpload.ts
|
|
50246
50426
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -50404,7 +50584,7 @@ registerSchema({
|
|
|
50404
50584
|
"dry-run": { type: "boolean", description: "Preview the operation without executing", required: false }
|
|
50405
50585
|
}
|
|
50406
50586
|
});
|
|
50407
|
-
var ingestCommand2 =
|
|
50587
|
+
var ingestCommand2 = defineCommand211({
|
|
50408
50588
|
meta: {
|
|
50409
50589
|
name: "ingest",
|
|
50410
50590
|
description: "Add a video to the library from a URL. A direct file URL is handed straight to Baker, which fetches it. A page URL (YouTube, TikTok, Vimeo, Instagram) is downloaded here first, then uploaded \u2014 and a direct URL that Baker cannot fetch falls back to that same path automatically.\n\nExample: baker videos ingest https://www.youtube.com/watch?v=abc123"
|
|
@@ -50590,7 +50770,7 @@ function ingestUrl(args) {
|
|
|
50590
50770
|
}
|
|
50591
50771
|
async function downloadThenIngest(args, country) {
|
|
50592
50772
|
const vimeoCookie = captureVimeoCookie();
|
|
50593
|
-
const workDir = await mkdtemp2(
|
|
50773
|
+
const workDir = await mkdtemp2(path38.join(tmpdir3(), "videos-ingest-"));
|
|
50594
50774
|
try {
|
|
50595
50775
|
const probe = await probeYtDlp({ url: args.url, country, vimeoCookie, cookieDir: workDir });
|
|
50596
50776
|
if (isAudioOnly(probe.info)) {
|
|
@@ -50666,7 +50846,7 @@ async function uploadToAssetStore(filePath, sizeBytes) {
|
|
|
50666
50846
|
}
|
|
50667
50847
|
|
|
50668
50848
|
// src/commands/videos/search.ts
|
|
50669
|
-
import { defineCommand as
|
|
50849
|
+
import { defineCommand as defineCommand212 } from "citty";
|
|
50670
50850
|
registerSchema({
|
|
50671
50851
|
command: "videos.search",
|
|
50672
50852
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -50676,7 +50856,7 @@ registerSchema({
|
|
|
50676
50856
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
50677
50857
|
}
|
|
50678
50858
|
});
|
|
50679
|
-
var searchCommand4 =
|
|
50859
|
+
var searchCommand4 = defineCommand212({
|
|
50680
50860
|
meta: {
|
|
50681
50861
|
name: "search",
|
|
50682
50862
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -50726,9 +50906,9 @@ var searchCommand4 = defineCommand211({
|
|
|
50726
50906
|
var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
50727
50907
|
|
|
50728
50908
|
// src/commands/videos/upload.ts
|
|
50729
|
-
import { readFile as
|
|
50909
|
+
import { readFile as readFile24, stat as stat8 } from "fs/promises";
|
|
50730
50910
|
import { basename as basename3, extname as extname4 } from "path";
|
|
50731
|
-
import { defineCommand as
|
|
50911
|
+
import { defineCommand as defineCommand213 } from "citty";
|
|
50732
50912
|
var MIME_MAP = {
|
|
50733
50913
|
".mp4": "video/mp4",
|
|
50734
50914
|
".mov": "video/quicktime",
|
|
@@ -50770,7 +50950,7 @@ function detectContentType(filePath) {
|
|
|
50770
50950
|
function isRemoteUrl3(value) {
|
|
50771
50951
|
return /^https?:\/\//i.test(value);
|
|
50772
50952
|
}
|
|
50773
|
-
var uploadCommand2 =
|
|
50953
|
+
var uploadCommand2 = defineCommand213({
|
|
50774
50954
|
meta: {
|
|
50775
50955
|
name: "upload",
|
|
50776
50956
|
description: "Upload a video to Baker \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: auto-detects content type and uploads via Mux direct upload.\nRemote: hands off to `videos ingest` (direct fetch, or download-then-upload for a YouTube/TikTok/Vimeo page).\n\nExamples:\n baker videos upload ./demo.mp4\n baker videos upload https://www.youtube.com/watch?v=abc123"
|
|
@@ -50823,7 +51003,7 @@ var uploadCommand2 = defineCommand212({
|
|
|
50823
51003
|
originalFilename,
|
|
50824
51004
|
descriptionContext
|
|
50825
51005
|
});
|
|
50826
|
-
const fileBuffer = await
|
|
51006
|
+
const fileBuffer = await readFile24(filePath);
|
|
50827
51007
|
const uploadResponse = await fetch(uploadUrl, {
|
|
50828
51008
|
method: "PUT",
|
|
50829
51009
|
headers: { "Content-Type": contentType },
|
|
@@ -50854,7 +51034,7 @@ var uploadCommand2 = defineCommand212({
|
|
|
50854
51034
|
});
|
|
50855
51035
|
|
|
50856
51036
|
// src/commands/videos/index.ts
|
|
50857
|
-
var videosCommand =
|
|
51037
|
+
var videosCommand = defineCommand214({
|
|
50858
51038
|
meta: {
|
|
50859
51039
|
name: "videos",
|
|
50860
51040
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, delete, tags.
|
|
@@ -50881,10 +51061,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
50881
51061
|
});
|
|
50882
51062
|
|
|
50883
51063
|
// src/commands/winning-ads/index.ts
|
|
50884
|
-
import { defineCommand as
|
|
51064
|
+
import { defineCommand as defineCommand227 } from "citty";
|
|
50885
51065
|
|
|
50886
51066
|
// src/commands/winning-ads/advertisers.ts
|
|
50887
|
-
import { defineCommand as
|
|
51067
|
+
import { defineCommand as defineCommand215 } from "citty";
|
|
50888
51068
|
|
|
50889
51069
|
// src/commands/winning-ads/shared.ts
|
|
50890
51070
|
function splitList2(value) {
|
|
@@ -50937,7 +51117,7 @@ function advertiserNormalizer(record, full) {
|
|
|
50937
51117
|
last_synced_at: record.last_synced_at ?? null
|
|
50938
51118
|
};
|
|
50939
51119
|
}
|
|
50940
|
-
var advertisersCommand2 =
|
|
51120
|
+
var advertisersCommand2 = defineCommand215({
|
|
50941
51121
|
meta: {
|
|
50942
51122
|
name: "advertisers",
|
|
50943
51123
|
description: 'List corpus advertisers by name or domain. Find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id / winners. Example: baker winning-ads advertisers "Deel" --output md'
|
|
@@ -50995,7 +51175,7 @@ var advertisersCommand2 = defineCommand214({
|
|
|
50995
51175
|
});
|
|
50996
51176
|
|
|
50997
51177
|
// src/commands/winning-ads/brief.ts
|
|
50998
|
-
import { defineCommand as
|
|
51178
|
+
import { defineCommand as defineCommand216 } from "citty";
|
|
50999
51179
|
registerSchema({
|
|
51000
51180
|
command: "winning-ads.brief",
|
|
51001
51181
|
description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
|
|
@@ -51041,7 +51221,7 @@ function parseDna(raw) {
|
|
|
51041
51221
|
}
|
|
51042
51222
|
return parsed;
|
|
51043
51223
|
}
|
|
51044
|
-
var briefCommand =
|
|
51224
|
+
var briefCommand = defineCommand216({
|
|
51045
51225
|
meta: {
|
|
51046
51226
|
name: "brief",
|
|
51047
51227
|
description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
|
|
@@ -51077,7 +51257,7 @@ var briefCommand = defineCommand215({
|
|
|
51077
51257
|
});
|
|
51078
51258
|
|
|
51079
51259
|
// src/commands/winning-ads/content.ts
|
|
51080
|
-
import { defineCommand as
|
|
51260
|
+
import { defineCommand as defineCommand217 } from "citty";
|
|
51081
51261
|
registerSchema({
|
|
51082
51262
|
command: "winning-ads.content",
|
|
51083
51263
|
description: "Read what's INSIDE one winning ad: the spoken transcript, the on-screen text, and the ad copy. Use this after `search`/`winners`/`feed` return a shortlist \u2014 pass an ad_id to understand a reference before reproducing it. Add --full for speech, pacing, and soundtrack detail. Video ads carry the transcript/on-screen text; static ads carry only the copy.",
|
|
@@ -51090,7 +51270,7 @@ registerSchema({
|
|
|
51090
51270
|
}
|
|
51091
51271
|
}
|
|
51092
51272
|
});
|
|
51093
|
-
var contentCommand =
|
|
51273
|
+
var contentCommand = defineCommand217({
|
|
51094
51274
|
meta: {
|
|
51095
51275
|
name: "content",
|
|
51096
51276
|
description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
|
|
@@ -51139,7 +51319,7 @@ var contentCommand = defineCommand216({
|
|
|
51139
51319
|
});
|
|
51140
51320
|
|
|
51141
51321
|
// src/commands/winning-ads/feed.ts
|
|
51142
|
-
import { defineCommand as
|
|
51322
|
+
import { defineCommand as defineCommand218 } from "citty";
|
|
51143
51323
|
function buildFeedParams(input) {
|
|
51144
51324
|
const params = {};
|
|
51145
51325
|
const advertiser = splitList2(input.advertiser);
|
|
@@ -51191,7 +51371,7 @@ registerSchema({
|
|
|
51191
51371
|
format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
|
|
51192
51372
|
}
|
|
51193
51373
|
});
|
|
51194
|
-
var feedCommand =
|
|
51374
|
+
var feedCommand = defineCommand218({
|
|
51195
51375
|
meta: {
|
|
51196
51376
|
name: "feed",
|
|
51197
51377
|
description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
|
|
@@ -51276,7 +51456,7 @@ var feedCommand = defineCommand217({
|
|
|
51276
51456
|
});
|
|
51277
51457
|
|
|
51278
51458
|
// src/commands/winning-ads/follow.ts
|
|
51279
|
-
import { defineCommand as
|
|
51459
|
+
import { defineCommand as defineCommand219 } from "citty";
|
|
51280
51460
|
var PLATFORMS = ["meta", "linkedin"];
|
|
51281
51461
|
registerSchema({
|
|
51282
51462
|
command: "winning-ads.follow",
|
|
@@ -51291,7 +51471,7 @@ registerSchema({
|
|
|
51291
51471
|
label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
|
|
51292
51472
|
}
|
|
51293
51473
|
});
|
|
51294
|
-
var followCommand =
|
|
51474
|
+
var followCommand = defineCommand219({
|
|
51295
51475
|
meta: {
|
|
51296
51476
|
name: "follow",
|
|
51297
51477
|
description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks both Meta + LinkedIn. Example: baker winning-ads follow "deel.com" --platform meta'
|
|
@@ -51338,7 +51518,7 @@ var followCommand = defineCommand218({
|
|
|
51338
51518
|
});
|
|
51339
51519
|
|
|
51340
51520
|
// src/commands/winning-ads/follow-competitors.ts
|
|
51341
|
-
import { defineCommand as
|
|
51521
|
+
import { defineCommand as defineCommand220 } from "citty";
|
|
51342
51522
|
var PLATFORMS2 = ["meta", "linkedin"];
|
|
51343
51523
|
var BATCH_TIMEOUT_MS = 3e5;
|
|
51344
51524
|
function buildFollowBatchBody(input) {
|
|
@@ -51371,7 +51551,7 @@ registerSchema({
|
|
|
51371
51551
|
}
|
|
51372
51552
|
}
|
|
51373
51553
|
});
|
|
51374
|
-
var followCompetitorsCommand =
|
|
51554
|
+
var followCompetitorsCommand = defineCommand220({
|
|
51375
51555
|
meta: {
|
|
51376
51556
|
name: "follow-competitors",
|
|
51377
51557
|
description: 'Follow many brands at once by domain \u2014 add every competitor in one call. Example: baker winning-ads follow-competitors "deel.com,notion.so,hubspot.com"'
|
|
@@ -51446,7 +51626,7 @@ var followCompetitorsCommand = defineCommand219({
|
|
|
51446
51626
|
});
|
|
51447
51627
|
|
|
51448
51628
|
// src/commands/winning-ads/following.ts
|
|
51449
|
-
import { defineCommand as
|
|
51629
|
+
import { defineCommand as defineCommand221 } from "citty";
|
|
51450
51630
|
registerSchema({
|
|
51451
51631
|
command: "winning-ads.following",
|
|
51452
51632
|
description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts. A brand still adding has counts that are a lie in progress; one with `discovery_failed` has counts that are short because we couldn't finish looking, which is not the same as it running no ads.",
|
|
@@ -51500,7 +51680,7 @@ function followingNormalizer(record, full) {
|
|
|
51500
51680
|
platforms: Array.isArray(record.platforms) ? record.platforms : []
|
|
51501
51681
|
};
|
|
51502
51682
|
}
|
|
51503
|
-
var followingCommand =
|
|
51683
|
+
var followingCommand = defineCommand221({
|
|
51504
51684
|
meta: {
|
|
51505
51685
|
name: "following",
|
|
51506
51686
|
description: "List brands you follow, with status (ready / adding\u2026) and cached counts. A brand's counts are only final once it is ready. Example: baker winning-ads following --output md"
|
|
@@ -51536,7 +51716,7 @@ var followingCommand = defineCommand220({
|
|
|
51536
51716
|
});
|
|
51537
51717
|
|
|
51538
51718
|
// src/commands/winning-ads/patterns.ts
|
|
51539
|
-
import { defineCommand as
|
|
51719
|
+
import { defineCommand as defineCommand222 } from "citty";
|
|
51540
51720
|
registerSchema({
|
|
51541
51721
|
command: "winning-ads.patterns",
|
|
51542
51722
|
description: "Mine what separates two cohorts of ads: pass a comma-list of winning ad ids (--winners) and a comma-list of weaker ad ids (--duds). Returns the discriminating DNA fields.",
|
|
@@ -51575,7 +51755,7 @@ function discriminatorRow(record) {
|
|
|
51575
51755
|
top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
|
|
51576
51756
|
};
|
|
51577
51757
|
}
|
|
51578
|
-
var patternsCommand =
|
|
51758
|
+
var patternsCommand = defineCommand222({
|
|
51579
51759
|
meta: {
|
|
51580
51760
|
name: "patterns",
|
|
51581
51761
|
description: "Discover what separates winning ads from weak ones. Example: baker winning-ads patterns --winners a_1,a_2,a_3 --duds a_9,a_8 --output md"
|
|
@@ -51631,7 +51811,7 @@ var patternsCommand = defineCommand221({
|
|
|
51631
51811
|
});
|
|
51632
51812
|
|
|
51633
51813
|
// src/commands/winning-ads/search.ts
|
|
51634
|
-
import { defineCommand as
|
|
51814
|
+
import { defineCommand as defineCommand223 } from "citty";
|
|
51635
51815
|
registerSchema({
|
|
51636
51816
|
command: "winning-ads.search",
|
|
51637
51817
|
description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
|
|
@@ -51739,7 +51919,7 @@ function buildSearchBody2(args) {
|
|
|
51739
51919
|
}
|
|
51740
51920
|
return body;
|
|
51741
51921
|
}
|
|
51742
|
-
var searchCommand5 =
|
|
51922
|
+
var searchCommand5 = defineCommand223({
|
|
51743
51923
|
meta: {
|
|
51744
51924
|
name: "search",
|
|
51745
51925
|
description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
|
|
@@ -51854,7 +52034,7 @@ var searchCommand5 = defineCommand222({
|
|
|
51854
52034
|
});
|
|
51855
52035
|
|
|
51856
52036
|
// src/commands/winning-ads/seeds.ts
|
|
51857
|
-
import { defineCommand as
|
|
52037
|
+
import { defineCommand as defineCommand224 } from "citty";
|
|
51858
52038
|
function leanRow(r) {
|
|
51859
52039
|
return {
|
|
51860
52040
|
key: r.key,
|
|
@@ -51882,7 +52062,7 @@ function makeSeedCommand(opts) {
|
|
|
51882
52062
|
limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
|
|
51883
52063
|
}
|
|
51884
52064
|
});
|
|
51885
|
-
return
|
|
52065
|
+
return defineCommand224({
|
|
51886
52066
|
meta: { name: opts.name, description: opts.description },
|
|
51887
52067
|
args: {
|
|
51888
52068
|
platform: { type: "string", description: "Single platform to segment on", required: false },
|
|
@@ -51931,7 +52111,7 @@ var formatsCommand = makeSeedCommand({
|
|
|
51931
52111
|
});
|
|
51932
52112
|
|
|
51933
52113
|
// src/commands/winning-ads/unfollow.ts
|
|
51934
|
-
import { defineCommand as
|
|
52114
|
+
import { defineCommand as defineCommand225 } from "citty";
|
|
51935
52115
|
registerSchema({
|
|
51936
52116
|
command: "winning-ads.unfollow",
|
|
51937
52117
|
description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
|
|
@@ -51939,7 +52119,7 @@ registerSchema({
|
|
|
51939
52119
|
advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
|
|
51940
52120
|
}
|
|
51941
52121
|
});
|
|
51942
|
-
var unfollowCommand =
|
|
52122
|
+
var unfollowCommand = defineCommand225({
|
|
51943
52123
|
meta: {
|
|
51944
52124
|
name: "unfollow",
|
|
51945
52125
|
description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
|
|
@@ -51960,7 +52140,7 @@ var unfollowCommand = defineCommand224({
|
|
|
51960
52140
|
});
|
|
51961
52141
|
|
|
51962
52142
|
// src/commands/winning-ads/winners.ts
|
|
51963
|
-
import { defineCommand as
|
|
52143
|
+
import { defineCommand as defineCommand226 } from "citty";
|
|
51964
52144
|
registerSchema({
|
|
51965
52145
|
command: "winning-ads.winners",
|
|
51966
52146
|
description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
|
|
@@ -51970,7 +52150,7 @@ registerSchema({
|
|
|
51970
52150
|
platform: { type: "string", description: "Filter to a single platform: meta|linkedin", required: false }
|
|
51971
52151
|
}
|
|
51972
52152
|
});
|
|
51973
|
-
var winnersCommand =
|
|
52153
|
+
var winnersCommand = defineCommand226({
|
|
51974
52154
|
meta: {
|
|
51975
52155
|
name: "winners",
|
|
51976
52156
|
description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
|
|
@@ -52020,7 +52200,7 @@ var winnersCommand = defineCommand225({
|
|
|
52020
52200
|
});
|
|
52021
52201
|
|
|
52022
52202
|
// src/commands/winning-ads/index.ts
|
|
52023
|
-
var winningAdsCommand =
|
|
52203
|
+
var winningAdsCommand = defineCommand227({
|
|
52024
52204
|
meta: {
|
|
52025
52205
|
name: "winning-ads",
|
|
52026
52206
|
description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce, and manage the brands your library tracks. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
|
|
@@ -52210,7 +52390,7 @@ function unknownFlagEnvelope(unknown, commandPath, suggestion) {
|
|
|
52210
52390
|
};
|
|
52211
52391
|
}
|
|
52212
52392
|
function commandPathOf(root, argv) {
|
|
52213
|
-
const
|
|
52393
|
+
const path39 = [];
|
|
52214
52394
|
let command = root;
|
|
52215
52395
|
for (const token of argv) {
|
|
52216
52396
|
if (token === "--" || token.startsWith("-")) {
|
|
@@ -52221,10 +52401,10 @@ function commandPathOf(root, argv) {
|
|
|
52221
52401
|
if (next === void 0 || typeof next !== "object") {
|
|
52222
52402
|
break;
|
|
52223
52403
|
}
|
|
52224
|
-
|
|
52404
|
+
path39.push(token);
|
|
52225
52405
|
command = next;
|
|
52226
52406
|
}
|
|
52227
|
-
return
|
|
52407
|
+
return path39.join(" ");
|
|
52228
52408
|
}
|
|
52229
52409
|
function refuseUnknownFlags(root, argv) {
|
|
52230
52410
|
const unknown = findUnknownFlags(root, argv);
|
|
@@ -52258,7 +52438,7 @@ function getCliVersion() {
|
|
|
52258
52438
|
}
|
|
52259
52439
|
|
|
52260
52440
|
// src/cli.ts
|
|
52261
|
-
var main =
|
|
52441
|
+
var main = defineCommand228({
|
|
52262
52442
|
meta: {
|
|
52263
52443
|
name: "baker",
|
|
52264
52444
|
version: getCliVersion(),
|