@koda-sl/baker-cli 0.378.0 → 0.379.0-dev.0114084a3
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 +1 -1
- package/dist/{chunk-FGHMWBUD.js → chunk-CHJOTJTZ.js} +4 -4
- package/dist/chunk-CHJOTJTZ.js.map +1 -0
- package/dist/cli.js +875 -419
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-FGHMWBUD.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
validateCanvasDeep,
|
|
71
71
|
withoutCastName,
|
|
72
72
|
ytDlpBlockSignal
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-CHJOTJTZ.js";
|
|
74
74
|
import {
|
|
75
75
|
NAME_CONTAINS_ARG,
|
|
76
76
|
csvOrJson,
|
|
@@ -143,7 +143,7 @@ import {
|
|
|
143
143
|
} from "./chunk-HJEMOSPH.js";
|
|
144
144
|
|
|
145
145
|
// src/cli.ts
|
|
146
|
-
import { defineCommand as
|
|
146
|
+
import { defineCommand as defineCommand255, runMain } from "citty";
|
|
147
147
|
|
|
148
148
|
// src/cache-flag.ts
|
|
149
149
|
var NO_CACHE_ARG = {
|
|
@@ -4534,6 +4534,9 @@ var chatChangeTypeSchema = z13.enum([
|
|
|
4534
4534
|
"image",
|
|
4535
4535
|
"video",
|
|
4536
4536
|
"followed-advertiser",
|
|
4537
|
+
// A connected social account feeding the image and video libraries, keyed
|
|
4538
|
+
// on `platform:handle`. Immediate — see convex/mediaSources/mutations.ts.
|
|
4539
|
+
"media-source",
|
|
4537
4540
|
// A landing page saved to the reference library, keyed on the page.
|
|
4538
4541
|
"landing-reference",
|
|
4539
4542
|
// One Studio batch — the takes of one brief, as a set. See convex/lib/validators.ts.
|
|
@@ -6398,6 +6401,9 @@ var imageSourceSchema = z20.enum([
|
|
|
6398
6401
|
"google_testimonial",
|
|
6399
6402
|
"trustpilot_testimonial",
|
|
6400
6403
|
"instagram",
|
|
6404
|
+
"tiktok",
|
|
6405
|
+
"linkedin",
|
|
6406
|
+
"facebook",
|
|
6401
6407
|
"pexels",
|
|
6402
6408
|
"pixabay",
|
|
6403
6409
|
// Retired stock provider — kept so existing library rows stay filterable.
|
|
@@ -8209,6 +8215,7 @@ var videoSourceSchema = z30.enum([
|
|
|
8209
8215
|
"dailymotion",
|
|
8210
8216
|
"facebook",
|
|
8211
8217
|
"instagram",
|
|
8218
|
+
"linkedin",
|
|
8212
8219
|
"loom",
|
|
8213
8220
|
"newgrounds",
|
|
8214
8221
|
"ok",
|
|
@@ -12109,9 +12116,9 @@ var COPY_LIST_FLAG = {
|
|
|
12109
12116
|
descriptions: "--descriptions",
|
|
12110
12117
|
longHeadlines: "--long-headlines"
|
|
12111
12118
|
};
|
|
12112
|
-
function valueAt(root,
|
|
12119
|
+
function valueAt(root, path49) {
|
|
12113
12120
|
let node = root;
|
|
12114
|
-
for (const key of
|
|
12121
|
+
for (const key of path49) {
|
|
12115
12122
|
if (node === null || typeof node !== "object") return void 0;
|
|
12116
12123
|
node = node[key];
|
|
12117
12124
|
}
|
|
@@ -12344,11 +12351,11 @@ function parseKeywordEntry(raw, defaultMatch) {
|
|
|
12344
12351
|
function rawTextEntries(value, rawArgs) {
|
|
12345
12352
|
return repeatedValues(rawArgs, "text", value).flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
12346
12353
|
}
|
|
12347
|
-
function rawFileEntries(
|
|
12348
|
-
if (typeof
|
|
12354
|
+
function rawFileEntries(path49) {
|
|
12355
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
12349
12356
|
return [];
|
|
12350
12357
|
}
|
|
12351
|
-
return readFileSync2(
|
|
12358
|
+
return readFileSync2(path49, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
12352
12359
|
}
|
|
12353
12360
|
function keywordEntries(args5, rawArgs) {
|
|
12354
12361
|
const defaultMatch = typeof args5["match-type"] === "string" ? args5["match-type"].toUpperCase() : void 0;
|
|
@@ -12371,14 +12378,14 @@ function keywordEntries(args5, rawArgs) {
|
|
|
12371
12378
|
}
|
|
12372
12379
|
return entries;
|
|
12373
12380
|
}
|
|
12374
|
-
function loadJsonFileArg(
|
|
12375
|
-
if (typeof
|
|
12381
|
+
function loadJsonFileArg(path49) {
|
|
12382
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
12376
12383
|
return {};
|
|
12377
12384
|
}
|
|
12378
|
-
const inline =
|
|
12379
|
-
const source = inline ? "inline JSON" :
|
|
12385
|
+
const inline = path49.trimStart().startsWith("{");
|
|
12386
|
+
const source = inline ? "inline JSON" : path49;
|
|
12380
12387
|
try {
|
|
12381
|
-
const parsed = JSON.parse(inline ?
|
|
12388
|
+
const parsed = JSON.parse(inline ? path49 : readFileSync2(path49, "utf8"));
|
|
12382
12389
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
12383
12390
|
failWriteValidation(`${source} must contain a JSON object`);
|
|
12384
12391
|
}
|
|
@@ -12515,10 +12522,10 @@ async function stageUpdate(kind, customerId, target2, payload, hints2) {
|
|
|
12515
12522
|
async function stageTarget(kind, customerId, target2, hints2) {
|
|
12516
12523
|
await stageGoogleOp({ kind, customerId, target: target2 }, hints2);
|
|
12517
12524
|
}
|
|
12518
|
-
async function draftAction(
|
|
12525
|
+
async function draftAction(path49, body, chat) {
|
|
12519
12526
|
try {
|
|
12520
12527
|
const chatId = resolveChatId(chat);
|
|
12521
|
-
const response = await apiPost(
|
|
12528
|
+
const response = await apiPost(path49, { chatId, ...body });
|
|
12522
12529
|
writeJsonEnvelope(response);
|
|
12523
12530
|
} catch (err) {
|
|
12524
12531
|
handleGoogleError(err);
|
|
@@ -14936,14 +14943,14 @@ function mappingRowProblem(row) {
|
|
|
14936
14943
|
|
|
14937
14944
|
// ../api/src/event-sources/template.ts
|
|
14938
14945
|
var MENTION = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
14939
|
-
function mentionOf(
|
|
14940
|
-
return `{{${
|
|
14946
|
+
function mentionOf(path49) {
|
|
14947
|
+
return `{{${path49}}}`;
|
|
14941
14948
|
}
|
|
14942
14949
|
function templateMentions(template) {
|
|
14943
14950
|
const seen = [];
|
|
14944
14951
|
for (const match of template.matchAll(MENTION)) {
|
|
14945
|
-
const
|
|
14946
|
-
if (
|
|
14952
|
+
const path49 = (match[1] ?? "").trim();
|
|
14953
|
+
if (path49 !== "" && !seen.includes(path49)) seen.push(path49);
|
|
14947
14954
|
}
|
|
14948
14955
|
return seen;
|
|
14949
14956
|
}
|
|
@@ -18298,17 +18305,17 @@ function ignoredColumnHints(columns) {
|
|
|
18298
18305
|
`Ignored ${columns.length} column(s) that are not part of a conversion: ${columns.join(", ")}. A conversion carries an order id, a date, and something to match on: a click id (gclid / gbraid / wbraid), an email, a phone, or all four of givenName + familyName + country + postalCode. Optionally a value + currency, conversionCount, and eventSource (WEB / APP / IN_STORE / PHONE / OTHER). A column named just \`Name\` is ignored on purpose \u2014 Google needs the first and last name separately, so split it before re-running.`
|
|
18299
18306
|
];
|
|
18300
18307
|
}
|
|
18301
|
-
function readRowsFile(
|
|
18302
|
-
const inline =
|
|
18308
|
+
function readRowsFile(path49) {
|
|
18309
|
+
const inline = path49.trimStart().startsWith("[") || path49.trimStart().startsWith("{");
|
|
18303
18310
|
let text2;
|
|
18304
18311
|
try {
|
|
18305
|
-
text2 = inline ?
|
|
18312
|
+
text2 = inline ? path49 : readFileSync4(path49, "utf8");
|
|
18306
18313
|
} catch (err) {
|
|
18307
|
-
failWriteValidation(`could not read ${
|
|
18314
|
+
failWriteValidation(`could not read ${path49}: ${err instanceof Error ? err.message : String(err)}`);
|
|
18308
18315
|
}
|
|
18309
18316
|
const parsed = parseConversionRowsText(text2);
|
|
18310
18317
|
if (!parsed.ok) {
|
|
18311
|
-
failWriteValidation(`${inline ? "the conversions passed inline" :
|
|
18318
|
+
failWriteValidation(`${inline ? "the conversions passed inline" : path49}: ${parsed.error}`);
|
|
18312
18319
|
}
|
|
18313
18320
|
return { rows: parsed.rows, ignoredColumns: parsed.ignoredColumns };
|
|
18314
18321
|
}
|
|
@@ -20183,19 +20190,19 @@ function failWriteValidation2(message) {
|
|
|
20183
20190
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
20184
20191
|
process.exit(1);
|
|
20185
20192
|
}
|
|
20186
|
-
function loadJsonFileArg2(
|
|
20187
|
-
if (typeof
|
|
20193
|
+
function loadJsonFileArg2(path49) {
|
|
20194
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20188
20195
|
return {};
|
|
20189
20196
|
}
|
|
20190
20197
|
try {
|
|
20191
|
-
const parsed = JSON.parse(readFileSync5(
|
|
20198
|
+
const parsed = JSON.parse(readFileSync5(path49, "utf8"));
|
|
20192
20199
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20193
|
-
failWriteValidation2(`${
|
|
20200
|
+
failWriteValidation2(`${path49} must contain a JSON object`);
|
|
20194
20201
|
}
|
|
20195
20202
|
return parsed;
|
|
20196
20203
|
} catch (err) {
|
|
20197
20204
|
if (err instanceof SyntaxError) {
|
|
20198
|
-
failWriteValidation2(`${
|
|
20205
|
+
failWriteValidation2(`${path49} is not valid JSON: ${err.message}`);
|
|
20199
20206
|
}
|
|
20200
20207
|
throw err;
|
|
20201
20208
|
}
|
|
@@ -20280,15 +20287,15 @@ function parseLocaleFlag(value) {
|
|
|
20280
20287
|
}
|
|
20281
20288
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
20282
20289
|
}
|
|
20283
|
-
function loadTargetingFileArg(
|
|
20284
|
-
if (typeof
|
|
20290
|
+
function loadTargetingFileArg(path49) {
|
|
20291
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20285
20292
|
return void 0;
|
|
20286
20293
|
}
|
|
20287
|
-
const parsed = loadJsonFileArg2(
|
|
20294
|
+
const parsed = loadJsonFileArg2(path49);
|
|
20288
20295
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
20289
20296
|
if (!criteria.include) {
|
|
20290
20297
|
failWriteValidation2(
|
|
20291
|
-
`${
|
|
20298
|
+
`${path49} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
20292
20299
|
);
|
|
20293
20300
|
}
|
|
20294
20301
|
return criteria;
|
|
@@ -20323,14 +20330,14 @@ function parseCsvLine(line) {
|
|
|
20323
20330
|
cells.push(current);
|
|
20324
20331
|
return cells.map((cell3) => cell3.trim());
|
|
20325
20332
|
}
|
|
20326
|
-
function parseListFileArg(
|
|
20327
|
-
if (typeof
|
|
20333
|
+
function parseListFileArg(path49, maxRows) {
|
|
20334
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20328
20335
|
return void 0;
|
|
20329
20336
|
}
|
|
20330
|
-
const raw = readFileSync5(
|
|
20337
|
+
const raw = readFileSync5(path49, "utf8");
|
|
20331
20338
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
20332
20339
|
if (lines.length < 2) {
|
|
20333
|
-
failWriteValidation2(`${
|
|
20340
|
+
failWriteValidation2(`${path49} needs a header row and at least one data row`);
|
|
20334
20341
|
}
|
|
20335
20342
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
20336
20343
|
const rows = [];
|
|
@@ -20349,7 +20356,7 @@ function parseListFileArg(path48, maxRows) {
|
|
|
20349
20356
|
}
|
|
20350
20357
|
}
|
|
20351
20358
|
if (rows.length > maxRows) {
|
|
20352
|
-
failWriteValidation2(`${
|
|
20359
|
+
failWriteValidation2(`${path49} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
20353
20360
|
}
|
|
20354
20361
|
return { columns, rows };
|
|
20355
20362
|
}
|
|
@@ -20445,11 +20452,11 @@ function readPositionals(args5) {
|
|
|
20445
20452
|
function splitIdList(raw) {
|
|
20446
20453
|
return raw.split(",").map((id) => id.trim()).filter(Boolean);
|
|
20447
20454
|
}
|
|
20448
|
-
function idsFileEntries(
|
|
20449
|
-
if (typeof
|
|
20455
|
+
function idsFileEntries(path49) {
|
|
20456
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20450
20457
|
return [];
|
|
20451
20458
|
}
|
|
20452
|
-
return readFileSync5(
|
|
20459
|
+
return readFileSync5(path49, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
|
|
20453
20460
|
}
|
|
20454
20461
|
function requireTargets(args5, entity) {
|
|
20455
20462
|
const positionals = readPositionals(args5);
|
|
@@ -23211,9 +23218,9 @@ import { defineCommand as defineCommand44 } from "citty";
|
|
|
23211
23218
|
function asRecord(value) {
|
|
23212
23219
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
23213
23220
|
}
|
|
23214
|
-
function readPath2(row,
|
|
23221
|
+
function readPath2(row, path49) {
|
|
23215
23222
|
let current = row;
|
|
23216
|
-
for (const segment of
|
|
23223
|
+
for (const segment of path49.split(".")) {
|
|
23217
23224
|
const record = asRecord(current);
|
|
23218
23225
|
if (!record) return void 0;
|
|
23219
23226
|
current = record[segment];
|
|
@@ -23223,10 +23230,10 @@ function readPath2(row, path48) {
|
|
|
23223
23230
|
function projectFields(rows, paths) {
|
|
23224
23231
|
return rows.map((row) => {
|
|
23225
23232
|
const projected = {};
|
|
23226
|
-
for (const
|
|
23227
|
-
const value = readPath2(row,
|
|
23233
|
+
for (const path49 of paths) {
|
|
23234
|
+
const value = readPath2(row, path49);
|
|
23228
23235
|
if (value !== void 0) {
|
|
23229
|
-
projected[
|
|
23236
|
+
projected[path49] = value;
|
|
23230
23237
|
}
|
|
23231
23238
|
}
|
|
23232
23239
|
return projected;
|
|
@@ -23239,16 +23246,16 @@ function shapeListRows(rows, args5, compact4) {
|
|
|
23239
23246
|
const paths = fields.split(",").map((field) => field.trim()).filter((field) => field.length > 0);
|
|
23240
23247
|
if (paths.length > 0) {
|
|
23241
23248
|
const projected = projectFields(raw, paths).map((row, i) => {
|
|
23242
|
-
const missing = paths.filter((
|
|
23249
|
+
const missing = paths.filter((path49) => row[path49] === void 0);
|
|
23243
23250
|
const source = rows[i];
|
|
23244
23251
|
if (missing.length === 0 || source === void 0) return row;
|
|
23245
23252
|
const compactRow3 = compact4.row(source);
|
|
23246
|
-
for (const
|
|
23247
|
-
if (compactRow3[
|
|
23253
|
+
for (const path49 of missing) {
|
|
23254
|
+
if (compactRow3[path49] !== void 0) row[path49] = compactRow3[path49];
|
|
23248
23255
|
}
|
|
23249
23256
|
return row;
|
|
23250
23257
|
});
|
|
23251
|
-
const unmatched = paths.filter((
|
|
23258
|
+
const unmatched = paths.filter((path49) => projected.every((row) => row[path49] === void 0));
|
|
23252
23259
|
if (projected.length === 0 || unmatched.length === 0) return { rows: projected, fields: paths };
|
|
23253
23260
|
const carried = /* @__PURE__ */ new Set([...compact4.columns, ...raw.flatMap((row) => Object.keys(row))]);
|
|
23254
23261
|
return {
|
|
@@ -24618,54 +24625,54 @@ function buildCustomConversionRule(input) {
|
|
|
24618
24625
|
function customConversionRuleRefusal(rule) {
|
|
24619
24626
|
return ruleNodeRefusal(rule, "rule");
|
|
24620
24627
|
}
|
|
24621
|
-
function branchRefusal(key, value,
|
|
24628
|
+
function branchRefusal(key, value, path49) {
|
|
24622
24629
|
if (!Array.isArray(value) || value.length === 0) {
|
|
24623
|
-
return `${
|
|
24630
|
+
return `${path49}.${key} must be a non-empty array of conditions \u2014 an empty one counts every event the pixel sends`;
|
|
24624
24631
|
}
|
|
24625
24632
|
for (const [index, child] of value.entries()) {
|
|
24626
|
-
const refusal = ruleNodeRefusal(child, `${
|
|
24633
|
+
const refusal = ruleNodeRefusal(child, `${path49}.${key}[${index}]`);
|
|
24627
24634
|
if (refusal) {
|
|
24628
24635
|
return refusal;
|
|
24629
24636
|
}
|
|
24630
24637
|
}
|
|
24631
24638
|
return void 0;
|
|
24632
24639
|
}
|
|
24633
|
-
function conditionRefusal(key, value,
|
|
24634
|
-
return key === "and" || key === "or" ? branchRefusal(key, value,
|
|
24640
|
+
function conditionRefusal(key, value, path49) {
|
|
24641
|
+
return key === "and" || key === "or" ? branchRefusal(key, value, path49) : leafRefusal(key, value, path49);
|
|
24635
24642
|
}
|
|
24636
|
-
function ruleNodeRefusal(node,
|
|
24643
|
+
function ruleNodeRefusal(node, path49) {
|
|
24637
24644
|
if (!isRecord2(node)) {
|
|
24638
|
-
return `${
|
|
24645
|
+
return `${path49} must be an object like {"URL":{"i_contains":"/thank-you"}}`;
|
|
24639
24646
|
}
|
|
24640
24647
|
const entries = Object.entries(node);
|
|
24641
24648
|
if (entries.length === 0) {
|
|
24642
|
-
return `${
|
|
24649
|
+
return `${path49} is empty \u2014 a rule with no condition counts every event the pixel sends`;
|
|
24643
24650
|
}
|
|
24644
24651
|
if (entries.length > 1) {
|
|
24645
|
-
return `${
|
|
24652
|
+
return `${path49} names ${entries.length} conditions side by side (${entries.map(([key]) => key).join(", ")}) \u2014 Meta reads one branch or one field test per object, so combine them with {"and":[\u2026]}`;
|
|
24646
24653
|
}
|
|
24647
24654
|
for (const [key, value] of entries) {
|
|
24648
|
-
const refusal = conditionRefusal(key, value,
|
|
24655
|
+
const refusal = conditionRefusal(key, value, path49);
|
|
24649
24656
|
if (refusal) {
|
|
24650
24657
|
return refusal;
|
|
24651
24658
|
}
|
|
24652
24659
|
}
|
|
24653
24660
|
return void 0;
|
|
24654
24661
|
}
|
|
24655
|
-
function leafRefusal(field, condition,
|
|
24662
|
+
function leafRefusal(field, condition, path49) {
|
|
24656
24663
|
if (!isRecord2(condition)) {
|
|
24657
|
-
return `${
|
|
24664
|
+
return `${path49}.${field} must be a test like {"i_contains":"/thank-you"}, not a bare value`;
|
|
24658
24665
|
}
|
|
24659
24666
|
const tests = Object.entries(condition);
|
|
24660
24667
|
if (tests.length === 0) {
|
|
24661
|
-
return `${
|
|
24668
|
+
return `${path49}.${field} names no test \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")}`;
|
|
24662
24669
|
}
|
|
24663
24670
|
if (tests.length > 1) {
|
|
24664
|
-
return `${
|
|
24671
|
+
return `${path49}.${field} names ${tests.length} operators at once (${tests.map(([operator]) => operator).join(", ")}) \u2014 test a field once per condition and combine them with {"and":[\u2026]}`;
|
|
24665
24672
|
}
|
|
24666
24673
|
for (const [operator] of tests) {
|
|
24667
24674
|
if (!RULE_OPERATORS[operator]) {
|
|
24668
|
-
return `${
|
|
24675
|
+
return `${path49}.${field} uses "${operator}", which is not a Meta rule operator \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")} (URL matching is i_contains, not contains or includes)`;
|
|
24669
24676
|
}
|
|
24670
24677
|
}
|
|
24671
24678
|
return void 0;
|
|
@@ -25146,7 +25153,8 @@ var LEAD_FORM_CTA_TYPES = [
|
|
|
25146
25153
|
var AD_FORMATS2 = ["SINGLE_IMAGE", "CAROUSEL", "SINGLE_VIDEO"];
|
|
25147
25154
|
var ENROLL_STATUSES = ["OPT_IN", "OPT_OUT"];
|
|
25148
25155
|
var STAGEABLE_CREATE_STATUSES4 = ["ACTIVE", "PAUSED"];
|
|
25149
|
-
var UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED"];
|
|
25156
|
+
var UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED", "DELETED"];
|
|
25157
|
+
var CREATIVE_UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED"];
|
|
25150
25158
|
var CUSTOM_AUDIENCE_SUBTYPES = ["CUSTOM", "WEBSITE", "ENGAGEMENT", "LOOKALIKE"];
|
|
25151
25159
|
var CUSTOMER_FILE_SOURCES = [
|
|
25152
25160
|
"USER_PROVIDED_ONLY",
|
|
@@ -25369,7 +25377,7 @@ function positionsMissingRequiredFeed(targeting) {
|
|
|
25369
25377
|
// ../api/src/ads-meta/ops.ts
|
|
25370
25378
|
var tempRefSchema4 = z37.string().regex(TEMP_REF_REGEX4, "expected a meta_temp_* reference");
|
|
25371
25379
|
var parentRefSchema3 = z37.union([z37.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema4]);
|
|
25372
|
-
var moneySchema2 = z37.
|
|
25380
|
+
var moneySchema2 = z37.strictObject({
|
|
25373
25381
|
amount: z37.string().regex(/^\d+(\.\d{1,3})?$/, "expected a decimal amount like 50 or 50.00").refine((val) => Number(val) > 0, "amount must be greater than zero"),
|
|
25374
25382
|
currencyCode: z37.string().length(3).optional()
|
|
25375
25383
|
});
|
|
@@ -25380,11 +25388,11 @@ var updateStatusSchema = z37.enum(UPDATE_STATUSES);
|
|
|
25380
25388
|
function currencyMinimums2(currencyCode) {
|
|
25381
25389
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
25382
25390
|
}
|
|
25383
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
25391
|
+
function validateDailyBudgetFloor(money, ctx, path49) {
|
|
25384
25392
|
if (money?.currencyCode) {
|
|
25385
25393
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
25386
25394
|
if (Number(money.amount) < min) {
|
|
25387
|
-
ctx.addIssue({ code: "custom", path:
|
|
25395
|
+
ctx.addIssue({ code: "custom", path: path49, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
25388
25396
|
}
|
|
25389
25397
|
}
|
|
25390
25398
|
}
|
|
@@ -25457,7 +25465,7 @@ function targetingHardLimitsDemographics(t) {
|
|
|
25457
25465
|
return narrowsAgeMax || narrowsAgeMin || narrowsGender;
|
|
25458
25466
|
}
|
|
25459
25467
|
var specialAdCategoriesSchema = z37.array(z37.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
|
|
25460
|
-
var campaignCreateSchema4 = z37.
|
|
25468
|
+
var campaignCreateSchema4 = z37.strictObject({
|
|
25461
25469
|
name: z37.string().min(1).max(META_LIMITS.campaign.nameMax),
|
|
25462
25470
|
objective: z37.enum(OBJECTIVES2),
|
|
25463
25471
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
@@ -25495,7 +25503,7 @@ var campaignCreateSchema4 = z37.object({
|
|
|
25495
25503
|
});
|
|
25496
25504
|
}
|
|
25497
25505
|
});
|
|
25498
|
-
var campaignUpdateSchema4 = z37.
|
|
25506
|
+
var campaignUpdateSchema4 = z37.strictObject({
|
|
25499
25507
|
name: z37.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
|
|
25500
25508
|
status: updateStatusSchema.optional(),
|
|
25501
25509
|
bid_strategy: z37.enum(BID_STRATEGIES2).optional(),
|
|
@@ -25513,7 +25521,7 @@ var campaignUpdateSchema4 = z37.object({
|
|
|
25513
25521
|
}
|
|
25514
25522
|
validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
|
|
25515
25523
|
});
|
|
25516
|
-
var
|
|
25524
|
+
var promotedObjectFields = {
|
|
25517
25525
|
page_id: parentRefSchema3.optional(),
|
|
25518
25526
|
pixel_id: z37.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
25519
25527
|
custom_event_type: z37.enum(CUSTOM_EVENT_TYPES).optional(),
|
|
@@ -25533,9 +25541,12 @@ var promotedObjectSchema = z37.object({
|
|
|
25533
25541
|
product_set_id: z37.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
25534
25542
|
whatsapp_phone_number: z37.string().optional(),
|
|
25535
25543
|
offline_conversion_data_set_id: z37.string().regex(NUMERIC_ID_REGEX3).optional()
|
|
25536
|
-
}
|
|
25544
|
+
};
|
|
25545
|
+
var promotedObjectSchema = z37.strictObject(promotedObjectFields, {
|
|
25546
|
+
error: (issue) => issue.code === "unrecognized_keys" ? `promoted_object does not take ${issue.keys.map((key) => `"${key}"`).join(", ")} \u2014 it takes ${Object.keys(promotedObjectFields).join(", ")}` : void 0
|
|
25547
|
+
});
|
|
25537
25548
|
var attributionSpecSchema = z37.array(
|
|
25538
|
-
z37.
|
|
25549
|
+
z37.strictObject({
|
|
25539
25550
|
event_type: z37.enum(ATTRIBUTION_EVENT_TYPES),
|
|
25540
25551
|
window_days: z37.union([z37.literal(1), z37.literal(7), z37.literal(28)])
|
|
25541
25552
|
})
|
|
@@ -25700,7 +25711,7 @@ function validateAdSetPlacements(p, ctx) {
|
|
|
25700
25711
|
ctx.addIssue({ code: "custom", path: ["targeting"], message: `${message} (${PLACEMENT_TARGETING_DOC})` });
|
|
25701
25712
|
}
|
|
25702
25713
|
}
|
|
25703
|
-
var adSetCreateSchema = z37.
|
|
25714
|
+
var adSetCreateSchema = z37.strictObject(adSetFields).superRefine((p, ctx) => {
|
|
25704
25715
|
validateAdSetBudgetAndBid(p, ctx);
|
|
25705
25716
|
validateAdSetPromotedObject(p, ctx);
|
|
25706
25717
|
validateAdvantageAudience(p, ctx);
|
|
@@ -25713,7 +25724,7 @@ var adSetCreateSchema = z37.object(adSetFields).superRefine((p, ctx) => {
|
|
|
25713
25724
|
});
|
|
25714
25725
|
}
|
|
25715
25726
|
});
|
|
25716
|
-
var adSetUpdateSchema = z37.
|
|
25727
|
+
var adSetUpdateSchema = z37.strictObject({
|
|
25717
25728
|
name: adSetFields.name.optional(),
|
|
25718
25729
|
status: updateStatusSchema.optional(),
|
|
25719
25730
|
dailyBudget: moneySchema2.optional(),
|
|
@@ -25743,7 +25754,7 @@ var adSetUpdateSchema = z37.object({
|
|
|
25743
25754
|
var messageSchema = z37.string().min(1).max(META_LIMITS.creative.messageHardMax);
|
|
25744
25755
|
var headlineSchema2 = z37.string().min(1).max(META_LIMITS.creative.headlineMax);
|
|
25745
25756
|
var descriptionSchema = z37.string().min(1).max(META_LIMITS.creative.descriptionMax);
|
|
25746
|
-
var callToActionSchema = z37.
|
|
25757
|
+
var callToActionSchema = z37.strictObject({
|
|
25747
25758
|
type: z37.enum(CTA_TYPES2),
|
|
25748
25759
|
/** Overrides the base link for the CTA button; defaults to the ad's link. */
|
|
25749
25760
|
link: httpsUrlSchema3.optional(),
|
|
@@ -25764,7 +25775,7 @@ var callToActionSchema = z37.object({
|
|
|
25764
25775
|
});
|
|
25765
25776
|
}
|
|
25766
25777
|
});
|
|
25767
|
-
var creativeEnhancementsSchema = z37.
|
|
25778
|
+
var creativeEnhancementsSchema = z37.strictObject({
|
|
25768
25779
|
standardEnhancements: z37.enum(ENROLL_STATUSES).optional(),
|
|
25769
25780
|
features: z37.record(z37.string(), z37.enum(ENROLL_STATUSES)).optional()
|
|
25770
25781
|
});
|
|
@@ -25795,7 +25806,7 @@ function countImageRefs(p) {
|
|
|
25795
25806
|
function countVideoRefs(p) {
|
|
25796
25807
|
return [p.videoId, p.videoRef].filter(Boolean).length;
|
|
25797
25808
|
}
|
|
25798
|
-
var singleCreativeSchema = z37.
|
|
25809
|
+
var singleCreativeSchema = z37.strictObject({
|
|
25799
25810
|
creativeType: z37.literal("single"),
|
|
25800
25811
|
...creativeSharedFields,
|
|
25801
25812
|
/** Primary text. */
|
|
@@ -25829,7 +25840,7 @@ var singleCreativeSchema = z37.object({
|
|
|
25829
25840
|
});
|
|
25830
25841
|
}
|
|
25831
25842
|
});
|
|
25832
|
-
var carouselCardSchema = z37.
|
|
25843
|
+
var carouselCardSchema = z37.strictObject({
|
|
25833
25844
|
link: httpsUrlSchema3,
|
|
25834
25845
|
headline: z37.string().max(META_LIMITS.creative.headlineMax).optional(),
|
|
25835
25846
|
description: z37.string().max(META_LIMITS.creative.descriptionMax).optional(),
|
|
@@ -25852,7 +25863,7 @@ var carouselCardSchema = z37.object({
|
|
|
25852
25863
|
ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
|
|
25853
25864
|
}
|
|
25854
25865
|
});
|
|
25855
|
-
var carouselCreativeSchema2 = z37.
|
|
25866
|
+
var carouselCreativeSchema2 = z37.strictObject({
|
|
25856
25867
|
creativeType: z37.literal("carousel"),
|
|
25857
25868
|
...creativeSharedFields,
|
|
25858
25869
|
message: messageSchema,
|
|
@@ -25874,19 +25885,19 @@ var carouselCreativeSchema2 = z37.object({
|
|
|
25874
25885
|
});
|
|
25875
25886
|
}
|
|
25876
25887
|
});
|
|
25877
|
-
var dynamicImageSchema = z37.
|
|
25878
|
-
var dynamicVideoSchema = z37.
|
|
25888
|
+
var dynamicImageSchema = z37.strictObject({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
|
|
25889
|
+
var dynamicVideoSchema = z37.strictObject({
|
|
25879
25890
|
videoId: videoMediaFields.videoId,
|
|
25880
25891
|
videoRef: videoMediaFields.videoRef,
|
|
25881
25892
|
thumbnailHash: videoMediaFields.thumbnailHash
|
|
25882
25893
|
}).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
|
|
25883
25894
|
var DYN = META_LIMITS.creative;
|
|
25884
|
-
var dynamicCreativeSchema = z37.
|
|
25895
|
+
var dynamicCreativeSchema = z37.strictObject({
|
|
25885
25896
|
creativeType: z37.literal("dynamic"),
|
|
25886
25897
|
...creativeSharedFields,
|
|
25887
|
-
bodies: z37.array(z37.
|
|
25888
|
-
titles: z37.array(z37.
|
|
25889
|
-
descriptions: z37.array(z37.
|
|
25898
|
+
bodies: z37.array(z37.strictObject({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
|
|
25899
|
+
titles: z37.array(z37.strictObject({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
|
|
25900
|
+
descriptions: z37.array(z37.strictObject({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
|
|
25890
25901
|
images: z37.array(dynamicImageSchema).optional(),
|
|
25891
25902
|
videos: z37.array(dynamicVideoSchema).optional(),
|
|
25892
25903
|
/**
|
|
@@ -25902,7 +25913,7 @@ var dynamicCreativeSchema = z37.object({
|
|
|
25902
25913
|
* different enums.
|
|
25903
25914
|
*/
|
|
25904
25915
|
call_to_action: callToActionSchema.optional(),
|
|
25905
|
-
link_urls: z37.array(z37.
|
|
25916
|
+
link_urls: z37.array(z37.strictObject({ website_url: httpsUrlSchema3, display_url: z37.string().optional() })).min(1),
|
|
25906
25917
|
/**
|
|
25907
25918
|
* `asset_feed_spec.optimization_type` — passed through as a free string on
|
|
25908
25919
|
* purpose. Meta's own 400 enumerates ten values and then accepts
|
|
@@ -25933,7 +25944,7 @@ var dynamicCreativeSchema = z37.object({
|
|
|
25933
25944
|
});
|
|
25934
25945
|
});
|
|
25935
25946
|
});
|
|
25936
|
-
var existingPostCreativeSchema = z37.
|
|
25947
|
+
var existingPostCreativeSchema = z37.strictObject({
|
|
25937
25948
|
creativeType: z37.literal("existing_post"),
|
|
25938
25949
|
name: creativeSharedFields.name,
|
|
25939
25950
|
/** "<page_id>_<post_id>" object story id of the post to promote. */
|
|
@@ -25942,7 +25953,7 @@ var existingPostCreativeSchema = z37.object({
|
|
|
25942
25953
|
url_tags: creativeSharedFields.url_tags,
|
|
25943
25954
|
enhancements: creativeSharedFields.enhancements
|
|
25944
25955
|
});
|
|
25945
|
-
var specCreativeSchema = z37.
|
|
25956
|
+
var specCreativeSchema = z37.strictObject({
|
|
25946
25957
|
creativeType: z37.literal("spec"),
|
|
25947
25958
|
name: creativeSharedFields.name,
|
|
25948
25959
|
url_tags: creativeSharedFields.url_tags,
|
|
@@ -25971,29 +25982,29 @@ var creativeContentSchema2 = z37.discriminatedUnion("creativeType", [
|
|
|
25971
25982
|
specCreativeSchema
|
|
25972
25983
|
]);
|
|
25973
25984
|
var adCreativeCreateSchema = creativeContentSchema2;
|
|
25974
|
-
var adCreativeUpdateSchema = z37.
|
|
25985
|
+
var adCreativeUpdateSchema = z37.strictObject({
|
|
25975
25986
|
name: z37.string().max(META_LIMITS.creative.nameMax).optional(),
|
|
25976
|
-
status:
|
|
25987
|
+
status: z37.enum(CREATIVE_UPDATE_STATUSES).optional(),
|
|
25977
25988
|
/** Content patch — only honored when the target is a staged meta_temp_* creative. */
|
|
25978
25989
|
content: z37.record(z37.string(), z37.unknown()).optional()
|
|
25979
25990
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
25980
|
-
var adCreateSchema2 = z37.
|
|
25991
|
+
var adCreateSchema2 = z37.strictObject({
|
|
25981
25992
|
name: z37.string().min(1).max(META_LIMITS.ad.nameMax),
|
|
25982
25993
|
adset_id: parentRefSchema3,
|
|
25983
25994
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
25984
|
-
creative: z37.
|
|
25995
|
+
creative: z37.strictObject({ creative_id: parentRefSchema3 }),
|
|
25985
25996
|
/** Conversion pixel / offline event set / view tags — structural passthrough. */
|
|
25986
25997
|
tracking_specs: z37.array(z37.record(z37.string(), z37.unknown())).optional()
|
|
25987
25998
|
});
|
|
25988
|
-
var adUpdateSchema2 = z37.
|
|
25999
|
+
var adUpdateSchema2 = z37.strictObject({
|
|
25989
26000
|
name: z37.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
|
|
25990
26001
|
status: updateStatusSchema.optional(),
|
|
25991
26002
|
/** Swapping the creative is the Meta way to "edit" an ad's creative. */
|
|
25992
|
-
creative: z37.
|
|
26003
|
+
creative: z37.strictObject({ creative_id: parentRefSchema3 }).optional(),
|
|
25993
26004
|
tracking_specs: z37.array(z37.record(z37.string(), z37.unknown())).optional()
|
|
25994
26005
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
25995
|
-
var lookalikeSpecSchema = z37.
|
|
25996
|
-
origin: z37.array(z37.
|
|
26006
|
+
var lookalikeSpecSchema = z37.strictObject({
|
|
26007
|
+
origin: z37.array(z37.strictObject({ id: parentRefSchema3 })).min(1),
|
|
25997
26008
|
ratio: z37.number().min(0.01).max(0.2).optional(),
|
|
25998
26009
|
country: z37.string().length(2).optional()
|
|
25999
26010
|
});
|
|
@@ -26011,7 +26022,7 @@ function mixedEventSourceTypes(rule) {
|
|
|
26011
26022
|
const distinct = [...new Set(types)].sort();
|
|
26012
26023
|
return distinct.length > 1 ? distinct : [];
|
|
26013
26024
|
}
|
|
26014
|
-
var customAudienceCreateSchema = z37.
|
|
26025
|
+
var customAudienceCreateSchema = z37.strictObject({
|
|
26015
26026
|
name: z37.string().min(1).max(META_LIMITS.audience.nameMax),
|
|
26016
26027
|
subtype: z37.enum(CUSTOM_AUDIENCE_SUBTYPES),
|
|
26017
26028
|
description: z37.string().max(500).optional(),
|
|
@@ -26043,11 +26054,11 @@ var customAudienceCreateSchema = z37.object({
|
|
|
26043
26054
|
});
|
|
26044
26055
|
}
|
|
26045
26056
|
});
|
|
26046
|
-
var customAudienceUpdateSchema = z37.
|
|
26057
|
+
var customAudienceUpdateSchema = z37.strictObject({
|
|
26047
26058
|
name: z37.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
|
|
26048
26059
|
description: z37.string().max(500).optional()
|
|
26049
26060
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
26050
|
-
var customConversionCreateSchema = z37.
|
|
26061
|
+
var customConversionCreateSchema = z37.strictObject({
|
|
26051
26062
|
name: z37.string().min(1).max(META_LIMITS.customConversion.nameMax),
|
|
26052
26063
|
description: z37.string().max(META_LIMITS.customConversion.descriptionMax).optional(),
|
|
26053
26064
|
/** The pixel the conversion counts from — `event_source_id` on the wire. Baker never creates pixels, so this is always a real id. */
|
|
@@ -26063,7 +26074,7 @@ var customConversionCreateSchema = z37.object({
|
|
|
26063
26074
|
ctx.addIssue({ code: "custom", path: ["rule"], message: refusal });
|
|
26064
26075
|
}
|
|
26065
26076
|
});
|
|
26066
|
-
var mediaUploadSchema = z37.
|
|
26077
|
+
var mediaUploadSchema = z37.strictObject({
|
|
26067
26078
|
kind: z37.enum(MEDIA_KINDS),
|
|
26068
26079
|
bakerImageId: bakerMediaIdSchema2.optional(),
|
|
26069
26080
|
bakerVideoId: bakerMediaIdSchema2.optional(),
|
|
@@ -26246,19 +26257,26 @@ function failWriteValidation3(message) {
|
|
|
26246
26257
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
26247
26258
|
process.exit(1);
|
|
26248
26259
|
}
|
|
26249
|
-
function
|
|
26250
|
-
if (
|
|
26260
|
+
function refuseDeleteByUpdate(payload, group) {
|
|
26261
|
+
if (payload.status === "DELETED") {
|
|
26262
|
+
failWriteValidation3(
|
|
26263
|
+
`update does not delete \u2014 deleting is permanent. Use \`baker ads meta ${group} delete <id>\` if the user asked to delete; otherwise pause or archive.`
|
|
26264
|
+
);
|
|
26265
|
+
}
|
|
26266
|
+
}
|
|
26267
|
+
function loadJsonFileArg3(path49) {
|
|
26268
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
26251
26269
|
return {};
|
|
26252
26270
|
}
|
|
26253
26271
|
try {
|
|
26254
|
-
const parsed = JSON.parse(readFileSync9(
|
|
26272
|
+
const parsed = JSON.parse(readFileSync9(path49, "utf8"));
|
|
26255
26273
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
26256
|
-
failWriteValidation3(`${
|
|
26274
|
+
failWriteValidation3(`${path49} must contain a JSON object`);
|
|
26257
26275
|
}
|
|
26258
26276
|
return parsed;
|
|
26259
26277
|
} catch (err) {
|
|
26260
26278
|
if (err instanceof SyntaxError) {
|
|
26261
|
-
failWriteValidation3(`${
|
|
26279
|
+
failWriteValidation3(`${path49} is not valid JSON: ${err.message}`);
|
|
26262
26280
|
}
|
|
26263
26281
|
throw err;
|
|
26264
26282
|
}
|
|
@@ -26453,6 +26471,7 @@ Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker a
|
|
|
26453
26471
|
start_time: parseDateFlag2(args5.start, "--start"),
|
|
26454
26472
|
stop_time: parseDateFlag2(args5.stop, "--stop")
|
|
26455
26473
|
});
|
|
26474
|
+
refuseDeleteByUpdate(payload, "campaigns");
|
|
26456
26475
|
await stageOp2({
|
|
26457
26476
|
kind: "campaign.update",
|
|
26458
26477
|
accountId,
|
|
@@ -26613,6 +26632,7 @@ Example: baker ads meta adsets update 6123 --daily-budget 80`
|
|
|
26613
26632
|
...payload
|
|
26614
26633
|
} = adSetPayloadFromFlags(args5);
|
|
26615
26634
|
const merged = mergePayload3(loadJsonFileArg3(args5.file), payload);
|
|
26635
|
+
refuseDeleteByUpdate(merged, "adsets");
|
|
26616
26636
|
await stageOp2({
|
|
26617
26637
|
kind: "adSet.update",
|
|
26618
26638
|
accountId,
|
|
@@ -26806,6 +26826,7 @@ Example: baker ads meta ads update 6123 --creative meta_temp_cr02`
|
|
|
26806
26826
|
status: upper(args5.status),
|
|
26807
26827
|
creative: args5.creative ? { creative_id: String(args5.creative) } : void 0
|
|
26808
26828
|
});
|
|
26829
|
+
refuseDeleteByUpdate(payload, "ads");
|
|
26809
26830
|
await stageOp2({
|
|
26810
26831
|
kind: "ad.update",
|
|
26811
26832
|
accountId,
|
|
@@ -26951,10 +26972,16 @@ Example: baker ads meta media upload --kind image --image-id <bakerImageId>`
|
|
|
26951
26972
|
});
|
|
26952
26973
|
}
|
|
26953
26974
|
});
|
|
26975
|
+
var STATUS_BY_COMMAND = { pause: "PAUSED", resume: "ACTIVE", archive: "ARCHIVED", delete: "DELETED" };
|
|
26976
|
+
var STATUS_COMMAND_NOTE = {
|
|
26977
|
+
archive: "Archived stays readable in Ads Manager and can be found with --effective-status ARCHIVED.",
|
|
26978
|
+
delete: "Deleting is permanent and cannot be undone \u2014 Meta removes it and everything under it. Prefer pause or archive unless the user asked to delete."
|
|
26979
|
+
};
|
|
26954
26980
|
function statusCommand3(name, kind, label) {
|
|
26955
|
-
const status = name
|
|
26981
|
+
const status = STATUS_BY_COMMAND[name];
|
|
26982
|
+
const note = STATUS_COMMAND_NOTE[name];
|
|
26956
26983
|
return defineCommand57({
|
|
26957
|
-
meta: { name, description: `Stage ${name} for a ${label}. ${STAGED_NOTE2}` },
|
|
26984
|
+
meta: { name, description: `Stage ${name} for a ${label}. ${note ? `${note} ` : ""}${STAGED_NOTE2}` },
|
|
26958
26985
|
args: { id: { type: "positional", description: `${label} id`, required: true }, ...accountArgs2 },
|
|
26959
26986
|
run: async ({ args: args5 }) => {
|
|
26960
26987
|
const accountId = bareAccountId2(args5);
|
|
@@ -27006,14 +27033,17 @@ function duplicateCommand2(entity, label) {
|
|
|
27006
27033
|
var campaignsPauseCommand2 = statusCommand3("pause", "campaign.update", "campaign");
|
|
27007
27034
|
var campaignsResumeCommand2 = statusCommand3("resume", "campaign.update", "campaign");
|
|
27008
27035
|
var campaignsArchiveCommand2 = statusCommand3("archive", "campaign.update", "campaign");
|
|
27036
|
+
var campaignsDeleteCommand = statusCommand3("delete", "campaign.update", "campaign");
|
|
27009
27037
|
var campaignsDuplicateCommand2 = duplicateCommand2("campaign", "campaign");
|
|
27010
27038
|
var adSetsPauseCommand = statusCommand3("pause", "adSet.update", "ad set");
|
|
27011
27039
|
var adSetsResumeCommand = statusCommand3("resume", "adSet.update", "ad set");
|
|
27012
27040
|
var adSetsArchiveCommand = statusCommand3("archive", "adSet.update", "ad set");
|
|
27041
|
+
var adSetsDeleteCommand = statusCommand3("delete", "adSet.update", "ad set");
|
|
27013
27042
|
var adSetsDuplicateCommand = duplicateCommand2("adSet", "ad set");
|
|
27014
27043
|
var adsPauseCommand = statusCommand3("pause", "ad.update", "ad");
|
|
27015
27044
|
var adsResumeCommand = statusCommand3("resume", "ad.update", "ad");
|
|
27016
27045
|
var adsArchiveCommand = statusCommand3("archive", "ad.update", "ad");
|
|
27046
|
+
var adsDeleteCommand = statusCommand3("delete", "ad.update", "ad");
|
|
27017
27047
|
var adsDuplicateCommand = duplicateCommand2("ad", "ad");
|
|
27018
27048
|
|
|
27019
27049
|
// src/commands/ads/meta/ads.ts
|
|
@@ -27061,7 +27091,7 @@ var listCommand4 = defineCommand58({
|
|
|
27061
27091
|
var adsListCommand = defineCommand58({
|
|
27062
27092
|
meta: {
|
|
27063
27093
|
name: "ads",
|
|
27064
|
-
description: `List ads in a Meta ad account, or stage writes (create/update/pause/resume/archive/duplicate/retag).
|
|
27094
|
+
description: `List ads in a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate/retag).
|
|
27065
27095
|
Defaults to ACTIVE only \u2014 pass --all-statuses to widen. Write subcommands stage ops on this chat's draft.
|
|
27066
27096
|
|
|
27067
27097
|
The dashboard shows effective_status (e.g. WITH_ISSUES, PENDING_REVIEW, DISAPPROVED, ADSET_PAUSED), not status.
|
|
@@ -27086,6 +27116,7 @@ Examples:
|
|
|
27086
27116
|
pause: adsPauseCommand,
|
|
27087
27117
|
resume: adsResumeCommand,
|
|
27088
27118
|
archive: adsArchiveCommand,
|
|
27119
|
+
delete: adsDeleteCommand,
|
|
27089
27120
|
duplicate: adsDuplicateCommand,
|
|
27090
27121
|
retag: adsRetagCommand
|
|
27091
27122
|
},
|
|
@@ -27141,7 +27172,7 @@ var listCommand5 = defineCommand59({
|
|
|
27141
27172
|
var adsetsCommand = defineCommand59({
|
|
27142
27173
|
meta: {
|
|
27143
27174
|
name: "adsets",
|
|
27144
|
-
description: `List ad sets in a Meta ad account, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
27175
|
+
description: `List ad sets in a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate).
|
|
27145
27176
|
Defaults to ACTIVE only. Write subcommands stage ops on this chat's draft.
|
|
27146
27177
|
|
|
27147
27178
|
Listings print a table by default: id, name, campaign_id, effective_status, optimization_goal, billing_event,
|
|
@@ -27162,6 +27193,7 @@ Examples:
|
|
|
27162
27193
|
pause: adSetsPauseCommand,
|
|
27163
27194
|
resume: adSetsResumeCommand,
|
|
27164
27195
|
archive: adSetsArchiveCommand,
|
|
27196
|
+
delete: adSetsDeleteCommand,
|
|
27165
27197
|
duplicate: adSetsDuplicateCommand
|
|
27166
27198
|
},
|
|
27167
27199
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
@@ -27300,7 +27332,7 @@ var listCommand7 = defineCommand62({
|
|
|
27300
27332
|
var campaignsCommand3 = defineCommand62({
|
|
27301
27333
|
meta: {
|
|
27302
27334
|
name: "campaigns",
|
|
27303
|
-
description: `List campaigns for a Meta ad account, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
27335
|
+
description: `List campaigns for a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate).
|
|
27304
27336
|
Defaults to ACTIVE only \u2014 pass --all-statuses to widen. Write subcommands stage ops on this chat's draft and
|
|
27305
27337
|
apply only when the chat is published.
|
|
27306
27338
|
|
|
@@ -27327,6 +27359,7 @@ Examples:
|
|
|
27327
27359
|
pause: campaignsPauseCommand2,
|
|
27328
27360
|
resume: campaignsResumeCommand2,
|
|
27329
27361
|
archive: campaignsArchiveCommand2,
|
|
27362
|
+
delete: campaignsDeleteCommand,
|
|
27330
27363
|
duplicate: campaignsDuplicateCommand2
|
|
27331
27364
|
},
|
|
27332
27365
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
@@ -31939,12 +31972,12 @@ function flowExists(slug) {
|
|
|
31939
31972
|
return existsSync3(join2(flowsDir(), slug, "_data.json"));
|
|
31940
31973
|
}
|
|
31941
31974
|
function readFlowTree(slug) {
|
|
31942
|
-
const
|
|
31943
|
-
if (!existsSync3(
|
|
31975
|
+
const path49 = join2(flowsDir(), slug, "_data.json");
|
|
31976
|
+
if (!existsSync3(path49)) {
|
|
31944
31977
|
failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
|
|
31945
31978
|
}
|
|
31946
31979
|
try {
|
|
31947
|
-
return JSON.parse(readFileSync11(
|
|
31980
|
+
return JSON.parse(readFileSync11(path49, "utf-8"));
|
|
31948
31981
|
} catch (error) {
|
|
31949
31982
|
failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
|
|
31950
31983
|
}
|
|
@@ -32904,12 +32937,12 @@ function readPeopleFile(args5) {
|
|
|
32904
32937
|
}
|
|
32905
32938
|
function unreadablePeopleFile(args5) {
|
|
32906
32939
|
if (!args5["people-file"]) return void 0;
|
|
32907
|
-
const
|
|
32940
|
+
const path49 = String(args5["people-file"]);
|
|
32908
32941
|
try {
|
|
32909
|
-
readFileSync12(
|
|
32942
|
+
readFileSync12(path49, "utf8");
|
|
32910
32943
|
return void 0;
|
|
32911
32944
|
} catch {
|
|
32912
|
-
return `Couldn't read --people-file ${
|
|
32945
|
+
return `Couldn't read --people-file ${path49}. Check the path, or pass the people inline with --person.`;
|
|
32913
32946
|
}
|
|
32914
32947
|
}
|
|
32915
32948
|
function peopleLimitError(args5) {
|
|
@@ -33881,11 +33914,11 @@ function parseFieldArgs(argv) {
|
|
|
33881
33914
|
for (const pair of parseRepeated(argv, "--field")) {
|
|
33882
33915
|
const eq = pair.indexOf("=");
|
|
33883
33916
|
const field = eq === -1 ? pair : pair.slice(0, eq);
|
|
33884
|
-
const
|
|
33917
|
+
const path49 = eq === -1 ? "" : pair.slice(eq + 1).trim();
|
|
33885
33918
|
const problem = mappingRowProblem(field);
|
|
33886
33919
|
if (problem !== null) throw new ConversionArgsError(problem);
|
|
33887
|
-
if (
|
|
33888
|
-
mapping[field] =
|
|
33920
|
+
if (path49 === "") throw new ConversionArgsError(`--field ${field} needs a path: --field ${field}=<dotted.path>.`);
|
|
33921
|
+
mapping[field] = path49;
|
|
33889
33922
|
}
|
|
33890
33923
|
return mapping;
|
|
33891
33924
|
}
|
|
@@ -35487,11 +35520,11 @@ function unwrap(response) {
|
|
|
35487
35520
|
}
|
|
35488
35521
|
return response.data;
|
|
35489
35522
|
}
|
|
35490
|
-
async function readAvatars(
|
|
35491
|
-
return unwrap(await apiGet(
|
|
35523
|
+
async function readAvatars(path49, params) {
|
|
35524
|
+
return unwrap(await apiGet(path49, params));
|
|
35492
35525
|
}
|
|
35493
|
-
async function writeAvatars(
|
|
35494
|
-
return unwrap(await apiPost(
|
|
35526
|
+
async function writeAvatars(path49, body) {
|
|
35527
|
+
return unwrap(await apiPost(path49, body));
|
|
35495
35528
|
}
|
|
35496
35529
|
|
|
35497
35530
|
// src/commands/avatars/create.ts
|
|
@@ -36400,12 +36433,12 @@ function missingFontFiles(urls, available) {
|
|
|
36400
36433
|
function planFontAdoption(sources, families) {
|
|
36401
36434
|
const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
|
|
36402
36435
|
const byFamily = /* @__PURE__ */ new Map();
|
|
36403
|
-
for (const { path:
|
|
36404
|
-
const dir = posix.dirname(
|
|
36436
|
+
for (const { path: path49, source } of sources) {
|
|
36437
|
+
const dir = posix.dirname(path49);
|
|
36405
36438
|
for (const face of declaredFontFaces(source)) {
|
|
36406
36439
|
if (!wanted.has(face.family)) continue;
|
|
36407
36440
|
const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
|
|
36408
|
-
perFile.set(
|
|
36441
|
+
perFile.set(path49, [...perFile.get(path49) ?? [], rebaseFontFaceSrc(face.block, dir)]);
|
|
36409
36442
|
byFamily.set(face.family, perFile);
|
|
36410
36443
|
}
|
|
36411
36444
|
}
|
|
@@ -49231,10 +49264,10 @@ function parseValueExpression(raw) {
|
|
|
49231
49264
|
return parts.map(parsePart);
|
|
49232
49265
|
}
|
|
49233
49266
|
function trackingFieldIds() {
|
|
49234
|
-
const
|
|
49235
|
-
if (!existsSync6(
|
|
49267
|
+
const path49 = join4(flowsDir(), "..", "tracking.ts");
|
|
49268
|
+
if (!existsSync6(path49)) return null;
|
|
49236
49269
|
try {
|
|
49237
|
-
const source = readFileSync15(
|
|
49270
|
+
const source = readFileSync15(path49, "utf-8");
|
|
49238
49271
|
const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
|
|
49239
49272
|
if (!block2) return null;
|
|
49240
49273
|
const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
|
|
@@ -49808,13 +49841,13 @@ function specsFromFile(parsed) {
|
|
|
49808
49841
|
return `${destField}${type}=${entry?.value ?? ""}`;
|
|
49809
49842
|
});
|
|
49810
49843
|
}
|
|
49811
|
-
function readSpecFile(
|
|
49844
|
+
function readSpecFile(path49) {
|
|
49812
49845
|
let raw;
|
|
49813
49846
|
try {
|
|
49814
|
-
raw =
|
|
49847
|
+
raw = path49 === "-" ? readFileSync16(0, "utf-8") : readFileSync16(path49, "utf-8");
|
|
49815
49848
|
} catch (error) {
|
|
49816
49849
|
refuse(
|
|
49817
|
-
`Could not read ${
|
|
49850
|
+
`Could not read ${path49 === "-" ? "the mapping from stdin" : `"${path49}"`}: ${error instanceof Error ? error.message : String(error)}`
|
|
49818
49851
|
);
|
|
49819
49852
|
}
|
|
49820
49853
|
let parsed;
|
|
@@ -49822,7 +49855,7 @@ function readSpecFile(path48) {
|
|
|
49822
49855
|
parsed = JSON.parse(raw);
|
|
49823
49856
|
} catch (error) {
|
|
49824
49857
|
refuse(
|
|
49825
|
-
`${
|
|
49858
|
+
`${path49 === "-" ? "stdin" : `"${path49}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
49826
49859
|
'Expected { "map": { "<destField>": "<value>", \u2026 } }'
|
|
49827
49860
|
);
|
|
49828
49861
|
}
|
|
@@ -50121,21 +50154,21 @@ var ARRAY_FIELDS = [
|
|
|
50121
50154
|
"tagIds"
|
|
50122
50155
|
];
|
|
50123
50156
|
var ARRAY_OWNERS = ["", "body"];
|
|
50124
|
-
function dropUnsetOptionals(sideEffect,
|
|
50157
|
+
function dropUnsetOptionals(sideEffect, path49) {
|
|
50125
50158
|
return OPTIONAL_STRINGS.flatMap((key) => {
|
|
50126
50159
|
if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
|
|
50127
50160
|
delete sideEffect[key];
|
|
50128
|
-
return [{ path:
|
|
50161
|
+
return [{ path: path49, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
|
|
50129
50162
|
});
|
|
50130
50163
|
}
|
|
50131
|
-
function fillNulledArrays(target2, prefix,
|
|
50164
|
+
function fillNulledArrays(target2, prefix, path49) {
|
|
50132
50165
|
return ARRAY_FIELDS.flatMap((key) => {
|
|
50133
50166
|
if (!(key in target2) || target2[key] !== null) return [];
|
|
50134
50167
|
target2[key] = [];
|
|
50135
|
-
return [{ path:
|
|
50168
|
+
return [{ path: path49, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
|
|
50136
50169
|
});
|
|
50137
50170
|
}
|
|
50138
|
-
function tidyEmailRecipients(sideEffect,
|
|
50171
|
+
function tidyEmailRecipients(sideEffect, path49) {
|
|
50139
50172
|
if (sideEffect.type !== "email") return [];
|
|
50140
50173
|
const config = sideEffect.encryptedConfig;
|
|
50141
50174
|
if (!config || typeof config !== "object" || Array.isArray(config)) return [];
|
|
@@ -50146,7 +50179,7 @@ function tidyEmailRecipients(sideEffect, path48) {
|
|
|
50146
50179
|
const tidied = to.join(", ");
|
|
50147
50180
|
if (tidied === raw) return [];
|
|
50148
50181
|
config.email = tidied;
|
|
50149
|
-
return [{ path:
|
|
50182
|
+
return [{ path: path49, change: "tidied the recipient list's spacing and separators" }];
|
|
50150
50183
|
}
|
|
50151
50184
|
function sideEffectsOf(node) {
|
|
50152
50185
|
if (!Array.isArray(node.sideEffects)) return [];
|
|
@@ -50155,13 +50188,13 @@ function sideEffectsOf(node) {
|
|
|
50155
50188
|
);
|
|
50156
50189
|
}
|
|
50157
50190
|
function normalizeSideEffect(sideEffect, where) {
|
|
50158
|
-
const
|
|
50191
|
+
const path49 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
|
|
50159
50192
|
const arrays = ARRAY_OWNERS.flatMap((owner) => {
|
|
50160
50193
|
const target2 = owner ? sideEffect[owner] : sideEffect;
|
|
50161
50194
|
if (!target2 || typeof target2 !== "object") return [];
|
|
50162
|
-
return fillNulledArrays(target2, owner ? `${owner}.` : "",
|
|
50195
|
+
return fillNulledArrays(target2, owner ? `${owner}.` : "", path49);
|
|
50163
50196
|
});
|
|
50164
|
-
return [...dropUnsetOptionals(sideEffect,
|
|
50197
|
+
return [...dropUnsetOptionals(sideEffect, path49), ...arrays, ...tidyEmailRecipients(sideEffect, path49)];
|
|
50165
50198
|
}
|
|
50166
50199
|
function normalizeFlowTree(tree) {
|
|
50167
50200
|
const changes = [];
|
|
@@ -51551,10 +51584,10 @@ async function stageOps(ops) {
|
|
|
51551
51584
|
handleError5(err);
|
|
51552
51585
|
}
|
|
51553
51586
|
}
|
|
51554
|
-
async function draftAction2(
|
|
51587
|
+
async function draftAction2(path49, body, chat) {
|
|
51555
51588
|
const chatId = resolveChatId(chat);
|
|
51556
51589
|
try {
|
|
51557
|
-
const data = await apiPost(
|
|
51590
|
+
const data = await apiPost(path49, { chatId, ...body });
|
|
51558
51591
|
writeJsonEnvelope({ ok: true, data });
|
|
51559
51592
|
return data;
|
|
51560
51593
|
} catch (err) {
|
|
@@ -54083,9 +54116,9 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
54083
54116
|
}
|
|
54084
54117
|
return readFile28(pathOrUrl);
|
|
54085
54118
|
}
|
|
54086
|
-
async function isDirectory(
|
|
54119
|
+
async function isDirectory(path49) {
|
|
54087
54120
|
try {
|
|
54088
|
-
const s = await stat7(
|
|
54121
|
+
const s = await stat7(path49);
|
|
54089
54122
|
return s.isDirectory();
|
|
54090
54123
|
} catch {
|
|
54091
54124
|
return false;
|
|
@@ -54513,13 +54546,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
|
|
|
54513
54546
|
}
|
|
54514
54547
|
function disambiguate(paths) {
|
|
54515
54548
|
const taken = /* @__PURE__ */ new Set();
|
|
54516
|
-
return paths.map((
|
|
54517
|
-
if (!taken.has(
|
|
54518
|
-
taken.add(
|
|
54519
|
-
return
|
|
54549
|
+
return paths.map((path49) => {
|
|
54550
|
+
if (!taken.has(path49)) {
|
|
54551
|
+
taken.add(path49);
|
|
54552
|
+
return path49;
|
|
54520
54553
|
}
|
|
54521
|
-
const ext = extname3(
|
|
54522
|
-
const stem =
|
|
54554
|
+
const ext = extname3(path49);
|
|
54555
|
+
const stem = path49.slice(0, path49.length - ext.length);
|
|
54523
54556
|
let n = 2;
|
|
54524
54557
|
while (taken.has(`${stem}-${n}${ext}`)) n += 1;
|
|
54525
54558
|
const unique = `${stem}-${n}${ext}`;
|
|
@@ -54645,10 +54678,10 @@ async function runDownloads(plan) {
|
|
|
54645
54678
|
const paths = disambiguate(fetched.map((item) => item.path));
|
|
54646
54679
|
const downloaded = [];
|
|
54647
54680
|
for (const [index, item] of fetched.entries()) {
|
|
54648
|
-
const
|
|
54681
|
+
const path49 = paths[index] ?? item.path;
|
|
54649
54682
|
try {
|
|
54650
|
-
await atomicWrite(
|
|
54651
|
-
downloaded.push({ input: item.input, output:
|
|
54683
|
+
await atomicWrite(path49, item.buffer);
|
|
54684
|
+
downloaded.push({ input: item.input, output: path49, bytes: item.buffer.length, contentType: item.contentType });
|
|
54652
54685
|
} catch (err) {
|
|
54653
54686
|
failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
|
|
54654
54687
|
}
|
|
@@ -62835,11 +62868,353 @@ Full guide: __tooling__/docs/tools/baker/mcp.md`
|
|
|
62835
62868
|
}
|
|
62836
62869
|
});
|
|
62837
62870
|
|
|
62871
|
+
// src/commands/media-sources/index.ts
|
|
62872
|
+
import { defineCommand as defineCommand189 } from "citty";
|
|
62873
|
+
|
|
62874
|
+
// ../api/src/media-sources.ts
|
|
62875
|
+
import { z as z51 } from "zod";
|
|
62876
|
+
var mediaSourcePlatformSchema = z51.enum(["instagram", "tiktok", "youtube", "linkedin", "facebook"]);
|
|
62877
|
+
var mediaSourceRefreshIntervalSchema = z51.enum(["never", "daily", "weekly", "monthly"]);
|
|
62878
|
+
var mediaSourceSyncStatusSchema = z51.enum(["idle", "fetching", "processing", "error"]);
|
|
62879
|
+
var mediaSourceHalfSchema = z51.object({
|
|
62880
|
+
sourceId: z51.string(),
|
|
62881
|
+
syncStatus: mediaSourceSyncStatusSchema,
|
|
62882
|
+
storedCount: z51.number().optional(),
|
|
62883
|
+
pendingItems: z51.number().optional(),
|
|
62884
|
+
failedItems: z51.number().optional(),
|
|
62885
|
+
lastSyncedAt: z51.number().optional(),
|
|
62886
|
+
errorMessage: z51.string().optional()
|
|
62887
|
+
});
|
|
62888
|
+
var mediaSourceSummarySchema = z51.object({
|
|
62889
|
+
key: z51.string(),
|
|
62890
|
+
platform: mediaSourcePlatformSchema,
|
|
62891
|
+
platformLabel: z51.string(),
|
|
62892
|
+
handle: z51.string(),
|
|
62893
|
+
label: z51.string(),
|
|
62894
|
+
profileUrl: z51.string(),
|
|
62895
|
+
profileImageUrl: z51.string().optional(),
|
|
62896
|
+
refreshInterval: mediaSourceRefreshIntervalSchema,
|
|
62897
|
+
/** Absent for a platform that feeds no images (YouTube). */
|
|
62898
|
+
images: mediaSourceHalfSchema.optional(),
|
|
62899
|
+
videos: mediaSourceHalfSchema.optional(),
|
|
62900
|
+
createdAt: z51.number()
|
|
62901
|
+
});
|
|
62902
|
+
var mediaSourceProfileSchema = z51.object({
|
|
62903
|
+
platform: mediaSourcePlatformSchema,
|
|
62904
|
+
handle: z51.string(),
|
|
62905
|
+
displayName: z51.string(),
|
|
62906
|
+
avatarUrl: z51.string(),
|
|
62907
|
+
bio: z51.string(),
|
|
62908
|
+
followers: z51.number().optional(),
|
|
62909
|
+
postCount: z51.number().optional(),
|
|
62910
|
+
isPrivate: z51.boolean(),
|
|
62911
|
+
profileUrl: z51.string(),
|
|
62912
|
+
channelId: z51.string().optional()
|
|
62913
|
+
});
|
|
62914
|
+
var mediaSourcesAddRequestSchema = z51.object({
|
|
62915
|
+
/** A profile URL, or an @handle together with `platform`. */
|
|
62916
|
+
input: z51.string().trim().min(1, "Pass the account's profile URL or @handle"),
|
|
62917
|
+
/** Needed only when `input` is a bare handle; a URL names its own platform. */
|
|
62918
|
+
platform: mediaSourcePlatformSchema.optional(),
|
|
62919
|
+
/** Auto-sync cadence. Omitted = off (sync on demand). */
|
|
62920
|
+
every: mediaSourceRefreshIntervalSchema.optional()
|
|
62921
|
+
});
|
|
62922
|
+
var mediaSourceKeySchema = z51.string().trim().regex(/^(instagram|tiktok|youtube|linkedin|facebook):.+$/, "Pass a source key like tiktok:nike");
|
|
62923
|
+
var mediaSourcesSyncRequestSchema = z51.object({ key: mediaSourceKeySchema });
|
|
62924
|
+
var mediaSourcesRemoveRequestSchema = z51.object({ key: mediaSourceKeySchema });
|
|
62925
|
+
var mediaSourcesScheduleRequestSchema = z51.object({
|
|
62926
|
+
key: mediaSourceKeySchema,
|
|
62927
|
+
every: mediaSourceRefreshIntervalSchema
|
|
62928
|
+
});
|
|
62929
|
+
|
|
62930
|
+
// src/commands/media-sources/add.ts
|
|
62931
|
+
import { defineCommand as defineCommand184 } from "citty";
|
|
62932
|
+
|
|
62933
|
+
// src/commands/media-sources/shared.ts
|
|
62934
|
+
function reportError2(err) {
|
|
62935
|
+
if (err instanceof ApiError) {
|
|
62936
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
62937
|
+
process.exit(1);
|
|
62938
|
+
}
|
|
62939
|
+
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
62940
|
+
process.exit(1);
|
|
62941
|
+
}
|
|
62942
|
+
function halfState(half) {
|
|
62943
|
+
if (!half) return null;
|
|
62944
|
+
return {
|
|
62945
|
+
status: half.syncStatus === "fetching" || half.syncStatus === "processing" ? "importing" : half.syncStatus,
|
|
62946
|
+
stored: half.storedCount ?? 0,
|
|
62947
|
+
...half.pendingItems ? { pending: half.pendingItems } : {},
|
|
62948
|
+
...half.failedItems ? { failed: half.failedItems } : {},
|
|
62949
|
+
...half.lastSyncedAt ? { lastSyncedAt: new Date(half.lastSyncedAt).toISOString() } : {},
|
|
62950
|
+
...half.errorMessage ? { error: half.errorMessage } : {}
|
|
62951
|
+
};
|
|
62952
|
+
}
|
|
62953
|
+
function compactSource(source) {
|
|
62954
|
+
return {
|
|
62955
|
+
key: source.key,
|
|
62956
|
+
platform: source.platform,
|
|
62957
|
+
label: source.label,
|
|
62958
|
+
url: source.profileUrl,
|
|
62959
|
+
autoSync: source.refreshInterval,
|
|
62960
|
+
images: halfState(source.images),
|
|
62961
|
+
videos: halfState(source.videos)
|
|
62962
|
+
};
|
|
62963
|
+
}
|
|
62964
|
+
function isImporting(source) {
|
|
62965
|
+
return [source.images, source.videos].some(
|
|
62966
|
+
(half) => half?.syncStatus === "fetching" || half?.syncStatus === "processing"
|
|
62967
|
+
);
|
|
62968
|
+
}
|
|
62969
|
+
|
|
62970
|
+
// src/commands/media-sources/add.ts
|
|
62971
|
+
registerSchema({
|
|
62972
|
+
command: "media-sources.add",
|
|
62973
|
+
description: "Connect a public social account as a source for the image and video libraries \u2014 Instagram, TikTok, YouTube (videos only), LinkedIn company pages, Facebook pages. Its recent posts (up to a year back) are imported, described and made searchable; the import runs in the background. Applies immediately and shows on the chat as an already-applied change. Adding an account that is already connected is a no-op.",
|
|
62974
|
+
args: {
|
|
62975
|
+
input: {
|
|
62976
|
+
type: "string",
|
|
62977
|
+
description: "Profile URL (names its own platform) or @handle together with --platform",
|
|
62978
|
+
required: true
|
|
62979
|
+
},
|
|
62980
|
+
platform: {
|
|
62981
|
+
type: "string",
|
|
62982
|
+
description: `Needed only for a bare handle: ${mediaSourcePlatformSchema.options.join("|")}`,
|
|
62983
|
+
required: false
|
|
62984
|
+
},
|
|
62985
|
+
every: {
|
|
62986
|
+
type: "string",
|
|
62987
|
+
description: `Auto-sync cadence: ${mediaSourceRefreshIntervalSchema.options.join("|")} (default never \u2014 sync on demand)`,
|
|
62988
|
+
required: false
|
|
62989
|
+
}
|
|
62990
|
+
}
|
|
62991
|
+
});
|
|
62992
|
+
var addCommand3 = defineCommand184({
|
|
62993
|
+
meta: {
|
|
62994
|
+
name: "add",
|
|
62995
|
+
description: "Connect a social account (Instagram, TikTok, YouTube, LinkedIn page, Facebook page) as a media source. Start here with the profile URL.\n\nExamples:\n baker media-sources add https://www.tiktok.com/@acme\n baker media-sources add @acme --platform instagram --every weekly\n baker media-sources add https://www.youtube.com/@acme"
|
|
62996
|
+
},
|
|
62997
|
+
args: {
|
|
62998
|
+
input: { type: "positional", description: "Profile URL or @handle", required: true },
|
|
62999
|
+
platform: {
|
|
63000
|
+
type: "string",
|
|
63001
|
+
description: "instagram|tiktok|youtube|linkedin|facebook \u2014 only for a bare handle",
|
|
63002
|
+
required: false
|
|
63003
|
+
},
|
|
63004
|
+
every: { type: "string", description: "Auto-sync: never|daily|weekly|monthly", required: false }
|
|
63005
|
+
},
|
|
63006
|
+
run: async ({ args: args5 }) => {
|
|
63007
|
+
const parsed = mediaSourcesAddRequestSchema.safeParse({
|
|
63008
|
+
input: String(args5.input ?? ""),
|
|
63009
|
+
platform: args5.platform ? String(args5.platform).toLowerCase() : void 0,
|
|
63010
|
+
every: args5.every ? String(args5.every).toLowerCase() : void 0
|
|
63011
|
+
});
|
|
63012
|
+
if (!parsed.success) {
|
|
63013
|
+
const issue = parsed.error.issues[0];
|
|
63014
|
+
writeJson({
|
|
63015
|
+
ok: false,
|
|
63016
|
+
error: {
|
|
63017
|
+
code: "VALIDATION_ERROR",
|
|
63018
|
+
message: issue ? `${issue.path.join(".") || "input"}: ${issue.message}` : "Invalid request"
|
|
63019
|
+
}
|
|
63020
|
+
});
|
|
63021
|
+
process.exit(1);
|
|
63022
|
+
}
|
|
63023
|
+
try {
|
|
63024
|
+
const data = await apiPost("/api/media-sources/add", parsed.data, {
|
|
63025
|
+
timeoutMs: 12e4
|
|
63026
|
+
});
|
|
63027
|
+
const hints2 = [
|
|
63028
|
+
data.created ? `Connected ${data.source.label} on ${data.source.platformLabel}. Its posts are importing in the background \u2014 they become searchable with \`baker images search\` / \`baker videos search\` as each one is analysed. Check progress with \`baker media-sources list\`.` : `${data.source.label} on ${data.source.platformLabel} was already connected; a fresh import was started if one wasn't running.`
|
|
63029
|
+
];
|
|
63030
|
+
if (data.source.platform === "youtube") {
|
|
63031
|
+
hints2.push(
|
|
63032
|
+
"YouTube feeds the video library only, newest first, a batch per sync; videos over 20 minutes are skipped."
|
|
63033
|
+
);
|
|
63034
|
+
}
|
|
63035
|
+
if (data.source.refreshInterval === "never") {
|
|
63036
|
+
hints2.push(
|
|
63037
|
+
`Auto-sync is off. If the user wants new posts to keep arriving: \`baker media-sources schedule ${data.source.key} --every weekly\`.`
|
|
63038
|
+
);
|
|
63039
|
+
}
|
|
63040
|
+
writeJson({
|
|
63041
|
+
ok: true,
|
|
63042
|
+
data: { created: data.created, source: compactSource(data.source), name: data.profile.displayName },
|
|
63043
|
+
hints: hints2
|
|
63044
|
+
});
|
|
63045
|
+
} catch (err) {
|
|
63046
|
+
reportError2(err);
|
|
63047
|
+
}
|
|
63048
|
+
}
|
|
63049
|
+
});
|
|
63050
|
+
|
|
63051
|
+
// src/commands/media-sources/list.ts
|
|
63052
|
+
import { defineCommand as defineCommand185 } from "citty";
|
|
63053
|
+
registerSchema({
|
|
63054
|
+
command: "media-sources.list",
|
|
63055
|
+
description: "List the social accounts connected as image/video sources, with each one's key, import status and how many images and videos it has brought in.",
|
|
63056
|
+
args: {}
|
|
63057
|
+
});
|
|
63058
|
+
var listCommand17 = defineCommand185({
|
|
63059
|
+
meta: {
|
|
63060
|
+
name: "list",
|
|
63061
|
+
description: "List connected media sources (key, platform, import status, stored images/videos).\n\nExample: baker media-sources list"
|
|
63062
|
+
},
|
|
63063
|
+
args: {},
|
|
63064
|
+
run: async () => {
|
|
63065
|
+
try {
|
|
63066
|
+
const { sources } = await apiGet("/api/media-sources/list");
|
|
63067
|
+
const hints2 = [];
|
|
63068
|
+
if (sources.length === 0) {
|
|
63069
|
+
hints2.push(
|
|
63070
|
+
"No sources connected. Connect the brand's own accounts with `baker media-sources add <profile URL>` to fill the image and video libraries."
|
|
63071
|
+
);
|
|
63072
|
+
} else if (sources.some(isImporting)) {
|
|
63073
|
+
hints2.push("Some sources are still importing \u2014 their counts will grow over the next minutes.");
|
|
63074
|
+
}
|
|
63075
|
+
writeJson({ ok: true, data: sources.map(compactSource), hints: hints2.length > 0 ? hints2 : void 0 });
|
|
63076
|
+
} catch (err) {
|
|
63077
|
+
reportError2(err);
|
|
63078
|
+
}
|
|
63079
|
+
}
|
|
63080
|
+
});
|
|
63081
|
+
|
|
63082
|
+
// src/commands/media-sources/remove.ts
|
|
63083
|
+
import { defineCommand as defineCommand186 } from "citty";
|
|
63084
|
+
registerSchema({
|
|
63085
|
+
command: "media-sources.remove",
|
|
63086
|
+
description: "Disconnect a media source. Stops future imports; images and videos it already brought in stay in the library. Applies immediately.",
|
|
63087
|
+
args: { key: { type: "string", description: "Source key, e.g. tiktok:acme", required: true } }
|
|
63088
|
+
});
|
|
63089
|
+
var removeCommand6 = defineCommand186({
|
|
63090
|
+
meta: {
|
|
63091
|
+
name: "remove",
|
|
63092
|
+
description: "Disconnect a media source (already-imported media stays).\n\nExample: baker media-sources remove tiktok:acme"
|
|
63093
|
+
},
|
|
63094
|
+
args: { key: { type: "positional", description: "Source key, e.g. tiktok:acme", required: true } },
|
|
63095
|
+
run: async ({ args: args5 }) => {
|
|
63096
|
+
const parsed = mediaSourcesRemoveRequestSchema.safeParse({ key: String(args5.key ?? "") });
|
|
63097
|
+
if (!parsed.success) {
|
|
63098
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: parsed.error.issues[0]?.message ?? "" } });
|
|
63099
|
+
process.exit(1);
|
|
63100
|
+
}
|
|
63101
|
+
try {
|
|
63102
|
+
const data = await apiPost("/api/media-sources/remove", parsed.data);
|
|
63103
|
+
writeJson({ ok: true, data });
|
|
63104
|
+
} catch (err) {
|
|
63105
|
+
reportError2(err);
|
|
63106
|
+
}
|
|
63107
|
+
}
|
|
63108
|
+
});
|
|
63109
|
+
|
|
63110
|
+
// src/commands/media-sources/schedule.ts
|
|
63111
|
+
import { defineCommand as defineCommand187 } from "citty";
|
|
63112
|
+
registerSchema({
|
|
63113
|
+
command: "media-sources.schedule",
|
|
63114
|
+
description: "Set how often a connected source imports new posts on its own.",
|
|
63115
|
+
args: {
|
|
63116
|
+
key: { type: "string", description: "Source key, e.g. tiktok:acme", required: true },
|
|
63117
|
+
every: {
|
|
63118
|
+
type: "string",
|
|
63119
|
+
description: `Cadence: ${mediaSourceRefreshIntervalSchema.options.join("|")} (never = only on demand)`,
|
|
63120
|
+
required: true
|
|
63121
|
+
}
|
|
63122
|
+
}
|
|
63123
|
+
});
|
|
63124
|
+
var scheduleCommand = defineCommand187({
|
|
63125
|
+
meta: {
|
|
63126
|
+
name: "schedule",
|
|
63127
|
+
description: "Set a source's auto-sync cadence.\n\nExample: baker media-sources schedule tiktok:acme --every weekly"
|
|
63128
|
+
},
|
|
63129
|
+
args: {
|
|
63130
|
+
key: { type: "positional", description: "Source key, e.g. tiktok:acme", required: true },
|
|
63131
|
+
every: { type: "string", description: "never|daily|weekly|monthly", required: true }
|
|
63132
|
+
},
|
|
63133
|
+
run: async ({ args: args5 }) => {
|
|
63134
|
+
const parsed = mediaSourcesScheduleRequestSchema.safeParse({
|
|
63135
|
+
key: String(args5.key ?? ""),
|
|
63136
|
+
every: String(args5.every ?? "").toLowerCase()
|
|
63137
|
+
});
|
|
63138
|
+
if (!parsed.success) {
|
|
63139
|
+
const issue = parsed.error.issues[0];
|
|
63140
|
+
writeJson({
|
|
63141
|
+
ok: false,
|
|
63142
|
+
error: { code: "VALIDATION_ERROR", message: issue ? `${issue.path.join(".")}: ${issue.message}` : "" }
|
|
63143
|
+
});
|
|
63144
|
+
process.exit(1);
|
|
63145
|
+
}
|
|
63146
|
+
try {
|
|
63147
|
+
const data = await apiPost("/api/media-sources/schedule", parsed.data);
|
|
63148
|
+
writeJson({ ok: true, data: { ...data, autoSync: parsed.data.every } });
|
|
63149
|
+
} catch (err) {
|
|
63150
|
+
reportError2(err);
|
|
63151
|
+
}
|
|
63152
|
+
}
|
|
63153
|
+
});
|
|
63154
|
+
|
|
63155
|
+
// src/commands/media-sources/sync.ts
|
|
63156
|
+
import { defineCommand as defineCommand188 } from "citty";
|
|
63157
|
+
registerSchema({
|
|
63158
|
+
command: "media-sources.sync",
|
|
63159
|
+
description: "Import a connected source's new posts now. Runs in the background; only posts not yet in the library are fetched.",
|
|
63160
|
+
args: {
|
|
63161
|
+
key: { type: "string", description: "Source key from `media-sources list`, e.g. tiktok:acme", required: true }
|
|
63162
|
+
}
|
|
63163
|
+
});
|
|
63164
|
+
var syncCommand = defineCommand188({
|
|
63165
|
+
meta: {
|
|
63166
|
+
name: "sync",
|
|
63167
|
+
description: "Import a source's new posts now.\n\nExample: baker media-sources sync tiktok:acme"
|
|
63168
|
+
},
|
|
63169
|
+
args: { key: { type: "positional", description: "Source key, e.g. tiktok:acme", required: true } },
|
|
63170
|
+
run: async ({ args: args5 }) => {
|
|
63171
|
+
const parsed = mediaSourcesSyncRequestSchema.safeParse({ key: String(args5.key ?? "") });
|
|
63172
|
+
if (!parsed.success) {
|
|
63173
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: parsed.error.issues[0]?.message ?? "" } });
|
|
63174
|
+
process.exit(1);
|
|
63175
|
+
}
|
|
63176
|
+
try {
|
|
63177
|
+
const data = await apiPost("/api/media-sources/sync", parsed.data);
|
|
63178
|
+
writeJson({
|
|
63179
|
+
ok: true,
|
|
63180
|
+
data,
|
|
63181
|
+
hints: data.started ? void 0 : ["An import was already running for this source; nothing new was started."]
|
|
63182
|
+
});
|
|
63183
|
+
} catch (err) {
|
|
63184
|
+
reportError2(err);
|
|
63185
|
+
}
|
|
63186
|
+
}
|
|
63187
|
+
});
|
|
63188
|
+
|
|
63189
|
+
// src/commands/media-sources/index.ts
|
|
63190
|
+
var mediaSourcesCommand = defineCommand189({
|
|
63191
|
+
meta: {
|
|
63192
|
+
name: "media-sources",
|
|
63193
|
+
description: `Connect social accounts whose posts fill the image and video libraries: Instagram, TikTok, YouTube (videos), LinkedIn company pages, Facebook pages. Subcommands: add, list, sync, schedule, remove.
|
|
63194
|
+
|
|
63195
|
+
Examples:
|
|
63196
|
+
baker media-sources add https://www.tiktok.com/@acme
|
|
63197
|
+
baker media-sources add @acme --platform instagram --every weekly
|
|
63198
|
+
baker media-sources list
|
|
63199
|
+
baker media-sources sync youtube:acme
|
|
63200
|
+
baker media-sources schedule linkedin:acme --every monthly
|
|
63201
|
+
baker media-sources remove facebook:acme
|
|
63202
|
+
Full guide: __tooling__/docs/tools/baker/media-sources.md`
|
|
63203
|
+
},
|
|
63204
|
+
subCommands: {
|
|
63205
|
+
add: addCommand3,
|
|
63206
|
+
list: listCommand17,
|
|
63207
|
+
sync: syncCommand,
|
|
63208
|
+
schedule: scheduleCommand,
|
|
63209
|
+
remove: removeCommand6
|
|
63210
|
+
}
|
|
63211
|
+
});
|
|
63212
|
+
|
|
62838
63213
|
// src/commands/research/index.ts
|
|
62839
|
-
import { defineCommand as
|
|
63214
|
+
import { defineCommand as defineCommand202 } from "citty";
|
|
62840
63215
|
|
|
62841
63216
|
// src/commands/research/advertisers.ts
|
|
62842
|
-
import { defineCommand as
|
|
63217
|
+
import { defineCommand as defineCommand190 } from "citty";
|
|
62843
63218
|
|
|
62844
63219
|
// src/commands/research/hints.ts
|
|
62845
63220
|
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.';
|
|
@@ -63041,7 +63416,7 @@ var FIELDS3 = {
|
|
|
63041
63416
|
etv: "Estimated traffic value (USD)",
|
|
63042
63417
|
visibility: "SERP visibility score (0-1)"
|
|
63043
63418
|
};
|
|
63044
|
-
var advertisersCommand =
|
|
63419
|
+
var advertisersCommand = defineCommand190({
|
|
63045
63420
|
meta: {
|
|
63046
63421
|
name: "advertisers",
|
|
63047
63422
|
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).
|
|
@@ -63097,7 +63472,7 @@ Examples:
|
|
|
63097
63472
|
});
|
|
63098
63473
|
|
|
63099
63474
|
// src/commands/research/autocomplete.ts
|
|
63100
|
-
import { defineCommand as
|
|
63475
|
+
import { defineCommand as defineCommand191 } from "citty";
|
|
63101
63476
|
registerSchema({
|
|
63102
63477
|
command: "research.autocomplete",
|
|
63103
63478
|
description: "Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. If --location and --language are omitted, defaults to United States (us) and English (en).",
|
|
@@ -63120,7 +63495,7 @@ registerSchema({
|
|
|
63120
63495
|
var FIELDS4 = {
|
|
63121
63496
|
suggestion: "Autocomplete suggestion from Google"
|
|
63122
63497
|
};
|
|
63123
|
-
var autocompleteCommand =
|
|
63498
|
+
var autocompleteCommand = defineCommand191({
|
|
63124
63499
|
meta: {
|
|
63125
63500
|
name: "autocomplete",
|
|
63126
63501
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -63175,7 +63550,7 @@ Examples:
|
|
|
63175
63550
|
});
|
|
63176
63551
|
|
|
63177
63552
|
// src/commands/research/countries.ts
|
|
63178
|
-
import { defineCommand as
|
|
63553
|
+
import { defineCommand as defineCommand192 } from "citty";
|
|
63179
63554
|
registerSchema({
|
|
63180
63555
|
command: "research.countries",
|
|
63181
63556
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -63232,7 +63607,7 @@ var FIELDS5 = {
|
|
|
63232
63607
|
code: "Country code to pass as --location",
|
|
63233
63608
|
name: "Country name"
|
|
63234
63609
|
};
|
|
63235
|
-
var countriesCommand =
|
|
63610
|
+
var countriesCommand = defineCommand192({
|
|
63236
63611
|
meta: {
|
|
63237
63612
|
name: "countries",
|
|
63238
63613
|
description: "List all supported country codes for --location flag."
|
|
@@ -63243,7 +63618,7 @@ var countriesCommand = defineCommand186({
|
|
|
63243
63618
|
});
|
|
63244
63619
|
|
|
63245
63620
|
// src/commands/research/fetch.ts
|
|
63246
|
-
import { defineCommand as
|
|
63621
|
+
import { defineCommand as defineCommand193 } from "citty";
|
|
63247
63622
|
var CONTENT_PREVIEW_CHARS = 2e4;
|
|
63248
63623
|
var TIMEOUT_MS = 18e4;
|
|
63249
63624
|
registerSchema({
|
|
@@ -63316,7 +63691,7 @@ function fetchFix(code) {
|
|
|
63316
63691
|
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."
|
|
63317
63692
|
};
|
|
63318
63693
|
}
|
|
63319
|
-
var fetchCommand =
|
|
63694
|
+
var fetchCommand = defineCommand193({
|
|
63320
63695
|
meta: {
|
|
63321
63696
|
name: "fetch",
|
|
63322
63697
|
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.
|
|
@@ -63393,7 +63768,7 @@ Examples:
|
|
|
63393
63768
|
});
|
|
63394
63769
|
|
|
63395
63770
|
// src/commands/research/intent.ts
|
|
63396
|
-
import { defineCommand as
|
|
63771
|
+
import { defineCommand as defineCommand194 } from "citty";
|
|
63397
63772
|
registerSchema({
|
|
63398
63773
|
command: "research.intent",
|
|
63399
63774
|
description: "Classify Google Search intent for keywords. Determines if someone searching is looking to buy, research, or navigate. If --language is omitted, defaults to English (en). The response includes a query_context object showing which language was used.",
|
|
@@ -63416,7 +63791,7 @@ var FIELDS7 = {
|
|
|
63416
63791
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
63417
63792
|
probability: "Confidence score 0.0-1.0"
|
|
63418
63793
|
};
|
|
63419
|
-
var intentCommand =
|
|
63794
|
+
var intentCommand = defineCommand194({
|
|
63420
63795
|
meta: {
|
|
63421
63796
|
name: "intent",
|
|
63422
63797
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -63464,7 +63839,7 @@ Examples:
|
|
|
63464
63839
|
});
|
|
63465
63840
|
|
|
63466
63841
|
// src/commands/research/keyword-gap.ts
|
|
63467
|
-
import { defineCommand as
|
|
63842
|
+
import { defineCommand as defineCommand195 } from "citty";
|
|
63468
63843
|
registerSchema({
|
|
63469
63844
|
command: "research.keyword-gap",
|
|
63470
63845
|
description: "Find keywords a competitor ranks for (organic or paid) that you don't. Discovers expansion opportunities. 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.",
|
|
@@ -63493,7 +63868,7 @@ var FIELDS8 = {
|
|
|
63493
63868
|
cpc: "Cost per click USD",
|
|
63494
63869
|
their_position: "Competitor's ranking position"
|
|
63495
63870
|
};
|
|
63496
|
-
var keywordGapCommand =
|
|
63871
|
+
var keywordGapCommand = defineCommand195({
|
|
63497
63872
|
meta: {
|
|
63498
63873
|
name: "keyword-gap",
|
|
63499
63874
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -63568,7 +63943,7 @@ Examples:
|
|
|
63568
63943
|
});
|
|
63569
63944
|
|
|
63570
63945
|
// src/commands/research/keyword-metrics.ts
|
|
63571
|
-
import { defineCommand as
|
|
63946
|
+
import { defineCommand as defineCommand196 } from "citty";
|
|
63572
63947
|
|
|
63573
63948
|
// src/commands/research/keyword-metrics-rows.ts
|
|
63574
63949
|
var KEYWORD_METRICS_SOURCE = "keyword_planner_estimate_via_dataforseo";
|
|
@@ -63648,7 +64023,7 @@ registerSchema({
|
|
|
63648
64023
|
"no-cache": { type: "boolean", description: "Skip server cache, hit API directly", required: false }
|
|
63649
64024
|
}
|
|
63650
64025
|
});
|
|
63651
|
-
var keywordMetricsCommand =
|
|
64026
|
+
var keywordMetricsCommand = defineCommand196({
|
|
63652
64027
|
meta: {
|
|
63653
64028
|
name: "keyword-metrics",
|
|
63654
64029
|
description: `Volume, CPC and competition for keywords you name. No domain required.
|
|
@@ -63730,7 +64105,7 @@ Examples:
|
|
|
63730
64105
|
});
|
|
63731
64106
|
|
|
63732
64107
|
// src/commands/research/keywords-for-site.ts
|
|
63733
|
-
import { defineCommand as
|
|
64108
|
+
import { defineCommand as defineCommand197 } from "citty";
|
|
63734
64109
|
registerSchema({
|
|
63735
64110
|
command: "research.keywords-for-site",
|
|
63736
64111
|
description: "Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. 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.",
|
|
@@ -63763,7 +64138,7 @@ var FIELDS9 = {
|
|
|
63763
64138
|
competition: "LOW, MEDIUM, or HIGH",
|
|
63764
64139
|
competition_index: "Competition score 0-100"
|
|
63765
64140
|
};
|
|
63766
|
-
var keywordsForSiteCommand =
|
|
64141
|
+
var keywordsForSiteCommand = defineCommand197({
|
|
63767
64142
|
meta: {
|
|
63768
64143
|
name: "keywords-for-site",
|
|
63769
64144
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -63825,7 +64200,7 @@ Examples:
|
|
|
63825
64200
|
});
|
|
63826
64201
|
|
|
63827
64202
|
// src/commands/research/languages.ts
|
|
63828
|
-
import { defineCommand as
|
|
64203
|
+
import { defineCommand as defineCommand198 } from "citty";
|
|
63829
64204
|
registerSchema({
|
|
63830
64205
|
command: "research.languages",
|
|
63831
64206
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -63855,7 +64230,7 @@ var FIELDS10 = {
|
|
|
63855
64230
|
code: "Language code to pass as --language",
|
|
63856
64231
|
name: "Language name (also accepted by --language)"
|
|
63857
64232
|
};
|
|
63858
|
-
var languagesCommand2 =
|
|
64233
|
+
var languagesCommand2 = defineCommand198({
|
|
63859
64234
|
meta: {
|
|
63860
64235
|
name: "languages",
|
|
63861
64236
|
description: "List all supported language codes for --language flag."
|
|
@@ -63866,7 +64241,7 @@ var languagesCommand2 = defineCommand192({
|
|
|
63866
64241
|
});
|
|
63867
64242
|
|
|
63868
64243
|
// src/commands/research/lighthouse.ts
|
|
63869
|
-
import { defineCommand as
|
|
64244
|
+
import { defineCommand as defineCommand199 } from "citty";
|
|
63870
64245
|
registerSchema({
|
|
63871
64246
|
command: "research.lighthouse",
|
|
63872
64247
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -63885,7 +64260,7 @@ var FIELDS11 = {
|
|
|
63885
64260
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
63886
64261
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
63887
64262
|
};
|
|
63888
|
-
var lighthouseCommand =
|
|
64263
|
+
var lighthouseCommand = defineCommand199({
|
|
63889
64264
|
meta: {
|
|
63890
64265
|
name: "lighthouse",
|
|
63891
64266
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -63923,7 +64298,7 @@ Examples:
|
|
|
63923
64298
|
});
|
|
63924
64299
|
|
|
63925
64300
|
// src/commands/research/relevant-pages.ts
|
|
63926
|
-
import { defineCommand as
|
|
64301
|
+
import { defineCommand as defineCommand200 } from "citty";
|
|
63927
64302
|
registerSchema({
|
|
63928
64303
|
command: "research.relevant-pages",
|
|
63929
64304
|
description: "Get the top pages of a competitor domain with organic traffic and ranking data. Shows which pages drive the most traffic. If --location and --language are omitted, defaults to United States (us) and English (en).",
|
|
@@ -63949,7 +64324,7 @@ var FIELDS12 = {
|
|
|
63949
64324
|
keywords: "Total organic keywords the page ranks for",
|
|
63950
64325
|
top_10: "Keywords in positions 1-10"
|
|
63951
64326
|
};
|
|
63952
|
-
var relevantPagesCommand =
|
|
64327
|
+
var relevantPagesCommand = defineCommand200({
|
|
63953
64328
|
meta: {
|
|
63954
64329
|
name: "relevant-pages",
|
|
63955
64330
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -63996,7 +64371,7 @@ Examples:
|
|
|
63996
64371
|
});
|
|
63997
64372
|
|
|
63998
64373
|
// src/commands/research/web.ts
|
|
63999
|
-
import { defineCommand as
|
|
64374
|
+
import { defineCommand as defineCommand201 } from "citty";
|
|
64000
64375
|
registerSchema({
|
|
64001
64376
|
command: "research.web",
|
|
64002
64377
|
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).",
|
|
@@ -64047,7 +64422,7 @@ async function runDeepResearch(question) {
|
|
|
64047
64422
|
}
|
|
64048
64423
|
throw new Error("Deep research timed out");
|
|
64049
64424
|
}
|
|
64050
|
-
var webCommand =
|
|
64425
|
+
var webCommand = defineCommand201({
|
|
64051
64426
|
meta: {
|
|
64052
64427
|
name: "web",
|
|
64053
64428
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -64109,7 +64484,7 @@ Examples:
|
|
|
64109
64484
|
});
|
|
64110
64485
|
|
|
64111
64486
|
// src/commands/research/index.ts
|
|
64112
|
-
var researchCommand =
|
|
64487
|
+
var researchCommand = defineCommand202({
|
|
64113
64488
|
meta: {
|
|
64114
64489
|
name: "research",
|
|
64115
64490
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -64156,10 +64531,10 @@ Full guide: __tooling__/docs/tools/baker/research.md`
|
|
|
64156
64531
|
});
|
|
64157
64532
|
|
|
64158
64533
|
// src/commands/scheduled-agents/index.ts
|
|
64159
|
-
import { defineCommand as
|
|
64534
|
+
import { defineCommand as defineCommand213 } from "citty";
|
|
64160
64535
|
|
|
64161
64536
|
// src/commands/scheduled-agents/create.ts
|
|
64162
|
-
import { defineCommand as
|
|
64537
|
+
import { defineCommand as defineCommand203 } from "citty";
|
|
64163
64538
|
|
|
64164
64539
|
// src/commands/scheduled-agents/shared.ts
|
|
64165
64540
|
var TEMP_SCHEDULED_AGENT_PREFIX = "temp_agent_";
|
|
@@ -64526,7 +64901,7 @@ registerSchema({
|
|
|
64526
64901
|
}
|
|
64527
64902
|
}
|
|
64528
64903
|
});
|
|
64529
|
-
var createCommand3 =
|
|
64904
|
+
var createCommand3 = defineCommand203({
|
|
64530
64905
|
meta: {
|
|
64531
64906
|
name: "create",
|
|
64532
64907
|
description: 'Stage a scheduled agent. Examples: baker scheduled-agents create --name "Weekly report" --description "..." --prompt "..." --cron "0 9 * * MON" | baker scheduled-agents create --name "Chase a new lead" --description "..." --prompt "Research {{payload.answers.company}} and draft a reply" --trigger form.submitted --form quote | baker scheduled-agents create --name "Big deals" --description "..." --prompt "..." --trigger webhook.received --when "deal.stage = won AND deal.amount > 10000" --times 3'
|
|
@@ -64583,7 +64958,7 @@ var createCommand3 = defineCommand197({
|
|
|
64583
64958
|
});
|
|
64584
64959
|
|
|
64585
64960
|
// src/commands/scheduled-agents/delete.ts
|
|
64586
|
-
import { defineCommand as
|
|
64961
|
+
import { defineCommand as defineCommand204 } from "citty";
|
|
64587
64962
|
registerSchema({
|
|
64588
64963
|
command: "scheduled-agents.delete",
|
|
64589
64964
|
description: "Stage deletion of a published scheduled agent, or cancel one this chat staged (temp_agent_*).",
|
|
@@ -64591,7 +64966,7 @@ registerSchema({
|
|
|
64591
64966
|
id: { type: "string", description: "Published scheduled agent ID or temp_agent_* draft ID", required: true }
|
|
64592
64967
|
}
|
|
64593
64968
|
});
|
|
64594
|
-
var deleteCommand3 =
|
|
64969
|
+
var deleteCommand3 = defineCommand204({
|
|
64595
64970
|
meta: {
|
|
64596
64971
|
name: "delete",
|
|
64597
64972
|
description: "Stage a scheduled agent deletion. Example: baker scheduled-agents delete <id-or-temp_agent_id>"
|
|
@@ -64620,7 +64995,7 @@ var deleteCommand3 = defineCommand198({
|
|
|
64620
64995
|
});
|
|
64621
64996
|
|
|
64622
64997
|
// src/commands/scheduled-agents/get.ts
|
|
64623
|
-
import { defineCommand as
|
|
64998
|
+
import { defineCommand as defineCommand205 } from "citty";
|
|
64624
64999
|
registerSchema({
|
|
64625
65000
|
command: "scheduled-agents.get",
|
|
64626
65001
|
description: "Get a published scheduled agent, or one this chat has staged (temp_agent_*). A published one comes with runsAs: who each run acts as ({ name, personalTools, companyTools, notSignedIn?, toolsOff? }) \u2014 the tools a run loads, which decides whether a job like reading someone's inbox can work. Its recentRuns and any draftOps this chat staged on it come with it.",
|
|
@@ -64629,7 +65004,7 @@ registerSchema({
|
|
|
64629
65004
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
64630
65005
|
}
|
|
64631
65006
|
});
|
|
64632
|
-
var getCommand4 =
|
|
65007
|
+
var getCommand4 = defineCommand205({
|
|
64633
65008
|
meta: {
|
|
64634
65009
|
name: "get",
|
|
64635
65010
|
description: "Get a scheduled agent. Example: baker scheduled-agents get <id-or-temp_agent_id>"
|
|
@@ -64668,7 +65043,7 @@ var getCommand4 = defineCommand199({
|
|
|
64668
65043
|
});
|
|
64669
65044
|
|
|
64670
65045
|
// src/commands/scheduled-agents/list.ts
|
|
64671
|
-
import { defineCommand as
|
|
65046
|
+
import { defineCommand as defineCommand206 } from "citty";
|
|
64672
65047
|
var FULL_DESCRIPTION = "Return every item and staged change as stored, briefs included (tens of KB). Prefer `get <id>` for one item.";
|
|
64673
65048
|
registerSchema({
|
|
64674
65049
|
command: "scheduled-agents.list",
|
|
@@ -64678,7 +65053,7 @@ registerSchema({
|
|
|
64678
65053
|
full: { type: "boolean", description: FULL_DESCRIPTION, required: false }
|
|
64679
65054
|
}
|
|
64680
65055
|
});
|
|
64681
|
-
var
|
|
65056
|
+
var listCommand18 = defineCommand206({
|
|
64682
65057
|
meta: {
|
|
64683
65058
|
name: "list",
|
|
64684
65059
|
description: "List scheduled agents: id, name, trigger and status for each, plus this chat's staged changes when BAKER_CHAT_ID is set (or --chat <id> for an earlier chat's). Briefs are left out. Start here: baker scheduled-agents list; then baker scheduled-agents get <id> for one item's brief."
|
|
@@ -64704,7 +65079,7 @@ var listCommand17 = defineCommand200({
|
|
|
64704
65079
|
});
|
|
64705
65080
|
|
|
64706
65081
|
// src/commands/scheduled-agents/run.ts
|
|
64707
|
-
import { defineCommand as
|
|
65082
|
+
import { defineCommand as defineCommand207 } from "citty";
|
|
64708
65083
|
registerSchema({
|
|
64709
65084
|
command: "scheduled-agents.run",
|
|
64710
65085
|
description: "Run a published scheduled agent now, whatever its trigger says. Opens a Session immediately and returns its chatId. Does not need BAKER_CHAT_ID, and refuses a temp_agent_* id \u2014 a staged item has to be published before it can run.",
|
|
@@ -64712,7 +65087,7 @@ registerSchema({
|
|
|
64712
65087
|
id: { type: "string", description: "Published scheduled agent ID", required: true }
|
|
64713
65088
|
}
|
|
64714
65089
|
});
|
|
64715
|
-
var runCommand2 =
|
|
65090
|
+
var runCommand2 = defineCommand207({
|
|
64716
65091
|
meta: {
|
|
64717
65092
|
name: "run",
|
|
64718
65093
|
description: "Run a published scheduled agent now. Example: baker scheduled-agents run <id>"
|
|
@@ -64744,7 +65119,7 @@ var runCommand2 = defineCommand201({
|
|
|
64744
65119
|
});
|
|
64745
65120
|
|
|
64746
65121
|
// src/commands/scheduled-agents/targets.ts
|
|
64747
|
-
import { defineCommand as
|
|
65122
|
+
import { defineCommand as defineCommand208 } from "citty";
|
|
64748
65123
|
var ARGS2 = {
|
|
64749
65124
|
trigger: {
|
|
64750
65125
|
type: "string",
|
|
@@ -64778,7 +65153,7 @@ registerSchema({
|
|
|
64778
65153
|
description: "What a trigger can be pointed at: the open Tasks, the company's scheduled agents, its review sources, followed competitors, pages, Forms and their steps, Knowledge collections, tools. Returns each option's value (pass it to the matching flag on create/update) with its name.",
|
|
64779
65154
|
args: ARGS2
|
|
64780
65155
|
});
|
|
64781
|
-
var targetsCommand =
|
|
65156
|
+
var targetsCommand = defineCommand208({
|
|
64782
65157
|
meta: {
|
|
64783
65158
|
name: "targets",
|
|
64784
65159
|
description: `What a trigger can be pointed at \u2014 so "when a Task is picked up" becomes "when THIS Task is picked up".
|
|
@@ -64821,7 +65196,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
64821
65196
|
// src/commands/scheduled-agents/templates.ts
|
|
64822
65197
|
import { readFile as readFile32 } from "fs/promises";
|
|
64823
65198
|
import path46 from "path";
|
|
64824
|
-
import { defineCommand as
|
|
65199
|
+
import { defineCommand as defineCommand209 } from "citty";
|
|
64825
65200
|
registerSchema({
|
|
64826
65201
|
command: "scheduled-agents.templates",
|
|
64827
65202
|
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.",
|
|
@@ -64876,7 +65251,7 @@ registerSchema({
|
|
|
64876
65251
|
}
|
|
64877
65252
|
}
|
|
64878
65253
|
});
|
|
64879
|
-
var templatesCommand =
|
|
65254
|
+
var templatesCommand = defineCommand209({
|
|
64880
65255
|
meta: {
|
|
64881
65256
|
name: "templates",
|
|
64882
65257
|
description: `The recipes this company can run \u2014 Baker's own plus theirs, with what each one produces.
|
|
@@ -64972,7 +65347,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
64972
65347
|
});
|
|
64973
65348
|
|
|
64974
65349
|
// src/commands/scheduled-agents/triggers.ts
|
|
64975
|
-
import { defineCommand as
|
|
65350
|
+
import { defineCommand as defineCommand210 } from "citty";
|
|
64976
65351
|
var ARGS3 = {
|
|
64977
65352
|
trigger: {
|
|
64978
65353
|
type: "string",
|
|
@@ -65058,7 +65433,7 @@ function shapeTriggerCatalog(response, filter) {
|
|
|
65058
65433
|
}
|
|
65059
65434
|
return { ok: true, data: { groups, reacting: catalog.reacting } };
|
|
65060
65435
|
}
|
|
65061
|
-
var triggersCommand2 =
|
|
65436
|
+
var triggersCommand2 = defineCommand210({
|
|
65062
65437
|
meta: {
|
|
65063
65438
|
name: "triggers",
|
|
65064
65439
|
description: `Everything that can start a scheduled agent.
|
|
@@ -65088,7 +65463,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
65088
65463
|
});
|
|
65089
65464
|
|
|
65090
65465
|
// src/commands/scheduled-agents/unstage.ts
|
|
65091
|
-
import { defineCommand as
|
|
65466
|
+
import { defineCommand as defineCommand211 } from "citty";
|
|
65092
65467
|
registerSchema({
|
|
65093
65468
|
command: "scheduled-agents.unstage",
|
|
65094
65469
|
description: "Take back what this chat staged on one scheduled agent, before Publish \u2014 the same as discarding its row in the change list. With --index, only that one change (its `index` in `baker scheduled-agents list` \u2192 draft.ops). Taking back a create also takes back the edits staged on it. Never touches a published item: to change or remove one, stage update/delete instead.",
|
|
@@ -65114,7 +65489,7 @@ function unstageBody(args5, chatId) {
|
|
|
65114
65489
|
}
|
|
65115
65490
|
return { chatId, ref: args5.ref, index };
|
|
65116
65491
|
}
|
|
65117
|
-
var unstageCommand =
|
|
65492
|
+
var unstageCommand = defineCommand211({
|
|
65118
65493
|
meta: {
|
|
65119
65494
|
name: "unstage",
|
|
65120
65495
|
description: "Take back what this chat staged on a scheduled agent, before Publish. Examples: baker scheduled-agents unstage temp_agent_abc123 | baker scheduled-agents unstage <id> --index 2"
|
|
@@ -65145,7 +65520,7 @@ var unstageCommand = defineCommand205({
|
|
|
65145
65520
|
});
|
|
65146
65521
|
|
|
65147
65522
|
// src/commands/scheduled-agents/update.ts
|
|
65148
|
-
import { defineCommand as
|
|
65523
|
+
import { defineCommand as defineCommand212 } from "citty";
|
|
65149
65524
|
registerSchema({
|
|
65150
65525
|
command: "scheduled-agents.update",
|
|
65151
65526
|
description: "Stage an update to a published scheduled agent, or to one this chat staged (temp_agent_*).",
|
|
@@ -65172,7 +65547,7 @@ registerSchema({
|
|
|
65172
65547
|
enabled: { type: "string", description: "Replacement enabled state", required: false, enum: ["true", "false"] }
|
|
65173
65548
|
}
|
|
65174
65549
|
});
|
|
65175
|
-
var updateCommand4 =
|
|
65550
|
+
var updateCommand4 = defineCommand212({
|
|
65176
65551
|
meta: {
|
|
65177
65552
|
name: "update",
|
|
65178
65553
|
description: "Stage a scheduled agent update. Examples: baker scheduled-agents update <id> --enabled false | baker scheduled-agents update <id> --trigger form.submitted --form quote"
|
|
@@ -65243,7 +65618,7 @@ var updateCommand4 = defineCommand206({
|
|
|
65243
65618
|
});
|
|
65244
65619
|
|
|
65245
65620
|
// src/commands/scheduled-agents/index.ts
|
|
65246
|
-
var scheduledAgentsCommand =
|
|
65621
|
+
var scheduledAgentsCommand = defineCommand213({
|
|
65247
65622
|
meta: {
|
|
65248
65623
|
name: "scheduled-agents",
|
|
65249
65624
|
description: `Manage Scheduled agents. Subcommands: list, get, triggers, targets, create, update, delete, unstage, run, templates.
|
|
@@ -65272,7 +65647,7 @@ Examples:
|
|
|
65272
65647
|
Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
65273
65648
|
},
|
|
65274
65649
|
subCommands: {
|
|
65275
|
-
list:
|
|
65650
|
+
list: listCommand18,
|
|
65276
65651
|
get: getCommand4,
|
|
65277
65652
|
triggers: triggersCommand2,
|
|
65278
65653
|
targets: targetsCommand,
|
|
@@ -65286,14 +65661,14 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
65286
65661
|
});
|
|
65287
65662
|
|
|
65288
65663
|
// src/commands/schema.ts
|
|
65289
|
-
import { defineCommand as
|
|
65664
|
+
import { defineCommand as defineCommand214 } from "citty";
|
|
65290
65665
|
function narrowToFamily(commandName, available) {
|
|
65291
65666
|
const segments = commandName.split(".");
|
|
65292
65667
|
const prefix = segments[0] === "ads" && segments[1] ? `ads.${segments[1]}.` : `${segments[0]}.`;
|
|
65293
65668
|
const siblings = available.filter((name) => name.startsWith(prefix));
|
|
65294
65669
|
return siblings.length > 0 ? siblings : available;
|
|
65295
65670
|
}
|
|
65296
|
-
var schemaCommand2 =
|
|
65671
|
+
var schemaCommand2 = defineCommand214({
|
|
65297
65672
|
meta: {
|
|
65298
65673
|
name: "schema",
|
|
65299
65674
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images search (or images.search)"
|
|
@@ -65338,10 +65713,10 @@ var schemaCommand2 = defineCommand208({
|
|
|
65338
65713
|
});
|
|
65339
65714
|
|
|
65340
65715
|
// src/commands/studio/index.ts
|
|
65341
|
-
import { defineCommand as
|
|
65716
|
+
import { defineCommand as defineCommand223 } from "citty";
|
|
65342
65717
|
|
|
65343
65718
|
// src/commands/studio/animate.ts
|
|
65344
|
-
import { defineCommand as
|
|
65719
|
+
import { defineCommand as defineCommand215 } from "citty";
|
|
65345
65720
|
|
|
65346
65721
|
// src/commands/studio/spokenPace.ts
|
|
65347
65722
|
var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
|
|
@@ -65567,7 +65942,7 @@ function parseImageRefs(spec) {
|
|
|
65567
65942
|
}
|
|
65568
65943
|
var defaultDeps = {
|
|
65569
65944
|
ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
|
|
65570
|
-
upload: (
|
|
65945
|
+
upload: (path49) => uploadLocalImage({ file: path49, contentType: detectImageContentType(path49), source: "uploaded" })
|
|
65571
65946
|
};
|
|
65572
65947
|
async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
65573
65948
|
const refs = parseImageRefs(spec);
|
|
@@ -65587,10 +65962,10 @@ async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
|
65587
65962
|
}
|
|
65588
65963
|
return { imageIds, added };
|
|
65589
65964
|
}
|
|
65590
|
-
function uploadFailure(
|
|
65965
|
+
function uploadFailure(path49) {
|
|
65591
65966
|
return (error) => {
|
|
65592
65967
|
if (error instanceof ApiError) throw error;
|
|
65593
|
-
throw new ApiError("VALIDATION_ERROR", `Could not read "${
|
|
65968
|
+
throw new ApiError("VALIDATION_ERROR", `Could not read "${path49}" as an image.`);
|
|
65594
65969
|
};
|
|
65595
65970
|
}
|
|
65596
65971
|
|
|
@@ -65854,7 +66229,7 @@ async function adByHandHintFor(body) {
|
|
|
65854
66229
|
return null;
|
|
65855
66230
|
}
|
|
65856
66231
|
}
|
|
65857
|
-
var animateCommand =
|
|
66232
|
+
var animateCommand = defineCommand215({
|
|
65858
66233
|
meta: {
|
|
65859
66234
|
name: "animate",
|
|
65860
66235
|
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"
|
|
@@ -65979,7 +66354,7 @@ var animateCommand = defineCommand209({
|
|
|
65979
66354
|
});
|
|
65980
66355
|
|
|
65981
66356
|
// src/commands/studio/generate.ts
|
|
65982
|
-
import { defineCommand as
|
|
66357
|
+
import { defineCommand as defineCommand216 } from "citty";
|
|
65983
66358
|
var MODEL_LIST2 = IMAGE_MODEL_IDS;
|
|
65984
66359
|
var DEFAULT_MAX_WAIT_MS2 = 24e4;
|
|
65985
66360
|
registerSchema({
|
|
@@ -66115,7 +66490,7 @@ function buildGenerateBody(args5, prompt) {
|
|
|
66115
66490
|
}
|
|
66116
66491
|
return body;
|
|
66117
66492
|
}
|
|
66118
|
-
var generateCommand =
|
|
66493
|
+
var generateCommand = defineCommand216({
|
|
66119
66494
|
meta: {
|
|
66120
66495
|
name: "generate",
|
|
66121
66496
|
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]]'"
|
|
@@ -66198,7 +66573,7 @@ var generateCommand = defineCommand210({
|
|
|
66198
66573
|
});
|
|
66199
66574
|
|
|
66200
66575
|
// src/commands/studio/get.ts
|
|
66201
|
-
import { defineCommand as
|
|
66576
|
+
import { defineCommand as defineCommand217 } from "citty";
|
|
66202
66577
|
registerSchema({
|
|
66203
66578
|
command: "studio.get",
|
|
66204
66579
|
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.",
|
|
@@ -66207,7 +66582,7 @@ registerSchema({
|
|
|
66207
66582
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
66208
66583
|
}
|
|
66209
66584
|
});
|
|
66210
|
-
var getCommand5 =
|
|
66585
|
+
var getCommand5 = defineCommand217({
|
|
66211
66586
|
meta: {
|
|
66212
66587
|
name: "get",
|
|
66213
66588
|
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"
|
|
@@ -66236,7 +66611,7 @@ var getCommand5 = defineCommand211({
|
|
|
66236
66611
|
});
|
|
66237
66612
|
|
|
66238
66613
|
// src/commands/studio/improve.ts
|
|
66239
|
-
import { defineCommand as
|
|
66614
|
+
import { defineCommand as defineCommand218 } from "citty";
|
|
66240
66615
|
var DESCRIPTION2 = "Sharpen a rough brief into directed art direction \u2014 the same rewrite the client gets from the wand in the Studio prompt bar. Reach for it when you are relaying the CLIENT's own words and want them shaped without substituting your voice; when you are writing the art direction yourself, just write it, because you will do a better job than this does.";
|
|
66241
66616
|
registerSchema({
|
|
66242
66617
|
command: "studio.improve",
|
|
@@ -66261,7 +66636,7 @@ registerSchema({
|
|
|
66261
66636
|
}
|
|
66262
66637
|
}
|
|
66263
66638
|
});
|
|
66264
|
-
var improveCommand =
|
|
66639
|
+
var improveCommand = defineCommand218({
|
|
66265
66640
|
meta: {
|
|
66266
66641
|
name: "improve",
|
|
66267
66642
|
description: `${DESCRIPTION2}
|
|
@@ -66305,7 +66680,7 @@ Examples:
|
|
|
66305
66680
|
});
|
|
66306
66681
|
|
|
66307
66682
|
// src/commands/studio/keep.ts
|
|
66308
|
-
import { defineCommand as
|
|
66683
|
+
import { defineCommand as defineCommand219 } from "citty";
|
|
66309
66684
|
registerSchema({
|
|
66310
66685
|
command: "studio.keep",
|
|
66311
66686
|
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.",
|
|
@@ -66315,7 +66690,7 @@ registerSchema({
|
|
|
66315
66690
|
undo: { type: "boolean", description: "Un-star an image, or take a kept clip back out", required: false }
|
|
66316
66691
|
}
|
|
66317
66692
|
});
|
|
66318
|
-
var keepCommand =
|
|
66693
|
+
var keepCommand = defineCommand219({
|
|
66319
66694
|
meta: {
|
|
66320
66695
|
name: "keep",
|
|
66321
66696
|
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"
|
|
@@ -66366,7 +66741,7 @@ var keepCommand = defineCommand213({
|
|
|
66366
66741
|
});
|
|
66367
66742
|
|
|
66368
66743
|
// src/commands/studio/list.ts
|
|
66369
|
-
import { defineCommand as
|
|
66744
|
+
import { defineCommand as defineCommand220 } from "citty";
|
|
66370
66745
|
registerSchema({
|
|
66371
66746
|
command: "studio.list",
|
|
66372
66747
|
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.",
|
|
@@ -66377,7 +66752,7 @@ registerSchema({
|
|
|
66377
66752
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
66378
66753
|
}
|
|
66379
66754
|
});
|
|
66380
|
-
var
|
|
66755
|
+
var listCommand19 = defineCommand220({
|
|
66381
66756
|
meta: {
|
|
66382
66757
|
name: "list",
|
|
66383
66758
|
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"
|
|
@@ -66411,7 +66786,7 @@ var listCommand18 = defineCommand214({
|
|
|
66411
66786
|
});
|
|
66412
66787
|
|
|
66413
66788
|
// src/commands/studio/models.ts
|
|
66414
|
-
import { defineCommand as
|
|
66789
|
+
import { defineCommand as defineCommand221 } from "citty";
|
|
66415
66790
|
var DESCRIPTION3 = "What each Studio model actually accepts: its shapes, resolutions, clip lengths, prompt character cap, how many reference images it takes, and which knobs it has. Read this before a batch you care about \u2014 the models disagree far more than they look like they do, and a setting the chosen model does not have is REFUSED, not ignored.";
|
|
66416
66791
|
registerSchema({
|
|
66417
66792
|
command: "studio.models",
|
|
@@ -66498,7 +66873,7 @@ function buildModelCards(kind, model) {
|
|
|
66498
66873
|
const selected = model ? ids.filter((id) => id === model) : ids;
|
|
66499
66874
|
return selected.map((id) => build(id));
|
|
66500
66875
|
}
|
|
66501
|
-
var modelsCommand =
|
|
66876
|
+
var modelsCommand = defineCommand221({
|
|
66502
66877
|
meta: {
|
|
66503
66878
|
name: "models",
|
|
66504
66879
|
description: `${DESCRIPTION3}
|
|
@@ -66545,13 +66920,13 @@ Examples:
|
|
|
66545
66920
|
});
|
|
66546
66921
|
|
|
66547
66922
|
// src/commands/studio/skills.ts
|
|
66548
|
-
import { defineCommand as
|
|
66923
|
+
import { defineCommand as defineCommand222 } from "citty";
|
|
66549
66924
|
registerSchema({
|
|
66550
66925
|
command: "studio.skills",
|
|
66551
66926
|
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.",
|
|
66552
66927
|
args: {}
|
|
66553
66928
|
});
|
|
66554
|
-
var skillsCommand =
|
|
66929
|
+
var skillsCommand = defineCommand222({
|
|
66555
66930
|
meta: {
|
|
66556
66931
|
name: "skills",
|
|
66557
66932
|
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"
|
|
@@ -66575,7 +66950,7 @@ var skillsCommand = defineCommand216({
|
|
|
66575
66950
|
});
|
|
66576
66951
|
|
|
66577
66952
|
// src/commands/studio/index.ts
|
|
66578
|
-
var studioCommand =
|
|
66953
|
+
var studioCommand = defineCommand223({
|
|
66579
66954
|
meta: {
|
|
66580
66955
|
name: "studio",
|
|
66581
66956
|
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.
|
|
@@ -66609,7 +66984,7 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
66609
66984
|
generate: generateCommand,
|
|
66610
66985
|
animate: animateCommand,
|
|
66611
66986
|
get: getCommand5,
|
|
66612
|
-
list:
|
|
66987
|
+
list: listCommand19,
|
|
66613
66988
|
keep: keepCommand,
|
|
66614
66989
|
models: modelsCommand,
|
|
66615
66990
|
skills: skillsCommand,
|
|
@@ -66618,10 +66993,10 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
66618
66993
|
});
|
|
66619
66994
|
|
|
66620
66995
|
// src/commands/tag-manager/index.ts
|
|
66621
|
-
import { defineCommand as
|
|
66996
|
+
import { defineCommand as defineCommand227 } from "citty";
|
|
66622
66997
|
|
|
66623
66998
|
// src/commands/tag-manager/draft.ts
|
|
66624
|
-
import { defineCommand as
|
|
66999
|
+
import { defineCommand as defineCommand224 } from "citty";
|
|
66625
67000
|
|
|
66626
67001
|
// src/commands/tag-manager/shared.ts
|
|
66627
67002
|
import { readFileSync as readFileSync21 } from "fs";
|
|
@@ -66688,10 +67063,10 @@ async function stageOp4(op) {
|
|
|
66688
67063
|
handleError8(err);
|
|
66689
67064
|
}
|
|
66690
67065
|
}
|
|
66691
|
-
async function draftAction3(
|
|
67066
|
+
async function draftAction3(path49, body, chat) {
|
|
66692
67067
|
const chatId = resolveChatId(chat);
|
|
66693
67068
|
try {
|
|
66694
|
-
const data = await apiPost(
|
|
67069
|
+
const data = await apiPost(path49, { chatId, ...body });
|
|
66695
67070
|
writeJsonEnvelope({ ok: true, data });
|
|
66696
67071
|
return data;
|
|
66697
67072
|
} catch (err) {
|
|
@@ -66744,13 +67119,13 @@ registerSchema({
|
|
|
66744
67119
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
66745
67120
|
}
|
|
66746
67121
|
});
|
|
66747
|
-
var draftCommand5 =
|
|
67122
|
+
var draftCommand5 = defineCommand224({
|
|
66748
67123
|
meta: {
|
|
66749
67124
|
name: "draft",
|
|
66750
67125
|
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."
|
|
66751
67126
|
},
|
|
66752
67127
|
subCommands: {
|
|
66753
|
-
list:
|
|
67128
|
+
list: defineCommand224({
|
|
66754
67129
|
meta: {
|
|
66755
67130
|
name: "list",
|
|
66756
67131
|
description: "Review everything staged on this chat (--json for the raw envelope)"
|
|
@@ -66763,7 +67138,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66763
67138
|
await draftList2(args5.json === true, args5.chat);
|
|
66764
67139
|
}
|
|
66765
67140
|
}),
|
|
66766
|
-
show:
|
|
67141
|
+
show: defineCommand224({
|
|
66767
67142
|
meta: {
|
|
66768
67143
|
name: "show",
|
|
66769
67144
|
description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
|
|
@@ -66780,7 +67155,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66780
67155
|
);
|
|
66781
67156
|
}
|
|
66782
67157
|
}),
|
|
66783
|
-
amend:
|
|
67158
|
+
amend: defineCommand224({
|
|
66784
67159
|
meta: {
|
|
66785
67160
|
name: "amend",
|
|
66786
67161
|
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."
|
|
@@ -66797,7 +67172,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66797
67172
|
});
|
|
66798
67173
|
}
|
|
66799
67174
|
}),
|
|
66800
|
-
remove:
|
|
67175
|
+
remove: defineCommand224({
|
|
66801
67176
|
meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
|
|
66802
67177
|
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
66803
67178
|
run: async ({ args: args5 }) => {
|
|
@@ -66806,7 +67181,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66806
67181
|
});
|
|
66807
67182
|
}
|
|
66808
67183
|
}),
|
|
66809
|
-
clear:
|
|
67184
|
+
clear: defineCommand224({
|
|
66810
67185
|
meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
|
|
66811
67186
|
run: async () => {
|
|
66812
67187
|
await draftAction3("/api/tag-manager/draft/clear", {});
|
|
@@ -66816,7 +67191,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66816
67191
|
});
|
|
66817
67192
|
|
|
66818
67193
|
// src/commands/tag-manager/read.ts
|
|
66819
|
-
import { defineCommand as
|
|
67194
|
+
import { defineCommand as defineCommand225 } from "citty";
|
|
66820
67195
|
registerSchema({
|
|
66821
67196
|
command: "tagManager.containers",
|
|
66822
67197
|
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.",
|
|
@@ -66857,7 +67232,7 @@ function containersHints(containers) {
|
|
|
66857
67232
|
}))
|
|
66858
67233
|
});
|
|
66859
67234
|
}
|
|
66860
|
-
var containersCommand =
|
|
67235
|
+
var containersCommand = defineCommand225({
|
|
66861
67236
|
meta: {
|
|
66862
67237
|
name: "containers",
|
|
66863
67238
|
description: `List Tag Manager containers reachable by this company's connection.
|
|
@@ -66874,7 +67249,7 @@ Start here:
|
|
|
66874
67249
|
}
|
|
66875
67250
|
}
|
|
66876
67251
|
});
|
|
66877
|
-
var readCommand =
|
|
67252
|
+
var readCommand = defineCommand225({
|
|
66878
67253
|
meta: {
|
|
66879
67254
|
name: "read",
|
|
66880
67255
|
description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
|
|
@@ -66916,7 +67291,7 @@ Examples:
|
|
|
66916
67291
|
});
|
|
66917
67292
|
|
|
66918
67293
|
// src/commands/tag-manager/write-commands.ts
|
|
66919
|
-
import { defineCommand as
|
|
67294
|
+
import { defineCommand as defineCommand226 } from "citty";
|
|
66920
67295
|
var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
|
|
66921
67296
|
var ENTITIES = [
|
|
66922
67297
|
{
|
|
@@ -66972,10 +67347,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
|
|
|
66972
67347
|
});
|
|
66973
67348
|
}
|
|
66974
67349
|
function entityCommand(entity, noun, example) {
|
|
66975
|
-
return
|
|
67350
|
+
return defineCommand226({
|
|
66976
67351
|
meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
|
|
66977
67352
|
subCommands: {
|
|
66978
|
-
create:
|
|
67353
|
+
create: defineCommand226({
|
|
66979
67354
|
meta: {
|
|
66980
67355
|
name: "create",
|
|
66981
67356
|
description: `Stage a new ${noun}
|
|
@@ -66997,7 +67372,7 @@ Examples:
|
|
|
66997
67372
|
});
|
|
66998
67373
|
}
|
|
66999
67374
|
}),
|
|
67000
|
-
update:
|
|
67375
|
+
update: defineCommand226({
|
|
67001
67376
|
meta: {
|
|
67002
67377
|
name: "update",
|
|
67003
67378
|
description: `Stage an update to an existing ${noun} (pass its id or path)`
|
|
@@ -67017,7 +67392,7 @@ Examples:
|
|
|
67017
67392
|
});
|
|
67018
67393
|
}
|
|
67019
67394
|
}),
|
|
67020
|
-
delete:
|
|
67395
|
+
delete: defineCommand226({
|
|
67021
67396
|
meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
|
|
67022
67397
|
args: {
|
|
67023
67398
|
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
@@ -67058,7 +67433,7 @@ function builtinTypes(args5) {
|
|
|
67058
67433
|
}
|
|
67059
67434
|
return raw.split(",").map((entry) => entry.trim());
|
|
67060
67435
|
}
|
|
67061
|
-
var builtinCommand =
|
|
67436
|
+
var builtinCommand = defineCommand226({
|
|
67062
67437
|
meta: {
|
|
67063
67438
|
name: "builtin",
|
|
67064
67439
|
description: `Enable or disable built-in variables
|
|
@@ -67068,7 +67443,7 @@ Examples:
|
|
|
67068
67443
|
baker tag-manager builtin disable --types formId`
|
|
67069
67444
|
},
|
|
67070
67445
|
subCommands: {
|
|
67071
|
-
enable:
|
|
67446
|
+
enable: defineCommand226({
|
|
67072
67447
|
meta: { name: "enable", description: "Stage enabling built-in variables" },
|
|
67073
67448
|
args: {
|
|
67074
67449
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -67082,7 +67457,7 @@ Examples:
|
|
|
67082
67457
|
});
|
|
67083
67458
|
}
|
|
67084
67459
|
}),
|
|
67085
|
-
disable:
|
|
67460
|
+
disable: defineCommand226({
|
|
67086
67461
|
meta: { name: "disable", description: "Stage disabling built-in variables" },
|
|
67087
67462
|
args: {
|
|
67088
67463
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -67100,7 +67475,7 @@ Examples:
|
|
|
67100
67475
|
});
|
|
67101
67476
|
|
|
67102
67477
|
// src/commands/tag-manager/index.ts
|
|
67103
|
-
var tagManagerCommand =
|
|
67478
|
+
var tagManagerCommand = defineCommand227({
|
|
67104
67479
|
meta: {
|
|
67105
67480
|
name: "tag-manager",
|
|
67106
67481
|
description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
|
|
@@ -67137,7 +67512,7 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
|
|
|
67137
67512
|
});
|
|
67138
67513
|
|
|
67139
67514
|
// src/commands/tags/index.ts
|
|
67140
|
-
import { defineCommand as
|
|
67515
|
+
import { defineCommand as defineCommand228 } from "citty";
|
|
67141
67516
|
|
|
67142
67517
|
// src/commands/tags/shared.ts
|
|
67143
67518
|
function failApi3(err) {
|
|
@@ -67217,7 +67592,7 @@ async function listTags(json) {
|
|
|
67217
67592
|
var listArgs12 = {
|
|
67218
67593
|
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
|
|
67219
67594
|
};
|
|
67220
|
-
var
|
|
67595
|
+
var listCommand20 = defineCommand228({
|
|
67221
67596
|
meta: {
|
|
67222
67597
|
name: "list",
|
|
67223
67598
|
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"
|
|
@@ -67236,7 +67611,7 @@ async function listDraft4(chat) {
|
|
|
67236
67611
|
failApi3(err);
|
|
67237
67612
|
}
|
|
67238
67613
|
}
|
|
67239
|
-
var draftCommand6 =
|
|
67614
|
+
var draftCommand6 = defineCommand228({
|
|
67240
67615
|
meta: {
|
|
67241
67616
|
name: "draft",
|
|
67242
67617
|
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."
|
|
@@ -67246,7 +67621,7 @@ var draftCommand6 = defineCommand222({
|
|
|
67246
67621
|
await listDraft4(args5.chat);
|
|
67247
67622
|
}
|
|
67248
67623
|
});
|
|
67249
|
-
var tagsCommand4 =
|
|
67624
|
+
var tagsCommand4 = defineCommand228({
|
|
67250
67625
|
meta: {
|
|
67251
67626
|
name: "tags",
|
|
67252
67627
|
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.
|
|
@@ -67263,7 +67638,7 @@ Examples:
|
|
|
67263
67638
|
Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
67264
67639
|
},
|
|
67265
67640
|
subCommands: {
|
|
67266
|
-
list:
|
|
67641
|
+
list: listCommand20,
|
|
67267
67642
|
draft: draftCommand6
|
|
67268
67643
|
},
|
|
67269
67644
|
// Bare `baker tags` lists the effective tags. `args` stays so citty knows this
|
|
@@ -67275,10 +67650,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
67275
67650
|
});
|
|
67276
67651
|
|
|
67277
67652
|
// src/commands/testimonials/index.ts
|
|
67278
|
-
import { defineCommand as
|
|
67653
|
+
import { defineCommand as defineCommand232 } from "citty";
|
|
67279
67654
|
|
|
67280
67655
|
// src/commands/testimonials/get.ts
|
|
67281
|
-
import { defineCommand as
|
|
67656
|
+
import { defineCommand as defineCommand229 } from "citty";
|
|
67282
67657
|
registerSchema({
|
|
67283
67658
|
command: "testimonials.get",
|
|
67284
67659
|
description: "Get a single testimonial by ID",
|
|
@@ -67286,7 +67661,7 @@ registerSchema({
|
|
|
67286
67661
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
67287
67662
|
}
|
|
67288
67663
|
});
|
|
67289
|
-
var getCommand6 =
|
|
67664
|
+
var getCommand6 = defineCommand229({
|
|
67290
67665
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
67291
67666
|
args: {
|
|
67292
67667
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -67323,7 +67698,7 @@ var getCommand6 = defineCommand223({
|
|
|
67323
67698
|
});
|
|
67324
67699
|
|
|
67325
67700
|
// src/commands/testimonials/list.ts
|
|
67326
|
-
import { defineCommand as
|
|
67701
|
+
import { defineCommand as defineCommand230 } from "citty";
|
|
67327
67702
|
|
|
67328
67703
|
// src/commands/testimonials/emptyCorpusHints.ts
|
|
67329
67704
|
function resolveEmptyReason({
|
|
@@ -67480,7 +67855,7 @@ function buildListParams(args5) {
|
|
|
67480
67855
|
}
|
|
67481
67856
|
return params;
|
|
67482
67857
|
}
|
|
67483
|
-
var
|
|
67858
|
+
var listCommand21 = defineCommand230({
|
|
67484
67859
|
meta: {
|
|
67485
67860
|
name: "list",
|
|
67486
67861
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -67540,7 +67915,7 @@ var listCommand20 = defineCommand224({
|
|
|
67540
67915
|
});
|
|
67541
67916
|
|
|
67542
67917
|
// src/commands/testimonials/search.ts
|
|
67543
|
-
import { defineCommand as
|
|
67918
|
+
import { defineCommand as defineCommand231 } from "citty";
|
|
67544
67919
|
var FILTER_FLAGS2 = ["source", "rating-min", "rating-max", "status", "sentiment", "language", "tags"];
|
|
67545
67920
|
function languageBiasHint(results, requestedLanguage) {
|
|
67546
67921
|
if (requestedLanguage) {
|
|
@@ -67619,7 +67994,7 @@ function buildSearchRequest(query, args5) {
|
|
|
67619
67994
|
}
|
|
67620
67995
|
return body;
|
|
67621
67996
|
}
|
|
67622
|
-
var searchCommand3 =
|
|
67997
|
+
var searchCommand3 = defineCommand231({
|
|
67623
67998
|
meta: {
|
|
67624
67999
|
name: "search",
|
|
67625
68000
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -67683,7 +68058,7 @@ var searchCommand3 = defineCommand225({
|
|
|
67683
68058
|
var tagsCommand5 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
67684
68059
|
|
|
67685
68060
|
// src/commands/testimonials/index.ts
|
|
67686
|
-
var testimonialsCommand =
|
|
68061
|
+
var testimonialsCommand = defineCommand232({
|
|
67687
68062
|
meta: {
|
|
67688
68063
|
name: "testimonials",
|
|
67689
68064
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -67699,16 +68074,16 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
|
|
|
67699
68074
|
subCommands: {
|
|
67700
68075
|
get: getCommand6,
|
|
67701
68076
|
search: searchCommand3,
|
|
67702
|
-
list:
|
|
68077
|
+
list: listCommand21,
|
|
67703
68078
|
tags: tagsCommand5
|
|
67704
68079
|
}
|
|
67705
68080
|
});
|
|
67706
68081
|
|
|
67707
68082
|
// src/commands/videos/index.ts
|
|
67708
|
-
import { defineCommand as
|
|
68083
|
+
import { defineCommand as defineCommand241 } from "citty";
|
|
67709
68084
|
|
|
67710
68085
|
// src/commands/videos/delete.ts
|
|
67711
|
-
import { defineCommand as
|
|
68086
|
+
import { defineCommand as defineCommand233 } from "citty";
|
|
67712
68087
|
registerSchema({
|
|
67713
68088
|
command: "videos.delete",
|
|
67714
68089
|
description: "Delete a video by ID",
|
|
@@ -67722,7 +68097,7 @@ registerSchema({
|
|
|
67722
68097
|
}
|
|
67723
68098
|
}
|
|
67724
68099
|
});
|
|
67725
|
-
var deleteCommand4 =
|
|
68100
|
+
var deleteCommand4 = defineCommand233({
|
|
67726
68101
|
meta: {
|
|
67727
68102
|
name: "delete",
|
|
67728
68103
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -67763,7 +68138,7 @@ var deleteCommand4 = defineCommand227({
|
|
|
67763
68138
|
});
|
|
67764
68139
|
|
|
67765
68140
|
// src/commands/videos/describe.ts
|
|
67766
|
-
import { defineCommand as
|
|
68141
|
+
import { defineCommand as defineCommand234 } from "citty";
|
|
67767
68142
|
var DESCRIPTION_HELP2 = "What the clip actually shows, in the words someone would search for it by. This is what `baker videos search` retrieves on.";
|
|
67768
68143
|
registerSchema({
|
|
67769
68144
|
command: "videos.describe",
|
|
@@ -67780,7 +68155,7 @@ registerSchema({
|
|
|
67780
68155
|
full: { type: "boolean", description: "Return the whole library row, not just what changed", required: false }
|
|
67781
68156
|
}
|
|
67782
68157
|
});
|
|
67783
|
-
var describeCommand2 =
|
|
68158
|
+
var describeCommand2 = defineCommand234({
|
|
67784
68159
|
meta: {
|
|
67785
68160
|
name: "describe",
|
|
67786
68161
|
description: `Correct what the library says a video is. Only the fields you pass change; the rest keep their current values.
|
|
@@ -67837,108 +68212,10 @@ Example: baker videos describe j571abc123 --description "Customer explaining how
|
|
|
67837
68212
|
}
|
|
67838
68213
|
});
|
|
67839
68214
|
|
|
67840
|
-
// src/commands/videos/
|
|
67841
|
-
import {
|
|
67842
|
-
registerSchema({
|
|
67843
|
-
command: "videos.get",
|
|
67844
|
-
description: "Get a single video by ID",
|
|
67845
|
-
args: {
|
|
67846
|
-
id: { type: "string", description: "Video ID", required: true }
|
|
67847
|
-
}
|
|
67848
|
-
});
|
|
67849
|
-
var getCommand7 = defineCommand229({
|
|
67850
|
-
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
67851
|
-
args: {
|
|
67852
|
-
id: { type: "positional", description: "Video ID", required: false },
|
|
67853
|
-
"video-id": { type: "string", description: "Video ID (alternative to positional)", required: false },
|
|
67854
|
-
output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
|
|
67855
|
-
fields: { type: "string", description: "Comma-separated field names to include", required: false },
|
|
67856
|
-
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
67857
|
-
},
|
|
67858
|
-
run: async ({ args: args5 }) => {
|
|
67859
|
-
try {
|
|
67860
|
-
const id = args5.id || args5["video-id"];
|
|
67861
|
-
if (!id) {
|
|
67862
|
-
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Video ID is required" } });
|
|
67863
|
-
process.exit(1);
|
|
67864
|
-
}
|
|
67865
|
-
validateConvexId(id);
|
|
67866
|
-
const data = await apiGet("/api/videos/get", { id });
|
|
67867
|
-
writeOutput(
|
|
67868
|
-
{ ok: true, data },
|
|
67869
|
-
args5.output || "json",
|
|
67870
|
-
args5.fields ? args5.fields.split(",") : void 0,
|
|
67871
|
-
args5.full,
|
|
67872
|
-
videoNormalizer
|
|
67873
|
-
);
|
|
67874
|
-
} catch (err) {
|
|
67875
|
-
if (err instanceof ApiError) {
|
|
67876
|
-
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
67877
|
-
process.exit(1);
|
|
67878
|
-
}
|
|
67879
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
67880
|
-
process.exit(1);
|
|
67881
|
-
}
|
|
67882
|
-
}
|
|
67883
|
-
});
|
|
67884
|
-
|
|
67885
|
-
// src/commands/videos/group.ts
|
|
67886
|
-
import { defineCommand as defineCommand230 } from "citty";
|
|
67887
|
-
registerSchema({
|
|
67888
|
-
command: "videos.group",
|
|
67889
|
-
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
67890
|
-
args: {
|
|
67891
|
-
id: { type: "string", description: "A video or image id \u2014 returns that asset's whole set", required: false },
|
|
67892
|
-
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
67893
|
-
}
|
|
67894
|
-
});
|
|
67895
|
-
var groupCommand2 = defineCommand230({
|
|
67896
|
-
meta: {
|
|
67897
|
-
name: "group",
|
|
67898
|
-
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>"
|
|
67899
|
-
},
|
|
67900
|
-
args: {
|
|
67901
|
-
id: { type: "positional", description: "A video or image id from the set", required: false },
|
|
67902
|
-
"group-key": { type: "string", description: "The set key, if you already have it", required: false }
|
|
67903
|
-
},
|
|
67904
|
-
run: async ({ args: args5 }) => {
|
|
67905
|
-
await runMediaGroupLookup({
|
|
67906
|
-
id: args5.id,
|
|
67907
|
-
groupKey: args5["group-key"],
|
|
67908
|
-
path: "/api/videos/group",
|
|
67909
|
-
idLabel: "a video or image id"
|
|
67910
|
-
});
|
|
67911
|
-
}
|
|
67912
|
-
});
|
|
67913
|
-
|
|
67914
|
-
// src/commands/videos/ingest.ts
|
|
67915
|
-
import { mkdtemp as mkdtemp3, rm as rm9, stat as stat11 } from "fs/promises";
|
|
67916
|
-
import { tmpdir as tmpdir4 } from "os";
|
|
68215
|
+
// src/commands/videos/fetch.ts
|
|
68216
|
+
import { mkdir as mkdir15 } from "fs/promises";
|
|
67917
68217
|
import path47 from "path";
|
|
67918
|
-
import { defineCommand as
|
|
67919
|
-
|
|
67920
|
-
// src/lib/streamUpload.ts
|
|
67921
|
-
import { createHash as createHash2 } from "crypto";
|
|
67922
|
-
import { createReadStream } from "fs";
|
|
67923
|
-
import { Readable } from "stream";
|
|
67924
|
-
import { pipeline } from "stream/promises";
|
|
67925
|
-
async function hashFile(filePath) {
|
|
67926
|
-
const hash = createHash2("sha256");
|
|
67927
|
-
await pipeline(createReadStream(filePath), hash);
|
|
67928
|
-
return hash.digest("hex");
|
|
67929
|
-
}
|
|
67930
|
-
async function putFileStreamed(args5) {
|
|
67931
|
-
const body = Readable.toWeb(createReadStream(args5.filePath));
|
|
67932
|
-
return await fetch(args5.putUrl, {
|
|
67933
|
-
method: "PUT",
|
|
67934
|
-
body,
|
|
67935
|
-
headers: {
|
|
67936
|
-
"Content-Type": args5.contentType,
|
|
67937
|
-
"Content-Length": String(args5.sizeBytes)
|
|
67938
|
-
},
|
|
67939
|
-
duplex: "half"
|
|
67940
|
-
});
|
|
67941
|
-
}
|
|
68218
|
+
import { defineCommand as defineCommand235 } from "citty";
|
|
67942
68219
|
|
|
67943
68220
|
// src/commands/videos/videoPlatforms.ts
|
|
67944
68221
|
var PLATFORM_DOMAINS = {
|
|
@@ -67947,6 +68224,7 @@ var PLATFORM_DOMAINS = {
|
|
|
67947
68224
|
tiktok: ["tiktok.com"],
|
|
67948
68225
|
twitter: ["twitter.com", "x.com", "vxtwitter.com", "fixvx.com"],
|
|
67949
68226
|
facebook: ["facebook.com", "fb.watch", "fb.com"],
|
|
68227
|
+
linkedin: ["linkedin.com", "lnkd.in"],
|
|
67950
68228
|
reddit: ["reddit.com", "redd.it"],
|
|
67951
68229
|
vimeo: ["vimeo.com"],
|
|
67952
68230
|
dailymotion: ["dailymotion.com", "dai.ly"],
|
|
@@ -68051,6 +68329,181 @@ function safePathname(rawUrl) {
|
|
|
68051
68329
|
}
|
|
68052
68330
|
}
|
|
68053
68331
|
|
|
68332
|
+
// src/commands/videos/fetch.ts
|
|
68333
|
+
registerSchema({
|
|
68334
|
+
command: "videos.fetch",
|
|
68335
|
+
description: "Download a video page (YouTube, TikTok, Vimeo, \u2026) to a local .mp4 without adding it to the library. For editing a clip locally; use `videos ingest` to add one to the library.",
|
|
68336
|
+
args: {
|
|
68337
|
+
url: { type: "string", description: "Video page URL", required: true },
|
|
68338
|
+
out: { type: "string", description: "Directory to write the file into (created if missing)", required: true },
|
|
68339
|
+
"max-seconds": {
|
|
68340
|
+
type: "string",
|
|
68341
|
+
description: `Refuse videos longer than this many seconds (default ${MAX_VIDEO_INGEST_SECONDS})`,
|
|
68342
|
+
required: false
|
|
68343
|
+
},
|
|
68344
|
+
"timeout-ms": { type: "string", description: "Download time limit in milliseconds", required: false }
|
|
68345
|
+
}
|
|
68346
|
+
});
|
|
68347
|
+
function positiveInt(value) {
|
|
68348
|
+
const parsed = typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
|
|
68349
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
68350
|
+
}
|
|
68351
|
+
var fetchCommand2 = defineCommand235({
|
|
68352
|
+
meta: {
|
|
68353
|
+
name: "fetch",
|
|
68354
|
+
description: "Download a video page to a local .mp4 without adding it to the library. Same downloader as `ingest` (proxy fallback, duration check).\n\nExample: baker videos fetch https://www.youtube.com/watch?v=abc123 --out ./clips"
|
|
68355
|
+
},
|
|
68356
|
+
args: {
|
|
68357
|
+
url: { type: "positional", description: "Video page URL", required: true },
|
|
68358
|
+
out: { type: "string", description: "Directory to write the file into", required: true },
|
|
68359
|
+
"max-seconds": { type: "string", description: "Refuse videos longer than this", required: false },
|
|
68360
|
+
"timeout-ms": { type: "string", description: "Download time limit in milliseconds", required: false }
|
|
68361
|
+
},
|
|
68362
|
+
run: async ({ args: args5 }) => {
|
|
68363
|
+
const url = String(args5.url ?? "");
|
|
68364
|
+
const outDir = path47.resolve(String(args5.out ?? ""));
|
|
68365
|
+
const maxSeconds = positiveInt(args5["max-seconds"]) ?? MAX_VIDEO_INGEST_SECONDS;
|
|
68366
|
+
try {
|
|
68367
|
+
await mkdir15(outDir, { recursive: true });
|
|
68368
|
+
const vimeoCookie = captureVimeoCookie();
|
|
68369
|
+
const probe = await probeYtDlp({ url, vimeoCookie, cookieDir: outDir });
|
|
68370
|
+
if (isAudioOnly(probe.info)) {
|
|
68371
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "That link is audio, not video." } });
|
|
68372
|
+
process.exit(1);
|
|
68373
|
+
}
|
|
68374
|
+
const seconds = durationSeconds(probe.info);
|
|
68375
|
+
const tooLong = refuseByDuration(seconds, maxSeconds);
|
|
68376
|
+
if (tooLong) {
|
|
68377
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: tooLong } });
|
|
68378
|
+
process.exit(1);
|
|
68379
|
+
}
|
|
68380
|
+
const { filePath, tier, reducedQuality } = await runYtDlp({
|
|
68381
|
+
url,
|
|
68382
|
+
audioOnly: false,
|
|
68383
|
+
workDir: outDir,
|
|
68384
|
+
vimeoCookie,
|
|
68385
|
+
timeoutMs: positiveInt(args5["timeout-ms"]) ?? downloadTimeoutMs(seconds)
|
|
68386
|
+
});
|
|
68387
|
+
writeJson({
|
|
68388
|
+
ok: true,
|
|
68389
|
+
data: {
|
|
68390
|
+
file: filePath,
|
|
68391
|
+
durationSeconds: seconds,
|
|
68392
|
+
egress: tier,
|
|
68393
|
+
...reducedQuality ? { reducedQuality: true } : {}
|
|
68394
|
+
}
|
|
68395
|
+
});
|
|
68396
|
+
} catch (err) {
|
|
68397
|
+
const message = err instanceof YtDlpError ? `${err.message}: ${err.stderrTail}`.trim() : err instanceof Error ? err.message : String(err);
|
|
68398
|
+
writeJson({ ok: false, error: { code: "DOWNLOAD_FAILED", message } });
|
|
68399
|
+
process.exit(1);
|
|
68400
|
+
}
|
|
68401
|
+
}
|
|
68402
|
+
});
|
|
68403
|
+
|
|
68404
|
+
// src/commands/videos/get.ts
|
|
68405
|
+
import { defineCommand as defineCommand236 } from "citty";
|
|
68406
|
+
registerSchema({
|
|
68407
|
+
command: "videos.get",
|
|
68408
|
+
description: "Get a single video by ID",
|
|
68409
|
+
args: {
|
|
68410
|
+
id: { type: "string", description: "Video ID", required: true }
|
|
68411
|
+
}
|
|
68412
|
+
});
|
|
68413
|
+
var getCommand7 = defineCommand236({
|
|
68414
|
+
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
68415
|
+
args: {
|
|
68416
|
+
id: { type: "positional", description: "Video ID", required: false },
|
|
68417
|
+
"video-id": { type: "string", description: "Video ID (alternative to positional)", required: false },
|
|
68418
|
+
output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
|
|
68419
|
+
fields: { type: "string", description: "Comma-separated field names to include", required: false },
|
|
68420
|
+
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
68421
|
+
},
|
|
68422
|
+
run: async ({ args: args5 }) => {
|
|
68423
|
+
try {
|
|
68424
|
+
const id = args5.id || args5["video-id"];
|
|
68425
|
+
if (!id) {
|
|
68426
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Video ID is required" } });
|
|
68427
|
+
process.exit(1);
|
|
68428
|
+
}
|
|
68429
|
+
validateConvexId(id);
|
|
68430
|
+
const data = await apiGet("/api/videos/get", { id });
|
|
68431
|
+
writeOutput(
|
|
68432
|
+
{ ok: true, data },
|
|
68433
|
+
args5.output || "json",
|
|
68434
|
+
args5.fields ? args5.fields.split(",") : void 0,
|
|
68435
|
+
args5.full,
|
|
68436
|
+
videoNormalizer
|
|
68437
|
+
);
|
|
68438
|
+
} catch (err) {
|
|
68439
|
+
if (err instanceof ApiError) {
|
|
68440
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
68441
|
+
process.exit(1);
|
|
68442
|
+
}
|
|
68443
|
+
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
68444
|
+
process.exit(1);
|
|
68445
|
+
}
|
|
68446
|
+
}
|
|
68447
|
+
});
|
|
68448
|
+
|
|
68449
|
+
// src/commands/videos/group.ts
|
|
68450
|
+
import { defineCommand as defineCommand237 } from "citty";
|
|
68451
|
+
registerSchema({
|
|
68452
|
+
command: "videos.group",
|
|
68453
|
+
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
68454
|
+
args: {
|
|
68455
|
+
id: { type: "string", description: "A video or image id \u2014 returns that asset's whole set", required: false },
|
|
68456
|
+
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
68457
|
+
}
|
|
68458
|
+
});
|
|
68459
|
+
var groupCommand2 = defineCommand237({
|
|
68460
|
+
meta: {
|
|
68461
|
+
name: "group",
|
|
68462
|
+
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>"
|
|
68463
|
+
},
|
|
68464
|
+
args: {
|
|
68465
|
+
id: { type: "positional", description: "A video or image id from the set", required: false },
|
|
68466
|
+
"group-key": { type: "string", description: "The set key, if you already have it", required: false }
|
|
68467
|
+
},
|
|
68468
|
+
run: async ({ args: args5 }) => {
|
|
68469
|
+
await runMediaGroupLookup({
|
|
68470
|
+
id: args5.id,
|
|
68471
|
+
groupKey: args5["group-key"],
|
|
68472
|
+
path: "/api/videos/group",
|
|
68473
|
+
idLabel: "a video or image id"
|
|
68474
|
+
});
|
|
68475
|
+
}
|
|
68476
|
+
});
|
|
68477
|
+
|
|
68478
|
+
// src/commands/videos/ingest.ts
|
|
68479
|
+
import { mkdtemp as mkdtemp3, rm as rm9, stat as stat11 } from "fs/promises";
|
|
68480
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
68481
|
+
import path48 from "path";
|
|
68482
|
+
import { defineCommand as defineCommand238 } from "citty";
|
|
68483
|
+
|
|
68484
|
+
// src/lib/streamUpload.ts
|
|
68485
|
+
import { createHash as createHash2 } from "crypto";
|
|
68486
|
+
import { createReadStream } from "fs";
|
|
68487
|
+
import { Readable } from "stream";
|
|
68488
|
+
import { pipeline } from "stream/promises";
|
|
68489
|
+
async function hashFile(filePath) {
|
|
68490
|
+
const hash = createHash2("sha256");
|
|
68491
|
+
await pipeline(createReadStream(filePath), hash);
|
|
68492
|
+
return hash.digest("hex");
|
|
68493
|
+
}
|
|
68494
|
+
async function putFileStreamed(args5) {
|
|
68495
|
+
const body = Readable.toWeb(createReadStream(args5.filePath));
|
|
68496
|
+
return await fetch(args5.putUrl, {
|
|
68497
|
+
method: "PUT",
|
|
68498
|
+
body,
|
|
68499
|
+
headers: {
|
|
68500
|
+
"Content-Type": args5.contentType,
|
|
68501
|
+
"Content-Length": String(args5.sizeBytes)
|
|
68502
|
+
},
|
|
68503
|
+
duplex: "half"
|
|
68504
|
+
});
|
|
68505
|
+
}
|
|
68506
|
+
|
|
68054
68507
|
// src/commands/videos/ingest.ts
|
|
68055
68508
|
registerSchema({
|
|
68056
68509
|
command: "videos.ingest",
|
|
@@ -68079,7 +68532,7 @@ registerSchema({
|
|
|
68079
68532
|
"dry-run": { type: "boolean", description: "Preview the operation without executing", required: false }
|
|
68080
68533
|
}
|
|
68081
68534
|
});
|
|
68082
|
-
var ingestCommand2 =
|
|
68535
|
+
var ingestCommand2 = defineCommand238({
|
|
68083
68536
|
meta: {
|
|
68084
68537
|
name: "ingest",
|
|
68085
68538
|
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"
|
|
@@ -68265,7 +68718,7 @@ function ingestUrl(args5) {
|
|
|
68265
68718
|
}
|
|
68266
68719
|
async function downloadThenIngest(args5, country) {
|
|
68267
68720
|
const vimeoCookie = captureVimeoCookie();
|
|
68268
|
-
const workDir = await mkdtemp3(
|
|
68721
|
+
const workDir = await mkdtemp3(path48.join(tmpdir4(), "videos-ingest-"));
|
|
68269
68722
|
try {
|
|
68270
68723
|
const probe = await probeYtDlp({ url: args5.url, country, vimeoCookie, cookieDir: workDir });
|
|
68271
68724
|
if (isAudioOnly(probe.info)) {
|
|
@@ -68341,7 +68794,7 @@ async function uploadToAssetStore(filePath, sizeBytes) {
|
|
|
68341
68794
|
}
|
|
68342
68795
|
|
|
68343
68796
|
// src/commands/videos/search.ts
|
|
68344
|
-
import { defineCommand as
|
|
68797
|
+
import { defineCommand as defineCommand239 } from "citty";
|
|
68345
68798
|
registerSchema({
|
|
68346
68799
|
command: "videos.search",
|
|
68347
68800
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -68351,7 +68804,7 @@ registerSchema({
|
|
|
68351
68804
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
68352
68805
|
}
|
|
68353
68806
|
});
|
|
68354
|
-
var searchCommand4 =
|
|
68807
|
+
var searchCommand4 = defineCommand239({
|
|
68355
68808
|
meta: {
|
|
68356
68809
|
name: "search",
|
|
68357
68810
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -68403,7 +68856,7 @@ var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
68403
68856
|
// src/commands/videos/upload.ts
|
|
68404
68857
|
import { readFile as readFile33, stat as stat12 } from "fs/promises";
|
|
68405
68858
|
import { basename as basename3, extname as extname4 } from "path";
|
|
68406
|
-
import { defineCommand as
|
|
68859
|
+
import { defineCommand as defineCommand240 } from "citty";
|
|
68407
68860
|
var MIME_MAP = {
|
|
68408
68861
|
".mp4": "video/mp4",
|
|
68409
68862
|
".mov": "video/quicktime",
|
|
@@ -68445,7 +68898,7 @@ function detectContentType(filePath) {
|
|
|
68445
68898
|
function isRemoteUrl3(value) {
|
|
68446
68899
|
return /^https?:\/\//i.test(value);
|
|
68447
68900
|
}
|
|
68448
|
-
var uploadCommand2 =
|
|
68901
|
+
var uploadCommand2 = defineCommand240({
|
|
68449
68902
|
meta: {
|
|
68450
68903
|
name: "upload",
|
|
68451
68904
|
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"
|
|
@@ -68529,10 +68982,10 @@ var uploadCommand2 = defineCommand233({
|
|
|
68529
68982
|
});
|
|
68530
68983
|
|
|
68531
68984
|
// src/commands/videos/index.ts
|
|
68532
|
-
var videosCommand =
|
|
68985
|
+
var videosCommand = defineCommand241({
|
|
68533
68986
|
meta: {
|
|
68534
68987
|
name: "videos",
|
|
68535
|
-
description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, describe, delete, tags.
|
|
68988
|
+
description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, fetch, describe, delete, tags.
|
|
68536
68989
|
|
|
68537
68990
|
Examples:
|
|
68538
68991
|
baker videos search "product demo" --limit 5
|
|
@@ -68540,6 +68993,7 @@ Examples:
|
|
|
68540
68993
|
baker videos get <video-id>
|
|
68541
68994
|
baker videos upload ./demo.mp4
|
|
68542
68995
|
baker videos ingest https://www.youtube.com/watch?v=abc123
|
|
68996
|
+
baker videos fetch https://www.youtube.com/watch?v=abc123 --out ./clips
|
|
68543
68997
|
baker videos describe <video-id> --description "Customer testimonial, 30s"
|
|
68544
68998
|
baker videos delete <video-id> --dry-run
|
|
68545
68999
|
baker videos tags
|
|
@@ -68551,6 +69005,7 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
68551
69005
|
search: searchCommand4,
|
|
68552
69006
|
upload: uploadCommand2,
|
|
68553
69007
|
ingest: ingestCommand2,
|
|
69008
|
+
fetch: fetchCommand2,
|
|
68554
69009
|
describe: describeCommand2,
|
|
68555
69010
|
delete: deleteCommand4,
|
|
68556
69011
|
tags: tagsCommand6
|
|
@@ -68558,10 +69013,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
68558
69013
|
});
|
|
68559
69014
|
|
|
68560
69015
|
// src/commands/winning-ads/index.ts
|
|
68561
|
-
import { defineCommand as
|
|
69016
|
+
import { defineCommand as defineCommand254 } from "citty";
|
|
68562
69017
|
|
|
68563
69018
|
// src/commands/winning-ads/advertisers.ts
|
|
68564
|
-
import { defineCommand as
|
|
69019
|
+
import { defineCommand as defineCommand242 } from "citty";
|
|
68565
69020
|
|
|
68566
69021
|
// src/commands/winning-ads/shared.ts
|
|
68567
69022
|
function splitList3(value) {
|
|
@@ -68570,7 +69025,7 @@ function splitList3(value) {
|
|
|
68570
69025
|
}
|
|
68571
69026
|
return value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
68572
69027
|
}
|
|
68573
|
-
function
|
|
69028
|
+
function reportError3(err) {
|
|
68574
69029
|
if (err instanceof ApiError) {
|
|
68575
69030
|
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
68576
69031
|
process.exit(1);
|
|
@@ -68614,7 +69069,7 @@ function advertiserNormalizer(record, full) {
|
|
|
68614
69069
|
last_synced_at: record.last_synced_at ?? null
|
|
68615
69070
|
};
|
|
68616
69071
|
}
|
|
68617
|
-
var advertisersCommand2 =
|
|
69072
|
+
var advertisersCommand2 = defineCommand242({
|
|
68618
69073
|
meta: {
|
|
68619
69074
|
name: "advertisers",
|
|
68620
69075
|
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'
|
|
@@ -68666,13 +69121,13 @@ var advertisersCommand2 = defineCommand235({
|
|
|
68666
69121
|
advertiserNormalizer
|
|
68667
69122
|
);
|
|
68668
69123
|
} catch (err) {
|
|
68669
|
-
|
|
69124
|
+
reportError3(err);
|
|
68670
69125
|
}
|
|
68671
69126
|
}
|
|
68672
69127
|
});
|
|
68673
69128
|
|
|
68674
69129
|
// src/commands/winning-ads/brief.ts
|
|
68675
|
-
import { defineCommand as
|
|
69130
|
+
import { defineCommand as defineCommand243 } from "citty";
|
|
68676
69131
|
registerSchema({
|
|
68677
69132
|
command: "winning-ads.brief",
|
|
68678
69133
|
description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
|
|
@@ -68718,7 +69173,7 @@ function parseDna(raw) {
|
|
|
68718
69173
|
}
|
|
68719
69174
|
return parsed;
|
|
68720
69175
|
}
|
|
68721
|
-
var briefCommand =
|
|
69176
|
+
var briefCommand = defineCommand243({
|
|
68722
69177
|
meta: {
|
|
68723
69178
|
name: "brief",
|
|
68724
69179
|
description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
|
|
@@ -68748,13 +69203,13 @@ var briefCommand = defineCommand236({
|
|
|
68748
69203
|
const data = await apiPost("/api/ad-library/brief", body);
|
|
68749
69204
|
writeJson({ ok: true, data });
|
|
68750
69205
|
} catch (err) {
|
|
68751
|
-
|
|
69206
|
+
reportError3(err);
|
|
68752
69207
|
}
|
|
68753
69208
|
}
|
|
68754
69209
|
});
|
|
68755
69210
|
|
|
68756
69211
|
// src/commands/winning-ads/content.ts
|
|
68757
|
-
import { defineCommand as
|
|
69212
|
+
import { defineCommand as defineCommand244 } from "citty";
|
|
68758
69213
|
registerSchema({
|
|
68759
69214
|
command: "winning-ads.content",
|
|
68760
69215
|
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.",
|
|
@@ -68767,7 +69222,7 @@ registerSchema({
|
|
|
68767
69222
|
}
|
|
68768
69223
|
}
|
|
68769
69224
|
});
|
|
68770
|
-
var contentCommand =
|
|
69225
|
+
var contentCommand = defineCommand244({
|
|
68771
69226
|
meta: {
|
|
68772
69227
|
name: "content",
|
|
68773
69228
|
description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
|
|
@@ -68810,13 +69265,13 @@ var contentCommand = defineCommand237({
|
|
|
68810
69265
|
adContentNormalizer
|
|
68811
69266
|
);
|
|
68812
69267
|
} catch (err) {
|
|
68813
|
-
|
|
69268
|
+
reportError3(err);
|
|
68814
69269
|
}
|
|
68815
69270
|
}
|
|
68816
69271
|
});
|
|
68817
69272
|
|
|
68818
69273
|
// src/commands/winning-ads/feed.ts
|
|
68819
|
-
import { defineCommand as
|
|
69274
|
+
import { defineCommand as defineCommand245 } from "citty";
|
|
68820
69275
|
function buildFeedParams(input) {
|
|
68821
69276
|
const params = {};
|
|
68822
69277
|
const advertiser = splitList3(input.advertiser);
|
|
@@ -68868,7 +69323,7 @@ registerSchema({
|
|
|
68868
69323
|
format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
|
|
68869
69324
|
}
|
|
68870
69325
|
});
|
|
68871
|
-
var feedCommand2 =
|
|
69326
|
+
var feedCommand2 = defineCommand245({
|
|
68872
69327
|
meta: {
|
|
68873
69328
|
name: "feed",
|
|
68874
69329
|
description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
|
|
@@ -68947,13 +69402,13 @@ var feedCommand2 = defineCommand238({
|
|
|
68947
69402
|
`);
|
|
68948
69403
|
}
|
|
68949
69404
|
} catch (err) {
|
|
68950
|
-
|
|
69405
|
+
reportError3(err);
|
|
68951
69406
|
}
|
|
68952
69407
|
}
|
|
68953
69408
|
});
|
|
68954
69409
|
|
|
68955
69410
|
// src/commands/winning-ads/follow.ts
|
|
68956
|
-
import { defineCommand as
|
|
69411
|
+
import { defineCommand as defineCommand246 } from "citty";
|
|
68957
69412
|
var PLATFORMS = adLibraryPlatformSchema.options;
|
|
68958
69413
|
registerSchema({
|
|
68959
69414
|
command: "winning-ads.follow",
|
|
@@ -68968,7 +69423,7 @@ registerSchema({
|
|
|
68968
69423
|
label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
|
|
68969
69424
|
}
|
|
68970
69425
|
});
|
|
68971
|
-
var followCommand =
|
|
69426
|
+
var followCommand = defineCommand246({
|
|
68972
69427
|
meta: {
|
|
68973
69428
|
name: "follow",
|
|
68974
69429
|
description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks every platform we can resolve. Example: baker winning-ads follow "deel.com" --platform meta'
|
|
@@ -69009,13 +69464,13 @@ var followCommand = defineCommand239({
|
|
|
69009
69464
|
}
|
|
69010
69465
|
writeJson({ ok: true, data, hints: hints2 });
|
|
69011
69466
|
} catch (err) {
|
|
69012
|
-
|
|
69467
|
+
reportError3(err);
|
|
69013
69468
|
}
|
|
69014
69469
|
}
|
|
69015
69470
|
});
|
|
69016
69471
|
|
|
69017
69472
|
// src/commands/winning-ads/follow-competitors.ts
|
|
69018
|
-
import { defineCommand as
|
|
69473
|
+
import { defineCommand as defineCommand247 } from "citty";
|
|
69019
69474
|
var PLATFORMS2 = adLibraryPlatformSchema.options;
|
|
69020
69475
|
var BATCH_TIMEOUT_MS = 3e5;
|
|
69021
69476
|
function buildFollowBatchBody(input) {
|
|
@@ -69048,7 +69503,7 @@ registerSchema({
|
|
|
69048
69503
|
}
|
|
69049
69504
|
}
|
|
69050
69505
|
});
|
|
69051
|
-
var followCompetitorsCommand =
|
|
69506
|
+
var followCompetitorsCommand = defineCommand247({
|
|
69052
69507
|
meta: {
|
|
69053
69508
|
name: "follow-competitors",
|
|
69054
69509
|
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"'
|
|
@@ -69117,13 +69572,13 @@ var followCompetitorsCommand = defineCommand240({
|
|
|
69117
69572
|
}
|
|
69118
69573
|
writeJson({ ok: true, data, hints: hints2.length > 0 ? hints2 : void 0 });
|
|
69119
69574
|
} catch (err) {
|
|
69120
|
-
|
|
69575
|
+
reportError3(err);
|
|
69121
69576
|
}
|
|
69122
69577
|
}
|
|
69123
69578
|
});
|
|
69124
69579
|
|
|
69125
69580
|
// src/commands/winning-ads/following.ts
|
|
69126
|
-
import { defineCommand as
|
|
69581
|
+
import { defineCommand as defineCommand248 } from "citty";
|
|
69127
69582
|
registerSchema({
|
|
69128
69583
|
command: "winning-ads.following",
|
|
69129
69584
|
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.",
|
|
@@ -69177,7 +69632,7 @@ function followingNormalizer(record, full) {
|
|
|
69177
69632
|
platforms: Array.isArray(record.platforms) ? record.platforms : []
|
|
69178
69633
|
};
|
|
69179
69634
|
}
|
|
69180
|
-
var followingCommand =
|
|
69635
|
+
var followingCommand = defineCommand248({
|
|
69181
69636
|
meta: {
|
|
69182
69637
|
name: "following",
|
|
69183
69638
|
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"
|
|
@@ -69207,13 +69662,13 @@ var followingCommand = defineCommand241({
|
|
|
69207
69662
|
followingNormalizer
|
|
69208
69663
|
);
|
|
69209
69664
|
} catch (err) {
|
|
69210
|
-
|
|
69665
|
+
reportError3(err);
|
|
69211
69666
|
}
|
|
69212
69667
|
}
|
|
69213
69668
|
});
|
|
69214
69669
|
|
|
69215
69670
|
// src/commands/winning-ads/patterns.ts
|
|
69216
|
-
import { defineCommand as
|
|
69671
|
+
import { defineCommand as defineCommand249 } from "citty";
|
|
69217
69672
|
registerSchema({
|
|
69218
69673
|
command: "winning-ads.patterns",
|
|
69219
69674
|
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.",
|
|
@@ -69252,7 +69707,7 @@ function discriminatorRow(record) {
|
|
|
69252
69707
|
top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
|
|
69253
69708
|
};
|
|
69254
69709
|
}
|
|
69255
|
-
var patternsCommand =
|
|
69710
|
+
var patternsCommand = defineCommand249({
|
|
69256
69711
|
meta: {
|
|
69257
69712
|
name: "patterns",
|
|
69258
69713
|
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"
|
|
@@ -69302,13 +69757,13 @@ var patternsCommand = defineCommand242({
|
|
|
69302
69757
|
(record) => discriminatorRow(record)
|
|
69303
69758
|
);
|
|
69304
69759
|
} catch (err) {
|
|
69305
|
-
|
|
69760
|
+
reportError3(err);
|
|
69306
69761
|
}
|
|
69307
69762
|
}
|
|
69308
69763
|
});
|
|
69309
69764
|
|
|
69310
69765
|
// src/commands/winning-ads/search.ts
|
|
69311
|
-
import { defineCommand as
|
|
69766
|
+
import { defineCommand as defineCommand250 } from "citty";
|
|
69312
69767
|
registerSchema({
|
|
69313
69768
|
command: "winning-ads.search",
|
|
69314
69769
|
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.",
|
|
@@ -69444,9 +69899,9 @@ function reportSearchError(err) {
|
|
|
69444
69899
|
writeJson({ ok: false, error: { code: err.code, message: err.message, fix } });
|
|
69445
69900
|
process.exit(1);
|
|
69446
69901
|
}
|
|
69447
|
-
|
|
69902
|
+
reportError3(err);
|
|
69448
69903
|
}
|
|
69449
|
-
var searchCommand5 =
|
|
69904
|
+
var searchCommand5 = defineCommand250({
|
|
69450
69905
|
meta: {
|
|
69451
69906
|
name: "search",
|
|
69452
69907
|
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"
|
|
@@ -69566,7 +70021,7 @@ var searchCommand5 = defineCommand243({
|
|
|
69566
70021
|
});
|
|
69567
70022
|
|
|
69568
70023
|
// src/commands/winning-ads/seeds.ts
|
|
69569
|
-
import { defineCommand as
|
|
70024
|
+
import { defineCommand as defineCommand251 } from "citty";
|
|
69570
70025
|
function leanRow(r) {
|
|
69571
70026
|
return {
|
|
69572
70027
|
key: r.key,
|
|
@@ -69594,7 +70049,7 @@ function makeSeedCommand(opts) {
|
|
|
69594
70049
|
limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
|
|
69595
70050
|
}
|
|
69596
70051
|
});
|
|
69597
|
-
return
|
|
70052
|
+
return defineCommand251({
|
|
69598
70053
|
meta: { name: opts.name, description: opts.description },
|
|
69599
70054
|
args: {
|
|
69600
70055
|
platform: { type: "string", description: "Single platform to segment on", required: false },
|
|
@@ -69621,7 +70076,7 @@ function makeSeedCommand(opts) {
|
|
|
69621
70076
|
}
|
|
69622
70077
|
writeOutput({ ok: true, data: projected }, output);
|
|
69623
70078
|
} catch (err) {
|
|
69624
|
-
|
|
70079
|
+
reportError3(err);
|
|
69625
70080
|
}
|
|
69626
70081
|
}
|
|
69627
70082
|
});
|
|
@@ -69643,7 +70098,7 @@ var formatsCommand = makeSeedCommand({
|
|
|
69643
70098
|
});
|
|
69644
70099
|
|
|
69645
70100
|
// src/commands/winning-ads/unfollow.ts
|
|
69646
|
-
import { defineCommand as
|
|
70101
|
+
import { defineCommand as defineCommand252 } from "citty";
|
|
69647
70102
|
registerSchema({
|
|
69648
70103
|
command: "winning-ads.unfollow",
|
|
69649
70104
|
description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
|
|
@@ -69651,7 +70106,7 @@ registerSchema({
|
|
|
69651
70106
|
advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
|
|
69652
70107
|
}
|
|
69653
70108
|
});
|
|
69654
|
-
var unfollowCommand =
|
|
70109
|
+
var unfollowCommand = defineCommand252({
|
|
69655
70110
|
meta: {
|
|
69656
70111
|
name: "unfollow",
|
|
69657
70112
|
description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
|
|
@@ -69666,13 +70121,13 @@ var unfollowCommand = defineCommand245({
|
|
|
69666
70121
|
});
|
|
69667
70122
|
writeJson({ ok: true, data });
|
|
69668
70123
|
} catch (err) {
|
|
69669
|
-
|
|
70124
|
+
reportError3(err);
|
|
69670
70125
|
}
|
|
69671
70126
|
}
|
|
69672
70127
|
});
|
|
69673
70128
|
|
|
69674
70129
|
// src/commands/winning-ads/winners.ts
|
|
69675
|
-
import { defineCommand as
|
|
70130
|
+
import { defineCommand as defineCommand253 } from "citty";
|
|
69676
70131
|
registerSchema({
|
|
69677
70132
|
command: "winning-ads.winners",
|
|
69678
70133
|
description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
|
|
@@ -69682,7 +70137,7 @@ registerSchema({
|
|
|
69682
70137
|
platform: { type: "string", description: "Filter to a single platform: meta|linkedin|tiktok", required: false }
|
|
69683
70138
|
}
|
|
69684
70139
|
});
|
|
69685
|
-
var winnersCommand =
|
|
70140
|
+
var winnersCommand = defineCommand253({
|
|
69686
70141
|
meta: {
|
|
69687
70142
|
name: "winners",
|
|
69688
70143
|
description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
|
|
@@ -69726,13 +70181,13 @@ var winnersCommand = defineCommand246({
|
|
|
69726
70181
|
winningAdNormalizer
|
|
69727
70182
|
);
|
|
69728
70183
|
} catch (err) {
|
|
69729
|
-
|
|
70184
|
+
reportError3(err);
|
|
69730
70185
|
}
|
|
69731
70186
|
}
|
|
69732
70187
|
});
|
|
69733
70188
|
|
|
69734
70189
|
// src/commands/winning-ads/index.ts
|
|
69735
|
-
var winningAdsCommand =
|
|
70190
|
+
var winningAdsCommand = defineCommand254({
|
|
69736
70191
|
meta: {
|
|
69737
70192
|
name: "winning-ads",
|
|
69738
70193
|
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.
|
|
@@ -69804,7 +70259,7 @@ function getCliVersion() {
|
|
|
69804
70259
|
}
|
|
69805
70260
|
|
|
69806
70261
|
// src/cli.ts
|
|
69807
|
-
var main =
|
|
70262
|
+
var main = defineCommand255({
|
|
69808
70263
|
meta: {
|
|
69809
70264
|
name: "baker",
|
|
69810
70265
|
version: getCliVersion(),
|
|
@@ -69844,6 +70299,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
69844
70299
|
history: historyCommand2,
|
|
69845
70300
|
hubspot: hubspotCommand,
|
|
69846
70301
|
"winning-ads": winningAdsCommand,
|
|
70302
|
+
"media-sources": mediaSourcesCommand,
|
|
69847
70303
|
mcp: mcpCommand,
|
|
69848
70304
|
schema: schemaCommand2
|
|
69849
70305
|
}
|