@koda-sl/baker-cli 0.379.0-dev.bfd923423 → 0.380.0-dev.824ccf426
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 +40 -4
- package/dist/{chunk-CHJOTJTZ.js → chunk-HOMVJ2D3.js} +8 -2
- package/dist/chunk-HOMVJ2D3.js.map +1 -0
- package/dist/{chunk-KAOU6QLP.js → chunk-VLUGGVJL.js} +9 -58
- package/dist/chunk-VLUGGVJL.js.map +1 -0
- package/dist/cli.js +945 -472
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/{shared-TD76Z3W2.js → shared-J7DQZ2ED.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-CHJOTJTZ.js.map +0 -1
- package/dist/chunk-KAOU6QLP.js.map +0 -1
- /package/dist/{shared-TD76Z3W2.js.map → shared-J7DQZ2ED.js.map} +0 -0
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-HOMVJ2D3.js";
|
|
74
74
|
import {
|
|
75
75
|
NAME_CONTAINS_ARG,
|
|
76
76
|
csvOrJson,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
resolveEffectiveStatus,
|
|
82
82
|
statusFilterHints,
|
|
83
83
|
todayIso
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-VLUGGVJL.js";
|
|
85
85
|
import {
|
|
86
86
|
buildQueryCacheKey,
|
|
87
87
|
cacheGet,
|
|
@@ -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,10 @@ var imageSourceSchema = z20.enum([
|
|
|
6398
6401
|
"google_testimonial",
|
|
6399
6402
|
"trustpilot_testimonial",
|
|
6400
6403
|
"instagram",
|
|
6404
|
+
"tiktok",
|
|
6405
|
+
"linkedin",
|
|
6406
|
+
"facebook",
|
|
6407
|
+
"google_drive",
|
|
6401
6408
|
"pexels",
|
|
6402
6409
|
"pixabay",
|
|
6403
6410
|
// Retired stock provider — kept so existing library rows stay filterable.
|
|
@@ -8208,7 +8215,9 @@ var videoSourceSchema = z30.enum([
|
|
|
8208
8215
|
"bluesky",
|
|
8209
8216
|
"dailymotion",
|
|
8210
8217
|
"facebook",
|
|
8218
|
+
"google_drive",
|
|
8211
8219
|
"instagram",
|
|
8220
|
+
"linkedin",
|
|
8212
8221
|
"loom",
|
|
8213
8222
|
"newgrounds",
|
|
8214
8223
|
"ok",
|
|
@@ -12109,9 +12118,9 @@ var COPY_LIST_FLAG = {
|
|
|
12109
12118
|
descriptions: "--descriptions",
|
|
12110
12119
|
longHeadlines: "--long-headlines"
|
|
12111
12120
|
};
|
|
12112
|
-
function valueAt(root,
|
|
12121
|
+
function valueAt(root, path49) {
|
|
12113
12122
|
let node = root;
|
|
12114
|
-
for (const key of
|
|
12123
|
+
for (const key of path49) {
|
|
12115
12124
|
if (node === null || typeof node !== "object") return void 0;
|
|
12116
12125
|
node = node[key];
|
|
12117
12126
|
}
|
|
@@ -12344,11 +12353,11 @@ function parseKeywordEntry(raw, defaultMatch) {
|
|
|
12344
12353
|
function rawTextEntries(value, rawArgs) {
|
|
12345
12354
|
return repeatedValues(rawArgs, "text", value).flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
12346
12355
|
}
|
|
12347
|
-
function rawFileEntries(
|
|
12348
|
-
if (typeof
|
|
12356
|
+
function rawFileEntries(path49) {
|
|
12357
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
12349
12358
|
return [];
|
|
12350
12359
|
}
|
|
12351
|
-
return readFileSync2(
|
|
12360
|
+
return readFileSync2(path49, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
12352
12361
|
}
|
|
12353
12362
|
function keywordEntries(args5, rawArgs) {
|
|
12354
12363
|
const defaultMatch = typeof args5["match-type"] === "string" ? args5["match-type"].toUpperCase() : void 0;
|
|
@@ -12371,14 +12380,14 @@ function keywordEntries(args5, rawArgs) {
|
|
|
12371
12380
|
}
|
|
12372
12381
|
return entries;
|
|
12373
12382
|
}
|
|
12374
|
-
function loadJsonFileArg(
|
|
12375
|
-
if (typeof
|
|
12383
|
+
function loadJsonFileArg(path49) {
|
|
12384
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
12376
12385
|
return {};
|
|
12377
12386
|
}
|
|
12378
|
-
const inline =
|
|
12379
|
-
const source = inline ? "inline JSON" :
|
|
12387
|
+
const inline = path49.trimStart().startsWith("{");
|
|
12388
|
+
const source = inline ? "inline JSON" : path49;
|
|
12380
12389
|
try {
|
|
12381
|
-
const parsed = JSON.parse(inline ?
|
|
12390
|
+
const parsed = JSON.parse(inline ? path49 : readFileSync2(path49, "utf8"));
|
|
12382
12391
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
12383
12392
|
failWriteValidation(`${source} must contain a JSON object`);
|
|
12384
12393
|
}
|
|
@@ -12515,10 +12524,10 @@ async function stageUpdate(kind, customerId, target2, payload, hints2) {
|
|
|
12515
12524
|
async function stageTarget(kind, customerId, target2, hints2) {
|
|
12516
12525
|
await stageGoogleOp({ kind, customerId, target: target2 }, hints2);
|
|
12517
12526
|
}
|
|
12518
|
-
async function draftAction(
|
|
12527
|
+
async function draftAction(path49, body, chat) {
|
|
12519
12528
|
try {
|
|
12520
12529
|
const chatId = resolveChatId(chat);
|
|
12521
|
-
const response = await apiPost(
|
|
12530
|
+
const response = await apiPost(path49, { chatId, ...body });
|
|
12522
12531
|
writeJsonEnvelope(response);
|
|
12523
12532
|
} catch (err) {
|
|
12524
12533
|
handleGoogleError(err);
|
|
@@ -14936,14 +14945,14 @@ function mappingRowProblem(row) {
|
|
|
14936
14945
|
|
|
14937
14946
|
// ../api/src/event-sources/template.ts
|
|
14938
14947
|
var MENTION = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
14939
|
-
function mentionOf(
|
|
14940
|
-
return `{{${
|
|
14948
|
+
function mentionOf(path49) {
|
|
14949
|
+
return `{{${path49}}}`;
|
|
14941
14950
|
}
|
|
14942
14951
|
function templateMentions(template) {
|
|
14943
14952
|
const seen = [];
|
|
14944
14953
|
for (const match of template.matchAll(MENTION)) {
|
|
14945
|
-
const
|
|
14946
|
-
if (
|
|
14954
|
+
const path49 = (match[1] ?? "").trim();
|
|
14955
|
+
if (path49 !== "" && !seen.includes(path49)) seen.push(path49);
|
|
14947
14956
|
}
|
|
14948
14957
|
return seen;
|
|
14949
14958
|
}
|
|
@@ -18298,17 +18307,17 @@ function ignoredColumnHints(columns) {
|
|
|
18298
18307
|
`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
18308
|
];
|
|
18300
18309
|
}
|
|
18301
|
-
function readRowsFile(
|
|
18302
|
-
const inline =
|
|
18310
|
+
function readRowsFile(path49) {
|
|
18311
|
+
const inline = path49.trimStart().startsWith("[") || path49.trimStart().startsWith("{");
|
|
18303
18312
|
let text2;
|
|
18304
18313
|
try {
|
|
18305
|
-
text2 = inline ?
|
|
18314
|
+
text2 = inline ? path49 : readFileSync4(path49, "utf8");
|
|
18306
18315
|
} catch (err) {
|
|
18307
|
-
failWriteValidation(`could not read ${
|
|
18316
|
+
failWriteValidation(`could not read ${path49}: ${err instanceof Error ? err.message : String(err)}`);
|
|
18308
18317
|
}
|
|
18309
18318
|
const parsed = parseConversionRowsText(text2);
|
|
18310
18319
|
if (!parsed.ok) {
|
|
18311
|
-
failWriteValidation(`${inline ? "the conversions passed inline" :
|
|
18320
|
+
failWriteValidation(`${inline ? "the conversions passed inline" : path49}: ${parsed.error}`);
|
|
18312
18321
|
}
|
|
18313
18322
|
return { rows: parsed.rows, ignoredColumns: parsed.ignoredColumns };
|
|
18314
18323
|
}
|
|
@@ -20183,19 +20192,19 @@ function failWriteValidation2(message) {
|
|
|
20183
20192
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
20184
20193
|
process.exit(1);
|
|
20185
20194
|
}
|
|
20186
|
-
function loadJsonFileArg2(
|
|
20187
|
-
if (typeof
|
|
20195
|
+
function loadJsonFileArg2(path49) {
|
|
20196
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20188
20197
|
return {};
|
|
20189
20198
|
}
|
|
20190
20199
|
try {
|
|
20191
|
-
const parsed = JSON.parse(readFileSync5(
|
|
20200
|
+
const parsed = JSON.parse(readFileSync5(path49, "utf8"));
|
|
20192
20201
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20193
|
-
failWriteValidation2(`${
|
|
20202
|
+
failWriteValidation2(`${path49} must contain a JSON object`);
|
|
20194
20203
|
}
|
|
20195
20204
|
return parsed;
|
|
20196
20205
|
} catch (err) {
|
|
20197
20206
|
if (err instanceof SyntaxError) {
|
|
20198
|
-
failWriteValidation2(`${
|
|
20207
|
+
failWriteValidation2(`${path49} is not valid JSON: ${err.message}`);
|
|
20199
20208
|
}
|
|
20200
20209
|
throw err;
|
|
20201
20210
|
}
|
|
@@ -20280,15 +20289,15 @@ function parseLocaleFlag(value) {
|
|
|
20280
20289
|
}
|
|
20281
20290
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
20282
20291
|
}
|
|
20283
|
-
function loadTargetingFileArg(
|
|
20284
|
-
if (typeof
|
|
20292
|
+
function loadTargetingFileArg(path49) {
|
|
20293
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20285
20294
|
return void 0;
|
|
20286
20295
|
}
|
|
20287
|
-
const parsed = loadJsonFileArg2(
|
|
20296
|
+
const parsed = loadJsonFileArg2(path49);
|
|
20288
20297
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
20289
20298
|
if (!criteria.include) {
|
|
20290
20299
|
failWriteValidation2(
|
|
20291
|
-
`${
|
|
20300
|
+
`${path49} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
20292
20301
|
);
|
|
20293
20302
|
}
|
|
20294
20303
|
return criteria;
|
|
@@ -20323,14 +20332,14 @@ function parseCsvLine(line) {
|
|
|
20323
20332
|
cells.push(current);
|
|
20324
20333
|
return cells.map((cell3) => cell3.trim());
|
|
20325
20334
|
}
|
|
20326
|
-
function parseListFileArg(
|
|
20327
|
-
if (typeof
|
|
20335
|
+
function parseListFileArg(path49, maxRows) {
|
|
20336
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20328
20337
|
return void 0;
|
|
20329
20338
|
}
|
|
20330
|
-
const raw = readFileSync5(
|
|
20339
|
+
const raw = readFileSync5(path49, "utf8");
|
|
20331
20340
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
20332
20341
|
if (lines.length < 2) {
|
|
20333
|
-
failWriteValidation2(`${
|
|
20342
|
+
failWriteValidation2(`${path49} needs a header row and at least one data row`);
|
|
20334
20343
|
}
|
|
20335
20344
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
20336
20345
|
const rows = [];
|
|
@@ -20349,7 +20358,7 @@ function parseListFileArg(path48, maxRows) {
|
|
|
20349
20358
|
}
|
|
20350
20359
|
}
|
|
20351
20360
|
if (rows.length > maxRows) {
|
|
20352
|
-
failWriteValidation2(`${
|
|
20361
|
+
failWriteValidation2(`${path49} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
20353
20362
|
}
|
|
20354
20363
|
return { columns, rows };
|
|
20355
20364
|
}
|
|
@@ -20445,11 +20454,11 @@ function readPositionals(args5) {
|
|
|
20445
20454
|
function splitIdList(raw) {
|
|
20446
20455
|
return raw.split(",").map((id) => id.trim()).filter(Boolean);
|
|
20447
20456
|
}
|
|
20448
|
-
function idsFileEntries(
|
|
20449
|
-
if (typeof
|
|
20457
|
+
function idsFileEntries(path49) {
|
|
20458
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
20450
20459
|
return [];
|
|
20451
20460
|
}
|
|
20452
|
-
return readFileSync5(
|
|
20461
|
+
return readFileSync5(path49, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
|
|
20453
20462
|
}
|
|
20454
20463
|
function requireTargets(args5, entity) {
|
|
20455
20464
|
const positionals = readPositionals(args5);
|
|
@@ -23211,9 +23220,9 @@ import { defineCommand as defineCommand44 } from "citty";
|
|
|
23211
23220
|
function asRecord(value) {
|
|
23212
23221
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
23213
23222
|
}
|
|
23214
|
-
function readPath2(row,
|
|
23223
|
+
function readPath2(row, path49) {
|
|
23215
23224
|
let current = row;
|
|
23216
|
-
for (const segment of
|
|
23225
|
+
for (const segment of path49.split(".")) {
|
|
23217
23226
|
const record = asRecord(current);
|
|
23218
23227
|
if (!record) return void 0;
|
|
23219
23228
|
current = record[segment];
|
|
@@ -23223,10 +23232,10 @@ function readPath2(row, path48) {
|
|
|
23223
23232
|
function projectFields(rows, paths) {
|
|
23224
23233
|
return rows.map((row) => {
|
|
23225
23234
|
const projected = {};
|
|
23226
|
-
for (const
|
|
23227
|
-
const value = readPath2(row,
|
|
23235
|
+
for (const path49 of paths) {
|
|
23236
|
+
const value = readPath2(row, path49);
|
|
23228
23237
|
if (value !== void 0) {
|
|
23229
|
-
projected[
|
|
23238
|
+
projected[path49] = value;
|
|
23230
23239
|
}
|
|
23231
23240
|
}
|
|
23232
23241
|
return projected;
|
|
@@ -23239,16 +23248,16 @@ function shapeListRows(rows, args5, compact4) {
|
|
|
23239
23248
|
const paths = fields.split(",").map((field) => field.trim()).filter((field) => field.length > 0);
|
|
23240
23249
|
if (paths.length > 0) {
|
|
23241
23250
|
const projected = projectFields(raw, paths).map((row, i) => {
|
|
23242
|
-
const missing = paths.filter((
|
|
23251
|
+
const missing = paths.filter((path49) => row[path49] === void 0);
|
|
23243
23252
|
const source = rows[i];
|
|
23244
23253
|
if (missing.length === 0 || source === void 0) return row;
|
|
23245
23254
|
const compactRow3 = compact4.row(source);
|
|
23246
|
-
for (const
|
|
23247
|
-
if (compactRow3[
|
|
23255
|
+
for (const path49 of missing) {
|
|
23256
|
+
if (compactRow3[path49] !== void 0) row[path49] = compactRow3[path49];
|
|
23248
23257
|
}
|
|
23249
23258
|
return row;
|
|
23250
23259
|
});
|
|
23251
|
-
const unmatched = paths.filter((
|
|
23260
|
+
const unmatched = paths.filter((path49) => projected.every((row) => row[path49] === void 0));
|
|
23252
23261
|
if (projected.length === 0 || unmatched.length === 0) return { rows: projected, fields: paths };
|
|
23253
23262
|
const carried = /* @__PURE__ */ new Set([...compact4.columns, ...raw.flatMap((row) => Object.keys(row))]);
|
|
23254
23263
|
return {
|
|
@@ -24295,14 +24304,11 @@ Examples:
|
|
|
24295
24304
|
BAKER_META_AD_ACCOUNT_ID=act_123 baker ads meta account`
|
|
24296
24305
|
},
|
|
24297
24306
|
args: {
|
|
24298
|
-
"account-id": {
|
|
24299
|
-
type: "string",
|
|
24300
|
-
description: "Meta ad account ID (act_...); defaults to the only connected account"
|
|
24301
|
-
},
|
|
24307
|
+
"account-id": { type: "string", description: "Meta ad account ID (act_...)" },
|
|
24302
24308
|
"no-cache": NO_CACHE_ARG
|
|
24303
24309
|
},
|
|
24304
24310
|
run: async ({ args: args5 }) => {
|
|
24305
|
-
const accountId =
|
|
24311
|
+
const accountId = resolveAccountIdArg(args5);
|
|
24306
24312
|
try {
|
|
24307
24313
|
const params = { "account-id": accountId };
|
|
24308
24314
|
if (args5["no-cache"]) params["skip-cache"] = "true";
|
|
@@ -24540,7 +24546,7 @@ function registerMetaListSchema(kind, description, args5) {
|
|
|
24540
24546
|
|
|
24541
24547
|
// src/commands/ads/meta/activities.ts
|
|
24542
24548
|
var listArgs4 = {
|
|
24543
|
-
"account-id": { type: "string", description: "Meta ad account ID
|
|
24549
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
24544
24550
|
days: { type: "string", description: "Lookback days (default 7)" },
|
|
24545
24551
|
limit: { type: "string", description: "Max rows" },
|
|
24546
24552
|
"no-cache": NO_CACHE_ARG,
|
|
@@ -24569,7 +24575,7 @@ Examples:
|
|
|
24569
24575
|
},
|
|
24570
24576
|
args: listArgs4,
|
|
24571
24577
|
run: async ({ args: args5 }) => {
|
|
24572
|
-
const accountId =
|
|
24578
|
+
const accountId = resolveAccountIdArg(args5);
|
|
24573
24579
|
try {
|
|
24574
24580
|
const params = { "account-id": accountId };
|
|
24575
24581
|
if (args5.days) params.days = args5.days;
|
|
@@ -24621,54 +24627,54 @@ function buildCustomConversionRule(input) {
|
|
|
24621
24627
|
function customConversionRuleRefusal(rule) {
|
|
24622
24628
|
return ruleNodeRefusal(rule, "rule");
|
|
24623
24629
|
}
|
|
24624
|
-
function branchRefusal(key, value,
|
|
24630
|
+
function branchRefusal(key, value, path49) {
|
|
24625
24631
|
if (!Array.isArray(value) || value.length === 0) {
|
|
24626
|
-
return `${
|
|
24632
|
+
return `${path49}.${key} must be a non-empty array of conditions \u2014 an empty one counts every event the pixel sends`;
|
|
24627
24633
|
}
|
|
24628
24634
|
for (const [index, child] of value.entries()) {
|
|
24629
|
-
const refusal = ruleNodeRefusal(child, `${
|
|
24635
|
+
const refusal = ruleNodeRefusal(child, `${path49}.${key}[${index}]`);
|
|
24630
24636
|
if (refusal) {
|
|
24631
24637
|
return refusal;
|
|
24632
24638
|
}
|
|
24633
24639
|
}
|
|
24634
24640
|
return void 0;
|
|
24635
24641
|
}
|
|
24636
|
-
function conditionRefusal(key, value,
|
|
24637
|
-
return key === "and" || key === "or" ? branchRefusal(key, value,
|
|
24642
|
+
function conditionRefusal(key, value, path49) {
|
|
24643
|
+
return key === "and" || key === "or" ? branchRefusal(key, value, path49) : leafRefusal(key, value, path49);
|
|
24638
24644
|
}
|
|
24639
|
-
function ruleNodeRefusal(node,
|
|
24645
|
+
function ruleNodeRefusal(node, path49) {
|
|
24640
24646
|
if (!isRecord2(node)) {
|
|
24641
|
-
return `${
|
|
24647
|
+
return `${path49} must be an object like {"URL":{"i_contains":"/thank-you"}}`;
|
|
24642
24648
|
}
|
|
24643
24649
|
const entries = Object.entries(node);
|
|
24644
24650
|
if (entries.length === 0) {
|
|
24645
|
-
return `${
|
|
24651
|
+
return `${path49} is empty \u2014 a rule with no condition counts every event the pixel sends`;
|
|
24646
24652
|
}
|
|
24647
24653
|
if (entries.length > 1) {
|
|
24648
|
-
return `${
|
|
24654
|
+
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]}`;
|
|
24649
24655
|
}
|
|
24650
24656
|
for (const [key, value] of entries) {
|
|
24651
|
-
const refusal = conditionRefusal(key, value,
|
|
24657
|
+
const refusal = conditionRefusal(key, value, path49);
|
|
24652
24658
|
if (refusal) {
|
|
24653
24659
|
return refusal;
|
|
24654
24660
|
}
|
|
24655
24661
|
}
|
|
24656
24662
|
return void 0;
|
|
24657
24663
|
}
|
|
24658
|
-
function leafRefusal(field, condition,
|
|
24664
|
+
function leafRefusal(field, condition, path49) {
|
|
24659
24665
|
if (!isRecord2(condition)) {
|
|
24660
|
-
return `${
|
|
24666
|
+
return `${path49}.${field} must be a test like {"i_contains":"/thank-you"}, not a bare value`;
|
|
24661
24667
|
}
|
|
24662
24668
|
const tests = Object.entries(condition);
|
|
24663
24669
|
if (tests.length === 0) {
|
|
24664
|
-
return `${
|
|
24670
|
+
return `${path49}.${field} names no test \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")}`;
|
|
24665
24671
|
}
|
|
24666
24672
|
if (tests.length > 1) {
|
|
24667
|
-
return `${
|
|
24673
|
+
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]}`;
|
|
24668
24674
|
}
|
|
24669
24675
|
for (const [operator] of tests) {
|
|
24670
24676
|
if (!RULE_OPERATORS[operator]) {
|
|
24671
|
-
return `${
|
|
24677
|
+
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)`;
|
|
24672
24678
|
}
|
|
24673
24679
|
}
|
|
24674
24680
|
return void 0;
|
|
@@ -25149,7 +25155,8 @@ var LEAD_FORM_CTA_TYPES = [
|
|
|
25149
25155
|
var AD_FORMATS2 = ["SINGLE_IMAGE", "CAROUSEL", "SINGLE_VIDEO"];
|
|
25150
25156
|
var ENROLL_STATUSES = ["OPT_IN", "OPT_OUT"];
|
|
25151
25157
|
var STAGEABLE_CREATE_STATUSES4 = ["ACTIVE", "PAUSED"];
|
|
25152
|
-
var UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED"];
|
|
25158
|
+
var UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED", "DELETED"];
|
|
25159
|
+
var CREATIVE_UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED"];
|
|
25153
25160
|
var CUSTOM_AUDIENCE_SUBTYPES = ["CUSTOM", "WEBSITE", "ENGAGEMENT", "LOOKALIKE"];
|
|
25154
25161
|
var CUSTOMER_FILE_SOURCES = [
|
|
25155
25162
|
"USER_PROVIDED_ONLY",
|
|
@@ -25372,7 +25379,7 @@ function positionsMissingRequiredFeed(targeting) {
|
|
|
25372
25379
|
// ../api/src/ads-meta/ops.ts
|
|
25373
25380
|
var tempRefSchema4 = z37.string().regex(TEMP_REF_REGEX4, "expected a meta_temp_* reference");
|
|
25374
25381
|
var parentRefSchema3 = z37.union([z37.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema4]);
|
|
25375
|
-
var moneySchema2 = z37.
|
|
25382
|
+
var moneySchema2 = z37.strictObject({
|
|
25376
25383
|
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"),
|
|
25377
25384
|
currencyCode: z37.string().length(3).optional()
|
|
25378
25385
|
});
|
|
@@ -25383,11 +25390,11 @@ var updateStatusSchema = z37.enum(UPDATE_STATUSES);
|
|
|
25383
25390
|
function currencyMinimums2(currencyCode) {
|
|
25384
25391
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
25385
25392
|
}
|
|
25386
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
25393
|
+
function validateDailyBudgetFloor(money, ctx, path49) {
|
|
25387
25394
|
if (money?.currencyCode) {
|
|
25388
25395
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
25389
25396
|
if (Number(money.amount) < min) {
|
|
25390
|
-
ctx.addIssue({ code: "custom", path:
|
|
25397
|
+
ctx.addIssue({ code: "custom", path: path49, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
25391
25398
|
}
|
|
25392
25399
|
}
|
|
25393
25400
|
}
|
|
@@ -25460,7 +25467,7 @@ function targetingHardLimitsDemographics(t) {
|
|
|
25460
25467
|
return narrowsAgeMax || narrowsAgeMin || narrowsGender;
|
|
25461
25468
|
}
|
|
25462
25469
|
var specialAdCategoriesSchema = z37.array(z37.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
|
|
25463
|
-
var campaignCreateSchema4 = z37.
|
|
25470
|
+
var campaignCreateSchema4 = z37.strictObject({
|
|
25464
25471
|
name: z37.string().min(1).max(META_LIMITS.campaign.nameMax),
|
|
25465
25472
|
objective: z37.enum(OBJECTIVES2),
|
|
25466
25473
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
@@ -25498,7 +25505,7 @@ var campaignCreateSchema4 = z37.object({
|
|
|
25498
25505
|
});
|
|
25499
25506
|
}
|
|
25500
25507
|
});
|
|
25501
|
-
var campaignUpdateSchema4 = z37.
|
|
25508
|
+
var campaignUpdateSchema4 = z37.strictObject({
|
|
25502
25509
|
name: z37.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
|
|
25503
25510
|
status: updateStatusSchema.optional(),
|
|
25504
25511
|
bid_strategy: z37.enum(BID_STRATEGIES2).optional(),
|
|
@@ -25516,7 +25523,7 @@ var campaignUpdateSchema4 = z37.object({
|
|
|
25516
25523
|
}
|
|
25517
25524
|
validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
|
|
25518
25525
|
});
|
|
25519
|
-
var
|
|
25526
|
+
var promotedObjectFields = {
|
|
25520
25527
|
page_id: parentRefSchema3.optional(),
|
|
25521
25528
|
pixel_id: z37.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
25522
25529
|
custom_event_type: z37.enum(CUSTOM_EVENT_TYPES).optional(),
|
|
@@ -25536,9 +25543,12 @@ var promotedObjectSchema = z37.object({
|
|
|
25536
25543
|
product_set_id: z37.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
25537
25544
|
whatsapp_phone_number: z37.string().optional(),
|
|
25538
25545
|
offline_conversion_data_set_id: z37.string().regex(NUMERIC_ID_REGEX3).optional()
|
|
25539
|
-
}
|
|
25546
|
+
};
|
|
25547
|
+
var promotedObjectSchema = z37.strictObject(promotedObjectFields, {
|
|
25548
|
+
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
|
|
25549
|
+
});
|
|
25540
25550
|
var attributionSpecSchema = z37.array(
|
|
25541
|
-
z37.
|
|
25551
|
+
z37.strictObject({
|
|
25542
25552
|
event_type: z37.enum(ATTRIBUTION_EVENT_TYPES),
|
|
25543
25553
|
window_days: z37.union([z37.literal(1), z37.literal(7), z37.literal(28)])
|
|
25544
25554
|
})
|
|
@@ -25703,7 +25713,7 @@ function validateAdSetPlacements(p, ctx) {
|
|
|
25703
25713
|
ctx.addIssue({ code: "custom", path: ["targeting"], message: `${message} (${PLACEMENT_TARGETING_DOC})` });
|
|
25704
25714
|
}
|
|
25705
25715
|
}
|
|
25706
|
-
var adSetCreateSchema = z37.
|
|
25716
|
+
var adSetCreateSchema = z37.strictObject(adSetFields).superRefine((p, ctx) => {
|
|
25707
25717
|
validateAdSetBudgetAndBid(p, ctx);
|
|
25708
25718
|
validateAdSetPromotedObject(p, ctx);
|
|
25709
25719
|
validateAdvantageAudience(p, ctx);
|
|
@@ -25716,7 +25726,7 @@ var adSetCreateSchema = z37.object(adSetFields).superRefine((p, ctx) => {
|
|
|
25716
25726
|
});
|
|
25717
25727
|
}
|
|
25718
25728
|
});
|
|
25719
|
-
var adSetUpdateSchema = z37.
|
|
25729
|
+
var adSetUpdateSchema = z37.strictObject({
|
|
25720
25730
|
name: adSetFields.name.optional(),
|
|
25721
25731
|
status: updateStatusSchema.optional(),
|
|
25722
25732
|
dailyBudget: moneySchema2.optional(),
|
|
@@ -25746,7 +25756,7 @@ var adSetUpdateSchema = z37.object({
|
|
|
25746
25756
|
var messageSchema = z37.string().min(1).max(META_LIMITS.creative.messageHardMax);
|
|
25747
25757
|
var headlineSchema2 = z37.string().min(1).max(META_LIMITS.creative.headlineMax);
|
|
25748
25758
|
var descriptionSchema = z37.string().min(1).max(META_LIMITS.creative.descriptionMax);
|
|
25749
|
-
var callToActionSchema = z37.
|
|
25759
|
+
var callToActionSchema = z37.strictObject({
|
|
25750
25760
|
type: z37.enum(CTA_TYPES2),
|
|
25751
25761
|
/** Overrides the base link for the CTA button; defaults to the ad's link. */
|
|
25752
25762
|
link: httpsUrlSchema3.optional(),
|
|
@@ -25767,7 +25777,7 @@ var callToActionSchema = z37.object({
|
|
|
25767
25777
|
});
|
|
25768
25778
|
}
|
|
25769
25779
|
});
|
|
25770
|
-
var creativeEnhancementsSchema = z37.
|
|
25780
|
+
var creativeEnhancementsSchema = z37.strictObject({
|
|
25771
25781
|
standardEnhancements: z37.enum(ENROLL_STATUSES).optional(),
|
|
25772
25782
|
features: z37.record(z37.string(), z37.enum(ENROLL_STATUSES)).optional()
|
|
25773
25783
|
});
|
|
@@ -25798,7 +25808,7 @@ function countImageRefs(p) {
|
|
|
25798
25808
|
function countVideoRefs(p) {
|
|
25799
25809
|
return [p.videoId, p.videoRef].filter(Boolean).length;
|
|
25800
25810
|
}
|
|
25801
|
-
var singleCreativeSchema = z37.
|
|
25811
|
+
var singleCreativeSchema = z37.strictObject({
|
|
25802
25812
|
creativeType: z37.literal("single"),
|
|
25803
25813
|
...creativeSharedFields,
|
|
25804
25814
|
/** Primary text. */
|
|
@@ -25832,7 +25842,7 @@ var singleCreativeSchema = z37.object({
|
|
|
25832
25842
|
});
|
|
25833
25843
|
}
|
|
25834
25844
|
});
|
|
25835
|
-
var carouselCardSchema = z37.
|
|
25845
|
+
var carouselCardSchema = z37.strictObject({
|
|
25836
25846
|
link: httpsUrlSchema3,
|
|
25837
25847
|
headline: z37.string().max(META_LIMITS.creative.headlineMax).optional(),
|
|
25838
25848
|
description: z37.string().max(META_LIMITS.creative.descriptionMax).optional(),
|
|
@@ -25855,7 +25865,7 @@ var carouselCardSchema = z37.object({
|
|
|
25855
25865
|
ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
|
|
25856
25866
|
}
|
|
25857
25867
|
});
|
|
25858
|
-
var carouselCreativeSchema2 = z37.
|
|
25868
|
+
var carouselCreativeSchema2 = z37.strictObject({
|
|
25859
25869
|
creativeType: z37.literal("carousel"),
|
|
25860
25870
|
...creativeSharedFields,
|
|
25861
25871
|
message: messageSchema,
|
|
@@ -25877,19 +25887,19 @@ var carouselCreativeSchema2 = z37.object({
|
|
|
25877
25887
|
});
|
|
25878
25888
|
}
|
|
25879
25889
|
});
|
|
25880
|
-
var dynamicImageSchema = z37.
|
|
25881
|
-
var dynamicVideoSchema = z37.
|
|
25890
|
+
var dynamicImageSchema = z37.strictObject({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
|
|
25891
|
+
var dynamicVideoSchema = z37.strictObject({
|
|
25882
25892
|
videoId: videoMediaFields.videoId,
|
|
25883
25893
|
videoRef: videoMediaFields.videoRef,
|
|
25884
25894
|
thumbnailHash: videoMediaFields.thumbnailHash
|
|
25885
25895
|
}).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
|
|
25886
25896
|
var DYN = META_LIMITS.creative;
|
|
25887
|
-
var dynamicCreativeSchema = z37.
|
|
25897
|
+
var dynamicCreativeSchema = z37.strictObject({
|
|
25888
25898
|
creativeType: z37.literal("dynamic"),
|
|
25889
25899
|
...creativeSharedFields,
|
|
25890
|
-
bodies: z37.array(z37.
|
|
25891
|
-
titles: z37.array(z37.
|
|
25892
|
-
descriptions: z37.array(z37.
|
|
25900
|
+
bodies: z37.array(z37.strictObject({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
|
|
25901
|
+
titles: z37.array(z37.strictObject({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
|
|
25902
|
+
descriptions: z37.array(z37.strictObject({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
|
|
25893
25903
|
images: z37.array(dynamicImageSchema).optional(),
|
|
25894
25904
|
videos: z37.array(dynamicVideoSchema).optional(),
|
|
25895
25905
|
/**
|
|
@@ -25905,7 +25915,7 @@ var dynamicCreativeSchema = z37.object({
|
|
|
25905
25915
|
* different enums.
|
|
25906
25916
|
*/
|
|
25907
25917
|
call_to_action: callToActionSchema.optional(),
|
|
25908
|
-
link_urls: z37.array(z37.
|
|
25918
|
+
link_urls: z37.array(z37.strictObject({ website_url: httpsUrlSchema3, display_url: z37.string().optional() })).min(1),
|
|
25909
25919
|
/**
|
|
25910
25920
|
* `asset_feed_spec.optimization_type` — passed through as a free string on
|
|
25911
25921
|
* purpose. Meta's own 400 enumerates ten values and then accepts
|
|
@@ -25936,7 +25946,7 @@ var dynamicCreativeSchema = z37.object({
|
|
|
25936
25946
|
});
|
|
25937
25947
|
});
|
|
25938
25948
|
});
|
|
25939
|
-
var existingPostCreativeSchema = z37.
|
|
25949
|
+
var existingPostCreativeSchema = z37.strictObject({
|
|
25940
25950
|
creativeType: z37.literal("existing_post"),
|
|
25941
25951
|
name: creativeSharedFields.name,
|
|
25942
25952
|
/** "<page_id>_<post_id>" object story id of the post to promote. */
|
|
@@ -25945,7 +25955,7 @@ var existingPostCreativeSchema = z37.object({
|
|
|
25945
25955
|
url_tags: creativeSharedFields.url_tags,
|
|
25946
25956
|
enhancements: creativeSharedFields.enhancements
|
|
25947
25957
|
});
|
|
25948
|
-
var specCreativeSchema = z37.
|
|
25958
|
+
var specCreativeSchema = z37.strictObject({
|
|
25949
25959
|
creativeType: z37.literal("spec"),
|
|
25950
25960
|
name: creativeSharedFields.name,
|
|
25951
25961
|
url_tags: creativeSharedFields.url_tags,
|
|
@@ -25974,29 +25984,29 @@ var creativeContentSchema2 = z37.discriminatedUnion("creativeType", [
|
|
|
25974
25984
|
specCreativeSchema
|
|
25975
25985
|
]);
|
|
25976
25986
|
var adCreativeCreateSchema = creativeContentSchema2;
|
|
25977
|
-
var adCreativeUpdateSchema = z37.
|
|
25987
|
+
var adCreativeUpdateSchema = z37.strictObject({
|
|
25978
25988
|
name: z37.string().max(META_LIMITS.creative.nameMax).optional(),
|
|
25979
|
-
status:
|
|
25989
|
+
status: z37.enum(CREATIVE_UPDATE_STATUSES).optional(),
|
|
25980
25990
|
/** Content patch — only honored when the target is a staged meta_temp_* creative. */
|
|
25981
25991
|
content: z37.record(z37.string(), z37.unknown()).optional()
|
|
25982
25992
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
25983
|
-
var adCreateSchema2 = z37.
|
|
25993
|
+
var adCreateSchema2 = z37.strictObject({
|
|
25984
25994
|
name: z37.string().min(1).max(META_LIMITS.ad.nameMax),
|
|
25985
25995
|
adset_id: parentRefSchema3,
|
|
25986
25996
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
25987
|
-
creative: z37.
|
|
25997
|
+
creative: z37.strictObject({ creative_id: parentRefSchema3 }),
|
|
25988
25998
|
/** Conversion pixel / offline event set / view tags — structural passthrough. */
|
|
25989
25999
|
tracking_specs: z37.array(z37.record(z37.string(), z37.unknown())).optional()
|
|
25990
26000
|
});
|
|
25991
|
-
var adUpdateSchema2 = z37.
|
|
26001
|
+
var adUpdateSchema2 = z37.strictObject({
|
|
25992
26002
|
name: z37.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
|
|
25993
26003
|
status: updateStatusSchema.optional(),
|
|
25994
26004
|
/** Swapping the creative is the Meta way to "edit" an ad's creative. */
|
|
25995
|
-
creative: z37.
|
|
26005
|
+
creative: z37.strictObject({ creative_id: parentRefSchema3 }).optional(),
|
|
25996
26006
|
tracking_specs: z37.array(z37.record(z37.string(), z37.unknown())).optional()
|
|
25997
26007
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
25998
|
-
var lookalikeSpecSchema = z37.
|
|
25999
|
-
origin: z37.array(z37.
|
|
26008
|
+
var lookalikeSpecSchema = z37.strictObject({
|
|
26009
|
+
origin: z37.array(z37.strictObject({ id: parentRefSchema3 })).min(1),
|
|
26000
26010
|
ratio: z37.number().min(0.01).max(0.2).optional(),
|
|
26001
26011
|
country: z37.string().length(2).optional()
|
|
26002
26012
|
});
|
|
@@ -26014,7 +26024,7 @@ function mixedEventSourceTypes(rule) {
|
|
|
26014
26024
|
const distinct = [...new Set(types)].sort();
|
|
26015
26025
|
return distinct.length > 1 ? distinct : [];
|
|
26016
26026
|
}
|
|
26017
|
-
var customAudienceCreateSchema = z37.
|
|
26027
|
+
var customAudienceCreateSchema = z37.strictObject({
|
|
26018
26028
|
name: z37.string().min(1).max(META_LIMITS.audience.nameMax),
|
|
26019
26029
|
subtype: z37.enum(CUSTOM_AUDIENCE_SUBTYPES),
|
|
26020
26030
|
description: z37.string().max(500).optional(),
|
|
@@ -26046,11 +26056,11 @@ var customAudienceCreateSchema = z37.object({
|
|
|
26046
26056
|
});
|
|
26047
26057
|
}
|
|
26048
26058
|
});
|
|
26049
|
-
var customAudienceUpdateSchema = z37.
|
|
26059
|
+
var customAudienceUpdateSchema = z37.strictObject({
|
|
26050
26060
|
name: z37.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
|
|
26051
26061
|
description: z37.string().max(500).optional()
|
|
26052
26062
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
26053
|
-
var customConversionCreateSchema = z37.
|
|
26063
|
+
var customConversionCreateSchema = z37.strictObject({
|
|
26054
26064
|
name: z37.string().min(1).max(META_LIMITS.customConversion.nameMax),
|
|
26055
26065
|
description: z37.string().max(META_LIMITS.customConversion.descriptionMax).optional(),
|
|
26056
26066
|
/** The pixel the conversion counts from — `event_source_id` on the wire. Baker never creates pixels, so this is always a real id. */
|
|
@@ -26066,7 +26076,7 @@ var customConversionCreateSchema = z37.object({
|
|
|
26066
26076
|
ctx.addIssue({ code: "custom", path: ["rule"], message: refusal });
|
|
26067
26077
|
}
|
|
26068
26078
|
});
|
|
26069
|
-
var mediaUploadSchema = z37.
|
|
26079
|
+
var mediaUploadSchema = z37.strictObject({
|
|
26070
26080
|
kind: z37.enum(MEDIA_KINDS),
|
|
26071
26081
|
bakerImageId: bakerMediaIdSchema2.optional(),
|
|
26072
26082
|
bakerVideoId: bakerMediaIdSchema2.optional(),
|
|
@@ -26242,26 +26252,33 @@ import { defineCommand as defineCommand57 } from "citty";
|
|
|
26242
26252
|
|
|
26243
26253
|
// src/commands/ads/meta/write-shared.ts
|
|
26244
26254
|
import { readFileSync as readFileSync9 } from "fs";
|
|
26245
|
-
|
|
26246
|
-
return
|
|
26255
|
+
function bareAccountId2(args5) {
|
|
26256
|
+
return resolveAccountIdArg(args5).replace(/^act_/, "");
|
|
26247
26257
|
}
|
|
26248
26258
|
function failWriteValidation3(message) {
|
|
26249
26259
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
26250
26260
|
process.exit(1);
|
|
26251
26261
|
}
|
|
26252
|
-
function
|
|
26253
|
-
if (
|
|
26262
|
+
function refuseDeleteByUpdate(payload, group) {
|
|
26263
|
+
if (payload.status === "DELETED") {
|
|
26264
|
+
failWriteValidation3(
|
|
26265
|
+
`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.`
|
|
26266
|
+
);
|
|
26267
|
+
}
|
|
26268
|
+
}
|
|
26269
|
+
function loadJsonFileArg3(path49) {
|
|
26270
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
26254
26271
|
return {};
|
|
26255
26272
|
}
|
|
26256
26273
|
try {
|
|
26257
|
-
const parsed = JSON.parse(readFileSync9(
|
|
26274
|
+
const parsed = JSON.parse(readFileSync9(path49, "utf8"));
|
|
26258
26275
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
26259
|
-
failWriteValidation3(`${
|
|
26276
|
+
failWriteValidation3(`${path49} must contain a JSON object`);
|
|
26260
26277
|
}
|
|
26261
26278
|
return parsed;
|
|
26262
26279
|
} catch (err) {
|
|
26263
26280
|
if (err instanceof SyntaxError) {
|
|
26264
|
-
failWriteValidation3(`${
|
|
26281
|
+
failWriteValidation3(`${path49} is not valid JSON: ${err.message}`);
|
|
26265
26282
|
}
|
|
26266
26283
|
throw err;
|
|
26267
26284
|
}
|
|
@@ -26369,7 +26386,7 @@ async function stageStatusChange2(input) {
|
|
|
26369
26386
|
// src/commands/ads/meta/write-commands.ts
|
|
26370
26387
|
var STAGED_NOTE2 = "Staged until publish \u2014 review with `baker ads meta draft`.";
|
|
26371
26388
|
var accountArgs2 = {
|
|
26372
|
-
"account-id": { type: "string", description: "Numeric account ID or act_N
|
|
26389
|
+
"account-id": { type: "string", description: "Numeric account ID or act_N" }
|
|
26373
26390
|
};
|
|
26374
26391
|
function campaignPayloadFromFlags2(args5) {
|
|
26375
26392
|
return {
|
|
@@ -26425,7 +26442,7 @@ Example: baker ads meta campaigns create --name "Q3 Prospecting" --objective OUT
|
|
|
26425
26442
|
file: { type: "string", description: "JSON file with the full payload; flags override file keys" }
|
|
26426
26443
|
},
|
|
26427
26444
|
run: async ({ args: args5 }) => {
|
|
26428
|
-
const accountId =
|
|
26445
|
+
const accountId = bareAccountId2(args5);
|
|
26429
26446
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), campaignPayloadFromFlags2(args5));
|
|
26430
26447
|
await stageOp2({ kind: "campaign.create", accountId, payload });
|
|
26431
26448
|
}
|
|
@@ -26445,7 +26462,7 @@ Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker a
|
|
|
26445
26462
|
file: { type: "string", description: "JSON file with fields to change" }
|
|
26446
26463
|
},
|
|
26447
26464
|
run: async ({ args: args5 }) => {
|
|
26448
|
-
const accountId =
|
|
26465
|
+
const accountId = bareAccountId2(args5);
|
|
26449
26466
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), {
|
|
26450
26467
|
name: args5.name,
|
|
26451
26468
|
status: upper(args5.status),
|
|
@@ -26456,6 +26473,7 @@ Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker a
|
|
|
26456
26473
|
start_time: parseDateFlag2(args5.start, "--start"),
|
|
26457
26474
|
stop_time: parseDateFlag2(args5.stop, "--stop")
|
|
26458
26475
|
});
|
|
26476
|
+
refuseDeleteByUpdate(payload, "campaigns");
|
|
26459
26477
|
await stageOp2({
|
|
26460
26478
|
kind: "campaign.update",
|
|
26461
26479
|
accountId,
|
|
@@ -26538,7 +26556,7 @@ Example: baker ads meta custom-conversions create --name "Lead formulario" --pix
|
|
|
26538
26556
|
value: { type: "string", description: "Default value of one conversion, when the site sends no value" }
|
|
26539
26557
|
},
|
|
26540
26558
|
run: async ({ args: args5 }) => {
|
|
26541
|
-
const accountId =
|
|
26559
|
+
const accountId = bareAccountId2(args5);
|
|
26542
26560
|
await stageOp2({
|
|
26543
26561
|
kind: "customConversion.create",
|
|
26544
26562
|
accountId,
|
|
@@ -26595,7 +26613,7 @@ Example: baker ads meta adsets create --campaign meta_temp_ab12 --name "US 25-54
|
|
|
26595
26613
|
},
|
|
26596
26614
|
args: { campaign: { type: "string", description: "Parent campaign id or meta_temp_* ref" }, ...adSetWriteArgs },
|
|
26597
26615
|
run: async ({ args: args5 }) => {
|
|
26598
|
-
const accountId =
|
|
26616
|
+
const accountId = bareAccountId2(args5);
|
|
26599
26617
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), adSetPayloadFromFlags(args5));
|
|
26600
26618
|
await stageOp2({ kind: "adSet.create", accountId, payload });
|
|
26601
26619
|
}
|
|
@@ -26609,13 +26627,14 @@ Example: baker ads meta adsets update 6123 --daily-budget 80`
|
|
|
26609
26627
|
},
|
|
26610
26628
|
args: { id: { type: "positional", description: "Ad set id or meta_temp_* ref", required: true }, ...adSetWriteArgs },
|
|
26611
26629
|
run: async ({ args: args5 }) => {
|
|
26612
|
-
const accountId =
|
|
26630
|
+
const accountId = bareAccountId2(args5);
|
|
26613
26631
|
const {
|
|
26614
26632
|
campaign_id: _drop,
|
|
26615
26633
|
billing_event: _be,
|
|
26616
26634
|
...payload
|
|
26617
26635
|
} = adSetPayloadFromFlags(args5);
|
|
26618
26636
|
const merged = mergePayload3(loadJsonFileArg3(args5.file), payload);
|
|
26637
|
+
refuseDeleteByUpdate(merged, "adsets");
|
|
26619
26638
|
await stageOp2({
|
|
26620
26639
|
kind: "adSet.update",
|
|
26621
26640
|
accountId,
|
|
@@ -26711,7 +26730,7 @@ Example: baker ads meta creatives create --page 555 --message "Save now" --link
|
|
|
26711
26730
|
file: { type: "string", description: "JSON file with the full creative payload (carousel cards / dynamic assets)" }
|
|
26712
26731
|
},
|
|
26713
26732
|
run: async ({ args: args5 }) => {
|
|
26714
|
-
const accountId =
|
|
26733
|
+
const accountId = bareAccountId2(args5);
|
|
26715
26734
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), creativePayloadFromFlags(args5));
|
|
26716
26735
|
if (payload.creativeType === void 0) {
|
|
26717
26736
|
payload.creativeType = "single";
|
|
@@ -26742,7 +26761,7 @@ Amending a staged (meta_temp_*) creative merges fields into the create. Example:
|
|
|
26742
26761
|
}
|
|
26743
26762
|
},
|
|
26744
26763
|
run: async ({ args: args5 }) => {
|
|
26745
|
-
const accountId =
|
|
26764
|
+
const accountId = bareAccountId2(args5);
|
|
26746
26765
|
const file = loadJsonFileArg3(args5.file);
|
|
26747
26766
|
const payload = mergePayload3(file, {
|
|
26748
26767
|
name: args5.name,
|
|
@@ -26776,7 +26795,7 @@ Example: baker ads meta ads create --name "Ad 1" --adset meta_temp_as01 --creati
|
|
|
26776
26795
|
file: { type: "string", description: "JSON file with the full payload" }
|
|
26777
26796
|
},
|
|
26778
26797
|
run: async ({ args: args5 }) => {
|
|
26779
|
-
const accountId =
|
|
26798
|
+
const accountId = bareAccountId2(args5);
|
|
26780
26799
|
const tracking = args5["tracking-file"] ? loadJsonFileArg3(args5["tracking-file"]).tracking_specs : void 0;
|
|
26781
26800
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), {
|
|
26782
26801
|
name: args5.name,
|
|
@@ -26803,12 +26822,13 @@ Example: baker ads meta ads update 6123 --creative meta_temp_cr02`
|
|
|
26803
26822
|
file: { type: "string", description: "JSON file with fields to change" }
|
|
26804
26823
|
},
|
|
26805
26824
|
run: async ({ args: args5 }) => {
|
|
26806
|
-
const accountId =
|
|
26825
|
+
const accountId = bareAccountId2(args5);
|
|
26807
26826
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), {
|
|
26808
26827
|
name: args5.name,
|
|
26809
26828
|
status: upper(args5.status),
|
|
26810
26829
|
creative: args5.creative ? { creative_id: String(args5.creative) } : void 0
|
|
26811
26830
|
});
|
|
26831
|
+
refuseDeleteByUpdate(payload, "ads");
|
|
26812
26832
|
await stageOp2({
|
|
26813
26833
|
kind: "ad.update",
|
|
26814
26834
|
accountId,
|
|
@@ -26839,9 +26859,9 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
26839
26859
|
const { apiPost: apiPost2 } = await import("./client-GR6YL3YX.js");
|
|
26840
26860
|
const { requireChatId: requireChatId2 } = await import("./env-4P5HOGNA.js");
|
|
26841
26861
|
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-NMQXZF3Z.js");
|
|
26842
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
26862
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-J7DQZ2ED.js");
|
|
26843
26863
|
try {
|
|
26844
|
-
const accountId =
|
|
26864
|
+
const accountId = bareAccountId2(args5);
|
|
26845
26865
|
const urlTags = typeof args5["url-tags"] === "string" ? args5["url-tags"] : void 0;
|
|
26846
26866
|
const setRaw = typeof args5.set === "string" ? args5.set : void 0;
|
|
26847
26867
|
if (urlTags === void 0 === (setRaw === void 0)) {
|
|
@@ -26895,7 +26915,7 @@ Example: baker ads meta audiences create --name "Site visitors 30d" --subtype WE
|
|
|
26895
26915
|
file: { type: "string", description: "JSON file with lookalike_spec / rule / full payload" }
|
|
26896
26916
|
},
|
|
26897
26917
|
run: async ({ args: args5 }) => {
|
|
26898
|
-
const accountId =
|
|
26918
|
+
const accountId = bareAccountId2(args5);
|
|
26899
26919
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), {
|
|
26900
26920
|
name: args5.name,
|
|
26901
26921
|
subtype: upper(args5.subtype),
|
|
@@ -26918,7 +26938,7 @@ var audiencesUpdateCommand = defineCommand57({
|
|
|
26918
26938
|
file: { type: "string", description: "JSON file with fields to change" }
|
|
26919
26939
|
},
|
|
26920
26940
|
run: async ({ args: args5 }) => {
|
|
26921
|
-
const accountId =
|
|
26941
|
+
const accountId = bareAccountId2(args5);
|
|
26922
26942
|
const payload = mergePayload3(loadJsonFileArg3(args5.file), { name: args5.name, description: args5.description });
|
|
26923
26943
|
await stageOp2({
|
|
26924
26944
|
kind: "customAudience.update",
|
|
@@ -26942,7 +26962,7 @@ Example: baker ads meta media upload --kind image --image-id <bakerImageId>`
|
|
|
26942
26962
|
name: { type: "string", description: "Display name / filename hint" }
|
|
26943
26963
|
},
|
|
26944
26964
|
run: async ({ args: args5 }) => {
|
|
26945
|
-
const accountId =
|
|
26965
|
+
const accountId = bareAccountId2(args5);
|
|
26946
26966
|
const kind = String(args5.kind ?? "").toLowerCase();
|
|
26947
26967
|
if (kind !== "image" && kind !== "video") {
|
|
26948
26968
|
failWriteValidation3("--kind must be image or video");
|
|
@@ -26954,13 +26974,19 @@ Example: baker ads meta media upload --kind image --image-id <bakerImageId>`
|
|
|
26954
26974
|
});
|
|
26955
26975
|
}
|
|
26956
26976
|
});
|
|
26977
|
+
var STATUS_BY_COMMAND = { pause: "PAUSED", resume: "ACTIVE", archive: "ARCHIVED", delete: "DELETED" };
|
|
26978
|
+
var STATUS_COMMAND_NOTE = {
|
|
26979
|
+
archive: "Archived stays readable in Ads Manager and can be found with --effective-status ARCHIVED.",
|
|
26980
|
+
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."
|
|
26981
|
+
};
|
|
26957
26982
|
function statusCommand3(name, kind, label) {
|
|
26958
|
-
const status = name
|
|
26983
|
+
const status = STATUS_BY_COMMAND[name];
|
|
26984
|
+
const note = STATUS_COMMAND_NOTE[name];
|
|
26959
26985
|
return defineCommand57({
|
|
26960
|
-
meta: { name, description: `Stage ${name} for a ${label}. ${STAGED_NOTE2}` },
|
|
26986
|
+
meta: { name, description: `Stage ${name} for a ${label}. ${note ? `${note} ` : ""}${STAGED_NOTE2}` },
|
|
26961
26987
|
args: { id: { type: "positional", description: `${label} id`, required: true }, ...accountArgs2 },
|
|
26962
26988
|
run: async ({ args: args5 }) => {
|
|
26963
|
-
const accountId =
|
|
26989
|
+
const accountId = bareAccountId2(args5);
|
|
26964
26990
|
await stageStatusChange2({
|
|
26965
26991
|
kind,
|
|
26966
26992
|
accountId,
|
|
@@ -26987,9 +27013,9 @@ function duplicateCommand2(entity, label) {
|
|
|
26987
27013
|
const { apiPost: apiPost2 } = await import("./client-GR6YL3YX.js");
|
|
26988
27014
|
const { requireChatId: requireChatId2 } = await import("./env-4P5HOGNA.js");
|
|
26989
27015
|
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-NMQXZF3Z.js");
|
|
26990
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
27016
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-J7DQZ2ED.js");
|
|
26991
27017
|
try {
|
|
26992
|
-
const accountId =
|
|
27018
|
+
const accountId = bareAccountId2(args5);
|
|
26993
27019
|
const chatId = requireChatId2();
|
|
26994
27020
|
const response = await apiPost2("/api/ads/meta/draft/duplicate", {
|
|
26995
27021
|
chatId,
|
|
@@ -27009,19 +27035,22 @@ function duplicateCommand2(entity, label) {
|
|
|
27009
27035
|
var campaignsPauseCommand2 = statusCommand3("pause", "campaign.update", "campaign");
|
|
27010
27036
|
var campaignsResumeCommand2 = statusCommand3("resume", "campaign.update", "campaign");
|
|
27011
27037
|
var campaignsArchiveCommand2 = statusCommand3("archive", "campaign.update", "campaign");
|
|
27038
|
+
var campaignsDeleteCommand = statusCommand3("delete", "campaign.update", "campaign");
|
|
27012
27039
|
var campaignsDuplicateCommand2 = duplicateCommand2("campaign", "campaign");
|
|
27013
27040
|
var adSetsPauseCommand = statusCommand3("pause", "adSet.update", "ad set");
|
|
27014
27041
|
var adSetsResumeCommand = statusCommand3("resume", "adSet.update", "ad set");
|
|
27015
27042
|
var adSetsArchiveCommand = statusCommand3("archive", "adSet.update", "ad set");
|
|
27043
|
+
var adSetsDeleteCommand = statusCommand3("delete", "adSet.update", "ad set");
|
|
27016
27044
|
var adSetsDuplicateCommand = duplicateCommand2("adSet", "ad set");
|
|
27017
27045
|
var adsPauseCommand = statusCommand3("pause", "ad.update", "ad");
|
|
27018
27046
|
var adsResumeCommand = statusCommand3("resume", "ad.update", "ad");
|
|
27019
27047
|
var adsArchiveCommand = statusCommand3("archive", "ad.update", "ad");
|
|
27048
|
+
var adsDeleteCommand = statusCommand3("delete", "ad.update", "ad");
|
|
27020
27049
|
var adsDuplicateCommand = duplicateCommand2("ad", "ad");
|
|
27021
27050
|
|
|
27022
27051
|
// src/commands/ads/meta/ads.ts
|
|
27023
27052
|
var listArgs5 = {
|
|
27024
|
-
"account-id": { type: "string", description: "Meta ad account ID
|
|
27053
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
27025
27054
|
"adset-id": { type: "string", description: "Filter to one adset" },
|
|
27026
27055
|
"campaign-id": { type: "string", description: "Filter to one campaign" },
|
|
27027
27056
|
"effective-status": { type: "string", description: "Comma-separated effective_status filter (overrides default)" },
|
|
@@ -27043,7 +27072,7 @@ var listCommand4 = defineCommand58({
|
|
|
27043
27072
|
},
|
|
27044
27073
|
args: listArgs5,
|
|
27045
27074
|
run: async ({ args: args5 }) => {
|
|
27046
|
-
const accountId =
|
|
27075
|
+
const accountId = resolveAccountIdArg(args5);
|
|
27047
27076
|
const effectiveStatus = resolveEffectiveStatus(args5);
|
|
27048
27077
|
try {
|
|
27049
27078
|
const params = { "account-id": accountId };
|
|
@@ -27064,7 +27093,7 @@ var listCommand4 = defineCommand58({
|
|
|
27064
27093
|
var adsListCommand = defineCommand58({
|
|
27065
27094
|
meta: {
|
|
27066
27095
|
name: "ads",
|
|
27067
|
-
description: `List ads in a Meta ad account, or stage writes (create/update/pause/resume/archive/duplicate/retag).
|
|
27096
|
+
description: `List ads in a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate/retag).
|
|
27068
27097
|
Defaults to ACTIVE only \u2014 pass --all-statuses to widen. Write subcommands stage ops on this chat's draft.
|
|
27069
27098
|
|
|
27070
27099
|
The dashboard shows effective_status (e.g. WITH_ISSUES, PENDING_REVIEW, DISAPPROVED, ADSET_PAUSED), not status.
|
|
@@ -27089,6 +27118,7 @@ Examples:
|
|
|
27089
27118
|
pause: adsPauseCommand,
|
|
27090
27119
|
resume: adsResumeCommand,
|
|
27091
27120
|
archive: adsArchiveCommand,
|
|
27121
|
+
delete: adsDeleteCommand,
|
|
27092
27122
|
duplicate: adsDuplicateCommand,
|
|
27093
27123
|
retag: adsRetagCommand
|
|
27094
27124
|
},
|
|
@@ -27103,7 +27133,7 @@ Examples:
|
|
|
27103
27133
|
// src/commands/ads/meta/adsets.ts
|
|
27104
27134
|
import { defineCommand as defineCommand59 } from "citty";
|
|
27105
27135
|
var listArgs6 = {
|
|
27106
|
-
"account-id": { type: "string", description: "Meta ad account ID
|
|
27136
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
27107
27137
|
"campaign-id": { type: "string", description: "Filter to one campaign" },
|
|
27108
27138
|
"effective-status": { type: "string", description: "Comma-separated effective_status filter (overrides default)" },
|
|
27109
27139
|
"all-statuses": { type: "boolean", description: "Drop the default ACTIVE filter" },
|
|
@@ -27124,7 +27154,7 @@ var listCommand5 = defineCommand59({
|
|
|
27124
27154
|
},
|
|
27125
27155
|
args: listArgs6,
|
|
27126
27156
|
run: async ({ args: args5 }) => {
|
|
27127
|
-
const accountId =
|
|
27157
|
+
const accountId = resolveAccountIdArg(args5);
|
|
27128
27158
|
const effectiveStatus = resolveEffectiveStatus(args5);
|
|
27129
27159
|
try {
|
|
27130
27160
|
const params = { "account-id": accountId };
|
|
@@ -27144,7 +27174,7 @@ var listCommand5 = defineCommand59({
|
|
|
27144
27174
|
var adsetsCommand = defineCommand59({
|
|
27145
27175
|
meta: {
|
|
27146
27176
|
name: "adsets",
|
|
27147
|
-
description: `List ad sets in a Meta ad account, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
27177
|
+
description: `List ad sets in a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate).
|
|
27148
27178
|
Defaults to ACTIVE only. Write subcommands stage ops on this chat's draft.
|
|
27149
27179
|
|
|
27150
27180
|
Listings print a table by default: id, name, campaign_id, effective_status, optimization_goal, billing_event,
|
|
@@ -27165,6 +27195,7 @@ Examples:
|
|
|
27165
27195
|
pause: adSetsPauseCommand,
|
|
27166
27196
|
resume: adSetsResumeCommand,
|
|
27167
27197
|
archive: adSetsArchiveCommand,
|
|
27198
|
+
delete: adSetsDeleteCommand,
|
|
27168
27199
|
duplicate: adSetsDuplicateCommand
|
|
27169
27200
|
},
|
|
27170
27201
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
@@ -27178,7 +27209,7 @@ Examples:
|
|
|
27178
27209
|
// src/commands/ads/meta/audiences.ts
|
|
27179
27210
|
import { defineCommand as defineCommand60 } from "citty";
|
|
27180
27211
|
var listArgs7 = {
|
|
27181
|
-
"account-id": { type: "string", description: "Meta ad account ID
|
|
27212
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
27182
27213
|
limit: { type: "string", description: "Max rows" },
|
|
27183
27214
|
"no-cache": NO_CACHE_ARG,
|
|
27184
27215
|
output: { type: "string", description: "Output format", default: "json" }
|
|
@@ -27190,7 +27221,7 @@ var listCommand6 = defineCommand60({
|
|
|
27190
27221
|
},
|
|
27191
27222
|
args: listArgs7,
|
|
27192
27223
|
run: async ({ args: args5 }) => {
|
|
27193
|
-
const accountId =
|
|
27224
|
+
const accountId = resolveAccountIdArg(args5);
|
|
27194
27225
|
try {
|
|
27195
27226
|
const params = { "account-id": accountId };
|
|
27196
27227
|
if (args5.limit) params.limit = args5.limit;
|
|
@@ -27264,7 +27295,7 @@ Examples:
|
|
|
27264
27295
|
// src/commands/ads/meta/campaigns.ts
|
|
27265
27296
|
import { defineCommand as defineCommand62 } from "citty";
|
|
27266
27297
|
var listArgs8 = {
|
|
27267
|
-
"account-id": { type: "string", description: "Meta ad account ID
|
|
27298
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
27268
27299
|
"effective-status": { type: "string", description: "Comma-separated effective_status filter (overrides default)" },
|
|
27269
27300
|
"all-statuses": { type: "boolean", description: "Drop the default ACTIVE filter and return everything" },
|
|
27270
27301
|
"name-contains": NAME_CONTAINS_ARG,
|
|
@@ -27284,7 +27315,7 @@ var listCommand7 = defineCommand62({
|
|
|
27284
27315
|
},
|
|
27285
27316
|
args: listArgs8,
|
|
27286
27317
|
run: async ({ args: args5 }) => {
|
|
27287
|
-
const accountId =
|
|
27318
|
+
const accountId = resolveAccountIdArg(args5);
|
|
27288
27319
|
const effectiveStatus = resolveEffectiveStatus(args5);
|
|
27289
27320
|
try {
|
|
27290
27321
|
const params = { "account-id": accountId };
|
|
@@ -27303,7 +27334,7 @@ var listCommand7 = defineCommand62({
|
|
|
27303
27334
|
var campaignsCommand3 = defineCommand62({
|
|
27304
27335
|
meta: {
|
|
27305
27336
|
name: "campaigns",
|
|
27306
|
-
description: `List campaigns for a Meta ad account, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
27337
|
+
description: `List campaigns for a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate).
|
|
27307
27338
|
Defaults to ACTIVE only \u2014 pass --all-statuses to widen. Write subcommands stage ops on this chat's draft and
|
|
27308
27339
|
apply only when the chat is published.
|
|
27309
27340
|
|
|
@@ -27330,6 +27361,7 @@ Examples:
|
|
|
27330
27361
|
pause: campaignsPauseCommand2,
|
|
27331
27362
|
resume: campaignsResumeCommand2,
|
|
27332
27363
|
archive: campaignsArchiveCommand2,
|
|
27364
|
+
delete: campaignsDeleteCommand,
|
|
27333
27365
|
duplicate: campaignsDuplicateCommand2
|
|
27334
27366
|
},
|
|
27335
27367
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
@@ -27343,10 +27375,7 @@ Examples:
|
|
|
27343
27375
|
// src/commands/ads/meta/creatives.ts
|
|
27344
27376
|
import { defineCommand as defineCommand63 } from "citty";
|
|
27345
27377
|
var listArgs9 = {
|
|
27346
|
-
"account-id": {
|
|
27347
|
-
type: "string",
|
|
27348
|
-
description: "Meta ad account ID (act_...) when listing without --creative-id; defaults to the only connected account"
|
|
27349
|
-
},
|
|
27378
|
+
"account-id": { type: "string", description: "Meta ad account ID (required if no --creative-id)" },
|
|
27350
27379
|
"creative-id": { type: "string", description: "Single creative ID" },
|
|
27351
27380
|
limit: { type: "string", description: "Max rows (default 500)" },
|
|
27352
27381
|
"no-cache": NO_CACHE_ARG,
|
|
@@ -27364,7 +27393,7 @@ var listCommand8 = defineCommand63({
|
|
|
27364
27393
|
if (args5["creative-id"]) {
|
|
27365
27394
|
params["creative-id"] = args5["creative-id"];
|
|
27366
27395
|
} else {
|
|
27367
|
-
const accountId =
|
|
27396
|
+
const accountId = resolveAccountIdArg(args5);
|
|
27368
27397
|
params["account-id"] = accountId;
|
|
27369
27398
|
}
|
|
27370
27399
|
if (args5.limit) params.limit = args5.limit;
|
|
@@ -27444,11 +27473,7 @@ registerSchema({
|
|
|
27444
27473
|
command: "ads.meta.custom-conversions",
|
|
27445
27474
|
description: "List the Custom Conversions defined on a Meta ad account \u2014 the measurement objects a marketer sets up in Events Manager (a pixel event narrowed by a rule, e.g. 'PageView on /thank-you'). Start here whenever the user talks about their own conversions rather than a standard event: an ad set optimizes toward one with `adsets create --custom-conversion-id <id>`.",
|
|
27446
27475
|
args: {
|
|
27447
|
-
"account-id": {
|
|
27448
|
-
type: "string",
|
|
27449
|
-
description: "Meta ad account ID (act_...); defaults to the only connected account",
|
|
27450
|
-
required: false
|
|
27451
|
-
},
|
|
27476
|
+
"account-id": { type: "string", description: "Meta ad account ID (act_123)", required: false },
|
|
27452
27477
|
full: { type: "boolean", description: "Include the raw rule JSON, retention and creation times", required: false },
|
|
27453
27478
|
limit: { type: "string", description: "Max rows", required: false },
|
|
27454
27479
|
"no-cache": { type: "boolean", description: "Bypass the cache", required: false },
|
|
@@ -27456,7 +27481,7 @@ registerSchema({
|
|
|
27456
27481
|
}
|
|
27457
27482
|
});
|
|
27458
27483
|
var listArgs10 = {
|
|
27459
|
-
"account-id": { type: "string", description: "Meta ad account ID
|
|
27484
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
27460
27485
|
full: { type: "boolean", description: "Include the raw rule JSON, retention and creation times" },
|
|
27461
27486
|
limit: { type: "string", description: "Max rows" },
|
|
27462
27487
|
"no-cache": NO_CACHE_ARG,
|
|
@@ -27469,7 +27494,7 @@ var listCommand9 = defineCommand64({
|
|
|
27469
27494
|
},
|
|
27470
27495
|
args: listArgs10,
|
|
27471
27496
|
run: async ({ args: args5 }) => {
|
|
27472
|
-
const accountId =
|
|
27497
|
+
const accountId = resolveAccountIdArg(args5);
|
|
27473
27498
|
try {
|
|
27474
27499
|
const params = { "account-id": accountId };
|
|
27475
27500
|
if (args5.limit) params.limit = args5.limit;
|
|
@@ -28346,10 +28371,7 @@ Examples:
|
|
|
28346
28371
|
baker ads meta pixels --account-id act_123 --pixel-id 9876 --stats --days 7`
|
|
28347
28372
|
},
|
|
28348
28373
|
args: {
|
|
28349
|
-
"account-id": {
|
|
28350
|
-
type: "string",
|
|
28351
|
-
description: "Meta ad account ID (act_...); defaults to the only connected account"
|
|
28352
|
-
},
|
|
28374
|
+
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
28353
28375
|
"pixel-id": { type: "string", description: "Pixel ID for --stats" },
|
|
28354
28376
|
stats: { type: "boolean", description: "Fetch firing stats for the pixel" },
|
|
28355
28377
|
aggregation: {
|
|
@@ -28393,7 +28415,7 @@ async function runStats(args5) {
|
|
|
28393
28415
|
emit(data, args5);
|
|
28394
28416
|
}
|
|
28395
28417
|
async function runList(args5) {
|
|
28396
|
-
const accountId =
|
|
28418
|
+
const accountId = resolveAccountIdArg(args5);
|
|
28397
28419
|
const params = { "account-id": accountId };
|
|
28398
28420
|
if (args5["no-cache"]) params["skip-cache"] = "true";
|
|
28399
28421
|
const { pixels, restrictedFields } = await apiGet("/api/ads/meta/pixels", params);
|
|
@@ -31952,12 +31974,12 @@ function flowExists(slug) {
|
|
|
31952
31974
|
return existsSync3(join2(flowsDir(), slug, "_data.json"));
|
|
31953
31975
|
}
|
|
31954
31976
|
function readFlowTree(slug) {
|
|
31955
|
-
const
|
|
31956
|
-
if (!existsSync3(
|
|
31977
|
+
const path49 = join2(flowsDir(), slug, "_data.json");
|
|
31978
|
+
if (!existsSync3(path49)) {
|
|
31957
31979
|
failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
|
|
31958
31980
|
}
|
|
31959
31981
|
try {
|
|
31960
|
-
return JSON.parse(readFileSync11(
|
|
31982
|
+
return JSON.parse(readFileSync11(path49, "utf-8"));
|
|
31961
31983
|
} catch (error) {
|
|
31962
31984
|
failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
|
|
31963
31985
|
}
|
|
@@ -32917,12 +32939,12 @@ function readPeopleFile(args5) {
|
|
|
32917
32939
|
}
|
|
32918
32940
|
function unreadablePeopleFile(args5) {
|
|
32919
32941
|
if (!args5["people-file"]) return void 0;
|
|
32920
|
-
const
|
|
32942
|
+
const path49 = String(args5["people-file"]);
|
|
32921
32943
|
try {
|
|
32922
|
-
readFileSync12(
|
|
32944
|
+
readFileSync12(path49, "utf8");
|
|
32923
32945
|
return void 0;
|
|
32924
32946
|
} catch {
|
|
32925
|
-
return `Couldn't read --people-file ${
|
|
32947
|
+
return `Couldn't read --people-file ${path49}. Check the path, or pass the people inline with --person.`;
|
|
32926
32948
|
}
|
|
32927
32949
|
}
|
|
32928
32950
|
function peopleLimitError(args5) {
|
|
@@ -33894,11 +33916,11 @@ function parseFieldArgs(argv) {
|
|
|
33894
33916
|
for (const pair of parseRepeated(argv, "--field")) {
|
|
33895
33917
|
const eq = pair.indexOf("=");
|
|
33896
33918
|
const field = eq === -1 ? pair : pair.slice(0, eq);
|
|
33897
|
-
const
|
|
33919
|
+
const path49 = eq === -1 ? "" : pair.slice(eq + 1).trim();
|
|
33898
33920
|
const problem = mappingRowProblem(field);
|
|
33899
33921
|
if (problem !== null) throw new ConversionArgsError(problem);
|
|
33900
|
-
if (
|
|
33901
|
-
mapping[field] =
|
|
33922
|
+
if (path49 === "") throw new ConversionArgsError(`--field ${field} needs a path: --field ${field}=<dotted.path>.`);
|
|
33923
|
+
mapping[field] = path49;
|
|
33902
33924
|
}
|
|
33903
33925
|
return mapping;
|
|
33904
33926
|
}
|
|
@@ -35500,11 +35522,11 @@ function unwrap(response) {
|
|
|
35500
35522
|
}
|
|
35501
35523
|
return response.data;
|
|
35502
35524
|
}
|
|
35503
|
-
async function readAvatars(
|
|
35504
|
-
return unwrap(await apiGet(
|
|
35525
|
+
async function readAvatars(path49, params) {
|
|
35526
|
+
return unwrap(await apiGet(path49, params));
|
|
35505
35527
|
}
|
|
35506
|
-
async function writeAvatars(
|
|
35507
|
-
return unwrap(await apiPost(
|
|
35528
|
+
async function writeAvatars(path49, body) {
|
|
35529
|
+
return unwrap(await apiPost(path49, body));
|
|
35508
35530
|
}
|
|
35509
35531
|
|
|
35510
35532
|
// src/commands/avatars/create.ts
|
|
@@ -36413,12 +36435,12 @@ function missingFontFiles(urls, available) {
|
|
|
36413
36435
|
function planFontAdoption(sources, families) {
|
|
36414
36436
|
const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
|
|
36415
36437
|
const byFamily = /* @__PURE__ */ new Map();
|
|
36416
|
-
for (const { path:
|
|
36417
|
-
const dir = posix.dirname(
|
|
36438
|
+
for (const { path: path49, source } of sources) {
|
|
36439
|
+
const dir = posix.dirname(path49);
|
|
36418
36440
|
for (const face of declaredFontFaces(source)) {
|
|
36419
36441
|
if (!wanted.has(face.family)) continue;
|
|
36420
36442
|
const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
|
|
36421
|
-
perFile.set(
|
|
36443
|
+
perFile.set(path49, [...perFile.get(path49) ?? [], rebaseFontFaceSrc(face.block, dir)]);
|
|
36422
36444
|
byFamily.set(face.family, perFile);
|
|
36423
36445
|
}
|
|
36424
36446
|
}
|
|
@@ -49244,10 +49266,10 @@ function parseValueExpression(raw) {
|
|
|
49244
49266
|
return parts.map(parsePart);
|
|
49245
49267
|
}
|
|
49246
49268
|
function trackingFieldIds() {
|
|
49247
|
-
const
|
|
49248
|
-
if (!existsSync6(
|
|
49269
|
+
const path49 = join4(flowsDir(), "..", "tracking.ts");
|
|
49270
|
+
if (!existsSync6(path49)) return null;
|
|
49249
49271
|
try {
|
|
49250
|
-
const source = readFileSync15(
|
|
49272
|
+
const source = readFileSync15(path49, "utf-8");
|
|
49251
49273
|
const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
|
|
49252
49274
|
if (!block2) return null;
|
|
49253
49275
|
const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
|
|
@@ -49821,13 +49843,13 @@ function specsFromFile(parsed) {
|
|
|
49821
49843
|
return `${destField}${type}=${entry?.value ?? ""}`;
|
|
49822
49844
|
});
|
|
49823
49845
|
}
|
|
49824
|
-
function readSpecFile(
|
|
49846
|
+
function readSpecFile(path49) {
|
|
49825
49847
|
let raw;
|
|
49826
49848
|
try {
|
|
49827
|
-
raw =
|
|
49849
|
+
raw = path49 === "-" ? readFileSync16(0, "utf-8") : readFileSync16(path49, "utf-8");
|
|
49828
49850
|
} catch (error) {
|
|
49829
49851
|
refuse(
|
|
49830
|
-
`Could not read ${
|
|
49852
|
+
`Could not read ${path49 === "-" ? "the mapping from stdin" : `"${path49}"`}: ${error instanceof Error ? error.message : String(error)}`
|
|
49831
49853
|
);
|
|
49832
49854
|
}
|
|
49833
49855
|
let parsed;
|
|
@@ -49835,7 +49857,7 @@ function readSpecFile(path48) {
|
|
|
49835
49857
|
parsed = JSON.parse(raw);
|
|
49836
49858
|
} catch (error) {
|
|
49837
49859
|
refuse(
|
|
49838
|
-
`${
|
|
49860
|
+
`${path49 === "-" ? "stdin" : `"${path49}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
49839
49861
|
'Expected { "map": { "<destField>": "<value>", \u2026 } }'
|
|
49840
49862
|
);
|
|
49841
49863
|
}
|
|
@@ -50134,21 +50156,21 @@ var ARRAY_FIELDS = [
|
|
|
50134
50156
|
"tagIds"
|
|
50135
50157
|
];
|
|
50136
50158
|
var ARRAY_OWNERS = ["", "body"];
|
|
50137
|
-
function dropUnsetOptionals(sideEffect,
|
|
50159
|
+
function dropUnsetOptionals(sideEffect, path49) {
|
|
50138
50160
|
return OPTIONAL_STRINGS.flatMap((key) => {
|
|
50139
50161
|
if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
|
|
50140
50162
|
delete sideEffect[key];
|
|
50141
|
-
return [{ path:
|
|
50163
|
+
return [{ path: path49, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
|
|
50142
50164
|
});
|
|
50143
50165
|
}
|
|
50144
|
-
function fillNulledArrays(target2, prefix,
|
|
50166
|
+
function fillNulledArrays(target2, prefix, path49) {
|
|
50145
50167
|
return ARRAY_FIELDS.flatMap((key) => {
|
|
50146
50168
|
if (!(key in target2) || target2[key] !== null) return [];
|
|
50147
50169
|
target2[key] = [];
|
|
50148
|
-
return [{ path:
|
|
50170
|
+
return [{ path: path49, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
|
|
50149
50171
|
});
|
|
50150
50172
|
}
|
|
50151
|
-
function tidyEmailRecipients(sideEffect,
|
|
50173
|
+
function tidyEmailRecipients(sideEffect, path49) {
|
|
50152
50174
|
if (sideEffect.type !== "email") return [];
|
|
50153
50175
|
const config = sideEffect.encryptedConfig;
|
|
50154
50176
|
if (!config || typeof config !== "object" || Array.isArray(config)) return [];
|
|
@@ -50159,7 +50181,7 @@ function tidyEmailRecipients(sideEffect, path48) {
|
|
|
50159
50181
|
const tidied = to.join(", ");
|
|
50160
50182
|
if (tidied === raw) return [];
|
|
50161
50183
|
config.email = tidied;
|
|
50162
|
-
return [{ path:
|
|
50184
|
+
return [{ path: path49, change: "tidied the recipient list's spacing and separators" }];
|
|
50163
50185
|
}
|
|
50164
50186
|
function sideEffectsOf(node) {
|
|
50165
50187
|
if (!Array.isArray(node.sideEffects)) return [];
|
|
@@ -50168,13 +50190,13 @@ function sideEffectsOf(node) {
|
|
|
50168
50190
|
);
|
|
50169
50191
|
}
|
|
50170
50192
|
function normalizeSideEffect(sideEffect, where) {
|
|
50171
|
-
const
|
|
50193
|
+
const path49 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
|
|
50172
50194
|
const arrays = ARRAY_OWNERS.flatMap((owner) => {
|
|
50173
50195
|
const target2 = owner ? sideEffect[owner] : sideEffect;
|
|
50174
50196
|
if (!target2 || typeof target2 !== "object") return [];
|
|
50175
|
-
return fillNulledArrays(target2, owner ? `${owner}.` : "",
|
|
50197
|
+
return fillNulledArrays(target2, owner ? `${owner}.` : "", path49);
|
|
50176
50198
|
});
|
|
50177
|
-
return [...dropUnsetOptionals(sideEffect,
|
|
50199
|
+
return [...dropUnsetOptionals(sideEffect, path49), ...arrays, ...tidyEmailRecipients(sideEffect, path49)];
|
|
50178
50200
|
}
|
|
50179
50201
|
function normalizeFlowTree(tree) {
|
|
50180
50202
|
const changes = [];
|
|
@@ -51564,10 +51586,10 @@ async function stageOps(ops) {
|
|
|
51564
51586
|
handleError5(err);
|
|
51565
51587
|
}
|
|
51566
51588
|
}
|
|
51567
|
-
async function draftAction2(
|
|
51589
|
+
async function draftAction2(path49, body, chat) {
|
|
51568
51590
|
const chatId = resolveChatId(chat);
|
|
51569
51591
|
try {
|
|
51570
|
-
const data = await apiPost(
|
|
51592
|
+
const data = await apiPost(path49, { chatId, ...body });
|
|
51571
51593
|
writeJsonEnvelope({ ok: true, data });
|
|
51572
51594
|
return data;
|
|
51573
51595
|
} catch (err) {
|
|
@@ -54096,9 +54118,9 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
54096
54118
|
}
|
|
54097
54119
|
return readFile28(pathOrUrl);
|
|
54098
54120
|
}
|
|
54099
|
-
async function isDirectory(
|
|
54121
|
+
async function isDirectory(path49) {
|
|
54100
54122
|
try {
|
|
54101
|
-
const s = await stat7(
|
|
54123
|
+
const s = await stat7(path49);
|
|
54102
54124
|
return s.isDirectory();
|
|
54103
54125
|
} catch {
|
|
54104
54126
|
return false;
|
|
@@ -54526,13 +54548,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
|
|
|
54526
54548
|
}
|
|
54527
54549
|
function disambiguate(paths) {
|
|
54528
54550
|
const taken = /* @__PURE__ */ new Set();
|
|
54529
|
-
return paths.map((
|
|
54530
|
-
if (!taken.has(
|
|
54531
|
-
taken.add(
|
|
54532
|
-
return
|
|
54551
|
+
return paths.map((path49) => {
|
|
54552
|
+
if (!taken.has(path49)) {
|
|
54553
|
+
taken.add(path49);
|
|
54554
|
+
return path49;
|
|
54533
54555
|
}
|
|
54534
|
-
const ext = extname3(
|
|
54535
|
-
const stem =
|
|
54556
|
+
const ext = extname3(path49);
|
|
54557
|
+
const stem = path49.slice(0, path49.length - ext.length);
|
|
54536
54558
|
let n = 2;
|
|
54537
54559
|
while (taken.has(`${stem}-${n}${ext}`)) n += 1;
|
|
54538
54560
|
const unique = `${stem}-${n}${ext}`;
|
|
@@ -54658,10 +54680,10 @@ async function runDownloads(plan) {
|
|
|
54658
54680
|
const paths = disambiguate(fetched.map((item) => item.path));
|
|
54659
54681
|
const downloaded = [];
|
|
54660
54682
|
for (const [index, item] of fetched.entries()) {
|
|
54661
|
-
const
|
|
54683
|
+
const path49 = paths[index] ?? item.path;
|
|
54662
54684
|
try {
|
|
54663
|
-
await atomicWrite(
|
|
54664
|
-
downloaded.push({ input: item.input, output:
|
|
54685
|
+
await atomicWrite(path49, item.buffer);
|
|
54686
|
+
downloaded.push({ input: item.input, output: path49, bytes: item.buffer.length, contentType: item.contentType });
|
|
54665
54687
|
} catch (err) {
|
|
54666
54688
|
failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
|
|
54667
54689
|
}
|
|
@@ -62848,11 +62870,374 @@ Full guide: __tooling__/docs/tools/baker/mcp.md`
|
|
|
62848
62870
|
}
|
|
62849
62871
|
});
|
|
62850
62872
|
|
|
62873
|
+
// src/commands/media-sources/index.ts
|
|
62874
|
+
import { defineCommand as defineCommand189 } from "citty";
|
|
62875
|
+
|
|
62876
|
+
// ../api/src/media-sources.ts
|
|
62877
|
+
import { z as z51 } from "zod";
|
|
62878
|
+
var mediaSourcePlatformSchema = z51.enum([
|
|
62879
|
+
"instagram",
|
|
62880
|
+
"tiktok",
|
|
62881
|
+
"youtube",
|
|
62882
|
+
"linkedin",
|
|
62883
|
+
"facebook",
|
|
62884
|
+
"google_drive"
|
|
62885
|
+
]);
|
|
62886
|
+
var mediaSourceRefreshIntervalSchema = z51.enum(["never", "daily", "weekly", "monthly"]);
|
|
62887
|
+
var mediaSourceSyncStatusSchema = z51.enum(["idle", "fetching", "processing", "error"]);
|
|
62888
|
+
var mediaSourceHalfSchema = z51.object({
|
|
62889
|
+
sourceId: z51.string(),
|
|
62890
|
+
syncStatus: mediaSourceSyncStatusSchema,
|
|
62891
|
+
storedCount: z51.number().optional(),
|
|
62892
|
+
pendingItems: z51.number().optional(),
|
|
62893
|
+
failedItems: z51.number().optional(),
|
|
62894
|
+
lastSyncedAt: z51.number().optional(),
|
|
62895
|
+
errorMessage: z51.string().optional()
|
|
62896
|
+
});
|
|
62897
|
+
var mediaSourceSummarySchema = z51.object({
|
|
62898
|
+
key: z51.string(),
|
|
62899
|
+
platform: mediaSourcePlatformSchema,
|
|
62900
|
+
platformLabel: z51.string(),
|
|
62901
|
+
handle: z51.string(),
|
|
62902
|
+
label: z51.string(),
|
|
62903
|
+
profileUrl: z51.string(),
|
|
62904
|
+
profileImageUrl: z51.string().optional(),
|
|
62905
|
+
refreshInterval: mediaSourceRefreshIntervalSchema,
|
|
62906
|
+
/** Absent for a platform that feeds no images (YouTube). */
|
|
62907
|
+
images: mediaSourceHalfSchema.optional(),
|
|
62908
|
+
videos: mediaSourceHalfSchema.optional(),
|
|
62909
|
+
createdAt: z51.number()
|
|
62910
|
+
});
|
|
62911
|
+
var mediaSourceProfileSchema = z51.object({
|
|
62912
|
+
platform: mediaSourcePlatformSchema,
|
|
62913
|
+
handle: z51.string(),
|
|
62914
|
+
displayName: z51.string(),
|
|
62915
|
+
avatarUrl: z51.string(),
|
|
62916
|
+
bio: z51.string(),
|
|
62917
|
+
followers: z51.number().optional(),
|
|
62918
|
+
postCount: z51.number().optional(),
|
|
62919
|
+
isPrivate: z51.boolean(),
|
|
62920
|
+
profileUrl: z51.string(),
|
|
62921
|
+
channelId: z51.string().optional(),
|
|
62922
|
+
/** Google Drive: the account that shared the folder with Baker. Absent for a link-shared folder. */
|
|
62923
|
+
sharedBy: z51.string().optional()
|
|
62924
|
+
});
|
|
62925
|
+
var mediaSourcesAddRequestSchema = z51.object({
|
|
62926
|
+
/** A profile URL or a Drive folder link, or an @handle together with `platform`. */
|
|
62927
|
+
input: z51.string().trim().min(1, "Pass the account's profile URL or @handle"),
|
|
62928
|
+
/** Needed only when `input` is a bare handle; a URL names its own platform. */
|
|
62929
|
+
platform: mediaSourcePlatformSchema.optional(),
|
|
62930
|
+
/** Auto-sync cadence. Omitted = weekly, except a Drive folder, which checks daily. */
|
|
62931
|
+
every: mediaSourceRefreshIntervalSchema.optional()
|
|
62932
|
+
});
|
|
62933
|
+
var mediaSourceKeySchema = z51.string().trim().regex(/^(instagram|tiktok|youtube|linkedin|facebook|google_drive):.+$/, "Pass a source key like tiktok:nike");
|
|
62934
|
+
var mediaSourcesSyncRequestSchema = z51.object({ key: mediaSourceKeySchema });
|
|
62935
|
+
var mediaSourcesRemoveRequestSchema = z51.object({ key: mediaSourceKeySchema });
|
|
62936
|
+
var mediaSourcesScheduleRequestSchema = z51.object({
|
|
62937
|
+
key: mediaSourceKeySchema,
|
|
62938
|
+
every: mediaSourceRefreshIntervalSchema
|
|
62939
|
+
});
|
|
62940
|
+
|
|
62941
|
+
// src/commands/media-sources/add.ts
|
|
62942
|
+
import { defineCommand as defineCommand184 } from "citty";
|
|
62943
|
+
|
|
62944
|
+
// src/commands/media-sources/shared.ts
|
|
62945
|
+
function driveRefusalFix(input, code) {
|
|
62946
|
+
const isDrive = /drive\.google\.com/i.test(input);
|
|
62947
|
+
if (!isDrive || code !== "NOT_FOUND" && code !== "FORBIDDEN") return void 0;
|
|
62948
|
+
return "Only the user can give Baker a folder, so tell them how, then carry on with the rest of the task. The quickest way: in Baker, open Images (or Videos) \u2192 Add source \u2192 Google Drive \u2192 Choose a folder, which connects their Google Drive and shares the folder in one step \u2014 once they do, it is connected and there is nothing to run. For a folder someone else owns, relay the message as written; once they say it's shared, run the same command again.";
|
|
62949
|
+
}
|
|
62950
|
+
function reportError2(err, input) {
|
|
62951
|
+
if (err instanceof ApiError) {
|
|
62952
|
+
const fix = input ? driveRefusalFix(input, err.code) : void 0;
|
|
62953
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message, ...fix ? { fix } : {} } });
|
|
62954
|
+
process.exit(1);
|
|
62955
|
+
}
|
|
62956
|
+
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
62957
|
+
process.exit(1);
|
|
62958
|
+
}
|
|
62959
|
+
function halfState(half) {
|
|
62960
|
+
if (!half) return null;
|
|
62961
|
+
return {
|
|
62962
|
+
status: half.syncStatus === "fetching" || half.syncStatus === "processing" ? "importing" : half.syncStatus,
|
|
62963
|
+
stored: half.storedCount ?? 0,
|
|
62964
|
+
...half.pendingItems ? { pending: half.pendingItems } : {},
|
|
62965
|
+
...half.failedItems ? { failed: half.failedItems } : {},
|
|
62966
|
+
...half.lastSyncedAt ? { lastSyncedAt: new Date(half.lastSyncedAt).toISOString() } : {},
|
|
62967
|
+
...half.errorMessage ? { error: half.errorMessage } : {}
|
|
62968
|
+
};
|
|
62969
|
+
}
|
|
62970
|
+
function compactSource(source) {
|
|
62971
|
+
return {
|
|
62972
|
+
key: source.key,
|
|
62973
|
+
platform: source.platform,
|
|
62974
|
+
label: source.label,
|
|
62975
|
+
url: source.profileUrl,
|
|
62976
|
+
autoSync: source.refreshInterval,
|
|
62977
|
+
images: halfState(source.images),
|
|
62978
|
+
videos: halfState(source.videos)
|
|
62979
|
+
};
|
|
62980
|
+
}
|
|
62981
|
+
function isImporting(source) {
|
|
62982
|
+
return [source.images, source.videos].some(
|
|
62983
|
+
(half) => half?.syncStatus === "fetching" || half?.syncStatus === "processing"
|
|
62984
|
+
);
|
|
62985
|
+
}
|
|
62986
|
+
|
|
62987
|
+
// src/commands/media-sources/add.ts
|
|
62988
|
+
registerSchema({
|
|
62989
|
+
command: "media-sources.add",
|
|
62990
|
+
description: "Connect a public social account or a shared Google Drive folder as a source for the image and video libraries \u2014 Instagram, TikTok, YouTube (videos only), LinkedIn company pages, Facebook pages, Google Drive folders. A social account's recent posts (up to a year back) are imported; a Drive folder's images and videos, subfolders included, are imported and new files keep arriving automatically. Everything is described and made searchable in the background. Applies immediately and shows on the chat as an already-applied change. Adding a source that is already connected is a no-op.",
|
|
62991
|
+
args: {
|
|
62992
|
+
input: {
|
|
62993
|
+
type: "string",
|
|
62994
|
+
description: "Profile URL or Drive folder link (names its own platform), or @handle together with --platform",
|
|
62995
|
+
required: true
|
|
62996
|
+
},
|
|
62997
|
+
platform: {
|
|
62998
|
+
type: "string",
|
|
62999
|
+
description: `Needed only for a bare handle: ${mediaSourcePlatformSchema.options.join("|")}`,
|
|
63000
|
+
required: false
|
|
63001
|
+
},
|
|
63002
|
+
every: {
|
|
63003
|
+
type: "string",
|
|
63004
|
+
description: `Auto-sync cadence: ${mediaSourceRefreshIntervalSchema.options.join("|")} (default weekly; a Drive folder defaults to daily and also syncs on every change)`,
|
|
63005
|
+
required: false
|
|
63006
|
+
}
|
|
63007
|
+
}
|
|
63008
|
+
});
|
|
63009
|
+
var addCommand3 = defineCommand184({
|
|
63010
|
+
meta: {
|
|
63011
|
+
name: "add",
|
|
63012
|
+
description: "Connect a social account (Instagram, TikTok, YouTube, LinkedIn page, Facebook page) or a Google Drive folder as a media source. Start here with the profile URL or the folder link. A Drive folder must first be shared with Baker by someone on the team \u2014 if it isn't, the error says with which address.\n\nExamples:\n baker media-sources add https://www.tiktok.com/@acme\n baker media-sources add @acme --platform instagram --every daily\n baker media-sources add https://drive.google.com/drive/folders/1AbC\u2026"
|
|
63013
|
+
},
|
|
63014
|
+
args: {
|
|
63015
|
+
input: { type: "positional", description: "Profile URL, Drive folder link, or @handle", required: true },
|
|
63016
|
+
platform: {
|
|
63017
|
+
type: "string",
|
|
63018
|
+
description: "instagram|tiktok|youtube|linkedin|facebook|google_drive \u2014 only for a bare handle or folder id",
|
|
63019
|
+
required: false
|
|
63020
|
+
},
|
|
63021
|
+
every: { type: "string", description: "Auto-sync: never|daily|weekly|monthly", required: false }
|
|
63022
|
+
},
|
|
63023
|
+
run: async ({ args: args5 }) => {
|
|
63024
|
+
const parsed = mediaSourcesAddRequestSchema.safeParse({
|
|
63025
|
+
input: String(args5.input ?? ""),
|
|
63026
|
+
platform: args5.platform ? String(args5.platform).toLowerCase() : void 0,
|
|
63027
|
+
every: args5.every ? String(args5.every).toLowerCase() : void 0
|
|
63028
|
+
});
|
|
63029
|
+
if (!parsed.success) {
|
|
63030
|
+
const issue = parsed.error.issues[0];
|
|
63031
|
+
writeJson({
|
|
63032
|
+
ok: false,
|
|
63033
|
+
error: {
|
|
63034
|
+
code: "VALIDATION_ERROR",
|
|
63035
|
+
message: issue ? `${issue.path.join(".") || "input"}: ${issue.message}` : "Invalid request"
|
|
63036
|
+
}
|
|
63037
|
+
});
|
|
63038
|
+
process.exit(1);
|
|
63039
|
+
}
|
|
63040
|
+
try {
|
|
63041
|
+
const data = await apiPost("/api/media-sources/add", parsed.data, {
|
|
63042
|
+
timeoutMs: 12e4
|
|
63043
|
+
});
|
|
63044
|
+
const hints2 = [
|
|
63045
|
+
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.`
|
|
63046
|
+
];
|
|
63047
|
+
if (data.source.platform === "youtube") {
|
|
63048
|
+
hints2.push(
|
|
63049
|
+
"YouTube feeds the video library only, newest first, a batch per sync; videos over 20 minutes are skipped."
|
|
63050
|
+
);
|
|
63051
|
+
}
|
|
63052
|
+
if (data.source.platform === "google_drive") {
|
|
63053
|
+
hints2.push(
|
|
63054
|
+
"New files added to the folder (or its subfolders) are imported on their own within minutes; large originals are resized for the library, and the files in Drive stay untouched. A big folder imports in batches over the next hours."
|
|
63055
|
+
);
|
|
63056
|
+
}
|
|
63057
|
+
if (data.source.refreshInterval === "never") {
|
|
63058
|
+
hints2.push(
|
|
63059
|
+
`Auto-sync is off. If the user wants new posts to keep arriving: \`baker media-sources schedule ${data.source.key} --every weekly\`.`
|
|
63060
|
+
);
|
|
63061
|
+
}
|
|
63062
|
+
writeJson({
|
|
63063
|
+
ok: true,
|
|
63064
|
+
data: { created: data.created, source: compactSource(data.source), name: data.profile.displayName },
|
|
63065
|
+
hints: hints2
|
|
63066
|
+
});
|
|
63067
|
+
} catch (err) {
|
|
63068
|
+
reportError2(err, parsed.data.input);
|
|
63069
|
+
}
|
|
63070
|
+
}
|
|
63071
|
+
});
|
|
63072
|
+
|
|
63073
|
+
// src/commands/media-sources/list.ts
|
|
63074
|
+
import { defineCommand as defineCommand185 } from "citty";
|
|
63075
|
+
registerSchema({
|
|
63076
|
+
command: "media-sources.list",
|
|
63077
|
+
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.",
|
|
63078
|
+
args: {}
|
|
63079
|
+
});
|
|
63080
|
+
var listCommand17 = defineCommand185({
|
|
63081
|
+
meta: {
|
|
63082
|
+
name: "list",
|
|
63083
|
+
description: "List connected media sources (key, platform, import status, stored images/videos).\n\nExample: baker media-sources list"
|
|
63084
|
+
},
|
|
63085
|
+
args: {},
|
|
63086
|
+
run: async () => {
|
|
63087
|
+
try {
|
|
63088
|
+
const { sources } = await apiGet("/api/media-sources/list");
|
|
63089
|
+
const hints2 = [];
|
|
63090
|
+
if (sources.length === 0) {
|
|
63091
|
+
hints2.push(
|
|
63092
|
+
"No sources connected. Connect the brand's own accounts with `baker media-sources add <profile URL>` to fill the image and video libraries."
|
|
63093
|
+
);
|
|
63094
|
+
} else if (sources.some(isImporting)) {
|
|
63095
|
+
hints2.push("Some sources are still importing \u2014 their counts will grow over the next minutes.");
|
|
63096
|
+
}
|
|
63097
|
+
writeJson({ ok: true, data: sources.map(compactSource), hints: hints2.length > 0 ? hints2 : void 0 });
|
|
63098
|
+
} catch (err) {
|
|
63099
|
+
reportError2(err);
|
|
63100
|
+
}
|
|
63101
|
+
}
|
|
63102
|
+
});
|
|
63103
|
+
|
|
63104
|
+
// src/commands/media-sources/remove.ts
|
|
63105
|
+
import { defineCommand as defineCommand186 } from "citty";
|
|
63106
|
+
registerSchema({
|
|
63107
|
+
command: "media-sources.remove",
|
|
63108
|
+
description: "Disconnect a media source. Stops future imports; images and videos it already brought in stay in the library. Applies immediately.",
|
|
63109
|
+
args: { key: { type: "string", description: "Source key, e.g. tiktok:acme", required: true } }
|
|
63110
|
+
});
|
|
63111
|
+
var removeCommand6 = defineCommand186({
|
|
63112
|
+
meta: {
|
|
63113
|
+
name: "remove",
|
|
63114
|
+
description: "Disconnect a media source (already-imported media stays).\n\nExample: baker media-sources remove tiktok:acme"
|
|
63115
|
+
},
|
|
63116
|
+
args: { key: { type: "positional", description: "Source key, e.g. tiktok:acme", required: true } },
|
|
63117
|
+
run: async ({ args: args5 }) => {
|
|
63118
|
+
const parsed = mediaSourcesRemoveRequestSchema.safeParse({ key: String(args5.key ?? "") });
|
|
63119
|
+
if (!parsed.success) {
|
|
63120
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: parsed.error.issues[0]?.message ?? "" } });
|
|
63121
|
+
process.exit(1);
|
|
63122
|
+
}
|
|
63123
|
+
try {
|
|
63124
|
+
const data = await apiPost("/api/media-sources/remove", parsed.data);
|
|
63125
|
+
writeJson({ ok: true, data });
|
|
63126
|
+
} catch (err) {
|
|
63127
|
+
reportError2(err);
|
|
63128
|
+
}
|
|
63129
|
+
}
|
|
63130
|
+
});
|
|
63131
|
+
|
|
63132
|
+
// src/commands/media-sources/schedule.ts
|
|
63133
|
+
import { defineCommand as defineCommand187 } from "citty";
|
|
63134
|
+
registerSchema({
|
|
63135
|
+
command: "media-sources.schedule",
|
|
63136
|
+
description: "Set how often a connected source imports new posts on its own.",
|
|
63137
|
+
args: {
|
|
63138
|
+
key: { type: "string", description: "Source key, e.g. tiktok:acme", required: true },
|
|
63139
|
+
every: {
|
|
63140
|
+
type: "string",
|
|
63141
|
+
description: `Cadence: ${mediaSourceRefreshIntervalSchema.options.join("|")} (never = only on demand)`,
|
|
63142
|
+
required: true
|
|
63143
|
+
}
|
|
63144
|
+
}
|
|
63145
|
+
});
|
|
63146
|
+
var scheduleCommand = defineCommand187({
|
|
63147
|
+
meta: {
|
|
63148
|
+
name: "schedule",
|
|
63149
|
+
description: "Set a source's auto-sync cadence.\n\nExample: baker media-sources schedule tiktok:acme --every weekly"
|
|
63150
|
+
},
|
|
63151
|
+
args: {
|
|
63152
|
+
key: { type: "positional", description: "Source key, e.g. tiktok:acme", required: true },
|
|
63153
|
+
every: { type: "string", description: "never|daily|weekly|monthly", required: true }
|
|
63154
|
+
},
|
|
63155
|
+
run: async ({ args: args5 }) => {
|
|
63156
|
+
const parsed = mediaSourcesScheduleRequestSchema.safeParse({
|
|
63157
|
+
key: String(args5.key ?? ""),
|
|
63158
|
+
every: String(args5.every ?? "").toLowerCase()
|
|
63159
|
+
});
|
|
63160
|
+
if (!parsed.success) {
|
|
63161
|
+
const issue = parsed.error.issues[0];
|
|
63162
|
+
writeJson({
|
|
63163
|
+
ok: false,
|
|
63164
|
+
error: { code: "VALIDATION_ERROR", message: issue ? `${issue.path.join(".")}: ${issue.message}` : "" }
|
|
63165
|
+
});
|
|
63166
|
+
process.exit(1);
|
|
63167
|
+
}
|
|
63168
|
+
try {
|
|
63169
|
+
const data = await apiPost("/api/media-sources/schedule", parsed.data);
|
|
63170
|
+
writeJson({ ok: true, data: { ...data, autoSync: parsed.data.every } });
|
|
63171
|
+
} catch (err) {
|
|
63172
|
+
reportError2(err);
|
|
63173
|
+
}
|
|
63174
|
+
}
|
|
63175
|
+
});
|
|
63176
|
+
|
|
63177
|
+
// src/commands/media-sources/sync.ts
|
|
63178
|
+
import { defineCommand as defineCommand188 } from "citty";
|
|
63179
|
+
registerSchema({
|
|
63180
|
+
command: "media-sources.sync",
|
|
63181
|
+
description: "Import a connected source's new posts now. Runs in the background; only posts not yet in the library are fetched.",
|
|
63182
|
+
args: {
|
|
63183
|
+
key: { type: "string", description: "Source key from `media-sources list`, e.g. tiktok:acme", required: true }
|
|
63184
|
+
}
|
|
63185
|
+
});
|
|
63186
|
+
var syncCommand = defineCommand188({
|
|
63187
|
+
meta: {
|
|
63188
|
+
name: "sync",
|
|
63189
|
+
description: "Import a source's new posts now.\n\nExample: baker media-sources sync tiktok:acme"
|
|
63190
|
+
},
|
|
63191
|
+
args: { key: { type: "positional", description: "Source key, e.g. tiktok:acme", required: true } },
|
|
63192
|
+
run: async ({ args: args5 }) => {
|
|
63193
|
+
const parsed = mediaSourcesSyncRequestSchema.safeParse({ key: String(args5.key ?? "") });
|
|
63194
|
+
if (!parsed.success) {
|
|
63195
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: parsed.error.issues[0]?.message ?? "" } });
|
|
63196
|
+
process.exit(1);
|
|
63197
|
+
}
|
|
63198
|
+
try {
|
|
63199
|
+
const data = await apiPost("/api/media-sources/sync", parsed.data);
|
|
63200
|
+
writeJson({
|
|
63201
|
+
ok: true,
|
|
63202
|
+
data,
|
|
63203
|
+
hints: data.started ? void 0 : ["An import was already running for this source; nothing new was started."]
|
|
63204
|
+
});
|
|
63205
|
+
} catch (err) {
|
|
63206
|
+
reportError2(err);
|
|
63207
|
+
}
|
|
63208
|
+
}
|
|
63209
|
+
});
|
|
63210
|
+
|
|
63211
|
+
// src/commands/media-sources/index.ts
|
|
63212
|
+
var mediaSourcesCommand = defineCommand189({
|
|
63213
|
+
meta: {
|
|
63214
|
+
name: "media-sources",
|
|
63215
|
+
description: `Connect social accounts and shared Google Drive folders whose images and videos fill the libraries: Instagram, TikTok, YouTube (videos), LinkedIn company pages, Facebook pages, Google Drive folders. Subcommands: add, list, sync, schedule, remove.
|
|
63216
|
+
|
|
63217
|
+
Examples:
|
|
63218
|
+
baker media-sources add https://www.tiktok.com/@acme
|
|
63219
|
+
baker media-sources add @acme --platform instagram --every daily
|
|
63220
|
+
baker media-sources add https://drive.google.com/drive/folders/1AbC\u2026
|
|
63221
|
+
baker media-sources list
|
|
63222
|
+
baker media-sources sync youtube:acme
|
|
63223
|
+
baker media-sources schedule linkedin:acme --every monthly
|
|
63224
|
+
baker media-sources remove facebook:acme
|
|
63225
|
+
Full guide: __tooling__/docs/tools/baker/media-sources.md`
|
|
63226
|
+
},
|
|
63227
|
+
subCommands: {
|
|
63228
|
+
add: addCommand3,
|
|
63229
|
+
list: listCommand17,
|
|
63230
|
+
sync: syncCommand,
|
|
63231
|
+
schedule: scheduleCommand,
|
|
63232
|
+
remove: removeCommand6
|
|
63233
|
+
}
|
|
63234
|
+
});
|
|
63235
|
+
|
|
62851
63236
|
// src/commands/research/index.ts
|
|
62852
|
-
import { defineCommand as
|
|
63237
|
+
import { defineCommand as defineCommand202 } from "citty";
|
|
62853
63238
|
|
|
62854
63239
|
// src/commands/research/advertisers.ts
|
|
62855
|
-
import { defineCommand as
|
|
63240
|
+
import { defineCommand as defineCommand190 } from "citty";
|
|
62856
63241
|
|
|
62857
63242
|
// src/commands/research/hints.ts
|
|
62858
63243
|
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.';
|
|
@@ -63054,7 +63439,7 @@ var FIELDS3 = {
|
|
|
63054
63439
|
etv: "Estimated traffic value (USD)",
|
|
63055
63440
|
visibility: "SERP visibility score (0-1)"
|
|
63056
63441
|
};
|
|
63057
|
-
var advertisersCommand =
|
|
63442
|
+
var advertisersCommand = defineCommand190({
|
|
63058
63443
|
meta: {
|
|
63059
63444
|
name: "advertisers",
|
|
63060
63445
|
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).
|
|
@@ -63110,7 +63495,7 @@ Examples:
|
|
|
63110
63495
|
});
|
|
63111
63496
|
|
|
63112
63497
|
// src/commands/research/autocomplete.ts
|
|
63113
|
-
import { defineCommand as
|
|
63498
|
+
import { defineCommand as defineCommand191 } from "citty";
|
|
63114
63499
|
registerSchema({
|
|
63115
63500
|
command: "research.autocomplete",
|
|
63116
63501
|
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).",
|
|
@@ -63133,7 +63518,7 @@ registerSchema({
|
|
|
63133
63518
|
var FIELDS4 = {
|
|
63134
63519
|
suggestion: "Autocomplete suggestion from Google"
|
|
63135
63520
|
};
|
|
63136
|
-
var autocompleteCommand =
|
|
63521
|
+
var autocompleteCommand = defineCommand191({
|
|
63137
63522
|
meta: {
|
|
63138
63523
|
name: "autocomplete",
|
|
63139
63524
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -63188,7 +63573,7 @@ Examples:
|
|
|
63188
63573
|
});
|
|
63189
63574
|
|
|
63190
63575
|
// src/commands/research/countries.ts
|
|
63191
|
-
import { defineCommand as
|
|
63576
|
+
import { defineCommand as defineCommand192 } from "citty";
|
|
63192
63577
|
registerSchema({
|
|
63193
63578
|
command: "research.countries",
|
|
63194
63579
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -63245,7 +63630,7 @@ var FIELDS5 = {
|
|
|
63245
63630
|
code: "Country code to pass as --location",
|
|
63246
63631
|
name: "Country name"
|
|
63247
63632
|
};
|
|
63248
|
-
var countriesCommand =
|
|
63633
|
+
var countriesCommand = defineCommand192({
|
|
63249
63634
|
meta: {
|
|
63250
63635
|
name: "countries",
|
|
63251
63636
|
description: "List all supported country codes for --location flag."
|
|
@@ -63256,7 +63641,7 @@ var countriesCommand = defineCommand186({
|
|
|
63256
63641
|
});
|
|
63257
63642
|
|
|
63258
63643
|
// src/commands/research/fetch.ts
|
|
63259
|
-
import { defineCommand as
|
|
63644
|
+
import { defineCommand as defineCommand193 } from "citty";
|
|
63260
63645
|
var CONTENT_PREVIEW_CHARS = 2e4;
|
|
63261
63646
|
var TIMEOUT_MS = 18e4;
|
|
63262
63647
|
registerSchema({
|
|
@@ -63329,7 +63714,7 @@ function fetchFix(code) {
|
|
|
63329
63714
|
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."
|
|
63330
63715
|
};
|
|
63331
63716
|
}
|
|
63332
|
-
var fetchCommand =
|
|
63717
|
+
var fetchCommand = defineCommand193({
|
|
63333
63718
|
meta: {
|
|
63334
63719
|
name: "fetch",
|
|
63335
63720
|
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.
|
|
@@ -63406,7 +63791,7 @@ Examples:
|
|
|
63406
63791
|
});
|
|
63407
63792
|
|
|
63408
63793
|
// src/commands/research/intent.ts
|
|
63409
|
-
import { defineCommand as
|
|
63794
|
+
import { defineCommand as defineCommand194 } from "citty";
|
|
63410
63795
|
registerSchema({
|
|
63411
63796
|
command: "research.intent",
|
|
63412
63797
|
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.",
|
|
@@ -63429,7 +63814,7 @@ var FIELDS7 = {
|
|
|
63429
63814
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
63430
63815
|
probability: "Confidence score 0.0-1.0"
|
|
63431
63816
|
};
|
|
63432
|
-
var intentCommand =
|
|
63817
|
+
var intentCommand = defineCommand194({
|
|
63433
63818
|
meta: {
|
|
63434
63819
|
name: "intent",
|
|
63435
63820
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -63477,7 +63862,7 @@ Examples:
|
|
|
63477
63862
|
});
|
|
63478
63863
|
|
|
63479
63864
|
// src/commands/research/keyword-gap.ts
|
|
63480
|
-
import { defineCommand as
|
|
63865
|
+
import { defineCommand as defineCommand195 } from "citty";
|
|
63481
63866
|
registerSchema({
|
|
63482
63867
|
command: "research.keyword-gap",
|
|
63483
63868
|
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.",
|
|
@@ -63506,7 +63891,7 @@ var FIELDS8 = {
|
|
|
63506
63891
|
cpc: "Cost per click USD",
|
|
63507
63892
|
their_position: "Competitor's ranking position"
|
|
63508
63893
|
};
|
|
63509
|
-
var keywordGapCommand =
|
|
63894
|
+
var keywordGapCommand = defineCommand195({
|
|
63510
63895
|
meta: {
|
|
63511
63896
|
name: "keyword-gap",
|
|
63512
63897
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -63581,7 +63966,7 @@ Examples:
|
|
|
63581
63966
|
});
|
|
63582
63967
|
|
|
63583
63968
|
// src/commands/research/keyword-metrics.ts
|
|
63584
|
-
import { defineCommand as
|
|
63969
|
+
import { defineCommand as defineCommand196 } from "citty";
|
|
63585
63970
|
|
|
63586
63971
|
// src/commands/research/keyword-metrics-rows.ts
|
|
63587
63972
|
var KEYWORD_METRICS_SOURCE = "keyword_planner_estimate_via_dataforseo";
|
|
@@ -63661,7 +64046,7 @@ registerSchema({
|
|
|
63661
64046
|
"no-cache": { type: "boolean", description: "Skip server cache, hit API directly", required: false }
|
|
63662
64047
|
}
|
|
63663
64048
|
});
|
|
63664
|
-
var keywordMetricsCommand =
|
|
64049
|
+
var keywordMetricsCommand = defineCommand196({
|
|
63665
64050
|
meta: {
|
|
63666
64051
|
name: "keyword-metrics",
|
|
63667
64052
|
description: `Volume, CPC and competition for keywords you name. No domain required.
|
|
@@ -63743,7 +64128,7 @@ Examples:
|
|
|
63743
64128
|
});
|
|
63744
64129
|
|
|
63745
64130
|
// src/commands/research/keywords-for-site.ts
|
|
63746
|
-
import { defineCommand as
|
|
64131
|
+
import { defineCommand as defineCommand197 } from "citty";
|
|
63747
64132
|
registerSchema({
|
|
63748
64133
|
command: "research.keywords-for-site",
|
|
63749
64134
|
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.",
|
|
@@ -63776,7 +64161,7 @@ var FIELDS9 = {
|
|
|
63776
64161
|
competition: "LOW, MEDIUM, or HIGH",
|
|
63777
64162
|
competition_index: "Competition score 0-100"
|
|
63778
64163
|
};
|
|
63779
|
-
var keywordsForSiteCommand =
|
|
64164
|
+
var keywordsForSiteCommand = defineCommand197({
|
|
63780
64165
|
meta: {
|
|
63781
64166
|
name: "keywords-for-site",
|
|
63782
64167
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -63838,7 +64223,7 @@ Examples:
|
|
|
63838
64223
|
});
|
|
63839
64224
|
|
|
63840
64225
|
// src/commands/research/languages.ts
|
|
63841
|
-
import { defineCommand as
|
|
64226
|
+
import { defineCommand as defineCommand198 } from "citty";
|
|
63842
64227
|
registerSchema({
|
|
63843
64228
|
command: "research.languages",
|
|
63844
64229
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -63868,7 +64253,7 @@ var FIELDS10 = {
|
|
|
63868
64253
|
code: "Language code to pass as --language",
|
|
63869
64254
|
name: "Language name (also accepted by --language)"
|
|
63870
64255
|
};
|
|
63871
|
-
var languagesCommand2 =
|
|
64256
|
+
var languagesCommand2 = defineCommand198({
|
|
63872
64257
|
meta: {
|
|
63873
64258
|
name: "languages",
|
|
63874
64259
|
description: "List all supported language codes for --language flag."
|
|
@@ -63879,7 +64264,7 @@ var languagesCommand2 = defineCommand192({
|
|
|
63879
64264
|
});
|
|
63880
64265
|
|
|
63881
64266
|
// src/commands/research/lighthouse.ts
|
|
63882
|
-
import { defineCommand as
|
|
64267
|
+
import { defineCommand as defineCommand199 } from "citty";
|
|
63883
64268
|
registerSchema({
|
|
63884
64269
|
command: "research.lighthouse",
|
|
63885
64270
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -63898,7 +64283,7 @@ var FIELDS11 = {
|
|
|
63898
64283
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
63899
64284
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
63900
64285
|
};
|
|
63901
|
-
var lighthouseCommand =
|
|
64286
|
+
var lighthouseCommand = defineCommand199({
|
|
63902
64287
|
meta: {
|
|
63903
64288
|
name: "lighthouse",
|
|
63904
64289
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -63936,7 +64321,7 @@ Examples:
|
|
|
63936
64321
|
});
|
|
63937
64322
|
|
|
63938
64323
|
// src/commands/research/relevant-pages.ts
|
|
63939
|
-
import { defineCommand as
|
|
64324
|
+
import { defineCommand as defineCommand200 } from "citty";
|
|
63940
64325
|
registerSchema({
|
|
63941
64326
|
command: "research.relevant-pages",
|
|
63942
64327
|
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).",
|
|
@@ -63962,7 +64347,7 @@ var FIELDS12 = {
|
|
|
63962
64347
|
keywords: "Total organic keywords the page ranks for",
|
|
63963
64348
|
top_10: "Keywords in positions 1-10"
|
|
63964
64349
|
};
|
|
63965
|
-
var relevantPagesCommand =
|
|
64350
|
+
var relevantPagesCommand = defineCommand200({
|
|
63966
64351
|
meta: {
|
|
63967
64352
|
name: "relevant-pages",
|
|
63968
64353
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -64009,7 +64394,7 @@ Examples:
|
|
|
64009
64394
|
});
|
|
64010
64395
|
|
|
64011
64396
|
// src/commands/research/web.ts
|
|
64012
|
-
import { defineCommand as
|
|
64397
|
+
import { defineCommand as defineCommand201 } from "citty";
|
|
64013
64398
|
registerSchema({
|
|
64014
64399
|
command: "research.web",
|
|
64015
64400
|
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).",
|
|
@@ -64060,7 +64445,7 @@ async function runDeepResearch(question) {
|
|
|
64060
64445
|
}
|
|
64061
64446
|
throw new Error("Deep research timed out");
|
|
64062
64447
|
}
|
|
64063
|
-
var webCommand =
|
|
64448
|
+
var webCommand = defineCommand201({
|
|
64064
64449
|
meta: {
|
|
64065
64450
|
name: "web",
|
|
64066
64451
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -64122,7 +64507,7 @@ Examples:
|
|
|
64122
64507
|
});
|
|
64123
64508
|
|
|
64124
64509
|
// src/commands/research/index.ts
|
|
64125
|
-
var researchCommand =
|
|
64510
|
+
var researchCommand = defineCommand202({
|
|
64126
64511
|
meta: {
|
|
64127
64512
|
name: "research",
|
|
64128
64513
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -64169,10 +64554,10 @@ Full guide: __tooling__/docs/tools/baker/research.md`
|
|
|
64169
64554
|
});
|
|
64170
64555
|
|
|
64171
64556
|
// src/commands/scheduled-agents/index.ts
|
|
64172
|
-
import { defineCommand as
|
|
64557
|
+
import { defineCommand as defineCommand213 } from "citty";
|
|
64173
64558
|
|
|
64174
64559
|
// src/commands/scheduled-agents/create.ts
|
|
64175
|
-
import { defineCommand as
|
|
64560
|
+
import { defineCommand as defineCommand203 } from "citty";
|
|
64176
64561
|
|
|
64177
64562
|
// src/commands/scheduled-agents/shared.ts
|
|
64178
64563
|
var TEMP_SCHEDULED_AGENT_PREFIX = "temp_agent_";
|
|
@@ -64539,7 +64924,7 @@ registerSchema({
|
|
|
64539
64924
|
}
|
|
64540
64925
|
}
|
|
64541
64926
|
});
|
|
64542
|
-
var createCommand3 =
|
|
64927
|
+
var createCommand3 = defineCommand203({
|
|
64543
64928
|
meta: {
|
|
64544
64929
|
name: "create",
|
|
64545
64930
|
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'
|
|
@@ -64596,7 +64981,7 @@ var createCommand3 = defineCommand197({
|
|
|
64596
64981
|
});
|
|
64597
64982
|
|
|
64598
64983
|
// src/commands/scheduled-agents/delete.ts
|
|
64599
|
-
import { defineCommand as
|
|
64984
|
+
import { defineCommand as defineCommand204 } from "citty";
|
|
64600
64985
|
registerSchema({
|
|
64601
64986
|
command: "scheduled-agents.delete",
|
|
64602
64987
|
description: "Stage deletion of a published scheduled agent, or cancel one this chat staged (temp_agent_*).",
|
|
@@ -64604,7 +64989,7 @@ registerSchema({
|
|
|
64604
64989
|
id: { type: "string", description: "Published scheduled agent ID or temp_agent_* draft ID", required: true }
|
|
64605
64990
|
}
|
|
64606
64991
|
});
|
|
64607
|
-
var deleteCommand3 =
|
|
64992
|
+
var deleteCommand3 = defineCommand204({
|
|
64608
64993
|
meta: {
|
|
64609
64994
|
name: "delete",
|
|
64610
64995
|
description: "Stage a scheduled agent deletion. Example: baker scheduled-agents delete <id-or-temp_agent_id>"
|
|
@@ -64633,7 +65018,7 @@ var deleteCommand3 = defineCommand198({
|
|
|
64633
65018
|
});
|
|
64634
65019
|
|
|
64635
65020
|
// src/commands/scheduled-agents/get.ts
|
|
64636
|
-
import { defineCommand as
|
|
65021
|
+
import { defineCommand as defineCommand205 } from "citty";
|
|
64637
65022
|
registerSchema({
|
|
64638
65023
|
command: "scheduled-agents.get",
|
|
64639
65024
|
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.",
|
|
@@ -64642,7 +65027,7 @@ registerSchema({
|
|
|
64642
65027
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
64643
65028
|
}
|
|
64644
65029
|
});
|
|
64645
|
-
var getCommand4 =
|
|
65030
|
+
var getCommand4 = defineCommand205({
|
|
64646
65031
|
meta: {
|
|
64647
65032
|
name: "get",
|
|
64648
65033
|
description: "Get a scheduled agent. Example: baker scheduled-agents get <id-or-temp_agent_id>"
|
|
@@ -64681,7 +65066,7 @@ var getCommand4 = defineCommand199({
|
|
|
64681
65066
|
});
|
|
64682
65067
|
|
|
64683
65068
|
// src/commands/scheduled-agents/list.ts
|
|
64684
|
-
import { defineCommand as
|
|
65069
|
+
import { defineCommand as defineCommand206 } from "citty";
|
|
64685
65070
|
var FULL_DESCRIPTION = "Return every item and staged change as stored, briefs included (tens of KB). Prefer `get <id>` for one item.";
|
|
64686
65071
|
registerSchema({
|
|
64687
65072
|
command: "scheduled-agents.list",
|
|
@@ -64691,7 +65076,7 @@ registerSchema({
|
|
|
64691
65076
|
full: { type: "boolean", description: FULL_DESCRIPTION, required: false }
|
|
64692
65077
|
}
|
|
64693
65078
|
});
|
|
64694
|
-
var
|
|
65079
|
+
var listCommand18 = defineCommand206({
|
|
64695
65080
|
meta: {
|
|
64696
65081
|
name: "list",
|
|
64697
65082
|
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."
|
|
@@ -64717,7 +65102,7 @@ var listCommand17 = defineCommand200({
|
|
|
64717
65102
|
});
|
|
64718
65103
|
|
|
64719
65104
|
// src/commands/scheduled-agents/run.ts
|
|
64720
|
-
import { defineCommand as
|
|
65105
|
+
import { defineCommand as defineCommand207 } from "citty";
|
|
64721
65106
|
registerSchema({
|
|
64722
65107
|
command: "scheduled-agents.run",
|
|
64723
65108
|
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.",
|
|
@@ -64725,7 +65110,7 @@ registerSchema({
|
|
|
64725
65110
|
id: { type: "string", description: "Published scheduled agent ID", required: true }
|
|
64726
65111
|
}
|
|
64727
65112
|
});
|
|
64728
|
-
var runCommand2 =
|
|
65113
|
+
var runCommand2 = defineCommand207({
|
|
64729
65114
|
meta: {
|
|
64730
65115
|
name: "run",
|
|
64731
65116
|
description: "Run a published scheduled agent now. Example: baker scheduled-agents run <id>"
|
|
@@ -64757,7 +65142,7 @@ var runCommand2 = defineCommand201({
|
|
|
64757
65142
|
});
|
|
64758
65143
|
|
|
64759
65144
|
// src/commands/scheduled-agents/targets.ts
|
|
64760
|
-
import { defineCommand as
|
|
65145
|
+
import { defineCommand as defineCommand208 } from "citty";
|
|
64761
65146
|
var ARGS2 = {
|
|
64762
65147
|
trigger: {
|
|
64763
65148
|
type: "string",
|
|
@@ -64791,7 +65176,7 @@ registerSchema({
|
|
|
64791
65176
|
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.",
|
|
64792
65177
|
args: ARGS2
|
|
64793
65178
|
});
|
|
64794
|
-
var targetsCommand =
|
|
65179
|
+
var targetsCommand = defineCommand208({
|
|
64795
65180
|
meta: {
|
|
64796
65181
|
name: "targets",
|
|
64797
65182
|
description: `What a trigger can be pointed at \u2014 so "when a Task is picked up" becomes "when THIS Task is picked up".
|
|
@@ -64834,7 +65219,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
64834
65219
|
// src/commands/scheduled-agents/templates.ts
|
|
64835
65220
|
import { readFile as readFile32 } from "fs/promises";
|
|
64836
65221
|
import path46 from "path";
|
|
64837
|
-
import { defineCommand as
|
|
65222
|
+
import { defineCommand as defineCommand209 } from "citty";
|
|
64838
65223
|
registerSchema({
|
|
64839
65224
|
command: "scheduled-agents.templates",
|
|
64840
65225
|
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.",
|
|
@@ -64889,7 +65274,7 @@ registerSchema({
|
|
|
64889
65274
|
}
|
|
64890
65275
|
}
|
|
64891
65276
|
});
|
|
64892
|
-
var templatesCommand =
|
|
65277
|
+
var templatesCommand = defineCommand209({
|
|
64893
65278
|
meta: {
|
|
64894
65279
|
name: "templates",
|
|
64895
65280
|
description: `The recipes this company can run \u2014 Baker's own plus theirs, with what each one produces.
|
|
@@ -64985,7 +65370,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
64985
65370
|
});
|
|
64986
65371
|
|
|
64987
65372
|
// src/commands/scheduled-agents/triggers.ts
|
|
64988
|
-
import { defineCommand as
|
|
65373
|
+
import { defineCommand as defineCommand210 } from "citty";
|
|
64989
65374
|
var ARGS3 = {
|
|
64990
65375
|
trigger: {
|
|
64991
65376
|
type: "string",
|
|
@@ -65071,7 +65456,7 @@ function shapeTriggerCatalog(response, filter) {
|
|
|
65071
65456
|
}
|
|
65072
65457
|
return { ok: true, data: { groups, reacting: catalog.reacting } };
|
|
65073
65458
|
}
|
|
65074
|
-
var triggersCommand2 =
|
|
65459
|
+
var triggersCommand2 = defineCommand210({
|
|
65075
65460
|
meta: {
|
|
65076
65461
|
name: "triggers",
|
|
65077
65462
|
description: `Everything that can start a scheduled agent.
|
|
@@ -65101,7 +65486,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
65101
65486
|
});
|
|
65102
65487
|
|
|
65103
65488
|
// src/commands/scheduled-agents/unstage.ts
|
|
65104
|
-
import { defineCommand as
|
|
65489
|
+
import { defineCommand as defineCommand211 } from "citty";
|
|
65105
65490
|
registerSchema({
|
|
65106
65491
|
command: "scheduled-agents.unstage",
|
|
65107
65492
|
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.",
|
|
@@ -65127,7 +65512,7 @@ function unstageBody(args5, chatId) {
|
|
|
65127
65512
|
}
|
|
65128
65513
|
return { chatId, ref: args5.ref, index };
|
|
65129
65514
|
}
|
|
65130
|
-
var unstageCommand =
|
|
65515
|
+
var unstageCommand = defineCommand211({
|
|
65131
65516
|
meta: {
|
|
65132
65517
|
name: "unstage",
|
|
65133
65518
|
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"
|
|
@@ -65158,7 +65543,7 @@ var unstageCommand = defineCommand205({
|
|
|
65158
65543
|
});
|
|
65159
65544
|
|
|
65160
65545
|
// src/commands/scheduled-agents/update.ts
|
|
65161
|
-
import { defineCommand as
|
|
65546
|
+
import { defineCommand as defineCommand212 } from "citty";
|
|
65162
65547
|
registerSchema({
|
|
65163
65548
|
command: "scheduled-agents.update",
|
|
65164
65549
|
description: "Stage an update to a published scheduled agent, or to one this chat staged (temp_agent_*).",
|
|
@@ -65185,7 +65570,7 @@ registerSchema({
|
|
|
65185
65570
|
enabled: { type: "string", description: "Replacement enabled state", required: false, enum: ["true", "false"] }
|
|
65186
65571
|
}
|
|
65187
65572
|
});
|
|
65188
|
-
var updateCommand4 =
|
|
65573
|
+
var updateCommand4 = defineCommand212({
|
|
65189
65574
|
meta: {
|
|
65190
65575
|
name: "update",
|
|
65191
65576
|
description: "Stage a scheduled agent update. Examples: baker scheduled-agents update <id> --enabled false | baker scheduled-agents update <id> --trigger form.submitted --form quote"
|
|
@@ -65256,7 +65641,7 @@ var updateCommand4 = defineCommand206({
|
|
|
65256
65641
|
});
|
|
65257
65642
|
|
|
65258
65643
|
// src/commands/scheduled-agents/index.ts
|
|
65259
|
-
var scheduledAgentsCommand =
|
|
65644
|
+
var scheduledAgentsCommand = defineCommand213({
|
|
65260
65645
|
meta: {
|
|
65261
65646
|
name: "scheduled-agents",
|
|
65262
65647
|
description: `Manage Scheduled agents. Subcommands: list, get, triggers, targets, create, update, delete, unstage, run, templates.
|
|
@@ -65285,7 +65670,7 @@ Examples:
|
|
|
65285
65670
|
Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
65286
65671
|
},
|
|
65287
65672
|
subCommands: {
|
|
65288
|
-
list:
|
|
65673
|
+
list: listCommand18,
|
|
65289
65674
|
get: getCommand4,
|
|
65290
65675
|
triggers: triggersCommand2,
|
|
65291
65676
|
targets: targetsCommand,
|
|
@@ -65299,14 +65684,14 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
65299
65684
|
});
|
|
65300
65685
|
|
|
65301
65686
|
// src/commands/schema.ts
|
|
65302
|
-
import { defineCommand as
|
|
65687
|
+
import { defineCommand as defineCommand214 } from "citty";
|
|
65303
65688
|
function narrowToFamily(commandName, available) {
|
|
65304
65689
|
const segments = commandName.split(".");
|
|
65305
65690
|
const prefix = segments[0] === "ads" && segments[1] ? `ads.${segments[1]}.` : `${segments[0]}.`;
|
|
65306
65691
|
const siblings = available.filter((name) => name.startsWith(prefix));
|
|
65307
65692
|
return siblings.length > 0 ? siblings : available;
|
|
65308
65693
|
}
|
|
65309
|
-
var schemaCommand2 =
|
|
65694
|
+
var schemaCommand2 = defineCommand214({
|
|
65310
65695
|
meta: {
|
|
65311
65696
|
name: "schema",
|
|
65312
65697
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images search (or images.search)"
|
|
@@ -65351,10 +65736,10 @@ var schemaCommand2 = defineCommand208({
|
|
|
65351
65736
|
});
|
|
65352
65737
|
|
|
65353
65738
|
// src/commands/studio/index.ts
|
|
65354
|
-
import { defineCommand as
|
|
65739
|
+
import { defineCommand as defineCommand223 } from "citty";
|
|
65355
65740
|
|
|
65356
65741
|
// src/commands/studio/animate.ts
|
|
65357
|
-
import { defineCommand as
|
|
65742
|
+
import { defineCommand as defineCommand215 } from "citty";
|
|
65358
65743
|
|
|
65359
65744
|
// src/commands/studio/spokenPace.ts
|
|
65360
65745
|
var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
|
|
@@ -65580,7 +65965,7 @@ function parseImageRefs(spec) {
|
|
|
65580
65965
|
}
|
|
65581
65966
|
var defaultDeps = {
|
|
65582
65967
|
ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
|
|
65583
|
-
upload: (
|
|
65968
|
+
upload: (path49) => uploadLocalImage({ file: path49, contentType: detectImageContentType(path49), source: "uploaded" })
|
|
65584
65969
|
};
|
|
65585
65970
|
async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
65586
65971
|
const refs = parseImageRefs(spec);
|
|
@@ -65600,10 +65985,10 @@ async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
|
65600
65985
|
}
|
|
65601
65986
|
return { imageIds, added };
|
|
65602
65987
|
}
|
|
65603
|
-
function uploadFailure(
|
|
65988
|
+
function uploadFailure(path49) {
|
|
65604
65989
|
return (error) => {
|
|
65605
65990
|
if (error instanceof ApiError) throw error;
|
|
65606
|
-
throw new ApiError("VALIDATION_ERROR", `Could not read "${
|
|
65991
|
+
throw new ApiError("VALIDATION_ERROR", `Could not read "${path49}" as an image.`);
|
|
65607
65992
|
};
|
|
65608
65993
|
}
|
|
65609
65994
|
|
|
@@ -65867,7 +66252,7 @@ async function adByHandHintFor(body) {
|
|
|
65867
66252
|
return null;
|
|
65868
66253
|
}
|
|
65869
66254
|
}
|
|
65870
|
-
var animateCommand =
|
|
66255
|
+
var animateCommand = defineCommand215({
|
|
65871
66256
|
meta: {
|
|
65872
66257
|
name: "animate",
|
|
65873
66258
|
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"
|
|
@@ -65992,7 +66377,7 @@ var animateCommand = defineCommand209({
|
|
|
65992
66377
|
});
|
|
65993
66378
|
|
|
65994
66379
|
// src/commands/studio/generate.ts
|
|
65995
|
-
import { defineCommand as
|
|
66380
|
+
import { defineCommand as defineCommand216 } from "citty";
|
|
65996
66381
|
var MODEL_LIST2 = IMAGE_MODEL_IDS;
|
|
65997
66382
|
var DEFAULT_MAX_WAIT_MS2 = 24e4;
|
|
65998
66383
|
registerSchema({
|
|
@@ -66128,7 +66513,7 @@ function buildGenerateBody(args5, prompt) {
|
|
|
66128
66513
|
}
|
|
66129
66514
|
return body;
|
|
66130
66515
|
}
|
|
66131
|
-
var generateCommand =
|
|
66516
|
+
var generateCommand = defineCommand216({
|
|
66132
66517
|
meta: {
|
|
66133
66518
|
name: "generate",
|
|
66134
66519
|
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]]'"
|
|
@@ -66211,7 +66596,7 @@ var generateCommand = defineCommand210({
|
|
|
66211
66596
|
});
|
|
66212
66597
|
|
|
66213
66598
|
// src/commands/studio/get.ts
|
|
66214
|
-
import { defineCommand as
|
|
66599
|
+
import { defineCommand as defineCommand217 } from "citty";
|
|
66215
66600
|
registerSchema({
|
|
66216
66601
|
command: "studio.get",
|
|
66217
66602
|
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.",
|
|
@@ -66220,7 +66605,7 @@ registerSchema({
|
|
|
66220
66605
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
66221
66606
|
}
|
|
66222
66607
|
});
|
|
66223
|
-
var getCommand5 =
|
|
66608
|
+
var getCommand5 = defineCommand217({
|
|
66224
66609
|
meta: {
|
|
66225
66610
|
name: "get",
|
|
66226
66611
|
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"
|
|
@@ -66249,7 +66634,7 @@ var getCommand5 = defineCommand211({
|
|
|
66249
66634
|
});
|
|
66250
66635
|
|
|
66251
66636
|
// src/commands/studio/improve.ts
|
|
66252
|
-
import { defineCommand as
|
|
66637
|
+
import { defineCommand as defineCommand218 } from "citty";
|
|
66253
66638
|
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.";
|
|
66254
66639
|
registerSchema({
|
|
66255
66640
|
command: "studio.improve",
|
|
@@ -66274,7 +66659,7 @@ registerSchema({
|
|
|
66274
66659
|
}
|
|
66275
66660
|
}
|
|
66276
66661
|
});
|
|
66277
|
-
var improveCommand =
|
|
66662
|
+
var improveCommand = defineCommand218({
|
|
66278
66663
|
meta: {
|
|
66279
66664
|
name: "improve",
|
|
66280
66665
|
description: `${DESCRIPTION2}
|
|
@@ -66318,7 +66703,7 @@ Examples:
|
|
|
66318
66703
|
});
|
|
66319
66704
|
|
|
66320
66705
|
// src/commands/studio/keep.ts
|
|
66321
|
-
import { defineCommand as
|
|
66706
|
+
import { defineCommand as defineCommand219 } from "citty";
|
|
66322
66707
|
registerSchema({
|
|
66323
66708
|
command: "studio.keep",
|
|
66324
66709
|
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.",
|
|
@@ -66328,7 +66713,7 @@ registerSchema({
|
|
|
66328
66713
|
undo: { type: "boolean", description: "Un-star an image, or take a kept clip back out", required: false }
|
|
66329
66714
|
}
|
|
66330
66715
|
});
|
|
66331
|
-
var keepCommand =
|
|
66716
|
+
var keepCommand = defineCommand219({
|
|
66332
66717
|
meta: {
|
|
66333
66718
|
name: "keep",
|
|
66334
66719
|
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"
|
|
@@ -66379,7 +66764,7 @@ var keepCommand = defineCommand213({
|
|
|
66379
66764
|
});
|
|
66380
66765
|
|
|
66381
66766
|
// src/commands/studio/list.ts
|
|
66382
|
-
import { defineCommand as
|
|
66767
|
+
import { defineCommand as defineCommand220 } from "citty";
|
|
66383
66768
|
registerSchema({
|
|
66384
66769
|
command: "studio.list",
|
|
66385
66770
|
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.",
|
|
@@ -66390,7 +66775,7 @@ registerSchema({
|
|
|
66390
66775
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
66391
66776
|
}
|
|
66392
66777
|
});
|
|
66393
|
-
var
|
|
66778
|
+
var listCommand19 = defineCommand220({
|
|
66394
66779
|
meta: {
|
|
66395
66780
|
name: "list",
|
|
66396
66781
|
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"
|
|
@@ -66424,7 +66809,7 @@ var listCommand18 = defineCommand214({
|
|
|
66424
66809
|
});
|
|
66425
66810
|
|
|
66426
66811
|
// src/commands/studio/models.ts
|
|
66427
|
-
import { defineCommand as
|
|
66812
|
+
import { defineCommand as defineCommand221 } from "citty";
|
|
66428
66813
|
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.";
|
|
66429
66814
|
registerSchema({
|
|
66430
66815
|
command: "studio.models",
|
|
@@ -66511,7 +66896,7 @@ function buildModelCards(kind, model) {
|
|
|
66511
66896
|
const selected = model ? ids.filter((id) => id === model) : ids;
|
|
66512
66897
|
return selected.map((id) => build(id));
|
|
66513
66898
|
}
|
|
66514
|
-
var modelsCommand =
|
|
66899
|
+
var modelsCommand = defineCommand221({
|
|
66515
66900
|
meta: {
|
|
66516
66901
|
name: "models",
|
|
66517
66902
|
description: `${DESCRIPTION3}
|
|
@@ -66558,13 +66943,13 @@ Examples:
|
|
|
66558
66943
|
});
|
|
66559
66944
|
|
|
66560
66945
|
// src/commands/studio/skills.ts
|
|
66561
|
-
import { defineCommand as
|
|
66946
|
+
import { defineCommand as defineCommand222 } from "citty";
|
|
66562
66947
|
registerSchema({
|
|
66563
66948
|
command: "studio.skills",
|
|
66564
66949
|
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.",
|
|
66565
66950
|
args: {}
|
|
66566
66951
|
});
|
|
66567
|
-
var skillsCommand =
|
|
66952
|
+
var skillsCommand = defineCommand222({
|
|
66568
66953
|
meta: {
|
|
66569
66954
|
name: "skills",
|
|
66570
66955
|
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"
|
|
@@ -66588,7 +66973,7 @@ var skillsCommand = defineCommand216({
|
|
|
66588
66973
|
});
|
|
66589
66974
|
|
|
66590
66975
|
// src/commands/studio/index.ts
|
|
66591
|
-
var studioCommand =
|
|
66976
|
+
var studioCommand = defineCommand223({
|
|
66592
66977
|
meta: {
|
|
66593
66978
|
name: "studio",
|
|
66594
66979
|
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.
|
|
@@ -66622,7 +67007,7 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
66622
67007
|
generate: generateCommand,
|
|
66623
67008
|
animate: animateCommand,
|
|
66624
67009
|
get: getCommand5,
|
|
66625
|
-
list:
|
|
67010
|
+
list: listCommand19,
|
|
66626
67011
|
keep: keepCommand,
|
|
66627
67012
|
models: modelsCommand,
|
|
66628
67013
|
skills: skillsCommand,
|
|
@@ -66631,10 +67016,10 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
66631
67016
|
});
|
|
66632
67017
|
|
|
66633
67018
|
// src/commands/tag-manager/index.ts
|
|
66634
|
-
import { defineCommand as
|
|
67019
|
+
import { defineCommand as defineCommand227 } from "citty";
|
|
66635
67020
|
|
|
66636
67021
|
// src/commands/tag-manager/draft.ts
|
|
66637
|
-
import { defineCommand as
|
|
67022
|
+
import { defineCommand as defineCommand224 } from "citty";
|
|
66638
67023
|
|
|
66639
67024
|
// src/commands/tag-manager/shared.ts
|
|
66640
67025
|
import { readFileSync as readFileSync21 } from "fs";
|
|
@@ -66701,10 +67086,10 @@ async function stageOp4(op) {
|
|
|
66701
67086
|
handleError8(err);
|
|
66702
67087
|
}
|
|
66703
67088
|
}
|
|
66704
|
-
async function draftAction3(
|
|
67089
|
+
async function draftAction3(path49, body, chat) {
|
|
66705
67090
|
const chatId = resolveChatId(chat);
|
|
66706
67091
|
try {
|
|
66707
|
-
const data = await apiPost(
|
|
67092
|
+
const data = await apiPost(path49, { chatId, ...body });
|
|
66708
67093
|
writeJsonEnvelope({ ok: true, data });
|
|
66709
67094
|
return data;
|
|
66710
67095
|
} catch (err) {
|
|
@@ -66757,13 +67142,13 @@ registerSchema({
|
|
|
66757
67142
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
66758
67143
|
}
|
|
66759
67144
|
});
|
|
66760
|
-
var draftCommand5 =
|
|
67145
|
+
var draftCommand5 = defineCommand224({
|
|
66761
67146
|
meta: {
|
|
66762
67147
|
name: "draft",
|
|
66763
67148
|
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."
|
|
66764
67149
|
},
|
|
66765
67150
|
subCommands: {
|
|
66766
|
-
list:
|
|
67151
|
+
list: defineCommand224({
|
|
66767
67152
|
meta: {
|
|
66768
67153
|
name: "list",
|
|
66769
67154
|
description: "Review everything staged on this chat (--json for the raw envelope)"
|
|
@@ -66776,7 +67161,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66776
67161
|
await draftList2(args5.json === true, args5.chat);
|
|
66777
67162
|
}
|
|
66778
67163
|
}),
|
|
66779
|
-
show:
|
|
67164
|
+
show: defineCommand224({
|
|
66780
67165
|
meta: {
|
|
66781
67166
|
name: "show",
|
|
66782
67167
|
description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
|
|
@@ -66793,7 +67178,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66793
67178
|
);
|
|
66794
67179
|
}
|
|
66795
67180
|
}),
|
|
66796
|
-
amend:
|
|
67181
|
+
amend: defineCommand224({
|
|
66797
67182
|
meta: {
|
|
66798
67183
|
name: "amend",
|
|
66799
67184
|
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."
|
|
@@ -66810,7 +67195,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66810
67195
|
});
|
|
66811
67196
|
}
|
|
66812
67197
|
}),
|
|
66813
|
-
remove:
|
|
67198
|
+
remove: defineCommand224({
|
|
66814
67199
|
meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
|
|
66815
67200
|
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
66816
67201
|
run: async ({ args: args5 }) => {
|
|
@@ -66819,7 +67204,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66819
67204
|
});
|
|
66820
67205
|
}
|
|
66821
67206
|
}),
|
|
66822
|
-
clear:
|
|
67207
|
+
clear: defineCommand224({
|
|
66823
67208
|
meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
|
|
66824
67209
|
run: async () => {
|
|
66825
67210
|
await draftAction3("/api/tag-manager/draft/clear", {});
|
|
@@ -66829,7 +67214,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66829
67214
|
});
|
|
66830
67215
|
|
|
66831
67216
|
// src/commands/tag-manager/read.ts
|
|
66832
|
-
import { defineCommand as
|
|
67217
|
+
import { defineCommand as defineCommand225 } from "citty";
|
|
66833
67218
|
registerSchema({
|
|
66834
67219
|
command: "tagManager.containers",
|
|
66835
67220
|
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.",
|
|
@@ -66870,7 +67255,7 @@ function containersHints(containers) {
|
|
|
66870
67255
|
}))
|
|
66871
67256
|
});
|
|
66872
67257
|
}
|
|
66873
|
-
var containersCommand =
|
|
67258
|
+
var containersCommand = defineCommand225({
|
|
66874
67259
|
meta: {
|
|
66875
67260
|
name: "containers",
|
|
66876
67261
|
description: `List Tag Manager containers reachable by this company's connection.
|
|
@@ -66887,7 +67272,7 @@ Start here:
|
|
|
66887
67272
|
}
|
|
66888
67273
|
}
|
|
66889
67274
|
});
|
|
66890
|
-
var readCommand =
|
|
67275
|
+
var readCommand = defineCommand225({
|
|
66891
67276
|
meta: {
|
|
66892
67277
|
name: "read",
|
|
66893
67278
|
description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
|
|
@@ -66929,7 +67314,7 @@ Examples:
|
|
|
66929
67314
|
});
|
|
66930
67315
|
|
|
66931
67316
|
// src/commands/tag-manager/write-commands.ts
|
|
66932
|
-
import { defineCommand as
|
|
67317
|
+
import { defineCommand as defineCommand226 } from "citty";
|
|
66933
67318
|
var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
|
|
66934
67319
|
var ENTITIES = [
|
|
66935
67320
|
{
|
|
@@ -66985,10 +67370,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
|
|
|
66985
67370
|
});
|
|
66986
67371
|
}
|
|
66987
67372
|
function entityCommand(entity, noun, example) {
|
|
66988
|
-
return
|
|
67373
|
+
return defineCommand226({
|
|
66989
67374
|
meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
|
|
66990
67375
|
subCommands: {
|
|
66991
|
-
create:
|
|
67376
|
+
create: defineCommand226({
|
|
66992
67377
|
meta: {
|
|
66993
67378
|
name: "create",
|
|
66994
67379
|
description: `Stage a new ${noun}
|
|
@@ -67010,7 +67395,7 @@ Examples:
|
|
|
67010
67395
|
});
|
|
67011
67396
|
}
|
|
67012
67397
|
}),
|
|
67013
|
-
update:
|
|
67398
|
+
update: defineCommand226({
|
|
67014
67399
|
meta: {
|
|
67015
67400
|
name: "update",
|
|
67016
67401
|
description: `Stage an update to an existing ${noun} (pass its id or path)`
|
|
@@ -67030,7 +67415,7 @@ Examples:
|
|
|
67030
67415
|
});
|
|
67031
67416
|
}
|
|
67032
67417
|
}),
|
|
67033
|
-
delete:
|
|
67418
|
+
delete: defineCommand226({
|
|
67034
67419
|
meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
|
|
67035
67420
|
args: {
|
|
67036
67421
|
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
@@ -67071,7 +67456,7 @@ function builtinTypes(args5) {
|
|
|
67071
67456
|
}
|
|
67072
67457
|
return raw.split(",").map((entry) => entry.trim());
|
|
67073
67458
|
}
|
|
67074
|
-
var builtinCommand =
|
|
67459
|
+
var builtinCommand = defineCommand226({
|
|
67075
67460
|
meta: {
|
|
67076
67461
|
name: "builtin",
|
|
67077
67462
|
description: `Enable or disable built-in variables
|
|
@@ -67081,7 +67466,7 @@ Examples:
|
|
|
67081
67466
|
baker tag-manager builtin disable --types formId`
|
|
67082
67467
|
},
|
|
67083
67468
|
subCommands: {
|
|
67084
|
-
enable:
|
|
67469
|
+
enable: defineCommand226({
|
|
67085
67470
|
meta: { name: "enable", description: "Stage enabling built-in variables" },
|
|
67086
67471
|
args: {
|
|
67087
67472
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -67095,7 +67480,7 @@ Examples:
|
|
|
67095
67480
|
});
|
|
67096
67481
|
}
|
|
67097
67482
|
}),
|
|
67098
|
-
disable:
|
|
67483
|
+
disable: defineCommand226({
|
|
67099
67484
|
meta: { name: "disable", description: "Stage disabling built-in variables" },
|
|
67100
67485
|
args: {
|
|
67101
67486
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -67113,7 +67498,7 @@ Examples:
|
|
|
67113
67498
|
});
|
|
67114
67499
|
|
|
67115
67500
|
// src/commands/tag-manager/index.ts
|
|
67116
|
-
var tagManagerCommand =
|
|
67501
|
+
var tagManagerCommand = defineCommand227({
|
|
67117
67502
|
meta: {
|
|
67118
67503
|
name: "tag-manager",
|
|
67119
67504
|
description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
|
|
@@ -67150,7 +67535,7 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
|
|
|
67150
67535
|
});
|
|
67151
67536
|
|
|
67152
67537
|
// src/commands/tags/index.ts
|
|
67153
|
-
import { defineCommand as
|
|
67538
|
+
import { defineCommand as defineCommand228 } from "citty";
|
|
67154
67539
|
|
|
67155
67540
|
// src/commands/tags/shared.ts
|
|
67156
67541
|
function failApi3(err) {
|
|
@@ -67230,7 +67615,7 @@ async function listTags(json) {
|
|
|
67230
67615
|
var listArgs12 = {
|
|
67231
67616
|
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
|
|
67232
67617
|
};
|
|
67233
|
-
var
|
|
67618
|
+
var listCommand20 = defineCommand228({
|
|
67234
67619
|
meta: {
|
|
67235
67620
|
name: "list",
|
|
67236
67621
|
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"
|
|
@@ -67249,7 +67634,7 @@ async function listDraft4(chat) {
|
|
|
67249
67634
|
failApi3(err);
|
|
67250
67635
|
}
|
|
67251
67636
|
}
|
|
67252
|
-
var draftCommand6 =
|
|
67637
|
+
var draftCommand6 = defineCommand228({
|
|
67253
67638
|
meta: {
|
|
67254
67639
|
name: "draft",
|
|
67255
67640
|
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."
|
|
@@ -67259,7 +67644,7 @@ var draftCommand6 = defineCommand222({
|
|
|
67259
67644
|
await listDraft4(args5.chat);
|
|
67260
67645
|
}
|
|
67261
67646
|
});
|
|
67262
|
-
var tagsCommand4 =
|
|
67647
|
+
var tagsCommand4 = defineCommand228({
|
|
67263
67648
|
meta: {
|
|
67264
67649
|
name: "tags",
|
|
67265
67650
|
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.
|
|
@@ -67276,7 +67661,7 @@ Examples:
|
|
|
67276
67661
|
Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
67277
67662
|
},
|
|
67278
67663
|
subCommands: {
|
|
67279
|
-
list:
|
|
67664
|
+
list: listCommand20,
|
|
67280
67665
|
draft: draftCommand6
|
|
67281
67666
|
},
|
|
67282
67667
|
// Bare `baker tags` lists the effective tags. `args` stays so citty knows this
|
|
@@ -67288,10 +67673,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
67288
67673
|
});
|
|
67289
67674
|
|
|
67290
67675
|
// src/commands/testimonials/index.ts
|
|
67291
|
-
import { defineCommand as
|
|
67676
|
+
import { defineCommand as defineCommand232 } from "citty";
|
|
67292
67677
|
|
|
67293
67678
|
// src/commands/testimonials/get.ts
|
|
67294
|
-
import { defineCommand as
|
|
67679
|
+
import { defineCommand as defineCommand229 } from "citty";
|
|
67295
67680
|
registerSchema({
|
|
67296
67681
|
command: "testimonials.get",
|
|
67297
67682
|
description: "Get a single testimonial by ID",
|
|
@@ -67299,7 +67684,7 @@ registerSchema({
|
|
|
67299
67684
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
67300
67685
|
}
|
|
67301
67686
|
});
|
|
67302
|
-
var getCommand6 =
|
|
67687
|
+
var getCommand6 = defineCommand229({
|
|
67303
67688
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
67304
67689
|
args: {
|
|
67305
67690
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -67336,7 +67721,7 @@ var getCommand6 = defineCommand223({
|
|
|
67336
67721
|
});
|
|
67337
67722
|
|
|
67338
67723
|
// src/commands/testimonials/list.ts
|
|
67339
|
-
import { defineCommand as
|
|
67724
|
+
import { defineCommand as defineCommand230 } from "citty";
|
|
67340
67725
|
|
|
67341
67726
|
// src/commands/testimonials/emptyCorpusHints.ts
|
|
67342
67727
|
function resolveEmptyReason({
|
|
@@ -67493,7 +67878,7 @@ function buildListParams(args5) {
|
|
|
67493
67878
|
}
|
|
67494
67879
|
return params;
|
|
67495
67880
|
}
|
|
67496
|
-
var
|
|
67881
|
+
var listCommand21 = defineCommand230({
|
|
67497
67882
|
meta: {
|
|
67498
67883
|
name: "list",
|
|
67499
67884
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -67553,7 +67938,7 @@ var listCommand20 = defineCommand224({
|
|
|
67553
67938
|
});
|
|
67554
67939
|
|
|
67555
67940
|
// src/commands/testimonials/search.ts
|
|
67556
|
-
import { defineCommand as
|
|
67941
|
+
import { defineCommand as defineCommand231 } from "citty";
|
|
67557
67942
|
var FILTER_FLAGS2 = ["source", "rating-min", "rating-max", "status", "sentiment", "language", "tags"];
|
|
67558
67943
|
function languageBiasHint(results, requestedLanguage) {
|
|
67559
67944
|
if (requestedLanguage) {
|
|
@@ -67632,7 +68017,7 @@ function buildSearchRequest(query, args5) {
|
|
|
67632
68017
|
}
|
|
67633
68018
|
return body;
|
|
67634
68019
|
}
|
|
67635
|
-
var searchCommand3 =
|
|
68020
|
+
var searchCommand3 = defineCommand231({
|
|
67636
68021
|
meta: {
|
|
67637
68022
|
name: "search",
|
|
67638
68023
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -67696,7 +68081,7 @@ var searchCommand3 = defineCommand225({
|
|
|
67696
68081
|
var tagsCommand5 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
67697
68082
|
|
|
67698
68083
|
// src/commands/testimonials/index.ts
|
|
67699
|
-
var testimonialsCommand =
|
|
68084
|
+
var testimonialsCommand = defineCommand232({
|
|
67700
68085
|
meta: {
|
|
67701
68086
|
name: "testimonials",
|
|
67702
68087
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -67712,16 +68097,16 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
|
|
|
67712
68097
|
subCommands: {
|
|
67713
68098
|
get: getCommand6,
|
|
67714
68099
|
search: searchCommand3,
|
|
67715
|
-
list:
|
|
68100
|
+
list: listCommand21,
|
|
67716
68101
|
tags: tagsCommand5
|
|
67717
68102
|
}
|
|
67718
68103
|
});
|
|
67719
68104
|
|
|
67720
68105
|
// src/commands/videos/index.ts
|
|
67721
|
-
import { defineCommand as
|
|
68106
|
+
import { defineCommand as defineCommand241 } from "citty";
|
|
67722
68107
|
|
|
67723
68108
|
// src/commands/videos/delete.ts
|
|
67724
|
-
import { defineCommand as
|
|
68109
|
+
import { defineCommand as defineCommand233 } from "citty";
|
|
67725
68110
|
registerSchema({
|
|
67726
68111
|
command: "videos.delete",
|
|
67727
68112
|
description: "Delete a video by ID",
|
|
@@ -67735,7 +68120,7 @@ registerSchema({
|
|
|
67735
68120
|
}
|
|
67736
68121
|
}
|
|
67737
68122
|
});
|
|
67738
|
-
var deleteCommand4 =
|
|
68123
|
+
var deleteCommand4 = defineCommand233({
|
|
67739
68124
|
meta: {
|
|
67740
68125
|
name: "delete",
|
|
67741
68126
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -67776,7 +68161,7 @@ var deleteCommand4 = defineCommand227({
|
|
|
67776
68161
|
});
|
|
67777
68162
|
|
|
67778
68163
|
// src/commands/videos/describe.ts
|
|
67779
|
-
import { defineCommand as
|
|
68164
|
+
import { defineCommand as defineCommand234 } from "citty";
|
|
67780
68165
|
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.";
|
|
67781
68166
|
registerSchema({
|
|
67782
68167
|
command: "videos.describe",
|
|
@@ -67793,7 +68178,7 @@ registerSchema({
|
|
|
67793
68178
|
full: { type: "boolean", description: "Return the whole library row, not just what changed", required: false }
|
|
67794
68179
|
}
|
|
67795
68180
|
});
|
|
67796
|
-
var describeCommand2 =
|
|
68181
|
+
var describeCommand2 = defineCommand234({
|
|
67797
68182
|
meta: {
|
|
67798
68183
|
name: "describe",
|
|
67799
68184
|
description: `Correct what the library says a video is. Only the fields you pass change; the rest keep their current values.
|
|
@@ -67850,108 +68235,10 @@ Example: baker videos describe j571abc123 --description "Customer explaining how
|
|
|
67850
68235
|
}
|
|
67851
68236
|
});
|
|
67852
68237
|
|
|
67853
|
-
// src/commands/videos/
|
|
67854
|
-
import {
|
|
67855
|
-
registerSchema({
|
|
67856
|
-
command: "videos.get",
|
|
67857
|
-
description: "Get a single video by ID",
|
|
67858
|
-
args: {
|
|
67859
|
-
id: { type: "string", description: "Video ID", required: true }
|
|
67860
|
-
}
|
|
67861
|
-
});
|
|
67862
|
-
var getCommand7 = defineCommand229({
|
|
67863
|
-
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
67864
|
-
args: {
|
|
67865
|
-
id: { type: "positional", description: "Video ID", required: false },
|
|
67866
|
-
"video-id": { type: "string", description: "Video ID (alternative to positional)", required: false },
|
|
67867
|
-
output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
|
|
67868
|
-
fields: { type: "string", description: "Comma-separated field names to include", required: false },
|
|
67869
|
-
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
67870
|
-
},
|
|
67871
|
-
run: async ({ args: args5 }) => {
|
|
67872
|
-
try {
|
|
67873
|
-
const id = args5.id || args5["video-id"];
|
|
67874
|
-
if (!id) {
|
|
67875
|
-
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Video ID is required" } });
|
|
67876
|
-
process.exit(1);
|
|
67877
|
-
}
|
|
67878
|
-
validateConvexId(id);
|
|
67879
|
-
const data = await apiGet("/api/videos/get", { id });
|
|
67880
|
-
writeOutput(
|
|
67881
|
-
{ ok: true, data },
|
|
67882
|
-
args5.output || "json",
|
|
67883
|
-
args5.fields ? args5.fields.split(",") : void 0,
|
|
67884
|
-
args5.full,
|
|
67885
|
-
videoNormalizer
|
|
67886
|
-
);
|
|
67887
|
-
} catch (err) {
|
|
67888
|
-
if (err instanceof ApiError) {
|
|
67889
|
-
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
67890
|
-
process.exit(1);
|
|
67891
|
-
}
|
|
67892
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
67893
|
-
process.exit(1);
|
|
67894
|
-
}
|
|
67895
|
-
}
|
|
67896
|
-
});
|
|
67897
|
-
|
|
67898
|
-
// src/commands/videos/group.ts
|
|
67899
|
-
import { defineCommand as defineCommand230 } from "citty";
|
|
67900
|
-
registerSchema({
|
|
67901
|
-
command: "videos.group",
|
|
67902
|
-
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
67903
|
-
args: {
|
|
67904
|
-
id: { type: "string", description: "A video or image id \u2014 returns that asset's whole set", required: false },
|
|
67905
|
-
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
67906
|
-
}
|
|
67907
|
-
});
|
|
67908
|
-
var groupCommand2 = defineCommand230({
|
|
67909
|
-
meta: {
|
|
67910
|
-
name: "group",
|
|
67911
|
-
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>"
|
|
67912
|
-
},
|
|
67913
|
-
args: {
|
|
67914
|
-
id: { type: "positional", description: "A video or image id from the set", required: false },
|
|
67915
|
-
"group-key": { type: "string", description: "The set key, if you already have it", required: false }
|
|
67916
|
-
},
|
|
67917
|
-
run: async ({ args: args5 }) => {
|
|
67918
|
-
await runMediaGroupLookup({
|
|
67919
|
-
id: args5.id,
|
|
67920
|
-
groupKey: args5["group-key"],
|
|
67921
|
-
path: "/api/videos/group",
|
|
67922
|
-
idLabel: "a video or image id"
|
|
67923
|
-
});
|
|
67924
|
-
}
|
|
67925
|
-
});
|
|
67926
|
-
|
|
67927
|
-
// src/commands/videos/ingest.ts
|
|
67928
|
-
import { mkdtemp as mkdtemp3, rm as rm9, stat as stat11 } from "fs/promises";
|
|
67929
|
-
import { tmpdir as tmpdir4 } from "os";
|
|
68238
|
+
// src/commands/videos/fetch.ts
|
|
68239
|
+
import { mkdir as mkdir15 } from "fs/promises";
|
|
67930
68240
|
import path47 from "path";
|
|
67931
|
-
import { defineCommand as
|
|
67932
|
-
|
|
67933
|
-
// src/lib/streamUpload.ts
|
|
67934
|
-
import { createHash as createHash2 } from "crypto";
|
|
67935
|
-
import { createReadStream } from "fs";
|
|
67936
|
-
import { Readable } from "stream";
|
|
67937
|
-
import { pipeline } from "stream/promises";
|
|
67938
|
-
async function hashFile(filePath) {
|
|
67939
|
-
const hash = createHash2("sha256");
|
|
67940
|
-
await pipeline(createReadStream(filePath), hash);
|
|
67941
|
-
return hash.digest("hex");
|
|
67942
|
-
}
|
|
67943
|
-
async function putFileStreamed(args5) {
|
|
67944
|
-
const body = Readable.toWeb(createReadStream(args5.filePath));
|
|
67945
|
-
return await fetch(args5.putUrl, {
|
|
67946
|
-
method: "PUT",
|
|
67947
|
-
body,
|
|
67948
|
-
headers: {
|
|
67949
|
-
"Content-Type": args5.contentType,
|
|
67950
|
-
"Content-Length": String(args5.sizeBytes)
|
|
67951
|
-
},
|
|
67952
|
-
duplex: "half"
|
|
67953
|
-
});
|
|
67954
|
-
}
|
|
68241
|
+
import { defineCommand as defineCommand235 } from "citty";
|
|
67955
68242
|
|
|
67956
68243
|
// src/commands/videos/videoPlatforms.ts
|
|
67957
68244
|
var PLATFORM_DOMAINS = {
|
|
@@ -67960,6 +68247,7 @@ var PLATFORM_DOMAINS = {
|
|
|
67960
68247
|
tiktok: ["tiktok.com"],
|
|
67961
68248
|
twitter: ["twitter.com", "x.com", "vxtwitter.com", "fixvx.com"],
|
|
67962
68249
|
facebook: ["facebook.com", "fb.watch", "fb.com"],
|
|
68250
|
+
linkedin: ["linkedin.com", "lnkd.in"],
|
|
67963
68251
|
reddit: ["reddit.com", "redd.it"],
|
|
67964
68252
|
vimeo: ["vimeo.com"],
|
|
67965
68253
|
dailymotion: ["dailymotion.com", "dai.ly"],
|
|
@@ -68064,6 +68352,188 @@ function safePathname(rawUrl) {
|
|
|
68064
68352
|
}
|
|
68065
68353
|
}
|
|
68066
68354
|
|
|
68355
|
+
// src/commands/videos/fetch.ts
|
|
68356
|
+
registerSchema({
|
|
68357
|
+
command: "videos.fetch",
|
|
68358
|
+
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.",
|
|
68359
|
+
args: {
|
|
68360
|
+
url: { type: "string", description: "Video page URL", required: true },
|
|
68361
|
+
out: { type: "string", description: "Directory to write the file into (created if missing)", required: true },
|
|
68362
|
+
"max-seconds": {
|
|
68363
|
+
type: "string",
|
|
68364
|
+
description: `Refuse videos longer than this many seconds (default ${MAX_VIDEO_INGEST_SECONDS})`,
|
|
68365
|
+
required: false
|
|
68366
|
+
},
|
|
68367
|
+
"timeout-ms": { type: "string", description: "Download time limit in milliseconds", required: false },
|
|
68368
|
+
"max-height": {
|
|
68369
|
+
type: "string",
|
|
68370
|
+
description: "Keep a version no taller than this many pixels (e.g. 1080) when the site offers one",
|
|
68371
|
+
required: false
|
|
68372
|
+
}
|
|
68373
|
+
}
|
|
68374
|
+
});
|
|
68375
|
+
function positiveInt(value) {
|
|
68376
|
+
const parsed = typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
|
|
68377
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
68378
|
+
}
|
|
68379
|
+
var fetchCommand2 = defineCommand235({
|
|
68380
|
+
meta: {
|
|
68381
|
+
name: "fetch",
|
|
68382
|
+
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"
|
|
68383
|
+
},
|
|
68384
|
+
args: {
|
|
68385
|
+
url: { type: "positional", description: "Video page URL", required: true },
|
|
68386
|
+
out: { type: "string", description: "Directory to write the file into", required: true },
|
|
68387
|
+
"max-seconds": { type: "string", description: "Refuse videos longer than this", required: false },
|
|
68388
|
+
"timeout-ms": { type: "string", description: "Download time limit in milliseconds", required: false },
|
|
68389
|
+
"max-height": { type: "string", description: "Keep a version no taller than this (e.g. 1080)", required: false }
|
|
68390
|
+
},
|
|
68391
|
+
run: async ({ args: args5 }) => {
|
|
68392
|
+
const url = String(args5.url ?? "");
|
|
68393
|
+
const outDir = path47.resolve(String(args5.out ?? ""));
|
|
68394
|
+
const maxSeconds = positiveInt(args5["max-seconds"]) ?? MAX_VIDEO_INGEST_SECONDS;
|
|
68395
|
+
try {
|
|
68396
|
+
await mkdir15(outDir, { recursive: true });
|
|
68397
|
+
const vimeoCookie = captureVimeoCookie();
|
|
68398
|
+
const probe = await probeYtDlp({ url, vimeoCookie, cookieDir: outDir });
|
|
68399
|
+
if (isAudioOnly(probe.info)) {
|
|
68400
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "That link is audio, not video." } });
|
|
68401
|
+
process.exit(1);
|
|
68402
|
+
}
|
|
68403
|
+
const seconds = durationSeconds(probe.info);
|
|
68404
|
+
const tooLong = refuseByDuration(seconds, maxSeconds);
|
|
68405
|
+
if (tooLong) {
|
|
68406
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: tooLong } });
|
|
68407
|
+
process.exit(1);
|
|
68408
|
+
}
|
|
68409
|
+
const { filePath, tier, reducedQuality } = await runYtDlp({
|
|
68410
|
+
url,
|
|
68411
|
+
audioOnly: false,
|
|
68412
|
+
workDir: outDir,
|
|
68413
|
+
vimeoCookie,
|
|
68414
|
+
timeoutMs: positiveInt(args5["timeout-ms"]) ?? downloadTimeoutMs(seconds),
|
|
68415
|
+
maxHeight: positiveInt(args5["max-height"])
|
|
68416
|
+
});
|
|
68417
|
+
writeJson({
|
|
68418
|
+
ok: true,
|
|
68419
|
+
data: {
|
|
68420
|
+
file: filePath,
|
|
68421
|
+
durationSeconds: seconds,
|
|
68422
|
+
egress: tier,
|
|
68423
|
+
...reducedQuality ? { reducedQuality: true } : {}
|
|
68424
|
+
}
|
|
68425
|
+
});
|
|
68426
|
+
} catch (err) {
|
|
68427
|
+
const message = err instanceof YtDlpError ? `${err.message}: ${err.stderrTail}`.trim() : err instanceof Error ? err.message : String(err);
|
|
68428
|
+
writeJson({ ok: false, error: { code: "DOWNLOAD_FAILED", message } });
|
|
68429
|
+
process.exit(1);
|
|
68430
|
+
}
|
|
68431
|
+
}
|
|
68432
|
+
});
|
|
68433
|
+
|
|
68434
|
+
// src/commands/videos/get.ts
|
|
68435
|
+
import { defineCommand as defineCommand236 } from "citty";
|
|
68436
|
+
registerSchema({
|
|
68437
|
+
command: "videos.get",
|
|
68438
|
+
description: "Get a single video by ID",
|
|
68439
|
+
args: {
|
|
68440
|
+
id: { type: "string", description: "Video ID", required: true }
|
|
68441
|
+
}
|
|
68442
|
+
});
|
|
68443
|
+
var getCommand7 = defineCommand236({
|
|
68444
|
+
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
68445
|
+
args: {
|
|
68446
|
+
id: { type: "positional", description: "Video ID", required: false },
|
|
68447
|
+
"video-id": { type: "string", description: "Video ID (alternative to positional)", required: false },
|
|
68448
|
+
output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
|
|
68449
|
+
fields: { type: "string", description: "Comma-separated field names to include", required: false },
|
|
68450
|
+
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
68451
|
+
},
|
|
68452
|
+
run: async ({ args: args5 }) => {
|
|
68453
|
+
try {
|
|
68454
|
+
const id = args5.id || args5["video-id"];
|
|
68455
|
+
if (!id) {
|
|
68456
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Video ID is required" } });
|
|
68457
|
+
process.exit(1);
|
|
68458
|
+
}
|
|
68459
|
+
validateConvexId(id);
|
|
68460
|
+
const data = await apiGet("/api/videos/get", { id });
|
|
68461
|
+
writeOutput(
|
|
68462
|
+
{ ok: true, data },
|
|
68463
|
+
args5.output || "json",
|
|
68464
|
+
args5.fields ? args5.fields.split(",") : void 0,
|
|
68465
|
+
args5.full,
|
|
68466
|
+
videoNormalizer
|
|
68467
|
+
);
|
|
68468
|
+
} catch (err) {
|
|
68469
|
+
if (err instanceof ApiError) {
|
|
68470
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
68471
|
+
process.exit(1);
|
|
68472
|
+
}
|
|
68473
|
+
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
68474
|
+
process.exit(1);
|
|
68475
|
+
}
|
|
68476
|
+
}
|
|
68477
|
+
});
|
|
68478
|
+
|
|
68479
|
+
// src/commands/videos/group.ts
|
|
68480
|
+
import { defineCommand as defineCommand237 } from "citty";
|
|
68481
|
+
registerSchema({
|
|
68482
|
+
command: "videos.group",
|
|
68483
|
+
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
68484
|
+
args: {
|
|
68485
|
+
id: { type: "string", description: "A video or image id \u2014 returns that asset's whole set", required: false },
|
|
68486
|
+
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
68487
|
+
}
|
|
68488
|
+
});
|
|
68489
|
+
var groupCommand2 = defineCommand237({
|
|
68490
|
+
meta: {
|
|
68491
|
+
name: "group",
|
|
68492
|
+
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>"
|
|
68493
|
+
},
|
|
68494
|
+
args: {
|
|
68495
|
+
id: { type: "positional", description: "A video or image id from the set", required: false },
|
|
68496
|
+
"group-key": { type: "string", description: "The set key, if you already have it", required: false }
|
|
68497
|
+
},
|
|
68498
|
+
run: async ({ args: args5 }) => {
|
|
68499
|
+
await runMediaGroupLookup({
|
|
68500
|
+
id: args5.id,
|
|
68501
|
+
groupKey: args5["group-key"],
|
|
68502
|
+
path: "/api/videos/group",
|
|
68503
|
+
idLabel: "a video or image id"
|
|
68504
|
+
});
|
|
68505
|
+
}
|
|
68506
|
+
});
|
|
68507
|
+
|
|
68508
|
+
// src/commands/videos/ingest.ts
|
|
68509
|
+
import { mkdtemp as mkdtemp3, rm as rm9, stat as stat11 } from "fs/promises";
|
|
68510
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
68511
|
+
import path48 from "path";
|
|
68512
|
+
import { defineCommand as defineCommand238 } from "citty";
|
|
68513
|
+
|
|
68514
|
+
// src/lib/streamUpload.ts
|
|
68515
|
+
import { createHash as createHash2 } from "crypto";
|
|
68516
|
+
import { createReadStream } from "fs";
|
|
68517
|
+
import { Readable } from "stream";
|
|
68518
|
+
import { pipeline } from "stream/promises";
|
|
68519
|
+
async function hashFile(filePath) {
|
|
68520
|
+
const hash = createHash2("sha256");
|
|
68521
|
+
await pipeline(createReadStream(filePath), hash);
|
|
68522
|
+
return hash.digest("hex");
|
|
68523
|
+
}
|
|
68524
|
+
async function putFileStreamed(args5) {
|
|
68525
|
+
const body = Readable.toWeb(createReadStream(args5.filePath));
|
|
68526
|
+
return await fetch(args5.putUrl, {
|
|
68527
|
+
method: "PUT",
|
|
68528
|
+
body,
|
|
68529
|
+
headers: {
|
|
68530
|
+
"Content-Type": args5.contentType,
|
|
68531
|
+
"Content-Length": String(args5.sizeBytes)
|
|
68532
|
+
},
|
|
68533
|
+
duplex: "half"
|
|
68534
|
+
});
|
|
68535
|
+
}
|
|
68536
|
+
|
|
68067
68537
|
// src/commands/videos/ingest.ts
|
|
68068
68538
|
registerSchema({
|
|
68069
68539
|
command: "videos.ingest",
|
|
@@ -68092,7 +68562,7 @@ registerSchema({
|
|
|
68092
68562
|
"dry-run": { type: "boolean", description: "Preview the operation without executing", required: false }
|
|
68093
68563
|
}
|
|
68094
68564
|
});
|
|
68095
|
-
var ingestCommand2 =
|
|
68565
|
+
var ingestCommand2 = defineCommand238({
|
|
68096
68566
|
meta: {
|
|
68097
68567
|
name: "ingest",
|
|
68098
68568
|
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"
|
|
@@ -68278,7 +68748,7 @@ function ingestUrl(args5) {
|
|
|
68278
68748
|
}
|
|
68279
68749
|
async function downloadThenIngest(args5, country) {
|
|
68280
68750
|
const vimeoCookie = captureVimeoCookie();
|
|
68281
|
-
const workDir = await mkdtemp3(
|
|
68751
|
+
const workDir = await mkdtemp3(path48.join(tmpdir4(), "videos-ingest-"));
|
|
68282
68752
|
try {
|
|
68283
68753
|
const probe = await probeYtDlp({ url: args5.url, country, vimeoCookie, cookieDir: workDir });
|
|
68284
68754
|
if (isAudioOnly(probe.info)) {
|
|
@@ -68354,7 +68824,7 @@ async function uploadToAssetStore(filePath, sizeBytes) {
|
|
|
68354
68824
|
}
|
|
68355
68825
|
|
|
68356
68826
|
// src/commands/videos/search.ts
|
|
68357
|
-
import { defineCommand as
|
|
68827
|
+
import { defineCommand as defineCommand239 } from "citty";
|
|
68358
68828
|
registerSchema({
|
|
68359
68829
|
command: "videos.search",
|
|
68360
68830
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -68364,7 +68834,7 @@ registerSchema({
|
|
|
68364
68834
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
68365
68835
|
}
|
|
68366
68836
|
});
|
|
68367
|
-
var searchCommand4 =
|
|
68837
|
+
var searchCommand4 = defineCommand239({
|
|
68368
68838
|
meta: {
|
|
68369
68839
|
name: "search",
|
|
68370
68840
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -68416,7 +68886,7 @@ var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
68416
68886
|
// src/commands/videos/upload.ts
|
|
68417
68887
|
import { readFile as readFile33, stat as stat12 } from "fs/promises";
|
|
68418
68888
|
import { basename as basename3, extname as extname4 } from "path";
|
|
68419
|
-
import { defineCommand as
|
|
68889
|
+
import { defineCommand as defineCommand240 } from "citty";
|
|
68420
68890
|
var MIME_MAP = {
|
|
68421
68891
|
".mp4": "video/mp4",
|
|
68422
68892
|
".mov": "video/quicktime",
|
|
@@ -68458,7 +68928,7 @@ function detectContentType(filePath) {
|
|
|
68458
68928
|
function isRemoteUrl3(value) {
|
|
68459
68929
|
return /^https?:\/\//i.test(value);
|
|
68460
68930
|
}
|
|
68461
|
-
var uploadCommand2 =
|
|
68931
|
+
var uploadCommand2 = defineCommand240({
|
|
68462
68932
|
meta: {
|
|
68463
68933
|
name: "upload",
|
|
68464
68934
|
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"
|
|
@@ -68542,10 +69012,10 @@ var uploadCommand2 = defineCommand233({
|
|
|
68542
69012
|
});
|
|
68543
69013
|
|
|
68544
69014
|
// src/commands/videos/index.ts
|
|
68545
|
-
var videosCommand =
|
|
69015
|
+
var videosCommand = defineCommand241({
|
|
68546
69016
|
meta: {
|
|
68547
69017
|
name: "videos",
|
|
68548
|
-
description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, describe, delete, tags.
|
|
69018
|
+
description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, fetch, describe, delete, tags.
|
|
68549
69019
|
|
|
68550
69020
|
Examples:
|
|
68551
69021
|
baker videos search "product demo" --limit 5
|
|
@@ -68553,6 +69023,7 @@ Examples:
|
|
|
68553
69023
|
baker videos get <video-id>
|
|
68554
69024
|
baker videos upload ./demo.mp4
|
|
68555
69025
|
baker videos ingest https://www.youtube.com/watch?v=abc123
|
|
69026
|
+
baker videos fetch https://www.youtube.com/watch?v=abc123 --out ./clips
|
|
68556
69027
|
baker videos describe <video-id> --description "Customer testimonial, 30s"
|
|
68557
69028
|
baker videos delete <video-id> --dry-run
|
|
68558
69029
|
baker videos tags
|
|
@@ -68564,6 +69035,7 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
68564
69035
|
search: searchCommand4,
|
|
68565
69036
|
upload: uploadCommand2,
|
|
68566
69037
|
ingest: ingestCommand2,
|
|
69038
|
+
fetch: fetchCommand2,
|
|
68567
69039
|
describe: describeCommand2,
|
|
68568
69040
|
delete: deleteCommand4,
|
|
68569
69041
|
tags: tagsCommand6
|
|
@@ -68571,10 +69043,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
68571
69043
|
});
|
|
68572
69044
|
|
|
68573
69045
|
// src/commands/winning-ads/index.ts
|
|
68574
|
-
import { defineCommand as
|
|
69046
|
+
import { defineCommand as defineCommand254 } from "citty";
|
|
68575
69047
|
|
|
68576
69048
|
// src/commands/winning-ads/advertisers.ts
|
|
68577
|
-
import { defineCommand as
|
|
69049
|
+
import { defineCommand as defineCommand242 } from "citty";
|
|
68578
69050
|
|
|
68579
69051
|
// src/commands/winning-ads/shared.ts
|
|
68580
69052
|
function splitList3(value) {
|
|
@@ -68583,7 +69055,7 @@ function splitList3(value) {
|
|
|
68583
69055
|
}
|
|
68584
69056
|
return value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
68585
69057
|
}
|
|
68586
|
-
function
|
|
69058
|
+
function reportError3(err) {
|
|
68587
69059
|
if (err instanceof ApiError) {
|
|
68588
69060
|
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
68589
69061
|
process.exit(1);
|
|
@@ -68627,7 +69099,7 @@ function advertiserNormalizer(record, full) {
|
|
|
68627
69099
|
last_synced_at: record.last_synced_at ?? null
|
|
68628
69100
|
};
|
|
68629
69101
|
}
|
|
68630
|
-
var advertisersCommand2 =
|
|
69102
|
+
var advertisersCommand2 = defineCommand242({
|
|
68631
69103
|
meta: {
|
|
68632
69104
|
name: "advertisers",
|
|
68633
69105
|
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'
|
|
@@ -68679,13 +69151,13 @@ var advertisersCommand2 = defineCommand235({
|
|
|
68679
69151
|
advertiserNormalizer
|
|
68680
69152
|
);
|
|
68681
69153
|
} catch (err) {
|
|
68682
|
-
|
|
69154
|
+
reportError3(err);
|
|
68683
69155
|
}
|
|
68684
69156
|
}
|
|
68685
69157
|
});
|
|
68686
69158
|
|
|
68687
69159
|
// src/commands/winning-ads/brief.ts
|
|
68688
|
-
import { defineCommand as
|
|
69160
|
+
import { defineCommand as defineCommand243 } from "citty";
|
|
68689
69161
|
registerSchema({
|
|
68690
69162
|
command: "winning-ads.brief",
|
|
68691
69163
|
description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
|
|
@@ -68731,7 +69203,7 @@ function parseDna(raw) {
|
|
|
68731
69203
|
}
|
|
68732
69204
|
return parsed;
|
|
68733
69205
|
}
|
|
68734
|
-
var briefCommand =
|
|
69206
|
+
var briefCommand = defineCommand243({
|
|
68735
69207
|
meta: {
|
|
68736
69208
|
name: "brief",
|
|
68737
69209
|
description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
|
|
@@ -68761,13 +69233,13 @@ var briefCommand = defineCommand236({
|
|
|
68761
69233
|
const data = await apiPost("/api/ad-library/brief", body);
|
|
68762
69234
|
writeJson({ ok: true, data });
|
|
68763
69235
|
} catch (err) {
|
|
68764
|
-
|
|
69236
|
+
reportError3(err);
|
|
68765
69237
|
}
|
|
68766
69238
|
}
|
|
68767
69239
|
});
|
|
68768
69240
|
|
|
68769
69241
|
// src/commands/winning-ads/content.ts
|
|
68770
|
-
import { defineCommand as
|
|
69242
|
+
import { defineCommand as defineCommand244 } from "citty";
|
|
68771
69243
|
registerSchema({
|
|
68772
69244
|
command: "winning-ads.content",
|
|
68773
69245
|
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.",
|
|
@@ -68780,7 +69252,7 @@ registerSchema({
|
|
|
68780
69252
|
}
|
|
68781
69253
|
}
|
|
68782
69254
|
});
|
|
68783
|
-
var contentCommand =
|
|
69255
|
+
var contentCommand = defineCommand244({
|
|
68784
69256
|
meta: {
|
|
68785
69257
|
name: "content",
|
|
68786
69258
|
description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
|
|
@@ -68823,13 +69295,13 @@ var contentCommand = defineCommand237({
|
|
|
68823
69295
|
adContentNormalizer
|
|
68824
69296
|
);
|
|
68825
69297
|
} catch (err) {
|
|
68826
|
-
|
|
69298
|
+
reportError3(err);
|
|
68827
69299
|
}
|
|
68828
69300
|
}
|
|
68829
69301
|
});
|
|
68830
69302
|
|
|
68831
69303
|
// src/commands/winning-ads/feed.ts
|
|
68832
|
-
import { defineCommand as
|
|
69304
|
+
import { defineCommand as defineCommand245 } from "citty";
|
|
68833
69305
|
function buildFeedParams(input) {
|
|
68834
69306
|
const params = {};
|
|
68835
69307
|
const advertiser = splitList3(input.advertiser);
|
|
@@ -68881,7 +69353,7 @@ registerSchema({
|
|
|
68881
69353
|
format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
|
|
68882
69354
|
}
|
|
68883
69355
|
});
|
|
68884
|
-
var feedCommand2 =
|
|
69356
|
+
var feedCommand2 = defineCommand245({
|
|
68885
69357
|
meta: {
|
|
68886
69358
|
name: "feed",
|
|
68887
69359
|
description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
|
|
@@ -68960,13 +69432,13 @@ var feedCommand2 = defineCommand238({
|
|
|
68960
69432
|
`);
|
|
68961
69433
|
}
|
|
68962
69434
|
} catch (err) {
|
|
68963
|
-
|
|
69435
|
+
reportError3(err);
|
|
68964
69436
|
}
|
|
68965
69437
|
}
|
|
68966
69438
|
});
|
|
68967
69439
|
|
|
68968
69440
|
// src/commands/winning-ads/follow.ts
|
|
68969
|
-
import { defineCommand as
|
|
69441
|
+
import { defineCommand as defineCommand246 } from "citty";
|
|
68970
69442
|
var PLATFORMS = adLibraryPlatformSchema.options;
|
|
68971
69443
|
registerSchema({
|
|
68972
69444
|
command: "winning-ads.follow",
|
|
@@ -68981,7 +69453,7 @@ registerSchema({
|
|
|
68981
69453
|
label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
|
|
68982
69454
|
}
|
|
68983
69455
|
});
|
|
68984
|
-
var followCommand =
|
|
69456
|
+
var followCommand = defineCommand246({
|
|
68985
69457
|
meta: {
|
|
68986
69458
|
name: "follow",
|
|
68987
69459
|
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'
|
|
@@ -69022,13 +69494,13 @@ var followCommand = defineCommand239({
|
|
|
69022
69494
|
}
|
|
69023
69495
|
writeJson({ ok: true, data, hints: hints2 });
|
|
69024
69496
|
} catch (err) {
|
|
69025
|
-
|
|
69497
|
+
reportError3(err);
|
|
69026
69498
|
}
|
|
69027
69499
|
}
|
|
69028
69500
|
});
|
|
69029
69501
|
|
|
69030
69502
|
// src/commands/winning-ads/follow-competitors.ts
|
|
69031
|
-
import { defineCommand as
|
|
69503
|
+
import { defineCommand as defineCommand247 } from "citty";
|
|
69032
69504
|
var PLATFORMS2 = adLibraryPlatformSchema.options;
|
|
69033
69505
|
var BATCH_TIMEOUT_MS = 3e5;
|
|
69034
69506
|
function buildFollowBatchBody(input) {
|
|
@@ -69061,7 +69533,7 @@ registerSchema({
|
|
|
69061
69533
|
}
|
|
69062
69534
|
}
|
|
69063
69535
|
});
|
|
69064
|
-
var followCompetitorsCommand =
|
|
69536
|
+
var followCompetitorsCommand = defineCommand247({
|
|
69065
69537
|
meta: {
|
|
69066
69538
|
name: "follow-competitors",
|
|
69067
69539
|
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"'
|
|
@@ -69130,13 +69602,13 @@ var followCompetitorsCommand = defineCommand240({
|
|
|
69130
69602
|
}
|
|
69131
69603
|
writeJson({ ok: true, data, hints: hints2.length > 0 ? hints2 : void 0 });
|
|
69132
69604
|
} catch (err) {
|
|
69133
|
-
|
|
69605
|
+
reportError3(err);
|
|
69134
69606
|
}
|
|
69135
69607
|
}
|
|
69136
69608
|
});
|
|
69137
69609
|
|
|
69138
69610
|
// src/commands/winning-ads/following.ts
|
|
69139
|
-
import { defineCommand as
|
|
69611
|
+
import { defineCommand as defineCommand248 } from "citty";
|
|
69140
69612
|
registerSchema({
|
|
69141
69613
|
command: "winning-ads.following",
|
|
69142
69614
|
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.",
|
|
@@ -69190,7 +69662,7 @@ function followingNormalizer(record, full) {
|
|
|
69190
69662
|
platforms: Array.isArray(record.platforms) ? record.platforms : []
|
|
69191
69663
|
};
|
|
69192
69664
|
}
|
|
69193
|
-
var followingCommand =
|
|
69665
|
+
var followingCommand = defineCommand248({
|
|
69194
69666
|
meta: {
|
|
69195
69667
|
name: "following",
|
|
69196
69668
|
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"
|
|
@@ -69220,13 +69692,13 @@ var followingCommand = defineCommand241({
|
|
|
69220
69692
|
followingNormalizer
|
|
69221
69693
|
);
|
|
69222
69694
|
} catch (err) {
|
|
69223
|
-
|
|
69695
|
+
reportError3(err);
|
|
69224
69696
|
}
|
|
69225
69697
|
}
|
|
69226
69698
|
});
|
|
69227
69699
|
|
|
69228
69700
|
// src/commands/winning-ads/patterns.ts
|
|
69229
|
-
import { defineCommand as
|
|
69701
|
+
import { defineCommand as defineCommand249 } from "citty";
|
|
69230
69702
|
registerSchema({
|
|
69231
69703
|
command: "winning-ads.patterns",
|
|
69232
69704
|
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.",
|
|
@@ -69265,7 +69737,7 @@ function discriminatorRow(record) {
|
|
|
69265
69737
|
top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
|
|
69266
69738
|
};
|
|
69267
69739
|
}
|
|
69268
|
-
var patternsCommand =
|
|
69740
|
+
var patternsCommand = defineCommand249({
|
|
69269
69741
|
meta: {
|
|
69270
69742
|
name: "patterns",
|
|
69271
69743
|
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"
|
|
@@ -69315,13 +69787,13 @@ var patternsCommand = defineCommand242({
|
|
|
69315
69787
|
(record) => discriminatorRow(record)
|
|
69316
69788
|
);
|
|
69317
69789
|
} catch (err) {
|
|
69318
|
-
|
|
69790
|
+
reportError3(err);
|
|
69319
69791
|
}
|
|
69320
69792
|
}
|
|
69321
69793
|
});
|
|
69322
69794
|
|
|
69323
69795
|
// src/commands/winning-ads/search.ts
|
|
69324
|
-
import { defineCommand as
|
|
69796
|
+
import { defineCommand as defineCommand250 } from "citty";
|
|
69325
69797
|
registerSchema({
|
|
69326
69798
|
command: "winning-ads.search",
|
|
69327
69799
|
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.",
|
|
@@ -69457,9 +69929,9 @@ function reportSearchError(err) {
|
|
|
69457
69929
|
writeJson({ ok: false, error: { code: err.code, message: err.message, fix } });
|
|
69458
69930
|
process.exit(1);
|
|
69459
69931
|
}
|
|
69460
|
-
|
|
69932
|
+
reportError3(err);
|
|
69461
69933
|
}
|
|
69462
|
-
var searchCommand5 =
|
|
69934
|
+
var searchCommand5 = defineCommand250({
|
|
69463
69935
|
meta: {
|
|
69464
69936
|
name: "search",
|
|
69465
69937
|
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"
|
|
@@ -69579,7 +70051,7 @@ var searchCommand5 = defineCommand243({
|
|
|
69579
70051
|
});
|
|
69580
70052
|
|
|
69581
70053
|
// src/commands/winning-ads/seeds.ts
|
|
69582
|
-
import { defineCommand as
|
|
70054
|
+
import { defineCommand as defineCommand251 } from "citty";
|
|
69583
70055
|
function leanRow(r) {
|
|
69584
70056
|
return {
|
|
69585
70057
|
key: r.key,
|
|
@@ -69607,7 +70079,7 @@ function makeSeedCommand(opts) {
|
|
|
69607
70079
|
limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
|
|
69608
70080
|
}
|
|
69609
70081
|
});
|
|
69610
|
-
return
|
|
70082
|
+
return defineCommand251({
|
|
69611
70083
|
meta: { name: opts.name, description: opts.description },
|
|
69612
70084
|
args: {
|
|
69613
70085
|
platform: { type: "string", description: "Single platform to segment on", required: false },
|
|
@@ -69634,7 +70106,7 @@ function makeSeedCommand(opts) {
|
|
|
69634
70106
|
}
|
|
69635
70107
|
writeOutput({ ok: true, data: projected }, output);
|
|
69636
70108
|
} catch (err) {
|
|
69637
|
-
|
|
70109
|
+
reportError3(err);
|
|
69638
70110
|
}
|
|
69639
70111
|
}
|
|
69640
70112
|
});
|
|
@@ -69656,7 +70128,7 @@ var formatsCommand = makeSeedCommand({
|
|
|
69656
70128
|
});
|
|
69657
70129
|
|
|
69658
70130
|
// src/commands/winning-ads/unfollow.ts
|
|
69659
|
-
import { defineCommand as
|
|
70131
|
+
import { defineCommand as defineCommand252 } from "citty";
|
|
69660
70132
|
registerSchema({
|
|
69661
70133
|
command: "winning-ads.unfollow",
|
|
69662
70134
|
description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
|
|
@@ -69664,7 +70136,7 @@ registerSchema({
|
|
|
69664
70136
|
advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
|
|
69665
70137
|
}
|
|
69666
70138
|
});
|
|
69667
|
-
var unfollowCommand =
|
|
70139
|
+
var unfollowCommand = defineCommand252({
|
|
69668
70140
|
meta: {
|
|
69669
70141
|
name: "unfollow",
|
|
69670
70142
|
description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
|
|
@@ -69679,13 +70151,13 @@ var unfollowCommand = defineCommand245({
|
|
|
69679
70151
|
});
|
|
69680
70152
|
writeJson({ ok: true, data });
|
|
69681
70153
|
} catch (err) {
|
|
69682
|
-
|
|
70154
|
+
reportError3(err);
|
|
69683
70155
|
}
|
|
69684
70156
|
}
|
|
69685
70157
|
});
|
|
69686
70158
|
|
|
69687
70159
|
// src/commands/winning-ads/winners.ts
|
|
69688
|
-
import { defineCommand as
|
|
70160
|
+
import { defineCommand as defineCommand253 } from "citty";
|
|
69689
70161
|
registerSchema({
|
|
69690
70162
|
command: "winning-ads.winners",
|
|
69691
70163
|
description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
|
|
@@ -69695,7 +70167,7 @@ registerSchema({
|
|
|
69695
70167
|
platform: { type: "string", description: "Filter to a single platform: meta|linkedin|tiktok", required: false }
|
|
69696
70168
|
}
|
|
69697
70169
|
});
|
|
69698
|
-
var winnersCommand =
|
|
70170
|
+
var winnersCommand = defineCommand253({
|
|
69699
70171
|
meta: {
|
|
69700
70172
|
name: "winners",
|
|
69701
70173
|
description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
|
|
@@ -69739,13 +70211,13 @@ var winnersCommand = defineCommand246({
|
|
|
69739
70211
|
winningAdNormalizer
|
|
69740
70212
|
);
|
|
69741
70213
|
} catch (err) {
|
|
69742
|
-
|
|
70214
|
+
reportError3(err);
|
|
69743
70215
|
}
|
|
69744
70216
|
}
|
|
69745
70217
|
});
|
|
69746
70218
|
|
|
69747
70219
|
// src/commands/winning-ads/index.ts
|
|
69748
|
-
var winningAdsCommand =
|
|
70220
|
+
var winningAdsCommand = defineCommand254({
|
|
69749
70221
|
meta: {
|
|
69750
70222
|
name: "winning-ads",
|
|
69751
70223
|
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.
|
|
@@ -69817,7 +70289,7 @@ function getCliVersion() {
|
|
|
69817
70289
|
}
|
|
69818
70290
|
|
|
69819
70291
|
// src/cli.ts
|
|
69820
|
-
var main =
|
|
70292
|
+
var main = defineCommand255({
|
|
69821
70293
|
meta: {
|
|
69822
70294
|
name: "baker",
|
|
69823
70295
|
version: getCliVersion(),
|
|
@@ -69857,6 +70329,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
69857
70329
|
history: historyCommand2,
|
|
69858
70330
|
hubspot: hubspotCommand,
|
|
69859
70331
|
"winning-ads": winningAdsCommand,
|
|
70332
|
+
"media-sources": mediaSourcesCommand,
|
|
69860
70333
|
mcp: mcpCommand,
|
|
69861
70334
|
schema: schemaCommand2
|
|
69862
70335
|
}
|