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