@koda-sl/baker-cli 0.98.1 → 0.99.0-dev.40c99be71
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/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
AssetRef,
|
|
3
4
|
ELEVENLABS_MAX_MUSIC_LENGTH_MS,
|
|
4
5
|
IMAGE_GENERATE_MODELS,
|
|
5
6
|
MODEL_REGISTRY,
|
|
@@ -7,12 +8,13 @@ import {
|
|
|
7
8
|
ValidationError,
|
|
8
9
|
createEngineFromEnv,
|
|
9
10
|
defaultRegistry,
|
|
11
|
+
extForMime,
|
|
10
12
|
generateCatalog,
|
|
11
13
|
validateCanvasDeep
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FOK2JPRW.js";
|
|
13
15
|
|
|
14
16
|
// src/cli.ts
|
|
15
|
-
import { defineCommand as
|
|
17
|
+
import { defineCommand as defineCommand150, runMain } from "citty";
|
|
16
18
|
|
|
17
19
|
// src/commands/actions/index.ts
|
|
18
20
|
import { defineCommand as defineCommand17 } from "citty";
|
|
@@ -43,6 +45,9 @@ function getEnv() {
|
|
|
43
45
|
}
|
|
44
46
|
return cached;
|
|
45
47
|
}
|
|
48
|
+
function runtimeEnvVar(name) {
|
|
49
|
+
return process.env[name];
|
|
50
|
+
}
|
|
46
51
|
function requireChatId() {
|
|
47
52
|
const env = getEnv();
|
|
48
53
|
if (!env.BAKER_CHAT_ID) {
|
|
@@ -147,9 +152,9 @@ async function handleResponse(response) {
|
|
|
147
152
|
throw new ApiError("INTERNAL_ERROR", "Failed to parse API response as JSON");
|
|
148
153
|
}
|
|
149
154
|
}
|
|
150
|
-
async function apiGet(
|
|
155
|
+
async function apiGet(path12, params) {
|
|
151
156
|
const env = getEnv();
|
|
152
|
-
const url = new URL(
|
|
157
|
+
const url = new URL(path12, env.BAKER_API_URL);
|
|
153
158
|
if (params) {
|
|
154
159
|
const clean = sanitizeParams(params);
|
|
155
160
|
for (const [key, value] of Object.entries(clean)) {
|
|
@@ -174,12 +179,12 @@ async function apiGet(path11, params) {
|
|
|
174
179
|
}
|
|
175
180
|
return handleResponse(response);
|
|
176
181
|
}
|
|
177
|
-
async function apiPost(
|
|
182
|
+
async function apiPost(path12, body, opts) {
|
|
178
183
|
const env = getEnv();
|
|
179
184
|
const timeoutMs = opts?.timeoutMs ?? 6e4;
|
|
180
185
|
let response;
|
|
181
186
|
try {
|
|
182
|
-
response = await fetchWithRateLimitRetry(new URL(
|
|
187
|
+
response = await fetchWithRateLimitRetry(new URL(path12, env.BAKER_API_URL).toString(), {
|
|
183
188
|
method: "POST",
|
|
184
189
|
headers: {
|
|
185
190
|
Authorization: `Bearer ${env.BAKER_API_KEY}`,
|
|
@@ -1327,31 +1332,31 @@ function cachePath(category, key) {
|
|
|
1327
1332
|
return join(dir, `${hashKey(key)}.json`);
|
|
1328
1333
|
}
|
|
1329
1334
|
function cacheGet(category, key) {
|
|
1330
|
-
const
|
|
1331
|
-
if (!existsSync(
|
|
1335
|
+
const path12 = cachePath(category, key);
|
|
1336
|
+
if (!existsSync(path12)) {
|
|
1332
1337
|
return null;
|
|
1333
1338
|
}
|
|
1334
1339
|
try {
|
|
1335
|
-
const raw = readFileSync(
|
|
1340
|
+
const raw = readFileSync(path12, "utf-8");
|
|
1336
1341
|
const entry = JSON.parse(raw);
|
|
1337
1342
|
if (entry.expiresAt < Date.now()) {
|
|
1338
|
-
rmSync(
|
|
1343
|
+
rmSync(path12, { force: true });
|
|
1339
1344
|
return null;
|
|
1340
1345
|
}
|
|
1341
1346
|
return entry;
|
|
1342
1347
|
} catch {
|
|
1343
|
-
rmSync(
|
|
1348
|
+
rmSync(path12, { force: true });
|
|
1344
1349
|
return null;
|
|
1345
1350
|
}
|
|
1346
1351
|
}
|
|
1347
1352
|
function cacheSet(category, key, data, ttlMs, fields) {
|
|
1348
|
-
const
|
|
1353
|
+
const path12 = cachePath(category, key);
|
|
1349
1354
|
const entry = {
|
|
1350
1355
|
expiresAt: Date.now() + ttlMs,
|
|
1351
1356
|
data,
|
|
1352
1357
|
fields
|
|
1353
1358
|
};
|
|
1354
|
-
writeFileSync(
|
|
1359
|
+
writeFileSync(path12, JSON.stringify(entry), "utf-8");
|
|
1355
1360
|
}
|
|
1356
1361
|
var HOUR = 60 * 60 * 1e3;
|
|
1357
1362
|
var MINUTE = 60 * 1e3;
|
|
@@ -8045,7 +8050,7 @@ Examples:
|
|
|
8045
8050
|
});
|
|
8046
8051
|
|
|
8047
8052
|
// src/commands/canvas/index.ts
|
|
8048
|
-
import { defineCommand as
|
|
8053
|
+
import { defineCommand as defineCommand86 } from "citty";
|
|
8049
8054
|
|
|
8050
8055
|
// src/commands/canvas/catalog.ts
|
|
8051
8056
|
import { defineCommand as defineCommand78 } from "citty";
|
|
@@ -8061,14 +8066,231 @@ var catalogCommand = defineCommand78({
|
|
|
8061
8066
|
}
|
|
8062
8067
|
});
|
|
8063
8068
|
|
|
8069
|
+
// src/commands/canvas/gallery.ts
|
|
8070
|
+
import { readdir, readFile } from "fs/promises";
|
|
8071
|
+
import path from "path";
|
|
8072
|
+
import { defineCommand as defineCommand79 } from "citty";
|
|
8073
|
+
|
|
8074
|
+
// src/engine/gallery/descriptor.ts
|
|
8075
|
+
var KNOWN_RATIOS = [
|
|
8076
|
+
["9:16", 9 / 16],
|
|
8077
|
+
["4:5", 4 / 5],
|
|
8078
|
+
["1:1", 1],
|
|
8079
|
+
["1.91:1", 1.91],
|
|
8080
|
+
["16:9", 16 / 9],
|
|
8081
|
+
["4:1", 4]
|
|
8082
|
+
];
|
|
8083
|
+
var RATIO_TOLERANCE = 0.06;
|
|
8084
|
+
function aspectLabel(width, height) {
|
|
8085
|
+
if (!width || !height) {
|
|
8086
|
+
return "other";
|
|
8087
|
+
}
|
|
8088
|
+
const ratio = width / height;
|
|
8089
|
+
let best = "other";
|
|
8090
|
+
let bestErr = Number.POSITIVE_INFINITY;
|
|
8091
|
+
for (const [label, value] of KNOWN_RATIOS) {
|
|
8092
|
+
const err = Math.abs(ratio - value) / value;
|
|
8093
|
+
if (err < bestErr) {
|
|
8094
|
+
bestErr = err;
|
|
8095
|
+
best = label;
|
|
8096
|
+
}
|
|
8097
|
+
}
|
|
8098
|
+
return bestErr <= RATIO_TOLERANCE ? best : `${width}x${height}`;
|
|
8099
|
+
}
|
|
8100
|
+
function visualRef(value) {
|
|
8101
|
+
const parsed = AssetRef.safeParse(value);
|
|
8102
|
+
if (!parsed.success) {
|
|
8103
|
+
return null;
|
|
8104
|
+
}
|
|
8105
|
+
if (parsed.data.kind !== "image" && parsed.data.kind !== "video") {
|
|
8106
|
+
return null;
|
|
8107
|
+
}
|
|
8108
|
+
return parsed.data;
|
|
8109
|
+
}
|
|
8110
|
+
function deliverableFor(ref, stem, resolveLocal) {
|
|
8111
|
+
const width = "width" in ref ? ref.width : void 0;
|
|
8112
|
+
const height = "height" in ref ? ref.height : void 0;
|
|
8113
|
+
return {
|
|
8114
|
+
kind: ref.kind,
|
|
8115
|
+
format: aspectLabel(width, height),
|
|
8116
|
+
// Remote-node outputs already carry a public R2 url; local composites are
|
|
8117
|
+
// resolved against the mounted run dir's public base.
|
|
8118
|
+
url: ref.url ?? resolveLocal(`${stem}.${extForMime(ref.mime)}`),
|
|
8119
|
+
width,
|
|
8120
|
+
height,
|
|
8121
|
+
label: stem
|
|
8122
|
+
};
|
|
8123
|
+
}
|
|
8124
|
+
function deliverablesFromOutput(output, resolveLocal) {
|
|
8125
|
+
if (Array.isArray(output)) {
|
|
8126
|
+
const out = [];
|
|
8127
|
+
output.forEach((entry, i) => {
|
|
8128
|
+
const ref2 = visualRef(entry);
|
|
8129
|
+
if (ref2) {
|
|
8130
|
+
out.push(deliverableFor(ref2, `_final__${i}`, resolveLocal));
|
|
8131
|
+
}
|
|
8132
|
+
});
|
|
8133
|
+
return out;
|
|
8134
|
+
}
|
|
8135
|
+
const ref = visualRef(output);
|
|
8136
|
+
return ref ? [deliverableFor(ref, "_final", resolveLocal)] : [];
|
|
8137
|
+
}
|
|
8138
|
+
function buildGeneration(runId, manifest, resolveLocal) {
|
|
8139
|
+
const m = manifest ?? {};
|
|
8140
|
+
const credits = typeof m.stats?.total_credits === "number" ? m.stats.total_credits : 0;
|
|
8141
|
+
return {
|
|
8142
|
+
runId,
|
|
8143
|
+
createdAt: typeof m.completed_at === "number" ? m.completed_at : 0,
|
|
8144
|
+
credits,
|
|
8145
|
+
deliverables: deliverablesFromOutput(m.output, resolveLocal)
|
|
8146
|
+
};
|
|
8147
|
+
}
|
|
8148
|
+
function buildGalleryDescriptor(input) {
|
|
8149
|
+
const generations = [...input.generations].sort((a, b) => b.createdAt - a.createdAt);
|
|
8150
|
+
return {
|
|
8151
|
+
slug: input.slug,
|
|
8152
|
+
title: input.definition.title,
|
|
8153
|
+
platform: input.definition.platform,
|
|
8154
|
+
status: input.definition.status,
|
|
8155
|
+
reference: input.definition.reference,
|
|
8156
|
+
selectedRun: input.definition.selectedRun,
|
|
8157
|
+
generations
|
|
8158
|
+
};
|
|
8159
|
+
}
|
|
8160
|
+
function titleFromSlug(slug) {
|
|
8161
|
+
return slug.split(/[-_/]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
8162
|
+
}
|
|
8163
|
+
function stripQuotes(raw) {
|
|
8164
|
+
const trimmed = raw.trim();
|
|
8165
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
8166
|
+
return trimmed.slice(1, -1);
|
|
8167
|
+
}
|
|
8168
|
+
return trimmed;
|
|
8169
|
+
}
|
|
8170
|
+
function parseInlineList(raw) {
|
|
8171
|
+
return raw.slice(1, -1).split(",").map((item) => stripQuotes(item)).filter(Boolean);
|
|
8172
|
+
}
|
|
8173
|
+
function parseFrontmatter(markdown) {
|
|
8174
|
+
const match = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
8175
|
+
const block = match?.[1];
|
|
8176
|
+
if (!block) {
|
|
8177
|
+
return {};
|
|
8178
|
+
}
|
|
8179
|
+
const out = {};
|
|
8180
|
+
let listKey = null;
|
|
8181
|
+
for (const line of block.split(/\r?\n/)) {
|
|
8182
|
+
const item = line.match(/^\s+-\s+(.*)$/)?.[1];
|
|
8183
|
+
if (listKey && item !== void 0) {
|
|
8184
|
+
out[listKey].push(stripQuotes(item));
|
|
8185
|
+
continue;
|
|
8186
|
+
}
|
|
8187
|
+
const kv = line.match(/^([A-Za-z0-9_]+):\s*(.*)$/);
|
|
8188
|
+
if (!kv?.[1]) {
|
|
8189
|
+
continue;
|
|
8190
|
+
}
|
|
8191
|
+
listKey = null;
|
|
8192
|
+
const key = kv[1];
|
|
8193
|
+
const value = (kv[2] ?? "").trim();
|
|
8194
|
+
if (value === "") {
|
|
8195
|
+
out[key] = [];
|
|
8196
|
+
listKey = key;
|
|
8197
|
+
} else if (value.startsWith("[") && value.endsWith("]")) {
|
|
8198
|
+
out[key] = parseInlineList(value);
|
|
8199
|
+
} else {
|
|
8200
|
+
out[key] = stripQuotes(value);
|
|
8201
|
+
}
|
|
8202
|
+
}
|
|
8203
|
+
return out;
|
|
8204
|
+
}
|
|
8205
|
+
function asString(value) {
|
|
8206
|
+
if (typeof value === "string" && value.length > 0) {
|
|
8207
|
+
return value;
|
|
8208
|
+
}
|
|
8209
|
+
return void 0;
|
|
8210
|
+
}
|
|
8211
|
+
function asList(value) {
|
|
8212
|
+
if (Array.isArray(value)) {
|
|
8213
|
+
return value;
|
|
8214
|
+
}
|
|
8215
|
+
return typeof value === "string" && value.length > 0 ? [value] : [];
|
|
8216
|
+
}
|
|
8217
|
+
function parseCreativeDefinition(markdown, slug) {
|
|
8218
|
+
const fm = parseFrontmatter(markdown);
|
|
8219
|
+
return {
|
|
8220
|
+
title: asString(fm.title) ?? titleFromSlug(slug),
|
|
8221
|
+
platform: asList(fm.platform),
|
|
8222
|
+
formats: asList(fm.formats),
|
|
8223
|
+
status: asString(fm.status) ?? "draft",
|
|
8224
|
+
reference: asString(fm.reference),
|
|
8225
|
+
selectedRun: asString(fm.selected_run)
|
|
8226
|
+
};
|
|
8227
|
+
}
|
|
8228
|
+
|
|
8229
|
+
// src/commands/canvas/gallery.ts
|
|
8230
|
+
async function readJson(file) {
|
|
8231
|
+
try {
|
|
8232
|
+
return JSON.parse(await readFile(file, "utf8"));
|
|
8233
|
+
} catch {
|
|
8234
|
+
return null;
|
|
8235
|
+
}
|
|
8236
|
+
}
|
|
8237
|
+
async function listRunDirs(runsDir) {
|
|
8238
|
+
try {
|
|
8239
|
+
const entries = await readdir(runsDir, { withFileTypes: true });
|
|
8240
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
8241
|
+
} catch {
|
|
8242
|
+
return [];
|
|
8243
|
+
}
|
|
8244
|
+
}
|
|
8245
|
+
var galleryCommand = defineCommand79({
|
|
8246
|
+
meta: {
|
|
8247
|
+
name: "gallery",
|
|
8248
|
+
description: "Read a creative's _definition.md + every persisted run manifest and emit the gallery descriptor (JSON) the dashboard renders."
|
|
8249
|
+
},
|
|
8250
|
+
args: {
|
|
8251
|
+
dir: { type: "positional", required: true, description: "Creative folder, e.g. src/creatives/<slug>" },
|
|
8252
|
+
"workspace-dir": { type: "string", description: "R2-mounted workspace root (default ./.creatives-workspace)" },
|
|
8253
|
+
"public-url": { type: "string", description: "R2 public base (default $R2_PUBLIC_URL)" },
|
|
8254
|
+
"company-id": { type: "string", description: "Company id for the R2 prefix (default $BAKER_COMPANY_ID)" }
|
|
8255
|
+
},
|
|
8256
|
+
async run({ args }) {
|
|
8257
|
+
const creativeDir = path.resolve(String(args.dir));
|
|
8258
|
+
const slug = path.basename(creativeDir);
|
|
8259
|
+
const workspaceDir = path.resolve(String(args["workspace-dir"] ?? ".creatives-workspace"));
|
|
8260
|
+
const runsDir = path.join(workspaceDir, slug, "runs");
|
|
8261
|
+
const publicUrl = (args["public-url"] ?? runtimeEnvVar("R2_PUBLIC_URL") ?? "").replace(/\/+$/, "");
|
|
8262
|
+
const companyId = String(args["company-id"] ?? runtimeEnvVar("BAKER_COMPANY_ID") ?? "");
|
|
8263
|
+
const definitionPath = path.join(creativeDir, "_definition.md");
|
|
8264
|
+
let definitionMd = "";
|
|
8265
|
+
try {
|
|
8266
|
+
definitionMd = await readFile(definitionPath, "utf8");
|
|
8267
|
+
} catch {
|
|
8268
|
+
}
|
|
8269
|
+
const definition = parseCreativeDefinition(definitionMd, slug);
|
|
8270
|
+
const generations = [];
|
|
8271
|
+
for (const runId of await listRunDirs(runsDir)) {
|
|
8272
|
+
const manifest = await readJson(path.join(runsDir, runId, "manifest.json"));
|
|
8273
|
+
if (!manifest) {
|
|
8274
|
+
continue;
|
|
8275
|
+
}
|
|
8276
|
+
const runDir = path.join(runsDir, runId);
|
|
8277
|
+
const resolveLocal = (filename) => publicUrl && companyId ? `${publicUrl}/creatives/${companyId}/${slug}/runs/${runId}/${filename}` : path.join(runDir, filename);
|
|
8278
|
+
generations.push(buildGeneration(runId, manifest, resolveLocal));
|
|
8279
|
+
}
|
|
8280
|
+
const descriptor = buildGalleryDescriptor({ slug, definition, generations });
|
|
8281
|
+
process.stdout.write(`${JSON.stringify({ ok: true, descriptor }, null, 2)}
|
|
8282
|
+
`);
|
|
8283
|
+
}
|
|
8284
|
+
});
|
|
8285
|
+
|
|
8064
8286
|
// src/commands/canvas/inspect.ts
|
|
8065
8287
|
import { execFile } from "child_process";
|
|
8066
|
-
import { readdir, readFile, stat } from "fs/promises";
|
|
8067
|
-
import
|
|
8288
|
+
import { readdir as readdir2, readFile as readFile2, stat } from "fs/promises";
|
|
8289
|
+
import path2 from "path";
|
|
8068
8290
|
import { promisify } from "util";
|
|
8069
|
-
import { defineCommand as
|
|
8291
|
+
import { defineCommand as defineCommand80 } from "citty";
|
|
8070
8292
|
var execFileAsync = promisify(execFile);
|
|
8071
|
-
var inspectCommand =
|
|
8293
|
+
var inspectCommand = defineCommand80({
|
|
8072
8294
|
meta: {
|
|
8073
8295
|
name: "inspect",
|
|
8074
8296
|
description: "Dump a one-page summary of a canvas run: per-node duration + cache status, list of output files in the run dir, and optionally three thumbnail frames per video output. Pass either a run_id (resolved against --outputs-dir) or an absolute run directory."
|
|
@@ -8082,7 +8304,7 @@ var inspectCommand = defineCommand79({
|
|
|
8082
8304
|
}
|
|
8083
8305
|
},
|
|
8084
8306
|
async run({ args }) {
|
|
8085
|
-
const outputsDir =
|
|
8307
|
+
const outputsDir = path2.resolve(String(args["outputs-dir"] ?? "canvas"));
|
|
8086
8308
|
const runArg = String(args.run);
|
|
8087
8309
|
const runDir = await resolveRunDir(runArg, outputsDir);
|
|
8088
8310
|
const manifest = await loadManifest(runDir);
|
|
@@ -8094,7 +8316,7 @@ var inspectCommand = defineCommand79({
|
|
|
8094
8316
|
}
|
|
8095
8317
|
const summary = {
|
|
8096
8318
|
ok: true,
|
|
8097
|
-
run_id: manifest.run_id ??
|
|
8319
|
+
run_id: manifest.run_id ?? path2.basename(runDir),
|
|
8098
8320
|
run_dir: runDir,
|
|
8099
8321
|
stats: manifest.stats ?? null,
|
|
8100
8322
|
output: manifest.output ?? null,
|
|
@@ -8107,20 +8329,20 @@ var inspectCommand = defineCommand79({
|
|
|
8107
8329
|
}
|
|
8108
8330
|
});
|
|
8109
8331
|
async function resolveRunDir(run, outputsDir) {
|
|
8110
|
-
if (
|
|
8332
|
+
if (path2.isAbsolute(run)) {
|
|
8111
8333
|
const s2 = await stat(run).catch(() => null);
|
|
8112
8334
|
if (s2?.isDirectory()) return run;
|
|
8113
8335
|
throw new Error(`inspect: ${run} is not a directory`);
|
|
8114
8336
|
}
|
|
8115
|
-
const candidate =
|
|
8337
|
+
const candidate = path2.join(outputsDir, run);
|
|
8116
8338
|
const s = await stat(candidate).catch(() => null);
|
|
8117
8339
|
if (s?.isDirectory()) return candidate;
|
|
8118
8340
|
throw new Error(`inspect: no run directory at ${candidate}`);
|
|
8119
8341
|
}
|
|
8120
8342
|
async function loadManifest(runDir) {
|
|
8121
|
-
const manifestPath =
|
|
8343
|
+
const manifestPath = path2.join(runDir, "manifest.json");
|
|
8122
8344
|
try {
|
|
8123
|
-
const raw = await
|
|
8345
|
+
const raw = await readFile2(manifestPath, "utf-8");
|
|
8124
8346
|
return JSON.parse(raw);
|
|
8125
8347
|
} catch {
|
|
8126
8348
|
return {};
|
|
@@ -8128,9 +8350,9 @@ async function loadManifest(runDir) {
|
|
|
8128
8350
|
}
|
|
8129
8351
|
async function listRunFiles(runDir) {
|
|
8130
8352
|
const out = [];
|
|
8131
|
-
const names = await
|
|
8353
|
+
const names = await readdir2(runDir);
|
|
8132
8354
|
for (const name of names) {
|
|
8133
|
-
const abs =
|
|
8355
|
+
const abs = path2.join(runDir, name);
|
|
8134
8356
|
const s = await stat(abs).catch(() => null);
|
|
8135
8357
|
if (!s?.isFile()) continue;
|
|
8136
8358
|
out.push({ name, path: abs, size: s.size });
|
|
@@ -8175,9 +8397,9 @@ async function probeDuration(filePath) {
|
|
|
8175
8397
|
}
|
|
8176
8398
|
|
|
8177
8399
|
// src/commands/canvas/run.ts
|
|
8178
|
-
import { readFile as
|
|
8179
|
-
import
|
|
8180
|
-
import { defineCommand as
|
|
8400
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
8401
|
+
import path5 from "path";
|
|
8402
|
+
import { defineCommand as defineCommand81 } from "citty";
|
|
8181
8403
|
|
|
8182
8404
|
// src/commands/canvas/placeholders.ts
|
|
8183
8405
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
@@ -8196,7 +8418,7 @@ function unsuppliedPlaceholderAssets(canvas) {
|
|
|
8196
8418
|
}
|
|
8197
8419
|
|
|
8198
8420
|
// src/commands/canvas/resolve-paths.ts
|
|
8199
|
-
import
|
|
8421
|
+
import path3 from "path";
|
|
8200
8422
|
function resolveRelativeCanvasPaths(canvas, baseDir) {
|
|
8201
8423
|
if (!canvas || typeof canvas !== "object") return canvas;
|
|
8202
8424
|
const c = canvas;
|
|
@@ -8209,37 +8431,37 @@ function resolveNode(node, baseDir) {
|
|
|
8209
8431
|
const params = n.params;
|
|
8210
8432
|
if (!params || typeof params !== "object") return node;
|
|
8211
8433
|
if (n.type === "ingest" && params.source === "path" && isResolvableRelative(params.path)) {
|
|
8212
|
-
return { ...node, params: { ...params, path:
|
|
8434
|
+
return { ...node, params: { ...params, path: path3.resolve(baseDir, params.path) } };
|
|
8213
8435
|
}
|
|
8214
8436
|
if (n.type === "hyperframe_render" && isResolvableRelative(params.composition)) {
|
|
8215
|
-
return { ...node, params: { ...params, composition:
|
|
8437
|
+
return { ...node, params: { ...params, composition: path3.resolve(baseDir, params.composition) } };
|
|
8216
8438
|
}
|
|
8217
8439
|
return node;
|
|
8218
8440
|
}
|
|
8219
8441
|
function isResolvableRelative(value) {
|
|
8220
|
-
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !
|
|
8442
|
+
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !path3.isAbsolute(value);
|
|
8221
8443
|
}
|
|
8222
8444
|
|
|
8223
8445
|
// src/commands/canvas/run-retention.ts
|
|
8224
8446
|
import { rm } from "fs/promises";
|
|
8225
|
-
import
|
|
8447
|
+
import path4 from "path";
|
|
8226
8448
|
function runDirsToPrune(entries, keep, currentRunId) {
|
|
8227
8449
|
const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
|
|
8228
8450
|
if (keep <= 0) return runs;
|
|
8229
8451
|
return runs.slice(0, Math.max(0, runs.length - keep));
|
|
8230
8452
|
}
|
|
8231
8453
|
async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
8232
|
-
const { readdir:
|
|
8454
|
+
const { readdir: readdir4 } = await import("fs/promises");
|
|
8233
8455
|
let entries;
|
|
8234
8456
|
try {
|
|
8235
|
-
entries = await
|
|
8457
|
+
entries = await readdir4(outputsDir);
|
|
8236
8458
|
} catch {
|
|
8237
8459
|
return;
|
|
8238
8460
|
}
|
|
8239
8461
|
const toPrune = runDirsToPrune(entries, keep, currentRunId);
|
|
8240
8462
|
if (toPrune.length === 0) return;
|
|
8241
8463
|
for (const dir of toPrune) {
|
|
8242
|
-
await rm(
|
|
8464
|
+
await rm(path4.join(outputsDir, dir), { recursive: true, force: true }).catch(
|
|
8243
8465
|
(e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
|
|
8244
8466
|
);
|
|
8245
8467
|
}
|
|
@@ -8247,7 +8469,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
8247
8469
|
}
|
|
8248
8470
|
|
|
8249
8471
|
// src/commands/canvas/run.ts
|
|
8250
|
-
var runCommand =
|
|
8472
|
+
var runCommand = defineCommand81({
|
|
8251
8473
|
meta: { name: "run", description: "Validate and execute a canvas JSON file." },
|
|
8252
8474
|
args: {
|
|
8253
8475
|
file: { type: "positional", required: true, description: "Path to canvas JSON" },
|
|
@@ -8261,8 +8483,8 @@ var runCommand = defineCommand80({
|
|
|
8261
8483
|
}
|
|
8262
8484
|
},
|
|
8263
8485
|
async run({ args }) {
|
|
8264
|
-
const filePath =
|
|
8265
|
-
const raw = await
|
|
8486
|
+
const filePath = path5.resolve(String(args.file));
|
|
8487
|
+
const raw = await readFile3(filePath, "utf8");
|
|
8266
8488
|
let parsed;
|
|
8267
8489
|
try {
|
|
8268
8490
|
parsed = JSON.parse(raw);
|
|
@@ -8272,7 +8494,7 @@ var runCommand = defineCommand80({
|
|
|
8272
8494
|
`);
|
|
8273
8495
|
process.exit(2);
|
|
8274
8496
|
}
|
|
8275
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
8497
|
+
parsed = resolveRelativeCanvasPaths(parsed, path5.dirname(filePath));
|
|
8276
8498
|
const pending = unsuppliedPlaceholderAssets(parsed);
|
|
8277
8499
|
if (pending.length > 0) {
|
|
8278
8500
|
process.stderr.write(
|
|
@@ -8306,7 +8528,7 @@ var runCommand = defineCommand80({
|
|
|
8306
8528
|
});
|
|
8307
8529
|
const keepRuns = args["keep-runs"] !== void 0 ? Number(args["keep-runs"]) : void 0;
|
|
8308
8530
|
if (keepRuns !== void 0 && Number.isFinite(keepRuns)) {
|
|
8309
|
-
const outputsDir = args["outputs-dir"] ?
|
|
8531
|
+
const outputsDir = args["outputs-dir"] ? path5.resolve(String(args["outputs-dir"])) : path5.resolve("canvas");
|
|
8310
8532
|
await pruneOldRuns(outputsDir, keepRuns, result.run_id, (line) => process.stdout.write(`${line}
|
|
8311
8533
|
`));
|
|
8312
8534
|
}
|
|
@@ -8341,9 +8563,9 @@ var runCommand = defineCommand80({
|
|
|
8341
8563
|
});
|
|
8342
8564
|
|
|
8343
8565
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
8344
|
-
import { readFile as
|
|
8345
|
-
import
|
|
8346
|
-
import { defineCommand as
|
|
8566
|
+
import { readFile as readFile4, writeFile } from "fs/promises";
|
|
8567
|
+
import path6 from "path";
|
|
8568
|
+
import { defineCommand as defineCommand82 } from "citty";
|
|
8347
8569
|
|
|
8348
8570
|
// src/engine/scaffold/staticAd.ts
|
|
8349
8571
|
import { z as z2 } from "zod";
|
|
@@ -8556,7 +8778,7 @@ var SELECT_SYSTEM = 'You identify the MAIN, identity-critical visual elements of
|
|
|
8556
8778
|
var SELECT_PROMPT = 'AD BLUEPRINT (from image_describe):\n{{blueprint}}\n\nFrom this blueprint, list ONLY the elements that are prominent, important, and identity-bearing \u2014 the ones a reproduction must ground in a real asset:\n- the brand logo/wordmark (from brands_logos with function_in_image = advertiser_brand) -> type "logo"\n- trust/rating/certification/app-store/review badges (brands_logos with function_in_image = trust_badge | review_platform | certification_or_seal | app_store_badge | payment_method) -> type "badge"\n- a showcased/hero product or package (a foreground entry in subjects that the ad is selling) -> type "product"\n- a foreground person whose identity matters (from people) -> type "person"\n- a foreground animal/character with a specific expression (from subjects) -> type "animal"\n\nDROP background extras, decorative props, generic scenery, and anything small or incidental. Keep at most ~6. If there are none, return an empty list.\n\nFor each kept element return: { "type": one of logo|product|person|animal|badge, "label": a short UPPER_SNAKE_CASE name (e.g. LOGO, PRODUCT, HERO_DOG, TRUSTPILOT), "description": a concrete reusable description to source/shoot the real asset (include the exact expression for a living subject), "expression": the facial expression for a living subject or null, "reason": why it is identity-critical, "locator": the blueprint entry this element came from as { "collection": one of "subjects" | "people" | "brands_logos", "index": its 0-based position in that array } (people -> people; logos/badges -> brands_logos; products/animals/objects -> subjects). Output ONLY the JSON object.';
|
|
8557
8779
|
async function loadAssetText(ref, label) {
|
|
8558
8780
|
const r = ref;
|
|
8559
|
-
if (typeof r?.path === "string") return
|
|
8781
|
+
if (typeof r?.path === "string") return readFile4(r.path, "utf8");
|
|
8560
8782
|
if (typeof r?.url === "string") {
|
|
8561
8783
|
const res = await fetch(r.url);
|
|
8562
8784
|
if (!res.ok) throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
@@ -8662,7 +8884,7 @@ async function runVisionPasses(canvas) {
|
|
|
8662
8884
|
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
8663
8885
|
}
|
|
8664
8886
|
}
|
|
8665
|
-
var scaffoldStaticAdCommand =
|
|
8887
|
+
var scaffoldStaticAdCommand = defineCommand82({
|
|
8666
8888
|
meta: {
|
|
8667
8889
|
name: "scaffold-static-ad",
|
|
8668
8890
|
description: "Turn a source/inspiration image into a runnable static-ad canvas. Runs billed passes \u2014 image_describe (the blueprint, baked to prompt.json as the editable 'prompt'), an AI selection of the image's MAIN identity elements, and a structured global-layout pass (the column/row grid with per-region bounds and text sizes) \u2014 then scaffolds a canvas that wires one [TODO] ingest slot per element (logo/product/subject/badge + brand font) into image_generate. Edit prompt.json and drop the real assets, then `baker canvas run` it."
|
|
@@ -8679,10 +8901,10 @@ var scaffoldStaticAdCommand = defineCommand81({
|
|
|
8679
8901
|
"skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
|
|
8680
8902
|
},
|
|
8681
8903
|
async run({ args }) {
|
|
8682
|
-
const imagePath =
|
|
8683
|
-
const outPath = args.out ?
|
|
8684
|
-
const outDir =
|
|
8685
|
-
const blueprintPath =
|
|
8904
|
+
const imagePath = path6.resolve(String(args.file));
|
|
8905
|
+
const outPath = args.out ? path6.resolve(String(args.out)) : path6.join(path6.dirname(imagePath), "static-ad.canvas.json");
|
|
8906
|
+
const outDir = path6.dirname(outPath);
|
|
8907
|
+
const blueprintPath = path6.join(outDir, "prompt.json");
|
|
8686
8908
|
const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
|
|
8687
8909
|
const describeCanvas = buildDescribeCanvas(
|
|
8688
8910
|
imagePath,
|
|
@@ -8739,7 +8961,7 @@ var scaffoldStaticAdCommand = defineCommand81({
|
|
|
8739
8961
|
run_estimated_credits: validation.estimatedCredits
|
|
8740
8962
|
},
|
|
8741
8963
|
checklist: {
|
|
8742
|
-
edit_prompt: `Edit ${
|
|
8964
|
+
edit_prompt: `Edit ${path6.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
|
|
8743
8965
|
assets_to_supply: report.elements,
|
|
8744
8966
|
font_slot: report.includes_font ? "Drop a brand font at the [TODO] brandfont path, or delete the brandfont + type_ref nodes to skip it." : "skipped (--skip-font)",
|
|
8745
8967
|
note: "Replace every [TODO] ingest path with a real file, then `baker canvas validate` and `baker canvas run`. Running generates a billed image \u2014 it is not free."
|
|
@@ -8754,13 +8976,13 @@ var scaffoldStaticAdCommand = defineCommand81({
|
|
|
8754
8976
|
});
|
|
8755
8977
|
|
|
8756
8978
|
// src/commands/canvas/scaffold-video.ts
|
|
8757
|
-
import { cp, mkdir, readFile as
|
|
8758
|
-
import
|
|
8759
|
-
import { defineCommand as
|
|
8979
|
+
import { cp, mkdir, readFile as readFile7, writeFile as writeFile2 } from "fs/promises";
|
|
8980
|
+
import path9 from "path";
|
|
8981
|
+
import { defineCommand as defineCommand83 } from "citty";
|
|
8760
8982
|
|
|
8761
8983
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
8762
8984
|
import { execFile as execFile2 } from "child_process";
|
|
8763
|
-
import { mkdtemp, readdir as
|
|
8985
|
+
import { mkdtemp, readdir as readdir3, readFile as readFile5, rm as rm2 } from "fs/promises";
|
|
8764
8986
|
import { tmpdir } from "os";
|
|
8765
8987
|
import { join as join2 } from "path";
|
|
8766
8988
|
import { promisify as promisify2 } from "util";
|
|
@@ -8824,9 +9046,9 @@ async function runSceneDetectOnce(filePath, threshold, minSceneLenS, timeoutMs)
|
|
|
8824
9046
|
],
|
|
8825
9047
|
{ encoding: "utf-8", maxBuffer: 32 * 1024 * 1024, timeout: timeoutMs }
|
|
8826
9048
|
);
|
|
8827
|
-
const csvName = (await
|
|
9049
|
+
const csvName = (await readdir3(outDir)).find((f) => f.toLowerCase().endsWith(".csv"));
|
|
8828
9050
|
if (!csvName) return [];
|
|
8829
|
-
return parsePySceneDetectCsvCuts(await
|
|
9051
|
+
return parsePySceneDetectCsvCuts(await readFile5(join2(outDir, csvName), "utf-8"));
|
|
8830
9052
|
} finally {
|
|
8831
9053
|
await rm2(outDir, { recursive: true, force: true });
|
|
8832
9054
|
}
|
|
@@ -11371,23 +11593,23 @@ function videoReport(input, elementsInput) {
|
|
|
11371
11593
|
|
|
11372
11594
|
// src/commands/canvas/composition-path.ts
|
|
11373
11595
|
import { existsSync as existsSync3 } from "fs";
|
|
11374
|
-
import
|
|
11596
|
+
import path7 from "path";
|
|
11375
11597
|
function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
|
|
11376
|
-
const rel =
|
|
11598
|
+
const rel = path7.join("canvas", name);
|
|
11377
11599
|
let dir = startDir;
|
|
11378
11600
|
for (let i = 0; i < maxDepth; i++) {
|
|
11379
|
-
const candidate =
|
|
11380
|
-
if (exists(
|
|
11381
|
-
const parent =
|
|
11601
|
+
const candidate = path7.join(dir, rel);
|
|
11602
|
+
if (exists(path7.join(candidate, "meta.json"))) return candidate;
|
|
11603
|
+
const parent = path7.dirname(dir);
|
|
11382
11604
|
if (parent === dir) break;
|
|
11383
11605
|
dir = parent;
|
|
11384
11606
|
}
|
|
11385
|
-
return
|
|
11607
|
+
return path7.resolve(startDir, "../../../", rel);
|
|
11386
11608
|
}
|
|
11387
11609
|
|
|
11388
11610
|
// src/commands/canvas/gitignore.ts
|
|
11389
|
-
import { appendFile, readFile as
|
|
11390
|
-
import
|
|
11611
|
+
import { appendFile, readFile as readFile6 } from "fs/promises";
|
|
11612
|
+
import path8 from "path";
|
|
11391
11613
|
function missingGitignoreEntries(existing, entries) {
|
|
11392
11614
|
const present = new Set(
|
|
11393
11615
|
existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
|
|
@@ -11395,10 +11617,10 @@ function missingGitignoreEntries(existing, entries) {
|
|
|
11395
11617
|
return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
|
|
11396
11618
|
}
|
|
11397
11619
|
async function ensureGitignore(dir, entries) {
|
|
11398
|
-
const file =
|
|
11620
|
+
const file = path8.join(dir, ".gitignore");
|
|
11399
11621
|
let existing;
|
|
11400
11622
|
try {
|
|
11401
|
-
existing = await
|
|
11623
|
+
existing = await readFile6(file, "utf8");
|
|
11402
11624
|
} catch {
|
|
11403
11625
|
return;
|
|
11404
11626
|
}
|
|
@@ -11437,7 +11659,7 @@ ONE PERSON, MULTIPLE LOOKS: if a single individual plays MULTIPLE personas or wa
|
|
|
11437
11659
|
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.`;
|
|
11438
11660
|
async function loadAssetText2(ref, label) {
|
|
11439
11661
|
const r = ref;
|
|
11440
|
-
if (typeof r?.path === "string") return
|
|
11662
|
+
if (typeof r?.path === "string") return readFile7(r.path, "utf8");
|
|
11441
11663
|
if (typeof r?.url === "string") {
|
|
11442
11664
|
const res = await fetch(r.url);
|
|
11443
11665
|
if (!res.ok) throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
@@ -11456,7 +11678,7 @@ async function loadTranscriptBestEffort(ref) {
|
|
|
11456
11678
|
async function stageCaptions(outDir, transcript) {
|
|
11457
11679
|
const text = transcript?.trim();
|
|
11458
11680
|
if (!text || text === "[]") return {};
|
|
11459
|
-
const compositionPath =
|
|
11681
|
+
const compositionPath = path9.join(outDir, "tiktok-captions-composition");
|
|
11460
11682
|
await cp(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
|
|
11461
11683
|
return { compositionPath };
|
|
11462
11684
|
}
|
|
@@ -11588,7 +11810,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
11588
11810
|
return fail2("deconstruct", e instanceof Error ? e.message : String(e));
|
|
11589
11811
|
}
|
|
11590
11812
|
}
|
|
11591
|
-
var scaffoldVideoCommand =
|
|
11813
|
+
var scaffoldVideoCommand = defineCommand83({
|
|
11592
11814
|
meta: {
|
|
11593
11815
|
name: "scaffold-video",
|
|
11594
11816
|
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 prompt.json as the editable 'prompt') 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 prompt.json, drop the real source images, then `baker canvas run`."
|
|
@@ -11618,11 +11840,11 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11618
11840
|
}
|
|
11619
11841
|
},
|
|
11620
11842
|
async run({ args }) {
|
|
11621
|
-
const videoPath =
|
|
11622
|
-
const base =
|
|
11623
|
-
const outPath = args.out ?
|
|
11624
|
-
const outDir =
|
|
11625
|
-
const blueprintPath =
|
|
11843
|
+
const videoPath = path9.resolve(String(args.file));
|
|
11844
|
+
const base = path9.basename(videoPath, path9.extname(videoPath));
|
|
11845
|
+
const outPath = args.out ? path9.resolve(String(args.out)) : path9.join(path9.dirname(videoPath), `${base}.video.canvas.json`);
|
|
11846
|
+
const outDir = path9.dirname(outPath);
|
|
11847
|
+
const blueprintPath = path9.join(outDir, "prompt.json");
|
|
11626
11848
|
const frames = args.frames === "reuse" ? "reuse" : "generate";
|
|
11627
11849
|
const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
|
|
11628
11850
|
if (Number.isFinite(maxScenes)) {
|
|
@@ -11645,11 +11867,11 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11645
11867
|
const annotated = annotateBlueprintWithElements(blueprint, elements);
|
|
11646
11868
|
await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
|
|
11647
11869
|
`, "utf8");
|
|
11648
|
-
const compositionDest =
|
|
11870
|
+
const compositionDest = path9.join(outDir, "video-overlay-composition");
|
|
11649
11871
|
await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
|
|
11650
|
-
const indexPath =
|
|
11872
|
+
const indexPath = path9.join(compositionDest, "index.html");
|
|
11651
11873
|
const overlayHtml = buildOverlayHtml(blueprint);
|
|
11652
|
-
const indexHtml = await
|
|
11874
|
+
const indexHtml = await readFile7(indexPath, "utf8");
|
|
11653
11875
|
const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
|
|
11654
11876
|
if (injected === indexHtml && overlayHtml.trim()) {
|
|
11655
11877
|
fail2(
|
|
@@ -11662,9 +11884,9 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11662
11884
|
const opts = {
|
|
11663
11885
|
imageModel,
|
|
11664
11886
|
videoModel,
|
|
11665
|
-
overlayCompositionPath:
|
|
11666
|
-
captionsCompositionPath: captions.compositionPath ?
|
|
11667
|
-
blueprintPath:
|
|
11887
|
+
overlayCompositionPath: path9.relative(outDir, compositionDest),
|
|
11888
|
+
captionsCompositionPath: captions.compositionPath ? path9.relative(outDir, captions.compositionPath) : void 0,
|
|
11889
|
+
blueprintPath: path9.relative(outDir, blueprintPath),
|
|
11668
11890
|
frames,
|
|
11669
11891
|
ambient: Boolean(args.ambient),
|
|
11670
11892
|
...args.resolution ? { resolution: String(args.resolution) } : {}
|
|
@@ -11705,7 +11927,7 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11705
11927
|
run_estimated_credits: validation.estimatedCredits
|
|
11706
11928
|
},
|
|
11707
11929
|
checklist: {
|
|
11708
|
-
edit_prompt: `Edit ${
|
|
11930
|
+
edit_prompt: `Edit ${path9.basename(blueprintPath)} \u2014 the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
|
|
11709
11931
|
recurring_elements_to_supply: report.elements,
|
|
11710
11932
|
voices_to_confirm: report.dialogue.map((d) => ({
|
|
11711
11933
|
scene: d.scene,
|
|
@@ -11731,9 +11953,9 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11731
11953
|
});
|
|
11732
11954
|
|
|
11733
11955
|
// src/commands/canvas/set-prompt.ts
|
|
11734
|
-
import { readFile as
|
|
11735
|
-
import
|
|
11736
|
-
import { defineCommand as
|
|
11956
|
+
import { readFile as readFile8, writeFile as writeFile3 } from "fs/promises";
|
|
11957
|
+
import path10 from "path";
|
|
11958
|
+
import { defineCommand as defineCommand84 } from "citty";
|
|
11737
11959
|
function setNodePrompt(canvas, nodeId, text) {
|
|
11738
11960
|
const nodes = canvas?.nodes;
|
|
11739
11961
|
if (!Array.isArray(nodes)) throw new Error("canvas has no nodes array");
|
|
@@ -11748,7 +11970,7 @@ function setNodePrompt(canvas, nodeId, text) {
|
|
|
11748
11970
|
newNodes[idx] = newNode;
|
|
11749
11971
|
return { ...canvas, nodes: newNodes };
|
|
11750
11972
|
}
|
|
11751
|
-
var setPromptCommand =
|
|
11973
|
+
var setPromptCommand = defineCommand84({
|
|
11752
11974
|
meta: {
|
|
11753
11975
|
name: "set-prompt",
|
|
11754
11976
|
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."
|
|
@@ -11760,17 +11982,17 @@ var setPromptCommand = defineCommand83({
|
|
|
11760
11982
|
"text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
|
|
11761
11983
|
},
|
|
11762
11984
|
async run({ args }) {
|
|
11763
|
-
const filePath =
|
|
11985
|
+
const filePath = path10.resolve(String(args.file));
|
|
11764
11986
|
let canvas;
|
|
11765
11987
|
try {
|
|
11766
|
-
canvas = JSON.parse(await
|
|
11988
|
+
canvas = JSON.parse(await readFile8(filePath, "utf8"));
|
|
11767
11989
|
} catch (e) {
|
|
11768
11990
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "parse", message: String(e) } }, null, 2)}
|
|
11769
11991
|
`);
|
|
11770
11992
|
process.exit(2);
|
|
11771
11993
|
}
|
|
11772
11994
|
let text;
|
|
11773
|
-
if (args["text-file"]) text = await
|
|
11995
|
+
if (args["text-file"]) text = await readFile8(path10.resolve(String(args["text-file"])), "utf8");
|
|
11774
11996
|
else if (args.text !== void 0) text = String(args.text);
|
|
11775
11997
|
else {
|
|
11776
11998
|
process.stderr.write(
|
|
@@ -11791,7 +12013,7 @@ var setPromptCommand = defineCommand83({
|
|
|
11791
12013
|
process.exit(2);
|
|
11792
12014
|
return;
|
|
11793
12015
|
}
|
|
11794
|
-
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated,
|
|
12016
|
+
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path10.dirname(filePath)), defaultRegistry());
|
|
11795
12017
|
if (!validation.ok) {
|
|
11796
12018
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
|
|
11797
12019
|
`);
|
|
@@ -11806,18 +12028,18 @@ var setPromptCommand = defineCommand83({
|
|
|
11806
12028
|
});
|
|
11807
12029
|
|
|
11808
12030
|
// src/commands/canvas/validate.ts
|
|
11809
|
-
import { readFile as
|
|
11810
|
-
import
|
|
11811
|
-
import { defineCommand as
|
|
11812
|
-
var validateCommand =
|
|
12031
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
12032
|
+
import path11 from "path";
|
|
12033
|
+
import { defineCommand as defineCommand85 } from "citty";
|
|
12034
|
+
var validateCommand = defineCommand85({
|
|
11813
12035
|
meta: {
|
|
11814
12036
|
name: "validate",
|
|
11815
12037
|
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)."
|
|
11816
12038
|
},
|
|
11817
12039
|
args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
|
|
11818
12040
|
async run({ args }) {
|
|
11819
|
-
const filePath =
|
|
11820
|
-
const raw = await
|
|
12041
|
+
const filePath = path11.resolve(String(args.file));
|
|
12042
|
+
const raw = await readFile9(filePath, "utf8");
|
|
11821
12043
|
let parsed;
|
|
11822
12044
|
try {
|
|
11823
12045
|
parsed = JSON.parse(raw);
|
|
@@ -11827,7 +12049,7 @@ var validateCommand = defineCommand84({
|
|
|
11827
12049
|
`);
|
|
11828
12050
|
process.exit(2);
|
|
11829
12051
|
}
|
|
11830
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
12052
|
+
parsed = resolveRelativeCanvasPaths(parsed, path11.dirname(filePath));
|
|
11831
12053
|
const result = await validateCanvasDeep(parsed, defaultRegistry());
|
|
11832
12054
|
if (!result.ok) {
|
|
11833
12055
|
process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
|
|
@@ -11852,7 +12074,7 @@ var validateCommand = defineCommand84({
|
|
|
11852
12074
|
});
|
|
11853
12075
|
|
|
11854
12076
|
// src/commands/canvas/index.ts
|
|
11855
|
-
var canvasCommand =
|
|
12077
|
+
var canvasCommand = defineCommand86({
|
|
11856
12078
|
meta: {
|
|
11857
12079
|
name: "canvas",
|
|
11858
12080
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -11864,6 +12086,7 @@ Subcommands:
|
|
|
11864
12086
|
baker canvas run <file.json> \u2014 execute the canvas, write outputs to ./canvas/<run_id>/
|
|
11865
12087
|
baker canvas catalog \u2014 print the agent-facing node + composition catalog (JSON Schema)
|
|
11866
12088
|
baker canvas inspect <run_id> \u2014 one-page summary of a completed run
|
|
12089
|
+
baker canvas gallery <dir> \u2014 read a creative folder's _definition.md + run manifests into the dashboard gallery descriptor (JSON)
|
|
11867
12090
|
baker canvas scaffold-video <video> \u2014 turn a reference video into a runnable reproduction canvas (deconstruct + recurring-element detection)
|
|
11868
12091
|
baker canvas scaffold-static-ad <image> \u2014 turn a source image into a runnable static-ad canvas (describe + element detection)`
|
|
11869
12092
|
},
|
|
@@ -11872,6 +12095,7 @@ Subcommands:
|
|
|
11872
12095
|
validate: validateCommand,
|
|
11873
12096
|
catalog: catalogCommand,
|
|
11874
12097
|
inspect: inspectCommand,
|
|
12098
|
+
gallery: galleryCommand,
|
|
11875
12099
|
"scaffold-video": scaffoldVideoCommand,
|
|
11876
12100
|
"scaffold-static-ad": scaffoldStaticAdCommand,
|
|
11877
12101
|
"set-prompt": setPromptCommand
|
|
@@ -11879,10 +12103,10 @@ Subcommands:
|
|
|
11879
12103
|
});
|
|
11880
12104
|
|
|
11881
12105
|
// src/commands/ga4/index.ts
|
|
11882
|
-
import { defineCommand as
|
|
12106
|
+
import { defineCommand as defineCommand90 } from "citty";
|
|
11883
12107
|
|
|
11884
12108
|
// src/commands/ga4/audit.ts
|
|
11885
|
-
import { defineCommand as
|
|
12109
|
+
import { defineCommand as defineCommand87 } from "citty";
|
|
11886
12110
|
|
|
11887
12111
|
// src/commands/ga4/resolve.ts
|
|
11888
12112
|
async function fetchProperties(useCache = true) {
|
|
@@ -11945,7 +12169,7 @@ registerSchema({
|
|
|
11945
12169
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
11946
12170
|
}
|
|
11947
12171
|
});
|
|
11948
|
-
var auditCommand2 =
|
|
12172
|
+
var auditCommand2 = defineCommand87({
|
|
11949
12173
|
meta: {
|
|
11950
12174
|
name: "audit",
|
|
11951
12175
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -11997,7 +12221,7 @@ Examples:
|
|
|
11997
12221
|
});
|
|
11998
12222
|
|
|
11999
12223
|
// src/commands/ga4/properties.ts
|
|
12000
|
-
import { defineCommand as
|
|
12224
|
+
import { defineCommand as defineCommand88 } from "citty";
|
|
12001
12225
|
registerSchema({
|
|
12002
12226
|
command: "ga4.properties",
|
|
12003
12227
|
description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
|
|
@@ -12005,7 +12229,7 @@ registerSchema({
|
|
|
12005
12229
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12006
12230
|
}
|
|
12007
12231
|
});
|
|
12008
|
-
var propertiesCommand =
|
|
12232
|
+
var propertiesCommand = defineCommand88({
|
|
12009
12233
|
meta: {
|
|
12010
12234
|
name: "properties",
|
|
12011
12235
|
description: `List accessible GA4 properties.
|
|
@@ -12055,7 +12279,7 @@ Examples:
|
|
|
12055
12279
|
// src/commands/ga4/query.ts
|
|
12056
12280
|
import { appendFileSync as appendFileSync2, existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
12057
12281
|
import { resolve as resolve2 } from "path";
|
|
12058
|
-
import { defineCommand as
|
|
12282
|
+
import { defineCommand as defineCommand89 } from "citty";
|
|
12059
12283
|
|
|
12060
12284
|
// src/commands/ga4/presets.ts
|
|
12061
12285
|
var GA4_PRESETS = [
|
|
@@ -12187,7 +12411,7 @@ function handleError(err) {
|
|
|
12187
12411
|
});
|
|
12188
12412
|
process.exit(1);
|
|
12189
12413
|
}
|
|
12190
|
-
var queryCommand2 =
|
|
12414
|
+
var queryCommand2 = defineCommand89({
|
|
12191
12415
|
meta: {
|
|
12192
12416
|
name: "query",
|
|
12193
12417
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -12258,7 +12482,7 @@ Free-form (escape hatch):
|
|
|
12258
12482
|
});
|
|
12259
12483
|
|
|
12260
12484
|
// src/commands/ga4/index.ts
|
|
12261
|
-
var ga4Command =
|
|
12485
|
+
var ga4Command = defineCommand90({
|
|
12262
12486
|
meta: {
|
|
12263
12487
|
name: "ga4",
|
|
12264
12488
|
description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
|
|
@@ -12281,12 +12505,12 @@ Examples:
|
|
|
12281
12505
|
});
|
|
12282
12506
|
|
|
12283
12507
|
// src/commands/gsc/index.ts
|
|
12284
|
-
import { defineCommand as
|
|
12508
|
+
import { defineCommand as defineCommand94 } from "citty";
|
|
12285
12509
|
|
|
12286
12510
|
// src/commands/gsc/query.ts
|
|
12287
12511
|
import { appendFileSync as appendFileSync3, existsSync as existsSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
12288
12512
|
import { resolve as resolve3 } from "path";
|
|
12289
|
-
import { defineCommand as
|
|
12513
|
+
import { defineCommand as defineCommand91 } from "citty";
|
|
12290
12514
|
|
|
12291
12515
|
// src/commands/gsc/presets.ts
|
|
12292
12516
|
var GSC_PRESETS = [
|
|
@@ -12474,7 +12698,7 @@ function handleError2(err) {
|
|
|
12474
12698
|
});
|
|
12475
12699
|
process.exit(1);
|
|
12476
12700
|
}
|
|
12477
|
-
var queryCommand3 =
|
|
12701
|
+
var queryCommand3 = defineCommand91({
|
|
12478
12702
|
meta: {
|
|
12479
12703
|
name: "query",
|
|
12480
12704
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -12552,7 +12776,7 @@ Free-form (escape hatch):
|
|
|
12552
12776
|
});
|
|
12553
12777
|
|
|
12554
12778
|
// src/commands/gsc/sitemaps.ts
|
|
12555
|
-
import { defineCommand as
|
|
12779
|
+
import { defineCommand as defineCommand92 } from "citty";
|
|
12556
12780
|
registerSchema({
|
|
12557
12781
|
command: "gsc.sitemaps",
|
|
12558
12782
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -12561,7 +12785,7 @@ registerSchema({
|
|
|
12561
12785
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12562
12786
|
}
|
|
12563
12787
|
});
|
|
12564
|
-
var sitemapsCommand =
|
|
12788
|
+
var sitemapsCommand = defineCommand92({
|
|
12565
12789
|
meta: {
|
|
12566
12790
|
name: "sitemaps",
|
|
12567
12791
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -12611,7 +12835,7 @@ Examples:
|
|
|
12611
12835
|
});
|
|
12612
12836
|
|
|
12613
12837
|
// src/commands/gsc/sites.ts
|
|
12614
|
-
import { defineCommand as
|
|
12838
|
+
import { defineCommand as defineCommand93 } from "citty";
|
|
12615
12839
|
registerSchema({
|
|
12616
12840
|
command: "gsc.sites",
|
|
12617
12841
|
description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
|
|
@@ -12619,7 +12843,7 @@ registerSchema({
|
|
|
12619
12843
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12620
12844
|
}
|
|
12621
12845
|
});
|
|
12622
|
-
var sitesCommand =
|
|
12846
|
+
var sitesCommand = defineCommand93({
|
|
12623
12847
|
meta: {
|
|
12624
12848
|
name: "sites",
|
|
12625
12849
|
description: `List verified Search Console sites.
|
|
@@ -12667,7 +12891,7 @@ Examples:
|
|
|
12667
12891
|
});
|
|
12668
12892
|
|
|
12669
12893
|
// src/commands/gsc/index.ts
|
|
12670
|
-
var gscCommand =
|
|
12894
|
+
var gscCommand = defineCommand94({
|
|
12671
12895
|
meta: {
|
|
12672
12896
|
name: "gsc",
|
|
12673
12897
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -12690,10 +12914,10 @@ Examples:
|
|
|
12690
12914
|
});
|
|
12691
12915
|
|
|
12692
12916
|
// src/commands/images/index.ts
|
|
12693
|
-
import { defineCommand as
|
|
12917
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
12694
12918
|
|
|
12695
12919
|
// src/commands/images/crop.ts
|
|
12696
|
-
import { defineCommand as
|
|
12920
|
+
import { defineCommand as defineCommand95 } from "citty";
|
|
12697
12921
|
|
|
12698
12922
|
// src/lib/image/crop-sprite.ts
|
|
12699
12923
|
import sharp from "sharp";
|
|
@@ -12708,7 +12932,7 @@ function cropSprite(input, region) {
|
|
|
12708
12932
|
|
|
12709
12933
|
// src/lib/image/io.ts
|
|
12710
12934
|
import { randomBytes } from "crypto";
|
|
12711
|
-
import { glob as fsGlob, readFile as
|
|
12935
|
+
import { glob as fsGlob, readFile as readFile10, rename, stat as stat2, writeFile as writeFile4 } from "fs/promises";
|
|
12712
12936
|
import { dirname, extname, join as join3, resolve as resolve4 } from "path";
|
|
12713
12937
|
var REMOTE_RE = /^https?:\/\//i;
|
|
12714
12938
|
var GLOB_RE = /[*?[\]{}]/;
|
|
@@ -12744,11 +12968,11 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
12744
12968
|
}
|
|
12745
12969
|
return Buffer.from(await response.arrayBuffer());
|
|
12746
12970
|
}
|
|
12747
|
-
return
|
|
12971
|
+
return readFile10(pathOrUrl);
|
|
12748
12972
|
}
|
|
12749
|
-
async function isDirectory(
|
|
12973
|
+
async function isDirectory(path12) {
|
|
12750
12974
|
try {
|
|
12751
|
-
const s = await stat2(
|
|
12975
|
+
const s = await stat2(path12);
|
|
12752
12976
|
return s.isDirectory();
|
|
12753
12977
|
} catch {
|
|
12754
12978
|
return false;
|
|
@@ -12818,7 +13042,7 @@ function emitError2(err) {
|
|
|
12818
13042
|
}
|
|
12819
13043
|
process.exit(1);
|
|
12820
13044
|
}
|
|
12821
|
-
var cropCommand =
|
|
13045
|
+
var cropCommand = defineCommand95({
|
|
12822
13046
|
meta: {
|
|
12823
13047
|
name: "crop",
|
|
12824
13048
|
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"
|
|
@@ -12854,7 +13078,7 @@ var cropCommand = defineCommand94({
|
|
|
12854
13078
|
});
|
|
12855
13079
|
|
|
12856
13080
|
// src/commands/images/delete.ts
|
|
12857
|
-
import { defineCommand as
|
|
13081
|
+
import { defineCommand as defineCommand96 } from "citty";
|
|
12858
13082
|
registerSchema({
|
|
12859
13083
|
command: "images.delete",
|
|
12860
13084
|
description: "Delete an image by ID",
|
|
@@ -12868,7 +13092,7 @@ registerSchema({
|
|
|
12868
13092
|
}
|
|
12869
13093
|
}
|
|
12870
13094
|
});
|
|
12871
|
-
var deleteCommand =
|
|
13095
|
+
var deleteCommand = defineCommand96({
|
|
12872
13096
|
meta: {
|
|
12873
13097
|
name: "delete",
|
|
12874
13098
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -12909,7 +13133,7 @@ var deleteCommand = defineCommand95({
|
|
|
12909
13133
|
});
|
|
12910
13134
|
|
|
12911
13135
|
// src/commands/images/dimensions.ts
|
|
12912
|
-
import { defineCommand as
|
|
13136
|
+
import { defineCommand as defineCommand97 } from "citty";
|
|
12913
13137
|
|
|
12914
13138
|
// src/lib/image/dimensions.ts
|
|
12915
13139
|
import { imageSize } from "image-size";
|
|
@@ -12932,7 +13156,7 @@ registerSchema({
|
|
|
12932
13156
|
target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
|
|
12933
13157
|
}
|
|
12934
13158
|
});
|
|
12935
|
-
var dimensionsCommand =
|
|
13159
|
+
var dimensionsCommand = defineCommand97({
|
|
12936
13160
|
meta: {
|
|
12937
13161
|
name: "dimensions",
|
|
12938
13162
|
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"
|
|
@@ -12976,7 +13200,7 @@ var dimensionsCommand = defineCommand96({
|
|
|
12976
13200
|
});
|
|
12977
13201
|
|
|
12978
13202
|
// src/commands/images/extract.ts
|
|
12979
|
-
import { defineCommand as
|
|
13203
|
+
import { defineCommand as defineCommand98 } from "citty";
|
|
12980
13204
|
registerSchema({
|
|
12981
13205
|
command: "images.extract",
|
|
12982
13206
|
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
@@ -12992,7 +13216,7 @@ registerSchema({
|
|
|
12992
13216
|
}
|
|
12993
13217
|
}
|
|
12994
13218
|
});
|
|
12995
|
-
var extractCommand =
|
|
13219
|
+
var extractCommand = defineCommand98({
|
|
12996
13220
|
meta: {
|
|
12997
13221
|
name: "extract",
|
|
12998
13222
|
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"
|
|
@@ -13030,7 +13254,7 @@ var extractCommand = defineCommand97({
|
|
|
13030
13254
|
});
|
|
13031
13255
|
|
|
13032
13256
|
// src/commands/images/find.ts
|
|
13033
|
-
import { defineCommand as
|
|
13257
|
+
import { defineCommand as defineCommand99 } from "citty";
|
|
13034
13258
|
registerSchema({
|
|
13035
13259
|
command: "images.find",
|
|
13036
13260
|
description: "Fanout image search: library first, then opted-in external providers.",
|
|
@@ -13062,7 +13286,7 @@ registerSchema({
|
|
|
13062
13286
|
}
|
|
13063
13287
|
}
|
|
13064
13288
|
});
|
|
13065
|
-
var findCommand =
|
|
13289
|
+
var findCommand = defineCommand99({
|
|
13066
13290
|
meta: {
|
|
13067
13291
|
name: "find",
|
|
13068
13292
|
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"
|
|
@@ -13108,8 +13332,8 @@ var findCommand = defineCommand98({
|
|
|
13108
13332
|
});
|
|
13109
13333
|
|
|
13110
13334
|
// src/commands/images/generate.ts
|
|
13111
|
-
import { readFile as
|
|
13112
|
-
import { defineCommand as
|
|
13335
|
+
import { readFile as readFile11 } from "fs/promises";
|
|
13336
|
+
import { defineCommand as defineCommand100 } from "citty";
|
|
13113
13337
|
import sharp2 from "sharp";
|
|
13114
13338
|
var GENERATE_TIMEOUT_MS = 18e4;
|
|
13115
13339
|
var REFERENCE_MAX_EDGE = 1536;
|
|
@@ -13191,7 +13415,7 @@ async function resolveReferences(spec) {
|
|
|
13191
13415
|
}
|
|
13192
13416
|
let raw;
|
|
13193
13417
|
try {
|
|
13194
|
-
raw = await
|
|
13418
|
+
raw = await readFile11(entry);
|
|
13195
13419
|
} catch {
|
|
13196
13420
|
throw new ApiError("VALIDATION_ERROR", `Reference file not found: ${entry}`);
|
|
13197
13421
|
}
|
|
@@ -13205,7 +13429,7 @@ async function resolveReferences(spec) {
|
|
|
13205
13429
|
}
|
|
13206
13430
|
return out;
|
|
13207
13431
|
}
|
|
13208
|
-
var generateCommand =
|
|
13432
|
+
var generateCommand = defineCommand100({
|
|
13209
13433
|
meta: {
|
|
13210
13434
|
name: "generate",
|
|
13211
13435
|
description: "Generate an image with AI and store it in the library (cost-tracked per request via OpenRouter usage). Models mirror the canvas: openai/gpt-5.4-image-2 (default \u2014 photoreal, cleanest text, best for ad/landing reproduction), google/gemini-3-pro-image-preview (Nano Banana Pro), google/gemini-3.5-flash & google/gemini-3.1-flash-image-preview (fast, extreme aspect ratios), recraft/recraft-v4.1-pro-vector (vector/SVG-style with palette control). The result is auto-ingested (describe + embed), so the next `baker images library` query finds it. Pass --reference with image URLs and/or local file paths (Pinterest, stock, brand assets, sandbox files) to ground generation in reality.\n\nExamples:\n baker images generate 'a friendly golden retriever sitting in a bright modern living room' --aspect-ratio 16:9\n baker images generate 'hero shot of a matte black water bottle on marble' --model google/gemini-3-pro-image-preview --image-size 2K\n baker images generate 'lifestyle photo matching this mood' --reference 'https://\u2026/ref1.jpg,https://\u2026/ref2.jpg'\n baker images generate 'put this product on a marble countertop, soft daylight' --reference './src/brand/logos/product.png,./refs/kitchen-mood.jpg'\n baker images generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
|
|
@@ -13257,7 +13481,7 @@ var generateCommand = defineCommand99({
|
|
|
13257
13481
|
});
|
|
13258
13482
|
|
|
13259
13483
|
// src/commands/images/get.ts
|
|
13260
|
-
import { defineCommand as
|
|
13484
|
+
import { defineCommand as defineCommand101 } from "citty";
|
|
13261
13485
|
registerSchema({
|
|
13262
13486
|
command: "images.get",
|
|
13263
13487
|
description: "Get a single image by ID",
|
|
@@ -13265,7 +13489,7 @@ registerSchema({
|
|
|
13265
13489
|
id: { type: "string", description: "Image ID", required: true }
|
|
13266
13490
|
}
|
|
13267
13491
|
});
|
|
13268
|
-
var getCommand2 =
|
|
13492
|
+
var getCommand2 = defineCommand101({
|
|
13269
13493
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
13270
13494
|
args: {
|
|
13271
13495
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -13301,7 +13525,7 @@ var getCommand2 = defineCommand100({
|
|
|
13301
13525
|
});
|
|
13302
13526
|
|
|
13303
13527
|
// src/commands/images/gif.ts
|
|
13304
|
-
import { defineCommand as
|
|
13528
|
+
import { defineCommand as defineCommand102 } from "citty";
|
|
13305
13529
|
registerSchema({
|
|
13306
13530
|
command: "images.gif",
|
|
13307
13531
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -13333,7 +13557,7 @@ registerSchema({
|
|
|
13333
13557
|
}
|
|
13334
13558
|
}
|
|
13335
13559
|
});
|
|
13336
|
-
var gifCommand =
|
|
13560
|
+
var gifCommand = defineCommand102({
|
|
13337
13561
|
meta: {
|
|
13338
13562
|
name: "gif",
|
|
13339
13563
|
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"
|
|
@@ -13380,7 +13604,7 @@ var gifCommand = defineCommand101({
|
|
|
13380
13604
|
});
|
|
13381
13605
|
|
|
13382
13606
|
// src/commands/images/google.ts
|
|
13383
|
-
import { defineCommand as
|
|
13607
|
+
import { defineCommand as defineCommand103 } from "citty";
|
|
13384
13608
|
registerSchema({
|
|
13385
13609
|
command: "images.google",
|
|
13386
13610
|
description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
|
|
@@ -13416,7 +13640,7 @@ registerSchema({
|
|
|
13416
13640
|
}
|
|
13417
13641
|
}
|
|
13418
13642
|
});
|
|
13419
|
-
var googleCommand2 =
|
|
13643
|
+
var googleCommand2 = defineCommand103({
|
|
13420
13644
|
meta: {
|
|
13421
13645
|
name: "google",
|
|
13422
13646
|
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"
|
|
@@ -13464,7 +13688,7 @@ var googleCommand2 = defineCommand102({
|
|
|
13464
13688
|
});
|
|
13465
13689
|
|
|
13466
13690
|
// src/commands/images/icon.ts
|
|
13467
|
-
import { defineCommand as
|
|
13691
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
13468
13692
|
registerSchema({
|
|
13469
13693
|
command: "images.icon",
|
|
13470
13694
|
description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
|
|
@@ -13490,7 +13714,7 @@ registerSchema({
|
|
|
13490
13714
|
}
|
|
13491
13715
|
}
|
|
13492
13716
|
});
|
|
13493
|
-
var iconCommand =
|
|
13717
|
+
var iconCommand = defineCommand104({
|
|
13494
13718
|
meta: {
|
|
13495
13719
|
name: "icon",
|
|
13496
13720
|
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'"
|
|
@@ -13530,7 +13754,7 @@ var iconCommand = defineCommand103({
|
|
|
13530
13754
|
});
|
|
13531
13755
|
|
|
13532
13756
|
// src/commands/images/ingest.ts
|
|
13533
|
-
import { defineCommand as
|
|
13757
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
13534
13758
|
registerSchema({
|
|
13535
13759
|
command: "images.ingest",
|
|
13536
13760
|
description: "Ingest a remote image URL into the library (full describe + embed).",
|
|
@@ -13542,7 +13766,7 @@ registerSchema({
|
|
|
13542
13766
|
context: { type: "string", description: "Description context hint", required: false }
|
|
13543
13767
|
}
|
|
13544
13768
|
});
|
|
13545
|
-
var ingestCommand =
|
|
13769
|
+
var ingestCommand = defineCommand105({
|
|
13546
13770
|
meta: {
|
|
13547
13771
|
name: "ingest",
|
|
13548
13772
|
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"
|
|
@@ -13584,7 +13808,7 @@ var ingestCommand = defineCommand104({
|
|
|
13584
13808
|
});
|
|
13585
13809
|
|
|
13586
13810
|
// src/commands/images/library.ts
|
|
13587
|
-
import { defineCommand as
|
|
13811
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
13588
13812
|
registerSchema({
|
|
13589
13813
|
command: "images.library",
|
|
13590
13814
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -13610,7 +13834,7 @@ registerSchema({
|
|
|
13610
13834
|
}
|
|
13611
13835
|
}
|
|
13612
13836
|
});
|
|
13613
|
-
var libraryCommand =
|
|
13837
|
+
var libraryCommand = defineCommand106({
|
|
13614
13838
|
meta: {
|
|
13615
13839
|
name: "library",
|
|
13616
13840
|
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"
|
|
@@ -13667,7 +13891,7 @@ var libraryCommand = defineCommand105({
|
|
|
13667
13891
|
});
|
|
13668
13892
|
|
|
13669
13893
|
// src/commands/images/logo.ts
|
|
13670
|
-
import { defineCommand as
|
|
13894
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
13671
13895
|
registerSchema({
|
|
13672
13896
|
command: "images.logo",
|
|
13673
13897
|
description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
|
|
@@ -13692,7 +13916,7 @@ registerSchema({
|
|
|
13692
13916
|
}
|
|
13693
13917
|
}
|
|
13694
13918
|
});
|
|
13695
|
-
var logoCommand =
|
|
13919
|
+
var logoCommand = defineCommand107({
|
|
13696
13920
|
meta: {
|
|
13697
13921
|
name: "logo",
|
|
13698
13922
|
description: "Brand logo via Brandfetch CDN. Returns up to 5 variants (icon, light/dark logo, light/dark symbol). Auto-ingests the first variant.\n\nExample: baker images logo stripe.com --variant logo"
|
|
@@ -13730,7 +13954,7 @@ var logoCommand = defineCommand106({
|
|
|
13730
13954
|
});
|
|
13731
13955
|
|
|
13732
13956
|
// src/commands/images/normalize.ts
|
|
13733
|
-
import { defineCommand as
|
|
13957
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
13734
13958
|
|
|
13735
13959
|
// src/lib/image/color-changer.ts
|
|
13736
13960
|
import quantize from "quantize";
|
|
@@ -14462,7 +14686,7 @@ function coerceRawArgs(args) {
|
|
|
14462
14686
|
"dry-run": bool(args["dry-run"])
|
|
14463
14687
|
};
|
|
14464
14688
|
}
|
|
14465
|
-
var normalizeCommand =
|
|
14689
|
+
var normalizeCommand = defineCommand108({
|
|
14466
14690
|
meta: {
|
|
14467
14691
|
name: "normalize",
|
|
14468
14692
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -14517,7 +14741,7 @@ Examples:
|
|
|
14517
14741
|
});
|
|
14518
14742
|
|
|
14519
14743
|
// src/commands/images/pinterest.ts
|
|
14520
|
-
import { defineCommand as
|
|
14744
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
14521
14745
|
registerSchema({
|
|
14522
14746
|
command: "images.pinterest",
|
|
14523
14747
|
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.",
|
|
@@ -14537,7 +14761,7 @@ registerSchema({
|
|
|
14537
14761
|
}
|
|
14538
14762
|
}
|
|
14539
14763
|
});
|
|
14540
|
-
var pinterestCommand =
|
|
14764
|
+
var pinterestCommand = defineCommand109({
|
|
14541
14765
|
meta: {
|
|
14542
14766
|
name: "pinterest",
|
|
14543
14767
|
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'"
|
|
@@ -14577,7 +14801,7 @@ var pinterestCommand = defineCommand108({
|
|
|
14577
14801
|
});
|
|
14578
14802
|
|
|
14579
14803
|
// src/commands/images/screenshot.ts
|
|
14580
|
-
import { defineCommand as
|
|
14804
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
14581
14805
|
registerSchema({
|
|
14582
14806
|
command: "images.screenshot",
|
|
14583
14807
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -14593,7 +14817,7 @@ registerSchema({
|
|
|
14593
14817
|
}
|
|
14594
14818
|
}
|
|
14595
14819
|
});
|
|
14596
|
-
var screenshotCommand =
|
|
14820
|
+
var screenshotCommand = defineCommand110({
|
|
14597
14821
|
meta: {
|
|
14598
14822
|
name: "screenshot",
|
|
14599
14823
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -14643,7 +14867,7 @@ var screenshotCommand = defineCommand109({
|
|
|
14643
14867
|
});
|
|
14644
14868
|
|
|
14645
14869
|
// src/commands/images/search.ts
|
|
14646
|
-
import { defineCommand as
|
|
14870
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
14647
14871
|
registerSchema({
|
|
14648
14872
|
command: "images.search",
|
|
14649
14873
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -14659,7 +14883,7 @@ registerSchema({
|
|
|
14659
14883
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
14660
14884
|
}
|
|
14661
14885
|
});
|
|
14662
|
-
var searchCommand =
|
|
14886
|
+
var searchCommand = defineCommand111({
|
|
14663
14887
|
meta: {
|
|
14664
14888
|
name: "search",
|
|
14665
14889
|
description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
|
|
@@ -14719,7 +14943,7 @@ var searchCommand = defineCommand110({
|
|
|
14719
14943
|
});
|
|
14720
14944
|
|
|
14721
14945
|
// src/commands/images/sticker.ts
|
|
14722
|
-
import { defineCommand as
|
|
14946
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
14723
14947
|
registerSchema({
|
|
14724
14948
|
command: "images.sticker",
|
|
14725
14949
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -14751,7 +14975,7 @@ registerSchema({
|
|
|
14751
14975
|
}
|
|
14752
14976
|
}
|
|
14753
14977
|
});
|
|
14754
|
-
var stickerCommand =
|
|
14978
|
+
var stickerCommand = defineCommand112({
|
|
14755
14979
|
meta: {
|
|
14756
14980
|
name: "sticker",
|
|
14757
14981
|
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"
|
|
@@ -14798,7 +15022,7 @@ var stickerCommand = defineCommand111({
|
|
|
14798
15022
|
});
|
|
14799
15023
|
|
|
14800
15024
|
// src/commands/images/stock.ts
|
|
14801
|
-
import { defineCommand as
|
|
15025
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
14802
15026
|
registerSchema({
|
|
14803
15027
|
command: "images.stock",
|
|
14804
15028
|
description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
|
|
@@ -14856,7 +15080,7 @@ registerSchema({
|
|
|
14856
15080
|
}
|
|
14857
15081
|
}
|
|
14858
15082
|
});
|
|
14859
|
-
var stockCommand =
|
|
15083
|
+
var stockCommand = defineCommand113({
|
|
14860
15084
|
meta: {
|
|
14861
15085
|
name: "stock",
|
|
14862
15086
|
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"
|
|
@@ -14912,7 +15136,7 @@ var stockCommand = defineCommand112({
|
|
|
14912
15136
|
});
|
|
14913
15137
|
|
|
14914
15138
|
// src/lib/tags-command.ts
|
|
14915
|
-
import { defineCommand as
|
|
15139
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
14916
15140
|
function makeTagsCommand(command, label, endpoint) {
|
|
14917
15141
|
registerSchema({
|
|
14918
15142
|
command: `${command}.tags`,
|
|
@@ -14921,7 +15145,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
14921
15145
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
14922
15146
|
}
|
|
14923
15147
|
});
|
|
14924
|
-
return
|
|
15148
|
+
return defineCommand114({
|
|
14925
15149
|
meta: {
|
|
14926
15150
|
name: "tags",
|
|
14927
15151
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -14957,9 +15181,9 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
14957
15181
|
var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
14958
15182
|
|
|
14959
15183
|
// src/commands/images/upload.ts
|
|
14960
|
-
import { readFile as
|
|
15184
|
+
import { readFile as readFile12 } from "fs/promises";
|
|
14961
15185
|
import { extname as extname2 } from "path";
|
|
14962
|
-
import { defineCommand as
|
|
15186
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
14963
15187
|
var MIME_MAP = {
|
|
14964
15188
|
".png": "image/png",
|
|
14965
15189
|
".jpg": "image/jpeg",
|
|
@@ -15014,7 +15238,7 @@ function detectContentType(filePath) {
|
|
|
15014
15238
|
}
|
|
15015
15239
|
return mime;
|
|
15016
15240
|
}
|
|
15017
|
-
var uploadCommand =
|
|
15241
|
+
var uploadCommand = defineCommand115({
|
|
15018
15242
|
meta: {
|
|
15019
15243
|
name: "upload",
|
|
15020
15244
|
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'"
|
|
@@ -15097,7 +15321,7 @@ async function uploadLocal(target, args) {
|
|
|
15097
15321
|
});
|
|
15098
15322
|
return;
|
|
15099
15323
|
}
|
|
15100
|
-
const fileBuffer = await
|
|
15324
|
+
const fileBuffer = await readFile12(target);
|
|
15101
15325
|
const base64 = fileBuffer.toString("base64");
|
|
15102
15326
|
const body = { base64, contentType };
|
|
15103
15327
|
if (args.source) body.source = args.source;
|
|
@@ -15107,7 +15331,7 @@ async function uploadLocal(target, args) {
|
|
|
15107
15331
|
}
|
|
15108
15332
|
|
|
15109
15333
|
// src/commands/images/upscale.ts
|
|
15110
|
-
import { defineCommand as
|
|
15334
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
15111
15335
|
registerSchema({
|
|
15112
15336
|
command: "images.upscale",
|
|
15113
15337
|
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).",
|
|
@@ -15122,7 +15346,7 @@ registerSchema({
|
|
|
15122
15346
|
}
|
|
15123
15347
|
});
|
|
15124
15348
|
var POLL_INTERVAL_MS3 = 1500;
|
|
15125
|
-
var upscaleCommand =
|
|
15349
|
+
var upscaleCommand = defineCommand116({
|
|
15126
15350
|
meta: {
|
|
15127
15351
|
name: "upscale",
|
|
15128
15352
|
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"
|
|
@@ -15177,7 +15401,7 @@ var upscaleCommand = defineCommand115({
|
|
|
15177
15401
|
});
|
|
15178
15402
|
|
|
15179
15403
|
// src/commands/images/use.ts
|
|
15180
|
-
import { defineCommand as
|
|
15404
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
15181
15405
|
registerSchema({
|
|
15182
15406
|
command: "images.use",
|
|
15183
15407
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -15193,7 +15417,7 @@ registerSchema({
|
|
|
15193
15417
|
}
|
|
15194
15418
|
});
|
|
15195
15419
|
var POLL_INTERVAL_MS4 = 1500;
|
|
15196
|
-
var useCommand =
|
|
15420
|
+
var useCommand = defineCommand117({
|
|
15197
15421
|
meta: {
|
|
15198
15422
|
name: "use",
|
|
15199
15423
|
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"
|
|
@@ -15239,7 +15463,7 @@ var useCommand = defineCommand116({
|
|
|
15239
15463
|
});
|
|
15240
15464
|
|
|
15241
15465
|
// src/commands/images/index.ts
|
|
15242
|
-
var imagesCommand =
|
|
15466
|
+
var imagesCommand = defineCommand118({
|
|
15243
15467
|
meta: {
|
|
15244
15468
|
name: "images",
|
|
15245
15469
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -15309,10 +15533,10 @@ Paid transforms (run on the Convex backend, cost-tracked):
|
|
|
15309
15533
|
});
|
|
15310
15534
|
|
|
15311
15535
|
// src/commands/research/index.ts
|
|
15312
|
-
import { defineCommand as
|
|
15536
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
15313
15537
|
|
|
15314
15538
|
// src/commands/research/advertisers.ts
|
|
15315
|
-
import { defineCommand as
|
|
15539
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
15316
15540
|
|
|
15317
15541
|
// src/commands/research/output.ts
|
|
15318
15542
|
var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
|
|
@@ -15425,7 +15649,7 @@ var FIELDS3 = {
|
|
|
15425
15649
|
etv: "Estimated traffic value (USD)",
|
|
15426
15650
|
visibility: "SERP visibility score (0-1)"
|
|
15427
15651
|
};
|
|
15428
|
-
var advertisersCommand =
|
|
15652
|
+
var advertisersCommand = defineCommand119({
|
|
15429
15653
|
meta: {
|
|
15430
15654
|
name: "advertisers",
|
|
15431
15655
|
description: `Find domains competing for a keyword in Google SERPs.
|
|
@@ -15472,7 +15696,7 @@ Examples:
|
|
|
15472
15696
|
});
|
|
15473
15697
|
|
|
15474
15698
|
// src/commands/research/autocomplete.ts
|
|
15475
|
-
import { defineCommand as
|
|
15699
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
15476
15700
|
registerSchema({
|
|
15477
15701
|
command: "research.autocomplete",
|
|
15478
15702
|
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).",
|
|
@@ -15495,7 +15719,7 @@ registerSchema({
|
|
|
15495
15719
|
var FIELDS4 = {
|
|
15496
15720
|
suggestion: "Autocomplete suggestion from Google"
|
|
15497
15721
|
};
|
|
15498
|
-
var autocompleteCommand =
|
|
15722
|
+
var autocompleteCommand = defineCommand120({
|
|
15499
15723
|
meta: {
|
|
15500
15724
|
name: "autocomplete",
|
|
15501
15725
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -15541,7 +15765,7 @@ Examples:
|
|
|
15541
15765
|
});
|
|
15542
15766
|
|
|
15543
15767
|
// src/commands/research/countries.ts
|
|
15544
|
-
import { defineCommand as
|
|
15768
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
15545
15769
|
registerSchema({
|
|
15546
15770
|
command: "research.countries",
|
|
15547
15771
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -15598,7 +15822,7 @@ var FIELDS5 = {
|
|
|
15598
15822
|
code: "Country code to pass as --location",
|
|
15599
15823
|
name: "Country name"
|
|
15600
15824
|
};
|
|
15601
|
-
var countriesCommand =
|
|
15825
|
+
var countriesCommand = defineCommand121({
|
|
15602
15826
|
meta: {
|
|
15603
15827
|
name: "countries",
|
|
15604
15828
|
description: "List all supported country codes for --location flag."
|
|
@@ -15609,7 +15833,7 @@ var countriesCommand = defineCommand120({
|
|
|
15609
15833
|
});
|
|
15610
15834
|
|
|
15611
15835
|
// src/commands/research/intent.ts
|
|
15612
|
-
import { defineCommand as
|
|
15836
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
15613
15837
|
registerSchema({
|
|
15614
15838
|
command: "research.intent",
|
|
15615
15839
|
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.",
|
|
@@ -15632,7 +15856,7 @@ var FIELDS6 = {
|
|
|
15632
15856
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
15633
15857
|
probability: "Confidence score 0.0-1.0"
|
|
15634
15858
|
};
|
|
15635
|
-
var intentCommand =
|
|
15859
|
+
var intentCommand = defineCommand122({
|
|
15636
15860
|
meta: {
|
|
15637
15861
|
name: "intent",
|
|
15638
15862
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -15680,7 +15904,7 @@ Examples:
|
|
|
15680
15904
|
});
|
|
15681
15905
|
|
|
15682
15906
|
// src/commands/research/keyword-gap.ts
|
|
15683
|
-
import { defineCommand as
|
|
15907
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
15684
15908
|
registerSchema({
|
|
15685
15909
|
command: "research.keyword-gap",
|
|
15686
15910
|
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.",
|
|
@@ -15709,7 +15933,7 @@ var FIELDS7 = {
|
|
|
15709
15933
|
cpc: "Cost per click USD",
|
|
15710
15934
|
their_position: "Competitor's ranking position"
|
|
15711
15935
|
};
|
|
15712
|
-
var keywordGapCommand =
|
|
15936
|
+
var keywordGapCommand = defineCommand123({
|
|
15713
15937
|
meta: {
|
|
15714
15938
|
name: "keyword-gap",
|
|
15715
15939
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -15783,7 +16007,7 @@ Examples:
|
|
|
15783
16007
|
});
|
|
15784
16008
|
|
|
15785
16009
|
// src/commands/research/keywords-for-site.ts
|
|
15786
|
-
import { defineCommand as
|
|
16010
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
15787
16011
|
registerSchema({
|
|
15788
16012
|
command: "research.keywords-for-site",
|
|
15789
16013
|
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.",
|
|
@@ -15816,7 +16040,7 @@ var FIELDS8 = {
|
|
|
15816
16040
|
competition: "LOW, MEDIUM, or HIGH",
|
|
15817
16041
|
competition_index: "Competition score 0-100"
|
|
15818
16042
|
};
|
|
15819
|
-
var keywordsForSiteCommand =
|
|
16043
|
+
var keywordsForSiteCommand = defineCommand124({
|
|
15820
16044
|
meta: {
|
|
15821
16045
|
name: "keywords-for-site",
|
|
15822
16046
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -15869,7 +16093,7 @@ Examples:
|
|
|
15869
16093
|
});
|
|
15870
16094
|
|
|
15871
16095
|
// src/commands/research/languages.ts
|
|
15872
|
-
import { defineCommand as
|
|
16096
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
15873
16097
|
registerSchema({
|
|
15874
16098
|
command: "research.languages",
|
|
15875
16099
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -15899,7 +16123,7 @@ var FIELDS9 = {
|
|
|
15899
16123
|
code: "Language code to pass as --language",
|
|
15900
16124
|
name: "Language name (also accepted by --language)"
|
|
15901
16125
|
};
|
|
15902
|
-
var languagesCommand2 =
|
|
16126
|
+
var languagesCommand2 = defineCommand125({
|
|
15903
16127
|
meta: {
|
|
15904
16128
|
name: "languages",
|
|
15905
16129
|
description: "List all supported language codes for --language flag."
|
|
@@ -15910,7 +16134,7 @@ var languagesCommand2 = defineCommand124({
|
|
|
15910
16134
|
});
|
|
15911
16135
|
|
|
15912
16136
|
// src/commands/research/lighthouse.ts
|
|
15913
|
-
import { defineCommand as
|
|
16137
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
15914
16138
|
registerSchema({
|
|
15915
16139
|
command: "research.lighthouse",
|
|
15916
16140
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -15929,7 +16153,7 @@ var FIELDS10 = {
|
|
|
15929
16153
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
15930
16154
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
15931
16155
|
};
|
|
15932
|
-
var lighthouseCommand =
|
|
16156
|
+
var lighthouseCommand = defineCommand126({
|
|
15933
16157
|
meta: {
|
|
15934
16158
|
name: "lighthouse",
|
|
15935
16159
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -15967,7 +16191,7 @@ Examples:
|
|
|
15967
16191
|
});
|
|
15968
16192
|
|
|
15969
16193
|
// src/commands/research/relevant-pages.ts
|
|
15970
|
-
import { defineCommand as
|
|
16194
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
15971
16195
|
registerSchema({
|
|
15972
16196
|
command: "research.relevant-pages",
|
|
15973
16197
|
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).",
|
|
@@ -15993,7 +16217,7 @@ var FIELDS11 = {
|
|
|
15993
16217
|
keywords: "Total organic keywords the page ranks for",
|
|
15994
16218
|
top_10: "Keywords in positions 1-10"
|
|
15995
16219
|
};
|
|
15996
|
-
var relevantPagesCommand =
|
|
16220
|
+
var relevantPagesCommand = defineCommand127({
|
|
15997
16221
|
meta: {
|
|
15998
16222
|
name: "relevant-pages",
|
|
15999
16223
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -16039,7 +16263,7 @@ Examples:
|
|
|
16039
16263
|
});
|
|
16040
16264
|
|
|
16041
16265
|
// src/commands/research/web.ts
|
|
16042
|
-
import { defineCommand as
|
|
16266
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
16043
16267
|
registerSchema({
|
|
16044
16268
|
command: "research.web",
|
|
16045
16269
|
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).",
|
|
@@ -16090,7 +16314,7 @@ async function runDeepResearch(question) {
|
|
|
16090
16314
|
}
|
|
16091
16315
|
throw new Error("Deep research timed out");
|
|
16092
16316
|
}
|
|
16093
|
-
var webCommand =
|
|
16317
|
+
var webCommand = defineCommand128({
|
|
16094
16318
|
meta: {
|
|
16095
16319
|
name: "web",
|
|
16096
16320
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -16150,7 +16374,7 @@ Examples:
|
|
|
16150
16374
|
});
|
|
16151
16375
|
|
|
16152
16376
|
// src/commands/research/index.ts
|
|
16153
|
-
var researchCommand =
|
|
16377
|
+
var researchCommand = defineCommand129({
|
|
16154
16378
|
meta: {
|
|
16155
16379
|
name: "research",
|
|
16156
16380
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -16190,10 +16414,10 @@ Examples:
|
|
|
16190
16414
|
});
|
|
16191
16415
|
|
|
16192
16416
|
// src/commands/scheduled-actions/index.ts
|
|
16193
|
-
import { defineCommand as
|
|
16417
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
16194
16418
|
|
|
16195
16419
|
// src/commands/scheduled-actions/create.ts
|
|
16196
|
-
import { defineCommand as
|
|
16420
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
16197
16421
|
|
|
16198
16422
|
// src/commands/scheduled-actions/shared.ts
|
|
16199
16423
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -16298,7 +16522,7 @@ registerSchema({
|
|
|
16298
16522
|
prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
|
|
16299
16523
|
}
|
|
16300
16524
|
});
|
|
16301
|
-
var createCommand2 =
|
|
16525
|
+
var createCommand2 = defineCommand130({
|
|
16302
16526
|
meta: {
|
|
16303
16527
|
name: "create",
|
|
16304
16528
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -16346,7 +16570,7 @@ var createCommand2 = defineCommand129({
|
|
|
16346
16570
|
});
|
|
16347
16571
|
|
|
16348
16572
|
// src/commands/scheduled-actions/delete.ts
|
|
16349
|
-
import { defineCommand as
|
|
16573
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
16350
16574
|
registerSchema({
|
|
16351
16575
|
command: "scheduled-actions.delete",
|
|
16352
16576
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -16354,7 +16578,7 @@ registerSchema({
|
|
|
16354
16578
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
16355
16579
|
}
|
|
16356
16580
|
});
|
|
16357
|
-
var deleteCommand2 =
|
|
16581
|
+
var deleteCommand2 = defineCommand131({
|
|
16358
16582
|
meta: {
|
|
16359
16583
|
name: "delete",
|
|
16360
16584
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -16383,7 +16607,7 @@ var deleteCommand2 = defineCommand130({
|
|
|
16383
16607
|
});
|
|
16384
16608
|
|
|
16385
16609
|
// src/commands/scheduled-actions/get.ts
|
|
16386
|
-
import { defineCommand as
|
|
16610
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
16387
16611
|
registerSchema({
|
|
16388
16612
|
command: "scheduled-actions.get",
|
|
16389
16613
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -16391,7 +16615,7 @@ registerSchema({
|
|
|
16391
16615
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
16392
16616
|
}
|
|
16393
16617
|
});
|
|
16394
|
-
var getCommand3 =
|
|
16618
|
+
var getCommand3 = defineCommand132({
|
|
16395
16619
|
meta: {
|
|
16396
16620
|
name: "get",
|
|
16397
16621
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -16428,13 +16652,13 @@ var getCommand3 = defineCommand131({
|
|
|
16428
16652
|
});
|
|
16429
16653
|
|
|
16430
16654
|
// src/commands/scheduled-actions/list.ts
|
|
16431
|
-
import { defineCommand as
|
|
16655
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
16432
16656
|
registerSchema({
|
|
16433
16657
|
command: "scheduled-actions.list",
|
|
16434
16658
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
|
|
16435
16659
|
args: {}
|
|
16436
16660
|
});
|
|
16437
|
-
var listCommand3 =
|
|
16661
|
+
var listCommand3 = defineCommand133({
|
|
16438
16662
|
meta: {
|
|
16439
16663
|
name: "list",
|
|
16440
16664
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
|
|
@@ -16455,7 +16679,7 @@ var listCommand3 = defineCommand132({
|
|
|
16455
16679
|
});
|
|
16456
16680
|
|
|
16457
16681
|
// src/commands/scheduled-actions/trigger.ts
|
|
16458
|
-
import { defineCommand as
|
|
16682
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
16459
16683
|
registerSchema({
|
|
16460
16684
|
command: "scheduled-actions.trigger",
|
|
16461
16685
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -16463,7 +16687,7 @@ registerSchema({
|
|
|
16463
16687
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
16464
16688
|
}
|
|
16465
16689
|
});
|
|
16466
|
-
var triggerCommand =
|
|
16690
|
+
var triggerCommand = defineCommand134({
|
|
16467
16691
|
meta: {
|
|
16468
16692
|
name: "trigger",
|
|
16469
16693
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -16500,7 +16724,7 @@ var triggerCommand = defineCommand133({
|
|
|
16500
16724
|
});
|
|
16501
16725
|
|
|
16502
16726
|
// src/commands/scheduled-actions/update.ts
|
|
16503
|
-
import { defineCommand as
|
|
16727
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
16504
16728
|
registerSchema({
|
|
16505
16729
|
command: "scheduled-actions.update",
|
|
16506
16730
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -16525,7 +16749,7 @@ registerSchema({
|
|
|
16525
16749
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
16526
16750
|
}
|
|
16527
16751
|
});
|
|
16528
|
-
var updateCommand2 =
|
|
16752
|
+
var updateCommand2 = defineCommand135({
|
|
16529
16753
|
meta: {
|
|
16530
16754
|
name: "update",
|
|
16531
16755
|
description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
|
|
@@ -16595,7 +16819,7 @@ var updateCommand2 = defineCommand134({
|
|
|
16595
16819
|
});
|
|
16596
16820
|
|
|
16597
16821
|
// src/commands/scheduled-actions/index.ts
|
|
16598
|
-
var scheduledActionsCommand =
|
|
16822
|
+
var scheduledActionsCommand = defineCommand136({
|
|
16599
16823
|
meta: {
|
|
16600
16824
|
name: "scheduled-actions",
|
|
16601
16825
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
|
|
@@ -16621,8 +16845,8 @@ Examples:
|
|
|
16621
16845
|
});
|
|
16622
16846
|
|
|
16623
16847
|
// src/commands/schema.ts
|
|
16624
|
-
import { defineCommand as
|
|
16625
|
-
var schemaCommand =
|
|
16848
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
16849
|
+
var schemaCommand = defineCommand137({
|
|
16626
16850
|
meta: {
|
|
16627
16851
|
name: "schema",
|
|
16628
16852
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -16658,10 +16882,10 @@ var schemaCommand = defineCommand136({
|
|
|
16658
16882
|
});
|
|
16659
16883
|
|
|
16660
16884
|
// src/commands/testimonials/index.ts
|
|
16661
|
-
import { defineCommand as
|
|
16885
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
16662
16886
|
|
|
16663
16887
|
// src/commands/testimonials/get.ts
|
|
16664
|
-
import { defineCommand as
|
|
16888
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
16665
16889
|
registerSchema({
|
|
16666
16890
|
command: "testimonials.get",
|
|
16667
16891
|
description: "Get a single testimonial by ID",
|
|
@@ -16669,7 +16893,7 @@ registerSchema({
|
|
|
16669
16893
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
16670
16894
|
}
|
|
16671
16895
|
});
|
|
16672
|
-
var getCommand4 =
|
|
16896
|
+
var getCommand4 = defineCommand138({
|
|
16673
16897
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
16674
16898
|
args: {
|
|
16675
16899
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -16706,7 +16930,7 @@ var getCommand4 = defineCommand137({
|
|
|
16706
16930
|
});
|
|
16707
16931
|
|
|
16708
16932
|
// src/commands/testimonials/list.ts
|
|
16709
|
-
import { defineCommand as
|
|
16933
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
16710
16934
|
registerSchema({
|
|
16711
16935
|
command: "testimonials.list",
|
|
16712
16936
|
description: "List testimonials with optional filters.",
|
|
@@ -16736,7 +16960,7 @@ registerSchema({
|
|
|
16736
16960
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
16737
16961
|
}
|
|
16738
16962
|
});
|
|
16739
|
-
var listCommand4 =
|
|
16963
|
+
var listCommand4 = defineCommand139({
|
|
16740
16964
|
meta: {
|
|
16741
16965
|
name: "list",
|
|
16742
16966
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -16785,7 +17009,7 @@ var listCommand4 = defineCommand138({
|
|
|
16785
17009
|
});
|
|
16786
17010
|
|
|
16787
17011
|
// src/commands/testimonials/search.ts
|
|
16788
|
-
import { defineCommand as
|
|
17012
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
16789
17013
|
registerSchema({
|
|
16790
17014
|
command: "testimonials.search",
|
|
16791
17015
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -16816,7 +17040,7 @@ registerSchema({
|
|
|
16816
17040
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
16817
17041
|
}
|
|
16818
17042
|
});
|
|
16819
|
-
var searchCommand2 =
|
|
17043
|
+
var searchCommand2 = defineCommand140({
|
|
16820
17044
|
meta: {
|
|
16821
17045
|
name: "search",
|
|
16822
17046
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -16890,7 +17114,7 @@ var searchCommand2 = defineCommand139({
|
|
|
16890
17114
|
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
16891
17115
|
|
|
16892
17116
|
// src/commands/testimonials/index.ts
|
|
16893
|
-
var testimonialsCommand =
|
|
17117
|
+
var testimonialsCommand = defineCommand141({
|
|
16894
17118
|
meta: {
|
|
16895
17119
|
name: "testimonials",
|
|
16896
17120
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -16911,10 +17135,10 @@ Examples:
|
|
|
16911
17135
|
});
|
|
16912
17136
|
|
|
16913
17137
|
// src/commands/videos/index.ts
|
|
16914
|
-
import { defineCommand as
|
|
17138
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
16915
17139
|
|
|
16916
17140
|
// src/commands/videos/delete.ts
|
|
16917
|
-
import { defineCommand as
|
|
17141
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
16918
17142
|
registerSchema({
|
|
16919
17143
|
command: "videos.delete",
|
|
16920
17144
|
description: "Delete a video by ID",
|
|
@@ -16928,7 +17152,7 @@ registerSchema({
|
|
|
16928
17152
|
}
|
|
16929
17153
|
}
|
|
16930
17154
|
});
|
|
16931
|
-
var deleteCommand3 =
|
|
17155
|
+
var deleteCommand3 = defineCommand142({
|
|
16932
17156
|
meta: {
|
|
16933
17157
|
name: "delete",
|
|
16934
17158
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -16969,7 +17193,7 @@ var deleteCommand3 = defineCommand141({
|
|
|
16969
17193
|
});
|
|
16970
17194
|
|
|
16971
17195
|
// src/commands/videos/get.ts
|
|
16972
|
-
import { defineCommand as
|
|
17196
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
16973
17197
|
registerSchema({
|
|
16974
17198
|
command: "videos.get",
|
|
16975
17199
|
description: "Get a single video by ID",
|
|
@@ -16977,7 +17201,7 @@ registerSchema({
|
|
|
16977
17201
|
id: { type: "string", description: "Video ID", required: true }
|
|
16978
17202
|
}
|
|
16979
17203
|
});
|
|
16980
|
-
var getCommand5 =
|
|
17204
|
+
var getCommand5 = defineCommand143({
|
|
16981
17205
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
16982
17206
|
args: {
|
|
16983
17207
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -17014,7 +17238,7 @@ var getCommand5 = defineCommand142({
|
|
|
17014
17238
|
});
|
|
17015
17239
|
|
|
17016
17240
|
// src/commands/videos/search.ts
|
|
17017
|
-
import { defineCommand as
|
|
17241
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
17018
17242
|
registerSchema({
|
|
17019
17243
|
command: "videos.search",
|
|
17020
17244
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -17024,7 +17248,7 @@ registerSchema({
|
|
|
17024
17248
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
17025
17249
|
}
|
|
17026
17250
|
});
|
|
17027
|
-
var searchCommand3 =
|
|
17251
|
+
var searchCommand3 = defineCommand144({
|
|
17028
17252
|
meta: {
|
|
17029
17253
|
name: "search",
|
|
17030
17254
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -17074,9 +17298,9 @@ var searchCommand3 = defineCommand143({
|
|
|
17074
17298
|
var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
17075
17299
|
|
|
17076
17300
|
// src/commands/videos/upload.ts
|
|
17077
|
-
import { readFile as
|
|
17301
|
+
import { readFile as readFile13, stat as stat3 } from "fs/promises";
|
|
17078
17302
|
import { extname as extname3 } from "path";
|
|
17079
|
-
import { defineCommand as
|
|
17303
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
17080
17304
|
var MIME_MAP2 = {
|
|
17081
17305
|
".mp4": "video/mp4",
|
|
17082
17306
|
".mov": "video/quicktime",
|
|
@@ -17110,7 +17334,7 @@ function detectContentType2(filePath) {
|
|
|
17110
17334
|
}
|
|
17111
17335
|
return mime;
|
|
17112
17336
|
}
|
|
17113
|
-
var uploadCommand2 =
|
|
17337
|
+
var uploadCommand2 = defineCommand145({
|
|
17114
17338
|
meta: {
|
|
17115
17339
|
name: "upload",
|
|
17116
17340
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -17139,7 +17363,7 @@ var uploadCommand2 = defineCommand144({
|
|
|
17139
17363
|
return;
|
|
17140
17364
|
}
|
|
17141
17365
|
const { uploadUrl, videoId } = await apiPost("/api/videos/upload", {});
|
|
17142
|
-
const fileBuffer = await
|
|
17366
|
+
const fileBuffer = await readFile13(filePath);
|
|
17143
17367
|
const uploadResponse = await fetch(uploadUrl, {
|
|
17144
17368
|
method: "PUT",
|
|
17145
17369
|
headers: { "Content-Type": contentType },
|
|
@@ -17164,7 +17388,7 @@ var uploadCommand2 = defineCommand144({
|
|
|
17164
17388
|
});
|
|
17165
17389
|
|
|
17166
17390
|
// src/commands/videos/index.ts
|
|
17167
|
-
var videosCommand =
|
|
17391
|
+
var videosCommand = defineCommand146({
|
|
17168
17392
|
meta: {
|
|
17169
17393
|
name: "videos",
|
|
17170
17394
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -17187,10 +17411,10 @@ Examples:
|
|
|
17187
17411
|
});
|
|
17188
17412
|
|
|
17189
17413
|
// src/commands/winning-ads/index.ts
|
|
17190
|
-
import { defineCommand as
|
|
17414
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
17191
17415
|
|
|
17192
17416
|
// src/commands/winning-ads/advertisers.ts
|
|
17193
|
-
import { defineCommand as
|
|
17417
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
17194
17418
|
registerSchema({
|
|
17195
17419
|
command: "winning-ads.advertisers",
|
|
17196
17420
|
description: "Resolve a brand name to advertiser_id(s) in the ad-dna corpus \u2014 to find your OWN advertiser (to --exclude-advertiser) or a competitor (to --advertiser-id).",
|
|
@@ -17203,7 +17427,7 @@ registerSchema({
|
|
|
17203
17427
|
function identity(record) {
|
|
17204
17428
|
return record;
|
|
17205
17429
|
}
|
|
17206
|
-
var advertisersCommand2 =
|
|
17430
|
+
var advertisersCommand2 = defineCommand147({
|
|
17207
17431
|
meta: {
|
|
17208
17432
|
name: "advertisers",
|
|
17209
17433
|
description: 'Resolve a brand name to advertiser_id(s). Use it to find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id. Example: baker winning-ads advertisers "Deel" --output md'
|
|
@@ -17254,7 +17478,7 @@ var advertisersCommand2 = defineCommand146({
|
|
|
17254
17478
|
});
|
|
17255
17479
|
|
|
17256
17480
|
// src/commands/winning-ads/search.ts
|
|
17257
|
-
import { defineCommand as
|
|
17481
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
17258
17482
|
registerSchema({
|
|
17259
17483
|
command: "winning-ads.search",
|
|
17260
17484
|
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.",
|
|
@@ -17362,7 +17586,7 @@ function buildSearchBody(args) {
|
|
|
17362
17586
|
}
|
|
17363
17587
|
return body;
|
|
17364
17588
|
}
|
|
17365
|
-
var searchCommand4 =
|
|
17589
|
+
var searchCommand4 = defineCommand148({
|
|
17366
17590
|
meta: {
|
|
17367
17591
|
name: "search",
|
|
17368
17592
|
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"
|
|
@@ -17474,7 +17698,7 @@ var searchCommand4 = defineCommand147({
|
|
|
17474
17698
|
});
|
|
17475
17699
|
|
|
17476
17700
|
// src/commands/winning-ads/index.ts
|
|
17477
|
-
var winningAdsCommand =
|
|
17701
|
+
var winningAdsCommand = defineCommand149({
|
|
17478
17702
|
meta: {
|
|
17479
17703
|
name: "winning-ads",
|
|
17480
17704
|
description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
|
|
@@ -17514,7 +17738,7 @@ function getCliVersion() {
|
|
|
17514
17738
|
}
|
|
17515
17739
|
|
|
17516
17740
|
// src/cli.ts
|
|
17517
|
-
var main =
|
|
17741
|
+
var main = defineCommand150({
|
|
17518
17742
|
meta: {
|
|
17519
17743
|
name: "baker",
|
|
17520
17744
|
version: getCliVersion(),
|