@koda-sl/baker-cli 0.380.0-dev.d26778d3f → 0.381.0-dev.3442c3753
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/cli.js +489 -162
- package/dist/cli.js.map +1 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -133,7 +133,7 @@ import {
|
|
|
133
133
|
} from "./chunk-7YNOGIWQ.js";
|
|
134
134
|
|
|
135
135
|
// src/cli.ts
|
|
136
|
-
import { defineCommand as
|
|
136
|
+
import { defineCommand as defineCommand256, runMain } from "citty";
|
|
137
137
|
|
|
138
138
|
// src/cache-flag.ts
|
|
139
139
|
var NO_CACHE_ARG = {
|
|
@@ -5111,6 +5111,20 @@ var FLOW_SIDE_EFFECT_CATALOG = [
|
|
|
5111
5111
|
reference: SIDE_EFFECT_REF("httpWebhook")
|
|
5112
5112
|
},
|
|
5113
5113
|
crmSideEffect("googleSpreadsheet", "Appends a row to a Google Sheet.", "columnMapping", MAP_FIRST),
|
|
5114
|
+
{
|
|
5115
|
+
kind: "side-effect",
|
|
5116
|
+
type: "shopifyCustomer",
|
|
5117
|
+
summary: "Adds a sign-up to the connected Shopify store with the consent they ticked.",
|
|
5118
|
+
skeleton: {
|
|
5119
|
+
...SIDE_EFFECT_ENVELOPE,
|
|
5120
|
+
type: "shopifyCustomer",
|
|
5121
|
+
customer: { email: null, phone: null, acceptsEmailMarketing: null, acceptsSmsMarketing: null },
|
|
5122
|
+
offer: null
|
|
5123
|
+
},
|
|
5124
|
+
owners: { customer: "agent", offer: "agent" },
|
|
5125
|
+
gotcha: "Map email to an email field with baker flows map. Email and SMS consent each need their own optional, visible, initially unticked checkbox; SMS also needs phone. No connection secret is needed. An optional offer names a published sign-up offer; read baker shopify signup-offers. Show its code with ShopifySignupCode.",
|
|
5126
|
+
reference: SIDE_EFFECT_REF("shopifyCustomer")
|
|
5127
|
+
},
|
|
5114
5128
|
crmSideEffect("hubspotForm", "Submits to a HubSpot form endpoint.", "fieldMapping", MAP_FIRST),
|
|
5115
5129
|
crmSideEffect("pipedrive", "Creates or updates a Pipedrive record.", "fieldMapping", MAP_FIRST),
|
|
5116
5130
|
crmSideEffect("goHighlevelContact", "Creates or updates a GoHighLevel contact.", "fieldMapping", MAP_FIRST),
|
|
@@ -7099,6 +7113,69 @@ var STORE_EVENTS = {
|
|
|
7099
7113
|
}
|
|
7100
7114
|
};
|
|
7101
7115
|
var STORE_EVENT_NAMES = Object.keys(STORE_EVENTS);
|
|
7116
|
+
var STORE_FIELD_LABELS = {
|
|
7117
|
+
baker_source: "Comes from",
|
|
7118
|
+
store: "Store",
|
|
7119
|
+
title: "Product",
|
|
7120
|
+
handle: "Product address",
|
|
7121
|
+
status: "Status",
|
|
7122
|
+
published: "On the store",
|
|
7123
|
+
price: "Price",
|
|
7124
|
+
price_max: "Highest price",
|
|
7125
|
+
currency: "Currency",
|
|
7126
|
+
collections: "Collections",
|
|
7127
|
+
tags: "Tags",
|
|
7128
|
+
product_type: "Product type",
|
|
7129
|
+
vendor: "Brand",
|
|
7130
|
+
product_url: "Product page",
|
|
7131
|
+
whole_product: "Whole product out of stock",
|
|
7132
|
+
options_out: "Options out of stock",
|
|
7133
|
+
options_out_count: "How many options are out",
|
|
7134
|
+
options_count: "How many options it has",
|
|
7135
|
+
promoted_by: "Ads found",
|
|
7136
|
+
promotions_checked: "Where Baker looked for ads",
|
|
7137
|
+
whole_product_was_out: "Whole product was out of stock",
|
|
7138
|
+
options_back: "Options back in stock",
|
|
7139
|
+
still_out_count: "Options still out of stock",
|
|
7140
|
+
stock_holds: "Ads Baker paused",
|
|
7141
|
+
reason: "Why",
|
|
7142
|
+
changed: "What changed",
|
|
7143
|
+
before_title: "Name before",
|
|
7144
|
+
before_price: "Price before",
|
|
7145
|
+
before_status: "Status before",
|
|
7146
|
+
before_published: "On the store before",
|
|
7147
|
+
price_changes: "Price changes",
|
|
7148
|
+
collection: "Collection",
|
|
7149
|
+
product_count: "Products",
|
|
7150
|
+
before_product_count: "Products before",
|
|
7151
|
+
order_name: "Order",
|
|
7152
|
+
ordered_at: "Ordered at",
|
|
7153
|
+
shopify_source: "Sold through",
|
|
7154
|
+
visitor_from: "Shopper came from",
|
|
7155
|
+
campaign_from: "Campaign",
|
|
7156
|
+
customer: "Customer",
|
|
7157
|
+
country: "Country",
|
|
7158
|
+
accepts_email: "Accepts email",
|
|
7159
|
+
orders: "Orders",
|
|
7160
|
+
account_state: "Account",
|
|
7161
|
+
total: "Total",
|
|
7162
|
+
items_count: "Items",
|
|
7163
|
+
products: "Products",
|
|
7164
|
+
product_handles: "Product addresses",
|
|
7165
|
+
known_customer: "Known customer",
|
|
7166
|
+
discount_codes_count: "Discount codes",
|
|
7167
|
+
started_at: "Started at",
|
|
7168
|
+
last_activity_at: "Last active at",
|
|
7169
|
+
window_hours: "Hours looked at",
|
|
7170
|
+
window_start: "From",
|
|
7171
|
+
window_end: "To",
|
|
7172
|
+
expected_orders: "Usual orders",
|
|
7173
|
+
revenue: "Sales",
|
|
7174
|
+
expected_revenue: "Usual sales",
|
|
7175
|
+
drop_percent: "Drop (%)",
|
|
7176
|
+
baseline_days: "Days compared"
|
|
7177
|
+
};
|
|
7178
|
+
var FIELD_LABELS = new Map(Object.entries(STORE_FIELD_LABELS));
|
|
7102
7179
|
|
|
7103
7180
|
// ../api/src/scheduledAgentRules.ts
|
|
7104
7181
|
var CONDITION_OPERATORS = {
|
|
@@ -8541,9 +8618,9 @@ function parsePriority(value, { allowClear }) {
|
|
|
8541
8618
|
`Unknown --priority "${value}". Expected one of: ${ACTION_PRIORITIES.join(", ")}${allowClear ? ", or 'none' to clear" : ""}.`
|
|
8542
8619
|
);
|
|
8543
8620
|
}
|
|
8544
|
-
function looksScheduled(name,
|
|
8621
|
+
function looksScheduled(name, description2) {
|
|
8545
8622
|
const haystack = fold(`${name}
|
|
8546
|
-
${
|
|
8623
|
+
${description2}`);
|
|
8547
8624
|
return SCHEDULE_SIGNALS.some((re2) => re2.test(haystack));
|
|
8548
8625
|
}
|
|
8549
8626
|
var CAMPAIGN_ENTITY = String.raw`(?:campaigns?|campanas?|ad\s*sets?|adsets?|ad\s*groups?|adgroups?|ads?|anuncios?|conjuntos?\s+de\s+anuncios|grupos?\s+de\s+anuncios)`;
|
|
@@ -8701,10 +8778,10 @@ var SURFACE_RULES = [
|
|
|
8701
8778
|
var FAN_OUT_NUDGE_THRESHOLD = 2;
|
|
8702
8779
|
var FAN_OUT_THRESHOLD = 3;
|
|
8703
8780
|
var SCHEDULED_HINT = 'This reads as recurring/scheduled work. If it should run on a cadence or a future date, create a Scheduled agent instead \u2014 baker scheduled-agents create --cron "0 9 * * MON" (or --run-at, or --trigger for a reaction rather than a clock; guide: `__tooling__/docs/tools/baker/scheduled-agents.md`). Do not capture "set up a schedule" as a Work Action.';
|
|
8704
|
-
function looksExecutable(name,
|
|
8781
|
+
function looksExecutable(name, description2) {
|
|
8705
8782
|
const foldedName = fold(name);
|
|
8706
8783
|
const full = `${foldedName}
|
|
8707
|
-
${fold(
|
|
8784
|
+
${fold(description2)}`;
|
|
8708
8785
|
for (const rule of SURFACE_RULES) {
|
|
8709
8786
|
const haystack = rule.nameOnly ? foldedName : full;
|
|
8710
8787
|
if (rule.except?.some((re2) => re2.test(full))) {
|
|
@@ -8724,7 +8801,7 @@ ${fold(description)}`;
|
|
|
8724
8801
|
}
|
|
8725
8802
|
function buildCreateHints({
|
|
8726
8803
|
name,
|
|
8727
|
-
description,
|
|
8804
|
+
description: description2,
|
|
8728
8805
|
tempId,
|
|
8729
8806
|
tags,
|
|
8730
8807
|
prioritySet,
|
|
@@ -8732,13 +8809,13 @@ function buildCreateHints({
|
|
|
8732
8809
|
}) {
|
|
8733
8810
|
const hints2 = [];
|
|
8734
8811
|
const expanded = shellExpandedIn(`${name}
|
|
8735
|
-
${
|
|
8812
|
+
${description2}`);
|
|
8736
8813
|
if (expanded) {
|
|
8737
8814
|
hints2.push(
|
|
8738
8815
|
`The text says \u201C${expanded}\u201D: the shell replaced a $ amount (like $0) inside double quotes before Baker saw it. Fix it now: baker actions update ${tempId} --description '<the text, with the amounts as you read them>' (and --name '\u2026' if the name has it) \u2014 single quotes keep $ as written.`
|
|
8739
8816
|
);
|
|
8740
8817
|
}
|
|
8741
|
-
const advisory = advisoryHint(name,
|
|
8818
|
+
const advisory = advisoryHint(name, description2);
|
|
8742
8819
|
if (advisory) {
|
|
8743
8820
|
hints2.push(
|
|
8744
8821
|
`${advisory.hint} If nothing actually blocks it: baker actions draft remove ${tempId}, then do the work.`
|
|
@@ -8754,7 +8831,7 @@ ${description}`);
|
|
|
8754
8831
|
);
|
|
8755
8832
|
}
|
|
8756
8833
|
hints2.push(`Link dependencies: baker actions link --blocker <id> --blocked ${tempId}`);
|
|
8757
|
-
if (!
|
|
8834
|
+
if (!description2) {
|
|
8758
8835
|
hints2.push("Add description: baker actions update <tempId> --description '...' (what/why/where/done-when)");
|
|
8759
8836
|
}
|
|
8760
8837
|
if (!tags || tags.length === 0) {
|
|
@@ -8772,11 +8849,11 @@ ${description}`);
|
|
|
8772
8849
|
function shellExpandedIn(text2) {
|
|
8773
8850
|
return /(?:^|[\s(])((?:\/usr)?\/bin\/(?:ba|z|da|k)?sh|-?(?:ba|z|da|k)sh)\b/.exec(text2)?.[1] ?? null;
|
|
8774
8851
|
}
|
|
8775
|
-
function advisoryHint(name,
|
|
8776
|
-
if (looksScheduled(name,
|
|
8852
|
+
function advisoryHint(name, description2) {
|
|
8853
|
+
if (looksScheduled(name, description2)) {
|
|
8777
8854
|
return { kind: "scheduled", hint: SCHEDULED_HINT };
|
|
8778
8855
|
}
|
|
8779
|
-
const executable = looksExecutable(name,
|
|
8856
|
+
const executable = looksExecutable(name, description2);
|
|
8780
8857
|
return executable ? { kind: "executable", ...executable } : null;
|
|
8781
8858
|
}
|
|
8782
8859
|
var ACTIONS_LIST_DEFAULT_LIMIT = 500;
|
|
@@ -8862,9 +8939,9 @@ function parseSkillFrontmatter(md) {
|
|
|
8862
8939
|
const lines = extractFrontmatterLines(md);
|
|
8863
8940
|
if (!lines) return null;
|
|
8864
8941
|
const name = readField(lines, "name");
|
|
8865
|
-
const
|
|
8866
|
-
if (!name || !
|
|
8867
|
-
const trimmed =
|
|
8942
|
+
const description2 = readField(lines, "description");
|
|
8943
|
+
if (!name || !description2) return null;
|
|
8944
|
+
const trimmed = description2.length > DESCRIPTION_MAX ? `${description2.slice(0, DESCRIPTION_MAX)}\u2026` : description2;
|
|
8868
8945
|
return { name, description: trimmed };
|
|
8869
8946
|
}
|
|
8870
8947
|
function findSkillsDir(startDir) {
|
|
@@ -14989,6 +15066,7 @@ var DESTINATION_NAMES = {
|
|
|
14989
15066
|
googleSpreadsheet: "Google Sheets",
|
|
14990
15067
|
hubspotForm: "HubSpot Form",
|
|
14991
15068
|
goHighlevelContact: "GoHighLevel",
|
|
15069
|
+
shopifyCustomer: "Shopify",
|
|
14992
15070
|
crmble: "Crmble"
|
|
14993
15071
|
};
|
|
14994
15072
|
function destinationKey(type) {
|
|
@@ -19550,9 +19628,9 @@ var assetGroupsCommand = defineCommand31({
|
|
|
19550
19628
|
])
|
|
19551
19629
|
}
|
|
19552
19630
|
});
|
|
19553
|
-
function fileCreateCommand(name, kind,
|
|
19631
|
+
function fileCreateCommand(name, kind, description2, hints2) {
|
|
19554
19632
|
return defineCommand31({
|
|
19555
|
-
meta: { name, description },
|
|
19633
|
+
meta: { name, description: description2 },
|
|
19556
19634
|
args: { ...customerIdArg, ...fileArg },
|
|
19557
19635
|
run: async ({ args: args5 }) => {
|
|
19558
19636
|
const customerId = requireCustomerId(args5);
|
|
@@ -37870,8 +37948,8 @@ function castAvatarsOnElements(elementsInput, avatars) {
|
|
|
37870
37948
|
if (!avatar) return el;
|
|
37871
37949
|
next += 1;
|
|
37872
37950
|
if (el.label) byLabel.set(el.label, avatar);
|
|
37873
|
-
const
|
|
37874
|
-
return { ...el, ...
|
|
37951
|
+
const description2 = avatar.subjectDescription?.trim();
|
|
37952
|
+
return { ...el, ...description2 ? { description: description2 } : {}, source_image: avatar.sheetUrl, source_is_sheet: true };
|
|
37875
37953
|
});
|
|
37876
37954
|
return cast.map((el) => {
|
|
37877
37955
|
const avatar = el.same_as ? byLabel.get(el.same_as) : void 0;
|
|
@@ -38166,7 +38244,7 @@ function buildFramePrompt(edge, sceneIndex, framePrompt, present2, hasAnchor, mo
|
|
|
38166
38244
|
"- ORIGINAL_FRAME \u2014 use ONLY for composition: framing, camera angle, shot size, subject placement, pose, and proportions. IGNORE its text, logo, brand name, colors, AND the identity of every person/animal/object in it \u2014 those come from the labeled reference images above, never from this frame. It is a DIFFERENT brand's footage with DIFFERENT actors, here ONLY to anchor where things sit and how the shot is framed (e.g. a profile/side angle stays a profile/side angle), never who they are or what palette to use."
|
|
38167
38245
|
] : []
|
|
38168
38246
|
].join("\n");
|
|
38169
|
-
const
|
|
38247
|
+
const description2 = framePrompt?.trim() || `the ${edge} frame of scene ${sceneIndex + 1} \u2014 describe the full composition, subjects, setting, action, lighting, and palette here. (Edit this line to change ONLY this frame.)`;
|
|
38170
38248
|
const isHookFrame = sceneIndex === 0 && edge === "start";
|
|
38171
38249
|
const cleanPlateBlock = [
|
|
38172
38250
|
"CRITICAL \u2014 RENDER A CLEAN PLATE WITH ZERO TEXT OR GRAPHIC OVERLAYS:",
|
|
@@ -38244,7 +38322,7 @@ function buildFramePrompt(edge, sceneIndex, framePrompt, present2, hasAnchor, mo
|
|
|
38244
38322
|
""
|
|
38245
38323
|
] : [],
|
|
38246
38324
|
"FRAME DESCRIPTION (this frame's editable prompt):",
|
|
38247
|
-
|
|
38325
|
+
description2,
|
|
38248
38326
|
"",
|
|
38249
38327
|
"Render exactly what the FRAME DESCRIPTION and the SHARED AD SPEC specify \u2014 this is the authoritative ad: its cast identity (via the reference images), palette, brand, and intent are law. Keep every recurring element identical to its reference image across all frames. Again: clean plate only \u2014 no rendered text, and no icons/stickers/emojis/badges (those live on the overlay layer).",
|
|
38250
38328
|
"",
|
|
@@ -39100,8 +39178,8 @@ function localizeNumeralsForNative(text2, langCode) {
|
|
|
39100
39178
|
if (!langCode || !INTEGER_SPELLERS[langCode]) return text2;
|
|
39101
39179
|
return text2.replace(/(?<![\w.,-])\d{1,9}(?![\w.,-])/g, (m) => spellNumber(langCode, Number.parseInt(m, 10)));
|
|
39102
39180
|
}
|
|
39103
|
-
function parseVoiceTraits(
|
|
39104
|
-
const d =
|
|
39181
|
+
function parseVoiceTraits(description2) {
|
|
39182
|
+
const d = description2.toLowerCase();
|
|
39105
39183
|
const out = {};
|
|
39106
39184
|
if (/\b(female|woman|women|girl|lady)\b/.test(d)) out.gender = "female";
|
|
39107
39185
|
else if (/\b(male|man|men|guy|boy)\b/.test(d)) out.gender = "male";
|
|
@@ -39312,11 +39390,11 @@ function makeVoiceFactory(blueprint, canonical2, nodes, voiceLanguage, pinnedVoi
|
|
|
39312
39390
|
const existing = bySpeaker.get(speaker);
|
|
39313
39391
|
if (existing) return existing;
|
|
39314
39392
|
const id = sanitizeId(`voice_${speaker}`, `voice_${bySpeaker.size}`);
|
|
39315
|
-
const
|
|
39316
|
-
const traits = parseVoiceTraits(
|
|
39393
|
+
const description2 = describe(speaker);
|
|
39394
|
+
const traits = parseVoiceTraits(description2);
|
|
39317
39395
|
if (voiceLanguage) traits.language = voiceLanguage;
|
|
39318
39396
|
nodes.push(
|
|
39319
|
-
pinnedVoiceId ? { id, type: "voice_select", params: { description, voice_id: pinnedVoiceId, ...traits } } : { id, type: "voice_select", params: { description, ...traits } }
|
|
39397
|
+
pinnedVoiceId ? { id, type: "voice_select", params: { description: description2, voice_id: pinnedVoiceId, ...traits } } : { id, type: "voice_select", params: { description: description2, ...traits } }
|
|
39320
39398
|
);
|
|
39321
39399
|
bySpeaker.set(speaker, id);
|
|
39322
39400
|
return id;
|
|
@@ -42608,8 +42686,8 @@ function castAvatarsOnStaticElements(elementsInput, avatars) {
|
|
|
42608
42686
|
const avatar = isPerson(el) ? avatars[next] : void 0;
|
|
42609
42687
|
if (!avatar) return el;
|
|
42610
42688
|
next += 1;
|
|
42611
|
-
const
|
|
42612
|
-
return { ...el, ...
|
|
42689
|
+
const description2 = avatar.subjectDescription?.trim();
|
|
42690
|
+
return { ...el, ...description2 ? { description: description2 } : {}, source_image: avatar.sheetUrl };
|
|
42613
42691
|
});
|
|
42614
42692
|
}
|
|
42615
42693
|
function staticAvatarsNotCast(elementsInput, handles) {
|
|
@@ -43915,8 +43993,8 @@ function adSpecCastElements(spec, avatar) {
|
|
|
43915
43993
|
...spec.set?.image?.trim() ? { source_image: spec.set.image.trim() } : {}
|
|
43916
43994
|
});
|
|
43917
43995
|
}
|
|
43918
|
-
const
|
|
43919
|
-
if (!
|
|
43996
|
+
const description2 = (avatar?.subjectDescription ?? spec.cast?.description)?.trim();
|
|
43997
|
+
if (!description2) return elements;
|
|
43920
43998
|
const scenes = spec.beats.map((beat, i) => ({ beat, i })).filter(({ beat, i }) => beat.cast !== false && !(endCardWanted(spec) && i === lastIndex)).map(({ i }) => i);
|
|
43921
43999
|
if (scenes.length === 0) return elements;
|
|
43922
44000
|
const sheet = avatar?.sheetUrl?.trim();
|
|
@@ -43926,7 +44004,7 @@ function adSpecCastElements(spec, avatar) {
|
|
|
43926
44004
|
// Same id the dialogue names as speaker: that pairing is what lets the engine see
|
|
43927
44005
|
// the presenter as present in a scene and route it to native audio.
|
|
43928
44006
|
cast_id: AD_CAST_ID,
|
|
43929
|
-
description,
|
|
44007
|
+
description: description2,
|
|
43930
44008
|
scenes,
|
|
43931
44009
|
// An avatar's identity sheet IS the turnaround the engine would otherwise render,
|
|
43932
44010
|
// so it is handed over as one. Left unmarked, the run paid to generate a sheet OF
|
|
@@ -48922,6 +49000,9 @@ var ADS_MATCHING = [
|
|
|
48922
49000
|
"country"
|
|
48923
49001
|
];
|
|
48924
49002
|
var MAPPING_SLOTS = {
|
|
49003
|
+
shopifyCustomer: [
|
|
49004
|
+
{ kind: "record", key: "customer", allowed: ["email", "phone", "acceptsEmailMarketing", "acceptsSmsMarketing"] }
|
|
49005
|
+
],
|
|
48925
49006
|
googleSpreadsheet: [{ kind: "list", key: "columnMapping", addressedBy: "column" }],
|
|
48926
49007
|
hubspotForm: [
|
|
48927
49008
|
{
|
|
@@ -64096,13 +64177,13 @@ var createCommand3 = defineCommand197({
|
|
|
64096
64177
|
try {
|
|
64097
64178
|
refuseAutoPublish(args5);
|
|
64098
64179
|
const name = args5.name;
|
|
64099
|
-
const
|
|
64180
|
+
const description2 = args5.description;
|
|
64100
64181
|
const prompt = args5.prompt;
|
|
64101
64182
|
const template = typeof args5.template === "string" ? args5.template.trim() : "";
|
|
64102
64183
|
if (template.length === 0 && (!name || name.trim().length === 0)) {
|
|
64103
64184
|
failValidation4("--name is required. Or pass --template to use a recipe's name.");
|
|
64104
64185
|
}
|
|
64105
|
-
if (template.length === 0 && (!
|
|
64186
|
+
if (template.length === 0 && (!description2 || description2.trim().length === 0)) {
|
|
64106
64187
|
failValidation4("--description is required. Or pass --template to use a recipe's line.");
|
|
64107
64188
|
}
|
|
64108
64189
|
if (template.length === 0 && (!prompt || prompt.trim().length === 0)) {
|
|
@@ -64113,7 +64194,7 @@ var createCommand3 = defineCommand197({
|
|
|
64113
64194
|
const body = {
|
|
64114
64195
|
chatId: requireChatId(),
|
|
64115
64196
|
...name?.trim() ? { name } : {},
|
|
64116
|
-
...
|
|
64197
|
+
...description2?.trim() ? { description: description2 } : {},
|
|
64117
64198
|
enabled: !args5.disabled,
|
|
64118
64199
|
...trigger,
|
|
64119
64200
|
...prompt ? { prompt } : {},
|
|
@@ -64793,7 +64874,7 @@ var schemaCommand2 = defineCommand208({
|
|
|
64793
64874
|
});
|
|
64794
64875
|
|
|
64795
64876
|
// src/commands/shopify/index.ts
|
|
64796
|
-
import { defineCommand as
|
|
64877
|
+
import { defineCommand as defineCommand216 } from "citty";
|
|
64797
64878
|
|
|
64798
64879
|
// src/commands/shopify/buyers.ts
|
|
64799
64880
|
import { defineCommand as defineCommand209 } from "citty";
|
|
@@ -65129,7 +65210,7 @@ var shopifyVariantSchema = z50.object({
|
|
|
65129
65210
|
compareAtPrice: shopifyPriceSchema.optional(),
|
|
65130
65211
|
stock: shopifyOptionStockSchema,
|
|
65131
65212
|
quantity: z50.number().optional(),
|
|
65132
|
-
/** The link for
|
|
65213
|
+
/** The option's buy link for ads, emails and messages (a landing places `<ShopifyProduct>` instead): never build a Shopify link by hand. Absent when the option can't be bought. */
|
|
65133
65214
|
buyUrl: z50.string().optional(),
|
|
65134
65215
|
buyUrlKind: shopifyBuyDestinationSchema.optional(),
|
|
65135
65216
|
/** Why there is no buy link. */
|
|
@@ -65244,7 +65325,7 @@ var shopifyProductDetailSchema = z50.object({
|
|
|
65244
65325
|
handle: z50.string(),
|
|
65245
65326
|
/** The product's page in Baker — the link to share with the user. */
|
|
65246
65327
|
url: z50.string(),
|
|
65247
|
-
/** The product's page on the online store: to look at, never a buy button's link (that is each option's `buyUrl
|
|
65328
|
+
/** The product's page on the online store: to look at, never a buy button's link (that is each option's `buyUrl`, or `<ShopifyProduct>` on a landing). */
|
|
65248
65329
|
storeUrl: z50.string().optional(),
|
|
65249
65330
|
availability: shopifyAvailabilitySchema.optional(),
|
|
65250
65331
|
status: shopifyProductStatusSchema.optional(),
|
|
@@ -65820,7 +65901,8 @@ var shopifyWriteEntitySchema = z52.enum([
|
|
|
65820
65901
|
"discountCode",
|
|
65821
65902
|
"urlRedirect",
|
|
65822
65903
|
"marketingActivity",
|
|
65823
|
-
"webPixel"
|
|
65904
|
+
"webPixel",
|
|
65905
|
+
"signupOffer"
|
|
65824
65906
|
]);
|
|
65825
65907
|
var shopifyDraftOpKindSchema = z52.enum([
|
|
65826
65908
|
"shopify.product.update",
|
|
@@ -65841,7 +65923,9 @@ var shopifyDraftOpKindSchema = z52.enum([
|
|
|
65841
65923
|
"shopify.urlRedirect.delete",
|
|
65842
65924
|
"shopify.marketingActivity.upsert",
|
|
65843
65925
|
"shopify.marketingActivity.delete",
|
|
65844
|
-
"shopify.webPixel.update"
|
|
65926
|
+
"shopify.webPixel.update",
|
|
65927
|
+
"shopify.signupOffer.set",
|
|
65928
|
+
"shopify.signupOffer.end"
|
|
65845
65929
|
]);
|
|
65846
65930
|
var shopifyDecimalSchema = z52.string().regex(/^\d{1,12}(\.\d{1,4})?$/, 'write amounts as a decimal string, e.g. "19.95"');
|
|
65847
65931
|
var tagSchema = z52.string().trim().min(1).max(255);
|
|
@@ -65963,6 +66047,27 @@ var marketingUpsertSchema = z52.object({
|
|
|
65963
66047
|
medium: z52.string().trim().min(1).max(255)
|
|
65964
66048
|
}).strict()
|
|
65965
66049
|
}).strict();
|
|
66050
|
+
var signupOfferHandleSchema = z52.string().regex(/^[a-z0-9][a-z0-9-]{1,39}$/, "2\u201340 lowercase letters, digits and dashes, e.g. welcome-10");
|
|
66051
|
+
var signupOfferSetSchema = z52.object({
|
|
66052
|
+
/** What the store's staff see in front of each code, and the Store page's row. */
|
|
66053
|
+
name: z52.string().trim().min(1).max(80),
|
|
66054
|
+
value: discountValueSchema,
|
|
66055
|
+
appliesTo: discountAppliesToSchema,
|
|
66056
|
+
minimumSubtotal: shopifyDecimalSchema.optional(),
|
|
66057
|
+
/** Each code's life, from the moment it is given. */
|
|
66058
|
+
validForDays: z52.number().int().min(1).max(365),
|
|
66059
|
+
/** The offer stops giving codes after this; no code outlives it. */
|
|
66060
|
+
endsAt: isoDateTimeSchema.optional(),
|
|
66061
|
+
/** How many codes the offer gives in all. */
|
|
66062
|
+
maxCodes: z52.number().int().min(1).max(1e5).optional(),
|
|
66063
|
+
/** The start of every code (WELCOME-7Q2M9XKD); default: the handle in capitals. */
|
|
66064
|
+
codePrefix: z52.string().regex(/^[A-Z0-9]{2,12}$/, "2\u201312 capital letters or digits, e.g. WELCOME").optional(),
|
|
66065
|
+
combinesWith: z52.object({
|
|
66066
|
+
productDiscounts: z52.boolean().optional(),
|
|
66067
|
+
orderDiscounts: z52.boolean().optional(),
|
|
66068
|
+
shippingDiscounts: z52.boolean().optional()
|
|
66069
|
+
}).strict().optional()
|
|
66070
|
+
}).strict();
|
|
65966
66071
|
var emptySchema = z52.object({}).strict();
|
|
65967
66072
|
var opFields = {
|
|
65968
66073
|
/** Optional caller-chosen ref for a create, so later ops in the batch can name it (`shopify_temp_…`). */
|
|
@@ -66008,7 +66113,19 @@ var shopifyDraftOpInputSchema = z52.discriminatedUnion("kind", [
|
|
|
66008
66113
|
payload: emptySchema.optional(),
|
|
66009
66114
|
...opFields
|
|
66010
66115
|
}),
|
|
66011
|
-
z52.object({ kind: z52.literal("shopify.webPixel.update"), payload: emptySchema.optional(), ...opFields })
|
|
66116
|
+
z52.object({ kind: z52.literal("shopify.webPixel.update"), payload: emptySchema.optional(), ...opFields }),
|
|
66117
|
+
z52.object({
|
|
66118
|
+
kind: z52.literal("shopify.signupOffer.set"),
|
|
66119
|
+
target: signupOfferHandleSchema,
|
|
66120
|
+
payload: signupOfferSetSchema,
|
|
66121
|
+
...opFields
|
|
66122
|
+
}),
|
|
66123
|
+
z52.object({
|
|
66124
|
+
kind: z52.literal("shopify.signupOffer.end"),
|
|
66125
|
+
target: signupOfferHandleSchema,
|
|
66126
|
+
payload: emptySchema.optional(),
|
|
66127
|
+
...opFields
|
|
66128
|
+
})
|
|
66012
66129
|
]);
|
|
66013
66130
|
var PAYLOAD_KEYS = new Map(
|
|
66014
66131
|
shopifyDraftOpInputSchema.options.map((option) => {
|
|
@@ -66226,7 +66343,7 @@ var fullArg = {
|
|
|
66226
66343
|
|
|
66227
66344
|
// src/commands/shopify/hints.ts
|
|
66228
66345
|
var RECONNECT = 'Baker has lost access to this Shopify store, so these products may be out of date. Say so, and ask the user to reconnect with `request_connection` { platform: "shopify" } \u2014 the card offers Reconnect.';
|
|
66229
|
-
var OWN_STOREFRONT = "This store sells through its own storefront, not a Shopify online store: Baker
|
|
66346
|
+
var OWN_STOREFRONT = "This store sells through its own storefront, not a Shopify online store: Baker links to its product pages once the website's address is set in Brain \u2192 Store (`buyUrlKind` says where each link goes); until then, link to the product pages on the client's own site, and ask the user for them if you don't know them.";
|
|
66230
66347
|
function day(iso) {
|
|
66231
66348
|
return iso ? iso.slice(0, 10) : null;
|
|
66232
66349
|
}
|
|
@@ -66334,17 +66451,17 @@ function stockHintsFor(product) {
|
|
|
66334
66451
|
}
|
|
66335
66452
|
var BUY_NOTES = {
|
|
66336
66453
|
password_protected: "The store asks for a password before anyone can see it: a shopper following a buy link meets it first \u2014 tell the user before sending traffic.",
|
|
66337
|
-
subscription_optional: "It can also be bought by subscription
|
|
66338
|
-
own_storefront: "The store sells through its own
|
|
66454
|
+
subscription_optional: "It can also be bought by subscription: on a landing `<ShopifyProduct>` offers the plans; a `buyUrl` elsewhere adds it once.",
|
|
66455
|
+
own_storefront: "The store sells through its own website: `buyUrlKind` says where each link goes \u2014 its product page, or its cart page once its developers confirm it in Brain \u2192 Store.",
|
|
66339
66456
|
details_pending: "Baker hasn't read this product's details yet (subscriptions among them): its buy links may change.",
|
|
66340
|
-
subscription_only: "It's sold only by subscription
|
|
66457
|
+
subscription_only: "It's sold only by subscription: on a landing `<ShopifyProduct>` offers the plans; a `buyUrl` elsewhere is its product page, where the shopper picks one."
|
|
66341
66458
|
};
|
|
66342
66459
|
function buyHints(product) {
|
|
66343
66460
|
const hints2 = [];
|
|
66344
66461
|
if (product.variants.some((variant) => variant.buyUrl)) {
|
|
66345
66462
|
hints2.push(
|
|
66346
|
-
`
|
|
66347
|
-
|
|
66463
|
+
`On a landing, place \`<ShopifyProduct product="${product.handle}" />\` (and \`<ShopifyBuyButton product="${product.handle}">\` for a second button): it shows the options, price and stock, and its button hands the shopper to the store. Never put a \`buyUrl\` on a landing yourself, and never build an option picker. See /landing \`.claude/skills/landing/references/verticals/ecommerce.md\`.`,
|
|
66464
|
+
`\`buyUrl\` is for links outside a landing \u2014 an ad, an email, a message: one per option; never \`storeUrl\` (a page to look at), never a Shopify link built yourself (it follows the store's setting: ${product.buyDestination.replace("_", " ")}; \`--quantity <n>\` sets how many).`
|
|
66348
66465
|
);
|
|
66349
66466
|
}
|
|
66350
66467
|
const notes = new Set(product.variants.flatMap((variant) => variant.notes ?? []));
|
|
@@ -66811,9 +66928,24 @@ var WARNINGS = "Read the warnings above before telling the user this is ready.";
|
|
|
66811
66928
|
var DISCOUNT = "The code works only after the chat is published; don't announce it as live or share it as working yet.";
|
|
66812
66929
|
var EMPTY_COLLECTION = "The new collection has no products yet: add them with `baker shopify change collection add <collection> <product\u2026>`.";
|
|
66813
66930
|
var COLLECTION_DELETE = "Its address stops working when it is deleted: keep old links alive with `baker shopify change redirect create --from /collections/<handle> --to <page>` (ask the user where they should land).";
|
|
66931
|
+
function repointedRedirects(ops) {
|
|
66932
|
+
const removed = ops.flatMap(
|
|
66933
|
+
(op) => op.kind === "shopify.urlRedirect.delete" && op.ref.startsWith("urlRedirect:") ? [op.ref.slice("urlRedirect:".length)] : []
|
|
66934
|
+
);
|
|
66935
|
+
return removed.flatMap((path49) => {
|
|
66936
|
+
const made = ops.find(
|
|
66937
|
+
(op) => op.kind === "shopify.urlRedirect.create" && op.summary.startsWith(`Redirect ${path49} to `)
|
|
66938
|
+
);
|
|
66939
|
+
if (!made) return [];
|
|
66940
|
+
const to = made.summary.slice(`Redirect ${path49} to `.length);
|
|
66941
|
+
return [
|
|
66942
|
+
`${path49} still redirects after publish, now to ${to}: tell the user the old link goes there, not that its redirect is removed.`
|
|
66943
|
+
];
|
|
66944
|
+
});
|
|
66945
|
+
}
|
|
66814
66946
|
function stageHints(data) {
|
|
66815
66947
|
if (!data.staged) return [];
|
|
66816
|
-
const hints2 = [STAGED];
|
|
66948
|
+
const hints2 = [STAGED, ...repointedRedirects(data.ops)];
|
|
66817
66949
|
if (data.ops.some((op) => op.warnings.length > 0)) hints2.push(WARNINGS);
|
|
66818
66950
|
if (data.ops.some((op) => op.kind === "shopify.discountCode.create")) hints2.push(DISCOUNT);
|
|
66819
66951
|
if (data.ops.some((op) => op.kind === "shopify.collection.delete")) hints2.push(COLLECTION_DELETE);
|
|
@@ -67154,18 +67286,18 @@ var collectionUpdate = leaf(
|
|
|
67154
67286
|
() => target3(args5, "collection")
|
|
67155
67287
|
)
|
|
67156
67288
|
);
|
|
67157
|
-
function collectionVerb(verb, kind,
|
|
67289
|
+
function collectionVerb(verb, kind, description2) {
|
|
67158
67290
|
return leaf(
|
|
67159
67291
|
`shopify.change.collection.${verb}`,
|
|
67160
|
-
{ name: verb, description },
|
|
67292
|
+
{ name: verb, description: description2 },
|
|
67161
67293
|
{ collection: TARGET("Collection id, handle, link or a shopify_temp_ ref staged in this chat") },
|
|
67162
67294
|
async (args5) => await stage([{ kind, target: target3(args5, "collection") }])
|
|
67163
67295
|
);
|
|
67164
67296
|
}
|
|
67165
|
-
function membership(verb, kind,
|
|
67297
|
+
function membership(verb, kind, description2) {
|
|
67166
67298
|
return leaf(
|
|
67167
67299
|
`shopify.change.collection.${verb}`,
|
|
67168
|
-
{ name: verb, description },
|
|
67300
|
+
{ name: verb, description: description2 },
|
|
67169
67301
|
{
|
|
67170
67302
|
collection: TARGET("Collection id, handle, link or a shopify_temp_ ref"),
|
|
67171
67303
|
products: TARGET("Products (ids, handles or links), space separated")
|
|
@@ -67215,6 +67347,75 @@ function discountPayload(args5) {
|
|
|
67215
67347
|
combinesWith: combinesOf(args5.combines)
|
|
67216
67348
|
});
|
|
67217
67349
|
}
|
|
67350
|
+
function signupOfferFlagsProblem(args5) {
|
|
67351
|
+
if (typeof args5.name !== "string" || args5.name.trim() === "")
|
|
67352
|
+
return 'Add --name "<what shoppers and store staff see, e.g. 10% off>": every sign-up offer needs a name.';
|
|
67353
|
+
if (args5["valid-days"] === void 0)
|
|
67354
|
+
return "Add --valid-days <1-365>: how many days each code lasts after it is given.";
|
|
67355
|
+
return void 0;
|
|
67356
|
+
}
|
|
67357
|
+
function signupOfferPayload(args5) {
|
|
67358
|
+
return defined({
|
|
67359
|
+
name: args5.name,
|
|
67360
|
+
value: discountValue(args5),
|
|
67361
|
+
appliesTo: appliesToOf(args5),
|
|
67362
|
+
minimumSubtotal: args5.minimum,
|
|
67363
|
+
validForDays: numberOf3(args5["valid-days"]),
|
|
67364
|
+
endsAt: args5.ends,
|
|
67365
|
+
maxCodes: numberOf3(args5["max-codes"]),
|
|
67366
|
+
codePrefix: args5.prefix,
|
|
67367
|
+
combinesWith: combinesOf(args5.combines)
|
|
67368
|
+
});
|
|
67369
|
+
}
|
|
67370
|
+
var signupOfferSet = leaf(
|
|
67371
|
+
"shopify.change.signupOffer.set",
|
|
67372
|
+
{
|
|
67373
|
+
name: "set",
|
|
67374
|
+
description: 'Stage a sign-up offer. Changes money: ask the exact approval question returned by this command. Example: baker shopify change signup-offer set welcome-10 --name "Welcome" --percent 10 --valid-days 14 --max-codes 1000'
|
|
67375
|
+
},
|
|
67376
|
+
{
|
|
67377
|
+
handle: TARGET("Offer handle, e.g. welcome-10"),
|
|
67378
|
+
name: {
|
|
67379
|
+
type: "string",
|
|
67380
|
+
description: 'Offer name shoppers and store staff see (required), e.g. "10% off"',
|
|
67381
|
+
required: false
|
|
67382
|
+
},
|
|
67383
|
+
percent: { type: "string", description: "Percentage off (choose percent or amount)", required: false },
|
|
67384
|
+
amount: { type: "string", description: "Amount off in the store currency", required: false },
|
|
67385
|
+
products: { type: "string", description: "Product handles or ids, comma separated", required: false },
|
|
67386
|
+
collections: { type: "string", description: "Collection handles or ids, comma separated", required: false },
|
|
67387
|
+
minimum: { type: "string", description: "Minimum subtotal", required: false },
|
|
67388
|
+
"valid-days": { type: "string", description: "Each code lasts 1\u2013365 days (required)", required: false },
|
|
67389
|
+
ends: { type: "string", description: "Offer end as ISO date and time; no code outlives it", required: false },
|
|
67390
|
+
"max-codes": { type: "string", description: "Total codes the offer may give, 1\u2013100000", required: false },
|
|
67391
|
+
prefix: { type: "string", description: "Code prefix: 2\u201312 uppercase letters or digits", required: false },
|
|
67392
|
+
combines: {
|
|
67393
|
+
type: "string",
|
|
67394
|
+
description: "Comma-separated product,order,shipping discounts to combine",
|
|
67395
|
+
required: false
|
|
67396
|
+
},
|
|
67397
|
+
...JSON_ARGS
|
|
67398
|
+
},
|
|
67399
|
+
async (args5) => await stageFor(
|
|
67400
|
+
"shopify.signupOffer.set",
|
|
67401
|
+
args5,
|
|
67402
|
+
() => {
|
|
67403
|
+
const problem = signupOfferFlagsProblem(args5);
|
|
67404
|
+
if (problem) failValidation3(problem);
|
|
67405
|
+
return signupOfferPayload(args5);
|
|
67406
|
+
},
|
|
67407
|
+
() => target3(args5, "offer handle")
|
|
67408
|
+
)
|
|
67409
|
+
);
|
|
67410
|
+
var signupOfferEnd = leaf(
|
|
67411
|
+
"shopify.change.signupOffer.end",
|
|
67412
|
+
{
|
|
67413
|
+
name: "end",
|
|
67414
|
+
description: "End a sign-up offer at Publish. Existing codes keep their terms. Example: baker shopify change signup-offer end welcome-10"
|
|
67415
|
+
},
|
|
67416
|
+
{ handle: TARGET("Offer handle") },
|
|
67417
|
+
async (args5) => await stage([{ kind: "shopify.signupOffer.end", target: target3(args5, "offer handle") }])
|
|
67418
|
+
);
|
|
67218
67419
|
var discountCreate = leaf(
|
|
67219
67420
|
"shopify.change.discount.create",
|
|
67220
67421
|
{
|
|
@@ -67340,7 +67541,7 @@ var measurementReconnect = leaf(
|
|
|
67340
67541
|
{},
|
|
67341
67542
|
async () => await stage([{ kind: "shopify.webPixel.update" }])
|
|
67342
67543
|
);
|
|
67343
|
-
var group = (name,
|
|
67544
|
+
var group = (name, description2, subCommands) => defineCommand211({ meta: { name, description: description2 }, subCommands });
|
|
67344
67545
|
var changeCommand = defineCommand211({
|
|
67345
67546
|
meta: {
|
|
67346
67547
|
name: "change",
|
|
@@ -67357,6 +67558,7 @@ change can be put back with \`baker shopify undo\`. Prices and discounts need th
|
|
|
67357
67558
|
baker shopify change measurement reconnect`
|
|
67358
67559
|
},
|
|
67359
67560
|
subCommands: {
|
|
67561
|
+
"signup-offer": group("signup-offer", "Stage or end a sign-up offer", { set: signupOfferSet, end: signupOfferEnd }),
|
|
67360
67562
|
product: group("product", "Change a product's title, description, SEO, tags or type", { update: productUpdate }),
|
|
67361
67563
|
variant: group("variant", "Change an option's SKU, barcode, weight or price", { update: variantUpdate }),
|
|
67362
67564
|
field: group("field", "Set or remove a custom field", { set: fieldSet, remove: fieldRemove }),
|
|
@@ -67567,12 +67769,46 @@ import { defineCommand as defineCommand213 } from "citty";
|
|
|
67567
67769
|
// src/commands/shopify/landingLinks.ts
|
|
67568
67770
|
import { readdir as readdir16, readFile as readFile33, stat as stat11 } from "fs/promises";
|
|
67569
67771
|
import path47 from "path";
|
|
67772
|
+
import { parse } from "@astrojs/compiler/sync";
|
|
67570
67773
|
var PAGES_MAX = 300;
|
|
67571
67774
|
var FILE_BYTES_MAX = 256 * 1024;
|
|
67572
67775
|
function escaped(text2) {
|
|
67573
67776
|
return text2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
67574
67777
|
}
|
|
67575
|
-
|
|
67778
|
+
var BUY_COMPONENTS = /* @__PURE__ */ new Set(["ShopifyProduct", "ShopifyBuyButton"]);
|
|
67779
|
+
var STRING_LITERAL = /^\s*(["'`])([^"'`]*)\1\s*$/;
|
|
67780
|
+
var ITEM_PRODUCT = /\bproduct\s*:\s*(["'`])([^"'`]*)\1/g;
|
|
67781
|
+
function namedBy(attribute) {
|
|
67782
|
+
if (attribute.name === "product") {
|
|
67783
|
+
if (attribute.kind === "quoted" || attribute.kind === "template-literal") return [attribute.value];
|
|
67784
|
+
if (attribute.kind === "expression") return [STRING_LITERAL.exec(attribute.value)?.[2] ?? ""];
|
|
67785
|
+
}
|
|
67786
|
+
if (attribute.name === "items" && attribute.kind === "expression") {
|
|
67787
|
+
return [...attribute.value.matchAll(ITEM_PRODUCT)].map((match) => match[2] ?? "");
|
|
67788
|
+
}
|
|
67789
|
+
return [];
|
|
67790
|
+
}
|
|
67791
|
+
function componentProducts(node, into) {
|
|
67792
|
+
if (node.type === "component" && BUY_COMPONENTS.has(node.name)) {
|
|
67793
|
+
for (const attribute of node.attributes) into.push(...namedBy(attribute));
|
|
67794
|
+
}
|
|
67795
|
+
if ("children" in node) for (const child of node.children) componentProducts(child, into);
|
|
67796
|
+
return into;
|
|
67797
|
+
}
|
|
67798
|
+
function buyComponentProducts(file) {
|
|
67799
|
+
if (!file.path.endsWith(".astro")) return [];
|
|
67800
|
+
try {
|
|
67801
|
+
return componentProducts(parse(file.text, void 0).ast, []);
|
|
67802
|
+
} catch {
|
|
67803
|
+
return [];
|
|
67804
|
+
}
|
|
67805
|
+
}
|
|
67806
|
+
function namesProduct(file, keys) {
|
|
67807
|
+
const wanted = new Set([keys.handle.toLowerCase(), ...keys.productId ? [keys.productId] : []].filter(Boolean));
|
|
67808
|
+
return buyComponentProducts(file).some((named) => wanted.has(named.trim().toLowerCase()));
|
|
67809
|
+
}
|
|
67810
|
+
function evidenceIn(file, keys) {
|
|
67811
|
+
const { text: text2 } = file;
|
|
67576
67812
|
const evidence = [];
|
|
67577
67813
|
if (keys.buyUrls.some((url) => url && text2.includes(url))) evidence.push("buy_link");
|
|
67578
67814
|
const page = new RegExp(`/products/${escaped(keys.handle)}(?![A-Za-z0-9_-])`, "i");
|
|
@@ -67581,19 +67817,20 @@ function evidenceIn(text2, keys) {
|
|
|
67581
67817
|
(id) => new RegExp(`(?:/cart/(?:\\d+:\\d+,)*${id}:|variant=${id}(?!\\d))`).test(text2)
|
|
67582
67818
|
);
|
|
67583
67819
|
if (option) evidence.push("variant_id");
|
|
67820
|
+
if (namesProduct(file, keys)) evidence.push("buy_button");
|
|
67584
67821
|
return evidence;
|
|
67585
67822
|
}
|
|
67586
67823
|
function landingLinksOf(pages, keys) {
|
|
67587
67824
|
const bySlug = /* @__PURE__ */ new Map();
|
|
67588
67825
|
for (const page of pages) {
|
|
67589
|
-
const found = new Set(page.files.flatMap((file) => evidenceIn(file
|
|
67826
|
+
const found = new Set(page.files.flatMap((file) => evidenceIn(file, keys)));
|
|
67590
67827
|
if (found.size === 0) continue;
|
|
67591
67828
|
const slug = page.slug.replace(/--\d+$/, "");
|
|
67592
67829
|
const held = bySlug.get(slug) ?? /* @__PURE__ */ new Set();
|
|
67593
67830
|
for (const evidence of found) held.add(evidence);
|
|
67594
67831
|
bySlug.set(slug, held);
|
|
67595
67832
|
}
|
|
67596
|
-
const order = ["buy_link", "product_page", "variant_id"];
|
|
67833
|
+
const order = ["buy_link", "product_page", "variant_id", "buy_button"];
|
|
67597
67834
|
return [...bySlug].map(([slug, evidence]) => ({ slug, evidence: order.filter((entry) => evidence.has(entry)) }));
|
|
67598
67835
|
}
|
|
67599
67836
|
async function isDir4(target4) {
|
|
@@ -67848,6 +68085,7 @@ var promotionsCommand = defineCommand213({
|
|
|
67848
68085
|
const scan = await readWorkspacePages(process.cwd());
|
|
67849
68086
|
const linked = scan ? landingLinksOf(scan.pages, {
|
|
67850
68087
|
handle: product.handle,
|
|
68088
|
+
productId: product.productId,
|
|
67851
68089
|
variantIds: product.variants.map((variant) => variant.variantId),
|
|
67852
68090
|
buyUrls: product.variants.flatMap((variant) => variant.buyUrl ? [variant.buyUrl] : [])
|
|
67853
68091
|
}) : void 0;
|
|
@@ -67893,8 +68131,96 @@ var stockHoldsCommand = defineCommand213({
|
|
|
67893
68131
|
}
|
|
67894
68132
|
});
|
|
67895
68133
|
|
|
67896
|
-
// src/
|
|
68134
|
+
// ../api/src/shopify/signups.ts
|
|
68135
|
+
import { z as z53 } from "zod";
|
|
68136
|
+
var SIGNUP_CODE_PATTERN = /^[A-Z0-9]{2,12}-[0-9A-HJKMNP-TV-Z]{8}$/;
|
|
68137
|
+
var SIGNUP_STATES = [
|
|
68138
|
+
"waiting",
|
|
68139
|
+
"ready",
|
|
68140
|
+
"used",
|
|
68141
|
+
"expired",
|
|
68142
|
+
"already",
|
|
68143
|
+
"ended",
|
|
68144
|
+
"none",
|
|
68145
|
+
"unavailable"
|
|
68146
|
+
];
|
|
68147
|
+
var CODE_STATES = /* @__PURE__ */ new Set(["ready", "used", "expired"]);
|
|
68148
|
+
var shopifySignupReplySchema = z53.object({
|
|
68149
|
+
state: z53.enum(SIGNUP_STATES),
|
|
68150
|
+
code: z53.string().regex(SIGNUP_CODE_PATTERN).optional(),
|
|
68151
|
+
endsAt: z53.string().min(1).max(40).optional()
|
|
68152
|
+
}).strict().refine(
|
|
68153
|
+
(reply) => CODE_STATES.has(reply.state) ? reply.code !== void 0 && reply.endsAt !== void 0 : true,
|
|
68154
|
+
"a code state carries the code and when it ends"
|
|
68155
|
+
).refine(
|
|
68156
|
+
(reply) => CODE_STATES.has(reply.state) ? true : reply.code === void 0 && reply.endsAt === void 0,
|
|
68157
|
+
"only the browser the code was given to is told it"
|
|
68158
|
+
);
|
|
68159
|
+
var shopifySignupResponseSchema = z53.union([
|
|
68160
|
+
z53.object({ ok: z53.literal(true), signup: shopifySignupReplySchema }).passthrough(),
|
|
68161
|
+
z53.object({ error: z53.string(), signup: shopifySignupReplySchema }).passthrough()
|
|
68162
|
+
]);
|
|
68163
|
+
var signupOfferStatusSchema = z53.enum(["active", "ended", "staged"]);
|
|
68164
|
+
var shopifySignupOfferViewSchema = z53.object({
|
|
68165
|
+
handle: z53.string(),
|
|
68166
|
+
name: z53.string(),
|
|
68167
|
+
/** "10% off everything, each code valid 14 days, at most 1,000 codes". */
|
|
68168
|
+
summary: z53.string(),
|
|
68169
|
+
status: signupOfferStatusSchema,
|
|
68170
|
+
validForDays: z53.number(),
|
|
68171
|
+
endsAt: z53.string().optional(),
|
|
68172
|
+
maxCodes: z53.number().optional(),
|
|
68173
|
+
codesGiven: z53.number()
|
|
68174
|
+
});
|
|
68175
|
+
var shopifySignupOffersResponseSchema = z53.object({
|
|
68176
|
+
/** The company has a store connection Baker can use (connected, not waiting on a reconnect). */
|
|
68177
|
+
connected: z53.boolean(),
|
|
68178
|
+
/** The store allows Baker to add customers (sign-ups work). */
|
|
68179
|
+
canAddCustomers: z53.boolean(),
|
|
68180
|
+
/** The store allows Baker to make discount codes (offers give codes). */
|
|
68181
|
+
canGiveCodes: z53.boolean(),
|
|
68182
|
+
offers: z53.array(shopifySignupOfferViewSchema),
|
|
68183
|
+
/** Sign-ups the store didn't take in the last 7 days: for a missing permission, and for anything else. */
|
|
68184
|
+
refusedLast7Days: z53.object({ permission: z53.number(), other: z53.number() })
|
|
68185
|
+
});
|
|
68186
|
+
|
|
68187
|
+
// src/commands/shopify/signupOffers.ts
|
|
67897
68188
|
import { defineCommand as defineCommand214 } from "citty";
|
|
68189
|
+
var description = "Start here for landing sign-ups: published and this chat's staged offers, codes given and store permissions. Example: baker shopify signup-offers. Forms name an offer handle; terms are staged with baker shopify change signup-offer set.";
|
|
68190
|
+
registerSchema({ command: "shopify.signupOffers", description, args: {} });
|
|
68191
|
+
var signupOffersCommand = defineCommand214({
|
|
68192
|
+
meta: { name: "signup-offers", description },
|
|
68193
|
+
async run() {
|
|
68194
|
+
try {
|
|
68195
|
+
const data = shopifySignupOffersResponseSchema.parse(
|
|
68196
|
+
await apiGet("/api/shopify/signup-offers", params({ chatId: optionalChatId() }))
|
|
68197
|
+
);
|
|
68198
|
+
const hints2 = [];
|
|
68199
|
+
if (!data.canAddCustomers)
|
|
68200
|
+
hints2.push(
|
|
68201
|
+
'Sign-ups cannot be added to the store yet: call request_connection with { platform: "shopify", reason: "Add sign-ups from your landing" }. Keep building the page; the Form works once allowed.'
|
|
68202
|
+
);
|
|
68203
|
+
if (!data.canGiveCodes)
|
|
68204
|
+
hints2.push(
|
|
68205
|
+
"Codes need the store to allow discounts: use request_connection for Shopify and keep building the page."
|
|
68206
|
+
);
|
|
68207
|
+
if (data.offers.some((offer) => offer.status === "ended"))
|
|
68208
|
+
hints2.push(
|
|
68209
|
+
"Forms naming ended offers still add customers but give no code: stage a new offer or remove offer from the Form."
|
|
68210
|
+
);
|
|
68211
|
+
if (data.offers.length === 0)
|
|
68212
|
+
hints2.push(
|
|
68213
|
+
"No sign-up offer exists yet. Omit offer for sign-ups without a code, or stage one after the user approves its terms."
|
|
68214
|
+
);
|
|
68215
|
+
writeJson({ ok: true, hints: hints2, data });
|
|
68216
|
+
} catch (error) {
|
|
68217
|
+
fail9(error);
|
|
68218
|
+
}
|
|
68219
|
+
}
|
|
68220
|
+
});
|
|
68221
|
+
|
|
68222
|
+
// src/commands/shopify/tracking.ts
|
|
68223
|
+
import { defineCommand as defineCommand215 } from "citty";
|
|
67898
68224
|
var audit = leaf(
|
|
67899
68225
|
"shopify.tracking.audit",
|
|
67900
68226
|
{
|
|
@@ -67911,7 +68237,7 @@ var audit = leaf(
|
|
|
67911
68237
|
}
|
|
67912
68238
|
}
|
|
67913
68239
|
);
|
|
67914
|
-
var trackingCommand2 =
|
|
68240
|
+
var trackingCommand2 = defineCommand215({
|
|
67915
68241
|
meta: { name: "tracking", description: "Check how the store is measured: baker shopify tracking audit" },
|
|
67916
68242
|
subCommands: { audit }
|
|
67917
68243
|
});
|
|
@@ -67954,7 +68280,7 @@ registerSchema({
|
|
|
67954
68280
|
});
|
|
67955
68281
|
registerSchema({
|
|
67956
68282
|
command: "shopify.product",
|
|
67957
|
-
description: "One product of the connected store \u2014 accepts its id, its handle, a link to it on the store, in Baker or in Shopify admin. Returns its options with price, stock and `buyUrl` (
|
|
68283
|
+
description: "One product of the connected store \u2014 accepts its id, its handle, a link to it on the store, in Baker or in Shopify admin. Returns its options with price, stock and `buyUrl` (each option's buy link for ads, emails and messages; on a landing use `<ShopifyProduct>` instead \u2014 never build a Shopify link yourself, never use `storeUrl` for it), prices by country, the options out of stock, its collections, its photos' library imageIds to place on a landing (`baker images download <imageIds> --out src/pages/<page>/_images/`) or pass to a creative, its videos' playbackIds (`<Video playbackId=\u2026/>`), and `contentSummary`: what else Baker keeps about it. Start here for a landing from a product: add `--content` for the formatted description, every custom field by its name (a size chart, care instructions), the rating, subscriptions and translations; `--field <name>` returns one field whole. `--out-of-stock` lists only the options out of stock.",
|
|
67958
68284
|
args: {
|
|
67959
68285
|
ref: { type: "positional", description: "Product id, handle, or a link to the product", required: true },
|
|
67960
68286
|
"variants-cursor": {
|
|
@@ -68044,7 +68370,7 @@ registerSchema({
|
|
|
68044
68370
|
}
|
|
68045
68371
|
}
|
|
68046
68372
|
});
|
|
68047
|
-
var salesCommand =
|
|
68373
|
+
var salesCommand = defineCommand216({
|
|
68048
68374
|
meta: {
|
|
68049
68375
|
name: "sales",
|
|
68050
68376
|
description: "What the store sold: orders, sales, refunds and net, by day, product, campaign or landing \u2014 or when buyers order (weekday, hour, month). Example: baker shopify sales --days 7 --by campaign"
|
|
@@ -68082,7 +68408,7 @@ var salesCommand = defineCommand215({
|
|
|
68082
68408
|
}
|
|
68083
68409
|
}
|
|
68084
68410
|
});
|
|
68085
|
-
var storeCommand =
|
|
68411
|
+
var storeCommand = defineCommand216({
|
|
68086
68412
|
meta: {
|
|
68087
68413
|
name: "store",
|
|
68088
68414
|
description: "The connected Shopify store: currency, countries, how many products, what is out of stock. Example: baker shopify store"
|
|
@@ -68100,7 +68426,7 @@ var storeCommand = defineCommand215({
|
|
|
68100
68426
|
}
|
|
68101
68427
|
}
|
|
68102
68428
|
});
|
|
68103
|
-
var productsCommand =
|
|
68429
|
+
var productsCommand = defineCommand216({
|
|
68104
68430
|
meta: {
|
|
68105
68431
|
name: "products",
|
|
68106
68432
|
description: 'What the store sells, with price and stock. Example: baker shopify products --search "snowboard" --stock out_of_stock'
|
|
@@ -68146,7 +68472,7 @@ var productsCommand = defineCommand215({
|
|
|
68146
68472
|
}
|
|
68147
68473
|
}
|
|
68148
68474
|
});
|
|
68149
|
-
var productCommand =
|
|
68475
|
+
var productCommand = defineCommand216({
|
|
68150
68476
|
meta: {
|
|
68151
68477
|
name: "product",
|
|
68152
68478
|
description: "One product: options with buy links, prices by country, stock, photo imageIds, video playbackIds. Accepts an id, handle or link. Example: baker shopify product the-complete-snowboard --content"
|
|
@@ -68209,7 +68535,7 @@ var productCommand = defineCommand215({
|
|
|
68209
68535
|
}
|
|
68210
68536
|
}
|
|
68211
68537
|
});
|
|
68212
|
-
var collectionsCommand =
|
|
68538
|
+
var collectionsCommand = defineCommand216({
|
|
68213
68539
|
meta: {
|
|
68214
68540
|
name: "collections",
|
|
68215
68541
|
description: "The store's collections, with the handles --collection takes. Example: baker shopify collections --full"
|
|
@@ -68234,7 +68560,7 @@ var collectionsCommand = defineCommand215({
|
|
|
68234
68560
|
}
|
|
68235
68561
|
}
|
|
68236
68562
|
});
|
|
68237
|
-
var stockCommand2 =
|
|
68563
|
+
var stockCommand2 = defineCommand216({
|
|
68238
68564
|
meta: {
|
|
68239
68565
|
name: "stock",
|
|
68240
68566
|
description: "Every product with options out of stock, naming them. Example: baker shopify stock"
|
|
@@ -68258,7 +68584,7 @@ var stockCommand2 = defineCommand215({
|
|
|
68258
68584
|
}
|
|
68259
68585
|
}
|
|
68260
68586
|
});
|
|
68261
|
-
var shopifyCommand =
|
|
68587
|
+
var shopifyCommand = defineCommand216({
|
|
68262
68588
|
meta: {
|
|
68263
68589
|
name: "shopify",
|
|
68264
68590
|
description: `Read the connected Shopify store as Baker keeps it \u2014 products, prices by country, stock, collections,
|
|
@@ -68295,13 +68621,14 @@ Examples:
|
|
|
68295
68621
|
Product photos are already in the image library: place them by imageId
|
|
68296
68622
|
(baker images download <imageIds> --out src/pages/<page>/_images/), never by a cdn.shopify.com link.
|
|
68297
68623
|
Product videos are in the video library: place them with <Video playbackId="\u2026" />.
|
|
68298
|
-
|
|
68299
|
-
|
|
68624
|
+
On a landing, the buy button is <ShopifyProduct product="\u2026"/> \u2014 never a buyUrl or a Shopify link
|
|
68625
|
+
written by hand. buyUrl is for ads, emails and messages; never use storeUrl (a page to look at) for it.
|
|
68300
68626
|
NO_SHOPIFY_CONNECTION means no store is connected: follow error.fix. SHOPIFY_NOT_AVAILABLE means it cannot be
|
|
68301
68627
|
connected here yet: carry on without it.
|
|
68302
68628
|
Full guide: __tooling__/docs/tools/baker/shopify.md`
|
|
68303
68629
|
},
|
|
68304
68630
|
subCommands: {
|
|
68631
|
+
"signup-offers": signupOffersCommand,
|
|
68305
68632
|
store: storeCommand,
|
|
68306
68633
|
products: productsCommand,
|
|
68307
68634
|
product: productCommand,
|
|
@@ -68325,10 +68652,10 @@ Full guide: __tooling__/docs/tools/baker/shopify.md`
|
|
|
68325
68652
|
});
|
|
68326
68653
|
|
|
68327
68654
|
// src/commands/studio/index.ts
|
|
68328
|
-
import { defineCommand as
|
|
68655
|
+
import { defineCommand as defineCommand225 } from "citty";
|
|
68329
68656
|
|
|
68330
68657
|
// src/commands/studio/animate.ts
|
|
68331
|
-
import { defineCommand as
|
|
68658
|
+
import { defineCommand as defineCommand217 } from "citty";
|
|
68332
68659
|
|
|
68333
68660
|
// src/commands/studio/spokenPace.ts
|
|
68334
68661
|
var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
|
|
@@ -68841,7 +69168,7 @@ async function adByHandHintFor(body) {
|
|
|
68841
69168
|
return null;
|
|
68842
69169
|
}
|
|
68843
69170
|
}
|
|
68844
|
-
var animateCommand =
|
|
69171
|
+
var animateCommand = defineCommand217({
|
|
68845
69172
|
meta: {
|
|
68846
69173
|
name: "animate",
|
|
68847
69174
|
description: "Render a clip. With an image the look is already fixed, so the prompt describes MOVEMENT \u2014 what the camera does, what the subject does, in what order. With --from text there is no image and the prompt is the whole shot.\n\nA rendered clip is NOT usable anywhere until you keep it: `baker studio keep <id> --slot N` is what puts it in the video library. Takes nobody keeps are never ingested, which is what makes a rejected batch cheap.\n\nFor anything longer than 15 seconds, or to build on footage that already exists, use --model bytedance/seedance-2.5: it renders 4-30s and is the only model that reads an existing clip or an existing soundtrack.\n\nExamples:\n baker studio animate 'slow push in, model turns to camera and smiles' --image j57abc123def456ghi789\n baker studio animate 'she looks to camera and says: \"Hola, soy Elena\"' --avatar elena --quality 720p --aspect-ratio 9:16\n baker studio animate 'handheld drift right, steam rising from the cup' --image './out/hero.png' --duration 6 --quality 1080p\n baker studio animate 'product rotates once on a turntable' --image j57abc\u2026,j57def\u2026 --from references\n baker studio animate 'she keeps walking, camera stays with her, then she stops and looks up' --image j57abc\u2026 --from references --from-clip j57batch\u2026:0 --model bytedance/seedance-2.5 --duration 20\n baker studio animate 'hold on the product, then a slow push-in' --from references --from-video j57vid\u2026 --model bytedance/seedance-2.5\n baker studio animate 'slow drone pull-back over a solar farm at golden hour, no people' --from text --model bytedance/seedance-2.5 --duration 12"
|
|
@@ -68966,7 +69293,7 @@ var animateCommand = defineCommand216({
|
|
|
68966
69293
|
});
|
|
68967
69294
|
|
|
68968
69295
|
// src/commands/studio/generate.ts
|
|
68969
|
-
import { defineCommand as
|
|
69296
|
+
import { defineCommand as defineCommand218 } from "citty";
|
|
68970
69297
|
var MODEL_LIST2 = IMAGE_MODEL_IDS;
|
|
68971
69298
|
var DEFAULT_MAX_WAIT_MS2 = 24e4;
|
|
68972
69299
|
registerSchema({
|
|
@@ -69102,7 +69429,7 @@ function buildGenerateBody(args5, prompt) {
|
|
|
69102
69429
|
}
|
|
69103
69430
|
return body;
|
|
69104
69431
|
}
|
|
69105
|
-
var generateCommand =
|
|
69432
|
+
var generateCommand = defineCommand218({
|
|
69106
69433
|
meta: {
|
|
69107
69434
|
name: "generate",
|
|
69108
69435
|
description: "Start here to make an image. Renders 1-8 takes of one brief, ingests each into the media library as it lands, and shows the batch in the dashboard Studio next to the ones the client ran.\n\nModel choice: google/gemini-3.1-flash-image-preview (default \u2014 fast, best at editing a reference and at extreme ratios), google/gemini-3-pro-image-preview (highest fidelity, slower), openai/gpt-image-2 (photoreal and the cleanest in-image text \u2014 no --image-size, no 4:5 / 5:4), recraft/recraft-v4.1-pro-vector (vector/flat marks with palette control).\n\n--reference is the biggest quality lever there is: a real logo, product shot, Pinterest pin or sandbox screenshot beats any amount of adjectives.\n\nExamples:\n baker studio generate 'matte black bottle on wet marble, hard studio light, 35mm' --aspect-ratio 3:2 --count 3\n baker studio generate 'this bottle on a sunlit kitchen counter' --reference './src/brand/product.png,https://\u2026/kitchen.jpg'\n baker studio generate 'founder-style selfie, kitchen background, natural light' --skill ugc-selfie-hook\n baker studio generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
|
|
@@ -69185,7 +69512,7 @@ var generateCommand = defineCommand217({
|
|
|
69185
69512
|
});
|
|
69186
69513
|
|
|
69187
69514
|
// src/commands/studio/get.ts
|
|
69188
|
-
import { defineCommand as
|
|
69515
|
+
import { defineCommand as defineCommand219 } from "citty";
|
|
69189
69516
|
registerSchema({
|
|
69190
69517
|
command: "studio.get",
|
|
69191
69518
|
description: "Read one Studio batch: every take, where it lives, and why a take is missing. This is how you pick up a batch that was still rendering when the start command returned.",
|
|
@@ -69194,7 +69521,7 @@ registerSchema({
|
|
|
69194
69521
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
69195
69522
|
}
|
|
69196
69523
|
});
|
|
69197
|
-
var getCommand5 =
|
|
69524
|
+
var getCommand5 = defineCommand219({
|
|
69198
69525
|
meta: {
|
|
69199
69526
|
name: "get",
|
|
69200
69527
|
description: "Read one Studio batch \u2014 the takes, their urls, whether each is in the library, and the reason for any that failed.\n\nExample: baker studio get j57abc123def456ghi789\nExample: baker studio get j57abc123def456ghi789 --full"
|
|
@@ -69223,7 +69550,7 @@ var getCommand5 = defineCommand218({
|
|
|
69223
69550
|
});
|
|
69224
69551
|
|
|
69225
69552
|
// src/commands/studio/improve.ts
|
|
69226
|
-
import { defineCommand as
|
|
69553
|
+
import { defineCommand as defineCommand220 } from "citty";
|
|
69227
69554
|
var DESCRIPTION2 = "Sharpen a rough brief into directed art direction \u2014 the same rewrite the client gets from the wand in the Studio prompt bar. Reach for it when you are relaying the CLIENT's own words and want them shaped without substituting your voice; when you are writing the art direction yourself, just write it, because you will do a better job than this does.";
|
|
69228
69555
|
registerSchema({
|
|
69229
69556
|
command: "studio.improve",
|
|
@@ -69248,7 +69575,7 @@ registerSchema({
|
|
|
69248
69575
|
}
|
|
69249
69576
|
}
|
|
69250
69577
|
});
|
|
69251
|
-
var improveCommand =
|
|
69578
|
+
var improveCommand = defineCommand220({
|
|
69252
69579
|
meta: {
|
|
69253
69580
|
name: "improve",
|
|
69254
69581
|
description: `${DESCRIPTION2}
|
|
@@ -69292,7 +69619,7 @@ Examples:
|
|
|
69292
69619
|
});
|
|
69293
69620
|
|
|
69294
69621
|
// src/commands/studio/keep.ts
|
|
69295
|
-
import { defineCommand as
|
|
69622
|
+
import { defineCommand as defineCommand221 } from "citty";
|
|
69296
69623
|
registerSchema({
|
|
69297
69624
|
command: "studio.keep",
|
|
69298
69625
|
description: "Mark one take as the keeper. For an image this stars it, so the client reviewing the batch sees which one you used. For a CLIP it is the step that puts it in the video library \u2014 until then the clip cannot be used in a canvas, a landing, or an ad.",
|
|
@@ -69302,7 +69629,7 @@ registerSchema({
|
|
|
69302
69629
|
undo: { type: "boolean", description: "Un-star an image, or take a kept clip back out", required: false }
|
|
69303
69630
|
}
|
|
69304
69631
|
});
|
|
69305
|
-
var keepCommand =
|
|
69632
|
+
var keepCommand = defineCommand221({
|
|
69306
69633
|
meta: {
|
|
69307
69634
|
name: "keep",
|
|
69308
69635
|
description: "Mark one take as the keeper. An image gets starred (it was already in the library); a clip gets INGESTED into the video library, which is what makes it usable anywhere else.\n\nExample: baker studio keep j57abc123def456ghi789 --slot 2\nExample: baker studio keep j57abc123def456ghi789 --slot 2 --undo"
|
|
@@ -69353,7 +69680,7 @@ var keepCommand = defineCommand220({
|
|
|
69353
69680
|
});
|
|
69354
69681
|
|
|
69355
69682
|
// src/commands/studio/list.ts
|
|
69356
|
-
import { defineCommand as
|
|
69683
|
+
import { defineCommand as defineCommand222 } from "citty";
|
|
69357
69684
|
registerSchema({
|
|
69358
69685
|
command: "studio.list",
|
|
69359
69686
|
description: "Recent Studio batches for THIS conversation, newest first \u2014 what you have already generated, so you re-use a take instead of paying for it twice. `--all` widens it to everything the company generated, including what people ran themselves in the dashboard.",
|
|
@@ -69364,7 +69691,7 @@ registerSchema({
|
|
|
69364
69691
|
full: { type: "boolean", description: "Include settings, references and attribution", required: false }
|
|
69365
69692
|
}
|
|
69366
69693
|
});
|
|
69367
|
-
var listCommand18 =
|
|
69694
|
+
var listCommand18 = defineCommand222({
|
|
69368
69695
|
meta: {
|
|
69369
69696
|
name: "list",
|
|
69370
69697
|
description: "Recent Studio batches, newest first. Scoped to this conversation unless you pass --all.\n\nExample: baker studio list\nExample: baker studio list --kind video --limit 5\nExample: baker studio list --all # includes batches the client ran in the dashboard"
|
|
@@ -69398,7 +69725,7 @@ var listCommand18 = defineCommand221({
|
|
|
69398
69725
|
});
|
|
69399
69726
|
|
|
69400
69727
|
// src/commands/studio/models.ts
|
|
69401
|
-
import { defineCommand as
|
|
69728
|
+
import { defineCommand as defineCommand223 } from "citty";
|
|
69402
69729
|
var DESCRIPTION3 = "What each Studio model actually accepts: its shapes, resolutions, clip lengths, prompt character cap, how many reference images it takes, and which knobs it has. Read this before a batch you care about \u2014 the models disagree far more than they look like they do, and a setting the chosen model does not have is REFUSED, not ignored.";
|
|
69403
69730
|
registerSchema({
|
|
69404
69731
|
command: "studio.models",
|
|
@@ -69485,7 +69812,7 @@ function buildModelCards(kind, model) {
|
|
|
69485
69812
|
const selected = model ? ids.filter((id) => id === model) : ids;
|
|
69486
69813
|
return selected.map((id) => build(id));
|
|
69487
69814
|
}
|
|
69488
|
-
var modelsCommand =
|
|
69815
|
+
var modelsCommand = defineCommand223({
|
|
69489
69816
|
meta: {
|
|
69490
69817
|
name: "models",
|
|
69491
69818
|
description: `${DESCRIPTION3}
|
|
@@ -69532,13 +69859,13 @@ Examples:
|
|
|
69532
69859
|
});
|
|
69533
69860
|
|
|
69534
69861
|
// src/commands/studio/skills.ts
|
|
69535
|
-
import { defineCommand as
|
|
69862
|
+
import { defineCommand as defineCommand224 } from "citty";
|
|
69536
69863
|
registerSchema({
|
|
69537
69864
|
command: "studio.skills",
|
|
69538
69865
|
description: "The craft directions `studio generate --skill <id>` accepts. Each one carries directed art direction plus the model, shape and take count it wants, so you pick a look by name instead of writing the boilerplate yourself.",
|
|
69539
69866
|
args: {}
|
|
69540
69867
|
});
|
|
69541
|
-
var skillsCommand =
|
|
69868
|
+
var skillsCommand = defineCommand224({
|
|
69542
69869
|
meta: {
|
|
69543
69870
|
name: "skills",
|
|
69544
69871
|
description: "List the craft directions available to `baker studio generate --skill <id>` \u2014 what each one is for, whether it wants a reference image, and the model/shape/count it defaults to.\n\nExample: baker studio skills"
|
|
@@ -69562,7 +69889,7 @@ var skillsCommand = defineCommand223({
|
|
|
69562
69889
|
});
|
|
69563
69890
|
|
|
69564
69891
|
// src/commands/studio/index.ts
|
|
69565
|
-
var studioCommand =
|
|
69892
|
+
var studioCommand = defineCommand225({
|
|
69566
69893
|
meta: {
|
|
69567
69894
|
name: "studio",
|
|
69568
69895
|
description: `Make new imagery and clips. Every batch is recorded and shows up in the dashboard Studio for the client to review, labelled with this conversation.
|
|
@@ -69605,10 +69932,10 @@ Full guide: __tooling__/docs/tools/baker/studio.md`
|
|
|
69605
69932
|
});
|
|
69606
69933
|
|
|
69607
69934
|
// src/commands/tag-manager/index.ts
|
|
69608
|
-
import { defineCommand as
|
|
69935
|
+
import { defineCommand as defineCommand229 } from "citty";
|
|
69609
69936
|
|
|
69610
69937
|
// src/commands/tag-manager/draft.ts
|
|
69611
|
-
import { defineCommand as
|
|
69938
|
+
import { defineCommand as defineCommand226 } from "citty";
|
|
69612
69939
|
|
|
69613
69940
|
// src/commands/tag-manager/shared.ts
|
|
69614
69941
|
import { readFileSync as readFileSync20 } from "fs";
|
|
@@ -69731,13 +70058,13 @@ registerSchema({
|
|
|
69731
70058
|
chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
|
|
69732
70059
|
}
|
|
69733
70060
|
});
|
|
69734
|
-
var draftCommand6 =
|
|
70061
|
+
var draftCommand6 = defineCommand226({
|
|
69735
70062
|
meta: {
|
|
69736
70063
|
name: "draft",
|
|
69737
70064
|
description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
|
|
69738
70065
|
},
|
|
69739
70066
|
subCommands: {
|
|
69740
|
-
list:
|
|
70067
|
+
list: defineCommand226({
|
|
69741
70068
|
meta: {
|
|
69742
70069
|
name: "list",
|
|
69743
70070
|
description: "Review everything staged on this chat (--json for the raw envelope)"
|
|
@@ -69750,7 +70077,7 @@ var draftCommand6 = defineCommand225({
|
|
|
69750
70077
|
await draftList2(args5.json === true, args5.chat);
|
|
69751
70078
|
}
|
|
69752
70079
|
}),
|
|
69753
|
-
show:
|
|
70080
|
+
show: defineCommand226({
|
|
69754
70081
|
meta: {
|
|
69755
70082
|
name: "show",
|
|
69756
70083
|
description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
|
|
@@ -69767,7 +70094,7 @@ var draftCommand6 = defineCommand225({
|
|
|
69767
70094
|
);
|
|
69768
70095
|
}
|
|
69769
70096
|
}),
|
|
69770
|
-
amend:
|
|
70097
|
+
amend: defineCommand226({
|
|
69771
70098
|
meta: {
|
|
69772
70099
|
name: "amend",
|
|
69773
70100
|
description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-validates. Use this instead of remove + re-create."
|
|
@@ -69784,7 +70111,7 @@ var draftCommand6 = defineCommand225({
|
|
|
69784
70111
|
});
|
|
69785
70112
|
}
|
|
69786
70113
|
}),
|
|
69787
|
-
remove:
|
|
70114
|
+
remove: defineCommand226({
|
|
69788
70115
|
meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
|
|
69789
70116
|
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
69790
70117
|
run: async ({ args: args5 }) => {
|
|
@@ -69793,7 +70120,7 @@ var draftCommand6 = defineCommand225({
|
|
|
69793
70120
|
});
|
|
69794
70121
|
}
|
|
69795
70122
|
}),
|
|
69796
|
-
clear:
|
|
70123
|
+
clear: defineCommand226({
|
|
69797
70124
|
meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
|
|
69798
70125
|
run: async () => {
|
|
69799
70126
|
await draftAction3("/api/tag-manager/draft/clear", {});
|
|
@@ -69803,7 +70130,7 @@ var draftCommand6 = defineCommand225({
|
|
|
69803
70130
|
});
|
|
69804
70131
|
|
|
69805
70132
|
// src/commands/tag-manager/read.ts
|
|
69806
|
-
import { defineCommand as
|
|
70133
|
+
import { defineCommand as defineCommand227 } from "citty";
|
|
69807
70134
|
registerSchema({
|
|
69808
70135
|
command: "tagManager.containers",
|
|
69809
70136
|
description: "List the Google Tag Manager containers this company's connection can reach. Every container the company connected is flagged `connected: true` \u2014 there can be several, and Baker may read and change all of them. Start here to confirm which containers you are managing.",
|
|
@@ -69844,7 +70171,7 @@ function containersHints(containers) {
|
|
|
69844
70171
|
}))
|
|
69845
70172
|
});
|
|
69846
70173
|
}
|
|
69847
|
-
var containersCommand =
|
|
70174
|
+
var containersCommand = defineCommand227({
|
|
69848
70175
|
meta: {
|
|
69849
70176
|
name: "containers",
|
|
69850
70177
|
description: `List Tag Manager containers reachable by this company's connection.
|
|
@@ -69861,7 +70188,7 @@ Start here:
|
|
|
69861
70188
|
}
|
|
69862
70189
|
}
|
|
69863
70190
|
});
|
|
69864
|
-
var readCommand =
|
|
70191
|
+
var readCommand = defineCommand227({
|
|
69865
70192
|
meta: {
|
|
69866
70193
|
name: "read",
|
|
69867
70194
|
description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
|
|
@@ -69903,7 +70230,7 @@ Examples:
|
|
|
69903
70230
|
});
|
|
69904
70231
|
|
|
69905
70232
|
// src/commands/tag-manager/write-commands.ts
|
|
69906
|
-
import { defineCommand as
|
|
70233
|
+
import { defineCommand as defineCommand228 } from "citty";
|
|
69907
70234
|
var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
|
|
69908
70235
|
var ENTITIES = [
|
|
69909
70236
|
{
|
|
@@ -69959,10 +70286,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
|
|
|
69959
70286
|
});
|
|
69960
70287
|
}
|
|
69961
70288
|
function entityCommand(entity, noun, example) {
|
|
69962
|
-
return
|
|
70289
|
+
return defineCommand228({
|
|
69963
70290
|
meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
|
|
69964
70291
|
subCommands: {
|
|
69965
|
-
create:
|
|
70292
|
+
create: defineCommand228({
|
|
69966
70293
|
meta: {
|
|
69967
70294
|
name: "create",
|
|
69968
70295
|
description: `Stage a new ${noun}
|
|
@@ -69984,7 +70311,7 @@ Examples:
|
|
|
69984
70311
|
});
|
|
69985
70312
|
}
|
|
69986
70313
|
}),
|
|
69987
|
-
update:
|
|
70314
|
+
update: defineCommand228({
|
|
69988
70315
|
meta: {
|
|
69989
70316
|
name: "update",
|
|
69990
70317
|
description: `Stage an update to an existing ${noun} (pass its id or path)`
|
|
@@ -70004,7 +70331,7 @@ Examples:
|
|
|
70004
70331
|
});
|
|
70005
70332
|
}
|
|
70006
70333
|
}),
|
|
70007
|
-
delete:
|
|
70334
|
+
delete: defineCommand228({
|
|
70008
70335
|
meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
|
|
70009
70336
|
args: {
|
|
70010
70337
|
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
@@ -70045,7 +70372,7 @@ function builtinTypes(args5) {
|
|
|
70045
70372
|
}
|
|
70046
70373
|
return raw.split(",").map((entry) => entry.trim());
|
|
70047
70374
|
}
|
|
70048
|
-
var builtinCommand =
|
|
70375
|
+
var builtinCommand = defineCommand228({
|
|
70049
70376
|
meta: {
|
|
70050
70377
|
name: "builtin",
|
|
70051
70378
|
description: `Enable or disable built-in variables
|
|
@@ -70055,7 +70382,7 @@ Examples:
|
|
|
70055
70382
|
baker tag-manager builtin disable --types formId`
|
|
70056
70383
|
},
|
|
70057
70384
|
subCommands: {
|
|
70058
|
-
enable:
|
|
70385
|
+
enable: defineCommand228({
|
|
70059
70386
|
meta: { name: "enable", description: "Stage enabling built-in variables" },
|
|
70060
70387
|
args: {
|
|
70061
70388
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -70069,7 +70396,7 @@ Examples:
|
|
|
70069
70396
|
});
|
|
70070
70397
|
}
|
|
70071
70398
|
}),
|
|
70072
|
-
disable:
|
|
70399
|
+
disable: defineCommand228({
|
|
70073
70400
|
meta: { name: "disable", description: "Stage disabling built-in variables" },
|
|
70074
70401
|
args: {
|
|
70075
70402
|
types: { type: "string", description: "Comma-separated types", required: false },
|
|
@@ -70087,7 +70414,7 @@ Examples:
|
|
|
70087
70414
|
});
|
|
70088
70415
|
|
|
70089
70416
|
// src/commands/tag-manager/index.ts
|
|
70090
|
-
var tagManagerCommand =
|
|
70417
|
+
var tagManagerCommand = defineCommand229({
|
|
70091
70418
|
meta: {
|
|
70092
70419
|
name: "tag-manager",
|
|
70093
70420
|
description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
|
|
@@ -70124,7 +70451,7 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
|
|
|
70124
70451
|
});
|
|
70125
70452
|
|
|
70126
70453
|
// src/commands/tags/index.ts
|
|
70127
|
-
import { defineCommand as
|
|
70454
|
+
import { defineCommand as defineCommand230 } from "citty";
|
|
70128
70455
|
|
|
70129
70456
|
// src/commands/tags/shared.ts
|
|
70130
70457
|
function failApi3(err) {
|
|
@@ -70204,7 +70531,7 @@ async function listTags(json) {
|
|
|
70204
70531
|
var listArgs11 = {
|
|
70205
70532
|
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
|
|
70206
70533
|
};
|
|
70207
|
-
var listCommand19 =
|
|
70534
|
+
var listCommand19 = defineCommand230({
|
|
70208
70535
|
meta: {
|
|
70209
70536
|
name: "list",
|
|
70210
70537
|
description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
|
|
@@ -70223,7 +70550,7 @@ async function listDraft4(chat) {
|
|
|
70223
70550
|
failApi3(err);
|
|
70224
70551
|
}
|
|
70225
70552
|
}
|
|
70226
|
-
var draftCommand7 =
|
|
70553
|
+
var draftCommand7 = defineCommand230({
|
|
70227
70554
|
meta: {
|
|
70228
70555
|
name: "draft",
|
|
70229
70556
|
description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create). Takes --chat <id> to read an earlier chat's staged changes instead."
|
|
@@ -70233,7 +70560,7 @@ var draftCommand7 = defineCommand229({
|
|
|
70233
70560
|
await listDraft4(args5.chat);
|
|
70234
70561
|
}
|
|
70235
70562
|
});
|
|
70236
|
-
var tagsCommand4 =
|
|
70563
|
+
var tagsCommand4 = defineCommand230({
|
|
70237
70564
|
meta: {
|
|
70238
70565
|
name: "tags",
|
|
70239
70566
|
description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
|
|
@@ -70262,10 +70589,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
70262
70589
|
});
|
|
70263
70590
|
|
|
70264
70591
|
// src/commands/testimonials/index.ts
|
|
70265
|
-
import { defineCommand as
|
|
70592
|
+
import { defineCommand as defineCommand234 } from "citty";
|
|
70266
70593
|
|
|
70267
70594
|
// src/commands/testimonials/get.ts
|
|
70268
|
-
import { defineCommand as
|
|
70595
|
+
import { defineCommand as defineCommand231 } from "citty";
|
|
70269
70596
|
registerSchema({
|
|
70270
70597
|
command: "testimonials.get",
|
|
70271
70598
|
description: "Get a single testimonial by ID",
|
|
@@ -70273,7 +70600,7 @@ registerSchema({
|
|
|
70273
70600
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
70274
70601
|
}
|
|
70275
70602
|
});
|
|
70276
|
-
var getCommand6 =
|
|
70603
|
+
var getCommand6 = defineCommand231({
|
|
70277
70604
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
70278
70605
|
args: {
|
|
70279
70606
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -70310,7 +70637,7 @@ var getCommand6 = defineCommand230({
|
|
|
70310
70637
|
});
|
|
70311
70638
|
|
|
70312
70639
|
// src/commands/testimonials/list.ts
|
|
70313
|
-
import { defineCommand as
|
|
70640
|
+
import { defineCommand as defineCommand232 } from "citty";
|
|
70314
70641
|
|
|
70315
70642
|
// src/commands/testimonials/emptyCorpusHints.ts
|
|
70316
70643
|
function resolveEmptyReason({
|
|
@@ -70467,7 +70794,7 @@ function buildListParams(args5) {
|
|
|
70467
70794
|
}
|
|
70468
70795
|
return params2;
|
|
70469
70796
|
}
|
|
70470
|
-
var listCommand20 =
|
|
70797
|
+
var listCommand20 = defineCommand232({
|
|
70471
70798
|
meta: {
|
|
70472
70799
|
name: "list",
|
|
70473
70800
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -70527,7 +70854,7 @@ var listCommand20 = defineCommand231({
|
|
|
70527
70854
|
});
|
|
70528
70855
|
|
|
70529
70856
|
// src/commands/testimonials/search.ts
|
|
70530
|
-
import { defineCommand as
|
|
70857
|
+
import { defineCommand as defineCommand233 } from "citty";
|
|
70531
70858
|
var FILTER_FLAGS2 = ["source", "rating-min", "rating-max", "status", "sentiment", "language", "tags"];
|
|
70532
70859
|
function languageBiasHint(results, requestedLanguage) {
|
|
70533
70860
|
if (requestedLanguage) {
|
|
@@ -70606,7 +70933,7 @@ function buildSearchRequest(query, args5) {
|
|
|
70606
70933
|
}
|
|
70607
70934
|
return body;
|
|
70608
70935
|
}
|
|
70609
|
-
var searchCommand3 =
|
|
70936
|
+
var searchCommand3 = defineCommand233({
|
|
70610
70937
|
meta: {
|
|
70611
70938
|
name: "search",
|
|
70612
70939
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -70670,7 +70997,7 @@ var searchCommand3 = defineCommand232({
|
|
|
70670
70997
|
var tagsCommand5 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
70671
70998
|
|
|
70672
70999
|
// src/commands/testimonials/index.ts
|
|
70673
|
-
var testimonialsCommand =
|
|
71000
|
+
var testimonialsCommand = defineCommand234({
|
|
70674
71001
|
meta: {
|
|
70675
71002
|
name: "testimonials",
|
|
70676
71003
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -70692,10 +71019,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
|
|
|
70692
71019
|
});
|
|
70693
71020
|
|
|
70694
71021
|
// src/commands/videos/index.ts
|
|
70695
|
-
import { defineCommand as
|
|
71022
|
+
import { defineCommand as defineCommand242 } from "citty";
|
|
70696
71023
|
|
|
70697
71024
|
// src/commands/videos/delete.ts
|
|
70698
|
-
import { defineCommand as
|
|
71025
|
+
import { defineCommand as defineCommand235 } from "citty";
|
|
70699
71026
|
registerSchema({
|
|
70700
71027
|
command: "videos.delete",
|
|
70701
71028
|
description: "Delete a video by ID",
|
|
@@ -70709,7 +71036,7 @@ registerSchema({
|
|
|
70709
71036
|
}
|
|
70710
71037
|
}
|
|
70711
71038
|
});
|
|
70712
|
-
var deleteCommand4 =
|
|
71039
|
+
var deleteCommand4 = defineCommand235({
|
|
70713
71040
|
meta: {
|
|
70714
71041
|
name: "delete",
|
|
70715
71042
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -70750,7 +71077,7 @@ var deleteCommand4 = defineCommand234({
|
|
|
70750
71077
|
});
|
|
70751
71078
|
|
|
70752
71079
|
// src/commands/videos/describe.ts
|
|
70753
|
-
import { defineCommand as
|
|
71080
|
+
import { defineCommand as defineCommand236 } from "citty";
|
|
70754
71081
|
var DESCRIPTION_HELP2 = "What the clip actually shows, in the words someone would search for it by. This is what `baker videos search` retrieves on.";
|
|
70755
71082
|
registerSchema({
|
|
70756
71083
|
command: "videos.describe",
|
|
@@ -70767,7 +71094,7 @@ registerSchema({
|
|
|
70767
71094
|
full: { type: "boolean", description: "Return the whole library row, not just what changed", required: false }
|
|
70768
71095
|
}
|
|
70769
71096
|
});
|
|
70770
|
-
var describeCommand2 =
|
|
71097
|
+
var describeCommand2 = defineCommand236({
|
|
70771
71098
|
meta: {
|
|
70772
71099
|
name: "describe",
|
|
70773
71100
|
description: `Correct what the library says a video is. Only the fields you pass change; the rest keep their current values.
|
|
@@ -70825,7 +71152,7 @@ Example: baker videos describe j571abc123 --description "Customer explaining how
|
|
|
70825
71152
|
});
|
|
70826
71153
|
|
|
70827
71154
|
// src/commands/videos/get.ts
|
|
70828
|
-
import { defineCommand as
|
|
71155
|
+
import { defineCommand as defineCommand237 } from "citty";
|
|
70829
71156
|
registerSchema({
|
|
70830
71157
|
command: "videos.get",
|
|
70831
71158
|
description: "Get a single video by ID",
|
|
@@ -70833,7 +71160,7 @@ registerSchema({
|
|
|
70833
71160
|
id: { type: "string", description: "Video ID", required: true }
|
|
70834
71161
|
}
|
|
70835
71162
|
});
|
|
70836
|
-
var getCommand7 =
|
|
71163
|
+
var getCommand7 = defineCommand237({
|
|
70837
71164
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
70838
71165
|
args: {
|
|
70839
71166
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -70870,7 +71197,7 @@ var getCommand7 = defineCommand236({
|
|
|
70870
71197
|
});
|
|
70871
71198
|
|
|
70872
71199
|
// src/commands/videos/group.ts
|
|
70873
|
-
import { defineCommand as
|
|
71200
|
+
import { defineCommand as defineCommand238 } from "citty";
|
|
70874
71201
|
registerSchema({
|
|
70875
71202
|
command: "videos.group",
|
|
70876
71203
|
description: "List every clip and image that arrived in the same set as this video (carousel slides, one page)",
|
|
@@ -70879,7 +71206,7 @@ registerSchema({
|
|
|
70879
71206
|
"group-key": { type: "string", description: "The set key directly, when you already have it", required: false }
|
|
70880
71207
|
}
|
|
70881
71208
|
});
|
|
70882
|
-
var groupCommand2 =
|
|
71209
|
+
var groupCommand2 = defineCommand238({
|
|
70883
71210
|
meta: {
|
|
70884
71211
|
name: "group",
|
|
70885
71212
|
description: "List every asset that arrived in the same set as this clip \u2014 the other slides of the Instagram post it came from, stills included. A carousel is authored to be read in order, so a clip pulled out of one is usually missing half its meaning. Example: baker videos group <videoId>"
|
|
@@ -70902,7 +71229,7 @@ var groupCommand2 = defineCommand237({
|
|
|
70902
71229
|
import { mkdtemp as mkdtemp3, rm as rm9, stat as stat12 } from "fs/promises";
|
|
70903
71230
|
import { tmpdir as tmpdir4 } from "os";
|
|
70904
71231
|
import path48 from "path";
|
|
70905
|
-
import { defineCommand as
|
|
71232
|
+
import { defineCommand as defineCommand239 } from "citty";
|
|
70906
71233
|
|
|
70907
71234
|
// src/lib/streamUpload.ts
|
|
70908
71235
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -71066,7 +71393,7 @@ registerSchema({
|
|
|
71066
71393
|
"dry-run": { type: "boolean", description: "Preview the operation without executing", required: false }
|
|
71067
71394
|
}
|
|
71068
71395
|
});
|
|
71069
|
-
var ingestCommand2 =
|
|
71396
|
+
var ingestCommand2 = defineCommand239({
|
|
71070
71397
|
meta: {
|
|
71071
71398
|
name: "ingest",
|
|
71072
71399
|
description: "Add a video to the library from a URL. A direct file URL is handed straight to Baker, which fetches it. A page URL (YouTube, TikTok, Vimeo, Instagram) is downloaded here first, then uploaded \u2014 and a direct URL that Baker cannot fetch falls back to that same path automatically.\n\nExample: baker videos ingest https://www.youtube.com/watch?v=abc123"
|
|
@@ -71328,7 +71655,7 @@ async function uploadToAssetStore(filePath, sizeBytes) {
|
|
|
71328
71655
|
}
|
|
71329
71656
|
|
|
71330
71657
|
// src/commands/videos/search.ts
|
|
71331
|
-
import { defineCommand as
|
|
71658
|
+
import { defineCommand as defineCommand240 } from "citty";
|
|
71332
71659
|
registerSchema({
|
|
71333
71660
|
command: "videos.search",
|
|
71334
71661
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -71338,7 +71665,7 @@ registerSchema({
|
|
|
71338
71665
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
71339
71666
|
}
|
|
71340
71667
|
});
|
|
71341
|
-
var searchCommand4 =
|
|
71668
|
+
var searchCommand4 = defineCommand240({
|
|
71342
71669
|
meta: {
|
|
71343
71670
|
name: "search",
|
|
71344
71671
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -71390,7 +71717,7 @@ var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
71390
71717
|
// src/commands/videos/upload.ts
|
|
71391
71718
|
import { readFile as readFile34, stat as stat13 } from "fs/promises";
|
|
71392
71719
|
import { basename as basename3, extname as extname4 } from "path";
|
|
71393
|
-
import { defineCommand as
|
|
71720
|
+
import { defineCommand as defineCommand241 } from "citty";
|
|
71394
71721
|
var MIME_MAP = {
|
|
71395
71722
|
".mp4": "video/mp4",
|
|
71396
71723
|
".mov": "video/quicktime",
|
|
@@ -71432,7 +71759,7 @@ function detectContentType(filePath) {
|
|
|
71432
71759
|
function isRemoteUrl3(value) {
|
|
71433
71760
|
return /^https?:\/\//i.test(value);
|
|
71434
71761
|
}
|
|
71435
|
-
var uploadCommand2 =
|
|
71762
|
+
var uploadCommand2 = defineCommand241({
|
|
71436
71763
|
meta: {
|
|
71437
71764
|
name: "upload",
|
|
71438
71765
|
description: "Upload a video to Baker \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: auto-detects content type and uploads via Mux direct upload.\nRemote: hands off to `videos ingest` (direct fetch, or download-then-upload for a YouTube/TikTok/Vimeo page).\n\nExamples:\n baker videos upload ./demo.mp4\n baker videos upload https://www.youtube.com/watch?v=abc123"
|
|
@@ -71516,7 +71843,7 @@ var uploadCommand2 = defineCommand240({
|
|
|
71516
71843
|
});
|
|
71517
71844
|
|
|
71518
71845
|
// src/commands/videos/index.ts
|
|
71519
|
-
var videosCommand =
|
|
71846
|
+
var videosCommand = defineCommand242({
|
|
71520
71847
|
meta: {
|
|
71521
71848
|
name: "videos",
|
|
71522
71849
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, ingest, describe, delete, tags.
|
|
@@ -71545,10 +71872,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
71545
71872
|
});
|
|
71546
71873
|
|
|
71547
71874
|
// src/commands/winning-ads/index.ts
|
|
71548
|
-
import { defineCommand as
|
|
71875
|
+
import { defineCommand as defineCommand255 } from "citty";
|
|
71549
71876
|
|
|
71550
71877
|
// src/commands/winning-ads/advertisers.ts
|
|
71551
|
-
import { defineCommand as
|
|
71878
|
+
import { defineCommand as defineCommand243 } from "citty";
|
|
71552
71879
|
|
|
71553
71880
|
// src/commands/winning-ads/shared.ts
|
|
71554
71881
|
function splitList3(value) {
|
|
@@ -71601,7 +71928,7 @@ function advertiserNormalizer(record, full) {
|
|
|
71601
71928
|
last_synced_at: record.last_synced_at ?? null
|
|
71602
71929
|
};
|
|
71603
71930
|
}
|
|
71604
|
-
var advertisersCommand2 =
|
|
71931
|
+
var advertisersCommand2 = defineCommand243({
|
|
71605
71932
|
meta: {
|
|
71606
71933
|
name: "advertisers",
|
|
71607
71934
|
description: 'List corpus advertisers by name or domain. Find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id / winners. Example: baker winning-ads advertisers "Deel" --output md'
|
|
@@ -71659,7 +71986,7 @@ var advertisersCommand2 = defineCommand242({
|
|
|
71659
71986
|
});
|
|
71660
71987
|
|
|
71661
71988
|
// src/commands/winning-ads/brief.ts
|
|
71662
|
-
import { defineCommand as
|
|
71989
|
+
import { defineCommand as defineCommand244 } from "citty";
|
|
71663
71990
|
registerSchema({
|
|
71664
71991
|
command: "winning-ads.brief",
|
|
71665
71992
|
description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
|
|
@@ -71705,7 +72032,7 @@ function parseDna(raw) {
|
|
|
71705
72032
|
}
|
|
71706
72033
|
return parsed;
|
|
71707
72034
|
}
|
|
71708
|
-
var briefCommand =
|
|
72035
|
+
var briefCommand = defineCommand244({
|
|
71709
72036
|
meta: {
|
|
71710
72037
|
name: "brief",
|
|
71711
72038
|
description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
|
|
@@ -71741,7 +72068,7 @@ var briefCommand = defineCommand243({
|
|
|
71741
72068
|
});
|
|
71742
72069
|
|
|
71743
72070
|
// src/commands/winning-ads/content.ts
|
|
71744
|
-
import { defineCommand as
|
|
72071
|
+
import { defineCommand as defineCommand245 } from "citty";
|
|
71745
72072
|
registerSchema({
|
|
71746
72073
|
command: "winning-ads.content",
|
|
71747
72074
|
description: "Read what's INSIDE one winning ad: the spoken transcript, the on-screen text, and the ad copy. Use this after `search`/`winners`/`feed` return a shortlist \u2014 pass an ad_id to understand a reference before reproducing it. Add --full for speech, pacing, and soundtrack detail. Video ads carry the transcript/on-screen text; static ads carry only the copy.",
|
|
@@ -71754,7 +72081,7 @@ registerSchema({
|
|
|
71754
72081
|
}
|
|
71755
72082
|
}
|
|
71756
72083
|
});
|
|
71757
|
-
var contentCommand =
|
|
72084
|
+
var contentCommand = defineCommand245({
|
|
71758
72085
|
meta: {
|
|
71759
72086
|
name: "content",
|
|
71760
72087
|
description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
|
|
@@ -71803,7 +72130,7 @@ var contentCommand = defineCommand244({
|
|
|
71803
72130
|
});
|
|
71804
72131
|
|
|
71805
72132
|
// src/commands/winning-ads/feed.ts
|
|
71806
|
-
import { defineCommand as
|
|
72133
|
+
import { defineCommand as defineCommand246 } from "citty";
|
|
71807
72134
|
function buildFeedParams(input) {
|
|
71808
72135
|
const params2 = {};
|
|
71809
72136
|
const advertiser = splitList3(input.advertiser);
|
|
@@ -71855,7 +72182,7 @@ registerSchema({
|
|
|
71855
72182
|
format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
|
|
71856
72183
|
}
|
|
71857
72184
|
});
|
|
71858
|
-
var feedCommand2 =
|
|
72185
|
+
var feedCommand2 = defineCommand246({
|
|
71859
72186
|
meta: {
|
|
71860
72187
|
name: "feed",
|
|
71861
72188
|
description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
|
|
@@ -71940,7 +72267,7 @@ var feedCommand2 = defineCommand245({
|
|
|
71940
72267
|
});
|
|
71941
72268
|
|
|
71942
72269
|
// src/commands/winning-ads/follow.ts
|
|
71943
|
-
import { defineCommand as
|
|
72270
|
+
import { defineCommand as defineCommand247 } from "citty";
|
|
71944
72271
|
var PLATFORMS = adLibraryPlatformSchema.options;
|
|
71945
72272
|
registerSchema({
|
|
71946
72273
|
command: "winning-ads.follow",
|
|
@@ -71955,7 +72282,7 @@ registerSchema({
|
|
|
71955
72282
|
label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
|
|
71956
72283
|
}
|
|
71957
72284
|
});
|
|
71958
|
-
var followCommand =
|
|
72285
|
+
var followCommand = defineCommand247({
|
|
71959
72286
|
meta: {
|
|
71960
72287
|
name: "follow",
|
|
71961
72288
|
description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks every platform we can resolve. Example: baker winning-ads follow "deel.com" --platform meta'
|
|
@@ -72002,7 +72329,7 @@ var followCommand = defineCommand246({
|
|
|
72002
72329
|
});
|
|
72003
72330
|
|
|
72004
72331
|
// src/commands/winning-ads/follow-competitors.ts
|
|
72005
|
-
import { defineCommand as
|
|
72332
|
+
import { defineCommand as defineCommand248 } from "citty";
|
|
72006
72333
|
var PLATFORMS2 = adLibraryPlatformSchema.options;
|
|
72007
72334
|
var BATCH_TIMEOUT_MS = 3e5;
|
|
72008
72335
|
function buildFollowBatchBody(input) {
|
|
@@ -72035,7 +72362,7 @@ registerSchema({
|
|
|
72035
72362
|
}
|
|
72036
72363
|
}
|
|
72037
72364
|
});
|
|
72038
|
-
var followCompetitorsCommand =
|
|
72365
|
+
var followCompetitorsCommand = defineCommand248({
|
|
72039
72366
|
meta: {
|
|
72040
72367
|
name: "follow-competitors",
|
|
72041
72368
|
description: 'Follow many brands at once by domain \u2014 add every competitor in one call. Example: baker winning-ads follow-competitors "deel.com,notion.so,hubspot.com"'
|
|
@@ -72110,7 +72437,7 @@ var followCompetitorsCommand = defineCommand247({
|
|
|
72110
72437
|
});
|
|
72111
72438
|
|
|
72112
72439
|
// src/commands/winning-ads/following.ts
|
|
72113
|
-
import { defineCommand as
|
|
72440
|
+
import { defineCommand as defineCommand249 } from "citty";
|
|
72114
72441
|
registerSchema({
|
|
72115
72442
|
command: "winning-ads.following",
|
|
72116
72443
|
description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts. A brand still adding has counts that are a lie in progress; one with `discovery_failed` has counts that are short because we couldn't finish looking, which is not the same as it running no ads.",
|
|
@@ -72164,7 +72491,7 @@ function followingNormalizer(record, full) {
|
|
|
72164
72491
|
platforms: Array.isArray(record.platforms) ? record.platforms : []
|
|
72165
72492
|
};
|
|
72166
72493
|
}
|
|
72167
|
-
var followingCommand =
|
|
72494
|
+
var followingCommand = defineCommand249({
|
|
72168
72495
|
meta: {
|
|
72169
72496
|
name: "following",
|
|
72170
72497
|
description: "List brands you follow, with status (ready / adding\u2026) and cached counts. A brand's counts are only final once it is ready. Example: baker winning-ads following --output md"
|
|
@@ -72200,7 +72527,7 @@ var followingCommand = defineCommand248({
|
|
|
72200
72527
|
});
|
|
72201
72528
|
|
|
72202
72529
|
// src/commands/winning-ads/patterns.ts
|
|
72203
|
-
import { defineCommand as
|
|
72530
|
+
import { defineCommand as defineCommand250 } from "citty";
|
|
72204
72531
|
registerSchema({
|
|
72205
72532
|
command: "winning-ads.patterns",
|
|
72206
72533
|
description: "Mine what separates two cohorts of ads: pass a comma-list of winning ad ids (--winners) and a comma-list of weaker ad ids (--duds). Returns the discriminating DNA fields.",
|
|
@@ -72239,7 +72566,7 @@ function discriminatorRow(record) {
|
|
|
72239
72566
|
top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
|
|
72240
72567
|
};
|
|
72241
72568
|
}
|
|
72242
|
-
var patternsCommand =
|
|
72569
|
+
var patternsCommand = defineCommand250({
|
|
72243
72570
|
meta: {
|
|
72244
72571
|
name: "patterns",
|
|
72245
72572
|
description: "Discover what separates winning ads from weak ones. Example: baker winning-ads patterns --winners a_1,a_2,a_3 --duds a_9,a_8 --output md"
|
|
@@ -72295,7 +72622,7 @@ var patternsCommand = defineCommand249({
|
|
|
72295
72622
|
});
|
|
72296
72623
|
|
|
72297
72624
|
// src/commands/winning-ads/search.ts
|
|
72298
|
-
import { defineCommand as
|
|
72625
|
+
import { defineCommand as defineCommand251 } from "citty";
|
|
72299
72626
|
registerSchema({
|
|
72300
72627
|
command: "winning-ads.search",
|
|
72301
72628
|
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.",
|
|
@@ -72433,7 +72760,7 @@ function reportSearchError(err) {
|
|
|
72433
72760
|
}
|
|
72434
72761
|
reportError2(err);
|
|
72435
72762
|
}
|
|
72436
|
-
var searchCommand5 =
|
|
72763
|
+
var searchCommand5 = defineCommand251({
|
|
72437
72764
|
meta: {
|
|
72438
72765
|
name: "search",
|
|
72439
72766
|
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"
|
|
@@ -72553,7 +72880,7 @@ var searchCommand5 = defineCommand250({
|
|
|
72553
72880
|
});
|
|
72554
72881
|
|
|
72555
72882
|
// src/commands/winning-ads/seeds.ts
|
|
72556
|
-
import { defineCommand as
|
|
72883
|
+
import { defineCommand as defineCommand252 } from "citty";
|
|
72557
72884
|
function leanRow(r) {
|
|
72558
72885
|
return {
|
|
72559
72886
|
key: r.key,
|
|
@@ -72581,7 +72908,7 @@ function makeSeedCommand(opts) {
|
|
|
72581
72908
|
limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
|
|
72582
72909
|
}
|
|
72583
72910
|
});
|
|
72584
|
-
return
|
|
72911
|
+
return defineCommand252({
|
|
72585
72912
|
meta: { name: opts.name, description: opts.description },
|
|
72586
72913
|
args: {
|
|
72587
72914
|
platform: { type: "string", description: "Single platform to segment on", required: false },
|
|
@@ -72630,7 +72957,7 @@ var formatsCommand = makeSeedCommand({
|
|
|
72630
72957
|
});
|
|
72631
72958
|
|
|
72632
72959
|
// src/commands/winning-ads/unfollow.ts
|
|
72633
|
-
import { defineCommand as
|
|
72960
|
+
import { defineCommand as defineCommand253 } from "citty";
|
|
72634
72961
|
registerSchema({
|
|
72635
72962
|
command: "winning-ads.unfollow",
|
|
72636
72963
|
description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
|
|
@@ -72638,7 +72965,7 @@ registerSchema({
|
|
|
72638
72965
|
advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
|
|
72639
72966
|
}
|
|
72640
72967
|
});
|
|
72641
|
-
var unfollowCommand =
|
|
72968
|
+
var unfollowCommand = defineCommand253({
|
|
72642
72969
|
meta: {
|
|
72643
72970
|
name: "unfollow",
|
|
72644
72971
|
description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
|
|
@@ -72659,7 +72986,7 @@ var unfollowCommand = defineCommand252({
|
|
|
72659
72986
|
});
|
|
72660
72987
|
|
|
72661
72988
|
// src/commands/winning-ads/winners.ts
|
|
72662
|
-
import { defineCommand as
|
|
72989
|
+
import { defineCommand as defineCommand254 } from "citty";
|
|
72663
72990
|
registerSchema({
|
|
72664
72991
|
command: "winning-ads.winners",
|
|
72665
72992
|
description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
|
|
@@ -72669,7 +72996,7 @@ registerSchema({
|
|
|
72669
72996
|
platform: { type: "string", description: "Filter to a single platform: meta|linkedin|tiktok", required: false }
|
|
72670
72997
|
}
|
|
72671
72998
|
});
|
|
72672
|
-
var winnersCommand =
|
|
72999
|
+
var winnersCommand = defineCommand254({
|
|
72673
73000
|
meta: {
|
|
72674
73001
|
name: "winners",
|
|
72675
73002
|
description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
|
|
@@ -72719,7 +73046,7 @@ var winnersCommand = defineCommand253({
|
|
|
72719
73046
|
});
|
|
72720
73047
|
|
|
72721
73048
|
// src/commands/winning-ads/index.ts
|
|
72722
|
-
var winningAdsCommand =
|
|
73049
|
+
var winningAdsCommand = defineCommand255({
|
|
72723
73050
|
meta: {
|
|
72724
73051
|
name: "winning-ads",
|
|
72725
73052
|
description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce, and manage the brands your library tracks. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
|
|
@@ -72919,8 +73246,8 @@ function suggestFlag(unknown, command) {
|
|
|
72919
73246
|
const name = flag3.slice(2);
|
|
72920
73247
|
const def = args5[name] ?? args5[camel(name)];
|
|
72921
73248
|
const described = def && typeof def === "object" ? def.description : void 0;
|
|
72922
|
-
const
|
|
72923
|
-
return
|
|
73249
|
+
const description2 = typeof described === "string" ? described.split(/(?<!\b(?:e\.g|i\.e|vs))\.\s/)[0]?.trim().replace(/\.$/, "") : "";
|
|
73250
|
+
return description2 ? { flag: flag3, description: description2 } : { flag: flag3 };
|
|
72924
73251
|
}
|
|
72925
73252
|
function suggestionText(suggestion) {
|
|
72926
73253
|
if (!suggestion) {
|
|
@@ -73046,7 +73373,7 @@ function getCliVersion() {
|
|
|
73046
73373
|
}
|
|
73047
73374
|
|
|
73048
73375
|
// src/cli.ts
|
|
73049
|
-
var main =
|
|
73376
|
+
var main = defineCommand256({
|
|
73050
73377
|
meta: {
|
|
73051
73378
|
name: "baker",
|
|
73052
73379
|
version: getCliVersion(),
|