@koda-sl/baker-cli 0.97.0 → 0.98.0-dev.62be5b016
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-IKMDQQ4M.js";
|
|
13
15
|
|
|
14
16
|
// src/cli.ts
|
|
15
|
-
import { defineCommand as
|
|
17
|
+
import { defineCommand as defineCommand149, runMain } from "citty";
|
|
16
18
|
|
|
17
19
|
// src/commands/actions/index.ts
|
|
18
20
|
import { defineCommand as defineCommand17 } from "citty";
|
|
@@ -147,9 +149,9 @@ async function handleResponse(response) {
|
|
|
147
149
|
throw new ApiError("INTERNAL_ERROR", "Failed to parse API response as JSON");
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
|
-
async function apiGet(
|
|
152
|
+
async function apiGet(path8, params) {
|
|
151
153
|
const env = getEnv();
|
|
152
|
-
const url = new URL(
|
|
154
|
+
const url = new URL(path8, env.BAKER_API_URL);
|
|
153
155
|
if (params) {
|
|
154
156
|
const clean = sanitizeParams(params);
|
|
155
157
|
for (const [key, value] of Object.entries(clean)) {
|
|
@@ -174,12 +176,12 @@ async function apiGet(path7, params) {
|
|
|
174
176
|
}
|
|
175
177
|
return handleResponse(response);
|
|
176
178
|
}
|
|
177
|
-
async function apiPost(
|
|
179
|
+
async function apiPost(path8, body, opts) {
|
|
178
180
|
const env = getEnv();
|
|
179
181
|
const timeoutMs = opts?.timeoutMs ?? 6e4;
|
|
180
182
|
let response;
|
|
181
183
|
try {
|
|
182
|
-
response = await fetchWithRateLimitRetry(new URL(
|
|
184
|
+
response = await fetchWithRateLimitRetry(new URL(path8, env.BAKER_API_URL).toString(), {
|
|
183
185
|
method: "POST",
|
|
184
186
|
headers: {
|
|
185
187
|
Authorization: `Bearer ${env.BAKER_API_KEY}`,
|
|
@@ -1327,31 +1329,31 @@ function cachePath(category, key) {
|
|
|
1327
1329
|
return join(dir, `${hashKey(key)}.json`);
|
|
1328
1330
|
}
|
|
1329
1331
|
function cacheGet(category, key) {
|
|
1330
|
-
const
|
|
1331
|
-
if (!existsSync(
|
|
1332
|
+
const path8 = cachePath(category, key);
|
|
1333
|
+
if (!existsSync(path8)) {
|
|
1332
1334
|
return null;
|
|
1333
1335
|
}
|
|
1334
1336
|
try {
|
|
1335
|
-
const raw = readFileSync(
|
|
1337
|
+
const raw = readFileSync(path8, "utf-8");
|
|
1336
1338
|
const entry = JSON.parse(raw);
|
|
1337
1339
|
if (entry.expiresAt < Date.now()) {
|
|
1338
|
-
rmSync(
|
|
1340
|
+
rmSync(path8, { force: true });
|
|
1339
1341
|
return null;
|
|
1340
1342
|
}
|
|
1341
1343
|
return entry;
|
|
1342
1344
|
} catch {
|
|
1343
|
-
rmSync(
|
|
1345
|
+
rmSync(path8, { force: true });
|
|
1344
1346
|
return null;
|
|
1345
1347
|
}
|
|
1346
1348
|
}
|
|
1347
1349
|
function cacheSet(category, key, data, ttlMs, fields) {
|
|
1348
|
-
const
|
|
1350
|
+
const path8 = cachePath(category, key);
|
|
1349
1351
|
const entry = {
|
|
1350
1352
|
expiresAt: Date.now() + ttlMs,
|
|
1351
1353
|
data,
|
|
1352
1354
|
fields
|
|
1353
1355
|
};
|
|
1354
|
-
writeFileSync(
|
|
1356
|
+
writeFileSync(path8, JSON.stringify(entry), "utf-8");
|
|
1355
1357
|
}
|
|
1356
1358
|
var HOUR = 60 * 60 * 1e3;
|
|
1357
1359
|
var MINUTE = 60 * 1e3;
|
|
@@ -8045,7 +8047,7 @@ Examples:
|
|
|
8045
8047
|
});
|
|
8046
8048
|
|
|
8047
8049
|
// src/commands/canvas/index.ts
|
|
8048
|
-
import { defineCommand as
|
|
8050
|
+
import { defineCommand as defineCommand85 } from "citty";
|
|
8049
8051
|
|
|
8050
8052
|
// src/commands/canvas/catalog.ts
|
|
8051
8053
|
import { defineCommand as defineCommand78 } from "citty";
|
|
@@ -8061,14 +8063,232 @@ var catalogCommand = defineCommand78({
|
|
|
8061
8063
|
}
|
|
8062
8064
|
});
|
|
8063
8065
|
|
|
8066
|
+
// src/commands/canvas/gallery.ts
|
|
8067
|
+
import { readdir, readFile } from "fs/promises";
|
|
8068
|
+
import path from "path";
|
|
8069
|
+
import { defineCommand as defineCommand79 } from "citty";
|
|
8070
|
+
|
|
8071
|
+
// src/engine/gallery/descriptor.ts
|
|
8072
|
+
var KNOWN_RATIOS = [
|
|
8073
|
+
["9:16", 9 / 16],
|
|
8074
|
+
["4:5", 4 / 5],
|
|
8075
|
+
["1:1", 1],
|
|
8076
|
+
["1.91:1", 1.91],
|
|
8077
|
+
["16:9", 16 / 9],
|
|
8078
|
+
["4:1", 4]
|
|
8079
|
+
];
|
|
8080
|
+
var RATIO_TOLERANCE = 0.06;
|
|
8081
|
+
function aspectLabel(width, height) {
|
|
8082
|
+
if (!width || !height) {
|
|
8083
|
+
return "other";
|
|
8084
|
+
}
|
|
8085
|
+
const ratio = width / height;
|
|
8086
|
+
let best = "other";
|
|
8087
|
+
let bestErr = Number.POSITIVE_INFINITY;
|
|
8088
|
+
for (const [label, value] of KNOWN_RATIOS) {
|
|
8089
|
+
const err = Math.abs(ratio - value) / value;
|
|
8090
|
+
if (err < bestErr) {
|
|
8091
|
+
bestErr = err;
|
|
8092
|
+
best = label;
|
|
8093
|
+
}
|
|
8094
|
+
}
|
|
8095
|
+
return bestErr <= RATIO_TOLERANCE ? best : `${width}x${height}`;
|
|
8096
|
+
}
|
|
8097
|
+
function visualRef(value) {
|
|
8098
|
+
const parsed = AssetRef.safeParse(value);
|
|
8099
|
+
if (!parsed.success) {
|
|
8100
|
+
return null;
|
|
8101
|
+
}
|
|
8102
|
+
if (parsed.data.kind !== "image" && parsed.data.kind !== "video") {
|
|
8103
|
+
return null;
|
|
8104
|
+
}
|
|
8105
|
+
return parsed.data;
|
|
8106
|
+
}
|
|
8107
|
+
function deliverableFor(ref, stem, resolveLocal) {
|
|
8108
|
+
const width = "width" in ref ? ref.width : void 0;
|
|
8109
|
+
const height = "height" in ref ? ref.height : void 0;
|
|
8110
|
+
return {
|
|
8111
|
+
kind: ref.kind,
|
|
8112
|
+
format: aspectLabel(width, height),
|
|
8113
|
+
// Remote-node outputs already carry a public R2 url; local composites are
|
|
8114
|
+
// resolved against the mounted run dir's public base.
|
|
8115
|
+
url: ref.url ?? resolveLocal(`${stem}.${extForMime(ref.mime)}`),
|
|
8116
|
+
width,
|
|
8117
|
+
height,
|
|
8118
|
+
label: stem
|
|
8119
|
+
};
|
|
8120
|
+
}
|
|
8121
|
+
function deliverablesFromOutput(output, resolveLocal) {
|
|
8122
|
+
if (Array.isArray(output)) {
|
|
8123
|
+
const out = [];
|
|
8124
|
+
output.forEach((entry, i) => {
|
|
8125
|
+
const ref2 = visualRef(entry);
|
|
8126
|
+
if (ref2) {
|
|
8127
|
+
out.push(deliverableFor(ref2, `_final__${i}`, resolveLocal));
|
|
8128
|
+
}
|
|
8129
|
+
});
|
|
8130
|
+
return out;
|
|
8131
|
+
}
|
|
8132
|
+
const ref = visualRef(output);
|
|
8133
|
+
return ref ? [deliverableFor(ref, "_final", resolveLocal)] : [];
|
|
8134
|
+
}
|
|
8135
|
+
function buildGeneration(runId, manifest, resolveLocal) {
|
|
8136
|
+
const m = manifest ?? {};
|
|
8137
|
+
const credits = typeof m.stats?.total_credits === "number" ? m.stats.total_credits : 0;
|
|
8138
|
+
return {
|
|
8139
|
+
runId,
|
|
8140
|
+
createdAt: typeof m.completed_at === "number" ? m.completed_at : 0,
|
|
8141
|
+
credits,
|
|
8142
|
+
deliverables: deliverablesFromOutput(m.output, resolveLocal)
|
|
8143
|
+
};
|
|
8144
|
+
}
|
|
8145
|
+
function buildGalleryDescriptor(input) {
|
|
8146
|
+
const generations = [...input.generations].sort((a, b) => b.createdAt - a.createdAt);
|
|
8147
|
+
return {
|
|
8148
|
+
slug: input.slug,
|
|
8149
|
+
title: input.definition.title,
|
|
8150
|
+
platform: input.definition.platform,
|
|
8151
|
+
status: input.definition.status,
|
|
8152
|
+
reference: input.definition.reference,
|
|
8153
|
+
selectedRun: input.definition.selectedRun,
|
|
8154
|
+
generations
|
|
8155
|
+
};
|
|
8156
|
+
}
|
|
8157
|
+
function titleFromSlug(slug) {
|
|
8158
|
+
return slug.split(/[-_/]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
8159
|
+
}
|
|
8160
|
+
function stripQuotes(raw) {
|
|
8161
|
+
const trimmed = raw.trim();
|
|
8162
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
8163
|
+
return trimmed.slice(1, -1);
|
|
8164
|
+
}
|
|
8165
|
+
return trimmed;
|
|
8166
|
+
}
|
|
8167
|
+
function parseInlineList(raw) {
|
|
8168
|
+
return raw.slice(1, -1).split(",").map((item) => stripQuotes(item)).filter(Boolean);
|
|
8169
|
+
}
|
|
8170
|
+
function parseFrontmatter(markdown) {
|
|
8171
|
+
const match = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
8172
|
+
const block = match?.[1];
|
|
8173
|
+
if (!block) {
|
|
8174
|
+
return {};
|
|
8175
|
+
}
|
|
8176
|
+
const out = {};
|
|
8177
|
+
let listKey = null;
|
|
8178
|
+
for (const line of block.split(/\r?\n/)) {
|
|
8179
|
+
const item = line.match(/^\s+-\s+(.*)$/)?.[1];
|
|
8180
|
+
if (listKey && item !== void 0) {
|
|
8181
|
+
out[listKey].push(stripQuotes(item));
|
|
8182
|
+
continue;
|
|
8183
|
+
}
|
|
8184
|
+
const kv = line.match(/^([A-Za-z0-9_]+):\s*(.*)$/);
|
|
8185
|
+
if (!kv?.[1]) {
|
|
8186
|
+
continue;
|
|
8187
|
+
}
|
|
8188
|
+
listKey = null;
|
|
8189
|
+
const key = kv[1];
|
|
8190
|
+
const value = (kv[2] ?? "").trim();
|
|
8191
|
+
if (value === "") {
|
|
8192
|
+
out[key] = [];
|
|
8193
|
+
listKey = key;
|
|
8194
|
+
} else if (value.startsWith("[") && value.endsWith("]")) {
|
|
8195
|
+
out[key] = parseInlineList(value);
|
|
8196
|
+
} else {
|
|
8197
|
+
out[key] = stripQuotes(value);
|
|
8198
|
+
}
|
|
8199
|
+
}
|
|
8200
|
+
return out;
|
|
8201
|
+
}
|
|
8202
|
+
function asString(value) {
|
|
8203
|
+
if (typeof value === "string" && value.length > 0) {
|
|
8204
|
+
return value;
|
|
8205
|
+
}
|
|
8206
|
+
return void 0;
|
|
8207
|
+
}
|
|
8208
|
+
function asList(value) {
|
|
8209
|
+
if (Array.isArray(value)) {
|
|
8210
|
+
return value;
|
|
8211
|
+
}
|
|
8212
|
+
return typeof value === "string" && value.length > 0 ? [value] : [];
|
|
8213
|
+
}
|
|
8214
|
+
function parseCreativeDefinition(markdown, slug) {
|
|
8215
|
+
const fm = parseFrontmatter(markdown);
|
|
8216
|
+
return {
|
|
8217
|
+
title: asString(fm.title) ?? titleFromSlug(slug),
|
|
8218
|
+
platform: asList(fm.platform),
|
|
8219
|
+
formats: asList(fm.formats),
|
|
8220
|
+
status: asString(fm.status) ?? "draft",
|
|
8221
|
+
reference: asString(fm.reference),
|
|
8222
|
+
selectedRun: asString(fm.selected_run)
|
|
8223
|
+
};
|
|
8224
|
+
}
|
|
8225
|
+
|
|
8226
|
+
// src/commands/canvas/gallery.ts
|
|
8227
|
+
async function readJson(file) {
|
|
8228
|
+
try {
|
|
8229
|
+
return JSON.parse(await readFile(file, "utf8"));
|
|
8230
|
+
} catch {
|
|
8231
|
+
return null;
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
async function listRunDirs(runsDir) {
|
|
8235
|
+
try {
|
|
8236
|
+
const entries = await readdir(runsDir, { withFileTypes: true });
|
|
8237
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
8238
|
+
} catch {
|
|
8239
|
+
return [];
|
|
8240
|
+
}
|
|
8241
|
+
}
|
|
8242
|
+
var galleryCommand = defineCommand79({
|
|
8243
|
+
meta: {
|
|
8244
|
+
name: "gallery",
|
|
8245
|
+
description: "Read a creative's _definition.md + every persisted run manifest and emit the gallery descriptor (JSON) the dashboard renders."
|
|
8246
|
+
},
|
|
8247
|
+
args: {
|
|
8248
|
+
dir: { type: "positional", required: true, description: "Creative folder, e.g. src/creatives/<slug>" },
|
|
8249
|
+
"workspace-dir": { type: "string", description: "R2-mounted workspace root (default ./.creatives-workspace)" },
|
|
8250
|
+
"public-url": { type: "string", description: "R2 public base (default $R2_PUBLIC_URL)" },
|
|
8251
|
+
"company-id": { type: "string", description: "Company id for the R2 prefix (default $BAKER_COMPANY_ID)" }
|
|
8252
|
+
},
|
|
8253
|
+
async run({ args }) {
|
|
8254
|
+
const creativeDir = path.resolve(String(args.dir));
|
|
8255
|
+
const slug = path.basename(creativeDir);
|
|
8256
|
+
const workspaceDir = path.resolve(String(args["workspace-dir"] ?? ".creatives-workspace"));
|
|
8257
|
+
const runsDir = path.join(workspaceDir, slug, "runs");
|
|
8258
|
+
const runtimeEnv = process.env;
|
|
8259
|
+
const publicUrl = (args["public-url"] ?? runtimeEnv.R2_PUBLIC_URL ?? "").replace(/\/+$/, "");
|
|
8260
|
+
const companyId = String(args["company-id"] ?? runtimeEnv.BAKER_COMPANY_ID ?? "");
|
|
8261
|
+
const definitionPath = path.join(creativeDir, "_definition.md");
|
|
8262
|
+
let definitionMd = "";
|
|
8263
|
+
try {
|
|
8264
|
+
definitionMd = await readFile(definitionPath, "utf8");
|
|
8265
|
+
} catch {
|
|
8266
|
+
}
|
|
8267
|
+
const definition = parseCreativeDefinition(definitionMd, slug);
|
|
8268
|
+
const generations = [];
|
|
8269
|
+
for (const runId of await listRunDirs(runsDir)) {
|
|
8270
|
+
const manifest = await readJson(path.join(runsDir, runId, "manifest.json"));
|
|
8271
|
+
if (!manifest) {
|
|
8272
|
+
continue;
|
|
8273
|
+
}
|
|
8274
|
+
const runDir = path.join(runsDir, runId);
|
|
8275
|
+
const resolveLocal = (filename) => publicUrl && companyId ? `${publicUrl}/creatives/${companyId}/${slug}/runs/${runId}/${filename}` : path.join(runDir, filename);
|
|
8276
|
+
generations.push(buildGeneration(runId, manifest, resolveLocal));
|
|
8277
|
+
}
|
|
8278
|
+
const descriptor = buildGalleryDescriptor({ slug, definition, generations });
|
|
8279
|
+
process.stdout.write(`${JSON.stringify({ ok: true, descriptor }, null, 2)}
|
|
8280
|
+
`);
|
|
8281
|
+
}
|
|
8282
|
+
});
|
|
8283
|
+
|
|
8064
8284
|
// src/commands/canvas/inspect.ts
|
|
8065
8285
|
import { execFile } from "child_process";
|
|
8066
|
-
import { readdir, readFile, stat } from "fs/promises";
|
|
8067
|
-
import
|
|
8286
|
+
import { readdir as readdir2, readFile as readFile2, stat } from "fs/promises";
|
|
8287
|
+
import path2 from "path";
|
|
8068
8288
|
import { promisify } from "util";
|
|
8069
|
-
import { defineCommand as
|
|
8289
|
+
import { defineCommand as defineCommand80 } from "citty";
|
|
8070
8290
|
var execFileAsync = promisify(execFile);
|
|
8071
|
-
var inspectCommand =
|
|
8291
|
+
var inspectCommand = defineCommand80({
|
|
8072
8292
|
meta: {
|
|
8073
8293
|
name: "inspect",
|
|
8074
8294
|
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 +8302,7 @@ var inspectCommand = defineCommand79({
|
|
|
8082
8302
|
}
|
|
8083
8303
|
},
|
|
8084
8304
|
async run({ args }) {
|
|
8085
|
-
const outputsDir =
|
|
8305
|
+
const outputsDir = path2.resolve(String(args["outputs-dir"] ?? "canvas"));
|
|
8086
8306
|
const runArg = String(args.run);
|
|
8087
8307
|
const runDir = await resolveRunDir(runArg, outputsDir);
|
|
8088
8308
|
const manifest = await loadManifest(runDir);
|
|
@@ -8094,7 +8314,7 @@ var inspectCommand = defineCommand79({
|
|
|
8094
8314
|
}
|
|
8095
8315
|
const summary = {
|
|
8096
8316
|
ok: true,
|
|
8097
|
-
run_id: manifest.run_id ??
|
|
8317
|
+
run_id: manifest.run_id ?? path2.basename(runDir),
|
|
8098
8318
|
run_dir: runDir,
|
|
8099
8319
|
stats: manifest.stats ?? null,
|
|
8100
8320
|
output: manifest.output ?? null,
|
|
@@ -8107,20 +8327,20 @@ var inspectCommand = defineCommand79({
|
|
|
8107
8327
|
}
|
|
8108
8328
|
});
|
|
8109
8329
|
async function resolveRunDir(run, outputsDir) {
|
|
8110
|
-
if (
|
|
8330
|
+
if (path2.isAbsolute(run)) {
|
|
8111
8331
|
const s2 = await stat(run).catch(() => null);
|
|
8112
8332
|
if (s2?.isDirectory()) return run;
|
|
8113
8333
|
throw new Error(`inspect: ${run} is not a directory`);
|
|
8114
8334
|
}
|
|
8115
|
-
const candidate =
|
|
8335
|
+
const candidate = path2.join(outputsDir, run);
|
|
8116
8336
|
const s = await stat(candidate).catch(() => null);
|
|
8117
8337
|
if (s?.isDirectory()) return candidate;
|
|
8118
8338
|
throw new Error(`inspect: no run directory at ${candidate}`);
|
|
8119
8339
|
}
|
|
8120
8340
|
async function loadManifest(runDir) {
|
|
8121
|
-
const manifestPath =
|
|
8341
|
+
const manifestPath = path2.join(runDir, "manifest.json");
|
|
8122
8342
|
try {
|
|
8123
|
-
const raw = await
|
|
8343
|
+
const raw = await readFile2(manifestPath, "utf-8");
|
|
8124
8344
|
return JSON.parse(raw);
|
|
8125
8345
|
} catch {
|
|
8126
8346
|
return {};
|
|
@@ -8128,9 +8348,9 @@ async function loadManifest(runDir) {
|
|
|
8128
8348
|
}
|
|
8129
8349
|
async function listRunFiles(runDir) {
|
|
8130
8350
|
const out = [];
|
|
8131
|
-
const names = await
|
|
8351
|
+
const names = await readdir2(runDir);
|
|
8132
8352
|
for (const name of names) {
|
|
8133
|
-
const abs =
|
|
8353
|
+
const abs = path2.join(runDir, name);
|
|
8134
8354
|
const s = await stat(abs).catch(() => null);
|
|
8135
8355
|
if (!s?.isFile()) continue;
|
|
8136
8356
|
out.push({ name, path: abs, size: s.size });
|
|
@@ -8175,9 +8395,9 @@ async function probeDuration(filePath) {
|
|
|
8175
8395
|
}
|
|
8176
8396
|
|
|
8177
8397
|
// src/commands/canvas/run.ts
|
|
8178
|
-
import { readFile as
|
|
8179
|
-
import
|
|
8180
|
-
import { defineCommand as
|
|
8398
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
8399
|
+
import path3 from "path";
|
|
8400
|
+
import { defineCommand as defineCommand81 } from "citty";
|
|
8181
8401
|
|
|
8182
8402
|
// src/commands/canvas/placeholders.ts
|
|
8183
8403
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
@@ -8196,7 +8416,7 @@ function unsuppliedPlaceholderAssets(canvas) {
|
|
|
8196
8416
|
}
|
|
8197
8417
|
|
|
8198
8418
|
// src/commands/canvas/run.ts
|
|
8199
|
-
var runCommand =
|
|
8419
|
+
var runCommand = defineCommand81({
|
|
8200
8420
|
meta: { name: "run", description: "Validate and execute a canvas JSON file." },
|
|
8201
8421
|
args: {
|
|
8202
8422
|
file: { type: "positional", required: true, description: "Path to canvas JSON" },
|
|
@@ -8206,8 +8426,8 @@ var runCommand = defineCommand80({
|
|
|
8206
8426
|
"cache-policy": { type: "string", description: "read_write | bypass | read_only" }
|
|
8207
8427
|
},
|
|
8208
8428
|
async run({ args }) {
|
|
8209
|
-
const filePath =
|
|
8210
|
-
const raw = await
|
|
8429
|
+
const filePath = path3.resolve(String(args.file));
|
|
8430
|
+
const raw = await readFile3(filePath, "utf8");
|
|
8211
8431
|
let parsed;
|
|
8212
8432
|
try {
|
|
8213
8433
|
parsed = JSON.parse(raw);
|
|
@@ -8279,9 +8499,9 @@ var runCommand = defineCommand80({
|
|
|
8279
8499
|
});
|
|
8280
8500
|
|
|
8281
8501
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
8282
|
-
import { readFile as
|
|
8283
|
-
import
|
|
8284
|
-
import { defineCommand as
|
|
8502
|
+
import { readFile as readFile4, writeFile } from "fs/promises";
|
|
8503
|
+
import path4 from "path";
|
|
8504
|
+
import { defineCommand as defineCommand82 } from "citty";
|
|
8285
8505
|
|
|
8286
8506
|
// src/engine/scaffold/staticAd.ts
|
|
8287
8507
|
import { z as z2 } from "zod";
|
|
@@ -8494,7 +8714,7 @@ var SELECT_SYSTEM = 'You identify the MAIN, identity-critical visual elements of
|
|
|
8494
8714
|
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.';
|
|
8495
8715
|
async function loadAssetText(ref, label) {
|
|
8496
8716
|
const r = ref;
|
|
8497
|
-
if (typeof r?.path === "string") return
|
|
8717
|
+
if (typeof r?.path === "string") return readFile4(r.path, "utf8");
|
|
8498
8718
|
if (typeof r?.url === "string") {
|
|
8499
8719
|
const res = await fetch(r.url);
|
|
8500
8720
|
if (!res.ok) throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
@@ -8600,7 +8820,7 @@ async function runVisionPasses(canvas) {
|
|
|
8600
8820
|
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
8601
8821
|
}
|
|
8602
8822
|
}
|
|
8603
|
-
var scaffoldStaticAdCommand =
|
|
8823
|
+
var scaffoldStaticAdCommand = defineCommand82({
|
|
8604
8824
|
meta: {
|
|
8605
8825
|
name: "scaffold-static-ad",
|
|
8606
8826
|
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."
|
|
@@ -8617,10 +8837,10 @@ var scaffoldStaticAdCommand = defineCommand81({
|
|
|
8617
8837
|
"skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
|
|
8618
8838
|
},
|
|
8619
8839
|
async run({ args }) {
|
|
8620
|
-
const imagePath =
|
|
8621
|
-
const outPath = args.out ?
|
|
8622
|
-
const outDir =
|
|
8623
|
-
const blueprintPath =
|
|
8840
|
+
const imagePath = path4.resolve(String(args.file));
|
|
8841
|
+
const outPath = args.out ? path4.resolve(String(args.out)) : path4.join(path4.dirname(imagePath), "static-ad.canvas.json");
|
|
8842
|
+
const outDir = path4.dirname(outPath);
|
|
8843
|
+
const blueprintPath = path4.join(outDir, "prompt.json");
|
|
8624
8844
|
const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
|
|
8625
8845
|
const describeCanvas = buildDescribeCanvas(
|
|
8626
8846
|
imagePath,
|
|
@@ -8677,7 +8897,7 @@ var scaffoldStaticAdCommand = defineCommand81({
|
|
|
8677
8897
|
run_estimated_credits: validation.estimatedCredits
|
|
8678
8898
|
},
|
|
8679
8899
|
checklist: {
|
|
8680
|
-
edit_prompt: `Edit ${
|
|
8900
|
+
edit_prompt: `Edit ${path4.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.`,
|
|
8681
8901
|
assets_to_supply: report.elements,
|
|
8682
8902
|
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)",
|
|
8683
8903
|
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."
|
|
@@ -8692,13 +8912,13 @@ var scaffoldStaticAdCommand = defineCommand81({
|
|
|
8692
8912
|
});
|
|
8693
8913
|
|
|
8694
8914
|
// src/commands/canvas/scaffold-video.ts
|
|
8695
|
-
import { cp, mkdir, readFile as
|
|
8696
|
-
import
|
|
8697
|
-
import { defineCommand as
|
|
8915
|
+
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
8916
|
+
import path6 from "path";
|
|
8917
|
+
import { defineCommand as defineCommand83 } from "citty";
|
|
8698
8918
|
|
|
8699
8919
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
8700
8920
|
import { execFile as execFile2 } from "child_process";
|
|
8701
|
-
import { mkdtemp, readdir as
|
|
8921
|
+
import { mkdtemp, readdir as readdir3, readFile as readFile5, rm } from "fs/promises";
|
|
8702
8922
|
import { tmpdir } from "os";
|
|
8703
8923
|
import { join as join2 } from "path";
|
|
8704
8924
|
import { promisify as promisify2 } from "util";
|
|
@@ -8762,9 +8982,9 @@ async function runSceneDetectOnce(filePath, threshold, minSceneLenS, timeoutMs)
|
|
|
8762
8982
|
],
|
|
8763
8983
|
{ encoding: "utf-8", maxBuffer: 32 * 1024 * 1024, timeout: timeoutMs }
|
|
8764
8984
|
);
|
|
8765
|
-
const csvName = (await
|
|
8985
|
+
const csvName = (await readdir3(outDir)).find((f) => f.toLowerCase().endsWith(".csv"));
|
|
8766
8986
|
if (!csvName) return [];
|
|
8767
|
-
return parsePySceneDetectCsvCuts(await
|
|
8987
|
+
return parsePySceneDetectCsvCuts(await readFile5(join2(outDir, csvName), "utf-8"));
|
|
8768
8988
|
} finally {
|
|
8769
8989
|
await rm(outDir, { recursive: true, force: true });
|
|
8770
8990
|
}
|
|
@@ -11154,18 +11374,18 @@ function videoReport(input, elementsInput) {
|
|
|
11154
11374
|
|
|
11155
11375
|
// src/commands/canvas/composition-path.ts
|
|
11156
11376
|
import { existsSync as existsSync3 } from "fs";
|
|
11157
|
-
import
|
|
11377
|
+
import path5 from "path";
|
|
11158
11378
|
function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
|
|
11159
|
-
const rel =
|
|
11379
|
+
const rel = path5.join("canvas", name);
|
|
11160
11380
|
let dir = startDir;
|
|
11161
11381
|
for (let i = 0; i < maxDepth; i++) {
|
|
11162
|
-
const candidate =
|
|
11163
|
-
if (exists(
|
|
11164
|
-
const parent =
|
|
11382
|
+
const candidate = path5.join(dir, rel);
|
|
11383
|
+
if (exists(path5.join(candidate, "meta.json"))) return candidate;
|
|
11384
|
+
const parent = path5.dirname(dir);
|
|
11165
11385
|
if (parent === dir) break;
|
|
11166
11386
|
dir = parent;
|
|
11167
11387
|
}
|
|
11168
|
-
return
|
|
11388
|
+
return path5.resolve(startDir, "../../../", rel);
|
|
11169
11389
|
}
|
|
11170
11390
|
|
|
11171
11391
|
// src/commands/canvas/scaffold-video.ts
|
|
@@ -11194,7 +11414,7 @@ ONE PERSON, MULTIPLE LOOKS: if a single individual plays MULTIPLE personas or wa
|
|
|
11194
11414
|
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.`;
|
|
11195
11415
|
async function loadAssetText2(ref, label) {
|
|
11196
11416
|
const r = ref;
|
|
11197
|
-
if (typeof r?.path === "string") return
|
|
11417
|
+
if (typeof r?.path === "string") return readFile6(r.path, "utf8");
|
|
11198
11418
|
if (typeof r?.url === "string") {
|
|
11199
11419
|
const res = await fetch(r.url);
|
|
11200
11420
|
if (!res.ok) throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
@@ -11213,7 +11433,7 @@ async function loadTranscriptBestEffort(ref) {
|
|
|
11213
11433
|
async function stageCaptions(outDir, transcript) {
|
|
11214
11434
|
const text = transcript?.trim();
|
|
11215
11435
|
if (!text || text === "[]") return {};
|
|
11216
|
-
const compositionPath =
|
|
11436
|
+
const compositionPath = path6.join(outDir, "tiktok-captions-composition");
|
|
11217
11437
|
await cp(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
|
|
11218
11438
|
return { compositionPath };
|
|
11219
11439
|
}
|
|
@@ -11345,7 +11565,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
11345
11565
|
return fail2("deconstruct", e instanceof Error ? e.message : String(e));
|
|
11346
11566
|
}
|
|
11347
11567
|
}
|
|
11348
|
-
var scaffoldVideoCommand =
|
|
11568
|
+
var scaffoldVideoCommand = defineCommand83({
|
|
11349
11569
|
meta: {
|
|
11350
11570
|
name: "scaffold-video",
|
|
11351
11571
|
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`."
|
|
@@ -11375,11 +11595,11 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11375
11595
|
}
|
|
11376
11596
|
},
|
|
11377
11597
|
async run({ args }) {
|
|
11378
|
-
const videoPath =
|
|
11379
|
-
const base =
|
|
11380
|
-
const outPath = args.out ?
|
|
11381
|
-
const outDir =
|
|
11382
|
-
const blueprintPath =
|
|
11598
|
+
const videoPath = path6.resolve(String(args.file));
|
|
11599
|
+
const base = path6.basename(videoPath, path6.extname(videoPath));
|
|
11600
|
+
const outPath = args.out ? path6.resolve(String(args.out)) : path6.join(path6.dirname(videoPath), `${base}.video.canvas.json`);
|
|
11601
|
+
const outDir = path6.dirname(outPath);
|
|
11602
|
+
const blueprintPath = path6.join(outDir, "prompt.json");
|
|
11383
11603
|
const frames = args.frames === "reuse" ? "reuse" : "generate";
|
|
11384
11604
|
const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
|
|
11385
11605
|
if (Number.isFinite(maxScenes)) {
|
|
@@ -11402,11 +11622,11 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11402
11622
|
const annotated = annotateBlueprintWithElements(blueprint, elements);
|
|
11403
11623
|
await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
|
|
11404
11624
|
`, "utf8");
|
|
11405
|
-
const compositionDest =
|
|
11625
|
+
const compositionDest = path6.join(outDir, "video-overlay-composition");
|
|
11406
11626
|
await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
|
|
11407
|
-
const indexPath =
|
|
11627
|
+
const indexPath = path6.join(compositionDest, "index.html");
|
|
11408
11628
|
const overlayHtml = buildOverlayHtml(blueprint);
|
|
11409
|
-
const indexHtml = await
|
|
11629
|
+
const indexHtml = await readFile6(indexPath, "utf8");
|
|
11410
11630
|
const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
|
|
11411
11631
|
if (injected === indexHtml && overlayHtml.trim()) {
|
|
11412
11632
|
fail2(
|
|
@@ -11461,7 +11681,7 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11461
11681
|
run_estimated_credits: validation.estimatedCredits
|
|
11462
11682
|
},
|
|
11463
11683
|
checklist: {
|
|
11464
|
-
edit_prompt: `Edit ${
|
|
11684
|
+
edit_prompt: `Edit ${path6.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.`,
|
|
11465
11685
|
recurring_elements_to_supply: report.elements,
|
|
11466
11686
|
voices_to_confirm: report.dialogue.map((d) => ({
|
|
11467
11687
|
scene: d.scene,
|
|
@@ -11487,18 +11707,18 @@ var scaffoldVideoCommand = defineCommand82({
|
|
|
11487
11707
|
});
|
|
11488
11708
|
|
|
11489
11709
|
// src/commands/canvas/validate.ts
|
|
11490
|
-
import { readFile as
|
|
11491
|
-
import
|
|
11492
|
-
import { defineCommand as
|
|
11493
|
-
var validateCommand =
|
|
11710
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
11711
|
+
import path7 from "path";
|
|
11712
|
+
import { defineCommand as defineCommand84 } from "citty";
|
|
11713
|
+
var validateCommand = defineCommand84({
|
|
11494
11714
|
meta: {
|
|
11495
11715
|
name: "validate",
|
|
11496
11716
|
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)."
|
|
11497
11717
|
},
|
|
11498
11718
|
args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
|
|
11499
11719
|
async run({ args }) {
|
|
11500
|
-
const filePath =
|
|
11501
|
-
const raw = await
|
|
11720
|
+
const filePath = path7.resolve(String(args.file));
|
|
11721
|
+
const raw = await readFile7(filePath, "utf8");
|
|
11502
11722
|
let parsed;
|
|
11503
11723
|
try {
|
|
11504
11724
|
parsed = JSON.parse(raw);
|
|
@@ -11532,7 +11752,7 @@ var validateCommand = defineCommand83({
|
|
|
11532
11752
|
});
|
|
11533
11753
|
|
|
11534
11754
|
// src/commands/canvas/index.ts
|
|
11535
|
-
var canvasCommand =
|
|
11755
|
+
var canvasCommand = defineCommand85({
|
|
11536
11756
|
meta: {
|
|
11537
11757
|
name: "canvas",
|
|
11538
11758
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -11544,6 +11764,7 @@ Subcommands:
|
|
|
11544
11764
|
baker canvas run <file.json> \u2014 execute the canvas, write outputs to ./canvas/<run_id>/
|
|
11545
11765
|
baker canvas catalog \u2014 print the agent-facing node + composition catalog (JSON Schema)
|
|
11546
11766
|
baker canvas inspect <run_id> \u2014 one-page summary of a completed run
|
|
11767
|
+
baker canvas gallery <dir> \u2014 read a creative folder's _definition.md + run manifests into the dashboard gallery descriptor (JSON)
|
|
11547
11768
|
baker canvas scaffold-video <video> \u2014 turn a reference video into a runnable reproduction canvas (deconstruct + recurring-element detection)
|
|
11548
11769
|
baker canvas scaffold-static-ad <image> \u2014 turn a source image into a runnable static-ad canvas (describe + element detection)`
|
|
11549
11770
|
},
|
|
@@ -11552,16 +11773,17 @@ Subcommands:
|
|
|
11552
11773
|
validate: validateCommand,
|
|
11553
11774
|
catalog: catalogCommand,
|
|
11554
11775
|
inspect: inspectCommand,
|
|
11776
|
+
gallery: galleryCommand,
|
|
11555
11777
|
"scaffold-video": scaffoldVideoCommand,
|
|
11556
11778
|
"scaffold-static-ad": scaffoldStaticAdCommand
|
|
11557
11779
|
}
|
|
11558
11780
|
});
|
|
11559
11781
|
|
|
11560
11782
|
// src/commands/ga4/index.ts
|
|
11561
|
-
import { defineCommand as
|
|
11783
|
+
import { defineCommand as defineCommand89 } from "citty";
|
|
11562
11784
|
|
|
11563
11785
|
// src/commands/ga4/audit.ts
|
|
11564
|
-
import { defineCommand as
|
|
11786
|
+
import { defineCommand as defineCommand86 } from "citty";
|
|
11565
11787
|
|
|
11566
11788
|
// src/commands/ga4/resolve.ts
|
|
11567
11789
|
async function fetchProperties(useCache = true) {
|
|
@@ -11624,7 +11846,7 @@ registerSchema({
|
|
|
11624
11846
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
11625
11847
|
}
|
|
11626
11848
|
});
|
|
11627
|
-
var auditCommand2 =
|
|
11849
|
+
var auditCommand2 = defineCommand86({
|
|
11628
11850
|
meta: {
|
|
11629
11851
|
name: "audit",
|
|
11630
11852
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -11676,7 +11898,7 @@ Examples:
|
|
|
11676
11898
|
});
|
|
11677
11899
|
|
|
11678
11900
|
// src/commands/ga4/properties.ts
|
|
11679
|
-
import { defineCommand as
|
|
11901
|
+
import { defineCommand as defineCommand87 } from "citty";
|
|
11680
11902
|
registerSchema({
|
|
11681
11903
|
command: "ga4.properties",
|
|
11682
11904
|
description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
|
|
@@ -11684,7 +11906,7 @@ registerSchema({
|
|
|
11684
11906
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
11685
11907
|
}
|
|
11686
11908
|
});
|
|
11687
|
-
var propertiesCommand =
|
|
11909
|
+
var propertiesCommand = defineCommand87({
|
|
11688
11910
|
meta: {
|
|
11689
11911
|
name: "properties",
|
|
11690
11912
|
description: `List accessible GA4 properties.
|
|
@@ -11734,7 +11956,7 @@ Examples:
|
|
|
11734
11956
|
// src/commands/ga4/query.ts
|
|
11735
11957
|
import { appendFileSync as appendFileSync2, existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
11736
11958
|
import { resolve as resolve2 } from "path";
|
|
11737
|
-
import { defineCommand as
|
|
11959
|
+
import { defineCommand as defineCommand88 } from "citty";
|
|
11738
11960
|
|
|
11739
11961
|
// src/commands/ga4/presets.ts
|
|
11740
11962
|
var GA4_PRESETS = [
|
|
@@ -11866,7 +12088,7 @@ function handleError(err) {
|
|
|
11866
12088
|
});
|
|
11867
12089
|
process.exit(1);
|
|
11868
12090
|
}
|
|
11869
|
-
var queryCommand2 =
|
|
12091
|
+
var queryCommand2 = defineCommand88({
|
|
11870
12092
|
meta: {
|
|
11871
12093
|
name: "query",
|
|
11872
12094
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -11937,7 +12159,7 @@ Free-form (escape hatch):
|
|
|
11937
12159
|
});
|
|
11938
12160
|
|
|
11939
12161
|
// src/commands/ga4/index.ts
|
|
11940
|
-
var ga4Command =
|
|
12162
|
+
var ga4Command = defineCommand89({
|
|
11941
12163
|
meta: {
|
|
11942
12164
|
name: "ga4",
|
|
11943
12165
|
description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
|
|
@@ -11960,12 +12182,12 @@ Examples:
|
|
|
11960
12182
|
});
|
|
11961
12183
|
|
|
11962
12184
|
// src/commands/gsc/index.ts
|
|
11963
|
-
import { defineCommand as
|
|
12185
|
+
import { defineCommand as defineCommand93 } from "citty";
|
|
11964
12186
|
|
|
11965
12187
|
// src/commands/gsc/query.ts
|
|
11966
12188
|
import { appendFileSync as appendFileSync3, existsSync as existsSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
11967
12189
|
import { resolve as resolve3 } from "path";
|
|
11968
|
-
import { defineCommand as
|
|
12190
|
+
import { defineCommand as defineCommand90 } from "citty";
|
|
11969
12191
|
|
|
11970
12192
|
// src/commands/gsc/presets.ts
|
|
11971
12193
|
var GSC_PRESETS = [
|
|
@@ -12153,7 +12375,7 @@ function handleError2(err) {
|
|
|
12153
12375
|
});
|
|
12154
12376
|
process.exit(1);
|
|
12155
12377
|
}
|
|
12156
|
-
var queryCommand3 =
|
|
12378
|
+
var queryCommand3 = defineCommand90({
|
|
12157
12379
|
meta: {
|
|
12158
12380
|
name: "query",
|
|
12159
12381
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -12231,7 +12453,7 @@ Free-form (escape hatch):
|
|
|
12231
12453
|
});
|
|
12232
12454
|
|
|
12233
12455
|
// src/commands/gsc/sitemaps.ts
|
|
12234
|
-
import { defineCommand as
|
|
12456
|
+
import { defineCommand as defineCommand91 } from "citty";
|
|
12235
12457
|
registerSchema({
|
|
12236
12458
|
command: "gsc.sitemaps",
|
|
12237
12459
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -12240,7 +12462,7 @@ registerSchema({
|
|
|
12240
12462
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12241
12463
|
}
|
|
12242
12464
|
});
|
|
12243
|
-
var sitemapsCommand =
|
|
12465
|
+
var sitemapsCommand = defineCommand91({
|
|
12244
12466
|
meta: {
|
|
12245
12467
|
name: "sitemaps",
|
|
12246
12468
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -12290,7 +12512,7 @@ Examples:
|
|
|
12290
12512
|
});
|
|
12291
12513
|
|
|
12292
12514
|
// src/commands/gsc/sites.ts
|
|
12293
|
-
import { defineCommand as
|
|
12515
|
+
import { defineCommand as defineCommand92 } from "citty";
|
|
12294
12516
|
registerSchema({
|
|
12295
12517
|
command: "gsc.sites",
|
|
12296
12518
|
description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
|
|
@@ -12298,7 +12520,7 @@ registerSchema({
|
|
|
12298
12520
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12299
12521
|
}
|
|
12300
12522
|
});
|
|
12301
|
-
var sitesCommand =
|
|
12523
|
+
var sitesCommand = defineCommand92({
|
|
12302
12524
|
meta: {
|
|
12303
12525
|
name: "sites",
|
|
12304
12526
|
description: `List verified Search Console sites.
|
|
@@ -12346,7 +12568,7 @@ Examples:
|
|
|
12346
12568
|
});
|
|
12347
12569
|
|
|
12348
12570
|
// src/commands/gsc/index.ts
|
|
12349
|
-
var gscCommand =
|
|
12571
|
+
var gscCommand = defineCommand93({
|
|
12350
12572
|
meta: {
|
|
12351
12573
|
name: "gsc",
|
|
12352
12574
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -12369,10 +12591,10 @@ Examples:
|
|
|
12369
12591
|
});
|
|
12370
12592
|
|
|
12371
12593
|
// src/commands/images/index.ts
|
|
12372
|
-
import { defineCommand as
|
|
12594
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
12373
12595
|
|
|
12374
12596
|
// src/commands/images/crop.ts
|
|
12375
|
-
import { defineCommand as
|
|
12597
|
+
import { defineCommand as defineCommand94 } from "citty";
|
|
12376
12598
|
|
|
12377
12599
|
// src/lib/image/crop-sprite.ts
|
|
12378
12600
|
import sharp from "sharp";
|
|
@@ -12387,7 +12609,7 @@ function cropSprite(input, region) {
|
|
|
12387
12609
|
|
|
12388
12610
|
// src/lib/image/io.ts
|
|
12389
12611
|
import { randomBytes } from "crypto";
|
|
12390
|
-
import { glob as fsGlob, readFile as
|
|
12612
|
+
import { glob as fsGlob, readFile as readFile8, rename, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
12391
12613
|
import { dirname, extname, join as join3, resolve as resolve4 } from "path";
|
|
12392
12614
|
var REMOTE_RE = /^https?:\/\//i;
|
|
12393
12615
|
var GLOB_RE = /[*?[\]{}]/;
|
|
@@ -12423,11 +12645,11 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
12423
12645
|
}
|
|
12424
12646
|
return Buffer.from(await response.arrayBuffer());
|
|
12425
12647
|
}
|
|
12426
|
-
return
|
|
12648
|
+
return readFile8(pathOrUrl);
|
|
12427
12649
|
}
|
|
12428
|
-
async function isDirectory(
|
|
12650
|
+
async function isDirectory(path8) {
|
|
12429
12651
|
try {
|
|
12430
|
-
const s = await stat2(
|
|
12652
|
+
const s = await stat2(path8);
|
|
12431
12653
|
return s.isDirectory();
|
|
12432
12654
|
} catch {
|
|
12433
12655
|
return false;
|
|
@@ -12497,7 +12719,7 @@ function emitError2(err) {
|
|
|
12497
12719
|
}
|
|
12498
12720
|
process.exit(1);
|
|
12499
12721
|
}
|
|
12500
|
-
var cropCommand =
|
|
12722
|
+
var cropCommand = defineCommand94({
|
|
12501
12723
|
meta: {
|
|
12502
12724
|
name: "crop",
|
|
12503
12725
|
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"
|
|
@@ -12533,7 +12755,7 @@ var cropCommand = defineCommand93({
|
|
|
12533
12755
|
});
|
|
12534
12756
|
|
|
12535
12757
|
// src/commands/images/delete.ts
|
|
12536
|
-
import { defineCommand as
|
|
12758
|
+
import { defineCommand as defineCommand95 } from "citty";
|
|
12537
12759
|
registerSchema({
|
|
12538
12760
|
command: "images.delete",
|
|
12539
12761
|
description: "Delete an image by ID",
|
|
@@ -12547,7 +12769,7 @@ registerSchema({
|
|
|
12547
12769
|
}
|
|
12548
12770
|
}
|
|
12549
12771
|
});
|
|
12550
|
-
var deleteCommand =
|
|
12772
|
+
var deleteCommand = defineCommand95({
|
|
12551
12773
|
meta: {
|
|
12552
12774
|
name: "delete",
|
|
12553
12775
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -12588,7 +12810,7 @@ var deleteCommand = defineCommand94({
|
|
|
12588
12810
|
});
|
|
12589
12811
|
|
|
12590
12812
|
// src/commands/images/dimensions.ts
|
|
12591
|
-
import { defineCommand as
|
|
12813
|
+
import { defineCommand as defineCommand96 } from "citty";
|
|
12592
12814
|
|
|
12593
12815
|
// src/lib/image/dimensions.ts
|
|
12594
12816
|
import { imageSize } from "image-size";
|
|
@@ -12611,7 +12833,7 @@ registerSchema({
|
|
|
12611
12833
|
target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
|
|
12612
12834
|
}
|
|
12613
12835
|
});
|
|
12614
|
-
var dimensionsCommand =
|
|
12836
|
+
var dimensionsCommand = defineCommand96({
|
|
12615
12837
|
meta: {
|
|
12616
12838
|
name: "dimensions",
|
|
12617
12839
|
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"
|
|
@@ -12655,7 +12877,7 @@ var dimensionsCommand = defineCommand95({
|
|
|
12655
12877
|
});
|
|
12656
12878
|
|
|
12657
12879
|
// src/commands/images/extract.ts
|
|
12658
|
-
import { defineCommand as
|
|
12880
|
+
import { defineCommand as defineCommand97 } from "citty";
|
|
12659
12881
|
registerSchema({
|
|
12660
12882
|
command: "images.extract",
|
|
12661
12883
|
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
@@ -12671,7 +12893,7 @@ registerSchema({
|
|
|
12671
12893
|
}
|
|
12672
12894
|
}
|
|
12673
12895
|
});
|
|
12674
|
-
var extractCommand =
|
|
12896
|
+
var extractCommand = defineCommand97({
|
|
12675
12897
|
meta: {
|
|
12676
12898
|
name: "extract",
|
|
12677
12899
|
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"
|
|
@@ -12709,7 +12931,7 @@ var extractCommand = defineCommand96({
|
|
|
12709
12931
|
});
|
|
12710
12932
|
|
|
12711
12933
|
// src/commands/images/find.ts
|
|
12712
|
-
import { defineCommand as
|
|
12934
|
+
import { defineCommand as defineCommand98 } from "citty";
|
|
12713
12935
|
registerSchema({
|
|
12714
12936
|
command: "images.find",
|
|
12715
12937
|
description: "Fanout image search: library first, then opted-in external providers.",
|
|
@@ -12741,7 +12963,7 @@ registerSchema({
|
|
|
12741
12963
|
}
|
|
12742
12964
|
}
|
|
12743
12965
|
});
|
|
12744
|
-
var findCommand =
|
|
12966
|
+
var findCommand = defineCommand98({
|
|
12745
12967
|
meta: {
|
|
12746
12968
|
name: "find",
|
|
12747
12969
|
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"
|
|
@@ -12787,8 +13009,8 @@ var findCommand = defineCommand97({
|
|
|
12787
13009
|
});
|
|
12788
13010
|
|
|
12789
13011
|
// src/commands/images/generate.ts
|
|
12790
|
-
import { readFile as
|
|
12791
|
-
import { defineCommand as
|
|
13012
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
13013
|
+
import { defineCommand as defineCommand99 } from "citty";
|
|
12792
13014
|
import sharp2 from "sharp";
|
|
12793
13015
|
var GENERATE_TIMEOUT_MS = 18e4;
|
|
12794
13016
|
var REFERENCE_MAX_EDGE = 1536;
|
|
@@ -12870,7 +13092,7 @@ async function resolveReferences(spec) {
|
|
|
12870
13092
|
}
|
|
12871
13093
|
let raw;
|
|
12872
13094
|
try {
|
|
12873
|
-
raw = await
|
|
13095
|
+
raw = await readFile9(entry);
|
|
12874
13096
|
} catch {
|
|
12875
13097
|
throw new ApiError("VALIDATION_ERROR", `Reference file not found: ${entry}`);
|
|
12876
13098
|
}
|
|
@@ -12884,7 +13106,7 @@ async function resolveReferences(spec) {
|
|
|
12884
13106
|
}
|
|
12885
13107
|
return out;
|
|
12886
13108
|
}
|
|
12887
|
-
var generateCommand =
|
|
13109
|
+
var generateCommand = defineCommand99({
|
|
12888
13110
|
meta: {
|
|
12889
13111
|
name: "generate",
|
|
12890
13112
|
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]]'"
|
|
@@ -12936,7 +13158,7 @@ var generateCommand = defineCommand98({
|
|
|
12936
13158
|
});
|
|
12937
13159
|
|
|
12938
13160
|
// src/commands/images/get.ts
|
|
12939
|
-
import { defineCommand as
|
|
13161
|
+
import { defineCommand as defineCommand100 } from "citty";
|
|
12940
13162
|
registerSchema({
|
|
12941
13163
|
command: "images.get",
|
|
12942
13164
|
description: "Get a single image by ID",
|
|
@@ -12944,7 +13166,7 @@ registerSchema({
|
|
|
12944
13166
|
id: { type: "string", description: "Image ID", required: true }
|
|
12945
13167
|
}
|
|
12946
13168
|
});
|
|
12947
|
-
var getCommand2 =
|
|
13169
|
+
var getCommand2 = defineCommand100({
|
|
12948
13170
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
12949
13171
|
args: {
|
|
12950
13172
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -12980,7 +13202,7 @@ var getCommand2 = defineCommand99({
|
|
|
12980
13202
|
});
|
|
12981
13203
|
|
|
12982
13204
|
// src/commands/images/gif.ts
|
|
12983
|
-
import { defineCommand as
|
|
13205
|
+
import { defineCommand as defineCommand101 } from "citty";
|
|
12984
13206
|
registerSchema({
|
|
12985
13207
|
command: "images.gif",
|
|
12986
13208
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -13012,7 +13234,7 @@ registerSchema({
|
|
|
13012
13234
|
}
|
|
13013
13235
|
}
|
|
13014
13236
|
});
|
|
13015
|
-
var gifCommand =
|
|
13237
|
+
var gifCommand = defineCommand101({
|
|
13016
13238
|
meta: {
|
|
13017
13239
|
name: "gif",
|
|
13018
13240
|
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"
|
|
@@ -13059,7 +13281,7 @@ var gifCommand = defineCommand100({
|
|
|
13059
13281
|
});
|
|
13060
13282
|
|
|
13061
13283
|
// src/commands/images/google.ts
|
|
13062
|
-
import { defineCommand as
|
|
13284
|
+
import { defineCommand as defineCommand102 } from "citty";
|
|
13063
13285
|
registerSchema({
|
|
13064
13286
|
command: "images.google",
|
|
13065
13287
|
description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
|
|
@@ -13095,7 +13317,7 @@ registerSchema({
|
|
|
13095
13317
|
}
|
|
13096
13318
|
}
|
|
13097
13319
|
});
|
|
13098
|
-
var googleCommand2 =
|
|
13320
|
+
var googleCommand2 = defineCommand102({
|
|
13099
13321
|
meta: {
|
|
13100
13322
|
name: "google",
|
|
13101
13323
|
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"
|
|
@@ -13143,7 +13365,7 @@ var googleCommand2 = defineCommand101({
|
|
|
13143
13365
|
});
|
|
13144
13366
|
|
|
13145
13367
|
// src/commands/images/icon.ts
|
|
13146
|
-
import { defineCommand as
|
|
13368
|
+
import { defineCommand as defineCommand103 } from "citty";
|
|
13147
13369
|
registerSchema({
|
|
13148
13370
|
command: "images.icon",
|
|
13149
13371
|
description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
|
|
@@ -13169,7 +13391,7 @@ registerSchema({
|
|
|
13169
13391
|
}
|
|
13170
13392
|
}
|
|
13171
13393
|
});
|
|
13172
|
-
var iconCommand =
|
|
13394
|
+
var iconCommand = defineCommand103({
|
|
13173
13395
|
meta: {
|
|
13174
13396
|
name: "icon",
|
|
13175
13397
|
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'"
|
|
@@ -13209,7 +13431,7 @@ var iconCommand = defineCommand102({
|
|
|
13209
13431
|
});
|
|
13210
13432
|
|
|
13211
13433
|
// src/commands/images/ingest.ts
|
|
13212
|
-
import { defineCommand as
|
|
13434
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
13213
13435
|
registerSchema({
|
|
13214
13436
|
command: "images.ingest",
|
|
13215
13437
|
description: "Ingest a remote image URL into the library (full describe + embed).",
|
|
@@ -13221,7 +13443,7 @@ registerSchema({
|
|
|
13221
13443
|
context: { type: "string", description: "Description context hint", required: false }
|
|
13222
13444
|
}
|
|
13223
13445
|
});
|
|
13224
|
-
var ingestCommand =
|
|
13446
|
+
var ingestCommand = defineCommand104({
|
|
13225
13447
|
meta: {
|
|
13226
13448
|
name: "ingest",
|
|
13227
13449
|
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"
|
|
@@ -13263,7 +13485,7 @@ var ingestCommand = defineCommand103({
|
|
|
13263
13485
|
});
|
|
13264
13486
|
|
|
13265
13487
|
// src/commands/images/library.ts
|
|
13266
|
-
import { defineCommand as
|
|
13488
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
13267
13489
|
registerSchema({
|
|
13268
13490
|
command: "images.library",
|
|
13269
13491
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -13289,7 +13511,7 @@ registerSchema({
|
|
|
13289
13511
|
}
|
|
13290
13512
|
}
|
|
13291
13513
|
});
|
|
13292
|
-
var libraryCommand =
|
|
13514
|
+
var libraryCommand = defineCommand105({
|
|
13293
13515
|
meta: {
|
|
13294
13516
|
name: "library",
|
|
13295
13517
|
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"
|
|
@@ -13346,7 +13568,7 @@ var libraryCommand = defineCommand104({
|
|
|
13346
13568
|
});
|
|
13347
13569
|
|
|
13348
13570
|
// src/commands/images/logo.ts
|
|
13349
|
-
import { defineCommand as
|
|
13571
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
13350
13572
|
registerSchema({
|
|
13351
13573
|
command: "images.logo",
|
|
13352
13574
|
description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
|
|
@@ -13371,7 +13593,7 @@ registerSchema({
|
|
|
13371
13593
|
}
|
|
13372
13594
|
}
|
|
13373
13595
|
});
|
|
13374
|
-
var logoCommand =
|
|
13596
|
+
var logoCommand = defineCommand106({
|
|
13375
13597
|
meta: {
|
|
13376
13598
|
name: "logo",
|
|
13377
13599
|
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"
|
|
@@ -13409,7 +13631,7 @@ var logoCommand = defineCommand105({
|
|
|
13409
13631
|
});
|
|
13410
13632
|
|
|
13411
13633
|
// src/commands/images/normalize.ts
|
|
13412
|
-
import { defineCommand as
|
|
13634
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
13413
13635
|
|
|
13414
13636
|
// src/lib/image/color-changer.ts
|
|
13415
13637
|
import quantize from "quantize";
|
|
@@ -14141,7 +14363,7 @@ function coerceRawArgs(args) {
|
|
|
14141
14363
|
"dry-run": bool(args["dry-run"])
|
|
14142
14364
|
};
|
|
14143
14365
|
}
|
|
14144
|
-
var normalizeCommand =
|
|
14366
|
+
var normalizeCommand = defineCommand107({
|
|
14145
14367
|
meta: {
|
|
14146
14368
|
name: "normalize",
|
|
14147
14369
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -14196,7 +14418,7 @@ Examples:
|
|
|
14196
14418
|
});
|
|
14197
14419
|
|
|
14198
14420
|
// src/commands/images/pinterest.ts
|
|
14199
|
-
import { defineCommand as
|
|
14421
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
14200
14422
|
registerSchema({
|
|
14201
14423
|
command: "images.pinterest",
|
|
14202
14424
|
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.",
|
|
@@ -14216,7 +14438,7 @@ registerSchema({
|
|
|
14216
14438
|
}
|
|
14217
14439
|
}
|
|
14218
14440
|
});
|
|
14219
|
-
var pinterestCommand =
|
|
14441
|
+
var pinterestCommand = defineCommand108({
|
|
14220
14442
|
meta: {
|
|
14221
14443
|
name: "pinterest",
|
|
14222
14444
|
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'"
|
|
@@ -14256,7 +14478,7 @@ var pinterestCommand = defineCommand107({
|
|
|
14256
14478
|
});
|
|
14257
14479
|
|
|
14258
14480
|
// src/commands/images/screenshot.ts
|
|
14259
|
-
import { defineCommand as
|
|
14481
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
14260
14482
|
registerSchema({
|
|
14261
14483
|
command: "images.screenshot",
|
|
14262
14484
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -14272,7 +14494,7 @@ registerSchema({
|
|
|
14272
14494
|
}
|
|
14273
14495
|
}
|
|
14274
14496
|
});
|
|
14275
|
-
var screenshotCommand =
|
|
14497
|
+
var screenshotCommand = defineCommand109({
|
|
14276
14498
|
meta: {
|
|
14277
14499
|
name: "screenshot",
|
|
14278
14500
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -14322,7 +14544,7 @@ var screenshotCommand = defineCommand108({
|
|
|
14322
14544
|
});
|
|
14323
14545
|
|
|
14324
14546
|
// src/commands/images/search.ts
|
|
14325
|
-
import { defineCommand as
|
|
14547
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
14326
14548
|
registerSchema({
|
|
14327
14549
|
command: "images.search",
|
|
14328
14550
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -14338,7 +14560,7 @@ registerSchema({
|
|
|
14338
14560
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
14339
14561
|
}
|
|
14340
14562
|
});
|
|
14341
|
-
var searchCommand =
|
|
14563
|
+
var searchCommand = defineCommand110({
|
|
14342
14564
|
meta: {
|
|
14343
14565
|
name: "search",
|
|
14344
14566
|
description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
|
|
@@ -14398,7 +14620,7 @@ var searchCommand = defineCommand109({
|
|
|
14398
14620
|
});
|
|
14399
14621
|
|
|
14400
14622
|
// src/commands/images/sticker.ts
|
|
14401
|
-
import { defineCommand as
|
|
14623
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
14402
14624
|
registerSchema({
|
|
14403
14625
|
command: "images.sticker",
|
|
14404
14626
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -14430,7 +14652,7 @@ registerSchema({
|
|
|
14430
14652
|
}
|
|
14431
14653
|
}
|
|
14432
14654
|
});
|
|
14433
|
-
var stickerCommand =
|
|
14655
|
+
var stickerCommand = defineCommand111({
|
|
14434
14656
|
meta: {
|
|
14435
14657
|
name: "sticker",
|
|
14436
14658
|
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"
|
|
@@ -14477,7 +14699,7 @@ var stickerCommand = defineCommand110({
|
|
|
14477
14699
|
});
|
|
14478
14700
|
|
|
14479
14701
|
// src/commands/images/stock.ts
|
|
14480
|
-
import { defineCommand as
|
|
14702
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
14481
14703
|
registerSchema({
|
|
14482
14704
|
command: "images.stock",
|
|
14483
14705
|
description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
|
|
@@ -14535,7 +14757,7 @@ registerSchema({
|
|
|
14535
14757
|
}
|
|
14536
14758
|
}
|
|
14537
14759
|
});
|
|
14538
|
-
var stockCommand =
|
|
14760
|
+
var stockCommand = defineCommand112({
|
|
14539
14761
|
meta: {
|
|
14540
14762
|
name: "stock",
|
|
14541
14763
|
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"
|
|
@@ -14591,7 +14813,7 @@ var stockCommand = defineCommand111({
|
|
|
14591
14813
|
});
|
|
14592
14814
|
|
|
14593
14815
|
// src/lib/tags-command.ts
|
|
14594
|
-
import { defineCommand as
|
|
14816
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
14595
14817
|
function makeTagsCommand(command, label, endpoint) {
|
|
14596
14818
|
registerSchema({
|
|
14597
14819
|
command: `${command}.tags`,
|
|
@@ -14600,7 +14822,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
14600
14822
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
14601
14823
|
}
|
|
14602
14824
|
});
|
|
14603
|
-
return
|
|
14825
|
+
return defineCommand113({
|
|
14604
14826
|
meta: {
|
|
14605
14827
|
name: "tags",
|
|
14606
14828
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -14636,9 +14858,9 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
14636
14858
|
var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
14637
14859
|
|
|
14638
14860
|
// src/commands/images/upload.ts
|
|
14639
|
-
import { readFile as
|
|
14861
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
14640
14862
|
import { extname as extname2 } from "path";
|
|
14641
|
-
import { defineCommand as
|
|
14863
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
14642
14864
|
var MIME_MAP = {
|
|
14643
14865
|
".png": "image/png",
|
|
14644
14866
|
".jpg": "image/jpeg",
|
|
@@ -14693,7 +14915,7 @@ function detectContentType(filePath) {
|
|
|
14693
14915
|
}
|
|
14694
14916
|
return mime;
|
|
14695
14917
|
}
|
|
14696
|
-
var uploadCommand =
|
|
14918
|
+
var uploadCommand = defineCommand114({
|
|
14697
14919
|
meta: {
|
|
14698
14920
|
name: "upload",
|
|
14699
14921
|
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'"
|
|
@@ -14776,7 +14998,7 @@ async function uploadLocal(target, args) {
|
|
|
14776
14998
|
});
|
|
14777
14999
|
return;
|
|
14778
15000
|
}
|
|
14779
|
-
const fileBuffer = await
|
|
15001
|
+
const fileBuffer = await readFile10(target);
|
|
14780
15002
|
const base64 = fileBuffer.toString("base64");
|
|
14781
15003
|
const body = { base64, contentType };
|
|
14782
15004
|
if (args.source) body.source = args.source;
|
|
@@ -14786,7 +15008,7 @@ async function uploadLocal(target, args) {
|
|
|
14786
15008
|
}
|
|
14787
15009
|
|
|
14788
15010
|
// src/commands/images/upscale.ts
|
|
14789
|
-
import { defineCommand as
|
|
15011
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
14790
15012
|
registerSchema({
|
|
14791
15013
|
command: "images.upscale",
|
|
14792
15014
|
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).",
|
|
@@ -14801,7 +15023,7 @@ registerSchema({
|
|
|
14801
15023
|
}
|
|
14802
15024
|
});
|
|
14803
15025
|
var POLL_INTERVAL_MS3 = 1500;
|
|
14804
|
-
var upscaleCommand =
|
|
15026
|
+
var upscaleCommand = defineCommand115({
|
|
14805
15027
|
meta: {
|
|
14806
15028
|
name: "upscale",
|
|
14807
15029
|
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"
|
|
@@ -14856,7 +15078,7 @@ var upscaleCommand = defineCommand114({
|
|
|
14856
15078
|
});
|
|
14857
15079
|
|
|
14858
15080
|
// src/commands/images/use.ts
|
|
14859
|
-
import { defineCommand as
|
|
15081
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
14860
15082
|
registerSchema({
|
|
14861
15083
|
command: "images.use",
|
|
14862
15084
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -14872,7 +15094,7 @@ registerSchema({
|
|
|
14872
15094
|
}
|
|
14873
15095
|
});
|
|
14874
15096
|
var POLL_INTERVAL_MS4 = 1500;
|
|
14875
|
-
var useCommand =
|
|
15097
|
+
var useCommand = defineCommand116({
|
|
14876
15098
|
meta: {
|
|
14877
15099
|
name: "use",
|
|
14878
15100
|
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"
|
|
@@ -14918,7 +15140,7 @@ var useCommand = defineCommand115({
|
|
|
14918
15140
|
});
|
|
14919
15141
|
|
|
14920
15142
|
// src/commands/images/index.ts
|
|
14921
|
-
var imagesCommand =
|
|
15143
|
+
var imagesCommand = defineCommand117({
|
|
14922
15144
|
meta: {
|
|
14923
15145
|
name: "images",
|
|
14924
15146
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -14988,10 +15210,10 @@ Paid transforms (run on the Convex backend, cost-tracked):
|
|
|
14988
15210
|
});
|
|
14989
15211
|
|
|
14990
15212
|
// src/commands/research/index.ts
|
|
14991
|
-
import { defineCommand as
|
|
15213
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
14992
15214
|
|
|
14993
15215
|
// src/commands/research/advertisers.ts
|
|
14994
|
-
import { defineCommand as
|
|
15216
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
14995
15217
|
|
|
14996
15218
|
// src/commands/research/output.ts
|
|
14997
15219
|
var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
|
|
@@ -15104,7 +15326,7 @@ var FIELDS3 = {
|
|
|
15104
15326
|
etv: "Estimated traffic value (USD)",
|
|
15105
15327
|
visibility: "SERP visibility score (0-1)"
|
|
15106
15328
|
};
|
|
15107
|
-
var advertisersCommand =
|
|
15329
|
+
var advertisersCommand = defineCommand118({
|
|
15108
15330
|
meta: {
|
|
15109
15331
|
name: "advertisers",
|
|
15110
15332
|
description: `Find domains competing for a keyword in Google SERPs.
|
|
@@ -15151,7 +15373,7 @@ Examples:
|
|
|
15151
15373
|
});
|
|
15152
15374
|
|
|
15153
15375
|
// src/commands/research/autocomplete.ts
|
|
15154
|
-
import { defineCommand as
|
|
15376
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
15155
15377
|
registerSchema({
|
|
15156
15378
|
command: "research.autocomplete",
|
|
15157
15379
|
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).",
|
|
@@ -15174,7 +15396,7 @@ registerSchema({
|
|
|
15174
15396
|
var FIELDS4 = {
|
|
15175
15397
|
suggestion: "Autocomplete suggestion from Google"
|
|
15176
15398
|
};
|
|
15177
|
-
var autocompleteCommand =
|
|
15399
|
+
var autocompleteCommand = defineCommand119({
|
|
15178
15400
|
meta: {
|
|
15179
15401
|
name: "autocomplete",
|
|
15180
15402
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -15220,7 +15442,7 @@ Examples:
|
|
|
15220
15442
|
});
|
|
15221
15443
|
|
|
15222
15444
|
// src/commands/research/countries.ts
|
|
15223
|
-
import { defineCommand as
|
|
15445
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
15224
15446
|
registerSchema({
|
|
15225
15447
|
command: "research.countries",
|
|
15226
15448
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -15277,7 +15499,7 @@ var FIELDS5 = {
|
|
|
15277
15499
|
code: "Country code to pass as --location",
|
|
15278
15500
|
name: "Country name"
|
|
15279
15501
|
};
|
|
15280
|
-
var countriesCommand =
|
|
15502
|
+
var countriesCommand = defineCommand120({
|
|
15281
15503
|
meta: {
|
|
15282
15504
|
name: "countries",
|
|
15283
15505
|
description: "List all supported country codes for --location flag."
|
|
@@ -15288,7 +15510,7 @@ var countriesCommand = defineCommand119({
|
|
|
15288
15510
|
});
|
|
15289
15511
|
|
|
15290
15512
|
// src/commands/research/intent.ts
|
|
15291
|
-
import { defineCommand as
|
|
15513
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
15292
15514
|
registerSchema({
|
|
15293
15515
|
command: "research.intent",
|
|
15294
15516
|
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.",
|
|
@@ -15311,7 +15533,7 @@ var FIELDS6 = {
|
|
|
15311
15533
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
15312
15534
|
probability: "Confidence score 0.0-1.0"
|
|
15313
15535
|
};
|
|
15314
|
-
var intentCommand =
|
|
15536
|
+
var intentCommand = defineCommand121({
|
|
15315
15537
|
meta: {
|
|
15316
15538
|
name: "intent",
|
|
15317
15539
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -15359,7 +15581,7 @@ Examples:
|
|
|
15359
15581
|
});
|
|
15360
15582
|
|
|
15361
15583
|
// src/commands/research/keyword-gap.ts
|
|
15362
|
-
import { defineCommand as
|
|
15584
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
15363
15585
|
registerSchema({
|
|
15364
15586
|
command: "research.keyword-gap",
|
|
15365
15587
|
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.",
|
|
@@ -15388,7 +15610,7 @@ var FIELDS7 = {
|
|
|
15388
15610
|
cpc: "Cost per click USD",
|
|
15389
15611
|
their_position: "Competitor's ranking position"
|
|
15390
15612
|
};
|
|
15391
|
-
var keywordGapCommand =
|
|
15613
|
+
var keywordGapCommand = defineCommand122({
|
|
15392
15614
|
meta: {
|
|
15393
15615
|
name: "keyword-gap",
|
|
15394
15616
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -15462,7 +15684,7 @@ Examples:
|
|
|
15462
15684
|
});
|
|
15463
15685
|
|
|
15464
15686
|
// src/commands/research/keywords-for-site.ts
|
|
15465
|
-
import { defineCommand as
|
|
15687
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
15466
15688
|
registerSchema({
|
|
15467
15689
|
command: "research.keywords-for-site",
|
|
15468
15690
|
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.",
|
|
@@ -15495,7 +15717,7 @@ var FIELDS8 = {
|
|
|
15495
15717
|
competition: "LOW, MEDIUM, or HIGH",
|
|
15496
15718
|
competition_index: "Competition score 0-100"
|
|
15497
15719
|
};
|
|
15498
|
-
var keywordsForSiteCommand =
|
|
15720
|
+
var keywordsForSiteCommand = defineCommand123({
|
|
15499
15721
|
meta: {
|
|
15500
15722
|
name: "keywords-for-site",
|
|
15501
15723
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -15548,7 +15770,7 @@ Examples:
|
|
|
15548
15770
|
});
|
|
15549
15771
|
|
|
15550
15772
|
// src/commands/research/languages.ts
|
|
15551
|
-
import { defineCommand as
|
|
15773
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
15552
15774
|
registerSchema({
|
|
15553
15775
|
command: "research.languages",
|
|
15554
15776
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -15578,7 +15800,7 @@ var FIELDS9 = {
|
|
|
15578
15800
|
code: "Language code to pass as --language",
|
|
15579
15801
|
name: "Language name (also accepted by --language)"
|
|
15580
15802
|
};
|
|
15581
|
-
var languagesCommand2 =
|
|
15803
|
+
var languagesCommand2 = defineCommand124({
|
|
15582
15804
|
meta: {
|
|
15583
15805
|
name: "languages",
|
|
15584
15806
|
description: "List all supported language codes for --language flag."
|
|
@@ -15589,7 +15811,7 @@ var languagesCommand2 = defineCommand123({
|
|
|
15589
15811
|
});
|
|
15590
15812
|
|
|
15591
15813
|
// src/commands/research/lighthouse.ts
|
|
15592
|
-
import { defineCommand as
|
|
15814
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
15593
15815
|
registerSchema({
|
|
15594
15816
|
command: "research.lighthouse",
|
|
15595
15817
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -15608,7 +15830,7 @@ var FIELDS10 = {
|
|
|
15608
15830
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
15609
15831
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
15610
15832
|
};
|
|
15611
|
-
var lighthouseCommand =
|
|
15833
|
+
var lighthouseCommand = defineCommand125({
|
|
15612
15834
|
meta: {
|
|
15613
15835
|
name: "lighthouse",
|
|
15614
15836
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -15646,7 +15868,7 @@ Examples:
|
|
|
15646
15868
|
});
|
|
15647
15869
|
|
|
15648
15870
|
// src/commands/research/relevant-pages.ts
|
|
15649
|
-
import { defineCommand as
|
|
15871
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
15650
15872
|
registerSchema({
|
|
15651
15873
|
command: "research.relevant-pages",
|
|
15652
15874
|
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).",
|
|
@@ -15672,7 +15894,7 @@ var FIELDS11 = {
|
|
|
15672
15894
|
keywords: "Total organic keywords the page ranks for",
|
|
15673
15895
|
top_10: "Keywords in positions 1-10"
|
|
15674
15896
|
};
|
|
15675
|
-
var relevantPagesCommand =
|
|
15897
|
+
var relevantPagesCommand = defineCommand126({
|
|
15676
15898
|
meta: {
|
|
15677
15899
|
name: "relevant-pages",
|
|
15678
15900
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -15718,7 +15940,7 @@ Examples:
|
|
|
15718
15940
|
});
|
|
15719
15941
|
|
|
15720
15942
|
// src/commands/research/web.ts
|
|
15721
|
-
import { defineCommand as
|
|
15943
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
15722
15944
|
registerSchema({
|
|
15723
15945
|
command: "research.web",
|
|
15724
15946
|
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).",
|
|
@@ -15769,7 +15991,7 @@ async function runDeepResearch(question) {
|
|
|
15769
15991
|
}
|
|
15770
15992
|
throw new Error("Deep research timed out");
|
|
15771
15993
|
}
|
|
15772
|
-
var webCommand =
|
|
15994
|
+
var webCommand = defineCommand127({
|
|
15773
15995
|
meta: {
|
|
15774
15996
|
name: "web",
|
|
15775
15997
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -15829,7 +16051,7 @@ Examples:
|
|
|
15829
16051
|
});
|
|
15830
16052
|
|
|
15831
16053
|
// src/commands/research/index.ts
|
|
15832
|
-
var researchCommand =
|
|
16054
|
+
var researchCommand = defineCommand128({
|
|
15833
16055
|
meta: {
|
|
15834
16056
|
name: "research",
|
|
15835
16057
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -15869,10 +16091,10 @@ Examples:
|
|
|
15869
16091
|
});
|
|
15870
16092
|
|
|
15871
16093
|
// src/commands/scheduled-actions/index.ts
|
|
15872
|
-
import { defineCommand as
|
|
16094
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
15873
16095
|
|
|
15874
16096
|
// src/commands/scheduled-actions/create.ts
|
|
15875
|
-
import { defineCommand as
|
|
16097
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
15876
16098
|
|
|
15877
16099
|
// src/commands/scheduled-actions/shared.ts
|
|
15878
16100
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -15977,7 +16199,7 @@ registerSchema({
|
|
|
15977
16199
|
prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
|
|
15978
16200
|
}
|
|
15979
16201
|
});
|
|
15980
|
-
var createCommand2 =
|
|
16202
|
+
var createCommand2 = defineCommand129({
|
|
15981
16203
|
meta: {
|
|
15982
16204
|
name: "create",
|
|
15983
16205
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -16025,7 +16247,7 @@ var createCommand2 = defineCommand128({
|
|
|
16025
16247
|
});
|
|
16026
16248
|
|
|
16027
16249
|
// src/commands/scheduled-actions/delete.ts
|
|
16028
|
-
import { defineCommand as
|
|
16250
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
16029
16251
|
registerSchema({
|
|
16030
16252
|
command: "scheduled-actions.delete",
|
|
16031
16253
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -16033,7 +16255,7 @@ registerSchema({
|
|
|
16033
16255
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
16034
16256
|
}
|
|
16035
16257
|
});
|
|
16036
|
-
var deleteCommand2 =
|
|
16258
|
+
var deleteCommand2 = defineCommand130({
|
|
16037
16259
|
meta: {
|
|
16038
16260
|
name: "delete",
|
|
16039
16261
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -16062,7 +16284,7 @@ var deleteCommand2 = defineCommand129({
|
|
|
16062
16284
|
});
|
|
16063
16285
|
|
|
16064
16286
|
// src/commands/scheduled-actions/get.ts
|
|
16065
|
-
import { defineCommand as
|
|
16287
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
16066
16288
|
registerSchema({
|
|
16067
16289
|
command: "scheduled-actions.get",
|
|
16068
16290
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -16070,7 +16292,7 @@ registerSchema({
|
|
|
16070
16292
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
16071
16293
|
}
|
|
16072
16294
|
});
|
|
16073
|
-
var getCommand3 =
|
|
16295
|
+
var getCommand3 = defineCommand131({
|
|
16074
16296
|
meta: {
|
|
16075
16297
|
name: "get",
|
|
16076
16298
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -16107,13 +16329,13 @@ var getCommand3 = defineCommand130({
|
|
|
16107
16329
|
});
|
|
16108
16330
|
|
|
16109
16331
|
// src/commands/scheduled-actions/list.ts
|
|
16110
|
-
import { defineCommand as
|
|
16332
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
16111
16333
|
registerSchema({
|
|
16112
16334
|
command: "scheduled-actions.list",
|
|
16113
16335
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
|
|
16114
16336
|
args: {}
|
|
16115
16337
|
});
|
|
16116
|
-
var listCommand3 =
|
|
16338
|
+
var listCommand3 = defineCommand132({
|
|
16117
16339
|
meta: {
|
|
16118
16340
|
name: "list",
|
|
16119
16341
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
|
|
@@ -16134,7 +16356,7 @@ var listCommand3 = defineCommand131({
|
|
|
16134
16356
|
});
|
|
16135
16357
|
|
|
16136
16358
|
// src/commands/scheduled-actions/trigger.ts
|
|
16137
|
-
import { defineCommand as
|
|
16359
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
16138
16360
|
registerSchema({
|
|
16139
16361
|
command: "scheduled-actions.trigger",
|
|
16140
16362
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -16142,7 +16364,7 @@ registerSchema({
|
|
|
16142
16364
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
16143
16365
|
}
|
|
16144
16366
|
});
|
|
16145
|
-
var triggerCommand =
|
|
16367
|
+
var triggerCommand = defineCommand133({
|
|
16146
16368
|
meta: {
|
|
16147
16369
|
name: "trigger",
|
|
16148
16370
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -16179,7 +16401,7 @@ var triggerCommand = defineCommand132({
|
|
|
16179
16401
|
});
|
|
16180
16402
|
|
|
16181
16403
|
// src/commands/scheduled-actions/update.ts
|
|
16182
|
-
import { defineCommand as
|
|
16404
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
16183
16405
|
registerSchema({
|
|
16184
16406
|
command: "scheduled-actions.update",
|
|
16185
16407
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -16204,7 +16426,7 @@ registerSchema({
|
|
|
16204
16426
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
16205
16427
|
}
|
|
16206
16428
|
});
|
|
16207
|
-
var updateCommand2 =
|
|
16429
|
+
var updateCommand2 = defineCommand134({
|
|
16208
16430
|
meta: {
|
|
16209
16431
|
name: "update",
|
|
16210
16432
|
description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
|
|
@@ -16274,7 +16496,7 @@ var updateCommand2 = defineCommand133({
|
|
|
16274
16496
|
});
|
|
16275
16497
|
|
|
16276
16498
|
// src/commands/scheduled-actions/index.ts
|
|
16277
|
-
var scheduledActionsCommand =
|
|
16499
|
+
var scheduledActionsCommand = defineCommand135({
|
|
16278
16500
|
meta: {
|
|
16279
16501
|
name: "scheduled-actions",
|
|
16280
16502
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
|
|
@@ -16300,8 +16522,8 @@ Examples:
|
|
|
16300
16522
|
});
|
|
16301
16523
|
|
|
16302
16524
|
// src/commands/schema.ts
|
|
16303
|
-
import { defineCommand as
|
|
16304
|
-
var schemaCommand =
|
|
16525
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
16526
|
+
var schemaCommand = defineCommand136({
|
|
16305
16527
|
meta: {
|
|
16306
16528
|
name: "schema",
|
|
16307
16529
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -16337,10 +16559,10 @@ var schemaCommand = defineCommand135({
|
|
|
16337
16559
|
});
|
|
16338
16560
|
|
|
16339
16561
|
// src/commands/testimonials/index.ts
|
|
16340
|
-
import { defineCommand as
|
|
16562
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
16341
16563
|
|
|
16342
16564
|
// src/commands/testimonials/get.ts
|
|
16343
|
-
import { defineCommand as
|
|
16565
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
16344
16566
|
registerSchema({
|
|
16345
16567
|
command: "testimonials.get",
|
|
16346
16568
|
description: "Get a single testimonial by ID",
|
|
@@ -16348,7 +16570,7 @@ registerSchema({
|
|
|
16348
16570
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
16349
16571
|
}
|
|
16350
16572
|
});
|
|
16351
|
-
var getCommand4 =
|
|
16573
|
+
var getCommand4 = defineCommand137({
|
|
16352
16574
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
16353
16575
|
args: {
|
|
16354
16576
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -16385,7 +16607,7 @@ var getCommand4 = defineCommand136({
|
|
|
16385
16607
|
});
|
|
16386
16608
|
|
|
16387
16609
|
// src/commands/testimonials/list.ts
|
|
16388
|
-
import { defineCommand as
|
|
16610
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
16389
16611
|
registerSchema({
|
|
16390
16612
|
command: "testimonials.list",
|
|
16391
16613
|
description: "List testimonials with optional filters.",
|
|
@@ -16415,7 +16637,7 @@ registerSchema({
|
|
|
16415
16637
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
16416
16638
|
}
|
|
16417
16639
|
});
|
|
16418
|
-
var listCommand4 =
|
|
16640
|
+
var listCommand4 = defineCommand138({
|
|
16419
16641
|
meta: {
|
|
16420
16642
|
name: "list",
|
|
16421
16643
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -16464,7 +16686,7 @@ var listCommand4 = defineCommand137({
|
|
|
16464
16686
|
});
|
|
16465
16687
|
|
|
16466
16688
|
// src/commands/testimonials/search.ts
|
|
16467
|
-
import { defineCommand as
|
|
16689
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
16468
16690
|
registerSchema({
|
|
16469
16691
|
command: "testimonials.search",
|
|
16470
16692
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -16495,7 +16717,7 @@ registerSchema({
|
|
|
16495
16717
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
16496
16718
|
}
|
|
16497
16719
|
});
|
|
16498
|
-
var searchCommand2 =
|
|
16720
|
+
var searchCommand2 = defineCommand139({
|
|
16499
16721
|
meta: {
|
|
16500
16722
|
name: "search",
|
|
16501
16723
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -16569,7 +16791,7 @@ var searchCommand2 = defineCommand138({
|
|
|
16569
16791
|
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
16570
16792
|
|
|
16571
16793
|
// src/commands/testimonials/index.ts
|
|
16572
|
-
var testimonialsCommand =
|
|
16794
|
+
var testimonialsCommand = defineCommand140({
|
|
16573
16795
|
meta: {
|
|
16574
16796
|
name: "testimonials",
|
|
16575
16797
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -16590,10 +16812,10 @@ Examples:
|
|
|
16590
16812
|
});
|
|
16591
16813
|
|
|
16592
16814
|
// src/commands/videos/index.ts
|
|
16593
|
-
import { defineCommand as
|
|
16815
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
16594
16816
|
|
|
16595
16817
|
// src/commands/videos/delete.ts
|
|
16596
|
-
import { defineCommand as
|
|
16818
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
16597
16819
|
registerSchema({
|
|
16598
16820
|
command: "videos.delete",
|
|
16599
16821
|
description: "Delete a video by ID",
|
|
@@ -16607,7 +16829,7 @@ registerSchema({
|
|
|
16607
16829
|
}
|
|
16608
16830
|
}
|
|
16609
16831
|
});
|
|
16610
|
-
var deleteCommand3 =
|
|
16832
|
+
var deleteCommand3 = defineCommand141({
|
|
16611
16833
|
meta: {
|
|
16612
16834
|
name: "delete",
|
|
16613
16835
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -16648,7 +16870,7 @@ var deleteCommand3 = defineCommand140({
|
|
|
16648
16870
|
});
|
|
16649
16871
|
|
|
16650
16872
|
// src/commands/videos/get.ts
|
|
16651
|
-
import { defineCommand as
|
|
16873
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
16652
16874
|
registerSchema({
|
|
16653
16875
|
command: "videos.get",
|
|
16654
16876
|
description: "Get a single video by ID",
|
|
@@ -16656,7 +16878,7 @@ registerSchema({
|
|
|
16656
16878
|
id: { type: "string", description: "Video ID", required: true }
|
|
16657
16879
|
}
|
|
16658
16880
|
});
|
|
16659
|
-
var getCommand5 =
|
|
16881
|
+
var getCommand5 = defineCommand142({
|
|
16660
16882
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
16661
16883
|
args: {
|
|
16662
16884
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -16693,7 +16915,7 @@ var getCommand5 = defineCommand141({
|
|
|
16693
16915
|
});
|
|
16694
16916
|
|
|
16695
16917
|
// src/commands/videos/search.ts
|
|
16696
|
-
import { defineCommand as
|
|
16918
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
16697
16919
|
registerSchema({
|
|
16698
16920
|
command: "videos.search",
|
|
16699
16921
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -16703,7 +16925,7 @@ registerSchema({
|
|
|
16703
16925
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
16704
16926
|
}
|
|
16705
16927
|
});
|
|
16706
|
-
var searchCommand3 =
|
|
16928
|
+
var searchCommand3 = defineCommand143({
|
|
16707
16929
|
meta: {
|
|
16708
16930
|
name: "search",
|
|
16709
16931
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -16753,9 +16975,9 @@ var searchCommand3 = defineCommand142({
|
|
|
16753
16975
|
var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
16754
16976
|
|
|
16755
16977
|
// src/commands/videos/upload.ts
|
|
16756
|
-
import { readFile as
|
|
16978
|
+
import { readFile as readFile11, stat as stat3 } from "fs/promises";
|
|
16757
16979
|
import { extname as extname3 } from "path";
|
|
16758
|
-
import { defineCommand as
|
|
16980
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
16759
16981
|
var MIME_MAP2 = {
|
|
16760
16982
|
".mp4": "video/mp4",
|
|
16761
16983
|
".mov": "video/quicktime",
|
|
@@ -16789,7 +17011,7 @@ function detectContentType2(filePath) {
|
|
|
16789
17011
|
}
|
|
16790
17012
|
return mime;
|
|
16791
17013
|
}
|
|
16792
|
-
var uploadCommand2 =
|
|
17014
|
+
var uploadCommand2 = defineCommand144({
|
|
16793
17015
|
meta: {
|
|
16794
17016
|
name: "upload",
|
|
16795
17017
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -16818,7 +17040,7 @@ var uploadCommand2 = defineCommand143({
|
|
|
16818
17040
|
return;
|
|
16819
17041
|
}
|
|
16820
17042
|
const { uploadUrl, videoId } = await apiPost("/api/videos/upload", {});
|
|
16821
|
-
const fileBuffer = await
|
|
17043
|
+
const fileBuffer = await readFile11(filePath);
|
|
16822
17044
|
const uploadResponse = await fetch(uploadUrl, {
|
|
16823
17045
|
method: "PUT",
|
|
16824
17046
|
headers: { "Content-Type": contentType },
|
|
@@ -16843,7 +17065,7 @@ var uploadCommand2 = defineCommand143({
|
|
|
16843
17065
|
});
|
|
16844
17066
|
|
|
16845
17067
|
// src/commands/videos/index.ts
|
|
16846
|
-
var videosCommand =
|
|
17068
|
+
var videosCommand = defineCommand145({
|
|
16847
17069
|
meta: {
|
|
16848
17070
|
name: "videos",
|
|
16849
17071
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -16866,10 +17088,10 @@ Examples:
|
|
|
16866
17088
|
});
|
|
16867
17089
|
|
|
16868
17090
|
// src/commands/winning-ads/index.ts
|
|
16869
|
-
import { defineCommand as
|
|
17091
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
16870
17092
|
|
|
16871
17093
|
// src/commands/winning-ads/advertisers.ts
|
|
16872
|
-
import { defineCommand as
|
|
17094
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
16873
17095
|
registerSchema({
|
|
16874
17096
|
command: "winning-ads.advertisers",
|
|
16875
17097
|
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).",
|
|
@@ -16882,7 +17104,7 @@ registerSchema({
|
|
|
16882
17104
|
function identity(record) {
|
|
16883
17105
|
return record;
|
|
16884
17106
|
}
|
|
16885
|
-
var advertisersCommand2 =
|
|
17107
|
+
var advertisersCommand2 = defineCommand146({
|
|
16886
17108
|
meta: {
|
|
16887
17109
|
name: "advertisers",
|
|
16888
17110
|
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'
|
|
@@ -16933,7 +17155,7 @@ var advertisersCommand2 = defineCommand145({
|
|
|
16933
17155
|
});
|
|
16934
17156
|
|
|
16935
17157
|
// src/commands/winning-ads/search.ts
|
|
16936
|
-
import { defineCommand as
|
|
17158
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
16937
17159
|
registerSchema({
|
|
16938
17160
|
command: "winning-ads.search",
|
|
16939
17161
|
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.",
|
|
@@ -17041,7 +17263,7 @@ function buildSearchBody(args) {
|
|
|
17041
17263
|
}
|
|
17042
17264
|
return body;
|
|
17043
17265
|
}
|
|
17044
|
-
var searchCommand4 =
|
|
17266
|
+
var searchCommand4 = defineCommand147({
|
|
17045
17267
|
meta: {
|
|
17046
17268
|
name: "search",
|
|
17047
17269
|
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"
|
|
@@ -17153,7 +17375,7 @@ var searchCommand4 = defineCommand146({
|
|
|
17153
17375
|
});
|
|
17154
17376
|
|
|
17155
17377
|
// src/commands/winning-ads/index.ts
|
|
17156
|
-
var winningAdsCommand =
|
|
17378
|
+
var winningAdsCommand = defineCommand148({
|
|
17157
17379
|
meta: {
|
|
17158
17380
|
name: "winning-ads",
|
|
17159
17381
|
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.
|
|
@@ -17193,7 +17415,7 @@ function getCliVersion() {
|
|
|
17193
17415
|
}
|
|
17194
17416
|
|
|
17195
17417
|
// src/cli.ts
|
|
17196
|
-
var main =
|
|
17418
|
+
var main = defineCommand149({
|
|
17197
17419
|
meta: {
|
|
17198
17420
|
name: "baker",
|
|
17199
17421
|
version: getCliVersion(),
|