@koda-sl/baker-cli 0.379.0 → 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 +38 -2
- package/dist/{chunk-FGHMWBUD.js → chunk-HOMVJ2D3.js} +11 -5
- package/dist/chunk-HOMVJ2D3.js.map +1 -0
- package/dist/cli.js +839 -379
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-FGHMWBUD.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
validateCanvasDeep,
|
|
71
71
|
withoutCastName,
|
|
72
72
|
ytDlpBlockSignal
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-HOMVJ2D3.js";
|
|
74
74
|
import {
|
|
75
75
|
NAME_CONTAINS_ARG,
|
|
76
76
|
csvOrJson,
|
|
@@ -143,7 +143,7 @@ import {
|
|
|
143
143
|
} from "./chunk-HJEMOSPH.js";
|
|
144
144
|
|
|
145
145
|
// src/cli.ts
|
|
146
|
-
import { defineCommand as
|
|
146
|
+
import { defineCommand as defineCommand255, runMain } from "citty";
|
|
147
147
|
|
|
148
148
|
// src/cache-flag.ts
|
|
149
149
|
var NO_CACHE_ARG = {
|
|
@@ -4534,6 +4534,9 @@ var chatChangeTypeSchema = z13.enum([
|
|
|
4534
4534
|
"image",
|
|
4535
4535
|
"video",
|
|
4536
4536
|
"followed-advertiser",
|
|
4537
|
+
// A connected social account feeding the image and video libraries, keyed
|
|
4538
|
+
// on `platform:handle`. Immediate — see convex/mediaSources/mutations.ts.
|
|
4539
|
+
"media-source",
|
|
4537
4540
|
// A landing page saved to the reference library, keyed on the page.
|
|
4538
4541
|
"landing-reference",
|
|
4539
4542
|
// One Studio batch — the takes of one brief, as a set. See convex/lib/validators.ts.
|
|
@@ -6398,6 +6401,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 {
|
|
@@ -24618,54 +24627,54 @@ function buildCustomConversionRule(input) {
|
|
|
24618
24627
|
function customConversionRuleRefusal(rule) {
|
|
24619
24628
|
return ruleNodeRefusal(rule, "rule");
|
|
24620
24629
|
}
|
|
24621
|
-
function branchRefusal(key, value,
|
|
24630
|
+
function branchRefusal(key, value, path49) {
|
|
24622
24631
|
if (!Array.isArray(value) || value.length === 0) {
|
|
24623
|
-
return `${
|
|
24632
|
+
return `${path49}.${key} must be a non-empty array of conditions \u2014 an empty one counts every event the pixel sends`;
|
|
24624
24633
|
}
|
|
24625
24634
|
for (const [index, child] of value.entries()) {
|
|
24626
|
-
const refusal = ruleNodeRefusal(child, `${
|
|
24635
|
+
const refusal = ruleNodeRefusal(child, `${path49}.${key}[${index}]`);
|
|
24627
24636
|
if (refusal) {
|
|
24628
24637
|
return refusal;
|
|
24629
24638
|
}
|
|
24630
24639
|
}
|
|
24631
24640
|
return void 0;
|
|
24632
24641
|
}
|
|
24633
|
-
function conditionRefusal(key, value,
|
|
24634
|
-
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);
|
|
24635
24644
|
}
|
|
24636
|
-
function ruleNodeRefusal(node,
|
|
24645
|
+
function ruleNodeRefusal(node, path49) {
|
|
24637
24646
|
if (!isRecord2(node)) {
|
|
24638
|
-
return `${
|
|
24647
|
+
return `${path49} must be an object like {"URL":{"i_contains":"/thank-you"}}`;
|
|
24639
24648
|
}
|
|
24640
24649
|
const entries = Object.entries(node);
|
|
24641
24650
|
if (entries.length === 0) {
|
|
24642
|
-
return `${
|
|
24651
|
+
return `${path49} is empty \u2014 a rule with no condition counts every event the pixel sends`;
|
|
24643
24652
|
}
|
|
24644
24653
|
if (entries.length > 1) {
|
|
24645
|
-
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]}`;
|
|
24646
24655
|
}
|
|
24647
24656
|
for (const [key, value] of entries) {
|
|
24648
|
-
const refusal = conditionRefusal(key, value,
|
|
24657
|
+
const refusal = conditionRefusal(key, value, path49);
|
|
24649
24658
|
if (refusal) {
|
|
24650
24659
|
return refusal;
|
|
24651
24660
|
}
|
|
24652
24661
|
}
|
|
24653
24662
|
return void 0;
|
|
24654
24663
|
}
|
|
24655
|
-
function leafRefusal(field, condition,
|
|
24664
|
+
function leafRefusal(field, condition, path49) {
|
|
24656
24665
|
if (!isRecord2(condition)) {
|
|
24657
|
-
return `${
|
|
24666
|
+
return `${path49}.${field} must be a test like {"i_contains":"/thank-you"}, not a bare value`;
|
|
24658
24667
|
}
|
|
24659
24668
|
const tests = Object.entries(condition);
|
|
24660
24669
|
if (tests.length === 0) {
|
|
24661
|
-
return `${
|
|
24670
|
+
return `${path49}.${field} names no test \u2014 use one of ${Object.keys(RULE_OPERATORS).join(", ")}`;
|
|
24662
24671
|
}
|
|
24663
24672
|
if (tests.length > 1) {
|
|
24664
|
-
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]}`;
|
|
24665
24674
|
}
|
|
24666
24675
|
for (const [operator] of tests) {
|
|
24667
24676
|
if (!RULE_OPERATORS[operator]) {
|
|
24668
|
-
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)`;
|
|
24669
24678
|
}
|
|
24670
24679
|
}
|
|
24671
24680
|
return void 0;
|
|
@@ -25381,11 +25390,11 @@ var updateStatusSchema = z37.enum(UPDATE_STATUSES);
|
|
|
25381
25390
|
function currencyMinimums2(currencyCode) {
|
|
25382
25391
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
25383
25392
|
}
|
|
25384
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
25393
|
+
function validateDailyBudgetFloor(money, ctx, path49) {
|
|
25385
25394
|
if (money?.currencyCode) {
|
|
25386
25395
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
25387
25396
|
if (Number(money.amount) < min) {
|
|
25388
|
-
ctx.addIssue({ code: "custom", path:
|
|
25397
|
+
ctx.addIssue({ code: "custom", path: path49, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
25389
25398
|
}
|
|
25390
25399
|
}
|
|
25391
25400
|
}
|
|
@@ -26257,19 +26266,19 @@ function refuseDeleteByUpdate(payload, group) {
|
|
|
26257
26266
|
);
|
|
26258
26267
|
}
|
|
26259
26268
|
}
|
|
26260
|
-
function loadJsonFileArg3(
|
|
26261
|
-
if (typeof
|
|
26269
|
+
function loadJsonFileArg3(path49) {
|
|
26270
|
+
if (typeof path49 !== "string" || path49.length === 0) {
|
|
26262
26271
|
return {};
|
|
26263
26272
|
}
|
|
26264
26273
|
try {
|
|
26265
|
-
const parsed = JSON.parse(readFileSync9(
|
|
26274
|
+
const parsed = JSON.parse(readFileSync9(path49, "utf8"));
|
|
26266
26275
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
26267
|
-
failWriteValidation3(`${
|
|
26276
|
+
failWriteValidation3(`${path49} must contain a JSON object`);
|
|
26268
26277
|
}
|
|
26269
26278
|
return parsed;
|
|
26270
26279
|
} catch (err) {
|
|
26271
26280
|
if (err instanceof SyntaxError) {
|
|
26272
|
-
failWriteValidation3(`${
|
|
26281
|
+
failWriteValidation3(`${path49} is not valid JSON: ${err.message}`);
|
|
26273
26282
|
}
|
|
26274
26283
|
throw err;
|
|
26275
26284
|
}
|
|
@@ -31965,12 +31974,12 @@ function flowExists(slug) {
|
|
|
31965
31974
|
return existsSync3(join2(flowsDir(), slug, "_data.json"));
|
|
31966
31975
|
}
|
|
31967
31976
|
function readFlowTree(slug) {
|
|
31968
|
-
const
|
|
31969
|
-
if (!existsSync3(
|
|
31977
|
+
const path49 = join2(flowsDir(), slug, "_data.json");
|
|
31978
|
+
if (!existsSync3(path49)) {
|
|
31970
31979
|
failLocal(`No form "${slug}". Run "baker flows list" to see the forms in this workspace.`);
|
|
31971
31980
|
}
|
|
31972
31981
|
try {
|
|
31973
|
-
return JSON.parse(readFileSync11(
|
|
31982
|
+
return JSON.parse(readFileSync11(path49, "utf-8"));
|
|
31974
31983
|
} catch (error) {
|
|
31975
31984
|
failLocal(`Could not read form "${slug}": ${error instanceof Error ? error.message : String(error)}`);
|
|
31976
31985
|
}
|
|
@@ -32930,12 +32939,12 @@ function readPeopleFile(args5) {
|
|
|
32930
32939
|
}
|
|
32931
32940
|
function unreadablePeopleFile(args5) {
|
|
32932
32941
|
if (!args5["people-file"]) return void 0;
|
|
32933
|
-
const
|
|
32942
|
+
const path49 = String(args5["people-file"]);
|
|
32934
32943
|
try {
|
|
32935
|
-
readFileSync12(
|
|
32944
|
+
readFileSync12(path49, "utf8");
|
|
32936
32945
|
return void 0;
|
|
32937
32946
|
} catch {
|
|
32938
|
-
return `Couldn't read --people-file ${
|
|
32947
|
+
return `Couldn't read --people-file ${path49}. Check the path, or pass the people inline with --person.`;
|
|
32939
32948
|
}
|
|
32940
32949
|
}
|
|
32941
32950
|
function peopleLimitError(args5) {
|
|
@@ -33907,11 +33916,11 @@ function parseFieldArgs(argv) {
|
|
|
33907
33916
|
for (const pair of parseRepeated(argv, "--field")) {
|
|
33908
33917
|
const eq = pair.indexOf("=");
|
|
33909
33918
|
const field = eq === -1 ? pair : pair.slice(0, eq);
|
|
33910
|
-
const
|
|
33919
|
+
const path49 = eq === -1 ? "" : pair.slice(eq + 1).trim();
|
|
33911
33920
|
const problem = mappingRowProblem(field);
|
|
33912
33921
|
if (problem !== null) throw new ConversionArgsError(problem);
|
|
33913
|
-
if (
|
|
33914
|
-
mapping[field] =
|
|
33922
|
+
if (path49 === "") throw new ConversionArgsError(`--field ${field} needs a path: --field ${field}=<dotted.path>.`);
|
|
33923
|
+
mapping[field] = path49;
|
|
33915
33924
|
}
|
|
33916
33925
|
return mapping;
|
|
33917
33926
|
}
|
|
@@ -35513,11 +35522,11 @@ function unwrap(response) {
|
|
|
35513
35522
|
}
|
|
35514
35523
|
return response.data;
|
|
35515
35524
|
}
|
|
35516
|
-
async function readAvatars(
|
|
35517
|
-
return unwrap(await apiGet(
|
|
35525
|
+
async function readAvatars(path49, params) {
|
|
35526
|
+
return unwrap(await apiGet(path49, params));
|
|
35518
35527
|
}
|
|
35519
|
-
async function writeAvatars(
|
|
35520
|
-
return unwrap(await apiPost(
|
|
35528
|
+
async function writeAvatars(path49, body) {
|
|
35529
|
+
return unwrap(await apiPost(path49, body));
|
|
35521
35530
|
}
|
|
35522
35531
|
|
|
35523
35532
|
// src/commands/avatars/create.ts
|
|
@@ -36426,12 +36435,12 @@ function missingFontFiles(urls, available) {
|
|
|
36426
36435
|
function planFontAdoption(sources, families) {
|
|
36427
36436
|
const wanted = new Map(families.map((family) => [normalizeFamily(family), family]));
|
|
36428
36437
|
const byFamily = /* @__PURE__ */ new Map();
|
|
36429
|
-
for (const { path:
|
|
36430
|
-
const dir = posix.dirname(
|
|
36438
|
+
for (const { path: path49, source } of sources) {
|
|
36439
|
+
const dir = posix.dirname(path49);
|
|
36431
36440
|
for (const face of declaredFontFaces(source)) {
|
|
36432
36441
|
if (!wanted.has(face.family)) continue;
|
|
36433
36442
|
const perFile = byFamily.get(face.family) ?? /* @__PURE__ */ new Map();
|
|
36434
|
-
perFile.set(
|
|
36443
|
+
perFile.set(path49, [...perFile.get(path49) ?? [], rebaseFontFaceSrc(face.block, dir)]);
|
|
36435
36444
|
byFamily.set(face.family, perFile);
|
|
36436
36445
|
}
|
|
36437
36446
|
}
|
|
@@ -49257,10 +49266,10 @@ function parseValueExpression(raw) {
|
|
|
49257
49266
|
return parts.map(parsePart);
|
|
49258
49267
|
}
|
|
49259
49268
|
function trackingFieldIds() {
|
|
49260
|
-
const
|
|
49261
|
-
if (!existsSync6(
|
|
49269
|
+
const path49 = join4(flowsDir(), "..", "tracking.ts");
|
|
49270
|
+
if (!existsSync6(path49)) return null;
|
|
49262
49271
|
try {
|
|
49263
|
-
const source = readFileSync15(
|
|
49272
|
+
const source = readFileSync15(path49, "utf-8");
|
|
49264
49273
|
const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
|
|
49265
49274
|
if (!block2) return null;
|
|
49266
49275
|
const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
|
|
@@ -49834,13 +49843,13 @@ function specsFromFile(parsed) {
|
|
|
49834
49843
|
return `${destField}${type}=${entry?.value ?? ""}`;
|
|
49835
49844
|
});
|
|
49836
49845
|
}
|
|
49837
|
-
function readSpecFile(
|
|
49846
|
+
function readSpecFile(path49) {
|
|
49838
49847
|
let raw;
|
|
49839
49848
|
try {
|
|
49840
|
-
raw =
|
|
49849
|
+
raw = path49 === "-" ? readFileSync16(0, "utf-8") : readFileSync16(path49, "utf-8");
|
|
49841
49850
|
} catch (error) {
|
|
49842
49851
|
refuse(
|
|
49843
|
-
`Could not read ${
|
|
49852
|
+
`Could not read ${path49 === "-" ? "the mapping from stdin" : `"${path49}"`}: ${error instanceof Error ? error.message : String(error)}`
|
|
49844
49853
|
);
|
|
49845
49854
|
}
|
|
49846
49855
|
let parsed;
|
|
@@ -49848,7 +49857,7 @@ function readSpecFile(path48) {
|
|
|
49848
49857
|
parsed = JSON.parse(raw);
|
|
49849
49858
|
} catch (error) {
|
|
49850
49859
|
refuse(
|
|
49851
|
-
`${
|
|
49860
|
+
`${path49 === "-" ? "stdin" : `"${path49}"`} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
49852
49861
|
'Expected { "map": { "<destField>": "<value>", \u2026 } }'
|
|
49853
49862
|
);
|
|
49854
49863
|
}
|
|
@@ -50147,21 +50156,21 @@ var ARRAY_FIELDS = [
|
|
|
50147
50156
|
"tagIds"
|
|
50148
50157
|
];
|
|
50149
50158
|
var ARRAY_OWNERS = ["", "body"];
|
|
50150
|
-
function dropUnsetOptionals(sideEffect,
|
|
50159
|
+
function dropUnsetOptionals(sideEffect, path49) {
|
|
50151
50160
|
return OPTIONAL_STRINGS.flatMap((key) => {
|
|
50152
50161
|
if (!(key in sideEffect) || sideEffect[key] !== null && sideEffect[key] !== "") return [];
|
|
50153
50162
|
delete sideEffect[key];
|
|
50154
|
-
return [{ path:
|
|
50163
|
+
return [{ path: path49, change: `dropped \`${key}\` (an optional string is absent, never null)` }];
|
|
50155
50164
|
});
|
|
50156
50165
|
}
|
|
50157
|
-
function fillNulledArrays(target2, prefix,
|
|
50166
|
+
function fillNulledArrays(target2, prefix, path49) {
|
|
50158
50167
|
return ARRAY_FIELDS.flatMap((key) => {
|
|
50159
50168
|
if (!(key in target2) || target2[key] !== null) return [];
|
|
50160
50169
|
target2[key] = [];
|
|
50161
|
-
return [{ path:
|
|
50170
|
+
return [{ path: path49, change: `\`${prefix}${key}: null\` \u2192 \`[]\`` }];
|
|
50162
50171
|
});
|
|
50163
50172
|
}
|
|
50164
|
-
function tidyEmailRecipients(sideEffect,
|
|
50173
|
+
function tidyEmailRecipients(sideEffect, path49) {
|
|
50165
50174
|
if (sideEffect.type !== "email") return [];
|
|
50166
50175
|
const config = sideEffect.encryptedConfig;
|
|
50167
50176
|
if (!config || typeof config !== "object" || Array.isArray(config)) return [];
|
|
@@ -50172,7 +50181,7 @@ function tidyEmailRecipients(sideEffect, path48) {
|
|
|
50172
50181
|
const tidied = to.join(", ");
|
|
50173
50182
|
if (tidied === raw) return [];
|
|
50174
50183
|
config.email = tidied;
|
|
50175
|
-
return [{ path:
|
|
50184
|
+
return [{ path: path49, change: "tidied the recipient list's spacing and separators" }];
|
|
50176
50185
|
}
|
|
50177
50186
|
function sideEffectsOf(node) {
|
|
50178
50187
|
if (!Array.isArray(node.sideEffects)) return [];
|
|
@@ -50181,13 +50190,13 @@ function sideEffectsOf(node) {
|
|
|
50181
50190
|
);
|
|
50182
50191
|
}
|
|
50183
50192
|
function normalizeSideEffect(sideEffect, where) {
|
|
50184
|
-
const
|
|
50193
|
+
const path49 = `${where} \u2192 ${String(sideEffect.id ?? "side effect")}`;
|
|
50185
50194
|
const arrays = ARRAY_OWNERS.flatMap((owner) => {
|
|
50186
50195
|
const target2 = owner ? sideEffect[owner] : sideEffect;
|
|
50187
50196
|
if (!target2 || typeof target2 !== "object") return [];
|
|
50188
|
-
return fillNulledArrays(target2, owner ? `${owner}.` : "",
|
|
50197
|
+
return fillNulledArrays(target2, owner ? `${owner}.` : "", path49);
|
|
50189
50198
|
});
|
|
50190
|
-
return [...dropUnsetOptionals(sideEffect,
|
|
50199
|
+
return [...dropUnsetOptionals(sideEffect, path49), ...arrays, ...tidyEmailRecipients(sideEffect, path49)];
|
|
50191
50200
|
}
|
|
50192
50201
|
function normalizeFlowTree(tree) {
|
|
50193
50202
|
const changes = [];
|
|
@@ -51577,10 +51586,10 @@ async function stageOps(ops) {
|
|
|
51577
51586
|
handleError5(err);
|
|
51578
51587
|
}
|
|
51579
51588
|
}
|
|
51580
|
-
async function draftAction2(
|
|
51589
|
+
async function draftAction2(path49, body, chat) {
|
|
51581
51590
|
const chatId = resolveChatId(chat);
|
|
51582
51591
|
try {
|
|
51583
|
-
const data = await apiPost(
|
|
51592
|
+
const data = await apiPost(path49, { chatId, ...body });
|
|
51584
51593
|
writeJsonEnvelope({ ok: true, data });
|
|
51585
51594
|
return data;
|
|
51586
51595
|
} catch (err) {
|
|
@@ -54109,9 +54118,9 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
54109
54118
|
}
|
|
54110
54119
|
return readFile28(pathOrUrl);
|
|
54111
54120
|
}
|
|
54112
|
-
async function isDirectory(
|
|
54121
|
+
async function isDirectory(path49) {
|
|
54113
54122
|
try {
|
|
54114
|
-
const s = await stat7(
|
|
54123
|
+
const s = await stat7(path49);
|
|
54115
54124
|
return s.isDirectory();
|
|
54116
54125
|
} catch {
|
|
54117
54126
|
return false;
|
|
@@ -54539,13 +54548,13 @@ function resolveDownloadPath({ baseName, extension, out, outIsDirectory: outIsDi
|
|
|
54539
54548
|
}
|
|
54540
54549
|
function disambiguate(paths) {
|
|
54541
54550
|
const taken = /* @__PURE__ */ new Set();
|
|
54542
|
-
return paths.map((
|
|
54543
|
-
if (!taken.has(
|
|
54544
|
-
taken.add(
|
|
54545
|
-
return
|
|
54551
|
+
return paths.map((path49) => {
|
|
54552
|
+
if (!taken.has(path49)) {
|
|
54553
|
+
taken.add(path49);
|
|
54554
|
+
return path49;
|
|
54546
54555
|
}
|
|
54547
|
-
const ext = extname3(
|
|
54548
|
-
const stem =
|
|
54556
|
+
const ext = extname3(path49);
|
|
54557
|
+
const stem = path49.slice(0, path49.length - ext.length);
|
|
54549
54558
|
let n = 2;
|
|
54550
54559
|
while (taken.has(`${stem}-${n}${ext}`)) n += 1;
|
|
54551
54560
|
const unique = `${stem}-${n}${ext}`;
|
|
@@ -54671,10 +54680,10 @@ async function runDownloads(plan) {
|
|
|
54671
54680
|
const paths = disambiguate(fetched.map((item) => item.path));
|
|
54672
54681
|
const downloaded = [];
|
|
54673
54682
|
for (const [index, item] of fetched.entries()) {
|
|
54674
|
-
const
|
|
54683
|
+
const path49 = paths[index] ?? item.path;
|
|
54675
54684
|
try {
|
|
54676
|
-
await atomicWrite(
|
|
54677
|
-
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 });
|
|
54678
54687
|
} catch (err) {
|
|
54679
54688
|
failed.push({ input: item.input, error: failureMessage(err, "Write failed") });
|
|
54680
54689
|
}
|
|
@@ -62861,11 +62870,374 @@ Full guide: __tooling__/docs/tools/baker/mcp.md`
|
|
|
62861
62870
|
}
|
|
62862
62871
|
});
|
|
62863
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
|
+
|
|
62864
63236
|
// src/commands/research/index.ts
|
|
62865
|
-
import { defineCommand as
|
|
63237
|
+
import { defineCommand as defineCommand202 } from "citty";
|
|
62866
63238
|
|
|
62867
63239
|
// src/commands/research/advertisers.ts
|
|
62868
|
-
import { defineCommand as
|
|
63240
|
+
import { defineCommand as defineCommand190 } from "citty";
|
|
62869
63241
|
|
|
62870
63242
|
// src/commands/research/hints.ts
|
|
62871
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.';
|
|
@@ -63067,7 +63439,7 @@ var FIELDS3 = {
|
|
|
63067
63439
|
etv: "Estimated traffic value (USD)",
|
|
63068
63440
|
visibility: "SERP visibility score (0-1)"
|
|
63069
63441
|
};
|
|
63070
|
-
var advertisersCommand =
|
|
63442
|
+
var advertisersCommand = defineCommand190({
|
|
63071
63443
|
meta: {
|
|
63072
63444
|
name: "advertisers",
|
|
63073
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).
|
|
@@ -63123,7 +63495,7 @@ Examples:
|
|
|
63123
63495
|
});
|
|
63124
63496
|
|
|
63125
63497
|
// src/commands/research/autocomplete.ts
|
|
63126
|
-
import { defineCommand as
|
|
63498
|
+
import { defineCommand as defineCommand191 } from "citty";
|
|
63127
63499
|
registerSchema({
|
|
63128
63500
|
command: "research.autocomplete",
|
|
63129
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).",
|
|
@@ -63146,7 +63518,7 @@ registerSchema({
|
|
|
63146
63518
|
var FIELDS4 = {
|
|
63147
63519
|
suggestion: "Autocomplete suggestion from Google"
|
|
63148
63520
|
};
|
|
63149
|
-
var autocompleteCommand =
|
|
63521
|
+
var autocompleteCommand = defineCommand191({
|
|
63150
63522
|
meta: {
|
|
63151
63523
|
name: "autocomplete",
|
|
63152
63524
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -63201,7 +63573,7 @@ Examples:
|
|
|
63201
63573
|
});
|
|
63202
63574
|
|
|
63203
63575
|
// src/commands/research/countries.ts
|
|
63204
|
-
import { defineCommand as
|
|
63576
|
+
import { defineCommand as defineCommand192 } from "citty";
|
|
63205
63577
|
registerSchema({
|
|
63206
63578
|
command: "research.countries",
|
|
63207
63579
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -63258,7 +63630,7 @@ var FIELDS5 = {
|
|
|
63258
63630
|
code: "Country code to pass as --location",
|
|
63259
63631
|
name: "Country name"
|
|
63260
63632
|
};
|
|
63261
|
-
var countriesCommand =
|
|
63633
|
+
var countriesCommand = defineCommand192({
|
|
63262
63634
|
meta: {
|
|
63263
63635
|
name: "countries",
|
|
63264
63636
|
description: "List all supported country codes for --location flag."
|
|
@@ -63269,7 +63641,7 @@ var countriesCommand = defineCommand186({
|
|
|
63269
63641
|
});
|
|
63270
63642
|
|
|
63271
63643
|
// src/commands/research/fetch.ts
|
|
63272
|
-
import { defineCommand as
|
|
63644
|
+
import { defineCommand as defineCommand193 } from "citty";
|
|
63273
63645
|
var CONTENT_PREVIEW_CHARS = 2e4;
|
|
63274
63646
|
var TIMEOUT_MS = 18e4;
|
|
63275
63647
|
registerSchema({
|
|
@@ -63342,7 +63714,7 @@ function fetchFix(code) {
|
|
|
63342
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."
|
|
63343
63715
|
};
|
|
63344
63716
|
}
|
|
63345
|
-
var fetchCommand =
|
|
63717
|
+
var fetchCommand = defineCommand193({
|
|
63346
63718
|
meta: {
|
|
63347
63719
|
name: "fetch",
|
|
63348
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.
|
|
@@ -63419,7 +63791,7 @@ Examples:
|
|
|
63419
63791
|
});
|
|
63420
63792
|
|
|
63421
63793
|
// src/commands/research/intent.ts
|
|
63422
|
-
import { defineCommand as
|
|
63794
|
+
import { defineCommand as defineCommand194 } from "citty";
|
|
63423
63795
|
registerSchema({
|
|
63424
63796
|
command: "research.intent",
|
|
63425
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.",
|
|
@@ -63442,7 +63814,7 @@ var FIELDS7 = {
|
|
|
63442
63814
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
63443
63815
|
probability: "Confidence score 0.0-1.0"
|
|
63444
63816
|
};
|
|
63445
|
-
var intentCommand =
|
|
63817
|
+
var intentCommand = defineCommand194({
|
|
63446
63818
|
meta: {
|
|
63447
63819
|
name: "intent",
|
|
63448
63820
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -63490,7 +63862,7 @@ Examples:
|
|
|
63490
63862
|
});
|
|
63491
63863
|
|
|
63492
63864
|
// src/commands/research/keyword-gap.ts
|
|
63493
|
-
import { defineCommand as
|
|
63865
|
+
import { defineCommand as defineCommand195 } from "citty";
|
|
63494
63866
|
registerSchema({
|
|
63495
63867
|
command: "research.keyword-gap",
|
|
63496
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.",
|
|
@@ -63519,7 +63891,7 @@ var FIELDS8 = {
|
|
|
63519
63891
|
cpc: "Cost per click USD",
|
|
63520
63892
|
their_position: "Competitor's ranking position"
|
|
63521
63893
|
};
|
|
63522
|
-
var keywordGapCommand =
|
|
63894
|
+
var keywordGapCommand = defineCommand195({
|
|
63523
63895
|
meta: {
|
|
63524
63896
|
name: "keyword-gap",
|
|
63525
63897
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -63594,7 +63966,7 @@ Examples:
|
|
|
63594
63966
|
});
|
|
63595
63967
|
|
|
63596
63968
|
// src/commands/research/keyword-metrics.ts
|
|
63597
|
-
import { defineCommand as
|
|
63969
|
+
import { defineCommand as defineCommand196 } from "citty";
|
|
63598
63970
|
|
|
63599
63971
|
// src/commands/research/keyword-metrics-rows.ts
|
|
63600
63972
|
var KEYWORD_METRICS_SOURCE = "keyword_planner_estimate_via_dataforseo";
|
|
@@ -63674,7 +64046,7 @@ registerSchema({
|
|
|
63674
64046
|
"no-cache": { type: "boolean", description: "Skip server cache, hit API directly", required: false }
|
|
63675
64047
|
}
|
|
63676
64048
|
});
|
|
63677
|
-
var keywordMetricsCommand =
|
|
64049
|
+
var keywordMetricsCommand = defineCommand196({
|
|
63678
64050
|
meta: {
|
|
63679
64051
|
name: "keyword-metrics",
|
|
63680
64052
|
description: `Volume, CPC and competition for keywords you name. No domain required.
|
|
@@ -63756,7 +64128,7 @@ Examples:
|
|
|
63756
64128
|
});
|
|
63757
64129
|
|
|
63758
64130
|
// src/commands/research/keywords-for-site.ts
|
|
63759
|
-
import { defineCommand as
|
|
64131
|
+
import { defineCommand as defineCommand197 } from "citty";
|
|
63760
64132
|
registerSchema({
|
|
63761
64133
|
command: "research.keywords-for-site",
|
|
63762
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.",
|
|
@@ -63789,7 +64161,7 @@ var FIELDS9 = {
|
|
|
63789
64161
|
competition: "LOW, MEDIUM, or HIGH",
|
|
63790
64162
|
competition_index: "Competition score 0-100"
|
|
63791
64163
|
};
|
|
63792
|
-
var keywordsForSiteCommand =
|
|
64164
|
+
var keywordsForSiteCommand = defineCommand197({
|
|
63793
64165
|
meta: {
|
|
63794
64166
|
name: "keywords-for-site",
|
|
63795
64167
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -63851,7 +64223,7 @@ Examples:
|
|
|
63851
64223
|
});
|
|
63852
64224
|
|
|
63853
64225
|
// src/commands/research/languages.ts
|
|
63854
|
-
import { defineCommand as
|
|
64226
|
+
import { defineCommand as defineCommand198 } from "citty";
|
|
63855
64227
|
registerSchema({
|
|
63856
64228
|
command: "research.languages",
|
|
63857
64229
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -63881,7 +64253,7 @@ var FIELDS10 = {
|
|
|
63881
64253
|
code: "Language code to pass as --language",
|
|
63882
64254
|
name: "Language name (also accepted by --language)"
|
|
63883
64255
|
};
|
|
63884
|
-
var languagesCommand2 =
|
|
64256
|
+
var languagesCommand2 = defineCommand198({
|
|
63885
64257
|
meta: {
|
|
63886
64258
|
name: "languages",
|
|
63887
64259
|
description: "List all supported language codes for --language flag."
|
|
@@ -63892,7 +64264,7 @@ var languagesCommand2 = defineCommand192({
|
|
|
63892
64264
|
});
|
|
63893
64265
|
|
|
63894
64266
|
// src/commands/research/lighthouse.ts
|
|
63895
|
-
import { defineCommand as
|
|
64267
|
+
import { defineCommand as defineCommand199 } from "citty";
|
|
63896
64268
|
registerSchema({
|
|
63897
64269
|
command: "research.lighthouse",
|
|
63898
64270
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -63911,7 +64283,7 @@ var FIELDS11 = {
|
|
|
63911
64283
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
63912
64284
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
63913
64285
|
};
|
|
63914
|
-
var lighthouseCommand =
|
|
64286
|
+
var lighthouseCommand = defineCommand199({
|
|
63915
64287
|
meta: {
|
|
63916
64288
|
name: "lighthouse",
|
|
63917
64289
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -63949,7 +64321,7 @@ Examples:
|
|
|
63949
64321
|
});
|
|
63950
64322
|
|
|
63951
64323
|
// src/commands/research/relevant-pages.ts
|
|
63952
|
-
import { defineCommand as
|
|
64324
|
+
import { defineCommand as defineCommand200 } from "citty";
|
|
63953
64325
|
registerSchema({
|
|
63954
64326
|
command: "research.relevant-pages",
|
|
63955
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).",
|
|
@@ -63975,7 +64347,7 @@ var FIELDS12 = {
|
|
|
63975
64347
|
keywords: "Total organic keywords the page ranks for",
|
|
63976
64348
|
top_10: "Keywords in positions 1-10"
|
|
63977
64349
|
};
|
|
63978
|
-
var relevantPagesCommand =
|
|
64350
|
+
var relevantPagesCommand = defineCommand200({
|
|
63979
64351
|
meta: {
|
|
63980
64352
|
name: "relevant-pages",
|
|
63981
64353
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -64022,7 +64394,7 @@ Examples:
|
|
|
64022
64394
|
});
|
|
64023
64395
|
|
|
64024
64396
|
// src/commands/research/web.ts
|
|
64025
|
-
import { defineCommand as
|
|
64397
|
+
import { defineCommand as defineCommand201 } from "citty";
|
|
64026
64398
|
registerSchema({
|
|
64027
64399
|
command: "research.web",
|
|
64028
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).",
|
|
@@ -64073,7 +64445,7 @@ async function runDeepResearch(question) {
|
|
|
64073
64445
|
}
|
|
64074
64446
|
throw new Error("Deep research timed out");
|
|
64075
64447
|
}
|
|
64076
|
-
var webCommand =
|
|
64448
|
+
var webCommand = defineCommand201({
|
|
64077
64449
|
meta: {
|
|
64078
64450
|
name: "web",
|
|
64079
64451
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -64135,7 +64507,7 @@ Examples:
|
|
|
64135
64507
|
});
|
|
64136
64508
|
|
|
64137
64509
|
// src/commands/research/index.ts
|
|
64138
|
-
var researchCommand =
|
|
64510
|
+
var researchCommand = defineCommand202({
|
|
64139
64511
|
meta: {
|
|
64140
64512
|
name: "research",
|
|
64141
64513
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -64182,10 +64554,10 @@ Full guide: __tooling__/docs/tools/baker/research.md`
|
|
|
64182
64554
|
});
|
|
64183
64555
|
|
|
64184
64556
|
// src/commands/scheduled-agents/index.ts
|
|
64185
|
-
import { defineCommand as
|
|
64557
|
+
import { defineCommand as defineCommand213 } from "citty";
|
|
64186
64558
|
|
|
64187
64559
|
// src/commands/scheduled-agents/create.ts
|
|
64188
|
-
import { defineCommand as
|
|
64560
|
+
import { defineCommand as defineCommand203 } from "citty";
|
|
64189
64561
|
|
|
64190
64562
|
// src/commands/scheduled-agents/shared.ts
|
|
64191
64563
|
var TEMP_SCHEDULED_AGENT_PREFIX = "temp_agent_";
|
|
@@ -64552,7 +64924,7 @@ registerSchema({
|
|
|
64552
64924
|
}
|
|
64553
64925
|
}
|
|
64554
64926
|
});
|
|
64555
|
-
var createCommand3 =
|
|
64927
|
+
var createCommand3 = defineCommand203({
|
|
64556
64928
|
meta: {
|
|
64557
64929
|
name: "create",
|
|
64558
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'
|
|
@@ -64609,7 +64981,7 @@ var createCommand3 = defineCommand197({
|
|
|
64609
64981
|
});
|
|
64610
64982
|
|
|
64611
64983
|
// src/commands/scheduled-agents/delete.ts
|
|
64612
|
-
import { defineCommand as
|
|
64984
|
+
import { defineCommand as defineCommand204 } from "citty";
|
|
64613
64985
|
registerSchema({
|
|
64614
64986
|
command: "scheduled-agents.delete",
|
|
64615
64987
|
description: "Stage deletion of a published scheduled agent, or cancel one this chat staged (temp_agent_*).",
|
|
@@ -64617,7 +64989,7 @@ registerSchema({
|
|
|
64617
64989
|
id: { type: "string", description: "Published scheduled agent ID or temp_agent_* draft ID", required: true }
|
|
64618
64990
|
}
|
|
64619
64991
|
});
|
|
64620
|
-
var deleteCommand3 =
|
|
64992
|
+
var deleteCommand3 = defineCommand204({
|
|
64621
64993
|
meta: {
|
|
64622
64994
|
name: "delete",
|
|
64623
64995
|
description: "Stage a scheduled agent deletion. Example: baker scheduled-agents delete <id-or-temp_agent_id>"
|
|
@@ -64646,7 +65018,7 @@ var deleteCommand3 = defineCommand198({
|
|
|
64646
65018
|
});
|
|
64647
65019
|
|
|
64648
65020
|
// src/commands/scheduled-agents/get.ts
|
|
64649
|
-
import { defineCommand as
|
|
65021
|
+
import { defineCommand as defineCommand205 } from "citty";
|
|
64650
65022
|
registerSchema({
|
|
64651
65023
|
command: "scheduled-agents.get",
|
|
64652
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.",
|
|
@@ -64655,7 +65027,7 @@ registerSchema({
|
|
|
64655
65027
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
64656
65028
|
}
|
|
64657
65029
|
});
|
|
64658
|
-
var getCommand4 =
|
|
65030
|
+
var getCommand4 = defineCommand205({
|
|
64659
65031
|
meta: {
|
|
64660
65032
|
name: "get",
|
|
64661
65033
|
description: "Get a scheduled agent. Example: baker scheduled-agents get <id-or-temp_agent_id>"
|
|
@@ -64694,7 +65066,7 @@ var getCommand4 = defineCommand199({
|
|
|
64694
65066
|
});
|
|
64695
65067
|
|
|
64696
65068
|
// src/commands/scheduled-agents/list.ts
|
|
64697
|
-
import { defineCommand as
|
|
65069
|
+
import { defineCommand as defineCommand206 } from "citty";
|
|
64698
65070
|
var FULL_DESCRIPTION = "Return every item and staged change as stored, briefs included (tens of KB). Prefer `get <id>` for one item.";
|
|
64699
65071
|
registerSchema({
|
|
64700
65072
|
command: "scheduled-agents.list",
|
|
@@ -64704,7 +65076,7 @@ registerSchema({
|
|
|
64704
65076
|
full: { type: "boolean", description: FULL_DESCRIPTION, required: false }
|
|
64705
65077
|
}
|
|
64706
65078
|
});
|
|
64707
|
-
var
|
|
65079
|
+
var listCommand18 = defineCommand206({
|
|
64708
65080
|
meta: {
|
|
64709
65081
|
name: "list",
|
|
64710
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."
|
|
@@ -64730,7 +65102,7 @@ var listCommand17 = defineCommand200({
|
|
|
64730
65102
|
});
|
|
64731
65103
|
|
|
64732
65104
|
// src/commands/scheduled-agents/run.ts
|
|
64733
|
-
import { defineCommand as
|
|
65105
|
+
import { defineCommand as defineCommand207 } from "citty";
|
|
64734
65106
|
registerSchema({
|
|
64735
65107
|
command: "scheduled-agents.run",
|
|
64736
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.",
|
|
@@ -64738,7 +65110,7 @@ registerSchema({
|
|
|
64738
65110
|
id: { type: "string", description: "Published scheduled agent ID", required: true }
|
|
64739
65111
|
}
|
|
64740
65112
|
});
|
|
64741
|
-
var runCommand2 =
|
|
65113
|
+
var runCommand2 = defineCommand207({
|
|
64742
65114
|
meta: {
|
|
64743
65115
|
name: "run",
|
|
64744
65116
|
description: "Run a published scheduled agent now. Example: baker scheduled-agents run <id>"
|
|
@@ -64770,7 +65142,7 @@ var runCommand2 = defineCommand201({
|
|
|
64770
65142
|
});
|
|
64771
65143
|
|
|
64772
65144
|
// src/commands/scheduled-agents/targets.ts
|
|
64773
|
-
import { defineCommand as
|
|
65145
|
+
import { defineCommand as defineCommand208 } from "citty";
|
|
64774
65146
|
var ARGS2 = {
|
|
64775
65147
|
trigger: {
|
|
64776
65148
|
type: "string",
|
|
@@ -64804,7 +65176,7 @@ registerSchema({
|
|
|
64804
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.",
|
|
64805
65177
|
args: ARGS2
|
|
64806
65178
|
});
|
|
64807
|
-
var targetsCommand =
|
|
65179
|
+
var targetsCommand = defineCommand208({
|
|
64808
65180
|
meta: {
|
|
64809
65181
|
name: "targets",
|
|
64810
65182
|
description: `What a trigger can be pointed at \u2014 so "when a Task is picked up" becomes "when THIS Task is picked up".
|
|
@@ -64847,7 +65219,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
64847
65219
|
// src/commands/scheduled-agents/templates.ts
|
|
64848
65220
|
import { readFile as readFile32 } from "fs/promises";
|
|
64849
65221
|
import path46 from "path";
|
|
64850
|
-
import { defineCommand as
|
|
65222
|
+
import { defineCommand as defineCommand209 } from "citty";
|
|
64851
65223
|
registerSchema({
|
|
64852
65224
|
command: "scheduled-agents.templates",
|
|
64853
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.",
|
|
@@ -64902,7 +65274,7 @@ registerSchema({
|
|
|
64902
65274
|
}
|
|
64903
65275
|
}
|
|
64904
65276
|
});
|
|
64905
|
-
var templatesCommand =
|
|
65277
|
+
var templatesCommand = defineCommand209({
|
|
64906
65278
|
meta: {
|
|
64907
65279
|
name: "templates",
|
|
64908
65280
|
description: `The recipes this company can run \u2014 Baker's own plus theirs, with what each one produces.
|
|
@@ -64998,7 +65370,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
64998
65370
|
});
|
|
64999
65371
|
|
|
65000
65372
|
// src/commands/scheduled-agents/triggers.ts
|
|
65001
|
-
import { defineCommand as
|
|
65373
|
+
import { defineCommand as defineCommand210 } from "citty";
|
|
65002
65374
|
var ARGS3 = {
|
|
65003
65375
|
trigger: {
|
|
65004
65376
|
type: "string",
|
|
@@ -65084,7 +65456,7 @@ function shapeTriggerCatalog(response, filter) {
|
|
|
65084
65456
|
}
|
|
65085
65457
|
return { ok: true, data: { groups, reacting: catalog.reacting } };
|
|
65086
65458
|
}
|
|
65087
|
-
var triggersCommand2 =
|
|
65459
|
+
var triggersCommand2 = defineCommand210({
|
|
65088
65460
|
meta: {
|
|
65089
65461
|
name: "triggers",
|
|
65090
65462
|
description: `Everything that can start a scheduled agent.
|
|
@@ -65114,7 +65486,7 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
65114
65486
|
});
|
|
65115
65487
|
|
|
65116
65488
|
// src/commands/scheduled-agents/unstage.ts
|
|
65117
|
-
import { defineCommand as
|
|
65489
|
+
import { defineCommand as defineCommand211 } from "citty";
|
|
65118
65490
|
registerSchema({
|
|
65119
65491
|
command: "scheduled-agents.unstage",
|
|
65120
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.",
|
|
@@ -65140,7 +65512,7 @@ function unstageBody(args5, chatId) {
|
|
|
65140
65512
|
}
|
|
65141
65513
|
return { chatId, ref: args5.ref, index };
|
|
65142
65514
|
}
|
|
65143
|
-
var unstageCommand =
|
|
65515
|
+
var unstageCommand = defineCommand211({
|
|
65144
65516
|
meta: {
|
|
65145
65517
|
name: "unstage",
|
|
65146
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"
|
|
@@ -65171,7 +65543,7 @@ var unstageCommand = defineCommand205({
|
|
|
65171
65543
|
});
|
|
65172
65544
|
|
|
65173
65545
|
// src/commands/scheduled-agents/update.ts
|
|
65174
|
-
import { defineCommand as
|
|
65546
|
+
import { defineCommand as defineCommand212 } from "citty";
|
|
65175
65547
|
registerSchema({
|
|
65176
65548
|
command: "scheduled-agents.update",
|
|
65177
65549
|
description: "Stage an update to a published scheduled agent, or to one this chat staged (temp_agent_*).",
|
|
@@ -65198,7 +65570,7 @@ registerSchema({
|
|
|
65198
65570
|
enabled: { type: "string", description: "Replacement enabled state", required: false, enum: ["true", "false"] }
|
|
65199
65571
|
}
|
|
65200
65572
|
});
|
|
65201
|
-
var updateCommand4 =
|
|
65573
|
+
var updateCommand4 = defineCommand212({
|
|
65202
65574
|
meta: {
|
|
65203
65575
|
name: "update",
|
|
65204
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"
|
|
@@ -65269,7 +65641,7 @@ var updateCommand4 = defineCommand206({
|
|
|
65269
65641
|
});
|
|
65270
65642
|
|
|
65271
65643
|
// src/commands/scheduled-agents/index.ts
|
|
65272
|
-
var scheduledAgentsCommand =
|
|
65644
|
+
var scheduledAgentsCommand = defineCommand213({
|
|
65273
65645
|
meta: {
|
|
65274
65646
|
name: "scheduled-agents",
|
|
65275
65647
|
description: `Manage Scheduled agents. Subcommands: list, get, triggers, targets, create, update, delete, unstage, run, templates.
|
|
@@ -65298,7 +65670,7 @@ Examples:
|
|
|
65298
65670
|
Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
65299
65671
|
},
|
|
65300
65672
|
subCommands: {
|
|
65301
|
-
list:
|
|
65673
|
+
list: listCommand18,
|
|
65302
65674
|
get: getCommand4,
|
|
65303
65675
|
triggers: triggersCommand2,
|
|
65304
65676
|
targets: targetsCommand,
|
|
@@ -65312,14 +65684,14 @@ Full guide: __tooling__/docs/tools/baker/scheduled-agents.md`
|
|
|
65312
65684
|
});
|
|
65313
65685
|
|
|
65314
65686
|
// src/commands/schema.ts
|
|
65315
|
-
import { defineCommand as
|
|
65687
|
+
import { defineCommand as defineCommand214 } from "citty";
|
|
65316
65688
|
function narrowToFamily(commandName, available) {
|
|
65317
65689
|
const segments = commandName.split(".");
|
|
65318
65690
|
const prefix = segments[0] === "ads" && segments[1] ? `ads.${segments[1]}.` : `${segments[0]}.`;
|
|
65319
65691
|
const siblings = available.filter((name) => name.startsWith(prefix));
|
|
65320
65692
|
return siblings.length > 0 ? siblings : available;
|
|
65321
65693
|
}
|
|
65322
|
-
var schemaCommand2 =
|
|
65694
|
+
var schemaCommand2 = defineCommand214({
|
|
65323
65695
|
meta: {
|
|
65324
65696
|
name: "schema",
|
|
65325
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)"
|
|
@@ -65364,10 +65736,10 @@ var schemaCommand2 = defineCommand208({
|
|
|
65364
65736
|
});
|
|
65365
65737
|
|
|
65366
65738
|
// src/commands/studio/index.ts
|
|
65367
|
-
import { defineCommand as
|
|
65739
|
+
import { defineCommand as defineCommand223 } from "citty";
|
|
65368
65740
|
|
|
65369
65741
|
// src/commands/studio/animate.ts
|
|
65370
|
-
import { defineCommand as
|
|
65742
|
+
import { defineCommand as defineCommand215 } from "citty";
|
|
65371
65743
|
|
|
65372
65744
|
// src/commands/studio/spokenPace.ts
|
|
65373
65745
|
var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
|
|
@@ -65593,7 +65965,7 @@ function parseImageRefs(spec) {
|
|
|
65593
65965
|
}
|
|
65594
65966
|
var defaultDeps = {
|
|
65595
65967
|
ingest: (url) => apiPost("/api/images/ingest", { url, source: "uploaded" }),
|
|
65596
|
-
upload: (
|
|
65968
|
+
upload: (path49) => uploadLocalImage({ file: path49, contentType: detectImageContentType(path49), source: "uploaded" })
|
|
65597
65969
|
};
|
|
65598
65970
|
async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
65599
65971
|
const refs = parseImageRefs(spec);
|
|
@@ -65613,10 +65985,10 @@ async function resolveLibraryImageIds(spec, limit, deps = defaultDeps) {
|
|
|
65613
65985
|
}
|
|
65614
65986
|
return { imageIds, added };
|
|
65615
65987
|
}
|
|
65616
|
-
function uploadFailure(
|
|
65988
|
+
function uploadFailure(path49) {
|
|
65617
65989
|
return (error) => {
|
|
65618
65990
|
if (error instanceof ApiError) throw error;
|
|
65619
|
-
throw new ApiError("VALIDATION_ERROR", `Could not read "${
|
|
65991
|
+
throw new ApiError("VALIDATION_ERROR", `Could not read "${path49}" as an image.`);
|
|
65620
65992
|
};
|
|
65621
65993
|
}
|
|
65622
65994
|
|
|
@@ -65880,7 +66252,7 @@ async function adByHandHintFor(body) {
|
|
|
65880
66252
|
return null;
|
|
65881
66253
|
}
|
|
65882
66254
|
}
|
|
65883
|
-
var animateCommand =
|
|
66255
|
+
var animateCommand = defineCommand215({
|
|
65884
66256
|
meta: {
|
|
65885
66257
|
name: "animate",
|
|
65886
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"
|
|
@@ -66005,7 +66377,7 @@ var animateCommand = defineCommand209({
|
|
|
66005
66377
|
});
|
|
66006
66378
|
|
|
66007
66379
|
// src/commands/studio/generate.ts
|
|
66008
|
-
import { defineCommand as
|
|
66380
|
+
import { defineCommand as defineCommand216 } from "citty";
|
|
66009
66381
|
var MODEL_LIST2 = IMAGE_MODEL_IDS;
|
|
66010
66382
|
var DEFAULT_MAX_WAIT_MS2 = 24e4;
|
|
66011
66383
|
registerSchema({
|
|
@@ -66141,7 +66513,7 @@ function buildGenerateBody(args5, prompt) {
|
|
|
66141
66513
|
}
|
|
66142
66514
|
return body;
|
|
66143
66515
|
}
|
|
66144
|
-
var generateCommand =
|
|
66516
|
+
var generateCommand = defineCommand216({
|
|
66145
66517
|
meta: {
|
|
66146
66518
|
name: "generate",
|
|
66147
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]]'"
|
|
@@ -66224,7 +66596,7 @@ var generateCommand = defineCommand210({
|
|
|
66224
66596
|
});
|
|
66225
66597
|
|
|
66226
66598
|
// src/commands/studio/get.ts
|
|
66227
|
-
import { defineCommand as
|
|
66599
|
+
import { defineCommand as defineCommand217 } from "citty";
|
|
66228
66600
|
registerSchema({
|
|
66229
66601
|
command: "studio.get",
|
|
66230
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.",
|
|
@@ -66233,7 +66605,7 @@ registerSchema({
|
|
|
66233
66605
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
66234
66606
|
}
|
|
66235
66607
|
});
|
|
66236
|
-
var getCommand5 =
|
|
66608
|
+
var getCommand5 = defineCommand217({
|
|
66237
66609
|
meta: {
|
|
66238
66610
|
name: "get",
|
|
66239
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"
|
|
@@ -66262,7 +66634,7 @@ var getCommand5 = defineCommand211({
|
|
|
66262
66634
|
});
|
|
66263
66635
|
|
|
66264
66636
|
// src/commands/studio/improve.ts
|
|
66265
|
-
import { defineCommand as
|
|
66637
|
+
import { defineCommand as defineCommand218 } from "citty";
|
|
66266
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.";
|
|
66267
66639
|
registerSchema({
|
|
66268
66640
|
command: "studio.improve",
|
|
@@ -66287,7 +66659,7 @@ registerSchema({
|
|
|
66287
66659
|
}
|
|
66288
66660
|
}
|
|
66289
66661
|
});
|
|
66290
|
-
var improveCommand =
|
|
66662
|
+
var improveCommand = defineCommand218({
|
|
66291
66663
|
meta: {
|
|
66292
66664
|
name: "improve",
|
|
66293
66665
|
description: `${DESCRIPTION2}
|
|
@@ -66331,7 +66703,7 @@ Examples:
|
|
|
66331
66703
|
});
|
|
66332
66704
|
|
|
66333
66705
|
// src/commands/studio/keep.ts
|
|
66334
|
-
import { defineCommand as
|
|
66706
|
+
import { defineCommand as defineCommand219 } from "citty";
|
|
66335
66707
|
registerSchema({
|
|
66336
66708
|
command: "studio.keep",
|
|
66337
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.",
|
|
@@ -66341,7 +66713,7 @@ registerSchema({
|
|
|
66341
66713
|
undo: { type: "boolean", description: "Un-star an image, or take a kept clip back out", required: false }
|
|
66342
66714
|
}
|
|
66343
66715
|
});
|
|
66344
|
-
var keepCommand =
|
|
66716
|
+
var keepCommand = defineCommand219({
|
|
66345
66717
|
meta: {
|
|
66346
66718
|
name: "keep",
|
|
66347
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"
|
|
@@ -66392,7 +66764,7 @@ var keepCommand = defineCommand213({
|
|
|
66392
66764
|
});
|
|
66393
66765
|
|
|
66394
66766
|
// src/commands/studio/list.ts
|
|
66395
|
-
import { defineCommand as
|
|
66767
|
+
import { defineCommand as defineCommand220 } from "citty";
|
|
66396
66768
|
registerSchema({
|
|
66397
66769
|
command: "studio.list",
|
|
66398
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.",
|
|
@@ -66403,7 +66775,7 @@ registerSchema({
|
|
|
66403
66775
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
66404
66776
|
}
|
|
66405
66777
|
});
|
|
66406
|
-
var
|
|
66778
|
+
var listCommand19 = defineCommand220({
|
|
66407
66779
|
meta: {
|
|
66408
66780
|
name: "list",
|
|
66409
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"
|
|
@@ -66437,7 +66809,7 @@ var listCommand18 = defineCommand214({
|
|
|
66437
66809
|
});
|
|
66438
66810
|
|
|
66439
66811
|
// src/commands/studio/models.ts
|
|
66440
|
-
import { defineCommand as
|
|
66812
|
+
import { defineCommand as defineCommand221 } from "citty";
|
|
66441
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.";
|
|
66442
66814
|
registerSchema({
|
|
66443
66815
|
command: "studio.models",
|
|
@@ -66524,7 +66896,7 @@ function buildModelCards(kind, model) {
|
|
|
66524
66896
|
const selected = model ? ids.filter((id) => id === model) : ids;
|
|
66525
66897
|
return selected.map((id) => build(id));
|
|
66526
66898
|
}
|
|
66527
|
-
var modelsCommand =
|
|
66899
|
+
var modelsCommand = defineCommand221({
|
|
66528
66900
|
meta: {
|
|
66529
66901
|
name: "models",
|
|
66530
66902
|
description: `${DESCRIPTION3}
|
|
@@ -66571,13 +66943,13 @@ Examples:
|
|
|
66571
66943
|
});
|
|
66572
66944
|
|
|
66573
66945
|
// src/commands/studio/skills.ts
|
|
66574
|
-
import { defineCommand as
|
|
66946
|
+
import { defineCommand as defineCommand222 } from "citty";
|
|
66575
66947
|
registerSchema({
|
|
66576
66948
|
command: "studio.skills",
|
|
66577
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.",
|
|
66578
66950
|
args: {}
|
|
66579
66951
|
});
|
|
66580
|
-
var skillsCommand =
|
|
66952
|
+
var skillsCommand = defineCommand222({
|
|
66581
66953
|
meta: {
|
|
66582
66954
|
name: "skills",
|
|
66583
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"
|
|
@@ -66601,7 +66973,7 @@ var skillsCommand = defineCommand216({
|
|
|
66601
66973
|
});
|
|
66602
66974
|
|
|
66603
66975
|
// src/commands/studio/index.ts
|
|
66604
|
-
var studioCommand =
|
|
66976
|
+
var studioCommand = defineCommand223({
|
|
66605
66977
|
meta: {
|
|
66606
66978
|
name: "studio",
|
|
66607
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.
|
|
@@ -66635,7 +67007,7 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
66635
67007
|
generate: generateCommand,
|
|
66636
67008
|
animate: animateCommand,
|
|
66637
67009
|
get: getCommand5,
|
|
66638
|
-
list:
|
|
67010
|
+
list: listCommand19,
|
|
66639
67011
|
keep: keepCommand,
|
|
66640
67012
|
models: modelsCommand,
|
|
66641
67013
|
skills: skillsCommand,
|
|
@@ -66644,10 +67016,10 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
66644
67016
|
});
|
|
66645
67017
|
|
|
66646
67018
|
// src/commands/tag-manager/index.ts
|
|
66647
|
-
import { defineCommand as
|
|
67019
|
+
import { defineCommand as defineCommand227 } from "citty";
|
|
66648
67020
|
|
|
66649
67021
|
// src/commands/tag-manager/draft.ts
|
|
66650
|
-
import { defineCommand as
|
|
67022
|
+
import { defineCommand as defineCommand224 } from "citty";
|
|
66651
67023
|
|
|
66652
67024
|
// src/commands/tag-manager/shared.ts
|
|
66653
67025
|
import { readFileSync as readFileSync21 } from "fs";
|
|
@@ -66714,10 +67086,10 @@ async function stageOp4(op) {
|
|
|
66714
67086
|
handleError8(err);
|
|
66715
67087
|
}
|
|
66716
67088
|
}
|
|
66717
|
-
async function draftAction3(
|
|
67089
|
+
async function draftAction3(path49, body, chat) {
|
|
66718
67090
|
const chatId = resolveChatId(chat);
|
|
66719
67091
|
try {
|
|
66720
|
-
const data = await apiPost(
|
|
67092
|
+
const data = await apiPost(path49, { chatId, ...body });
|
|
66721
67093
|
writeJsonEnvelope({ ok: true, data });
|
|
66722
67094
|
return data;
|
|
66723
67095
|
} catch (err) {
|
|
@@ -66770,13 +67142,13 @@ registerSchema({
|
|
|
66770
67142
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
66771
67143
|
}
|
|
66772
67144
|
});
|
|
66773
|
-
var draftCommand5 =
|
|
67145
|
+
var draftCommand5 = defineCommand224({
|
|
66774
67146
|
meta: {
|
|
66775
67147
|
name: "draft",
|
|
66776
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."
|
|
66777
67149
|
},
|
|
66778
67150
|
subCommands: {
|
|
66779
|
-
list:
|
|
67151
|
+
list: defineCommand224({
|
|
66780
67152
|
meta: {
|
|
66781
67153
|
name: "list",
|
|
66782
67154
|
description: "Review everything staged on this chat (--json for the raw envelope)"
|
|
@@ -66789,7 +67161,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66789
67161
|
await draftList2(args5.json === true, args5.chat);
|
|
66790
67162
|
}
|
|
66791
67163
|
}),
|
|
66792
|
-
show:
|
|
67164
|
+
show: defineCommand224({
|
|
66793
67165
|
meta: {
|
|
66794
67166
|
name: "show",
|
|
66795
67167
|
description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
|
|
@@ -66806,7 +67178,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66806
67178
|
);
|
|
66807
67179
|
}
|
|
66808
67180
|
}),
|
|
66809
|
-
amend:
|
|
67181
|
+
amend: defineCommand224({
|
|
66810
67182
|
meta: {
|
|
66811
67183
|
name: "amend",
|
|
66812
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."
|
|
@@ -66823,7 +67195,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66823
67195
|
});
|
|
66824
67196
|
}
|
|
66825
67197
|
}),
|
|
66826
|
-
remove:
|
|
67198
|
+
remove: defineCommand224({
|
|
66827
67199
|
meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
|
|
66828
67200
|
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
66829
67201
|
run: async ({ args: args5 }) => {
|
|
@@ -66832,7 +67204,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66832
67204
|
});
|
|
66833
67205
|
}
|
|
66834
67206
|
}),
|
|
66835
|
-
clear:
|
|
67207
|
+
clear: defineCommand224({
|
|
66836
67208
|
meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
|
|
66837
67209
|
run: async () => {
|
|
66838
67210
|
await draftAction3("/api/tag-manager/draft/clear", {});
|
|
@@ -66842,7 +67214,7 @@ var draftCommand5 = defineCommand218({
|
|
|
66842
67214
|
});
|
|
66843
67215
|
|
|
66844
67216
|
// src/commands/tag-manager/read.ts
|
|
66845
|
-
import { defineCommand as
|
|
67217
|
+
import { defineCommand as defineCommand225 } from "citty";
|
|
66846
67218
|
registerSchema({
|
|
66847
67219
|
command: "tagManager.containers",
|
|
66848
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.",
|
|
@@ -66883,7 +67255,7 @@ function containersHints(containers) {
|
|
|
66883
67255
|
}))
|
|
66884
67256
|
});
|
|
66885
67257
|
}
|
|
66886
|
-
var containersCommand =
|
|
67258
|
+
var containersCommand = defineCommand225({
|
|
66887
67259
|
meta: {
|
|
66888
67260
|
name: "containers",
|
|
66889
67261
|
description: `List Tag Manager containers reachable by this company's connection.
|
|
@@ -66900,7 +67272,7 @@ Start here:
|
|
|
66900
67272
|
}
|
|
66901
67273
|
}
|
|
66902
67274
|
});
|
|
66903
|
-
var readCommand =
|
|
67275
|
+
var readCommand = defineCommand225({
|
|
66904
67276
|
meta: {
|
|
66905
67277
|
name: "read",
|
|
66906
67278
|
description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
|
|
@@ -66942,7 +67314,7 @@ Examples:
|
|
|
66942
67314
|
});
|
|
66943
67315
|
|
|
66944
67316
|
// src/commands/tag-manager/write-commands.ts
|
|
66945
|
-
import { defineCommand as
|
|
67317
|
+
import { defineCommand as defineCommand226 } from "citty";
|
|
66946
67318
|
var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
|
|
66947
67319
|
var ENTITIES = [
|
|
66948
67320
|
{
|
|
@@ -66998,10 +67370,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
|
|
|
66998
67370
|
});
|
|
66999
67371
|
}
|
|
67000
67372
|
function entityCommand(entity, noun, example) {
|
|
67001
|
-
return
|
|
67373
|
+
return defineCommand226({
|
|
67002
67374
|
meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
|
|
67003
67375
|
subCommands: {
|
|
67004
|
-
create:
|
|
67376
|
+
create: defineCommand226({
|
|
67005
67377
|
meta: {
|
|
67006
67378
|
name: "create",
|
|
67007
67379
|
description: `Stage a new ${noun}
|
|
@@ -67023,7 +67395,7 @@ Examples:
|
|
|
67023
67395
|
});
|
|
67024
67396
|
}
|
|
67025
67397
|
}),
|
|
67026
|
-
update:
|
|
67398
|
+
update: defineCommand226({
|
|
67027
67399
|
meta: {
|
|
67028
67400
|
name: "update",
|
|
67029
67401
|
description: `Stage an update to an existing ${noun} (pass its id or path)`
|
|
@@ -67043,7 +67415,7 @@ Examples:
|
|
|
67043
67415
|
});
|
|
67044
67416
|
}
|
|
67045
67417
|
}),
|
|
67046
|
-
delete:
|
|
67418
|
+
delete: defineCommand226({
|
|
67047
67419
|
meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
|
|
67048
67420
|
args: {
|
|
67049
67421
|
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
@@ -67084,7 +67456,7 @@ function builtinTypes(args5) {
|
|
|
67084
67456
|
}
|
|
67085
67457
|
return raw.split(",").map((entry) => entry.trim());
|
|
67086
67458
|
}
|
|
67087
|
-
var builtinCommand =
|
|
67459
|
+
var builtinCommand = defineCommand226({
|
|
67088
67460
|
meta: {
|
|
67089
67461
|
name: "builtin",
|
|
67090
67462
|
description: `Enable or disable built-in variables
|
|
@@ -67094,7 +67466,7 @@ Examples:
|
|
|
67094
67466
|
baker tag-manager builtin disable --types formId`
|
|
67095
67467
|
},
|
|
67096
67468
|
subCommands: {
|
|
67097
|
-
enable:
|
|
67469
|
+
enable: defineCommand226({
|
|
67098
67470
|
meta: { name: "enable", description: "Stage enabling built-in variables" },
|
|
67099
67471
|
args: {
|
|
67100
67472
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -67108,7 +67480,7 @@ Examples:
|
|
|
67108
67480
|
});
|
|
67109
67481
|
}
|
|
67110
67482
|
}),
|
|
67111
|
-
disable:
|
|
67483
|
+
disable: defineCommand226({
|
|
67112
67484
|
meta: { name: "disable", description: "Stage disabling built-in variables" },
|
|
67113
67485
|
args: {
|
|
67114
67486
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -67126,7 +67498,7 @@ Examples:
|
|
|
67126
67498
|
});
|
|
67127
67499
|
|
|
67128
67500
|
// src/commands/tag-manager/index.ts
|
|
67129
|
-
var tagManagerCommand =
|
|
67501
|
+
var tagManagerCommand = defineCommand227({
|
|
67130
67502
|
meta: {
|
|
67131
67503
|
name: "tag-manager",
|
|
67132
67504
|
description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
|
|
@@ -67163,7 +67535,7 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
|
|
|
67163
67535
|
});
|
|
67164
67536
|
|
|
67165
67537
|
// src/commands/tags/index.ts
|
|
67166
|
-
import { defineCommand as
|
|
67538
|
+
import { defineCommand as defineCommand228 } from "citty";
|
|
67167
67539
|
|
|
67168
67540
|
// src/commands/tags/shared.ts
|
|
67169
67541
|
function failApi3(err) {
|
|
@@ -67243,7 +67615,7 @@ async function listTags(json) {
|
|
|
67243
67615
|
var listArgs12 = {
|
|
67244
67616
|
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
|
|
67245
67617
|
};
|
|
67246
|
-
var
|
|
67618
|
+
var listCommand20 = defineCommand228({
|
|
67247
67619
|
meta: {
|
|
67248
67620
|
name: "list",
|
|
67249
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"
|
|
@@ -67262,7 +67634,7 @@ async function listDraft4(chat) {
|
|
|
67262
67634
|
failApi3(err);
|
|
67263
67635
|
}
|
|
67264
67636
|
}
|
|
67265
|
-
var draftCommand6 =
|
|
67637
|
+
var draftCommand6 = defineCommand228({
|
|
67266
67638
|
meta: {
|
|
67267
67639
|
name: "draft",
|
|
67268
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."
|
|
@@ -67272,7 +67644,7 @@ var draftCommand6 = defineCommand222({
|
|
|
67272
67644
|
await listDraft4(args5.chat);
|
|
67273
67645
|
}
|
|
67274
67646
|
});
|
|
67275
|
-
var tagsCommand4 =
|
|
67647
|
+
var tagsCommand4 = defineCommand228({
|
|
67276
67648
|
meta: {
|
|
67277
67649
|
name: "tags",
|
|
67278
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.
|
|
@@ -67289,7 +67661,7 @@ Examples:
|
|
|
67289
67661
|
Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
67290
67662
|
},
|
|
67291
67663
|
subCommands: {
|
|
67292
|
-
list:
|
|
67664
|
+
list: listCommand20,
|
|
67293
67665
|
draft: draftCommand6
|
|
67294
67666
|
},
|
|
67295
67667
|
// Bare `baker tags` lists the effective tags. `args` stays so citty knows this
|
|
@@ -67301,10 +67673,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
67301
67673
|
});
|
|
67302
67674
|
|
|
67303
67675
|
// src/commands/testimonials/index.ts
|
|
67304
|
-
import { defineCommand as
|
|
67676
|
+
import { defineCommand as defineCommand232 } from "citty";
|
|
67305
67677
|
|
|
67306
67678
|
// src/commands/testimonials/get.ts
|
|
67307
|
-
import { defineCommand as
|
|
67679
|
+
import { defineCommand as defineCommand229 } from "citty";
|
|
67308
67680
|
registerSchema({
|
|
67309
67681
|
command: "testimonials.get",
|
|
67310
67682
|
description: "Get a single testimonial by ID",
|
|
@@ -67312,7 +67684,7 @@ registerSchema({
|
|
|
67312
67684
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
67313
67685
|
}
|
|
67314
67686
|
});
|
|
67315
|
-
var getCommand6 =
|
|
67687
|
+
var getCommand6 = defineCommand229({
|
|
67316
67688
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
67317
67689
|
args: {
|
|
67318
67690
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -67349,7 +67721,7 @@ var getCommand6 = defineCommand223({
|
|
|
67349
67721
|
});
|
|
67350
67722
|
|
|
67351
67723
|
// src/commands/testimonials/list.ts
|
|
67352
|
-
import { defineCommand as
|
|
67724
|
+
import { defineCommand as defineCommand230 } from "citty";
|
|
67353
67725
|
|
|
67354
67726
|
// src/commands/testimonials/emptyCorpusHints.ts
|
|
67355
67727
|
function resolveEmptyReason({
|
|
@@ -67506,7 +67878,7 @@ function buildListParams(args5) {
|
|
|
67506
67878
|
}
|
|
67507
67879
|
return params;
|
|
67508
67880
|
}
|
|
67509
|
-
var
|
|
67881
|
+
var listCommand21 = defineCommand230({
|
|
67510
67882
|
meta: {
|
|
67511
67883
|
name: "list",
|
|
67512
67884
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -67566,7 +67938,7 @@ var listCommand20 = defineCommand224({
|
|
|
67566
67938
|
});
|
|
67567
67939
|
|
|
67568
67940
|
// src/commands/testimonials/search.ts
|
|
67569
|
-
import { defineCommand as
|
|
67941
|
+
import { defineCommand as defineCommand231 } from "citty";
|
|
67570
67942
|
var FILTER_FLAGS2 = ["source", "rating-min", "rating-max", "status", "sentiment", "language", "tags"];
|
|
67571
67943
|
function languageBiasHint(results, requestedLanguage) {
|
|
67572
67944
|
if (requestedLanguage) {
|
|
@@ -67645,7 +68017,7 @@ function buildSearchRequest(query, args5) {
|
|
|
67645
68017
|
}
|
|
67646
68018
|
return body;
|
|
67647
68019
|
}
|
|
67648
|
-
var searchCommand3 =
|
|
68020
|
+
var searchCommand3 = defineCommand231({
|
|
67649
68021
|
meta: {
|
|
67650
68022
|
name: "search",
|
|
67651
68023
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -67709,7 +68081,7 @@ var searchCommand3 = defineCommand225({
|
|
|
67709
68081
|
var tagsCommand5 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
67710
68082
|
|
|
67711
68083
|
// src/commands/testimonials/index.ts
|
|
67712
|
-
var testimonialsCommand =
|
|
68084
|
+
var testimonialsCommand = defineCommand232({
|
|
67713
68085
|
meta: {
|
|
67714
68086
|
name: "testimonials",
|
|
67715
68087
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -67725,16 +68097,16 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
|
|
|
67725
68097
|
subCommands: {
|
|
67726
68098
|
get: getCommand6,
|
|
67727
68099
|
search: searchCommand3,
|
|
67728
|
-
list:
|
|
68100
|
+
list: listCommand21,
|
|
67729
68101
|
tags: tagsCommand5
|
|
67730
68102
|
}
|
|
67731
68103
|
});
|
|
67732
68104
|
|
|
67733
68105
|
// src/commands/videos/index.ts
|
|
67734
|
-
import { defineCommand as
|
|
68106
|
+
import { defineCommand as defineCommand241 } from "citty";
|
|
67735
68107
|
|
|
67736
68108
|
// src/commands/videos/delete.ts
|
|
67737
|
-
import { defineCommand as
|
|
68109
|
+
import { defineCommand as defineCommand233 } from "citty";
|
|
67738
68110
|
registerSchema({
|
|
67739
68111
|
command: "videos.delete",
|
|
67740
68112
|
description: "Delete a video by ID",
|
|
@@ -67748,7 +68120,7 @@ registerSchema({
|
|
|
67748
68120
|
}
|
|
67749
68121
|
}
|
|
67750
68122
|
});
|
|
67751
|
-
var deleteCommand4 =
|
|
68123
|
+
var deleteCommand4 = defineCommand233({
|
|
67752
68124
|
meta: {
|
|
67753
68125
|
name: "delete",
|
|
67754
68126
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -67789,7 +68161,7 @@ var deleteCommand4 = defineCommand227({
|
|
|
67789
68161
|
});
|
|
67790
68162
|
|
|
67791
68163
|
// src/commands/videos/describe.ts
|
|
67792
|
-
import { defineCommand as
|
|
68164
|
+
import { defineCommand as defineCommand234 } from "citty";
|
|
67793
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.";
|
|
67794
68166
|
registerSchema({
|
|
67795
68167
|
command: "videos.describe",
|
|
@@ -67806,7 +68178,7 @@ registerSchema({
|
|
|
67806
68178
|
full: { type: "boolean", description: "Return the whole library row, not just what changed", required: false }
|
|
67807
68179
|
}
|
|
67808
68180
|
});
|
|
67809
|
-
var describeCommand2 =
|
|
68181
|
+
var describeCommand2 = defineCommand234({
|
|
67810
68182
|
meta: {
|
|
67811
68183
|
name: "describe",
|
|
67812
68184
|
description: `Correct what the library says a video is. Only the fields you pass change; the rest keep their current values.
|
|
@@ -67863,108 +68235,10 @@ Example: baker videos describe j571abc123 --description "Customer explaining how
|
|
|
67863
68235
|
}
|
|
67864
68236
|
});
|
|
67865
68237
|
|
|
67866
|
-
// src/commands/videos/
|
|
67867
|
-
import {
|
|
67868
|
-
registerSchema({
|
|
67869
|
-
command: "videos.get",
|
|
67870
|
-
description: "Get a single video by ID",
|
|
67871
|
-
args: {
|
|
67872
|
-
id: { type: "string", description: "Video ID", required: true }
|
|
67873
|
-
}
|
|
67874
|
-
});
|
|
67875
|
-
var getCommand7 = defineCommand229({
|
|
67876
|
-
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
67877
|
-
args: {
|
|
67878
|
-
id: { type: "positional", description: "Video ID", required: false },
|
|
67879
|
-
"video-id": { type: "string", description: "Video ID (alternative to positional)", required: false },
|
|
67880
|
-
output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
|
|
67881
|
-
fields: { type: "string", description: "Comma-separated field names to include", required: false },
|
|
67882
|
-
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
67883
|
-
},
|
|
67884
|
-
run: async ({ args: args5 }) => {
|
|
67885
|
-
try {
|
|
67886
|
-
const id = args5.id || args5["video-id"];
|
|
67887
|
-
if (!id) {
|
|
67888
|
-
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Video ID is required" } });
|
|
67889
|
-
process.exit(1);
|
|
67890
|
-
}
|
|
67891
|
-
validateConvexId(id);
|
|
67892
|
-
const data = await apiGet("/api/videos/get", { id });
|
|
67893
|
-
writeOutput(
|
|
67894
|
-
{ ok: true, data },
|
|
67895
|
-
args5.output || "json",
|
|
67896
|
-
args5.fields ? args5.fields.split(",") : void 0,
|
|
67897
|
-
args5.full,
|
|
67898
|
-
videoNormalizer
|
|
67899
|
-
);
|
|
67900
|
-
} catch (err) {
|
|
67901
|
-
if (err instanceof ApiError) {
|
|
67902
|
-
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
67903
|
-
process.exit(1);
|
|
67904
|
-
}
|
|
67905
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
67906
|
-
process.exit(1);
|
|
67907
|
-
}
|
|
67908
|
-
}
|
|
67909
|
-
});
|
|
67910
|
-
|
|
67911
|
-
// src/commands/videos/group.ts
|
|
67912
|
-
import { defineCommand as defineCommand230 } from "citty";
|
|
67913
|
-
registerSchema({
|
|
67914
|
-
command: "videos.group",
|
|
67915
|
-
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
67916
|
-
args: {
|
|
67917
|
-
id: { type: "string", description: "A video or image id \u2014 returns that asset's whole set", required: false },
|
|
67918
|
-
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
67919
|
-
}
|
|
67920
|
-
});
|
|
67921
|
-
var groupCommand2 = defineCommand230({
|
|
67922
|
-
meta: {
|
|
67923
|
-
name: "group",
|
|
67924
|
-
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>"
|
|
67925
|
-
},
|
|
67926
|
-
args: {
|
|
67927
|
-
id: { type: "positional", description: "A video or image id from the set", required: false },
|
|
67928
|
-
"group-key": { type: "string", description: "The set key, if you already have it", required: false }
|
|
67929
|
-
},
|
|
67930
|
-
run: async ({ args: args5 }) => {
|
|
67931
|
-
await runMediaGroupLookup({
|
|
67932
|
-
id: args5.id,
|
|
67933
|
-
groupKey: args5["group-key"],
|
|
67934
|
-
path: "/api/videos/group",
|
|
67935
|
-
idLabel: "a video or image id"
|
|
67936
|
-
});
|
|
67937
|
-
}
|
|
67938
|
-
});
|
|
67939
|
-
|
|
67940
|
-
// src/commands/videos/ingest.ts
|
|
67941
|
-
import { mkdtemp as mkdtemp3, rm as rm9, stat as stat11 } from "fs/promises";
|
|
67942
|
-
import { tmpdir as tmpdir4 } from "os";
|
|
68238
|
+
// src/commands/videos/fetch.ts
|
|
68239
|
+
import { mkdir as mkdir15 } from "fs/promises";
|
|
67943
68240
|
import path47 from "path";
|
|
67944
|
-
import { defineCommand as
|
|
67945
|
-
|
|
67946
|
-
// src/lib/streamUpload.ts
|
|
67947
|
-
import { createHash as createHash2 } from "crypto";
|
|
67948
|
-
import { createReadStream } from "fs";
|
|
67949
|
-
import { Readable } from "stream";
|
|
67950
|
-
import { pipeline } from "stream/promises";
|
|
67951
|
-
async function hashFile(filePath) {
|
|
67952
|
-
const hash = createHash2("sha256");
|
|
67953
|
-
await pipeline(createReadStream(filePath), hash);
|
|
67954
|
-
return hash.digest("hex");
|
|
67955
|
-
}
|
|
67956
|
-
async function putFileStreamed(args5) {
|
|
67957
|
-
const body = Readable.toWeb(createReadStream(args5.filePath));
|
|
67958
|
-
return await fetch(args5.putUrl, {
|
|
67959
|
-
method: "PUT",
|
|
67960
|
-
body,
|
|
67961
|
-
headers: {
|
|
67962
|
-
"Content-Type": args5.contentType,
|
|
67963
|
-
"Content-Length": String(args5.sizeBytes)
|
|
67964
|
-
},
|
|
67965
|
-
duplex: "half"
|
|
67966
|
-
});
|
|
67967
|
-
}
|
|
68241
|
+
import { defineCommand as defineCommand235 } from "citty";
|
|
67968
68242
|
|
|
67969
68243
|
// src/commands/videos/videoPlatforms.ts
|
|
67970
68244
|
var PLATFORM_DOMAINS = {
|
|
@@ -67973,6 +68247,7 @@ var PLATFORM_DOMAINS = {
|
|
|
67973
68247
|
tiktok: ["tiktok.com"],
|
|
67974
68248
|
twitter: ["twitter.com", "x.com", "vxtwitter.com", "fixvx.com"],
|
|
67975
68249
|
facebook: ["facebook.com", "fb.watch", "fb.com"],
|
|
68250
|
+
linkedin: ["linkedin.com", "lnkd.in"],
|
|
67976
68251
|
reddit: ["reddit.com", "redd.it"],
|
|
67977
68252
|
vimeo: ["vimeo.com"],
|
|
67978
68253
|
dailymotion: ["dailymotion.com", "dai.ly"],
|
|
@@ -68077,6 +68352,188 @@ function safePathname(rawUrl) {
|
|
|
68077
68352
|
}
|
|
68078
68353
|
}
|
|
68079
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
|
+
|
|
68080
68537
|
// src/commands/videos/ingest.ts
|
|
68081
68538
|
registerSchema({
|
|
68082
68539
|
command: "videos.ingest",
|
|
@@ -68105,7 +68562,7 @@ registerSchema({
|
|
|
68105
68562
|
"dry-run": { type: "boolean", description: "Preview the operation without executing", required: false }
|
|
68106
68563
|
}
|
|
68107
68564
|
});
|
|
68108
|
-
var ingestCommand2 =
|
|
68565
|
+
var ingestCommand2 = defineCommand238({
|
|
68109
68566
|
meta: {
|
|
68110
68567
|
name: "ingest",
|
|
68111
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"
|
|
@@ -68291,7 +68748,7 @@ function ingestUrl(args5) {
|
|
|
68291
68748
|
}
|
|
68292
68749
|
async function downloadThenIngest(args5, country) {
|
|
68293
68750
|
const vimeoCookie = captureVimeoCookie();
|
|
68294
|
-
const workDir = await mkdtemp3(
|
|
68751
|
+
const workDir = await mkdtemp3(path48.join(tmpdir4(), "videos-ingest-"));
|
|
68295
68752
|
try {
|
|
68296
68753
|
const probe = await probeYtDlp({ url: args5.url, country, vimeoCookie, cookieDir: workDir });
|
|
68297
68754
|
if (isAudioOnly(probe.info)) {
|
|
@@ -68367,7 +68824,7 @@ async function uploadToAssetStore(filePath, sizeBytes) {
|
|
|
68367
68824
|
}
|
|
68368
68825
|
|
|
68369
68826
|
// src/commands/videos/search.ts
|
|
68370
|
-
import { defineCommand as
|
|
68827
|
+
import { defineCommand as defineCommand239 } from "citty";
|
|
68371
68828
|
registerSchema({
|
|
68372
68829
|
command: "videos.search",
|
|
68373
68830
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -68377,7 +68834,7 @@ registerSchema({
|
|
|
68377
68834
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
68378
68835
|
}
|
|
68379
68836
|
});
|
|
68380
|
-
var searchCommand4 =
|
|
68837
|
+
var searchCommand4 = defineCommand239({
|
|
68381
68838
|
meta: {
|
|
68382
68839
|
name: "search",
|
|
68383
68840
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -68429,7 +68886,7 @@ var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
68429
68886
|
// src/commands/videos/upload.ts
|
|
68430
68887
|
import { readFile as readFile33, stat as stat12 } from "fs/promises";
|
|
68431
68888
|
import { basename as basename3, extname as extname4 } from "path";
|
|
68432
|
-
import { defineCommand as
|
|
68889
|
+
import { defineCommand as defineCommand240 } from "citty";
|
|
68433
68890
|
var MIME_MAP = {
|
|
68434
68891
|
".mp4": "video/mp4",
|
|
68435
68892
|
".mov": "video/quicktime",
|
|
@@ -68471,7 +68928,7 @@ function detectContentType(filePath) {
|
|
|
68471
68928
|
function isRemoteUrl3(value) {
|
|
68472
68929
|
return /^https?:\/\//i.test(value);
|
|
68473
68930
|
}
|
|
68474
|
-
var uploadCommand2 =
|
|
68931
|
+
var uploadCommand2 = defineCommand240({
|
|
68475
68932
|
meta: {
|
|
68476
68933
|
name: "upload",
|
|
68477
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"
|
|
@@ -68555,10 +69012,10 @@ var uploadCommand2 = defineCommand233({
|
|
|
68555
69012
|
});
|
|
68556
69013
|
|
|
68557
69014
|
// src/commands/videos/index.ts
|
|
68558
|
-
var videosCommand =
|
|
69015
|
+
var videosCommand = defineCommand241({
|
|
68559
69016
|
meta: {
|
|
68560
69017
|
name: "videos",
|
|
68561
|
-
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.
|
|
68562
69019
|
|
|
68563
69020
|
Examples:
|
|
68564
69021
|
baker videos search "product demo" --limit 5
|
|
@@ -68566,6 +69023,7 @@ Examples:
|
|
|
68566
69023
|
baker videos get <video-id>
|
|
68567
69024
|
baker videos upload ./demo.mp4
|
|
68568
69025
|
baker videos ingest https://www.youtube.com/watch?v=abc123
|
|
69026
|
+
baker videos fetch https://www.youtube.com/watch?v=abc123 --out ./clips
|
|
68569
69027
|
baker videos describe <video-id> --description "Customer testimonial, 30s"
|
|
68570
69028
|
baker videos delete <video-id> --dry-run
|
|
68571
69029
|
baker videos tags
|
|
@@ -68577,6 +69035,7 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
68577
69035
|
search: searchCommand4,
|
|
68578
69036
|
upload: uploadCommand2,
|
|
68579
69037
|
ingest: ingestCommand2,
|
|
69038
|
+
fetch: fetchCommand2,
|
|
68580
69039
|
describe: describeCommand2,
|
|
68581
69040
|
delete: deleteCommand4,
|
|
68582
69041
|
tags: tagsCommand6
|
|
@@ -68584,10 +69043,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
68584
69043
|
});
|
|
68585
69044
|
|
|
68586
69045
|
// src/commands/winning-ads/index.ts
|
|
68587
|
-
import { defineCommand as
|
|
69046
|
+
import { defineCommand as defineCommand254 } from "citty";
|
|
68588
69047
|
|
|
68589
69048
|
// src/commands/winning-ads/advertisers.ts
|
|
68590
|
-
import { defineCommand as
|
|
69049
|
+
import { defineCommand as defineCommand242 } from "citty";
|
|
68591
69050
|
|
|
68592
69051
|
// src/commands/winning-ads/shared.ts
|
|
68593
69052
|
function splitList3(value) {
|
|
@@ -68596,7 +69055,7 @@ function splitList3(value) {
|
|
|
68596
69055
|
}
|
|
68597
69056
|
return value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
68598
69057
|
}
|
|
68599
|
-
function
|
|
69058
|
+
function reportError3(err) {
|
|
68600
69059
|
if (err instanceof ApiError) {
|
|
68601
69060
|
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
68602
69061
|
process.exit(1);
|
|
@@ -68640,7 +69099,7 @@ function advertiserNormalizer(record, full) {
|
|
|
68640
69099
|
last_synced_at: record.last_synced_at ?? null
|
|
68641
69100
|
};
|
|
68642
69101
|
}
|
|
68643
|
-
var advertisersCommand2 =
|
|
69102
|
+
var advertisersCommand2 = defineCommand242({
|
|
68644
69103
|
meta: {
|
|
68645
69104
|
name: "advertisers",
|
|
68646
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'
|
|
@@ -68692,13 +69151,13 @@ var advertisersCommand2 = defineCommand235({
|
|
|
68692
69151
|
advertiserNormalizer
|
|
68693
69152
|
);
|
|
68694
69153
|
} catch (err) {
|
|
68695
|
-
|
|
69154
|
+
reportError3(err);
|
|
68696
69155
|
}
|
|
68697
69156
|
}
|
|
68698
69157
|
});
|
|
68699
69158
|
|
|
68700
69159
|
// src/commands/winning-ads/brief.ts
|
|
68701
|
-
import { defineCommand as
|
|
69160
|
+
import { defineCommand as defineCommand243 } from "citty";
|
|
68702
69161
|
registerSchema({
|
|
68703
69162
|
command: "winning-ads.brief",
|
|
68704
69163
|
description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
|
|
@@ -68744,7 +69203,7 @@ function parseDna(raw) {
|
|
|
68744
69203
|
}
|
|
68745
69204
|
return parsed;
|
|
68746
69205
|
}
|
|
68747
|
-
var briefCommand =
|
|
69206
|
+
var briefCommand = defineCommand243({
|
|
68748
69207
|
meta: {
|
|
68749
69208
|
name: "brief",
|
|
68750
69209
|
description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
|
|
@@ -68774,13 +69233,13 @@ var briefCommand = defineCommand236({
|
|
|
68774
69233
|
const data = await apiPost("/api/ad-library/brief", body);
|
|
68775
69234
|
writeJson({ ok: true, data });
|
|
68776
69235
|
} catch (err) {
|
|
68777
|
-
|
|
69236
|
+
reportError3(err);
|
|
68778
69237
|
}
|
|
68779
69238
|
}
|
|
68780
69239
|
});
|
|
68781
69240
|
|
|
68782
69241
|
// src/commands/winning-ads/content.ts
|
|
68783
|
-
import { defineCommand as
|
|
69242
|
+
import { defineCommand as defineCommand244 } from "citty";
|
|
68784
69243
|
registerSchema({
|
|
68785
69244
|
command: "winning-ads.content",
|
|
68786
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.",
|
|
@@ -68793,7 +69252,7 @@ registerSchema({
|
|
|
68793
69252
|
}
|
|
68794
69253
|
}
|
|
68795
69254
|
});
|
|
68796
|
-
var contentCommand =
|
|
69255
|
+
var contentCommand = defineCommand244({
|
|
68797
69256
|
meta: {
|
|
68798
69257
|
name: "content",
|
|
68799
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"
|
|
@@ -68836,13 +69295,13 @@ var contentCommand = defineCommand237({
|
|
|
68836
69295
|
adContentNormalizer
|
|
68837
69296
|
);
|
|
68838
69297
|
} catch (err) {
|
|
68839
|
-
|
|
69298
|
+
reportError3(err);
|
|
68840
69299
|
}
|
|
68841
69300
|
}
|
|
68842
69301
|
});
|
|
68843
69302
|
|
|
68844
69303
|
// src/commands/winning-ads/feed.ts
|
|
68845
|
-
import { defineCommand as
|
|
69304
|
+
import { defineCommand as defineCommand245 } from "citty";
|
|
68846
69305
|
function buildFeedParams(input) {
|
|
68847
69306
|
const params = {};
|
|
68848
69307
|
const advertiser = splitList3(input.advertiser);
|
|
@@ -68894,7 +69353,7 @@ registerSchema({
|
|
|
68894
69353
|
format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
|
|
68895
69354
|
}
|
|
68896
69355
|
});
|
|
68897
|
-
var feedCommand2 =
|
|
69356
|
+
var feedCommand2 = defineCommand245({
|
|
68898
69357
|
meta: {
|
|
68899
69358
|
name: "feed",
|
|
68900
69359
|
description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
|
|
@@ -68973,13 +69432,13 @@ var feedCommand2 = defineCommand238({
|
|
|
68973
69432
|
`);
|
|
68974
69433
|
}
|
|
68975
69434
|
} catch (err) {
|
|
68976
|
-
|
|
69435
|
+
reportError3(err);
|
|
68977
69436
|
}
|
|
68978
69437
|
}
|
|
68979
69438
|
});
|
|
68980
69439
|
|
|
68981
69440
|
// src/commands/winning-ads/follow.ts
|
|
68982
|
-
import { defineCommand as
|
|
69441
|
+
import { defineCommand as defineCommand246 } from "citty";
|
|
68983
69442
|
var PLATFORMS = adLibraryPlatformSchema.options;
|
|
68984
69443
|
registerSchema({
|
|
68985
69444
|
command: "winning-ads.follow",
|
|
@@ -68994,7 +69453,7 @@ registerSchema({
|
|
|
68994
69453
|
label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
|
|
68995
69454
|
}
|
|
68996
69455
|
});
|
|
68997
|
-
var followCommand =
|
|
69456
|
+
var followCommand = defineCommand246({
|
|
68998
69457
|
meta: {
|
|
68999
69458
|
name: "follow",
|
|
69000
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'
|
|
@@ -69035,13 +69494,13 @@ var followCommand = defineCommand239({
|
|
|
69035
69494
|
}
|
|
69036
69495
|
writeJson({ ok: true, data, hints: hints2 });
|
|
69037
69496
|
} catch (err) {
|
|
69038
|
-
|
|
69497
|
+
reportError3(err);
|
|
69039
69498
|
}
|
|
69040
69499
|
}
|
|
69041
69500
|
});
|
|
69042
69501
|
|
|
69043
69502
|
// src/commands/winning-ads/follow-competitors.ts
|
|
69044
|
-
import { defineCommand as
|
|
69503
|
+
import { defineCommand as defineCommand247 } from "citty";
|
|
69045
69504
|
var PLATFORMS2 = adLibraryPlatformSchema.options;
|
|
69046
69505
|
var BATCH_TIMEOUT_MS = 3e5;
|
|
69047
69506
|
function buildFollowBatchBody(input) {
|
|
@@ -69074,7 +69533,7 @@ registerSchema({
|
|
|
69074
69533
|
}
|
|
69075
69534
|
}
|
|
69076
69535
|
});
|
|
69077
|
-
var followCompetitorsCommand =
|
|
69536
|
+
var followCompetitorsCommand = defineCommand247({
|
|
69078
69537
|
meta: {
|
|
69079
69538
|
name: "follow-competitors",
|
|
69080
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"'
|
|
@@ -69143,13 +69602,13 @@ var followCompetitorsCommand = defineCommand240({
|
|
|
69143
69602
|
}
|
|
69144
69603
|
writeJson({ ok: true, data, hints: hints2.length > 0 ? hints2 : void 0 });
|
|
69145
69604
|
} catch (err) {
|
|
69146
|
-
|
|
69605
|
+
reportError3(err);
|
|
69147
69606
|
}
|
|
69148
69607
|
}
|
|
69149
69608
|
});
|
|
69150
69609
|
|
|
69151
69610
|
// src/commands/winning-ads/following.ts
|
|
69152
|
-
import { defineCommand as
|
|
69611
|
+
import { defineCommand as defineCommand248 } from "citty";
|
|
69153
69612
|
registerSchema({
|
|
69154
69613
|
command: "winning-ads.following",
|
|
69155
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.",
|
|
@@ -69203,7 +69662,7 @@ function followingNormalizer(record, full) {
|
|
|
69203
69662
|
platforms: Array.isArray(record.platforms) ? record.platforms : []
|
|
69204
69663
|
};
|
|
69205
69664
|
}
|
|
69206
|
-
var followingCommand =
|
|
69665
|
+
var followingCommand = defineCommand248({
|
|
69207
69666
|
meta: {
|
|
69208
69667
|
name: "following",
|
|
69209
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"
|
|
@@ -69233,13 +69692,13 @@ var followingCommand = defineCommand241({
|
|
|
69233
69692
|
followingNormalizer
|
|
69234
69693
|
);
|
|
69235
69694
|
} catch (err) {
|
|
69236
|
-
|
|
69695
|
+
reportError3(err);
|
|
69237
69696
|
}
|
|
69238
69697
|
}
|
|
69239
69698
|
});
|
|
69240
69699
|
|
|
69241
69700
|
// src/commands/winning-ads/patterns.ts
|
|
69242
|
-
import { defineCommand as
|
|
69701
|
+
import { defineCommand as defineCommand249 } from "citty";
|
|
69243
69702
|
registerSchema({
|
|
69244
69703
|
command: "winning-ads.patterns",
|
|
69245
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.",
|
|
@@ -69278,7 +69737,7 @@ function discriminatorRow(record) {
|
|
|
69278
69737
|
top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
|
|
69279
69738
|
};
|
|
69280
69739
|
}
|
|
69281
|
-
var patternsCommand =
|
|
69740
|
+
var patternsCommand = defineCommand249({
|
|
69282
69741
|
meta: {
|
|
69283
69742
|
name: "patterns",
|
|
69284
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"
|
|
@@ -69328,13 +69787,13 @@ var patternsCommand = defineCommand242({
|
|
|
69328
69787
|
(record) => discriminatorRow(record)
|
|
69329
69788
|
);
|
|
69330
69789
|
} catch (err) {
|
|
69331
|
-
|
|
69790
|
+
reportError3(err);
|
|
69332
69791
|
}
|
|
69333
69792
|
}
|
|
69334
69793
|
});
|
|
69335
69794
|
|
|
69336
69795
|
// src/commands/winning-ads/search.ts
|
|
69337
|
-
import { defineCommand as
|
|
69796
|
+
import { defineCommand as defineCommand250 } from "citty";
|
|
69338
69797
|
registerSchema({
|
|
69339
69798
|
command: "winning-ads.search",
|
|
69340
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.",
|
|
@@ -69470,9 +69929,9 @@ function reportSearchError(err) {
|
|
|
69470
69929
|
writeJson({ ok: false, error: { code: err.code, message: err.message, fix } });
|
|
69471
69930
|
process.exit(1);
|
|
69472
69931
|
}
|
|
69473
|
-
|
|
69932
|
+
reportError3(err);
|
|
69474
69933
|
}
|
|
69475
|
-
var searchCommand5 =
|
|
69934
|
+
var searchCommand5 = defineCommand250({
|
|
69476
69935
|
meta: {
|
|
69477
69936
|
name: "search",
|
|
69478
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"
|
|
@@ -69592,7 +70051,7 @@ var searchCommand5 = defineCommand243({
|
|
|
69592
70051
|
});
|
|
69593
70052
|
|
|
69594
70053
|
// src/commands/winning-ads/seeds.ts
|
|
69595
|
-
import { defineCommand as
|
|
70054
|
+
import { defineCommand as defineCommand251 } from "citty";
|
|
69596
70055
|
function leanRow(r) {
|
|
69597
70056
|
return {
|
|
69598
70057
|
key: r.key,
|
|
@@ -69620,7 +70079,7 @@ function makeSeedCommand(opts) {
|
|
|
69620
70079
|
limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
|
|
69621
70080
|
}
|
|
69622
70081
|
});
|
|
69623
|
-
return
|
|
70082
|
+
return defineCommand251({
|
|
69624
70083
|
meta: { name: opts.name, description: opts.description },
|
|
69625
70084
|
args: {
|
|
69626
70085
|
platform: { type: "string", description: "Single platform to segment on", required: false },
|
|
@@ -69647,7 +70106,7 @@ function makeSeedCommand(opts) {
|
|
|
69647
70106
|
}
|
|
69648
70107
|
writeOutput({ ok: true, data: projected }, output);
|
|
69649
70108
|
} catch (err) {
|
|
69650
|
-
|
|
70109
|
+
reportError3(err);
|
|
69651
70110
|
}
|
|
69652
70111
|
}
|
|
69653
70112
|
});
|
|
@@ -69669,7 +70128,7 @@ var formatsCommand = makeSeedCommand({
|
|
|
69669
70128
|
});
|
|
69670
70129
|
|
|
69671
70130
|
// src/commands/winning-ads/unfollow.ts
|
|
69672
|
-
import { defineCommand as
|
|
70131
|
+
import { defineCommand as defineCommand252 } from "citty";
|
|
69673
70132
|
registerSchema({
|
|
69674
70133
|
command: "winning-ads.unfollow",
|
|
69675
70134
|
description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
|
|
@@ -69677,7 +70136,7 @@ registerSchema({
|
|
|
69677
70136
|
advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
|
|
69678
70137
|
}
|
|
69679
70138
|
});
|
|
69680
|
-
var unfollowCommand =
|
|
70139
|
+
var unfollowCommand = defineCommand252({
|
|
69681
70140
|
meta: {
|
|
69682
70141
|
name: "unfollow",
|
|
69683
70142
|
description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
|
|
@@ -69692,13 +70151,13 @@ var unfollowCommand = defineCommand245({
|
|
|
69692
70151
|
});
|
|
69693
70152
|
writeJson({ ok: true, data });
|
|
69694
70153
|
} catch (err) {
|
|
69695
|
-
|
|
70154
|
+
reportError3(err);
|
|
69696
70155
|
}
|
|
69697
70156
|
}
|
|
69698
70157
|
});
|
|
69699
70158
|
|
|
69700
70159
|
// src/commands/winning-ads/winners.ts
|
|
69701
|
-
import { defineCommand as
|
|
70160
|
+
import { defineCommand as defineCommand253 } from "citty";
|
|
69702
70161
|
registerSchema({
|
|
69703
70162
|
command: "winning-ads.winners",
|
|
69704
70163
|
description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
|
|
@@ -69708,7 +70167,7 @@ registerSchema({
|
|
|
69708
70167
|
platform: { type: "string", description: "Filter to a single platform: meta|linkedin|tiktok", required: false }
|
|
69709
70168
|
}
|
|
69710
70169
|
});
|
|
69711
|
-
var winnersCommand =
|
|
70170
|
+
var winnersCommand = defineCommand253({
|
|
69712
70171
|
meta: {
|
|
69713
70172
|
name: "winners",
|
|
69714
70173
|
description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
|
|
@@ -69752,13 +70211,13 @@ var winnersCommand = defineCommand246({
|
|
|
69752
70211
|
winningAdNormalizer
|
|
69753
70212
|
);
|
|
69754
70213
|
} catch (err) {
|
|
69755
|
-
|
|
70214
|
+
reportError3(err);
|
|
69756
70215
|
}
|
|
69757
70216
|
}
|
|
69758
70217
|
});
|
|
69759
70218
|
|
|
69760
70219
|
// src/commands/winning-ads/index.ts
|
|
69761
|
-
var winningAdsCommand =
|
|
70220
|
+
var winningAdsCommand = defineCommand254({
|
|
69762
70221
|
meta: {
|
|
69763
70222
|
name: "winning-ads",
|
|
69764
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.
|
|
@@ -69830,7 +70289,7 @@ function getCliVersion() {
|
|
|
69830
70289
|
}
|
|
69831
70290
|
|
|
69832
70291
|
// src/cli.ts
|
|
69833
|
-
var main =
|
|
70292
|
+
var main = defineCommand255({
|
|
69834
70293
|
meta: {
|
|
69835
70294
|
name: "baker",
|
|
69836
70295
|
version: getCliVersion(),
|
|
@@ -69870,6 +70329,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
69870
70329
|
history: historyCommand2,
|
|
69871
70330
|
hubspot: hubspotCommand,
|
|
69872
70331
|
"winning-ads": winningAdsCommand,
|
|
70332
|
+
"media-sources": mediaSourcesCommand,
|
|
69873
70333
|
mcp: mcpCommand,
|
|
69874
70334
|
schema: schemaCommand2
|
|
69875
70335
|
}
|