@koda-sl/baker-cli 0.105.0 → 0.106.0-dev.a605c0acb
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 +52 -1
- package/dist/{chunk-3JVYU72O.js → chunk-26K7V346.js} +4 -4
- package/dist/chunk-26K7V346.js.map +1 -0
- package/dist/cli.js +2431 -762
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3JVYU72O.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
defaultRegistry,
|
|
10
10
|
generateCatalog,
|
|
11
11
|
validateCanvasDeep
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-26K7V346.js";
|
|
13
13
|
|
|
14
14
|
// src/cli.ts
|
|
15
|
-
import { defineCommand as
|
|
15
|
+
import { defineCommand as defineCommand154, runMain } from "citty";
|
|
16
16
|
|
|
17
17
|
// src/commands/actions/index.ts
|
|
18
18
|
import { defineCommand as defineCommand18 } from "citty";
|
|
@@ -935,9 +935,553 @@ var actionsTagsCreateResponseSchema = okResponse(z2.object({ tagId: z2.string()
|
|
|
935
935
|
var actionsTagsDeleteRequestSchema = z2.object({ name: z2.string() });
|
|
936
936
|
var actionsTagsDeleteResponseSchema = okOnlySchema();
|
|
937
937
|
|
|
938
|
-
// ../api/src/
|
|
938
|
+
// ../api/src/ads-linkedin/limits.ts
|
|
939
|
+
var LINKEDIN_LIMITS = {
|
|
940
|
+
campaignGroup: {
|
|
941
|
+
nameMax: 100
|
|
942
|
+
},
|
|
943
|
+
campaign: {
|
|
944
|
+
nameMax: 255
|
|
945
|
+
},
|
|
946
|
+
creative: {
|
|
947
|
+
commentarySoftMax: 600,
|
|
948
|
+
// feed truncates with "…see more" beyond this
|
|
949
|
+
commentaryHardMax: 3e3,
|
|
950
|
+
headlineMax: 70,
|
|
951
|
+
descriptionMax: 300,
|
|
952
|
+
textAdHeadlineMax: 25,
|
|
953
|
+
textAdDescriptionMax: 75,
|
|
954
|
+
spotlightHeadlineMax: 70,
|
|
955
|
+
spotlightDescriptionMax: 70,
|
|
956
|
+
spotlightCtaMax: 18,
|
|
957
|
+
carouselCardHeadlineMax: 45,
|
|
958
|
+
carouselCardsMin: 2,
|
|
959
|
+
carouselCardsMax: 10,
|
|
960
|
+
conversationButtonLabelMax: 25
|
|
961
|
+
},
|
|
962
|
+
audience: {
|
|
963
|
+
nameMax: 100,
|
|
964
|
+
minRowsToServe: 300,
|
|
965
|
+
// LinkedIn refuses to serve smaller matched audiences
|
|
966
|
+
inlineRowsMax: 1e4,
|
|
967
|
+
// above this the list must come as a stored file ref
|
|
968
|
+
rowsMax: 3e5
|
|
969
|
+
},
|
|
970
|
+
conversion: {
|
|
971
|
+
nameMax: 255,
|
|
972
|
+
postClickWindows: [1, 7, 30, 90],
|
|
973
|
+
viewThroughWindows: [1, 7, 30]
|
|
974
|
+
},
|
|
975
|
+
leadForm: {
|
|
976
|
+
nameMax: 256,
|
|
977
|
+
headlineMax: 60,
|
|
978
|
+
descriptionMax: 160,
|
|
979
|
+
questionsMax: 12,
|
|
980
|
+
questionsSoftMax: 4,
|
|
981
|
+
// playbook: >4 fields tanks completion rate
|
|
982
|
+
customQuestionsMax: 3,
|
|
983
|
+
thankYouMessageMax: 300
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
var CAMPAIGN_TYPES = ["SPONSORED_UPDATES", "TEXT_AD", "SPONSORED_INMAILS", "DYNAMIC"];
|
|
987
|
+
var COST_TYPES = ["CPC", "CPM", "CPV"];
|
|
988
|
+
var OBJECTIVE_TYPES = [
|
|
989
|
+
"BRAND_AWARENESS",
|
|
990
|
+
"ENGAGEMENT",
|
|
991
|
+
"JOB_APPLICANT",
|
|
992
|
+
"LEAD_GENERATION",
|
|
993
|
+
"WEBSITE_CONVERSION",
|
|
994
|
+
"WEBSITE_VISIT",
|
|
995
|
+
"VIDEO_VIEW",
|
|
996
|
+
"TALENT_LEAD"
|
|
997
|
+
];
|
|
998
|
+
var OBJECTIVE_CAMPAIGN_TYPES = {
|
|
999
|
+
VIDEO_VIEW: ["SPONSORED_UPDATES"],
|
|
1000
|
+
LEAD_GENERATION: ["SPONSORED_UPDATES", "SPONSORED_INMAILS"],
|
|
1001
|
+
ENGAGEMENT: ["SPONSORED_UPDATES", "DYNAMIC"]
|
|
1002
|
+
};
|
|
1003
|
+
var STAGEABLE_CREATE_STATUSES = ["DRAFT", "ACTIVE", "PAUSED"];
|
|
1004
|
+
var CREATIVE_INTENDED_STATUSES = ["ACTIVE", "PAUSED", "DRAFT"];
|
|
1005
|
+
var CTA_TYPES = [
|
|
1006
|
+
"APPLY",
|
|
1007
|
+
"DOWNLOAD",
|
|
1008
|
+
"VIEW_QUOTE",
|
|
1009
|
+
"LEARN_MORE",
|
|
1010
|
+
"SIGN_UP",
|
|
1011
|
+
"SUBSCRIBE",
|
|
1012
|
+
"REGISTER",
|
|
1013
|
+
"JOIN",
|
|
1014
|
+
"ATTEND",
|
|
1015
|
+
"REQUEST_DEMO",
|
|
1016
|
+
"SEE_MORE"
|
|
1017
|
+
];
|
|
1018
|
+
var CREATIVE_SELECTIONS = ["OPTIMIZED", "ROUND_ROBIN"];
|
|
1019
|
+
var AUDIENCE_TYPES = ["company-list", "user-list", "retargeting", "engagement"];
|
|
1020
|
+
var CONVERSION_TYPES = [
|
|
1021
|
+
"ADD_TO_CART",
|
|
1022
|
+
"DOWNLOAD",
|
|
1023
|
+
"INSTALL",
|
|
1024
|
+
"KEY_PAGE_VIEW",
|
|
1025
|
+
"LEAD",
|
|
1026
|
+
"PURCHASE",
|
|
1027
|
+
"SIGN_UP",
|
|
1028
|
+
"OTHER"
|
|
1029
|
+
];
|
|
1030
|
+
var CONVERSION_METHODS = ["INSIGHT_TAG", "CONVERSIONS_API"];
|
|
1031
|
+
var ATTRIBUTION_TYPES = ["LAST_TOUCH_BY_CAMPAIGN", "LAST_TOUCH_BY_CONVERSION"];
|
|
1032
|
+
var CURRENCY_MINIMUMS = {
|
|
1033
|
+
USD: { dailyBudgetMin: 10, unitCostMin: 2 },
|
|
1034
|
+
EUR: { dailyBudgetMin: 10, unitCostMin: 2 },
|
|
1035
|
+
GBP: { dailyBudgetMin: 8, unitCostMin: 2 }
|
|
1036
|
+
};
|
|
1037
|
+
var DEFAULT_CURRENCY_MINIMUM = { dailyBudgetMin: 10, unitCostMin: 2 };
|
|
1038
|
+
var TEMP_REF_REGEX = /^li_temp_[A-Za-z0-9_-]{4,}$/;
|
|
1039
|
+
var NUMERIC_ID_REGEX = /^\d+$/;
|
|
1040
|
+
var URN_REGEX = /^urn:li:[a-zA-Z]+:.+$/;
|
|
1041
|
+
var IMAGE_URN_REGEX = /^urn:li:image:.+$/;
|
|
1042
|
+
var VIDEO_URN_REGEX = /^urn:li:video:.+$/;
|
|
1043
|
+
var DOCUMENT_URN_REGEX = /^urn:li:document:.+$/;
|
|
1044
|
+
var POST_URN_REGEX = /^urn:li:(share|ugcPost):\d+$/;
|
|
1045
|
+
var ORGANIZATION_URN_REGEX = /^urn:li:organization:\d+$/;
|
|
1046
|
+
var TARGETING_FACET_URN_REGEX = /^urn:li:adTargetingFacet:[a-zA-Z]+$/;
|
|
1047
|
+
|
|
1048
|
+
// ../api/src/ads-linkedin/ops.ts
|
|
939
1049
|
import { z as z3 } from "zod";
|
|
940
|
-
var
|
|
1050
|
+
var tempRefSchema = z3.string().regex(TEMP_REF_REGEX, "expected a li_temp_* reference");
|
|
1051
|
+
var parentRefSchema = z3.union([
|
|
1052
|
+
z3.string().regex(URN_REGEX, "expected a urn:li:* value"),
|
|
1053
|
+
z3.string().regex(NUMERIC_ID_REGEX, "expected a numeric id"),
|
|
1054
|
+
tempRefSchema
|
|
1055
|
+
]);
|
|
1056
|
+
var moneySchema = z3.object({
|
|
1057
|
+
amount: z3.string().regex(/^\d+(\.\d{1,2})?$/, "expected a decimal amount like 50 or 50.00").refine((val) => Number(val) > 0, "amount must be greater than zero"),
|
|
1058
|
+
currencyCode: z3.string().length(3)
|
|
1059
|
+
});
|
|
1060
|
+
var runScheduleSchema = z3.object({
|
|
1061
|
+
start: z3.number().int().positive(),
|
|
1062
|
+
end: z3.number().int().positive().optional()
|
|
1063
|
+
}).refine((s) => s.end === void 0 || s.end > s.start, {
|
|
1064
|
+
message: "runSchedule.end must be after runSchedule.start",
|
|
1065
|
+
path: ["end"]
|
|
1066
|
+
});
|
|
1067
|
+
var facetValuesSchema = z3.array(z3.union([z3.string().regex(URN_REGEX), tempRefSchema])).min(1);
|
|
1068
|
+
var targetingCriteriaSchema = z3.object({
|
|
1069
|
+
include: z3.object({
|
|
1070
|
+
and: z3.array(
|
|
1071
|
+
z3.object({
|
|
1072
|
+
or: z3.record(z3.string().regex(TARGETING_FACET_URN_REGEX, "invalid targeting facet URN"), facetValuesSchema)
|
|
1073
|
+
})
|
|
1074
|
+
).min(1, "targeting needs at least one include facet group")
|
|
1075
|
+
}),
|
|
1076
|
+
exclude: z3.object({
|
|
1077
|
+
or: z3.record(z3.string().regex(TARGETING_FACET_URN_REGEX, "invalid targeting facet URN"), facetValuesSchema)
|
|
1078
|
+
}).optional()
|
|
1079
|
+
});
|
|
1080
|
+
var stageableStatusSchema = z3.enum(STAGEABLE_CREATE_STATUSES);
|
|
1081
|
+
var entityStatusSchema = z3.enum(["ACTIVE", "PAUSED", "ARCHIVED", "CANCELED", "DRAFT", "COMPLETED"]);
|
|
1082
|
+
function currencyMinimums(currencyCode) {
|
|
1083
|
+
return CURRENCY_MINIMUMS[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM;
|
|
1084
|
+
}
|
|
1085
|
+
var campaignGroupCreateSchema = z3.object({
|
|
1086
|
+
name: z3.string().min(1).max(LINKEDIN_LIMITS.campaignGroup.nameMax),
|
|
1087
|
+
runSchedule: runScheduleSchema,
|
|
1088
|
+
totalBudget: moneySchema.optional(),
|
|
1089
|
+
status: stageableStatusSchema.default("DRAFT")
|
|
1090
|
+
});
|
|
1091
|
+
var campaignGroupUpdateSchema = z3.object({
|
|
1092
|
+
name: z3.string().min(1).max(LINKEDIN_LIMITS.campaignGroup.nameMax).optional(),
|
|
1093
|
+
runSchedule: runScheduleSchema.optional(),
|
|
1094
|
+
totalBudget: moneySchema.optional(),
|
|
1095
|
+
status: entityStatusSchema.optional()
|
|
1096
|
+
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
1097
|
+
var campaignFields = {
|
|
1098
|
+
name: z3.string().min(1).max(LINKEDIN_LIMITS.campaign.nameMax),
|
|
1099
|
+
campaignGroup: parentRefSchema,
|
|
1100
|
+
type: z3.enum(CAMPAIGN_TYPES),
|
|
1101
|
+
objectiveType: z3.enum(OBJECTIVE_TYPES).optional(),
|
|
1102
|
+
costType: z3.enum(COST_TYPES),
|
|
1103
|
+
unitCost: moneySchema.optional(),
|
|
1104
|
+
dailyBudget: moneySchema.optional(),
|
|
1105
|
+
totalBudget: moneySchema.optional(),
|
|
1106
|
+
runSchedule: runScheduleSchema.optional(),
|
|
1107
|
+
locale: z3.object({ country: z3.string().length(2), language: z3.string().length(2) }),
|
|
1108
|
+
targetingCriteria: targetingCriteriaSchema,
|
|
1109
|
+
audienceExpansionEnabled: z3.boolean().default(false),
|
|
1110
|
+
offsiteDeliveryEnabled: z3.boolean().default(false),
|
|
1111
|
+
connectedTelevisionOnly: z3.boolean().default(false),
|
|
1112
|
+
creativeSelection: z3.enum(CREATIVE_SELECTIONS).optional(),
|
|
1113
|
+
associatedEntity: z3.string().regex(ORGANIZATION_URN_REGEX).optional(),
|
|
1114
|
+
status: stageableStatusSchema.default("DRAFT")
|
|
1115
|
+
};
|
|
1116
|
+
function validateCampaignBudgets(p, ctx, { requireBudget }) {
|
|
1117
|
+
if (requireBudget && !p.dailyBudget && !p.totalBudget) {
|
|
1118
|
+
ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set dailyBudget and/or totalBudget" });
|
|
1119
|
+
}
|
|
1120
|
+
if (p.totalBudget && !p.dailyBudget && !p.runSchedule?.end) {
|
|
1121
|
+
ctx.addIssue({
|
|
1122
|
+
code: "custom",
|
|
1123
|
+
path: ["runSchedule", "end"],
|
|
1124
|
+
message: "totalBudget-only campaigns need runSchedule.end"
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
if (p.dailyBudget) {
|
|
1128
|
+
const min = currencyMinimums(p.dailyBudget.currencyCode).dailyBudgetMin;
|
|
1129
|
+
if (Number(p.dailyBudget.amount) < min) {
|
|
1130
|
+
ctx.addIssue({
|
|
1131
|
+
code: "custom",
|
|
1132
|
+
path: ["dailyBudget", "amount"],
|
|
1133
|
+
message: `dailyBudget below the ${min} ${p.dailyBudget.currencyCode} minimum`
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
if (p.unitCost) {
|
|
1138
|
+
const min = currencyMinimums(p.unitCost.currencyCode).unitCostMin;
|
|
1139
|
+
if (Number(p.unitCost.amount) < min) {
|
|
1140
|
+
ctx.addIssue({
|
|
1141
|
+
code: "custom",
|
|
1142
|
+
path: ["unitCost", "amount"],
|
|
1143
|
+
message: `unitCost below the ${min} ${p.unitCost.currencyCode} minimum bid`
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
var campaignCreateSchema = z3.object(campaignFields).superRefine((p, ctx) => {
|
|
1149
|
+
validateCampaignBudgets(p, ctx, { requireBudget: true });
|
|
1150
|
+
const allowedTypes = p.objectiveType ? OBJECTIVE_CAMPAIGN_TYPES[p.objectiveType] : void 0;
|
|
1151
|
+
if (allowedTypes && !allowedTypes.includes(p.type)) {
|
|
1152
|
+
ctx.addIssue({
|
|
1153
|
+
code: "custom",
|
|
1154
|
+
path: ["type"],
|
|
1155
|
+
message: `objective ${p.objectiveType} only supports campaign types ${allowedTypes.join(", ")}`
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
var campaignUpdateSchema = z3.object({
|
|
1160
|
+
name: campaignFields.name.optional(),
|
|
1161
|
+
objectiveType: campaignFields.objectiveType,
|
|
1162
|
+
unitCost: moneySchema.optional(),
|
|
1163
|
+
dailyBudget: moneySchema.optional(),
|
|
1164
|
+
totalBudget: moneySchema.optional(),
|
|
1165
|
+
runSchedule: runScheduleSchema.optional(),
|
|
1166
|
+
targetingCriteria: targetingCriteriaSchema.optional(),
|
|
1167
|
+
audienceExpansionEnabled: z3.boolean().optional(),
|
|
1168
|
+
offsiteDeliveryEnabled: z3.boolean().optional(),
|
|
1169
|
+
connectedTelevisionOnly: z3.boolean().optional(),
|
|
1170
|
+
creativeSelection: z3.enum(CREATIVE_SELECTIONS).optional(),
|
|
1171
|
+
status: entityStatusSchema.optional()
|
|
1172
|
+
}).superRefine((p, ctx) => {
|
|
1173
|
+
if (!Object.values(p).some((val) => val !== void 0)) {
|
|
1174
|
+
ctx.addIssue({ code: "custom", message: "update needs at least one field" });
|
|
1175
|
+
}
|
|
1176
|
+
validateCampaignBudgets(p, ctx, { requireBudget: false });
|
|
1177
|
+
});
|
|
1178
|
+
var commentarySchema = z3.string().min(1).max(LINKEDIN_LIMITS.creative.commentaryHardMax);
|
|
1179
|
+
var headlineSchema = z3.string().min(1).max(LINKEDIN_LIMITS.creative.headlineMax);
|
|
1180
|
+
var httpsUrlSchema = z3.string().url().refine((u) => u.startsWith("https://"), "landing pages must be https");
|
|
1181
|
+
var bakerMediaIdSchema = z3.string().min(1);
|
|
1182
|
+
var imageCreativeSchema = z3.object({
|
|
1183
|
+
format: z3.literal("image"),
|
|
1184
|
+
commentary: commentarySchema,
|
|
1185
|
+
imageId: bakerMediaIdSchema.optional(),
|
|
1186
|
+
imageUrn: z3.string().regex(IMAGE_URN_REGEX).optional(),
|
|
1187
|
+
headline: headlineSchema,
|
|
1188
|
+
landingUrl: httpsUrlSchema,
|
|
1189
|
+
cta: z3.enum(CTA_TYPES).optional(),
|
|
1190
|
+
mediaTitle: z3.string().max(200).optional()
|
|
1191
|
+
}).refine((p) => p.imageId ? !p.imageUrn : Boolean(p.imageUrn), {
|
|
1192
|
+
message: "provide exactly one of imageId (Baker library) or imageUrn (already on LinkedIn)",
|
|
1193
|
+
path: ["imageId"]
|
|
1194
|
+
});
|
|
1195
|
+
var videoCreativeSchema = z3.object({
|
|
1196
|
+
format: z3.literal("video"),
|
|
1197
|
+
commentary: commentarySchema,
|
|
1198
|
+
videoId: bakerMediaIdSchema.optional(),
|
|
1199
|
+
videoUrn: z3.string().regex(VIDEO_URN_REGEX).optional(),
|
|
1200
|
+
headline: headlineSchema,
|
|
1201
|
+
landingUrl: httpsUrlSchema.optional(),
|
|
1202
|
+
cta: z3.enum(CTA_TYPES).optional(),
|
|
1203
|
+
mediaTitle: z3.string().max(200).optional()
|
|
1204
|
+
}).refine((p) => p.videoId ? !p.videoUrn : Boolean(p.videoUrn), {
|
|
1205
|
+
message: "provide exactly one of videoId (Baker library) or videoUrn (already on LinkedIn)",
|
|
1206
|
+
path: ["videoId"]
|
|
1207
|
+
});
|
|
1208
|
+
var textCreativeSchema = z3.object({
|
|
1209
|
+
format: z3.literal("text"),
|
|
1210
|
+
headline: z3.string().min(1).max(LINKEDIN_LIMITS.creative.textAdHeadlineMax),
|
|
1211
|
+
description: z3.string().min(1).max(LINKEDIN_LIMITS.creative.textAdDescriptionMax),
|
|
1212
|
+
landingUrl: httpsUrlSchema,
|
|
1213
|
+
imageId: bakerMediaIdSchema.optional(),
|
|
1214
|
+
imageUrn: z3.string().regex(IMAGE_URN_REGEX).optional()
|
|
1215
|
+
});
|
|
1216
|
+
var spotlightCreativeSchema = z3.object({
|
|
1217
|
+
format: z3.literal("spotlight"),
|
|
1218
|
+
headline: z3.string().min(1).max(LINKEDIN_LIMITS.creative.spotlightHeadlineMax),
|
|
1219
|
+
description: z3.string().min(1).max(LINKEDIN_LIMITS.creative.spotlightDescriptionMax),
|
|
1220
|
+
landingUrl: httpsUrlSchema,
|
|
1221
|
+
ctaLabel: z3.string().min(1).max(LINKEDIN_LIMITS.creative.spotlightCtaMax),
|
|
1222
|
+
logoImageId: bakerMediaIdSchema.optional(),
|
|
1223
|
+
logoUrn: z3.string().regex(IMAGE_URN_REGEX).optional(),
|
|
1224
|
+
showMemberProfilePhoto: z3.boolean().default(true)
|
|
1225
|
+
});
|
|
1226
|
+
var followerCreativeSchema = z3.object({
|
|
1227
|
+
format: z3.literal("follower"),
|
|
1228
|
+
headline: z3.string().max(LINKEDIN_LIMITS.creative.spotlightHeadlineMax).optional(),
|
|
1229
|
+
description: z3.string().max(LINKEDIN_LIMITS.creative.spotlightDescriptionMax).optional(),
|
|
1230
|
+
logoImageId: bakerMediaIdSchema.optional(),
|
|
1231
|
+
logoUrn: z3.string().regex(IMAGE_URN_REGEX).optional()
|
|
1232
|
+
});
|
|
1233
|
+
var documentCreativeSchema = z3.object({
|
|
1234
|
+
format: z3.literal("document"),
|
|
1235
|
+
commentary: commentarySchema,
|
|
1236
|
+
documentTitle: z3.string().min(1).max(200),
|
|
1237
|
+
documentUrn: z3.string().regex(DOCUMENT_URN_REGEX).optional(),
|
|
1238
|
+
documentId: bakerMediaIdSchema.optional()
|
|
1239
|
+
}).refine((p) => p.documentId ? !p.documentUrn : Boolean(p.documentUrn), {
|
|
1240
|
+
message: "provide exactly one of documentId or documentUrn",
|
|
1241
|
+
path: ["documentId"]
|
|
1242
|
+
});
|
|
1243
|
+
var carouselCreativeSchema = z3.object({
|
|
1244
|
+
format: z3.literal("carousel"),
|
|
1245
|
+
commentary: commentarySchema,
|
|
1246
|
+
cards: z3.array(
|
|
1247
|
+
z3.object({
|
|
1248
|
+
imageId: bakerMediaIdSchema.optional(),
|
|
1249
|
+
imageUrn: z3.string().regex(IMAGE_URN_REGEX).optional(),
|
|
1250
|
+
headline: z3.string().min(1).max(LINKEDIN_LIMITS.creative.carouselCardHeadlineMax),
|
|
1251
|
+
landingUrl: httpsUrlSchema
|
|
1252
|
+
}).refine((card) => card.imageId ? !card.imageUrn : Boolean(card.imageUrn), {
|
|
1253
|
+
message: "each card needs exactly one of imageId or imageUrn",
|
|
1254
|
+
path: ["imageId"]
|
|
1255
|
+
})
|
|
1256
|
+
).min(LINKEDIN_LIMITS.creative.carouselCardsMin).max(LINKEDIN_LIMITS.creative.carouselCardsMax)
|
|
1257
|
+
});
|
|
1258
|
+
var conversationCreativeSchema = z3.object({
|
|
1259
|
+
format: z3.literal("conversation"),
|
|
1260
|
+
name: z3.string().max(255).optional(),
|
|
1261
|
+
raw: z3.record(z3.string(), z3.unknown())
|
|
1262
|
+
});
|
|
1263
|
+
var tlaCreativeSchema = z3.object({
|
|
1264
|
+
format: z3.literal("tla"),
|
|
1265
|
+
postUrn: z3.string().regex(POST_URN_REGEX, "expected urn:li:share:* or urn:li:ugcPost:*")
|
|
1266
|
+
});
|
|
1267
|
+
var jobsCreativeSchema = z3.object({
|
|
1268
|
+
format: z3.literal("jobs"),
|
|
1269
|
+
organizationName: z3.string().min(1).max(200),
|
|
1270
|
+
logoImageId: bakerMediaIdSchema.optional(),
|
|
1271
|
+
logoUrn: z3.string().regex(IMAGE_URN_REGEX).optional(),
|
|
1272
|
+
headlinePreset: z3.string().min(1),
|
|
1273
|
+
buttonLabelPreset: z3.string().min(1)
|
|
1274
|
+
});
|
|
1275
|
+
var creativeContentSchema = z3.discriminatedUnion("format", [
|
|
1276
|
+
imageCreativeSchema,
|
|
1277
|
+
videoCreativeSchema,
|
|
1278
|
+
textCreativeSchema,
|
|
1279
|
+
spotlightCreativeSchema,
|
|
1280
|
+
followerCreativeSchema,
|
|
1281
|
+
documentCreativeSchema,
|
|
1282
|
+
carouselCreativeSchema,
|
|
1283
|
+
conversationCreativeSchema,
|
|
1284
|
+
tlaCreativeSchema,
|
|
1285
|
+
jobsCreativeSchema
|
|
1286
|
+
]);
|
|
1287
|
+
var creativeCreateSchema = z3.object({
|
|
1288
|
+
campaign: parentRefSchema,
|
|
1289
|
+
intendedStatus: z3.enum(CREATIVE_INTENDED_STATUSES).default("DRAFT"),
|
|
1290
|
+
content: creativeContentSchema
|
|
1291
|
+
});
|
|
1292
|
+
var creativeUpdateSchema = z3.object({
|
|
1293
|
+
intendedStatus: z3.enum(["ACTIVE", "PAUSED", "ARCHIVED", "DRAFT"]).optional(),
|
|
1294
|
+
name: z3.string().max(255).optional(),
|
|
1295
|
+
headline: headlineSchema.optional(),
|
|
1296
|
+
landingUrl: httpsUrlSchema.optional(),
|
|
1297
|
+
cta: z3.enum(CTA_TYPES).optional()
|
|
1298
|
+
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
1299
|
+
var listRowSchema = z3.record(z3.string(), z3.string());
|
|
1300
|
+
var audienceCreateSchema = z3.object({
|
|
1301
|
+
name: z3.string().min(1).max(LINKEDIN_LIMITS.audience.nameMax),
|
|
1302
|
+
audienceType: z3.enum(AUDIENCE_TYPES),
|
|
1303
|
+
listColumns: z3.array(z3.string().min(1)).optional(),
|
|
1304
|
+
listRows: z3.array(listRowSchema).max(LINKEDIN_LIMITS.audience.inlineRowsMax).optional(),
|
|
1305
|
+
/** Baker file reference (R2) for lists too large to inline. */
|
|
1306
|
+
sourceFileRef: z3.string().optional(),
|
|
1307
|
+
/** Retargeting/engagement source config — structural passthrough, file-first. */
|
|
1308
|
+
raw: z3.record(z3.string(), z3.unknown()).optional()
|
|
1309
|
+
}).superRefine((p, ctx) => {
|
|
1310
|
+
const isList = p.audienceType === "company-list" || p.audienceType === "user-list";
|
|
1311
|
+
if (isList && !p.listRows?.length && !p.sourceFileRef) {
|
|
1312
|
+
ctx.addIssue({
|
|
1313
|
+
code: "custom",
|
|
1314
|
+
path: ["listRows"],
|
|
1315
|
+
message: "list audiences need listRows (or sourceFileRef for large files)"
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
if (!isList && !p.raw) {
|
|
1319
|
+
ctx.addIssue({
|
|
1320
|
+
code: "custom",
|
|
1321
|
+
path: ["raw"],
|
|
1322
|
+
message: `${p.audienceType} audiences need a raw source config (use --file)`
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
var audienceUploadListSchema = z3.object({
|
|
1327
|
+
segment: parentRefSchema,
|
|
1328
|
+
listColumns: z3.array(z3.string().min(1)).optional(),
|
|
1329
|
+
listRows: z3.array(listRowSchema).max(LINKEDIN_LIMITS.audience.inlineRowsMax).optional(),
|
|
1330
|
+
sourceFileRef: z3.string().optional()
|
|
1331
|
+
}).refine((p) => Boolean(p.listRows?.length) || Boolean(p.sourceFileRef), {
|
|
1332
|
+
message: "upload needs listRows (or sourceFileRef for large files)",
|
|
1333
|
+
path: ["listRows"]
|
|
1334
|
+
});
|
|
1335
|
+
var postClickWindowSchema = z3.number().refine(
|
|
1336
|
+
(val) => LINKEDIN_LIMITS.conversion.postClickWindows.includes(val),
|
|
1337
|
+
`postClickAttributionWindowSize must be one of ${LINKEDIN_LIMITS.conversion.postClickWindows.join(", ")}`
|
|
1338
|
+
);
|
|
1339
|
+
var viewThroughWindowSchema = z3.number().refine(
|
|
1340
|
+
(val) => LINKEDIN_LIMITS.conversion.viewThroughWindows.includes(val),
|
|
1341
|
+
`viewThroughAttributionWindowSize must be one of ${LINKEDIN_LIMITS.conversion.viewThroughWindows.join(", ")}`
|
|
1342
|
+
);
|
|
1343
|
+
var conversionCreateSchema = z3.object({
|
|
1344
|
+
name: z3.string().min(1).max(LINKEDIN_LIMITS.conversion.nameMax),
|
|
1345
|
+
type: z3.enum(CONVERSION_TYPES),
|
|
1346
|
+
conversionMethod: z3.enum(CONVERSION_METHODS),
|
|
1347
|
+
postClickAttributionWindowSize: postClickWindowSchema.optional(),
|
|
1348
|
+
viewThroughAttributionWindowSize: viewThroughWindowSchema.optional(),
|
|
1349
|
+
attributionType: z3.enum(ATTRIBUTION_TYPES).optional(),
|
|
1350
|
+
/** Insight-tag URL match rules — passthrough validated by LinkedIn. */
|
|
1351
|
+
urlMatchRuleExpression: z3.array(z3.array(z3.record(z3.string(), z3.string()))).optional(),
|
|
1352
|
+
associateAllCampaigns: z3.boolean().optional()
|
|
1353
|
+
});
|
|
1354
|
+
var conversionUpdateSchema = z3.object({
|
|
1355
|
+
name: conversionCreateSchema.shape.name.optional(),
|
|
1356
|
+
postClickAttributionWindowSize: postClickWindowSchema.optional(),
|
|
1357
|
+
viewThroughAttributionWindowSize: viewThroughWindowSchema.optional(),
|
|
1358
|
+
attributionType: z3.enum(ATTRIBUTION_TYPES).optional(),
|
|
1359
|
+
enabled: z3.boolean().optional()
|
|
1360
|
+
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
1361
|
+
var leadFormCreateSchema = z3.object({
|
|
1362
|
+
name: z3.string().min(1).max(LINKEDIN_LIMITS.leadForm.nameMax),
|
|
1363
|
+
headline: z3.string().min(1).max(LINKEDIN_LIMITS.leadForm.headlineMax),
|
|
1364
|
+
description: z3.string().max(LINKEDIN_LIMITS.leadForm.descriptionMax).optional(),
|
|
1365
|
+
privacyPolicyUrl: httpsUrlSchema,
|
|
1366
|
+
questions: z3.array(z3.object({ name: z3.string().min(1), predefinedField: z3.string().optional() })).min(1).max(LINKEDIN_LIMITS.leadForm.questionsMax),
|
|
1367
|
+
thankYou: z3.object({
|
|
1368
|
+
message: z3.string().max(LINKEDIN_LIMITS.leadForm.thankYouMessageMax).optional(),
|
|
1369
|
+
landingUrl: httpsUrlSchema.optional()
|
|
1370
|
+
}).optional(),
|
|
1371
|
+
legalDisclaimer: z3.string().optional(),
|
|
1372
|
+
raw: z3.record(z3.string(), z3.unknown()).optional()
|
|
1373
|
+
});
|
|
1374
|
+
var leadFormUpdateSchema = z3.object({
|
|
1375
|
+
name: leadFormCreateSchema.shape.name.optional(),
|
|
1376
|
+
raw: z3.record(z3.string(), z3.unknown()).optional()
|
|
1377
|
+
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
1378
|
+
var LINKEDIN_DRAFT_OP_KINDS = [
|
|
1379
|
+
"campaignGroup.create",
|
|
1380
|
+
"campaignGroup.update",
|
|
1381
|
+
"campaign.create",
|
|
1382
|
+
"campaign.update",
|
|
1383
|
+
"creative.create",
|
|
1384
|
+
"creative.update",
|
|
1385
|
+
"audience.create",
|
|
1386
|
+
"audience.uploadList",
|
|
1387
|
+
"conversion.create",
|
|
1388
|
+
"conversion.update",
|
|
1389
|
+
"leadForm.create",
|
|
1390
|
+
"leadForm.update"
|
|
1391
|
+
];
|
|
1392
|
+
var linkedinDraftOpKindSchema = z3.enum(LINKEDIN_DRAFT_OP_KINDS);
|
|
1393
|
+
var accountIdSchema = z3.string().regex(NUMERIC_ID_REGEX, "accountId must be the bare numeric ad account id");
|
|
1394
|
+
var updateTargetSchema = z3.union([z3.string().regex(URN_REGEX), z3.string().regex(NUMERIC_ID_REGEX)]);
|
|
1395
|
+
function createOp(kind, payload) {
|
|
1396
|
+
return z3.object({ kind: z3.literal(kind), accountId: accountIdSchema, payload });
|
|
1397
|
+
}
|
|
1398
|
+
function updateOp(kind, payload) {
|
|
1399
|
+
return z3.object({ kind: z3.literal(kind), accountId: accountIdSchema, target: updateTargetSchema, payload });
|
|
1400
|
+
}
|
|
1401
|
+
var linkedinDraftOpInputSchema = z3.discriminatedUnion("kind", [
|
|
1402
|
+
createOp("campaignGroup.create", campaignGroupCreateSchema),
|
|
1403
|
+
updateOp("campaignGroup.update", campaignGroupUpdateSchema),
|
|
1404
|
+
createOp("campaign.create", campaignCreateSchema),
|
|
1405
|
+
updateOp("campaign.update", campaignUpdateSchema),
|
|
1406
|
+
createOp("creative.create", creativeCreateSchema),
|
|
1407
|
+
updateOp("creative.update", creativeUpdateSchema),
|
|
1408
|
+
createOp("audience.create", audienceCreateSchema),
|
|
1409
|
+
createOp("audience.uploadList", audienceUploadListSchema),
|
|
1410
|
+
createOp("conversion.create", conversionCreateSchema),
|
|
1411
|
+
updateOp("conversion.update", conversionUpdateSchema),
|
|
1412
|
+
createOp("leadForm.create", leadFormCreateSchema),
|
|
1413
|
+
updateOp("leadForm.update", leadFormUpdateSchema)
|
|
1414
|
+
]);
|
|
1415
|
+
|
|
1416
|
+
// ../api/src/ads-linkedin/wire.ts
|
|
1417
|
+
import { z as z4 } from "zod";
|
|
1418
|
+
var linkedinWriteModeSchema = z4.enum(["live", "simulated"]);
|
|
1419
|
+
var linkedinDraftOpResultSchema = z4.object({
|
|
1420
|
+
status: z4.enum(["applied", "simulated", "failed", "skipped"]),
|
|
1421
|
+
urn: z4.string().optional(),
|
|
1422
|
+
error: z4.string().optional(),
|
|
1423
|
+
skippedBecause: z4.string().optional(),
|
|
1424
|
+
executedAt: z4.number().optional()
|
|
1425
|
+
});
|
|
1426
|
+
var linkedinDraftStageRequestSchema = z4.object({
|
|
1427
|
+
chatId: z4.string(),
|
|
1428
|
+
op: linkedinDraftOpInputSchema
|
|
1429
|
+
});
|
|
1430
|
+
var linkedinDraftStageResponseSchema = z4.object({
|
|
1431
|
+
staged: z4.literal(true),
|
|
1432
|
+
ref: z4.string(),
|
|
1433
|
+
kind: linkedinDraftOpKindSchema,
|
|
1434
|
+
mode: linkedinWriteModeSchema,
|
|
1435
|
+
dependsOn: z4.array(z4.string()),
|
|
1436
|
+
summary: z4.string(),
|
|
1437
|
+
warnings: z4.array(z4.string())
|
|
1438
|
+
});
|
|
1439
|
+
var linkedinDraftOpViewSchema = z4.object({
|
|
1440
|
+
ref: z4.string(),
|
|
1441
|
+
kind: linkedinDraftOpKindSchema,
|
|
1442
|
+
accountId: z4.string(),
|
|
1443
|
+
target: z4.string().optional(),
|
|
1444
|
+
dependsOn: z4.array(z4.string()),
|
|
1445
|
+
summary: z4.string(),
|
|
1446
|
+
stagedAt: z4.number(),
|
|
1447
|
+
result: linkedinDraftOpResultSchema.optional()
|
|
1448
|
+
});
|
|
1449
|
+
var linkedinDraftListRequestSchema = z4.object({
|
|
1450
|
+
chatId: z4.string()
|
|
1451
|
+
});
|
|
1452
|
+
var linkedinDraftListResponseSchema = z4.object({
|
|
1453
|
+
status: z4.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
1454
|
+
mode: linkedinWriteModeSchema,
|
|
1455
|
+
count: z4.number(),
|
|
1456
|
+
ops: z4.array(linkedinDraftOpViewSchema)
|
|
1457
|
+
});
|
|
1458
|
+
var linkedinDraftRemoveRequestSchema = z4.object({
|
|
1459
|
+
chatId: z4.string(),
|
|
1460
|
+
ref: z4.string()
|
|
1461
|
+
});
|
|
1462
|
+
var linkedinDraftRemoveResponseSchema = z4.object({
|
|
1463
|
+
/** The requested ref plus any dependents removed by cascade. */
|
|
1464
|
+
removed: z4.array(z4.string())
|
|
1465
|
+
});
|
|
1466
|
+
var linkedinDraftClearRequestSchema = z4.object({
|
|
1467
|
+
chatId: z4.string()
|
|
1468
|
+
});
|
|
1469
|
+
var linkedinDraftClearResponseSchema = z4.object({
|
|
1470
|
+
cleared: z4.number()
|
|
1471
|
+
});
|
|
1472
|
+
var linkedinFieldErrorSchema = z4.object({
|
|
1473
|
+
path: z4.string(),
|
|
1474
|
+
message: z4.string()
|
|
1475
|
+
});
|
|
1476
|
+
var linkedinDraftErrorResponseSchema = z4.object({
|
|
1477
|
+
code: z4.string(),
|
|
1478
|
+
error: z4.string(),
|
|
1479
|
+
fields: z4.array(linkedinFieldErrorSchema).optional()
|
|
1480
|
+
});
|
|
1481
|
+
|
|
1482
|
+
// ../api/src/images.ts
|
|
1483
|
+
import { z as z5 } from "zod";
|
|
1484
|
+
var imageSourceSchema = z5.enum([
|
|
941
1485
|
"uploaded",
|
|
942
1486
|
"website",
|
|
943
1487
|
"google_testimonial",
|
|
@@ -953,49 +1497,49 @@ var imageSourceSchema = z3.enum([
|
|
|
953
1497
|
"pinterest",
|
|
954
1498
|
"ai_generated"
|
|
955
1499
|
]);
|
|
956
|
-
var imageStatusSchema =
|
|
957
|
-
var upscaleConfigSchema =
|
|
958
|
-
model:
|
|
959
|
-
input:
|
|
960
|
-
scale_factor:
|
|
961
|
-
creativity:
|
|
962
|
-
output_format:
|
|
1500
|
+
var imageStatusSchema = z5.enum(["uploading", "processing", "ready", "error"]);
|
|
1501
|
+
var upscaleConfigSchema = z5.object({
|
|
1502
|
+
model: z5.literal("philz1337x/crystal-upscaler"),
|
|
1503
|
+
input: z5.object({
|
|
1504
|
+
scale_factor: z5.number(),
|
|
1505
|
+
creativity: z5.number(),
|
|
1506
|
+
output_format: z5.string()
|
|
963
1507
|
}),
|
|
964
|
-
status:
|
|
1508
|
+
status: z5.enum(["pending", "completed"])
|
|
965
1509
|
});
|
|
966
|
-
var imageDocSchema =
|
|
967
|
-
_id:
|
|
968
|
-
_creationTime:
|
|
969
|
-
companyId:
|
|
970
|
-
storageKey:
|
|
1510
|
+
var imageDocSchema = z5.object({
|
|
1511
|
+
_id: z5.string(),
|
|
1512
|
+
_creationTime: z5.number(),
|
|
1513
|
+
companyId: z5.string(),
|
|
1514
|
+
storageKey: z5.string(),
|
|
971
1515
|
upscaleConfig: upscaleConfigSchema.optional(),
|
|
972
|
-
upscaledStorageKey:
|
|
973
|
-
name:
|
|
974
|
-
description:
|
|
975
|
-
tags:
|
|
976
|
-
source:
|
|
977
|
-
externalId:
|
|
978
|
-
externalUrl:
|
|
979
|
-
contentHash:
|
|
980
|
-
sourceId:
|
|
981
|
-
descriptionContext:
|
|
982
|
-
width:
|
|
983
|
-
height:
|
|
984
|
-
aspectRatio:
|
|
985
|
-
dominantColor:
|
|
986
|
-
imagePalette:
|
|
987
|
-
thumbhashDataUri:
|
|
988
|
-
isLightImage:
|
|
989
|
-
descriptionEmbedding:
|
|
990
|
-
imageEmbedding:
|
|
991
|
-
searchText:
|
|
1516
|
+
upscaledStorageKey: z5.string().optional(),
|
|
1517
|
+
name: z5.string(),
|
|
1518
|
+
description: z5.string(),
|
|
1519
|
+
tags: z5.array(z5.string()),
|
|
1520
|
+
source: z5.string(),
|
|
1521
|
+
externalId: z5.string().optional(),
|
|
1522
|
+
externalUrl: z5.string().optional(),
|
|
1523
|
+
contentHash: z5.string().optional(),
|
|
1524
|
+
sourceId: z5.string().optional(),
|
|
1525
|
+
descriptionContext: z5.string().optional(),
|
|
1526
|
+
width: z5.number().optional(),
|
|
1527
|
+
height: z5.number().optional(),
|
|
1528
|
+
aspectRatio: z5.number().optional(),
|
|
1529
|
+
dominantColor: z5.string().optional(),
|
|
1530
|
+
imagePalette: z5.array(z5.string()).optional(),
|
|
1531
|
+
thumbhashDataUri: z5.string().optional(),
|
|
1532
|
+
isLightImage: z5.boolean().optional(),
|
|
1533
|
+
descriptionEmbedding: z5.array(z5.number()).optional(),
|
|
1534
|
+
imageEmbedding: z5.array(z5.number()).optional(),
|
|
1535
|
+
searchText: z5.string().optional(),
|
|
992
1536
|
status: imageStatusSchema,
|
|
993
|
-
errorMessage:
|
|
994
|
-
createdAt:
|
|
995
|
-
updatedAt:
|
|
996
|
-
imageUrl:
|
|
1537
|
+
errorMessage: z5.string().optional(),
|
|
1538
|
+
createdAt: z5.number(),
|
|
1539
|
+
updatedAt: z5.number(),
|
|
1540
|
+
imageUrl: z5.string()
|
|
997
1541
|
});
|
|
998
|
-
var imageHitSourceSchema =
|
|
1542
|
+
var imageHitSourceSchema = z5.enum([
|
|
999
1543
|
"library",
|
|
1000
1544
|
"magnific",
|
|
1001
1545
|
"google_images",
|
|
@@ -1006,374 +1550,374 @@ var imageHitSourceSchema = z3.enum([
|
|
|
1006
1550
|
"giphy",
|
|
1007
1551
|
"pinterest"
|
|
1008
1552
|
]);
|
|
1009
|
-
var imageHitSchema =
|
|
1553
|
+
var imageHitSchema = z5.object({
|
|
1010
1554
|
source: imageHitSourceSchema,
|
|
1011
|
-
url:
|
|
1012
|
-
thumbnailUrl:
|
|
1013
|
-
width:
|
|
1014
|
-
height:
|
|
1015
|
-
aspectRatio:
|
|
1016
|
-
dominantColor:
|
|
1017
|
-
externalId:
|
|
1018
|
-
externalUrl:
|
|
1019
|
-
providerMeta:
|
|
1020
|
-
descriptionContext:
|
|
1021
|
-
_id:
|
|
1022
|
-
name:
|
|
1023
|
-
description:
|
|
1024
|
-
tags:
|
|
1025
|
-
score:
|
|
1026
|
-
alsoInLibrary:
|
|
1027
|
-
prefetchedBytes:
|
|
1028
|
-
prefetchedContentType:
|
|
1555
|
+
url: z5.string(),
|
|
1556
|
+
thumbnailUrl: z5.string().optional(),
|
|
1557
|
+
width: z5.number().optional(),
|
|
1558
|
+
height: z5.number().optional(),
|
|
1559
|
+
aspectRatio: z5.number().optional(),
|
|
1560
|
+
dominantColor: z5.string().optional(),
|
|
1561
|
+
externalId: z5.string().optional(),
|
|
1562
|
+
externalUrl: z5.string().optional(),
|
|
1563
|
+
providerMeta: z5.record(z5.string(), z5.unknown()).optional(),
|
|
1564
|
+
descriptionContext: z5.string().optional(),
|
|
1565
|
+
_id: z5.string().optional(),
|
|
1566
|
+
name: z5.string().optional(),
|
|
1567
|
+
description: z5.string().optional(),
|
|
1568
|
+
tags: z5.array(z5.string()).optional(),
|
|
1569
|
+
score: z5.number().optional(),
|
|
1570
|
+
alsoInLibrary: z5.string().optional(),
|
|
1571
|
+
prefetchedBytes: z5.string().optional(),
|
|
1572
|
+
prefetchedContentType: z5.string().optional()
|
|
1029
1573
|
});
|
|
1030
1574
|
var ingestedImageHitSchema = imageHitSchema.extend({
|
|
1031
|
-
imageId:
|
|
1032
|
-
imageUrl:
|
|
1033
|
-
deduped:
|
|
1034
|
-
sourceUrl:
|
|
1035
|
-
});
|
|
1036
|
-
var autoIngestItemSchema =
|
|
1037
|
-
imageId:
|
|
1038
|
-
deduped:
|
|
1039
|
-
imageUrl:
|
|
1040
|
-
sourceUrl:
|
|
1041
|
-
externalUrl:
|
|
1575
|
+
imageId: z5.string().optional(),
|
|
1576
|
+
imageUrl: z5.string().optional(),
|
|
1577
|
+
deduped: z5.boolean().optional(),
|
|
1578
|
+
sourceUrl: z5.string().optional()
|
|
1579
|
+
});
|
|
1580
|
+
var autoIngestItemSchema = z5.object({
|
|
1581
|
+
imageId: z5.string(),
|
|
1582
|
+
deduped: z5.boolean(),
|
|
1583
|
+
imageUrl: z5.string(),
|
|
1584
|
+
sourceUrl: z5.string(),
|
|
1585
|
+
externalUrl: z5.string().optional()
|
|
1042
1586
|
});
|
|
1043
1587
|
function providerHitsResponseSchema() {
|
|
1044
|
-
return
|
|
1045
|
-
hits:
|
|
1046
|
-
ingested:
|
|
1588
|
+
return z5.object({
|
|
1589
|
+
hits: z5.array(ingestedImageHitSchema),
|
|
1590
|
+
ingested: z5.array(autoIngestItemSchema)
|
|
1047
1591
|
});
|
|
1048
1592
|
}
|
|
1049
|
-
var imagesGetRequestSchema =
|
|
1050
|
-
var imagesSearchRequestSchema =
|
|
1051
|
-
query:
|
|
1052
|
-
limit:
|
|
1053
|
-
aspectRatio:
|
|
1054
|
-
tags:
|
|
1055
|
-
source:
|
|
1056
|
-
externalUrlHost:
|
|
1057
|
-
});
|
|
1058
|
-
var imageSearchResultSchema =
|
|
1059
|
-
_id:
|
|
1060
|
-
imageUrl:
|
|
1061
|
-
name:
|
|
1062
|
-
description:
|
|
1063
|
-
tags:
|
|
1064
|
-
width:
|
|
1065
|
-
height:
|
|
1066
|
-
aspectRatio:
|
|
1067
|
-
dominantColor:
|
|
1068
|
-
imagePalette:
|
|
1069
|
-
source:
|
|
1070
|
-
externalUrl:
|
|
1071
|
-
score:
|
|
1072
|
-
});
|
|
1073
|
-
var imagesSearchResponseSchema =
|
|
1074
|
-
var imagesUploadRequestSchema =
|
|
1075
|
-
base64:
|
|
1076
|
-
contentType:
|
|
1077
|
-
source:
|
|
1078
|
-
descriptionContext:
|
|
1079
|
-
});
|
|
1080
|
-
var imagesUploadResponseSchema =
|
|
1081
|
-
var imagesDeleteRequestSchema =
|
|
1082
|
-
var imagesDeleteResponseSchema =
|
|
1083
|
-
var imagesUpscaleRequestSchema =
|
|
1084
|
-
var imagesUpscaleResponseSchema =
|
|
1085
|
-
imageId:
|
|
1086
|
-
status:
|
|
1593
|
+
var imagesGetRequestSchema = z5.object({ id: z5.string().min(1, "Missing id parameter") });
|
|
1594
|
+
var imagesSearchRequestSchema = z5.object({
|
|
1595
|
+
query: z5.string().min(1),
|
|
1596
|
+
limit: z5.coerce.number().int().positive().max(100).optional(),
|
|
1597
|
+
aspectRatio: z5.string().optional(),
|
|
1598
|
+
tags: z5.array(z5.string()).optional(),
|
|
1599
|
+
source: z5.string().optional(),
|
|
1600
|
+
externalUrlHost: z5.string().optional()
|
|
1601
|
+
});
|
|
1602
|
+
var imageSearchResultSchema = z5.object({
|
|
1603
|
+
_id: z5.string(),
|
|
1604
|
+
imageUrl: z5.string(),
|
|
1605
|
+
name: z5.string(),
|
|
1606
|
+
description: z5.string(),
|
|
1607
|
+
tags: z5.array(z5.string()),
|
|
1608
|
+
width: z5.number().optional(),
|
|
1609
|
+
height: z5.number().optional(),
|
|
1610
|
+
aspectRatio: z5.number().optional(),
|
|
1611
|
+
dominantColor: z5.string().optional(),
|
|
1612
|
+
imagePalette: z5.array(z5.string()).optional(),
|
|
1613
|
+
source: z5.string(),
|
|
1614
|
+
externalUrl: z5.string().optional(),
|
|
1615
|
+
score: z5.number()
|
|
1616
|
+
});
|
|
1617
|
+
var imagesSearchResponseSchema = z5.array(imageSearchResultSchema);
|
|
1618
|
+
var imagesUploadRequestSchema = z5.object({
|
|
1619
|
+
base64: z5.string().min(1),
|
|
1620
|
+
contentType: z5.string().min(1),
|
|
1621
|
+
source: z5.string().optional(),
|
|
1622
|
+
descriptionContext: z5.string().optional()
|
|
1623
|
+
});
|
|
1624
|
+
var imagesUploadResponseSchema = z5.object({ imageId: z5.string() });
|
|
1625
|
+
var imagesDeleteRequestSchema = z5.object({ id: z5.string().min(1, "Missing image ID") });
|
|
1626
|
+
var imagesDeleteResponseSchema = z5.object({ ok: z5.literal(true) });
|
|
1627
|
+
var imagesUpscaleRequestSchema = z5.object({ imageId: z5.string().min(1, "Missing image ID") });
|
|
1628
|
+
var imagesUpscaleResponseSchema = z5.object({
|
|
1629
|
+
imageId: z5.string(),
|
|
1630
|
+
status: z5.literal("processing")
|
|
1087
1631
|
});
|
|
1088
1632
|
var IMAGES_FIND_SOURCES = ["library", "magnific", "google", "iconify", "giphy", "pinterest"];
|
|
1089
|
-
var imagesFindRequestSchema =
|
|
1090
|
-
query:
|
|
1091
|
-
sources:
|
|
1092
|
-
limit:
|
|
1093
|
-
fallback:
|
|
1094
|
-
threshold:
|
|
1095
|
-
autoIngest:
|
|
1096
|
-
descriptionContext:
|
|
1097
|
-
});
|
|
1098
|
-
var imagesFindResponseSchema =
|
|
1099
|
-
groups:
|
|
1100
|
-
library:
|
|
1101
|
-
external:
|
|
1633
|
+
var imagesFindRequestSchema = z5.object({
|
|
1634
|
+
query: z5.string().min(1),
|
|
1635
|
+
sources: z5.array(z5.enum(IMAGES_FIND_SOURCES)).optional(),
|
|
1636
|
+
limit: z5.coerce.number().int().positive().max(50).optional(),
|
|
1637
|
+
fallback: z5.boolean().optional(),
|
|
1638
|
+
threshold: z5.number().min(0).max(1).optional(),
|
|
1639
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1640
|
+
descriptionContext: z5.string().optional()
|
|
1641
|
+
});
|
|
1642
|
+
var imagesFindResponseSchema = z5.object({
|
|
1643
|
+
groups: z5.object({
|
|
1644
|
+
library: z5.array(imageHitSchema),
|
|
1645
|
+
external: z5.array(ingestedImageHitSchema)
|
|
1102
1646
|
}),
|
|
1103
|
-
meta:
|
|
1104
|
-
counts:
|
|
1105
|
-
errors:
|
|
1647
|
+
meta: z5.object({
|
|
1648
|
+
counts: z5.record(z5.string(), z5.number()),
|
|
1649
|
+
errors: z5.array(z5.object({ source: imageHitSourceSchema, message: z5.string() }))
|
|
1106
1650
|
}),
|
|
1107
|
-
ingested:
|
|
1108
|
-
});
|
|
1109
|
-
var imagesStockRequestSchema =
|
|
1110
|
-
query:
|
|
1111
|
-
orientation:
|
|
1112
|
-
contentType:
|
|
1113
|
-
license:
|
|
1114
|
-
color:
|
|
1115
|
-
aiGenerated:
|
|
1116
|
-
people:
|
|
1117
|
-
order:
|
|
1118
|
-
limit:
|
|
1119
|
-
page:
|
|
1120
|
-
autoIngest:
|
|
1121
|
-
descriptionContext:
|
|
1651
|
+
ingested: z5.array(autoIngestItemSchema)
|
|
1652
|
+
});
|
|
1653
|
+
var imagesStockRequestSchema = z5.object({
|
|
1654
|
+
query: z5.string().min(1),
|
|
1655
|
+
orientation: z5.enum(["landscape", "portrait", "square", "panoramic"]).optional(),
|
|
1656
|
+
contentType: z5.enum(["photo", "vector", "psd"]).optional(),
|
|
1657
|
+
license: z5.enum(["freemium", "premium"]).optional(),
|
|
1658
|
+
color: z5.string().optional(),
|
|
1659
|
+
aiGenerated: z5.enum(["exclude", "only"]).optional(),
|
|
1660
|
+
people: z5.enum(["include", "exclude", "only"]).optional(),
|
|
1661
|
+
order: z5.enum(["relevance", "recent"]).optional(),
|
|
1662
|
+
limit: z5.coerce.number().int().positive().max(50).optional(),
|
|
1663
|
+
page: z5.coerce.number().int().positive().optional(),
|
|
1664
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1665
|
+
descriptionContext: z5.string().optional()
|
|
1122
1666
|
});
|
|
1123
1667
|
var imagesStockResponseSchema = providerHitsResponseSchema();
|
|
1124
|
-
var imagesGoogleRequestSchema =
|
|
1125
|
-
query:
|
|
1126
|
-
type:
|
|
1127
|
-
size:
|
|
1128
|
-
color:
|
|
1129
|
-
safe:
|
|
1130
|
-
limit:
|
|
1131
|
-
autoIngest:
|
|
1132
|
-
descriptionContext:
|
|
1668
|
+
var imagesGoogleRequestSchema = z5.object({
|
|
1669
|
+
query: z5.string().min(1),
|
|
1670
|
+
type: z5.string().optional(),
|
|
1671
|
+
size: z5.string().optional(),
|
|
1672
|
+
color: z5.string().optional(),
|
|
1673
|
+
safe: z5.enum(["off", "active"]).optional(),
|
|
1674
|
+
limit: z5.coerce.number().int().positive().max(50).optional(),
|
|
1675
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1676
|
+
descriptionContext: z5.string().optional()
|
|
1133
1677
|
});
|
|
1134
1678
|
var imagesGoogleResponseSchema = providerHitsResponseSchema();
|
|
1135
|
-
var imagesPinterestRequestSchema =
|
|
1136
|
-
query:
|
|
1137
|
-
limit:
|
|
1138
|
-
autoIngest:
|
|
1139
|
-
descriptionContext:
|
|
1679
|
+
var imagesPinterestRequestSchema = z5.object({
|
|
1680
|
+
query: z5.string().min(1),
|
|
1681
|
+
limit: z5.coerce.number().int().positive().max(20).optional(),
|
|
1682
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1683
|
+
descriptionContext: z5.string().optional()
|
|
1140
1684
|
});
|
|
1141
1685
|
var imagesPinterestResponseSchema = providerHitsResponseSchema();
|
|
1142
|
-
var rgbTriple =
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1686
|
+
var rgbTriple = z5.tuple([
|
|
1687
|
+
z5.number().int().min(0).max(255),
|
|
1688
|
+
z5.number().int().min(0).max(255),
|
|
1689
|
+
z5.number().int().min(0).max(255)
|
|
1146
1690
|
]);
|
|
1147
|
-
var imageGenerateModelSchema =
|
|
1691
|
+
var imageGenerateModelSchema = z5.enum([
|
|
1148
1692
|
"openai/gpt-5.4-image-2",
|
|
1149
1693
|
"google/gemini-3.5-flash",
|
|
1150
1694
|
"google/gemini-3.1-flash-image-preview",
|
|
1151
1695
|
"google/gemini-3-pro-image-preview",
|
|
1152
1696
|
"recraft/recraft-v4.1-pro-vector"
|
|
1153
1697
|
]);
|
|
1154
|
-
var imagesGenerateRequestSchema =
|
|
1155
|
-
prompt:
|
|
1698
|
+
var imagesGenerateRequestSchema = z5.object({
|
|
1699
|
+
prompt: z5.string().min(1),
|
|
1156
1700
|
model: imageGenerateModelSchema.optional(),
|
|
1157
1701
|
// Aspect ratio + size are validated loosely as strings; the per-model enum
|
|
1158
1702
|
// lives in canvas-contract and OpenRouter rejects unsupported combinations.
|
|
1159
|
-
aspectRatio:
|
|
1160
|
-
imageSize:
|
|
1703
|
+
aspectRatio: z5.string().optional(),
|
|
1704
|
+
imageSize: z5.string().optional(),
|
|
1161
1705
|
// Recraft v4.1 Pro Vector levers (ignored by other models).
|
|
1162
|
-
strength:
|
|
1163
|
-
rgbColors:
|
|
1706
|
+
strength: z5.coerce.number().min(0).max(1).optional(),
|
|
1707
|
+
rgbColors: z5.array(rgbTriple).optional(),
|
|
1164
1708
|
backgroundRgbColor: rgbTriple.optional(),
|
|
1165
1709
|
// Public image URLs used as visual references (multi-reference, in order).
|
|
1166
|
-
referenceUrls:
|
|
1167
|
-
descriptionContext:
|
|
1168
|
-
});
|
|
1169
|
-
var generatedImageSchema =
|
|
1170
|
-
imageId:
|
|
1171
|
-
deduped:
|
|
1172
|
-
imageUrl:
|
|
1173
|
-
width:
|
|
1174
|
-
height:
|
|
1175
|
-
});
|
|
1176
|
-
var imagesGenerateResponseSchema =
|
|
1177
|
-
model:
|
|
1178
|
-
costUsd:
|
|
1179
|
-
images:
|
|
1180
|
-
});
|
|
1181
|
-
var imagesLogoRequestSchema =
|
|
1182
|
-
domain:
|
|
1183
|
-
variant:
|
|
1184
|
-
autoIngest:
|
|
1185
|
-
descriptionContext:
|
|
1710
|
+
referenceUrls: z5.array(z5.string().url()).optional(),
|
|
1711
|
+
descriptionContext: z5.string().optional()
|
|
1712
|
+
});
|
|
1713
|
+
var generatedImageSchema = z5.object({
|
|
1714
|
+
imageId: z5.string(),
|
|
1715
|
+
deduped: z5.boolean(),
|
|
1716
|
+
imageUrl: z5.string(),
|
|
1717
|
+
width: z5.number().optional(),
|
|
1718
|
+
height: z5.number().optional()
|
|
1719
|
+
});
|
|
1720
|
+
var imagesGenerateResponseSchema = z5.object({
|
|
1721
|
+
model: z5.string(),
|
|
1722
|
+
costUsd: z5.number(),
|
|
1723
|
+
images: z5.array(generatedImageSchema)
|
|
1724
|
+
});
|
|
1725
|
+
var imagesLogoRequestSchema = z5.object({
|
|
1726
|
+
domain: z5.string().min(1),
|
|
1727
|
+
variant: z5.enum(["icon", "logo", "symbol"]).optional(),
|
|
1728
|
+
autoIngest: z5.coerce.number().int().min(0).max(5).optional(),
|
|
1729
|
+
descriptionContext: z5.string().optional()
|
|
1186
1730
|
});
|
|
1187
1731
|
var imagesLogoResponseSchema = providerHitsResponseSchema();
|
|
1188
|
-
var imagesIconRequestSchema =
|
|
1189
|
-
name:
|
|
1190
|
-
set:
|
|
1191
|
-
color:
|
|
1192
|
-
width:
|
|
1193
|
-
autoIngest:
|
|
1194
|
-
descriptionContext:
|
|
1732
|
+
var imagesIconRequestSchema = z5.object({
|
|
1733
|
+
name: z5.string().min(1),
|
|
1734
|
+
set: z5.string().optional(),
|
|
1735
|
+
color: z5.string().optional(),
|
|
1736
|
+
width: z5.coerce.number().int().positive().optional(),
|
|
1737
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1738
|
+
descriptionContext: z5.string().optional()
|
|
1195
1739
|
});
|
|
1196
1740
|
var imagesIconResponseSchema = providerHitsResponseSchema();
|
|
1197
|
-
var imagesExtractRequestSchema =
|
|
1198
|
-
url:
|
|
1199
|
-
waitFor:
|
|
1200
|
-
limit:
|
|
1201
|
-
autoIngest:
|
|
1202
|
-
descriptionContext:
|
|
1741
|
+
var imagesExtractRequestSchema = z5.object({
|
|
1742
|
+
url: z5.string().url(),
|
|
1743
|
+
waitFor: z5.coerce.number().int().min(0).max(3e4).optional(),
|
|
1744
|
+
limit: z5.coerce.number().int().positive().max(50).optional(),
|
|
1745
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1746
|
+
descriptionContext: z5.string().optional()
|
|
1203
1747
|
});
|
|
1204
1748
|
var imagesExtractResponseSchema = providerHitsResponseSchema();
|
|
1205
|
-
var imagesScreenshotRequestSchema =
|
|
1206
|
-
url:
|
|
1207
|
-
fullPage:
|
|
1208
|
-
viewportWidth:
|
|
1209
|
-
viewportHeight:
|
|
1210
|
-
format:
|
|
1211
|
-
descriptionContext:
|
|
1749
|
+
var imagesScreenshotRequestSchema = z5.object({
|
|
1750
|
+
url: z5.string().url(),
|
|
1751
|
+
fullPage: z5.boolean().optional(),
|
|
1752
|
+
viewportWidth: z5.coerce.number().int().positive().max(3840).optional(),
|
|
1753
|
+
viewportHeight: z5.coerce.number().int().positive().max(2160).optional(),
|
|
1754
|
+
format: z5.enum(["webp", "png", "jpg"]).optional(),
|
|
1755
|
+
descriptionContext: z5.string().optional()
|
|
1212
1756
|
});
|
|
1213
1757
|
var imagesScreenshotResponseSchema = providerHitsResponseSchema();
|
|
1214
|
-
var imagesGiphyRequestSchema =
|
|
1215
|
-
query:
|
|
1216
|
-
trending:
|
|
1217
|
-
limit:
|
|
1218
|
-
rating:
|
|
1219
|
-
lang:
|
|
1220
|
-
autoIngest:
|
|
1221
|
-
descriptionContext:
|
|
1758
|
+
var imagesGiphyRequestSchema = z5.object({
|
|
1759
|
+
query: z5.string().min(1).optional(),
|
|
1760
|
+
trending: z5.coerce.boolean().optional(),
|
|
1761
|
+
limit: z5.coerce.number().int().positive().max(50).optional(),
|
|
1762
|
+
rating: z5.enum(["g", "pg", "pg-13", "r"]).optional(),
|
|
1763
|
+
lang: z5.string().optional(),
|
|
1764
|
+
autoIngest: z5.coerce.number().int().min(0).max(20).optional(),
|
|
1765
|
+
descriptionContext: z5.string().optional()
|
|
1222
1766
|
});
|
|
1223
1767
|
var imagesGifResponseSchema = providerHitsResponseSchema();
|
|
1224
1768
|
var imagesStickerResponseSchema = providerHitsResponseSchema();
|
|
1225
|
-
var imagesIngestRequestSchema =
|
|
1226
|
-
url:
|
|
1769
|
+
var imagesIngestRequestSchema = z5.object({
|
|
1770
|
+
url: z5.string().url(),
|
|
1227
1771
|
// Validate source at the HTTP boundary so unknown values produce the standard
|
|
1228
1772
|
// `{ code: "BAD_REQUEST", message }` shape instead of a plain Error from
|
|
1229
1773
|
// `assertImageSource` inside the action.
|
|
1230
1774
|
source: imageSourceSchema,
|
|
1231
|
-
externalId:
|
|
1232
|
-
externalUrl:
|
|
1233
|
-
descriptionContext:
|
|
1775
|
+
externalId: z5.string().optional(),
|
|
1776
|
+
externalUrl: z5.string().optional(),
|
|
1777
|
+
descriptionContext: z5.string().optional()
|
|
1234
1778
|
});
|
|
1235
|
-
var imagesIngestResponseSchema =
|
|
1236
|
-
imageId:
|
|
1237
|
-
deduped:
|
|
1238
|
-
contentHash:
|
|
1779
|
+
var imagesIngestResponseSchema = z5.object({
|
|
1780
|
+
imageId: z5.string(),
|
|
1781
|
+
deduped: z5.boolean(),
|
|
1782
|
+
contentHash: z5.string()
|
|
1239
1783
|
});
|
|
1240
1784
|
|
|
1241
1785
|
// ../api/src/testimonials.ts
|
|
1242
|
-
import { z as
|
|
1243
|
-
var testimonialSourceTypeSchema =
|
|
1244
|
-
var testimonialStatusSchema =
|
|
1245
|
-
var testimonialSentimentSchema =
|
|
1246
|
-
var testimonialDocSchema =
|
|
1247
|
-
_id:
|
|
1248
|
-
_creationTime:
|
|
1249
|
-
companyId:
|
|
1250
|
-
sourceId:
|
|
1786
|
+
import { z as z6 } from "zod";
|
|
1787
|
+
var testimonialSourceTypeSchema = z6.enum(["google", "trustpilot"]);
|
|
1788
|
+
var testimonialStatusSchema = z6.enum(["pending", "processing", "ready", "error"]);
|
|
1789
|
+
var testimonialSentimentSchema = z6.enum(["positive", "neutral", "negative"]);
|
|
1790
|
+
var testimonialDocSchema = z6.object({
|
|
1791
|
+
_id: z6.string(),
|
|
1792
|
+
_creationTime: z6.number(),
|
|
1793
|
+
companyId: z6.string(),
|
|
1794
|
+
sourceId: z6.string(),
|
|
1251
1795
|
sourceType: testimonialSourceTypeSchema,
|
|
1252
|
-
reviewText:
|
|
1253
|
-
reviewTitle:
|
|
1254
|
-
searchText:
|
|
1255
|
-
reviewerName:
|
|
1256
|
-
reviewerImageUrl:
|
|
1257
|
-
reviewerImageId:
|
|
1258
|
-
reviewerLocation:
|
|
1259
|
-
rating:
|
|
1260
|
-
reviewDate:
|
|
1261
|
-
ownerAnswer:
|
|
1262
|
-
mediaUrls:
|
|
1263
|
-
imageIds:
|
|
1264
|
-
videoIds:
|
|
1265
|
-
sourceUrl:
|
|
1266
|
-
rawData:
|
|
1267
|
-
tags:
|
|
1268
|
-
highlight:
|
|
1269
|
-
language:
|
|
1270
|
-
summary:
|
|
1796
|
+
reviewText: z6.string(),
|
|
1797
|
+
reviewTitle: z6.string().optional(),
|
|
1798
|
+
searchText: z6.string().optional(),
|
|
1799
|
+
reviewerName: z6.string().optional(),
|
|
1800
|
+
reviewerImageUrl: z6.string().optional(),
|
|
1801
|
+
reviewerImageId: z6.string().optional(),
|
|
1802
|
+
reviewerLocation: z6.string().optional(),
|
|
1803
|
+
rating: z6.number().optional(),
|
|
1804
|
+
reviewDate: z6.number().optional(),
|
|
1805
|
+
ownerAnswer: z6.string().optional(),
|
|
1806
|
+
mediaUrls: z6.array(z6.string()).optional(),
|
|
1807
|
+
imageIds: z6.array(z6.string()).optional(),
|
|
1808
|
+
videoIds: z6.array(z6.string()).optional(),
|
|
1809
|
+
sourceUrl: z6.string().optional(),
|
|
1810
|
+
rawData: z6.unknown().optional(),
|
|
1811
|
+
tags: z6.array(z6.string()),
|
|
1812
|
+
highlight: z6.string().optional(),
|
|
1813
|
+
language: z6.string().optional(),
|
|
1814
|
+
summary: z6.string().optional(),
|
|
1271
1815
|
sentiment: testimonialSentimentSchema.optional(),
|
|
1272
|
-
textEmbedding:
|
|
1273
|
-
externalId:
|
|
1274
|
-
contentHash:
|
|
1816
|
+
textEmbedding: z6.array(z6.number()).optional(),
|
|
1817
|
+
externalId: z6.string().optional(),
|
|
1818
|
+
contentHash: z6.string().optional(),
|
|
1275
1819
|
status: testimonialStatusSchema,
|
|
1276
|
-
errorMessage:
|
|
1277
|
-
createdAt:
|
|
1278
|
-
updatedAt:
|
|
1820
|
+
errorMessage: z6.string().optional(),
|
|
1821
|
+
createdAt: z6.number(),
|
|
1822
|
+
updatedAt: z6.number()
|
|
1279
1823
|
});
|
|
1280
|
-
var testimonialsListRequestSchema =
|
|
1824
|
+
var testimonialsListRequestSchema = z6.object({
|
|
1281
1825
|
source: testimonialSourceTypeSchema.optional(),
|
|
1282
|
-
rating_min:
|
|
1283
|
-
rating_max:
|
|
1284
|
-
tags:
|
|
1826
|
+
rating_min: z6.coerce.number().int().min(1).max(5).optional(),
|
|
1827
|
+
rating_max: z6.coerce.number().int().min(1).max(5).optional(),
|
|
1828
|
+
tags: z6.string().transform((s) => s.split(",").filter(Boolean)).optional(),
|
|
1285
1829
|
status: testimonialStatusSchema.optional(),
|
|
1286
1830
|
sentiment: testimonialSentimentSchema.optional(),
|
|
1287
|
-
language:
|
|
1288
|
-
limit:
|
|
1289
|
-
});
|
|
1290
|
-
var testimonialsListResponseSchema =
|
|
1291
|
-
var testimonialsGetRequestSchema =
|
|
1292
|
-
var testimonialsSearchRequestSchema =
|
|
1293
|
-
query:
|
|
1294
|
-
limit:
|
|
1831
|
+
language: z6.string().min(2).max(5).optional(),
|
|
1832
|
+
limit: z6.coerce.number().int().positive().max(200).optional()
|
|
1833
|
+
});
|
|
1834
|
+
var testimonialsListResponseSchema = z6.array(testimonialDocSchema);
|
|
1835
|
+
var testimonialsGetRequestSchema = z6.object({ id: z6.string().min(1, "Missing id parameter") });
|
|
1836
|
+
var testimonialsSearchRequestSchema = z6.object({
|
|
1837
|
+
query: z6.string().min(1),
|
|
1838
|
+
limit: z6.coerce.number().int().positive().max(100).optional(),
|
|
1295
1839
|
source: testimonialSourceTypeSchema.optional(),
|
|
1296
|
-
rating_min:
|
|
1297
|
-
rating_max:
|
|
1298
|
-
tags:
|
|
1840
|
+
rating_min: z6.coerce.number().int().min(1).max(5).optional(),
|
|
1841
|
+
rating_max: z6.coerce.number().int().min(1).max(5).optional(),
|
|
1842
|
+
tags: z6.array(z6.string()).optional(),
|
|
1299
1843
|
status: testimonialStatusSchema.optional(),
|
|
1300
1844
|
sentiment: testimonialSentimentSchema.optional(),
|
|
1301
|
-
language:
|
|
1845
|
+
language: z6.string().min(2).max(5).optional()
|
|
1302
1846
|
}).refine(
|
|
1303
1847
|
(data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
|
|
1304
1848
|
{ message: "rating_min must be less than or equal to rating_max" }
|
|
1305
1849
|
);
|
|
1306
|
-
var testimonialsSearchResponseSchema =
|
|
1307
|
-
var testimonialsOutscraperWebhookResponseSchema =
|
|
1308
|
-
ok:
|
|
1309
|
-
note:
|
|
1850
|
+
var testimonialsSearchResponseSchema = z6.array(testimonialDocSchema);
|
|
1851
|
+
var testimonialsOutscraperWebhookResponseSchema = z6.object({
|
|
1852
|
+
ok: z6.literal(true),
|
|
1853
|
+
note: z6.string().optional()
|
|
1310
1854
|
});
|
|
1311
1855
|
|
|
1312
1856
|
// ../api/src/videos.ts
|
|
1313
|
-
import { z as
|
|
1314
|
-
var videoStatusSchema =
|
|
1315
|
-
var videoTranscriptSegmentSchema =
|
|
1316
|
-
text:
|
|
1317
|
-
startSecond:
|
|
1318
|
-
endSecond:
|
|
1319
|
-
});
|
|
1320
|
-
var videoSceneSchema =
|
|
1321
|
-
title:
|
|
1322
|
-
description:
|
|
1323
|
-
startSecond:
|
|
1324
|
-
endSecond:
|
|
1325
|
-
thumbnailTime:
|
|
1326
|
-
});
|
|
1327
|
-
var videoDocSchema =
|
|
1328
|
-
_id:
|
|
1329
|
-
_creationTime:
|
|
1330
|
-
companyId:
|
|
1331
|
-
muxAssetId:
|
|
1332
|
-
muxPlaybackId:
|
|
1333
|
-
muxUploadId:
|
|
1334
|
-
name:
|
|
1335
|
-
description:
|
|
1336
|
-
tags:
|
|
1337
|
-
source:
|
|
1338
|
-
externalId:
|
|
1339
|
-
sourceId:
|
|
1340
|
-
width:
|
|
1341
|
-
height:
|
|
1342
|
-
aspectRatio:
|
|
1343
|
-
duration:
|
|
1344
|
-
transcript:
|
|
1345
|
-
transcriptSegments:
|
|
1346
|
-
scenes:
|
|
1347
|
-
descriptionEmbedding:
|
|
1348
|
-
searchText:
|
|
1857
|
+
import { z as z7 } from "zod";
|
|
1858
|
+
var videoStatusSchema = z7.enum(["uploading", "uploaded", "processing", "ready", "error"]);
|
|
1859
|
+
var videoTranscriptSegmentSchema = z7.object({
|
|
1860
|
+
text: z7.string(),
|
|
1861
|
+
startSecond: z7.number(),
|
|
1862
|
+
endSecond: z7.number()
|
|
1863
|
+
});
|
|
1864
|
+
var videoSceneSchema = z7.object({
|
|
1865
|
+
title: z7.string(),
|
|
1866
|
+
description: z7.string(),
|
|
1867
|
+
startSecond: z7.number(),
|
|
1868
|
+
endSecond: z7.number(),
|
|
1869
|
+
thumbnailTime: z7.number()
|
|
1870
|
+
});
|
|
1871
|
+
var videoDocSchema = z7.object({
|
|
1872
|
+
_id: z7.string(),
|
|
1873
|
+
_creationTime: z7.number(),
|
|
1874
|
+
companyId: z7.string(),
|
|
1875
|
+
muxAssetId: z7.string(),
|
|
1876
|
+
muxPlaybackId: z7.string(),
|
|
1877
|
+
muxUploadId: z7.string(),
|
|
1878
|
+
name: z7.string(),
|
|
1879
|
+
description: z7.string(),
|
|
1880
|
+
tags: z7.array(z7.string()),
|
|
1881
|
+
source: z7.string(),
|
|
1882
|
+
externalId: z7.string().optional(),
|
|
1883
|
+
sourceId: z7.string().optional(),
|
|
1884
|
+
width: z7.number().optional(),
|
|
1885
|
+
height: z7.number().optional(),
|
|
1886
|
+
aspectRatio: z7.number().optional(),
|
|
1887
|
+
duration: z7.number().optional(),
|
|
1888
|
+
transcript: z7.string().optional(),
|
|
1889
|
+
transcriptSegments: z7.array(videoTranscriptSegmentSchema).optional(),
|
|
1890
|
+
scenes: z7.array(videoSceneSchema).optional(),
|
|
1891
|
+
descriptionEmbedding: z7.array(z7.number()).optional(),
|
|
1892
|
+
searchText: z7.string().optional(),
|
|
1349
1893
|
status: videoStatusSchema,
|
|
1350
|
-
errorMessage:
|
|
1351
|
-
createdAt:
|
|
1352
|
-
updatedAt:
|
|
1353
|
-
thumbnailUrl:
|
|
1354
|
-
});
|
|
1355
|
-
var videosWebhookResponseSchema =
|
|
1356
|
-
var videosGetRequestSchema =
|
|
1357
|
-
var videosSearchRequestSchema =
|
|
1358
|
-
query:
|
|
1359
|
-
limit:
|
|
1360
|
-
tags:
|
|
1361
|
-
});
|
|
1362
|
-
var videoSearchResultSchema =
|
|
1363
|
-
_id:
|
|
1364
|
-
thumbnailUrl:
|
|
1365
|
-
name:
|
|
1366
|
-
description:
|
|
1367
|
-
tags:
|
|
1368
|
-
status:
|
|
1369
|
-
duration:
|
|
1370
|
-
muxPlaybackId:
|
|
1371
|
-
createdAt:
|
|
1372
|
-
});
|
|
1373
|
-
var videosSearchResponseSchema =
|
|
1374
|
-
var videosUploadResponseSchema =
|
|
1375
|
-
var videosDeleteRequestSchema =
|
|
1376
|
-
var videosDeleteResponseSchema =
|
|
1894
|
+
errorMessage: z7.string().optional(),
|
|
1895
|
+
createdAt: z7.number(),
|
|
1896
|
+
updatedAt: z7.number(),
|
|
1897
|
+
thumbnailUrl: z7.string()
|
|
1898
|
+
});
|
|
1899
|
+
var videosWebhookResponseSchema = z7.object({ ok: z7.literal(true) });
|
|
1900
|
+
var videosGetRequestSchema = z7.object({ id: z7.string().min(1, "Missing id parameter") });
|
|
1901
|
+
var videosSearchRequestSchema = z7.object({
|
|
1902
|
+
query: z7.string().min(1),
|
|
1903
|
+
limit: z7.coerce.number().int().positive().max(100).optional(),
|
|
1904
|
+
tags: z7.array(z7.string()).optional()
|
|
1905
|
+
});
|
|
1906
|
+
var videoSearchResultSchema = z7.object({
|
|
1907
|
+
_id: z7.string(),
|
|
1908
|
+
thumbnailUrl: z7.string(),
|
|
1909
|
+
name: z7.string(),
|
|
1910
|
+
description: z7.string(),
|
|
1911
|
+
tags: z7.array(z7.string()),
|
|
1912
|
+
status: z7.string(),
|
|
1913
|
+
duration: z7.number().optional(),
|
|
1914
|
+
muxPlaybackId: z7.string(),
|
|
1915
|
+
createdAt: z7.number()
|
|
1916
|
+
});
|
|
1917
|
+
var videosSearchResponseSchema = z7.array(videoSearchResultSchema);
|
|
1918
|
+
var videosUploadResponseSchema = z7.object({ uploadUrl: z7.string(), videoId: z7.string() });
|
|
1919
|
+
var videosDeleteRequestSchema = z7.object({ id: z7.string().min(1, "Missing video ID") });
|
|
1920
|
+
var videosDeleteResponseSchema = z7.object({ ok: z7.literal(true) });
|
|
1377
1921
|
|
|
1378
1922
|
// src/commands/actions/complete.ts
|
|
1379
1923
|
import { defineCommand as defineCommand2 } from "citty";
|
|
@@ -2202,7 +2746,7 @@ Examples:
|
|
|
2202
2746
|
});
|
|
2203
2747
|
|
|
2204
2748
|
// src/commands/ads/index.ts
|
|
2205
|
-
import { defineCommand as
|
|
2749
|
+
import { defineCommand as defineCommand80 } from "citty";
|
|
2206
2750
|
|
|
2207
2751
|
// src/commands/ads/google/index.ts
|
|
2208
2752
|
import { defineCommand as defineCommand29 } from "citty";
|
|
@@ -4526,7 +5070,7 @@ Examples:
|
|
|
4526
5070
|
});
|
|
4527
5071
|
|
|
4528
5072
|
// src/commands/ads/linkedin/index.ts
|
|
4529
|
-
import { defineCommand as
|
|
5073
|
+
import { defineCommand as defineCommand49 } from "citty";
|
|
4530
5074
|
|
|
4531
5075
|
// src/commands/ads/linkedin/schemas.ts
|
|
4532
5076
|
registerSchema({
|
|
@@ -4824,6 +5368,293 @@ registerSchema({
|
|
|
4824
5368
|
"skip-cache": { type: "boolean", description: "Bypass cache", required: false }
|
|
4825
5369
|
}
|
|
4826
5370
|
});
|
|
5371
|
+
var writeAccountArgs = {
|
|
5372
|
+
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N", required: false },
|
|
5373
|
+
"account-urn": { type: "string", description: "Alias for --account-id", required: false }
|
|
5374
|
+
};
|
|
5375
|
+
registerSchema({
|
|
5376
|
+
command: "ads.linkedin.campaign-groups.create",
|
|
5377
|
+
description: "Stage a new campaign group (staged until publish; review with `baker ads linkedin draft`). Returns a li_temp_* ref that later `campaigns create --group` calls can reference.",
|
|
5378
|
+
args: {
|
|
5379
|
+
...writeAccountArgs,
|
|
5380
|
+
name: { type: "string", description: "Name (\u2264100 chars)", required: true },
|
|
5381
|
+
start: { type: "string", description: "Run schedule start (ISO date or epoch ms)", required: true },
|
|
5382
|
+
end: { type: "string", description: "Run schedule end", required: false },
|
|
5383
|
+
"total-budget": { type: "string", description: "Lifetime budget amount", required: false },
|
|
5384
|
+
currency: { type: "string", description: "3-letter currency code (required with money flags)", required: false },
|
|
5385
|
+
status: { type: "string", description: "DRAFT|ACTIVE|PAUSED (default DRAFT)", required: false },
|
|
5386
|
+
file: { type: "string", description: "JSON payload file; flags override file keys", required: false }
|
|
5387
|
+
}
|
|
5388
|
+
});
|
|
5389
|
+
registerSchema({
|
|
5390
|
+
command: "ads.linkedin.campaign-groups.update",
|
|
5391
|
+
description: "Stage changes to an existing campaign group (name, schedule, budget, status). Captures a before-snapshot for the dashboard diff. Applies on chat publish.",
|
|
5392
|
+
args: {
|
|
5393
|
+
id: { type: "positional", description: "Campaign group id or URN", required: true },
|
|
5394
|
+
...writeAccountArgs,
|
|
5395
|
+
name: { type: "string", description: "New name", required: false },
|
|
5396
|
+
start: { type: "string", description: "New schedule start", required: false },
|
|
5397
|
+
end: { type: "string", description: "New schedule end", required: false },
|
|
5398
|
+
"total-budget": { type: "string", description: "New lifetime budget", required: false },
|
|
5399
|
+
currency: { type: "string", description: "3-letter currency code", required: false },
|
|
5400
|
+
status: { type: "string", description: "ACTIVE|PAUSED|ARCHIVED", required: false },
|
|
5401
|
+
file: { type: "string", description: "JSON file with fields to change", required: false }
|
|
5402
|
+
}
|
|
5403
|
+
});
|
|
5404
|
+
registerSchema({
|
|
5405
|
+
command: "ads.linkedin.campaigns.create",
|
|
5406
|
+
description: "Stage a new campaign. --group accepts a real id/URN or a li_temp_* ref staged earlier in this chat. Targeting goes in --targeting-file as LinkedIn criteria: {include:{and:[{or:{'urn:li:adTargetingFacet:locations':['urn:li:geo:\u2026']}}]}} \u2014 find facet values with `baker ads linkedin facets values`. Playbook defaults: manual bid (--bid), audience expansion off, LAN off. Staged until publish.",
|
|
5407
|
+
args: {
|
|
5408
|
+
...writeAccountArgs,
|
|
5409
|
+
name: { type: "string", description: "Name (\u2264255 chars)", required: true },
|
|
5410
|
+
group: { type: "string", description: "Campaign group id/URN or li_temp_* ref", required: true },
|
|
5411
|
+
type: { type: "string", description: "SPONSORED_UPDATES|TEXT_AD|SPONSORED_INMAILS|DYNAMIC", required: true },
|
|
5412
|
+
objective: { type: "string", description: "LEAD_GENERATION|WEBSITE_VISIT|BRAND_AWARENESS|\u2026", required: false },
|
|
5413
|
+
"cost-type": { type: "string", description: "CPC|CPM|CPV", required: true },
|
|
5414
|
+
bid: { type: "string", description: "Manual bid amount (unitCost)", required: false },
|
|
5415
|
+
"daily-budget": { type: "string", description: "Daily budget amount", required: false },
|
|
5416
|
+
"total-budget": { type: "string", description: "Lifetime budget amount", required: false },
|
|
5417
|
+
currency: { type: "string", description: "3-letter currency code (required with money flags)", required: false },
|
|
5418
|
+
start: { type: "string", description: "Run schedule start", required: false },
|
|
5419
|
+
end: { type: "string", description: "Run schedule end", required: false },
|
|
5420
|
+
locale: { type: "string", description: "Profile locale like en_US (default en_US)", required: false },
|
|
5421
|
+
"targeting-file": { type: "string", description: "JSON file with targetingCriteria", required: true },
|
|
5422
|
+
"audience-expansion": { type: "string", description: "on|off (playbook: off; default off)", required: false },
|
|
5423
|
+
lan: {
|
|
5424
|
+
type: "string",
|
|
5425
|
+
description: "LinkedIn Audience Network on|off (playbook: off; default off)",
|
|
5426
|
+
required: false
|
|
5427
|
+
},
|
|
5428
|
+
ctv: { type: "string", description: "Connected TV on|off (default off)", required: false },
|
|
5429
|
+
"creative-selection": { type: "string", description: "OPTIMIZED|ROUND_ROBIN", required: false },
|
|
5430
|
+
"associated-entity": { type: "string", description: "Organization URN", required: false },
|
|
5431
|
+
status: { type: "string", description: "DRAFT|ACTIVE|PAUSED (default DRAFT)", required: false },
|
|
5432
|
+
file: { type: "string", description: "JSON payload file; flags override file keys", required: false }
|
|
5433
|
+
}
|
|
5434
|
+
});
|
|
5435
|
+
registerSchema({
|
|
5436
|
+
command: "ads.linkedin.campaigns.update",
|
|
5437
|
+
description: "Stage changes to an existing campaign \u2014 budget, bid, targeting, schedule, flags, status. Only pass what changes; a before-snapshot powers the dashboard diff. Applies on chat publish.",
|
|
5438
|
+
args: {
|
|
5439
|
+
id: { type: "positional", description: "Campaign id or URN", required: true },
|
|
5440
|
+
...writeAccountArgs,
|
|
5441
|
+
name: { type: "string", description: "New name", required: false },
|
|
5442
|
+
objective: { type: "string", description: "New objective", required: false },
|
|
5443
|
+
bid: { type: "string", description: "New manual bid", required: false },
|
|
5444
|
+
"daily-budget": { type: "string", description: "New daily budget", required: false },
|
|
5445
|
+
"total-budget": { type: "string", description: "New lifetime budget", required: false },
|
|
5446
|
+
currency: { type: "string", description: "3-letter currency code", required: false },
|
|
5447
|
+
start: { type: "string", description: "New schedule start", required: false },
|
|
5448
|
+
end: { type: "string", description: "New schedule end", required: false },
|
|
5449
|
+
"targeting-file": { type: "string", description: "JSON file with replacement targetingCriteria", required: false },
|
|
5450
|
+
"audience-expansion": { type: "string", description: "on|off", required: false },
|
|
5451
|
+
lan: { type: "string", description: "on|off", required: false },
|
|
5452
|
+
ctv: { type: "string", description: "on|off", required: false },
|
|
5453
|
+
"creative-selection": { type: "string", description: "OPTIMIZED|ROUND_ROBIN", required: false },
|
|
5454
|
+
status: { type: "string", description: "ACTIVE|PAUSED|ARCHIVED", required: false },
|
|
5455
|
+
file: { type: "string", description: "JSON file with fields to change", required: false }
|
|
5456
|
+
}
|
|
5457
|
+
});
|
|
5458
|
+
var statusSugarArgs = {
|
|
5459
|
+
id: { type: "positional", description: "Entity id or URN", required: true },
|
|
5460
|
+
...writeAccountArgs
|
|
5461
|
+
};
|
|
5462
|
+
registerSchema({
|
|
5463
|
+
command: "ads.linkedin.campaigns.pause",
|
|
5464
|
+
description: "Stage pausing a campaign (status \u2192 PAUSED on publish).",
|
|
5465
|
+
args: statusSugarArgs
|
|
5466
|
+
});
|
|
5467
|
+
registerSchema({
|
|
5468
|
+
command: "ads.linkedin.campaigns.resume",
|
|
5469
|
+
description: "Stage resuming a paused campaign (status \u2192 ACTIVE on publish).",
|
|
5470
|
+
args: statusSugarArgs
|
|
5471
|
+
});
|
|
5472
|
+
registerSchema({
|
|
5473
|
+
command: "ads.linkedin.campaigns.archive",
|
|
5474
|
+
description: "Stage archiving a campaign (status \u2192 ARCHIVED on publish).",
|
|
5475
|
+
args: statusSugarArgs
|
|
5476
|
+
});
|
|
5477
|
+
registerSchema({
|
|
5478
|
+
command: "ads.linkedin.campaign-groups.pause",
|
|
5479
|
+
description: "Stage pausing a campaign group.",
|
|
5480
|
+
args: statusSugarArgs
|
|
5481
|
+
});
|
|
5482
|
+
registerSchema({
|
|
5483
|
+
command: "ads.linkedin.campaign-groups.resume",
|
|
5484
|
+
description: "Stage resuming a campaign group.",
|
|
5485
|
+
args: statusSugarArgs
|
|
5486
|
+
});
|
|
5487
|
+
registerSchema({
|
|
5488
|
+
command: "ads.linkedin.creatives.pause",
|
|
5489
|
+
description: "Stage pausing a creative (intendedStatus \u2192 PAUSED on publish). Playbook early-kill rule: >30 impressions with 0 clicks.",
|
|
5490
|
+
args: statusSugarArgs
|
|
5491
|
+
});
|
|
5492
|
+
registerSchema({
|
|
5493
|
+
command: "ads.linkedin.creatives.resume",
|
|
5494
|
+
description: "Stage resuming a paused creative.",
|
|
5495
|
+
args: statusSugarArgs
|
|
5496
|
+
});
|
|
5497
|
+
var duplicateArgs = {
|
|
5498
|
+
id: { type: "positional", description: "Source id or URN", required: true },
|
|
5499
|
+
...writeAccountArgs,
|
|
5500
|
+
name: { type: "string", description: "Name for the copy", required: false },
|
|
5501
|
+
file: { type: "string", description: "JSON file with field overrides for the copy", required: false }
|
|
5502
|
+
};
|
|
5503
|
+
registerSchema({
|
|
5504
|
+
command: "ads.linkedin.campaigns.duplicate",
|
|
5505
|
+
description: "Stage a copy of an existing campaign as a new DRAFT create (playbook: duplicate, never link-to-original). Reads the source at stage time; override fields via --name/--file.",
|
|
5506
|
+
args: duplicateArgs
|
|
5507
|
+
});
|
|
5508
|
+
registerSchema({
|
|
5509
|
+
command: "ads.linkedin.campaign-groups.duplicate",
|
|
5510
|
+
description: "Stage a copy of an existing campaign group as a new DRAFT create.",
|
|
5511
|
+
args: duplicateArgs
|
|
5512
|
+
});
|
|
5513
|
+
registerSchema({
|
|
5514
|
+
command: "ads.linkedin.creatives.duplicate",
|
|
5515
|
+
description: "Stage a copy of an existing creative by re-sponsoring its underlying post into a new DRAFT creative (--file can override the target campaign).",
|
|
5516
|
+
args: duplicateArgs
|
|
5517
|
+
});
|
|
5518
|
+
registerSchema({
|
|
5519
|
+
command: "ads.linkedin.creatives.create",
|
|
5520
|
+
description: "Stage a new creative (ad). Formats: image|video|text|spotlight|follower|document|carousel|conversation|tla|jobs. Media: --image-id/--video-id reference the Baker library (`baker images`/`baker videos`) and upload to LinkedIn at publish; --image-urn/--video-urn reference media already on LinkedIn. Limits: headline \u226470 (text ads \u226425), intro soft-truncates at 600 chars, landing URL must be https. Complex formats take --file with the full content object. Staged until publish.",
|
|
5521
|
+
args: {
|
|
5522
|
+
...writeAccountArgs,
|
|
5523
|
+
campaign: { type: "string", description: "Campaign id/URN or li_temp_* ref", required: true },
|
|
5524
|
+
format: {
|
|
5525
|
+
type: "string",
|
|
5526
|
+
description: "image|video|text|spotlight|follower|document|carousel|conversation|tla|jobs",
|
|
5527
|
+
required: true
|
|
5528
|
+
},
|
|
5529
|
+
"image-id": { type: "string", description: "Baker image library id", required: false },
|
|
5530
|
+
"image-urn": { type: "string", description: "Existing urn:li:image:*", required: false },
|
|
5531
|
+
"video-id": { type: "string", description: "Baker video library id", required: false },
|
|
5532
|
+
"video-urn": { type: "string", description: "Existing urn:li:video:*", required: false },
|
|
5533
|
+
"logo-image-id": { type: "string", description: "Baker image id for the logo", required: false },
|
|
5534
|
+
intro: { type: "string", description: "Commentary / intro text", required: false },
|
|
5535
|
+
headline: { type: "string", description: "Headline", required: false },
|
|
5536
|
+
description: { type: "string", description: "Description (text/spotlight)", required: false },
|
|
5537
|
+
"landing-url": { type: "string", description: "https destination URL", required: false },
|
|
5538
|
+
cta: { type: "string", description: "LEARN_MORE|REQUEST_DEMO|SIGN_UP|REGISTER|DOWNLOAD|\u2026", required: false },
|
|
5539
|
+
"cta-label": { type: "string", description: "Spotlight CTA label (\u226418 chars)", required: false },
|
|
5540
|
+
"post-urn": { type: "string", description: "TLA: post to sponsor (urn:li:share|ugcPost:*)", required: false },
|
|
5541
|
+
"intended-status": { type: "string", description: "DRAFT|ACTIVE|PAUSED (default DRAFT)", required: false },
|
|
5542
|
+
title: { type: "string", description: "Media title", required: false },
|
|
5543
|
+
file: { type: "string", description: "JSON file with the full content object", required: false }
|
|
5544
|
+
}
|
|
5545
|
+
});
|
|
5546
|
+
registerSchema({
|
|
5547
|
+
command: "ads.linkedin.creatives.update",
|
|
5548
|
+
description: "Stage changes to an existing creative (intendedStatus, name). Applies on chat publish.",
|
|
5549
|
+
args: {
|
|
5550
|
+
id: { type: "positional", description: "Creative id or URN", required: true },
|
|
5551
|
+
...writeAccountArgs,
|
|
5552
|
+
"intended-status": { type: "string", description: "ACTIVE|PAUSED|ARCHIVED|DRAFT", required: false },
|
|
5553
|
+
name: { type: "string", description: "New creative name", required: false },
|
|
5554
|
+
file: { type: "string", description: "JSON file with fields to change", required: false }
|
|
5555
|
+
}
|
|
5556
|
+
});
|
|
5557
|
+
registerSchema({
|
|
5558
|
+
command: "ads.linkedin.audiences.create",
|
|
5559
|
+
description: "Stage a new matched audience. company-list/user-list take --list-file (CSV with header; companyName,domain for companies; email column is SHA-256 hashed locally). LinkedIn needs 300+ MATCHED members to serve \u2014 upload well above that. retargeting/engagement configs go in --file. Staged until publish.",
|
|
5560
|
+
args: {
|
|
5561
|
+
...writeAccountArgs,
|
|
5562
|
+
name: { type: "string", description: "Audience name (\u2264100 chars)", required: true },
|
|
5563
|
+
type: { type: "string", description: "company-list|user-list|retargeting|engagement", required: true },
|
|
5564
|
+
"list-file": { type: "string", description: "CSV file with the list rows", required: false },
|
|
5565
|
+
file: { type: "string", description: "JSON raw source config for retargeting/engagement", required: false }
|
|
5566
|
+
}
|
|
5567
|
+
});
|
|
5568
|
+
registerSchema({
|
|
5569
|
+
command: "ads.linkedin.audiences.upload",
|
|
5570
|
+
description: "Stage adding rows to an existing audience segment (or a li_temp_* segment staged in this chat). Same CSV rules as audiences.create.",
|
|
5571
|
+
args: {
|
|
5572
|
+
id: { type: "positional", description: "Segment URN/id or li_temp_* ref", required: true },
|
|
5573
|
+
...writeAccountArgs,
|
|
5574
|
+
"list-file": { type: "string", description: "CSV file with the rows to add", required: true }
|
|
5575
|
+
}
|
|
5576
|
+
});
|
|
5577
|
+
registerSchema({
|
|
5578
|
+
command: "ads.linkedin.conversions.create",
|
|
5579
|
+
description: "Stage a new conversion rule. Playbook defaults: --post-click-window 30 --view-window 7, counting ONE_TIME_EACH_MEMBER for leads. Staged until publish.",
|
|
5580
|
+
args: {
|
|
5581
|
+
...writeAccountArgs,
|
|
5582
|
+
name: { type: "string", description: "Rule name", required: true },
|
|
5583
|
+
type: {
|
|
5584
|
+
type: "string",
|
|
5585
|
+
description: "LEAD|SIGN_UP|DOWNLOAD|PURCHASE|KEY_PAGE_VIEW|ADD_TO_CART|INSTALL|OTHER",
|
|
5586
|
+
required: true
|
|
5587
|
+
},
|
|
5588
|
+
method: { type: "string", description: "INSIGHT_TAG|CONVERSIONS_API", required: true },
|
|
5589
|
+
"post-click-window": { type: "string", description: "1|7|30|90 days", required: false },
|
|
5590
|
+
"view-window": { type: "string", description: "1|7|30 days", required: false },
|
|
5591
|
+
"attribution-type": {
|
|
5592
|
+
type: "string",
|
|
5593
|
+
description: "LAST_TOUCH_BY_CAMPAIGN|LAST_TOUCH_BY_CONVERSION",
|
|
5594
|
+
required: false
|
|
5595
|
+
},
|
|
5596
|
+
"associate-all-campaigns": {
|
|
5597
|
+
type: "boolean",
|
|
5598
|
+
description: "Auto-associate with active campaigns",
|
|
5599
|
+
required: false
|
|
5600
|
+
},
|
|
5601
|
+
file: { type: "string", description: "JSON payload file (e.g. urlMatchRuleExpression)", required: false }
|
|
5602
|
+
}
|
|
5603
|
+
});
|
|
5604
|
+
registerSchema({
|
|
5605
|
+
command: "ads.linkedin.conversions.update",
|
|
5606
|
+
description: "Stage changes to a conversion rule (windows, attribution, enabled, name). Applies on chat publish.",
|
|
5607
|
+
args: {
|
|
5608
|
+
id: { type: "positional", description: "Conversion rule id or URN", required: true },
|
|
5609
|
+
...writeAccountArgs,
|
|
5610
|
+
name: { type: "string", description: "New name", required: false },
|
|
5611
|
+
"post-click-window": { type: "string", description: "1|7|30|90 days", required: false },
|
|
5612
|
+
"view-window": { type: "string", description: "1|7|30 days", required: false },
|
|
5613
|
+
"attribution-type": { type: "string", description: "New attribution type", required: false },
|
|
5614
|
+
enabled: { type: "string", description: "on|off", required: false },
|
|
5615
|
+
file: { type: "string", description: "JSON file with fields to change", required: false }
|
|
5616
|
+
}
|
|
5617
|
+
});
|
|
5618
|
+
registerSchema({
|
|
5619
|
+
command: "ads.linkedin.lead-forms.create",
|
|
5620
|
+
description: "Stage a new Lead Gen Form from a JSON file: {name, headline \u226460, description? \u2264160, privacyPolicyUrl, questions[] \u226412 (playbook: \u22644 for completion), thankYou?, legalDisclaimer?}. Staged until publish.",
|
|
5621
|
+
args: {
|
|
5622
|
+
...writeAccountArgs,
|
|
5623
|
+
file: { type: "string", description: "JSON form definition file", required: true },
|
|
5624
|
+
name: { type: "string", description: "Override the form name", required: false }
|
|
5625
|
+
}
|
|
5626
|
+
});
|
|
5627
|
+
registerSchema({
|
|
5628
|
+
command: "ads.linkedin.lead-forms.update",
|
|
5629
|
+
description: "Stage changes to a Lead Gen Form from a JSON file. Applies on chat publish.",
|
|
5630
|
+
args: {
|
|
5631
|
+
id: { type: "positional", description: "Lead form id or URN", required: true },
|
|
5632
|
+
...writeAccountArgs,
|
|
5633
|
+
file: { type: "string", description: "JSON file with the fields to change", required: true },
|
|
5634
|
+
name: { type: "string", description: "New form name", required: false }
|
|
5635
|
+
}
|
|
5636
|
+
});
|
|
5637
|
+
registerSchema({
|
|
5638
|
+
command: "ads.linkedin.draft.list",
|
|
5639
|
+
description: "Show every LinkedIn write op staged in this chat: ref, summary, dependencies, warnings, mode (simulated = publish will NOT hit LinkedIn), and post-publish results (applied/simulated/failed/skipped). Ops are invisible to the read commands until publish \u2014 check here before finishing.",
|
|
5640
|
+
args: {}
|
|
5641
|
+
});
|
|
5642
|
+
registerSchema({
|
|
5643
|
+
command: "ads.linkedin.draft.remove",
|
|
5644
|
+
description: "Drop one staged LinkedIn op from this chat's draft. Removing a create cascades to every op that depends on it (a campaign removal drops its staged creatives).",
|
|
5645
|
+
args: {
|
|
5646
|
+
ref: {
|
|
5647
|
+
type: "positional",
|
|
5648
|
+
description: "Op ref (li_temp_* for creates, target id/URN for updates)",
|
|
5649
|
+
required: true
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
});
|
|
5653
|
+
registerSchema({
|
|
5654
|
+
command: "ads.linkedin.draft.clear",
|
|
5655
|
+
description: "Discard ALL staged LinkedIn ops in this chat's draft. Nothing applies on publish.",
|
|
5656
|
+
args: {}
|
|
5657
|
+
});
|
|
4827
5658
|
|
|
4828
5659
|
// src/commands/ads/linkedin/account.ts
|
|
4829
5660
|
import { defineCommand as defineCommand30 } from "citty";
|
|
@@ -5678,55 +6509,779 @@ Examples:
|
|
|
5678
6509
|
});
|
|
5679
6510
|
|
|
5680
6511
|
// src/commands/ads/linkedin/campaign-groups.ts
|
|
5681
|
-
import { defineCommand as
|
|
5682
|
-
var campaignGroupsCommand = defineCommand36({
|
|
5683
|
-
meta: {
|
|
5684
|
-
name: "campaign-groups",
|
|
5685
|
-
description: `List LinkedIn campaign groups.
|
|
6512
|
+
import { defineCommand as defineCommand37 } from "citty";
|
|
5686
6513
|
|
|
5687
|
-
|
|
6514
|
+
// src/commands/ads/linkedin/write-commands.ts
|
|
6515
|
+
import { defineCommand as defineCommand36 } from "citty";
|
|
5688
6516
|
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
6517
|
+
// src/commands/ads/linkedin/write-shared.ts
|
|
6518
|
+
import { createHash as createHash2 } from "crypto";
|
|
6519
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
6520
|
+
function bareAccountId(args) {
|
|
6521
|
+
const raw = resolveAccountIdArg(args);
|
|
6522
|
+
return raw.replace(/^urn:li:sponsoredAccount:/, "").replace(/^sponsoredAccount:/, "");
|
|
6523
|
+
}
|
|
6524
|
+
function failWriteValidation(message) {
|
|
6525
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
6526
|
+
process.exit(1);
|
|
6527
|
+
}
|
|
6528
|
+
function loadJsonFileArg(path11) {
|
|
6529
|
+
if (typeof path11 !== "string" || path11.length === 0) {
|
|
6530
|
+
return {};
|
|
6531
|
+
}
|
|
6532
|
+
try {
|
|
6533
|
+
const parsed = JSON.parse(readFileSync6(path11, "utf8"));
|
|
6534
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
6535
|
+
failWriteValidation(`${path11} must contain a JSON object`);
|
|
6536
|
+
}
|
|
6537
|
+
return parsed;
|
|
6538
|
+
} catch (err) {
|
|
6539
|
+
if (err instanceof SyntaxError) {
|
|
6540
|
+
failWriteValidation(`${path11} is not valid JSON: ${err.message}`);
|
|
6541
|
+
}
|
|
6542
|
+
throw err;
|
|
6543
|
+
}
|
|
6544
|
+
}
|
|
6545
|
+
function mergePayload(file, flags) {
|
|
6546
|
+
const merged = { ...file };
|
|
6547
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
6548
|
+
if (value !== void 0) {
|
|
6549
|
+
merged[key] = value;
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
return merged;
|
|
6553
|
+
}
|
|
6554
|
+
function parseMoneyFlag(amount, currency, flag) {
|
|
6555
|
+
if (amount === void 0 || amount === null || amount === "") {
|
|
6556
|
+
return void 0;
|
|
6557
|
+
}
|
|
6558
|
+
if (typeof currency !== "string" || currency.length !== 3) {
|
|
6559
|
+
failWriteValidation(`${flag} needs --currency (3-letter code matching the ad account, e.g. EUR)`);
|
|
6560
|
+
}
|
|
6561
|
+
return { amount: String(amount), currencyCode: currency.toUpperCase() };
|
|
6562
|
+
}
|
|
6563
|
+
function parseDateFlag(value, flag) {
|
|
6564
|
+
if (value === void 0 || value === null || value === "") {
|
|
6565
|
+
return void 0;
|
|
6566
|
+
}
|
|
6567
|
+
const raw = String(value);
|
|
6568
|
+
if (/^\d{10,}$/.test(raw)) {
|
|
6569
|
+
return Number(raw);
|
|
6570
|
+
}
|
|
6571
|
+
const parsed = Date.parse(raw);
|
|
6572
|
+
if (Number.isNaN(parsed)) {
|
|
6573
|
+
failWriteValidation(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);
|
|
6574
|
+
}
|
|
6575
|
+
return parsed;
|
|
6576
|
+
}
|
|
6577
|
+
function parseOnOffFlag(value, flag) {
|
|
6578
|
+
if (value === void 0 || value === null || value === "") {
|
|
6579
|
+
return void 0;
|
|
6580
|
+
}
|
|
6581
|
+
const raw = String(value).toLowerCase();
|
|
6582
|
+
if (raw === "on" || raw === "true") {
|
|
6583
|
+
return true;
|
|
6584
|
+
}
|
|
6585
|
+
if (raw === "off" || raw === "false") {
|
|
6586
|
+
return false;
|
|
6587
|
+
}
|
|
6588
|
+
failWriteValidation(`${flag} must be on|off`);
|
|
6589
|
+
}
|
|
6590
|
+
function parseLocaleFlag(value) {
|
|
6591
|
+
if (value === void 0 || value === null || value === "") {
|
|
6592
|
+
return void 0;
|
|
6593
|
+
}
|
|
6594
|
+
const match = /^([a-z]{2})[_-]([A-Za-z]{2})$/.exec(String(value));
|
|
6595
|
+
if (!match) {
|
|
6596
|
+
failWriteValidation("--locale must look like en_US (language_COUNTRY)");
|
|
6597
|
+
}
|
|
6598
|
+
return { language: match[1], country: match[2].toUpperCase() };
|
|
6599
|
+
}
|
|
6600
|
+
function loadTargetingFileArg(path11) {
|
|
6601
|
+
if (typeof path11 !== "string" || path11.length === 0) {
|
|
6602
|
+
return void 0;
|
|
6603
|
+
}
|
|
6604
|
+
const parsed = loadJsonFileArg(path11);
|
|
6605
|
+
const criteria = parsed.targetingCriteria ?? parsed;
|
|
6606
|
+
if (!criteria.include) {
|
|
6607
|
+
failWriteValidation(
|
|
6608
|
+
`${path11} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
6609
|
+
);
|
|
6610
|
+
}
|
|
6611
|
+
return criteria;
|
|
6612
|
+
}
|
|
6613
|
+
function sha256Lower(value) {
|
|
6614
|
+
return createHash2("sha256").update(value.trim().toLowerCase()).digest("hex");
|
|
6615
|
+
}
|
|
6616
|
+
function parseCsvLine(line) {
|
|
6617
|
+
const cells = [];
|
|
6618
|
+
let current = "";
|
|
6619
|
+
let inQuotes = false;
|
|
6620
|
+
for (let i = 0; i < line.length; i++) {
|
|
6621
|
+
const char = line[i];
|
|
6622
|
+
if (inQuotes) {
|
|
6623
|
+
if (char === '"' && line[i + 1] === '"') {
|
|
6624
|
+
current += '"';
|
|
6625
|
+
i++;
|
|
6626
|
+
} else if (char === '"') {
|
|
6627
|
+
inQuotes = false;
|
|
6628
|
+
} else {
|
|
6629
|
+
current += char;
|
|
6630
|
+
}
|
|
6631
|
+
} else if (char === '"') {
|
|
6632
|
+
inQuotes = true;
|
|
6633
|
+
} else if (char === ",") {
|
|
6634
|
+
cells.push(current);
|
|
6635
|
+
current = "";
|
|
6636
|
+
} else {
|
|
6637
|
+
current += char;
|
|
6638
|
+
}
|
|
6639
|
+
}
|
|
6640
|
+
cells.push(current);
|
|
6641
|
+
return cells.map((cell) => cell.trim());
|
|
6642
|
+
}
|
|
6643
|
+
function parseListFileArg(path11, maxRows) {
|
|
6644
|
+
if (typeof path11 !== "string" || path11.length === 0) {
|
|
6645
|
+
return void 0;
|
|
6646
|
+
}
|
|
6647
|
+
const raw = readFileSync6(path11, "utf8");
|
|
6648
|
+
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
6649
|
+
if (lines.length < 2) {
|
|
6650
|
+
failWriteValidation(`${path11} needs a header row and at least one data row`);
|
|
6651
|
+
}
|
|
6652
|
+
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
6653
|
+
const rows = [];
|
|
6654
|
+
for (const line of lines.slice(1)) {
|
|
6655
|
+
const cells = parseCsvLine(line);
|
|
6656
|
+
const row = {};
|
|
6657
|
+
columns.forEach((column, index) => {
|
|
6658
|
+
const value = cells[index] ?? "";
|
|
6659
|
+
if (!value) {
|
|
6660
|
+
return;
|
|
6661
|
+
}
|
|
6662
|
+
row[column] = column.toLowerCase() === "email" ? sha256Lower(value) : value;
|
|
6663
|
+
});
|
|
6664
|
+
if (Object.keys(row).length > 0) {
|
|
6665
|
+
rows.push(row);
|
|
6666
|
+
}
|
|
6667
|
+
}
|
|
6668
|
+
if (rows.length > maxRows) {
|
|
6669
|
+
failWriteValidation(`${path11} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
6670
|
+
}
|
|
6671
|
+
return { columns, rows };
|
|
6672
|
+
}
|
|
6673
|
+
async function stageOp(raw) {
|
|
6674
|
+
const preflight = linkedinDraftOpInputSchema.safeParse(raw);
|
|
6675
|
+
if (!preflight.success) {
|
|
6676
|
+
const fields = preflight.error.issues.map((issue) => ({
|
|
6677
|
+
path: issue.path.join("."),
|
|
6678
|
+
message: issue.message
|
|
6679
|
+
}));
|
|
6680
|
+
writeJsonEnvelope({
|
|
6681
|
+
ok: false,
|
|
6682
|
+
error: {
|
|
6683
|
+
code: "VALIDATION_ERROR",
|
|
6684
|
+
message: fields.map((field) => field.path ? `${field.path}: ${field.message}` : field.message).join("; "),
|
|
6685
|
+
fields
|
|
6686
|
+
}
|
|
6687
|
+
});
|
|
6688
|
+
process.exit(1);
|
|
6689
|
+
}
|
|
6690
|
+
try {
|
|
6691
|
+
const chatId = requireChatId();
|
|
6692
|
+
const response = await apiPost("/api/ads/linkedin/draft/stage", {
|
|
6693
|
+
chatId,
|
|
6694
|
+
op: preflight.data
|
|
6695
|
+
});
|
|
6696
|
+
writeJsonEnvelope(response);
|
|
6697
|
+
} catch (err) {
|
|
6698
|
+
handleLinkedinError(err);
|
|
6699
|
+
}
|
|
6700
|
+
}
|
|
6701
|
+
async function stageStatusChange(input) {
|
|
6702
|
+
const payload = input.kind === "creative.update" ? { intendedStatus: input.status } : { status: input.status };
|
|
6703
|
+
await stageOp({ kind: input.kind, accountId: input.accountId, target: input.target, payload });
|
|
6704
|
+
}
|
|
6705
|
+
function requireTarget(args, entity) {
|
|
6706
|
+
const target = args.id ?? args.target;
|
|
6707
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
6708
|
+
failWriteValidation(`pass the ${entity} id or URN as the positional argument`);
|
|
6709
|
+
}
|
|
6710
|
+
return target;
|
|
6711
|
+
}
|
|
6712
|
+
|
|
6713
|
+
// src/commands/ads/linkedin/write-commands.ts
|
|
6714
|
+
var STAGED_NOTE = "Staged until publish \u2014 review with `baker ads linkedin draft`.";
|
|
6715
|
+
var accountArgs = {
|
|
6716
|
+
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
6717
|
+
"account-urn": { type: "string", description: "Alias for --account-id" }
|
|
6718
|
+
};
|
|
6719
|
+
function runScheduleFromFlags(args) {
|
|
6720
|
+
const start = parseDateFlag(args.start, "--start");
|
|
6721
|
+
const end = parseDateFlag(args.end, "--end");
|
|
6722
|
+
if (start === void 0 && end === void 0) {
|
|
6723
|
+
return void 0;
|
|
6724
|
+
}
|
|
6725
|
+
return { ...start !== void 0 ? { start } : {}, ...end !== void 0 ? { end } : {} };
|
|
6726
|
+
}
|
|
6727
|
+
var campaignGroupsCreateCommand = defineCommand36({
|
|
6728
|
+
meta: {
|
|
6729
|
+
name: "create",
|
|
6730
|
+
description: `Stage a new campaign group. ${STAGED_NOTE}
|
|
6731
|
+
Example: baker ads linkedin campaign-groups create --name "Q3 ABM" --start 2026-07-10 --total-budget 5000 --currency EUR`
|
|
6732
|
+
},
|
|
6733
|
+
args: {
|
|
6734
|
+
...accountArgs,
|
|
6735
|
+
name: { type: "string", description: "Campaign group name (\u2264100 chars)" },
|
|
6736
|
+
start: { type: "string", description: "Run schedule start (ISO date or epoch ms)" },
|
|
6737
|
+
end: { type: "string", description: "Run schedule end" },
|
|
6738
|
+
"total-budget": { type: "string", description: "Lifetime budget amount" },
|
|
6739
|
+
currency: { type: "string", description: "3-letter currency code (required with money flags)" },
|
|
6740
|
+
status: { type: "string", description: "DRAFT|ACTIVE|PAUSED (default DRAFT)" },
|
|
6741
|
+
file: { type: "string", description: "JSON file with the full payload; flags override file keys" }
|
|
6742
|
+
},
|
|
6743
|
+
run: async ({ args }) => {
|
|
6744
|
+
const accountId = bareAccountId(args);
|
|
6745
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6746
|
+
name: args.name,
|
|
6747
|
+
runSchedule: runScheduleFromFlags(args),
|
|
6748
|
+
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
6749
|
+
status: args.status ? String(args.status).toUpperCase() : void 0
|
|
6750
|
+
});
|
|
6751
|
+
await stageOp({ kind: "campaignGroup.create", accountId, payload });
|
|
6752
|
+
}
|
|
6753
|
+
});
|
|
6754
|
+
var campaignGroupsUpdateCommand = defineCommand36({
|
|
6755
|
+
meta: {
|
|
6756
|
+
name: "update",
|
|
6757
|
+
description: `Stage changes to an existing campaign group. ${STAGED_NOTE}
|
|
6758
|
+
Example: baker ads linkedin campaign-groups update 635137195 --total-budget 8000 --currency EUR`
|
|
6759
|
+
},
|
|
6760
|
+
args: {
|
|
6761
|
+
id: { type: "positional", description: "Campaign group id or URN", required: true },
|
|
6762
|
+
...accountArgs,
|
|
6763
|
+
name: { type: "string", description: "New name" },
|
|
6764
|
+
start: { type: "string", description: "New run schedule start" },
|
|
6765
|
+
end: { type: "string", description: "New run schedule end" },
|
|
6766
|
+
"total-budget": { type: "string", description: "New lifetime budget" },
|
|
6767
|
+
currency: { type: "string", description: "3-letter currency code" },
|
|
6768
|
+
status: { type: "string", description: "ACTIVE|PAUSED|ARCHIVED|\u2026" },
|
|
6769
|
+
file: { type: "string", description: "JSON file with fields to change" }
|
|
6770
|
+
},
|
|
6771
|
+
run: async ({ args }) => {
|
|
6772
|
+
const accountId = bareAccountId(args);
|
|
6773
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6774
|
+
name: args.name,
|
|
6775
|
+
runSchedule: runScheduleFromFlags(args),
|
|
6776
|
+
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
6777
|
+
status: args.status ? String(args.status).toUpperCase() : void 0
|
|
6778
|
+
});
|
|
6779
|
+
await stageOp({
|
|
6780
|
+
kind: "campaignGroup.update",
|
|
6781
|
+
accountId,
|
|
6782
|
+
target: requireTarget(args, "campaign group"),
|
|
6783
|
+
payload
|
|
6784
|
+
});
|
|
6785
|
+
}
|
|
6786
|
+
});
|
|
6787
|
+
function campaignPayloadFromFlags(args) {
|
|
6788
|
+
return {
|
|
6789
|
+
name: args.name,
|
|
6790
|
+
campaignGroup: args.group,
|
|
6791
|
+
type: args.type ? String(args.type).toUpperCase() : void 0,
|
|
6792
|
+
objectiveType: args.objective ? String(args.objective).toUpperCase() : void 0,
|
|
6793
|
+
costType: args["cost-type"] ? String(args["cost-type"]).toUpperCase() : void 0,
|
|
6794
|
+
unitCost: parseMoneyFlag(args.bid, args.currency, "--bid"),
|
|
6795
|
+
dailyBudget: parseMoneyFlag(args["daily-budget"], args.currency, "--daily-budget"),
|
|
6796
|
+
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
6797
|
+
runSchedule: runScheduleFromFlags(args),
|
|
6798
|
+
locale: parseLocaleFlag(args.locale),
|
|
6799
|
+
targetingCriteria: loadTargetingFileArg(args["targeting-file"]),
|
|
6800
|
+
audienceExpansionEnabled: parseOnOffFlag(args["audience-expansion"], "--audience-expansion"),
|
|
6801
|
+
offsiteDeliveryEnabled: parseOnOffFlag(args.lan, "--lan"),
|
|
6802
|
+
connectedTelevisionOnly: parseOnOffFlag(args.ctv, "--ctv"),
|
|
6803
|
+
creativeSelection: args["creative-selection"] ? String(args["creative-selection"]).toUpperCase() : void 0,
|
|
6804
|
+
associatedEntity: args["associated-entity"],
|
|
6805
|
+
status: args.status ? String(args.status).toUpperCase() : void 0
|
|
6806
|
+
};
|
|
6807
|
+
}
|
|
6808
|
+
var campaignFlagArgs = {
|
|
6809
|
+
...accountArgs,
|
|
6810
|
+
name: { type: "string", description: "Campaign name (\u2264255 chars)" },
|
|
6811
|
+
group: { type: "string", description: "Campaign group id/URN, or li_temp_* ref staged in this chat" },
|
|
6812
|
+
type: { type: "string", description: "SPONSORED_UPDATES|TEXT_AD|SPONSORED_INMAILS|DYNAMIC" },
|
|
6813
|
+
objective: { type: "string", description: "e.g. LEAD_GENERATION, WEBSITE_VISIT, BRAND_AWARENESS" },
|
|
6814
|
+
"cost-type": { type: "string", description: "CPC|CPM|CPV" },
|
|
6815
|
+
bid: { type: "string", description: "Manual bid (unitCost) \u2014 playbook mandates manual bidding" },
|
|
6816
|
+
"daily-budget": { type: "string", description: "Daily budget amount" },
|
|
6817
|
+
"total-budget": { type: "string", description: "Lifetime budget amount" },
|
|
6818
|
+
currency: { type: "string", description: "3-letter currency code (required with money flags)" },
|
|
6819
|
+
start: { type: "string", description: "Run schedule start (ISO date or epoch ms)" },
|
|
6820
|
+
end: { type: "string", description: "Run schedule end" },
|
|
6821
|
+
locale: { type: "string", description: "Profile locale like en_US" },
|
|
6822
|
+
"targeting-file": { type: "string", description: "JSON file with targetingCriteria (include.and[].or facets)" },
|
|
6823
|
+
"audience-expansion": { type: "string", description: "on|off (playbook: off)" },
|
|
6824
|
+
lan: { type: "string", description: "LinkedIn Audience Network on|off (playbook: off)" },
|
|
6825
|
+
ctv: { type: "string", description: "Connected TV on|off" },
|
|
6826
|
+
"creative-selection": { type: "string", description: "OPTIMIZED|ROUND_ROBIN" },
|
|
6827
|
+
"associated-entity": { type: "string", description: "Organization URN" },
|
|
6828
|
+
status: { type: "string", description: "DRAFT|ACTIVE|PAUSED" },
|
|
6829
|
+
file: { type: "string", description: "JSON file with the full payload; flags override file keys" }
|
|
6830
|
+
};
|
|
6831
|
+
var campaignsCreateCommand = defineCommand36({
|
|
6832
|
+
meta: {
|
|
6833
|
+
name: "create",
|
|
6834
|
+
description: `Stage a new campaign. ${STAGED_NOTE}
|
|
6835
|
+
Targeting goes in --targeting-file (facet URNs). --group accepts a li_temp_* ref from a campaign group staged in this chat.
|
|
6836
|
+
Example: baker ads linkedin campaigns create --name "ABM Tier-1" --group li_temp_x1 --objective WEBSITE_VISIT --type SPONSORED_UPDATES --cost-type CPC --bid 8.50 --daily-budget 75 --currency EUR --locale en_US --targeting-file targeting.json`
|
|
6837
|
+
},
|
|
6838
|
+
args: campaignFlagArgs,
|
|
6839
|
+
run: async ({ args }) => {
|
|
6840
|
+
const accountId = bareAccountId(args);
|
|
6841
|
+
const payload = mergePayload(loadJsonFileArg(args.file), campaignPayloadFromFlags(args));
|
|
6842
|
+
if (payload.locale === void 0) {
|
|
6843
|
+
payload.locale = { country: "US", language: "en" };
|
|
6844
|
+
}
|
|
6845
|
+
await stageOp({ kind: "campaign.create", accountId, payload });
|
|
6846
|
+
}
|
|
6847
|
+
});
|
|
6848
|
+
var campaignsUpdateCommand = defineCommand36({
|
|
6849
|
+
meta: {
|
|
6850
|
+
name: "update",
|
|
6851
|
+
description: `Stage changes to an existing campaign (budget, bid, targeting, flags, schedule, status). ${STAGED_NOTE}
|
|
6852
|
+
Example: baker ads linkedin campaigns update 123456 --daily-budget 100 --currency EUR --audience-expansion off`
|
|
6853
|
+
},
|
|
6854
|
+
args: {
|
|
6855
|
+
id: { type: "positional", description: "Campaign id or URN", required: true },
|
|
6856
|
+
...campaignFlagArgs
|
|
6857
|
+
},
|
|
6858
|
+
run: async ({ args }) => {
|
|
6859
|
+
const accountId = bareAccountId(args);
|
|
6860
|
+
const flags = campaignPayloadFromFlags(args);
|
|
6861
|
+
flags.campaignGroup = void 0;
|
|
6862
|
+
flags.type = void 0;
|
|
6863
|
+
flags.locale = void 0;
|
|
6864
|
+
flags.associatedEntity = void 0;
|
|
6865
|
+
const payload = mergePayload(loadJsonFileArg(args.file), flags);
|
|
6866
|
+
await stageOp({
|
|
6867
|
+
kind: "campaign.update",
|
|
6868
|
+
accountId,
|
|
6869
|
+
target: requireTarget(args, "campaign"),
|
|
6870
|
+
payload
|
|
6871
|
+
});
|
|
6872
|
+
}
|
|
6873
|
+
});
|
|
6874
|
+
function statusSugarCommand(entity, kind, name) {
|
|
6875
|
+
const status = name === "pause" ? "PAUSED" : name === "resume" ? "ACTIVE" : "ARCHIVED";
|
|
6876
|
+
return defineCommand36({
|
|
6877
|
+
meta: {
|
|
6878
|
+
name,
|
|
6879
|
+
description: `Stage a status change to ${status}. ${STAGED_NOTE}
|
|
6880
|
+
Example: baker ads linkedin ${entity} ${name} 123456`
|
|
6881
|
+
},
|
|
6882
|
+
args: {
|
|
6883
|
+
id: { type: "positional", description: "Entity id or URN", required: true },
|
|
6884
|
+
...accountArgs
|
|
6885
|
+
},
|
|
6886
|
+
run: async ({ args }) => {
|
|
6887
|
+
await stageStatusChange({
|
|
6888
|
+
kind,
|
|
6889
|
+
accountId: bareAccountId(args),
|
|
6890
|
+
target: requireTarget(args, entity.replace(/-/g, " ").replace(/s$/, "")),
|
|
6891
|
+
status
|
|
6892
|
+
});
|
|
6893
|
+
}
|
|
6894
|
+
});
|
|
6895
|
+
}
|
|
6896
|
+
var campaignsPauseCommand = statusSugarCommand("campaigns", "campaign.update", "pause");
|
|
6897
|
+
var campaignsResumeCommand = statusSugarCommand("campaigns", "campaign.update", "resume");
|
|
6898
|
+
var campaignsArchiveCommand = statusSugarCommand("campaigns", "campaign.update", "archive");
|
|
6899
|
+
var campaignGroupsPauseCommand = statusSugarCommand("campaign-groups", "campaignGroup.update", "pause");
|
|
6900
|
+
var campaignGroupsResumeCommand = statusSugarCommand("campaign-groups", "campaignGroup.update", "resume");
|
|
6901
|
+
var creativesPauseCommand = statusSugarCommand("creatives", "creative.update", "pause");
|
|
6902
|
+
var creativesResumeCommand = statusSugarCommand("creatives", "creative.update", "resume");
|
|
6903
|
+
function duplicateCommand(entity, cliGroup) {
|
|
6904
|
+
return defineCommand36({
|
|
6905
|
+
meta: {
|
|
6906
|
+
name: "duplicate",
|
|
6907
|
+
description: `Stage a copy of an existing ${entity} as a new DRAFT create (playbook: duplicate, never link-to-original). ${STAGED_NOTE}
|
|
6908
|
+
Example: baker ads linkedin ${cliGroup} duplicate 123456 --name "New variant"`
|
|
6909
|
+
},
|
|
6910
|
+
args: {
|
|
6911
|
+
id: { type: "positional", description: "Source id or URN", required: true },
|
|
6912
|
+
...accountArgs,
|
|
6913
|
+
name: { type: "string", description: "Name for the copy" },
|
|
6914
|
+
file: { type: "string", description: "JSON file with field overrides for the copy" }
|
|
6915
|
+
},
|
|
6916
|
+
run: async ({ args }) => {
|
|
6917
|
+
try {
|
|
6918
|
+
const chatId = requireChatId();
|
|
6919
|
+
const overrides = mergePayload(loadJsonFileArg(args.file), { name: args.name });
|
|
6920
|
+
const response = await apiPost(
|
|
6921
|
+
"/api/ads/linkedin/draft/duplicate",
|
|
6922
|
+
{
|
|
6923
|
+
chatId,
|
|
6924
|
+
accountId: bareAccountId(args),
|
|
6925
|
+
entity,
|
|
6926
|
+
sourceId: requireTarget(args, entity),
|
|
6927
|
+
...Object.keys(overrides).length > 0 ? { overrides } : {}
|
|
6928
|
+
}
|
|
6929
|
+
);
|
|
6930
|
+
writeJsonEnvelope(response);
|
|
6931
|
+
} catch (err) {
|
|
6932
|
+
handleLinkedinError(err);
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
});
|
|
6936
|
+
}
|
|
6937
|
+
var campaignsDuplicateCommand = duplicateCommand("campaign", "campaigns");
|
|
6938
|
+
var campaignGroupsDuplicateCommand = duplicateCommand("campaignGroup", "campaign-groups");
|
|
6939
|
+
var creativesDuplicateCommand = duplicateCommand("creative", "creatives");
|
|
6940
|
+
var CREATIVE_FORMATS = [
|
|
6941
|
+
"image",
|
|
6942
|
+
"video",
|
|
6943
|
+
"text",
|
|
6944
|
+
"spotlight",
|
|
6945
|
+
"follower",
|
|
6946
|
+
"document",
|
|
6947
|
+
"carousel",
|
|
6948
|
+
"conversation",
|
|
6949
|
+
"tla",
|
|
6950
|
+
"jobs"
|
|
6951
|
+
];
|
|
6952
|
+
var creativesCreateCommand = defineCommand36({
|
|
6953
|
+
meta: {
|
|
6954
|
+
name: "create",
|
|
6955
|
+
description: `Stage a new creative (ad). ${STAGED_NOTE}
|
|
6956
|
+
Formats: ${CREATIVE_FORMATS.join("|")}. Media comes from the Baker library (--image-id / --video-id from \`baker images\`/\`baker videos\`) or as LinkedIn URNs. Complex formats (carousel, conversation, jobs) take --file with the full content object.
|
|
6957
|
+
Examples:
|
|
6958
|
+
baker ads linkedin creatives create --campaign li_temp_x2 --format image --image-id <bakerImageId> --intro "Meet the platform\u2026" --headline "Book a demo" --landing-url https://example.com/demo --cta REQUEST_DEMO
|
|
6959
|
+
baker ads linkedin creatives create --campaign 123456 --format tla --post-urn urn:li:ugcPost:789`
|
|
6960
|
+
},
|
|
6961
|
+
args: {
|
|
6962
|
+
...accountArgs,
|
|
6963
|
+
campaign: { type: "string", description: "Campaign id/URN, or li_temp_* ref staged in this chat" },
|
|
6964
|
+
format: { type: "string", description: CREATIVE_FORMATS.join("|") },
|
|
6965
|
+
"image-id": { type: "string", description: "Baker image library id (uploaded to LinkedIn at publish)" },
|
|
6966
|
+
"image-urn": { type: "string", description: "Existing urn:li:image:*" },
|
|
6967
|
+
"video-id": { type: "string", description: "Baker video library id" },
|
|
6968
|
+
"video-urn": { type: "string", description: "Existing urn:li:video:*" },
|
|
6969
|
+
"logo-image-id": { type: "string", description: "Baker image id for logo (text/spotlight/follower/jobs)" },
|
|
6970
|
+
intro: { type: "string", description: "Commentary / intro text (\u2264600 chars before feed truncation)" },
|
|
6971
|
+
headline: { type: "string", description: "Headline (\u226470; text ads \u226425)" },
|
|
6972
|
+
description: { type: "string", description: "Description (text ads \u226475, spotlight \u226470)" },
|
|
6973
|
+
"landing-url": { type: "string", description: "https destination URL" },
|
|
6974
|
+
cta: { type: "string", description: "LEARN_MORE|REQUEST_DEMO|SIGN_UP|REGISTER|DOWNLOAD|\u2026" },
|
|
6975
|
+
"cta-label": { type: "string", description: "Spotlight custom CTA label (\u226418 chars)" },
|
|
6976
|
+
"post-urn": { type: "string", description: "TLA: existing post to sponsor (urn:li:share|ugcPost:*)" },
|
|
6977
|
+
"intended-status": { type: "string", description: "DRAFT|ACTIVE|PAUSED (default DRAFT)" },
|
|
6978
|
+
title: { type: "string", description: "Media title" },
|
|
6979
|
+
file: { type: "string", description: "JSON file with the full content object; flags override" }
|
|
6980
|
+
},
|
|
6981
|
+
run: async ({ args }) => {
|
|
6982
|
+
const accountId = bareAccountId(args);
|
|
6983
|
+
if (!args.campaign) {
|
|
6984
|
+
failWriteValidation("--campaign is required (id, URN, or li_temp_* ref)");
|
|
6985
|
+
}
|
|
6986
|
+
const format = args.format ? String(args.format) : void 0;
|
|
6987
|
+
if (!format || !CREATIVE_FORMATS.includes(format)) {
|
|
6988
|
+
failWriteValidation(`--format must be one of ${CREATIVE_FORMATS.join("|")}`);
|
|
6989
|
+
}
|
|
6990
|
+
const content = mergePayload(loadJsonFileArg(args.file), {
|
|
6991
|
+
format,
|
|
6992
|
+
commentary: args.intro,
|
|
6993
|
+
imageId: args["image-id"],
|
|
6994
|
+
imageUrn: args["image-urn"],
|
|
6995
|
+
videoId: args["video-id"],
|
|
6996
|
+
videoUrn: args["video-urn"],
|
|
6997
|
+
logoImageId: args["logo-image-id"],
|
|
6998
|
+
headline: args.headline,
|
|
6999
|
+
description: args.description,
|
|
7000
|
+
landingUrl: args["landing-url"],
|
|
7001
|
+
cta: args.cta ? String(args.cta).toUpperCase() : void 0,
|
|
7002
|
+
ctaLabel: args["cta-label"],
|
|
7003
|
+
postUrn: args["post-urn"],
|
|
7004
|
+
mediaTitle: args.title
|
|
7005
|
+
});
|
|
7006
|
+
await stageOp({
|
|
7007
|
+
kind: "creative.create",
|
|
7008
|
+
accountId,
|
|
7009
|
+
payload: {
|
|
7010
|
+
campaign: args.campaign,
|
|
7011
|
+
intendedStatus: args["intended-status"] ? String(args["intended-status"]).toUpperCase() : void 0,
|
|
7012
|
+
content
|
|
7013
|
+
}
|
|
7014
|
+
});
|
|
7015
|
+
}
|
|
7016
|
+
});
|
|
7017
|
+
var creativesUpdateCommand = defineCommand36({
|
|
7018
|
+
meta: {
|
|
7019
|
+
name: "update",
|
|
7020
|
+
description: `Stage changes to an existing creative. ${STAGED_NOTE}
|
|
7021
|
+
Example: baker ads linkedin creatives update urn:li:sponsoredCreative:789 --intended-status PAUSED`
|
|
7022
|
+
},
|
|
7023
|
+
args: {
|
|
7024
|
+
id: { type: "positional", description: "Creative id or URN", required: true },
|
|
7025
|
+
...accountArgs,
|
|
7026
|
+
"intended-status": { type: "string", description: "ACTIVE|PAUSED|ARCHIVED|DRAFT" },
|
|
7027
|
+
name: { type: "string", description: "New creative name" },
|
|
7028
|
+
file: { type: "string", description: "JSON file with fields to change" }
|
|
7029
|
+
},
|
|
7030
|
+
run: async ({ args }) => {
|
|
7031
|
+
const accountId = bareAccountId(args);
|
|
7032
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
7033
|
+
intendedStatus: args["intended-status"] ? String(args["intended-status"]).toUpperCase() : void 0,
|
|
7034
|
+
name: args.name
|
|
7035
|
+
});
|
|
7036
|
+
await stageOp({
|
|
7037
|
+
kind: "creative.update",
|
|
7038
|
+
accountId,
|
|
7039
|
+
target: requireTarget(args, "creative"),
|
|
7040
|
+
payload
|
|
7041
|
+
});
|
|
7042
|
+
}
|
|
7043
|
+
});
|
|
7044
|
+
var AUDIENCE_TYPES2 = ["company-list", "user-list", "retargeting", "engagement"];
|
|
7045
|
+
var INLINE_ROWS_MAX = 1e4;
|
|
7046
|
+
var audiencesCreateCommand = defineCommand36({
|
|
7047
|
+
meta: {
|
|
7048
|
+
name: "create",
|
|
7049
|
+
description: `Stage a new matched audience. ${STAGED_NOTE}
|
|
7050
|
+
List audiences take --list-file (CSV: companyName,domain for companies; email,\u2026 for contacts \u2014 emails are SHA-256 hashed locally). LinkedIn needs 300+ MATCHED members to serve.
|
|
7051
|
+
Example: baker ads linkedin audiences create --name "ABM Tier-1" --type company-list --list-file accounts.csv`
|
|
7052
|
+
},
|
|
7053
|
+
args: {
|
|
7054
|
+
...accountArgs,
|
|
7055
|
+
name: { type: "string", description: "Audience name (\u2264100 chars)" },
|
|
7056
|
+
type: { type: "string", description: AUDIENCE_TYPES2.join("|") },
|
|
7057
|
+
"list-file": { type: "string", description: "CSV file with the list rows (header row required)" },
|
|
7058
|
+
file: { type: "string", description: "JSON file with a raw source config (retargeting/engagement)" }
|
|
7059
|
+
},
|
|
7060
|
+
run: async ({ args }) => {
|
|
7061
|
+
const accountId = bareAccountId(args);
|
|
7062
|
+
const list = parseListFileArg(args["list-file"], INLINE_ROWS_MAX);
|
|
7063
|
+
const raw = args.file ? loadJsonFileArg(args.file) : void 0;
|
|
7064
|
+
await stageOp({
|
|
7065
|
+
kind: "audience.create",
|
|
7066
|
+
accountId,
|
|
7067
|
+
payload: {
|
|
7068
|
+
name: args.name,
|
|
7069
|
+
audienceType: args.type,
|
|
7070
|
+
...list ? { listColumns: list.columns, listRows: list.rows } : {},
|
|
7071
|
+
...raw ? { raw } : {}
|
|
7072
|
+
}
|
|
7073
|
+
});
|
|
7074
|
+
}
|
|
7075
|
+
});
|
|
7076
|
+
var audiencesUploadCommand = defineCommand36({
|
|
7077
|
+
meta: {
|
|
7078
|
+
name: "upload",
|
|
7079
|
+
description: `Stage a list upload into an existing audience segment. ${STAGED_NOTE}
|
|
7080
|
+
Example: baker ads linkedin audiences upload urn:li:dmpSegment:42 --list-file more-accounts.csv`
|
|
7081
|
+
},
|
|
7082
|
+
args: {
|
|
7083
|
+
id: { type: "positional", description: "Segment URN/id, or li_temp_* ref staged in this chat", required: true },
|
|
7084
|
+
...accountArgs,
|
|
7085
|
+
"list-file": { type: "string", description: "CSV file with the rows to add", required: true }
|
|
7086
|
+
},
|
|
7087
|
+
run: async ({ args }) => {
|
|
7088
|
+
const accountId = bareAccountId(args);
|
|
7089
|
+
const list = parseListFileArg(args["list-file"], INLINE_ROWS_MAX);
|
|
7090
|
+
if (!list) {
|
|
7091
|
+
failWriteValidation("--list-file is required");
|
|
7092
|
+
}
|
|
7093
|
+
await stageOp({
|
|
7094
|
+
kind: "audience.uploadList",
|
|
7095
|
+
accountId,
|
|
7096
|
+
payload: {
|
|
7097
|
+
segment: requireTarget(args, "audience segment"),
|
|
7098
|
+
listColumns: list.columns,
|
|
7099
|
+
listRows: list.rows
|
|
7100
|
+
}
|
|
7101
|
+
});
|
|
7102
|
+
}
|
|
7103
|
+
});
|
|
7104
|
+
var audiencesCommand = defineCommand36({
|
|
7105
|
+
meta: {
|
|
7106
|
+
name: "audiences",
|
|
7107
|
+
description: "Stage LinkedIn matched-audience changes (create lists, upload rows). Staged until publish \u2014 never hits the API directly."
|
|
7108
|
+
},
|
|
7109
|
+
subCommands: {
|
|
7110
|
+
create: audiencesCreateCommand,
|
|
7111
|
+
upload: audiencesUploadCommand
|
|
7112
|
+
}
|
|
7113
|
+
});
|
|
7114
|
+
var conversionsCreateCommand = defineCommand36({
|
|
7115
|
+
meta: {
|
|
7116
|
+
name: "create",
|
|
7117
|
+
description: `Stage a new conversion rule. ${STAGED_NOTE}
|
|
7118
|
+
Example: baker ads linkedin conversions create --name "Demo booked" --type LEAD --method INSIGHT_TAG --post-click-window 30 --view-window 7`
|
|
7119
|
+
},
|
|
7120
|
+
args: {
|
|
7121
|
+
...accountArgs,
|
|
7122
|
+
name: { type: "string", description: "Conversion rule name" },
|
|
7123
|
+
type: { type: "string", description: "LEAD|SIGN_UP|DOWNLOAD|PURCHASE|KEY_PAGE_VIEW|ADD_TO_CART|INSTALL|OTHER" },
|
|
7124
|
+
method: { type: "string", description: "INSIGHT_TAG|CONVERSIONS_API" },
|
|
7125
|
+
"post-click-window": { type: "string", description: "1|7|30|90 days (playbook default 30)" },
|
|
7126
|
+
"view-window": { type: "string", description: "1|7|30 days (playbook default 7)" },
|
|
7127
|
+
"attribution-type": { type: "string", description: "LAST_TOUCH_BY_CAMPAIGN|LAST_TOUCH_BY_CONVERSION" },
|
|
7128
|
+
"associate-all-campaigns": { type: "boolean", description: "Auto-associate with active campaigns" },
|
|
7129
|
+
file: { type: "string", description: "JSON file with the full payload (e.g. urlMatchRuleExpression)" }
|
|
7130
|
+
},
|
|
7131
|
+
run: async ({ args }) => {
|
|
7132
|
+
const accountId = bareAccountId(args);
|
|
7133
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
7134
|
+
name: args.name,
|
|
7135
|
+
type: args.type ? String(args.type).toUpperCase() : void 0,
|
|
7136
|
+
conversionMethod: args.method ? String(args.method).toUpperCase() : void 0,
|
|
7137
|
+
postClickAttributionWindowSize: args["post-click-window"] ? Number(args["post-click-window"]) : void 0,
|
|
7138
|
+
viewThroughAttributionWindowSize: args["view-window"] ? Number(args["view-window"]) : void 0,
|
|
7139
|
+
attributionType: args["attribution-type"] ? String(args["attribution-type"]).toUpperCase() : void 0,
|
|
7140
|
+
associateAllCampaigns: args["associate-all-campaigns"] === true ? true : void 0
|
|
7141
|
+
});
|
|
7142
|
+
await stageOp({ kind: "conversion.create", accountId, payload });
|
|
7143
|
+
}
|
|
7144
|
+
});
|
|
7145
|
+
var conversionsUpdateCommand = defineCommand36({
|
|
7146
|
+
meta: {
|
|
7147
|
+
name: "update",
|
|
7148
|
+
description: `Stage changes to a conversion rule (windows, name, enabled). ${STAGED_NOTE}
|
|
7149
|
+
Example: baker ads linkedin conversions update 104988516 --post-click-window 30 --view-window 7`
|
|
7150
|
+
},
|
|
7151
|
+
args: {
|
|
7152
|
+
id: { type: "positional", description: "Conversion rule id or URN", required: true },
|
|
7153
|
+
...accountArgs,
|
|
7154
|
+
name: { type: "string", description: "New name" },
|
|
7155
|
+
"post-click-window": { type: "string", description: "1|7|30|90 days" },
|
|
7156
|
+
"view-window": { type: "string", description: "1|7|30 days" },
|
|
7157
|
+
"attribution-type": { type: "string", description: "LAST_TOUCH_BY_CAMPAIGN|LAST_TOUCH_BY_CONVERSION" },
|
|
7158
|
+
enabled: { type: "string", description: "on|off" },
|
|
7159
|
+
file: { type: "string", description: "JSON file with fields to change" }
|
|
7160
|
+
},
|
|
7161
|
+
run: async ({ args }) => {
|
|
7162
|
+
const accountId = bareAccountId(args);
|
|
7163
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
7164
|
+
name: args.name,
|
|
7165
|
+
postClickAttributionWindowSize: args["post-click-window"] ? Number(args["post-click-window"]) : void 0,
|
|
7166
|
+
viewThroughAttributionWindowSize: args["view-window"] ? Number(args["view-window"]) : void 0,
|
|
7167
|
+
attributionType: args["attribution-type"] ? String(args["attribution-type"]).toUpperCase() : void 0,
|
|
7168
|
+
enabled: parseOnOffFlag(args.enabled, "--enabled")
|
|
7169
|
+
});
|
|
7170
|
+
await stageOp({
|
|
7171
|
+
kind: "conversion.update",
|
|
7172
|
+
accountId,
|
|
7173
|
+
target: requireTarget(args, "conversion rule"),
|
|
7174
|
+
payload
|
|
7175
|
+
});
|
|
7176
|
+
}
|
|
7177
|
+
});
|
|
7178
|
+
var leadFormsCreateCommand = defineCommand36({
|
|
7179
|
+
meta: {
|
|
7180
|
+
name: "create",
|
|
7181
|
+
description: `Stage a new Lead Gen Form from a JSON file. ${STAGED_NOTE}
|
|
7182
|
+
The file needs: name, headline (\u226460), privacyPolicyUrl, questions[] (\u226412; playbook: \u22644 for completion). Example: baker ads linkedin lead-forms create --file form.json`
|
|
7183
|
+
},
|
|
7184
|
+
args: {
|
|
7185
|
+
...accountArgs,
|
|
7186
|
+
file: { type: "string", description: "JSON file with the form definition", required: true },
|
|
7187
|
+
name: { type: "string", description: "Override the form name" }
|
|
7188
|
+
},
|
|
7189
|
+
run: async ({ args }) => {
|
|
7190
|
+
const accountId = bareAccountId(args);
|
|
7191
|
+
const payload = mergePayload(loadJsonFileArg(args.file), { name: args.name });
|
|
7192
|
+
await stageOp({ kind: "leadForm.create", accountId, payload });
|
|
7193
|
+
}
|
|
7194
|
+
});
|
|
7195
|
+
var leadFormsUpdateCommand = defineCommand36({
|
|
7196
|
+
meta: {
|
|
7197
|
+
name: "update",
|
|
7198
|
+
description: `Stage changes to a Lead Gen Form from a JSON file. ${STAGED_NOTE}`
|
|
7199
|
+
},
|
|
7200
|
+
args: {
|
|
7201
|
+
id: { type: "positional", description: "Lead form id or URN", required: true },
|
|
7202
|
+
...accountArgs,
|
|
7203
|
+
file: { type: "string", description: "JSON file with the fields to change", required: true },
|
|
7204
|
+
name: { type: "string", description: "New form name" }
|
|
7205
|
+
},
|
|
7206
|
+
run: async ({ args }) => {
|
|
7207
|
+
const accountId = bareAccountId(args);
|
|
7208
|
+
const payload = mergePayload({ raw: loadJsonFileArg(args.file) }, { name: args.name });
|
|
7209
|
+
await stageOp({
|
|
7210
|
+
kind: "leadForm.update",
|
|
7211
|
+
accountId,
|
|
7212
|
+
target: requireTarget(args, "lead form"),
|
|
7213
|
+
payload
|
|
7214
|
+
});
|
|
7215
|
+
}
|
|
7216
|
+
});
|
|
7217
|
+
var leadFormsCommand = defineCommand36({
|
|
7218
|
+
meta: {
|
|
7219
|
+
name: "lead-forms",
|
|
7220
|
+
description: "Stage LinkedIn Lead Gen Form changes (file-first). Staged until publish \u2014 never hits the API directly."
|
|
7221
|
+
},
|
|
7222
|
+
subCommands: {
|
|
7223
|
+
create: leadFormsCreateCommand,
|
|
7224
|
+
update: leadFormsUpdateCommand
|
|
7225
|
+
}
|
|
7226
|
+
});
|
|
7227
|
+
|
|
7228
|
+
// src/commands/ads/linkedin/campaign-groups.ts
|
|
7229
|
+
var campaignGroupsCommand = defineCommand37({
|
|
7230
|
+
meta: {
|
|
7231
|
+
name: "campaign-groups",
|
|
7232
|
+
description: `List LinkedIn campaign groups, or stage writes (create/update/pause/resume/duplicate).
|
|
7233
|
+
|
|
7234
|
+
Default: ACTIVE only. Pass --all-statuses to widen, or --statuses ACTIVE,PAUSED to override.
|
|
7235
|
+
Write subcommands stage ops on this chat's draft and apply only when the chat is published.
|
|
7236
|
+
|
|
7237
|
+
Examples:
|
|
7238
|
+
baker ads linkedin campaign-groups --account-id 503001492
|
|
7239
|
+
baker ads linkedin campaign-groups --account-id 503001492 --all-statuses
|
|
7240
|
+
baker ads linkedin campaign-groups create --name "Q3 ABM" --start 2026-07-10 --total-budget 5000 --currency EUR`
|
|
7241
|
+
},
|
|
7242
|
+
subCommands: {
|
|
7243
|
+
create: campaignGroupsCreateCommand,
|
|
7244
|
+
update: campaignGroupsUpdateCommand,
|
|
7245
|
+
pause: campaignGroupsPauseCommand,
|
|
7246
|
+
resume: campaignGroupsResumeCommand,
|
|
7247
|
+
duplicate: campaignGroupsDuplicateCommand
|
|
7248
|
+
},
|
|
7249
|
+
args: {
|
|
7250
|
+
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
7251
|
+
"account-urn": { type: "string", description: "Alias for --account-id" },
|
|
7252
|
+
"all-statuses": { type: "boolean", description: "Drop the default ACTIVE filter" },
|
|
7253
|
+
statuses: { type: "string", description: "CSV of statuses (ACTIVE,PAUSED,ARCHIVED,COMPLETED,DRAFT)" },
|
|
7254
|
+
limit: { type: "string", description: "Max rows (default: 500)" },
|
|
7255
|
+
"skip-cache": { type: "boolean", description: "Bypass server-side cache" },
|
|
7256
|
+
output: { type: "string", description: "json|csv|jsonl|md", default: "json" }
|
|
7257
|
+
},
|
|
7258
|
+
run: async ({ args }) => {
|
|
7259
|
+
const accountId = resolveAccountIdArg(args);
|
|
7260
|
+
try {
|
|
7261
|
+
const params = { "account-id": accountId };
|
|
7262
|
+
const statuses = resolveStatusFilter(args);
|
|
7263
|
+
if (statuses) params.statuses = statuses.join(",");
|
|
7264
|
+
if (args.limit) params.limit = String(args.limit);
|
|
7265
|
+
if (args["skip-cache"]) params["skip-cache"] = "true";
|
|
7266
|
+
const data = await apiGet("/api/ads/linkedin/campaign-groups", params);
|
|
7267
|
+
const fmt = csvOrJson(args);
|
|
7268
|
+
if (fmt !== "json") {
|
|
7269
|
+
writeAdsOutput(data, fmt);
|
|
7270
|
+
return;
|
|
7271
|
+
}
|
|
7272
|
+
writeAdsJson({ ok: true, data });
|
|
7273
|
+
} catch (err) {
|
|
7274
|
+
handleLinkedinError(err);
|
|
7275
|
+
}
|
|
5721
7276
|
}
|
|
5722
7277
|
});
|
|
5723
7278
|
|
|
5724
7279
|
// src/commands/ads/linkedin/campaigns.ts
|
|
5725
|
-
import { defineCommand as
|
|
5726
|
-
var campaignsCommand =
|
|
7280
|
+
import { defineCommand as defineCommand38 } from "citty";
|
|
7281
|
+
var campaignsCommand = defineCommand38({
|
|
5727
7282
|
meta: {
|
|
5728
7283
|
name: "campaigns",
|
|
5729
|
-
description: `List LinkedIn campaigns.
|
|
7284
|
+
description: `List LinkedIn campaigns, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
5730
7285
|
|
|
5731
7286
|
Default: ACTIVE only. The schema includes the audit-relevant settings:
|
|
5732
7287
|
audienceExpansionEnabled \u2014 playbook \xA702 silent budget drain (should be false)
|
|
@@ -5734,10 +7289,22 @@ Default: ACTIVE only. The schema includes the audit-relevant settings:
|
|
|
5734
7289
|
optimizationTargetType \u2014 driver of the bidding strategy
|
|
5735
7290
|
costType \u2014 CPC | CPM | CPV | CPS
|
|
5736
7291
|
|
|
7292
|
+
Write subcommands stage ops on this chat's draft \u2014 they never hit the LinkedIn
|
|
7293
|
+
API directly and apply only when the chat is published.
|
|
7294
|
+
|
|
5737
7295
|
Examples:
|
|
5738
7296
|
baker ads linkedin campaigns --account-id 503001492
|
|
5739
|
-
baker ads linkedin campaigns --account-id 503001492 --
|
|
5740
|
-
baker ads linkedin campaigns
|
|
7297
|
+
baker ads linkedin campaigns --account-id 503001492 --all-statuses --output csv
|
|
7298
|
+
baker ads linkedin campaigns update 123456 --daily-budget 100 --currency EUR
|
|
7299
|
+
baker ads linkedin campaigns pause 123456`
|
|
7300
|
+
},
|
|
7301
|
+
subCommands: {
|
|
7302
|
+
create: campaignsCreateCommand,
|
|
7303
|
+
update: campaignsUpdateCommand,
|
|
7304
|
+
pause: campaignsPauseCommand,
|
|
7305
|
+
resume: campaignsResumeCommand,
|
|
7306
|
+
archive: campaignsArchiveCommand,
|
|
7307
|
+
duplicate: campaignsDuplicateCommand
|
|
5741
7308
|
},
|
|
5742
7309
|
args: {
|
|
5743
7310
|
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
@@ -5772,8 +7339,8 @@ Examples:
|
|
|
5772
7339
|
});
|
|
5773
7340
|
|
|
5774
7341
|
// src/commands/ads/linkedin/conversation.ts
|
|
5775
|
-
import { defineCommand as
|
|
5776
|
-
var conversationCommand =
|
|
7342
|
+
import { defineCommand as defineCommand39 } from "citty";
|
|
7343
|
+
var conversationCommand = defineCommand39({
|
|
5777
7344
|
meta: {
|
|
5778
7345
|
name: "conversation",
|
|
5779
7346
|
description: `Per-button click rates inside Sponsored Messaging / Conversation Ads.
|
|
@@ -5836,7 +7403,7 @@ Examples:
|
|
|
5836
7403
|
});
|
|
5837
7404
|
|
|
5838
7405
|
// src/commands/ads/linkedin/conversions.ts
|
|
5839
|
-
import { defineCommand as
|
|
7406
|
+
import { defineCommand as defineCommand40 } from "citty";
|
|
5840
7407
|
var DAY_MS3 = 864e5;
|
|
5841
7408
|
function healthOf(rules) {
|
|
5842
7409
|
const enabled = rules.filter((r) => r.enabled !== false);
|
|
@@ -5862,7 +7429,7 @@ function healthOf(rules) {
|
|
|
5862
7429
|
wrongLeadDedup: wrongDedup
|
|
5863
7430
|
};
|
|
5864
7431
|
}
|
|
5865
|
-
var listCmd =
|
|
7432
|
+
var listCmd = defineCommand40({
|
|
5866
7433
|
meta: {
|
|
5867
7434
|
name: "list",
|
|
5868
7435
|
description: `List conversion rules on the account.`
|
|
@@ -5890,7 +7457,7 @@ var listCmd = defineCommand39({
|
|
|
5890
7457
|
}
|
|
5891
7458
|
}
|
|
5892
7459
|
});
|
|
5893
|
-
var healthCmd =
|
|
7460
|
+
var healthCmd = defineCommand40({
|
|
5894
7461
|
meta: {
|
|
5895
7462
|
name: "health",
|
|
5896
7463
|
description: `5-point Insight Tag / CAPI health check (playbook \xA707).
|
|
@@ -5920,27 +7487,30 @@ Surfaces:
|
|
|
5920
7487
|
}
|
|
5921
7488
|
}
|
|
5922
7489
|
});
|
|
5923
|
-
var conversionsCommand =
|
|
7490
|
+
var conversionsCommand = defineCommand40({
|
|
5924
7491
|
meta: {
|
|
5925
7492
|
name: "conversions",
|
|
5926
7493
|
description: `Conversion rules \u2014 Insight Tag and Conversions API.
|
|
5927
7494
|
|
|
5928
7495
|
Subcommands:
|
|
5929
7496
|
list \u2014 every rule on the account
|
|
5930
|
-
health \u2014 playbook \xA707 5-point health check
|
|
7497
|
+
health \u2014 playbook \xA707 5-point health check
|
|
7498
|
+
create / update \u2014 stage a conversion-rule write (applies on chat publish)`
|
|
5931
7499
|
},
|
|
5932
7500
|
subCommands: {
|
|
5933
7501
|
list: listCmd,
|
|
5934
|
-
health: healthCmd
|
|
7502
|
+
health: healthCmd,
|
|
7503
|
+
create: conversionsCreateCommand,
|
|
7504
|
+
update: conversionsUpdateCommand
|
|
5935
7505
|
}
|
|
5936
7506
|
});
|
|
5937
7507
|
|
|
5938
7508
|
// src/commands/ads/linkedin/creatives.ts
|
|
5939
|
-
import { defineCommand as
|
|
5940
|
-
var creativesCommand =
|
|
7509
|
+
import { defineCommand as defineCommand41 } from "citty";
|
|
7510
|
+
var creativesCommand = defineCommand41({
|
|
5941
7511
|
meta: {
|
|
5942
7512
|
name: "creatives",
|
|
5943
|
-
description: `List LinkedIn creatives (ads).
|
|
7513
|
+
description: `List LinkedIn creatives (ads), or stage writes (create/update/pause/resume/duplicate).
|
|
5944
7514
|
|
|
5945
7515
|
Defaults to ACTIVE intended-status. Pass --all-statuses or --statuses ACTIVE,PAUSED to widen.
|
|
5946
7516
|
|
|
@@ -5948,10 +7518,20 @@ The 'content' block is opaque (varies by creative type \u2014 image, video, docu
|
|
|
5948
7518
|
spotlight, conversation, dynamic). Use 'reviewStatus' to spot rejected/pending
|
|
5949
7519
|
creatives during an audit.
|
|
5950
7520
|
|
|
7521
|
+
Write subcommands stage ops on this chat's draft \u2014 media comes from the Baker
|
|
7522
|
+
library and is uploaded to LinkedIn only at publish.
|
|
7523
|
+
|
|
5951
7524
|
Examples:
|
|
5952
7525
|
baker ads linkedin creatives --account-id 503001492
|
|
5953
|
-
baker ads linkedin creatives --
|
|
5954
|
-
baker ads linkedin creatives
|
|
7526
|
+
baker ads linkedin creatives create --campaign 1234 --format image --image-id <bakerImageId> --intro "\u2026" --headline "Book a demo" --landing-url https://example.com --cta REQUEST_DEMO
|
|
7527
|
+
baker ads linkedin creatives pause urn:li:sponsoredCreative:789`
|
|
7528
|
+
},
|
|
7529
|
+
subCommands: {
|
|
7530
|
+
create: creativesCreateCommand,
|
|
7531
|
+
update: creativesUpdateCommand,
|
|
7532
|
+
pause: creativesPauseCommand,
|
|
7533
|
+
resume: creativesResumeCommand,
|
|
7534
|
+
duplicate: creativesDuplicateCommand
|
|
5955
7535
|
},
|
|
5956
7536
|
args: {
|
|
5957
7537
|
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
@@ -5986,7 +7566,7 @@ Examples:
|
|
|
5986
7566
|
});
|
|
5987
7567
|
|
|
5988
7568
|
// src/commands/ads/linkedin/demographics.ts
|
|
5989
|
-
import { defineCommand as
|
|
7569
|
+
import { defineCommand as defineCommand42 } from "citty";
|
|
5990
7570
|
var DEFAULT_PIVOTS = ["job-title", "company", "industry", "seniority", "job-function", "company-size"];
|
|
5991
7571
|
function numberOf2(v) {
|
|
5992
7572
|
if (typeof v === "number") return Number.isFinite(v) ? v : 0;
|
|
@@ -5999,7 +7579,7 @@ function numberOf2(v) {
|
|
|
5999
7579
|
function topByImpressions(rows, limit) {
|
|
6000
7580
|
return [...rows].sort((a, b) => numberOf2(b.impressions) - numberOf2(a.impressions)).slice(0, limit);
|
|
6001
7581
|
}
|
|
6002
|
-
var demographicsCommand =
|
|
7582
|
+
var demographicsCommand = defineCommand42({
|
|
6003
7583
|
meta: {
|
|
6004
7584
|
name: "demographics",
|
|
6005
7585
|
description: `Sweep all firmographic pivots in one command \u2014 LinkedIn's superpower.
|
|
@@ -6082,22 +7662,97 @@ Examples:
|
|
|
6082
7662
|
}
|
|
6083
7663
|
}
|
|
6084
7664
|
});
|
|
6085
|
-
function resolveRange(args) {
|
|
6086
|
-
const start = args.start;
|
|
6087
|
-
const end = args.end;
|
|
6088
|
-
if (start) {
|
|
6089
|
-
return { start, end };
|
|
6090
|
-
}
|
|
6091
|
-
const days = args["last-days"] ? Number(args["last-days"]) : 30;
|
|
6092
|
-
if (!Number.isFinite(days) || days < 1) {
|
|
6093
|
-
handleLinkedinError(new Error("Invalid --last-days; must be a positive integer."));
|
|
6094
|
-
}
|
|
6095
|
-
return { start: daysAgoIso(days), end: todayIso() };
|
|
6096
|
-
}
|
|
7665
|
+
function resolveRange(args) {
|
|
7666
|
+
const start = args.start;
|
|
7667
|
+
const end = args.end;
|
|
7668
|
+
if (start) {
|
|
7669
|
+
return { start, end };
|
|
7670
|
+
}
|
|
7671
|
+
const days = args["last-days"] ? Number(args["last-days"]) : 30;
|
|
7672
|
+
if (!Number.isFinite(days) || days < 1) {
|
|
7673
|
+
handleLinkedinError(new Error("Invalid --last-days; must be a positive integer."));
|
|
7674
|
+
}
|
|
7675
|
+
return { start: daysAgoIso(days), end: todayIso() };
|
|
7676
|
+
}
|
|
7677
|
+
|
|
7678
|
+
// src/commands/ads/linkedin/draft.ts
|
|
7679
|
+
import { defineCommand as defineCommand43 } from "citty";
|
|
7680
|
+
async function listDraft() {
|
|
7681
|
+
try {
|
|
7682
|
+
const chatId = requireChatId();
|
|
7683
|
+
const response = await apiPost("/api/ads/linkedin/draft", {
|
|
7684
|
+
chatId
|
|
7685
|
+
});
|
|
7686
|
+
writeJsonEnvelope(response);
|
|
7687
|
+
} catch (err) {
|
|
7688
|
+
handleLinkedinError(err);
|
|
7689
|
+
}
|
|
7690
|
+
}
|
|
7691
|
+
var listCommand3 = defineCommand43({
|
|
7692
|
+
meta: {
|
|
7693
|
+
name: "list",
|
|
7694
|
+
description: "Show every LinkedIn write op staged in this chat, its mode (simulated = publish will NOT hit LinkedIn), dependencies, and post-publish results. Example: baker ads linkedin draft"
|
|
7695
|
+
},
|
|
7696
|
+
run: listDraft
|
|
7697
|
+
});
|
|
7698
|
+
var removeCommand2 = defineCommand43({
|
|
7699
|
+
meta: {
|
|
7700
|
+
name: "remove",
|
|
7701
|
+
description: "Drop one staged LinkedIn op. Removing a create cascades to everything that depends on it. Example: baker ads linkedin draft remove li_temp_abc123"
|
|
7702
|
+
},
|
|
7703
|
+
args: {
|
|
7704
|
+
ref: {
|
|
7705
|
+
type: "positional",
|
|
7706
|
+
description: "Op ref (li_temp_* for creates, target id/URN for updates)",
|
|
7707
|
+
required: true
|
|
7708
|
+
}
|
|
7709
|
+
},
|
|
7710
|
+
run: async ({ args }) => {
|
|
7711
|
+
try {
|
|
7712
|
+
const chatId = requireChatId();
|
|
7713
|
+
const response = await apiPost(
|
|
7714
|
+
"/api/ads/linkedin/draft/remove",
|
|
7715
|
+
{ chatId, ref: args.ref }
|
|
7716
|
+
);
|
|
7717
|
+
writeJsonEnvelope(response);
|
|
7718
|
+
} catch (err) {
|
|
7719
|
+
handleLinkedinError(err);
|
|
7720
|
+
}
|
|
7721
|
+
}
|
|
7722
|
+
});
|
|
7723
|
+
var clearCommand2 = defineCommand43({
|
|
7724
|
+
meta: {
|
|
7725
|
+
name: "clear",
|
|
7726
|
+
description: "Discard ALL staged LinkedIn ops in this chat's draft \u2014 nothing will apply on publish. Example: baker ads linkedin draft clear"
|
|
7727
|
+
},
|
|
7728
|
+
run: async () => {
|
|
7729
|
+
try {
|
|
7730
|
+
const chatId = requireChatId();
|
|
7731
|
+
const response = await apiPost("/api/ads/linkedin/draft/clear", {
|
|
7732
|
+
chatId
|
|
7733
|
+
});
|
|
7734
|
+
writeJsonEnvelope(response);
|
|
7735
|
+
} catch (err) {
|
|
7736
|
+
handleLinkedinError(err);
|
|
7737
|
+
}
|
|
7738
|
+
}
|
|
7739
|
+
});
|
|
7740
|
+
var linkedinDraftCommand = defineCommand43({
|
|
7741
|
+
meta: {
|
|
7742
|
+
name: "draft",
|
|
7743
|
+
description: "Review and edit the LinkedIn write ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear. Ops never hit LinkedIn until the chat is published."
|
|
7744
|
+
},
|
|
7745
|
+
subCommands: {
|
|
7746
|
+
list: listCommand3,
|
|
7747
|
+
remove: removeCommand2,
|
|
7748
|
+
clear: clearCommand2
|
|
7749
|
+
},
|
|
7750
|
+
run: listDraft
|
|
7751
|
+
});
|
|
6097
7752
|
|
|
6098
7753
|
// src/commands/ads/linkedin/facets.ts
|
|
6099
|
-
import { defineCommand as
|
|
6100
|
-
var listCmd2 =
|
|
7754
|
+
import { defineCommand as defineCommand44 } from "citty";
|
|
7755
|
+
var listCmd2 = defineCommand44({
|
|
6101
7756
|
meta: {
|
|
6102
7757
|
name: "list",
|
|
6103
7758
|
description: `List every targeting facet LinkedIn supports.
|
|
@@ -6125,7 +7780,7 @@ seniorities, titles, employers, growthRate, companyCategory, skills, etc.).`
|
|
|
6125
7780
|
}
|
|
6126
7781
|
}
|
|
6127
7782
|
});
|
|
6128
|
-
var valuesCmd =
|
|
7783
|
+
var valuesCmd = defineCommand44({
|
|
6129
7784
|
meta: {
|
|
6130
7785
|
name: "values",
|
|
6131
7786
|
description: `Look up entity values for a single facet \u2014 full list or typeahead search.
|
|
@@ -6166,7 +7821,7 @@ or the full URN (urn:li:adTargetingFacet:industries).`
|
|
|
6166
7821
|
}
|
|
6167
7822
|
}
|
|
6168
7823
|
});
|
|
6169
|
-
var facetsCommand =
|
|
7824
|
+
var facetsCommand = defineCommand44({
|
|
6170
7825
|
meta: {
|
|
6171
7826
|
name: "facets",
|
|
6172
7827
|
description: `LinkedIn targeting facets and entity lookup.
|
|
@@ -6183,8 +7838,8 @@ Subcommands:
|
|
|
6183
7838
|
});
|
|
6184
7839
|
|
|
6185
7840
|
// src/commands/ads/linkedin/forecast.ts
|
|
6186
|
-
import { readFileSync as
|
|
6187
|
-
import { defineCommand as
|
|
7841
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
7842
|
+
import { defineCommand as defineCommand45 } from "citty";
|
|
6188
7843
|
function loadTargeting3(args) {
|
|
6189
7844
|
const inline = args.targeting;
|
|
6190
7845
|
if (inline) {
|
|
@@ -6197,7 +7852,7 @@ function loadTargeting3(args) {
|
|
|
6197
7852
|
const file = args["targeting-file"];
|
|
6198
7853
|
if (file) {
|
|
6199
7854
|
try {
|
|
6200
|
-
return JSON.parse(
|
|
7855
|
+
return JSON.parse(readFileSync7(file, "utf-8"));
|
|
6201
7856
|
} catch (e) {
|
|
6202
7857
|
handleLinkedinError(
|
|
6203
7858
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -6214,7 +7869,7 @@ function parseMoney(raw) {
|
|
|
6214
7869
|
}
|
|
6215
7870
|
return { amount: m[1] ?? "0", currencyCode: m[2] ?? "USD" };
|
|
6216
7871
|
}
|
|
6217
|
-
var forecastCommand =
|
|
7872
|
+
var forecastCommand = defineCommand45({
|
|
6218
7873
|
meta: {
|
|
6219
7874
|
name: "forecast",
|
|
6220
7875
|
description: `Forecast reach + impressions + clicks + spend for a hypothetical campaign.
|
|
@@ -6261,9 +7916,9 @@ Examples:
|
|
|
6261
7916
|
});
|
|
6262
7917
|
|
|
6263
7918
|
// src/commands/ads/linkedin/leads.ts
|
|
6264
|
-
import { defineCommand as
|
|
7919
|
+
import { defineCommand as defineCommand46 } from "citty";
|
|
6265
7920
|
var DAY_MS4 = 864e5;
|
|
6266
|
-
var leadsCommand =
|
|
7921
|
+
var leadsCommand = defineCommand46({
|
|
6267
7922
|
meta: {
|
|
6268
7923
|
name: "leads",
|
|
6269
7924
|
description: `List Lead Gen Form responses (playbook \xA707).
|
|
@@ -6323,7 +7978,7 @@ Examples:
|
|
|
6323
7978
|
});
|
|
6324
7979
|
|
|
6325
7980
|
// src/commands/ads/linkedin/resolve.ts
|
|
6326
|
-
import { defineCommand as
|
|
7981
|
+
import { defineCommand as defineCommand47 } from "citty";
|
|
6327
7982
|
function toOrgUrn(raw) {
|
|
6328
7983
|
const trimmed = raw.trim();
|
|
6329
7984
|
if (trimmed.length === 0) {
|
|
@@ -6334,7 +7989,7 @@ function toOrgUrn(raw) {
|
|
|
6334
7989
|
}
|
|
6335
7990
|
return /^\d+$/.test(trimmed) ? `urn:li:organization:${trimmed}` : null;
|
|
6336
7991
|
}
|
|
6337
|
-
var resolveCommand =
|
|
7992
|
+
var resolveCommand = defineCommand47({
|
|
6338
7993
|
meta: {
|
|
6339
7994
|
name: "resolve",
|
|
6340
7995
|
description: `Resolve organization URNs to company names.
|
|
@@ -6376,8 +8031,8 @@ couldn't be resolved \u2014 typically an org outside LinkedIn's targetable set.`
|
|
|
6376
8031
|
});
|
|
6377
8032
|
|
|
6378
8033
|
// src/commands/ads/linkedin/top-companies.ts
|
|
6379
|
-
import { defineCommand as
|
|
6380
|
-
var topCompaniesCommand =
|
|
8034
|
+
import { defineCommand as defineCommand48 } from "citty";
|
|
8035
|
+
var topCompaniesCommand = defineCommand48({
|
|
6381
8036
|
meta: {
|
|
6382
8037
|
name: "top-companies",
|
|
6383
8038
|
description: `Top companies whose employees saw / clicked / converted on a campaign.
|
|
@@ -6448,7 +8103,7 @@ Examples:
|
|
|
6448
8103
|
});
|
|
6449
8104
|
|
|
6450
8105
|
// src/commands/ads/linkedin/index.ts
|
|
6451
|
-
var linkedinCommand =
|
|
8106
|
+
var linkedinCommand = defineCommand49({
|
|
6452
8107
|
meta: {
|
|
6453
8108
|
name: "linkedin",
|
|
6454
8109
|
description: `LinkedIn Marketing API \u2014 AI-first command surface for B2B ad insights.
|
|
@@ -6474,6 +8129,17 @@ Performance \u2014 the workhorse (3 axes):
|
|
|
6474
8129
|
baker ads linkedin analytics --list-intents
|
|
6475
8130
|
baker ads linkedin analytics --list-pivots
|
|
6476
8131
|
|
|
8132
|
+
Staged writes (NEVER hit LinkedIn directly \u2014 ops stage on this chat's draft,
|
|
8133
|
+
show in the dashboard as pending LinkedIn changes, and apply when the chat is
|
|
8134
|
+
published; if the company's LinkedIn-write flag is off the publish is simulated):
|
|
8135
|
+
baker ads linkedin campaign-groups create|update|pause|resume|duplicate
|
|
8136
|
+
baker ads linkedin campaigns create|update|pause|resume|archive|duplicate
|
|
8137
|
+
baker ads linkedin creatives create|update|pause|resume|duplicate
|
|
8138
|
+
baker ads linkedin audiences create|upload
|
|
8139
|
+
baker ads linkedin conversions create|update
|
|
8140
|
+
baker ads linkedin lead-forms create|update
|
|
8141
|
+
baker ads linkedin draft [list|remove <ref>|clear] \u2014 review/undo staged ops
|
|
8142
|
+
|
|
6477
8143
|
Account ID format:
|
|
6478
8144
|
--account-id accepts numeric (503001492) or URN (urn:li:sponsoredAccount:503001492).
|
|
6479
8145
|
Set BAKER_LINKEDIN_AD_ACCOUNT_ID env to skip --account-id on every call.`
|
|
@@ -6484,6 +8150,9 @@ Account ID format:
|
|
|
6484
8150
|
"campaign-groups": campaignGroupsCommand,
|
|
6485
8151
|
campaigns: campaignsCommand,
|
|
6486
8152
|
creatives: creativesCommand,
|
|
8153
|
+
audiences: audiencesCommand,
|
|
8154
|
+
"lead-forms": leadFormsCommand,
|
|
8155
|
+
draft: linkedinDraftCommand,
|
|
6487
8156
|
analytics: analyticsCommand,
|
|
6488
8157
|
demographics: demographicsCommand,
|
|
6489
8158
|
"top-companies": topCompaniesCommand,
|
|
@@ -6500,10 +8169,10 @@ Account ID format:
|
|
|
6500
8169
|
});
|
|
6501
8170
|
|
|
6502
8171
|
// src/commands/ads/meta/index.ts
|
|
6503
|
-
import { defineCommand as
|
|
8172
|
+
import { defineCommand as defineCommand62 } from "citty";
|
|
6504
8173
|
|
|
6505
8174
|
// src/commands/ads/meta/account.ts
|
|
6506
|
-
import { defineCommand as
|
|
8175
|
+
import { defineCommand as defineCommand50 } from "citty";
|
|
6507
8176
|
|
|
6508
8177
|
// src/commands/ads/meta/shared.ts
|
|
6509
8178
|
var DAY_MS5 = 864e5;
|
|
@@ -6582,7 +8251,7 @@ function resolveEffectiveStatus(args) {
|
|
|
6582
8251
|
}
|
|
6583
8252
|
|
|
6584
8253
|
// src/commands/ads/meta/account.ts
|
|
6585
|
-
var accountCommand2 =
|
|
8254
|
+
var accountCommand2 = defineCommand50({
|
|
6586
8255
|
meta: {
|
|
6587
8256
|
name: "account",
|
|
6588
8257
|
description: `Show single Meta ad account detail (currency, timezone, balance, business).
|
|
@@ -6609,8 +8278,8 @@ Examples:
|
|
|
6609
8278
|
});
|
|
6610
8279
|
|
|
6611
8280
|
// src/commands/ads/meta/accounts.ts
|
|
6612
|
-
import { defineCommand as
|
|
6613
|
-
var accountsCommand3 =
|
|
8281
|
+
import { defineCommand as defineCommand51 } from "citty";
|
|
8282
|
+
var accountsCommand3 = defineCommand51({
|
|
6614
8283
|
meta: {
|
|
6615
8284
|
name: "accounts",
|
|
6616
8285
|
description: `List Meta ad accounts in this company's connected scope.
|
|
@@ -6658,8 +8327,8 @@ Examples:
|
|
|
6658
8327
|
});
|
|
6659
8328
|
|
|
6660
8329
|
// src/commands/ads/meta/activities.ts
|
|
6661
|
-
import { defineCommand as
|
|
6662
|
-
var activitiesCommand =
|
|
8330
|
+
import { defineCommand as defineCommand52 } from "citty";
|
|
8331
|
+
var activitiesCommand = defineCommand52({
|
|
6663
8332
|
meta: {
|
|
6664
8333
|
name: "activities",
|
|
6665
8334
|
description: `Audit log of recent ad-account changes (created, paused, edited). Default lookback 7 days,
|
|
@@ -6696,8 +8365,8 @@ Examples:
|
|
|
6696
8365
|
});
|
|
6697
8366
|
|
|
6698
8367
|
// src/commands/ads/meta/ads.ts
|
|
6699
|
-
import { defineCommand as
|
|
6700
|
-
var adsListCommand =
|
|
8368
|
+
import { defineCommand as defineCommand53 } from "citty";
|
|
8369
|
+
var adsListCommand = defineCommand53({
|
|
6701
8370
|
meta: {
|
|
6702
8371
|
name: "ads",
|
|
6703
8372
|
description: `List ads in a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -6745,8 +8414,8 @@ Examples:
|
|
|
6745
8414
|
});
|
|
6746
8415
|
|
|
6747
8416
|
// src/commands/ads/meta/adsets.ts
|
|
6748
|
-
import { defineCommand as
|
|
6749
|
-
var adsetsCommand =
|
|
8417
|
+
import { defineCommand as defineCommand54 } from "citty";
|
|
8418
|
+
var adsetsCommand = defineCommand54({
|
|
6750
8419
|
meta: {
|
|
6751
8420
|
name: "adsets",
|
|
6752
8421
|
description: `List ad sets in a Meta ad account, optionally scoped to one campaign. Defaults to ACTIVE only.
|
|
@@ -6788,8 +8457,8 @@ Examples:
|
|
|
6788
8457
|
});
|
|
6789
8458
|
|
|
6790
8459
|
// src/commands/ads/meta/audiences.ts
|
|
6791
|
-
import { defineCommand as
|
|
6792
|
-
var
|
|
8460
|
+
import { defineCommand as defineCommand55 } from "citty";
|
|
8461
|
+
var audiencesCommand2 = defineCommand55({
|
|
6793
8462
|
meta: {
|
|
6794
8463
|
name: "audiences",
|
|
6795
8464
|
description: `List custom audiences for a Meta ad account. Includes lookalikes, website-pixel audiences,
|
|
@@ -6824,8 +8493,8 @@ Examples:
|
|
|
6824
8493
|
});
|
|
6825
8494
|
|
|
6826
8495
|
// src/commands/ads/meta/businesses.ts
|
|
6827
|
-
import { defineCommand as
|
|
6828
|
-
var businessesCommand =
|
|
8496
|
+
import { defineCommand as defineCommand56 } from "citty";
|
|
8497
|
+
var businessesCommand = defineCommand56({
|
|
6829
8498
|
meta: {
|
|
6830
8499
|
name: "businesses",
|
|
6831
8500
|
description: `List Meta Business Manager accounts the connected user has access to. Required for ad-studies and product-catalogs commands.
|
|
@@ -6855,8 +8524,8 @@ Examples:
|
|
|
6855
8524
|
});
|
|
6856
8525
|
|
|
6857
8526
|
// src/commands/ads/meta/campaigns.ts
|
|
6858
|
-
import { defineCommand as
|
|
6859
|
-
var campaignsCommand2 =
|
|
8527
|
+
import { defineCommand as defineCommand57 } from "citty";
|
|
8528
|
+
var campaignsCommand2 = defineCommand57({
|
|
6860
8529
|
meta: {
|
|
6861
8530
|
name: "campaigns",
|
|
6862
8531
|
description: `List campaigns for a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -6900,8 +8569,8 @@ Examples:
|
|
|
6900
8569
|
});
|
|
6901
8570
|
|
|
6902
8571
|
// src/commands/ads/meta/creatives.ts
|
|
6903
|
-
import { defineCommand as
|
|
6904
|
-
var creativesCommand2 =
|
|
8572
|
+
import { defineCommand as defineCommand58 } from "citty";
|
|
8573
|
+
var creativesCommand2 = defineCommand58({
|
|
6905
8574
|
meta: {
|
|
6906
8575
|
name: "creatives",
|
|
6907
8576
|
description: `List ad creatives in an account, or fetch a single creative by ID.
|
|
@@ -6945,7 +8614,7 @@ Examples:
|
|
|
6945
8614
|
});
|
|
6946
8615
|
|
|
6947
8616
|
// src/commands/ads/meta/insights.ts
|
|
6948
|
-
import { defineCommand as
|
|
8617
|
+
import { defineCommand as defineCommand59 } from "citty";
|
|
6949
8618
|
|
|
6950
8619
|
// src/commands/ads/meta/presets.ts
|
|
6951
8620
|
var INSIGHTS_INTENTS = {
|
|
@@ -7150,7 +8819,7 @@ function sortRowsBySpendDesc(rows) {
|
|
|
7150
8819
|
return sb - sa;
|
|
7151
8820
|
});
|
|
7152
8821
|
}
|
|
7153
|
-
var insightsCommand =
|
|
8822
|
+
var insightsCommand = defineCommand59({
|
|
7154
8823
|
meta: {
|
|
7155
8824
|
name: "insights",
|
|
7156
8825
|
description: `Performance reporting \u2014 the main Meta tool for AI agents.
|
|
@@ -7251,8 +8920,8 @@ Async is automatic for heavy queries; pass --async to force it, or --no-async to
|
|
|
7251
8920
|
});
|
|
7252
8921
|
|
|
7253
8922
|
// src/commands/ads/meta/pixels.ts
|
|
7254
|
-
import { defineCommand as
|
|
7255
|
-
var pixelsCommand =
|
|
8923
|
+
import { defineCommand as defineCommand60 } from "citty";
|
|
8924
|
+
var pixelsCommand = defineCommand60({
|
|
7256
8925
|
meta: {
|
|
7257
8926
|
name: "pixels",
|
|
7258
8927
|
description: `List Meta Pixels for an ad account, or fetch firing stats for one pixel.
|
|
@@ -7323,7 +8992,7 @@ function emit(data, args) {
|
|
|
7323
8992
|
|
|
7324
8993
|
// src/commands/ads/meta/preview.ts
|
|
7325
8994
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
7326
|
-
import { defineCommand as
|
|
8995
|
+
import { defineCommand as defineCommand61 } from "citty";
|
|
7327
8996
|
var VALID_AD_FORMATS = [
|
|
7328
8997
|
"DESKTOP_FEED_STANDARD",
|
|
7329
8998
|
"MOBILE_FEED_STANDARD",
|
|
@@ -7357,7 +9026,7 @@ var VALID_AD_FORMATS = [
|
|
|
7357
9026
|
"MARKETPLACE_MOBILE",
|
|
7358
9027
|
"BIZ_DISCO_FEED_MOBILE"
|
|
7359
9028
|
];
|
|
7360
|
-
var previewCommand =
|
|
9029
|
+
var previewCommand = defineCommand61({
|
|
7361
9030
|
meta: {
|
|
7362
9031
|
name: "preview",
|
|
7363
9032
|
description: `Generate a Meta-hosted preview iframe for a creative or ad. Returns iframe HTML which you
|
|
@@ -7404,7 +9073,7 @@ Examples:
|
|
|
7404
9073
|
});
|
|
7405
9074
|
|
|
7406
9075
|
// src/commands/ads/meta/index.ts
|
|
7407
|
-
var metaCommand =
|
|
9076
|
+
var metaCommand = defineCommand62({
|
|
7408
9077
|
meta: {
|
|
7409
9078
|
name: "meta",
|
|
7410
9079
|
description: `Meta Marketing API \u2014 AI-first command surface (Facebook + Instagram ads).
|
|
@@ -7447,7 +9116,7 @@ Audit & review:
|
|
|
7447
9116
|
adsets: adsetsCommand,
|
|
7448
9117
|
ads: adsListCommand,
|
|
7449
9118
|
creatives: creativesCommand2,
|
|
7450
|
-
audiences:
|
|
9119
|
+
audiences: audiencesCommand2,
|
|
7451
9120
|
pixels: pixelsCommand,
|
|
7452
9121
|
activities: activitiesCommand,
|
|
7453
9122
|
insights: insightsCommand,
|
|
@@ -7456,10 +9125,10 @@ Audit & review:
|
|
|
7456
9125
|
});
|
|
7457
9126
|
|
|
7458
9127
|
// src/commands/ads/x/index.ts
|
|
7459
|
-
import { defineCommand as
|
|
9128
|
+
import { defineCommand as defineCommand79 } from "citty";
|
|
7460
9129
|
|
|
7461
9130
|
// src/commands/ads/x/accounts.ts
|
|
7462
|
-
import { defineCommand as
|
|
9131
|
+
import { defineCommand as defineCommand63 } from "citty";
|
|
7463
9132
|
registerSchema({
|
|
7464
9133
|
command: "ads.x.accounts",
|
|
7465
9134
|
description: "List all accessible X Ads accounts. Returns accounts with id (base36), name, approval_status, timezone, currency. Run this first to find account IDs for other commands.",
|
|
@@ -7487,7 +9156,7 @@ function handleAccountsError2(err) {
|
|
|
7487
9156
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
7488
9157
|
process.exit(1);
|
|
7489
9158
|
}
|
|
7490
|
-
var accountsCommand4 =
|
|
9159
|
+
var accountsCommand4 = defineCommand63({
|
|
7491
9160
|
meta: {
|
|
7492
9161
|
name: "accounts",
|
|
7493
9162
|
description: `List accessible X Ads accounts. Returns account IDs needed for all other commands.
|
|
@@ -7527,7 +9196,7 @@ Examples:
|
|
|
7527
9196
|
});
|
|
7528
9197
|
|
|
7529
9198
|
// src/commands/ads/x/active-entities.ts
|
|
7530
|
-
import { defineCommand as
|
|
9199
|
+
import { defineCommand as defineCommand64 } from "citty";
|
|
7531
9200
|
|
|
7532
9201
|
// src/commands/ads/x/error-parser.ts
|
|
7533
9202
|
function mapXErrorCode(message) {
|
|
@@ -7678,7 +9347,7 @@ function parseCsv(v) {
|
|
|
7678
9347
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7679
9348
|
return parts.length > 0 ? parts : void 0;
|
|
7680
9349
|
}
|
|
7681
|
-
var activeEntitiesCommand =
|
|
9350
|
+
var activeEntitiesCommand = defineCommand64({
|
|
7682
9351
|
meta: {
|
|
7683
9352
|
name: "active-entities",
|
|
7684
9353
|
description: `List entities with metric activity in a time range.
|
|
@@ -7736,7 +9405,7 @@ Examples:
|
|
|
7736
9405
|
});
|
|
7737
9406
|
|
|
7738
9407
|
// src/commands/ads/x/audiences.ts
|
|
7739
|
-
import { defineCommand as
|
|
9408
|
+
import { defineCommand as defineCommand65 } from "citty";
|
|
7740
9409
|
registerSchema({
|
|
7741
9410
|
command: "ads.x.audiences",
|
|
7742
9411
|
description: "List custom audiences for an X Ads account. Returns id, name, audience_size, audience_type, targetable status. Audiences need 100+ active users in the past 90 days to be targetable.",
|
|
@@ -7745,7 +9414,7 @@ registerSchema({
|
|
|
7745
9414
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7746
9415
|
}
|
|
7747
9416
|
});
|
|
7748
|
-
var
|
|
9417
|
+
var audiencesCommand3 = defineCommand65({
|
|
7749
9418
|
meta: {
|
|
7750
9419
|
name: "audiences",
|
|
7751
9420
|
description: `List X Ads custom audiences.
|
|
@@ -7794,7 +9463,7 @@ Examples:
|
|
|
7794
9463
|
});
|
|
7795
9464
|
|
|
7796
9465
|
// src/commands/ads/x/campaigns.ts
|
|
7797
|
-
import { defineCommand as
|
|
9466
|
+
import { defineCommand as defineCommand66 } from "citty";
|
|
7798
9467
|
|
|
7799
9468
|
// src/commands/ads/x/run-list.ts
|
|
7800
9469
|
function buildCleanParams(opts) {
|
|
@@ -7857,7 +9526,7 @@ registerSchema({
|
|
|
7857
9526
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7858
9527
|
}
|
|
7859
9528
|
});
|
|
7860
|
-
var campaignsCommand3 =
|
|
9529
|
+
var campaignsCommand3 = defineCommand66({
|
|
7861
9530
|
meta: {
|
|
7862
9531
|
name: "campaigns",
|
|
7863
9532
|
description: `List X Ads campaigns. Returns budget, schedule, funding instrument, status.
|
|
@@ -7899,7 +9568,7 @@ Examples:
|
|
|
7899
9568
|
});
|
|
7900
9569
|
|
|
7901
9570
|
// src/commands/ads/x/cards.ts
|
|
7902
|
-
import { defineCommand as
|
|
9571
|
+
import { defineCommand as defineCommand67 } from "citty";
|
|
7903
9572
|
registerSchema({
|
|
7904
9573
|
command: "ads.x.cards",
|
|
7905
9574
|
description: "List website cards, video cards, and carousels for an X Ads account.",
|
|
@@ -7908,7 +9577,7 @@ registerSchema({
|
|
|
7908
9577
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7909
9578
|
}
|
|
7910
9579
|
});
|
|
7911
|
-
var cardsCommand =
|
|
9580
|
+
var cardsCommand = defineCommand67({
|
|
7912
9581
|
meta: {
|
|
7913
9582
|
name: "cards",
|
|
7914
9583
|
description: `List X Ads cards (rich creatives).
|
|
@@ -7957,7 +9626,7 @@ Examples:
|
|
|
7957
9626
|
});
|
|
7958
9627
|
|
|
7959
9628
|
// src/commands/ads/x/funding.ts
|
|
7960
|
-
import { defineCommand as
|
|
9629
|
+
import { defineCommand as defineCommand68 } from "citty";
|
|
7961
9630
|
registerSchema({
|
|
7962
9631
|
command: "ads.x.funding",
|
|
7963
9632
|
description: "List funding instruments for an X Ads account. Returns id, type, currency, credit_limit_local_micro, funded_amount_local_micro, status. Falls back to BAKER_X_ADS_ACCOUNT_ID env var.",
|
|
@@ -7966,7 +9635,7 @@ registerSchema({
|
|
|
7966
9635
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7967
9636
|
}
|
|
7968
9637
|
});
|
|
7969
|
-
var fundingCommand =
|
|
9638
|
+
var fundingCommand = defineCommand68({
|
|
7970
9639
|
meta: {
|
|
7971
9640
|
name: "funding",
|
|
7972
9641
|
description: `List funding instruments for an X Ads account.
|
|
@@ -8015,7 +9684,7 @@ Examples:
|
|
|
8015
9684
|
});
|
|
8016
9685
|
|
|
8017
9686
|
// src/commands/ads/x/line-items.ts
|
|
8018
|
-
import { defineCommand as
|
|
9687
|
+
import { defineCommand as defineCommand69 } from "citty";
|
|
8019
9688
|
registerSchema({
|
|
8020
9689
|
command: "ads.x.lineItems",
|
|
8021
9690
|
description: "List line items (ad groups) for an X Ads account. Returns bid, product_type, objective, placements, schedule. Filter by campaign-ids or line-item-ids (CSV).",
|
|
@@ -8027,7 +9696,7 @@ registerSchema({
|
|
|
8027
9696
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8028
9697
|
}
|
|
8029
9698
|
});
|
|
8030
|
-
var lineItemsCommand =
|
|
9699
|
+
var lineItemsCommand = defineCommand69({
|
|
8031
9700
|
meta: {
|
|
8032
9701
|
name: "line-items",
|
|
8033
9702
|
description: `List X Ads line items (ad groups).
|
|
@@ -8068,7 +9737,7 @@ Examples:
|
|
|
8068
9737
|
});
|
|
8069
9738
|
|
|
8070
9739
|
// src/commands/ads/x/media.ts
|
|
8071
|
-
import { defineCommand as
|
|
9740
|
+
import { defineCommand as defineCommand70 } from "citty";
|
|
8072
9741
|
registerSchema({
|
|
8073
9742
|
command: "ads.x.media",
|
|
8074
9743
|
description: "List media assets in the X Ads media library (images, GIFs, videos). Filter by media-type (IMAGE, GIF, VIDEO).",
|
|
@@ -8078,7 +9747,7 @@ registerSchema({
|
|
|
8078
9747
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8079
9748
|
}
|
|
8080
9749
|
});
|
|
8081
|
-
var mediaCommand =
|
|
9750
|
+
var mediaCommand = defineCommand70({
|
|
8082
9751
|
meta: {
|
|
8083
9752
|
name: "media",
|
|
8084
9753
|
description: `List media assets in the X Ads media library.
|
|
@@ -8130,7 +9799,7 @@ Examples:
|
|
|
8130
9799
|
});
|
|
8131
9800
|
|
|
8132
9801
|
// src/commands/ads/x/promoted-tweets.ts
|
|
8133
|
-
import { defineCommand as
|
|
9802
|
+
import { defineCommand as defineCommand71 } from "citty";
|
|
8134
9803
|
registerSchema({
|
|
8135
9804
|
command: "ads.x.promotedTweets",
|
|
8136
9805
|
description: "List promoted tweets for an X Ads account. Returns id, line_item_id, tweet_id, approval_status. Filter by line-item-ids (CSV).",
|
|
@@ -8141,7 +9810,7 @@ registerSchema({
|
|
|
8141
9810
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8142
9811
|
}
|
|
8143
9812
|
});
|
|
8144
|
-
var promotedTweetsCommand =
|
|
9813
|
+
var promotedTweetsCommand = defineCommand71({
|
|
8145
9814
|
meta: {
|
|
8146
9815
|
name: "promoted-tweets",
|
|
8147
9816
|
description: `List X Ads promoted tweets.
|
|
@@ -8195,11 +9864,11 @@ Examples:
|
|
|
8195
9864
|
});
|
|
8196
9865
|
|
|
8197
9866
|
// src/commands/ads/x/stats/index.ts
|
|
8198
|
-
import { defineCommand as
|
|
9867
|
+
import { defineCommand as defineCommand76 } from "citty";
|
|
8199
9868
|
|
|
8200
9869
|
// src/commands/ads/x/stats/job.ts
|
|
8201
9870
|
import { gunzipSync } from "zlib";
|
|
8202
|
-
import { defineCommand as
|
|
9871
|
+
import { defineCommand as defineCommand72 } from "citty";
|
|
8203
9872
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
8204
9873
|
var DEADLINE_MS = 12 * 60 * 1e3;
|
|
8205
9874
|
var RESULT_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -8269,7 +9938,7 @@ async function pollUntilDone(accountId, jobId) {
|
|
|
8269
9938
|
function buildCacheKey(body) {
|
|
8270
9939
|
return `stats-job:${JSON.stringify(body)}`;
|
|
8271
9940
|
}
|
|
8272
|
-
var statsJobCommand =
|
|
9941
|
+
var statsJobCommand = defineCommand72({
|
|
8273
9942
|
meta: {
|
|
8274
9943
|
name: "job",
|
|
8275
9944
|
description: `Async X Ads stats job, sync from the CLI's perspective. Creates \u2192 polls \u2192 downloads \u2192 returns.
|
|
@@ -8374,7 +10043,7 @@ For fine-grained control (don't wait, poll yourself), use:
|
|
|
8374
10043
|
});
|
|
8375
10044
|
|
|
8376
10045
|
// src/commands/ads/x/stats/job-create.ts
|
|
8377
|
-
import { defineCommand as
|
|
10046
|
+
import { defineCommand as defineCommand73 } from "citty";
|
|
8378
10047
|
registerSchema({
|
|
8379
10048
|
command: "ads.x.statsJobCreate",
|
|
8380
10049
|
description: "Create an asynchronous X Ads stats job (range up to 90 days non-segmented, 45 days segmented). Returns a job id; poll with `stats job-status`. Times must be ISO 8601 hour-aligned.",
|
|
@@ -8397,7 +10066,7 @@ function parseCsv3(v) {
|
|
|
8397
10066
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
8398
10067
|
return parts.length > 0 ? parts : void 0;
|
|
8399
10068
|
}
|
|
8400
|
-
var statsJobCreateCommand =
|
|
10069
|
+
var statsJobCreateCommand = defineCommand73({
|
|
8401
10070
|
meta: {
|
|
8402
10071
|
name: "job-create",
|
|
8403
10072
|
description: `Create an async X Ads stats job (up to 90 days, supports segmentation).
|
|
@@ -8460,7 +10129,7 @@ Examples:
|
|
|
8460
10129
|
});
|
|
8461
10130
|
|
|
8462
10131
|
// src/commands/ads/x/stats/job-status.ts
|
|
8463
|
-
import { defineCommand as
|
|
10132
|
+
import { defineCommand as defineCommand74 } from "citty";
|
|
8464
10133
|
registerSchema({
|
|
8465
10134
|
command: "ads.x.statsJobStatus",
|
|
8466
10135
|
description: "Check the status of one or more X Ads stats jobs. Returns status (PROCESSING|SUCCESS|FAILED) and a downloadable url when SUCCESS. Pass --job-id or --job-ids (CSV).",
|
|
@@ -8470,7 +10139,7 @@ registerSchema({
|
|
|
8470
10139
|
"job-ids": { type: "string", description: "CSV of job IDs", required: false }
|
|
8471
10140
|
}
|
|
8472
10141
|
});
|
|
8473
|
-
var statsJobStatusCommand =
|
|
10142
|
+
var statsJobStatusCommand = defineCommand74({
|
|
8474
10143
|
meta: {
|
|
8475
10144
|
name: "job-status",
|
|
8476
10145
|
description: `Poll the status of an async X Ads stats job.
|
|
@@ -8511,7 +10180,7 @@ Examples:
|
|
|
8511
10180
|
});
|
|
8512
10181
|
|
|
8513
10182
|
// src/commands/ads/x/stats/sync.ts
|
|
8514
|
-
import { defineCommand as
|
|
10183
|
+
import { defineCommand as defineCommand75 } from "citty";
|
|
8515
10184
|
|
|
8516
10185
|
// src/commands/ads/x/presets.ts
|
|
8517
10186
|
var X_STATS_PRESETS = [
|
|
@@ -8670,7 +10339,7 @@ async function runSync(args, q) {
|
|
|
8670
10339
|
process.exit(1);
|
|
8671
10340
|
}
|
|
8672
10341
|
}
|
|
8673
|
-
var statsSyncCommand =
|
|
10342
|
+
var statsSyncCommand = defineCommand75({
|
|
8674
10343
|
meta: {
|
|
8675
10344
|
name: "sync",
|
|
8676
10345
|
description: `Synchronous X Ads analytics (max 7-day window).
|
|
@@ -8713,7 +10382,7 @@ Examples:
|
|
|
8713
10382
|
});
|
|
8714
10383
|
|
|
8715
10384
|
// src/commands/ads/x/stats/index.ts
|
|
8716
|
-
var statsCommand =
|
|
10385
|
+
var statsCommand = defineCommand76({
|
|
8717
10386
|
meta: {
|
|
8718
10387
|
name: "stats",
|
|
8719
10388
|
description: `X Ads analytics. Sync (\u22647 days, no segmentation) or async jobs (\u226490 days, segmentable).
|
|
@@ -8741,7 +10410,7 @@ Examples:
|
|
|
8741
10410
|
});
|
|
8742
10411
|
|
|
8743
10412
|
// src/commands/ads/x/targeting-constants.ts
|
|
8744
|
-
import { defineCommand as
|
|
10413
|
+
import { defineCommand as defineCommand77 } from "citty";
|
|
8745
10414
|
var ALLOWED_CONSTANTS = [
|
|
8746
10415
|
"locations",
|
|
8747
10416
|
"interests",
|
|
@@ -8769,7 +10438,7 @@ registerSchema({
|
|
|
8769
10438
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8770
10439
|
}
|
|
8771
10440
|
});
|
|
8772
|
-
var targetingConstantsCommand =
|
|
10441
|
+
var targetingConstantsCommand = defineCommand77({
|
|
8773
10442
|
meta: {
|
|
8774
10443
|
name: "targeting-constants",
|
|
8775
10444
|
description: `Lookup X Ads targeting constants.
|
|
@@ -8819,7 +10488,7 @@ Examples:
|
|
|
8819
10488
|
});
|
|
8820
10489
|
|
|
8821
10490
|
// src/commands/ads/x/targeting-criteria.ts
|
|
8822
|
-
import { defineCommand as
|
|
10491
|
+
import { defineCommand as defineCommand78 } from "citty";
|
|
8823
10492
|
registerSchema({
|
|
8824
10493
|
command: "ads.x.targetingCriteria",
|
|
8825
10494
|
description: "List targeting criteria attached to line items in an X Ads account. Returns targeting_type, targeting_value, name, operator_type per criterion. Filter by line-item-ids.",
|
|
@@ -8829,7 +10498,7 @@ registerSchema({
|
|
|
8829
10498
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8830
10499
|
}
|
|
8831
10500
|
});
|
|
8832
|
-
var targetingCriteriaCommand =
|
|
10501
|
+
var targetingCriteriaCommand = defineCommand78({
|
|
8833
10502
|
meta: {
|
|
8834
10503
|
name: "targeting-criteria",
|
|
8835
10504
|
description: `List targeting criteria attached to line items.
|
|
@@ -8880,7 +10549,7 @@ Examples:
|
|
|
8880
10549
|
});
|
|
8881
10550
|
|
|
8882
10551
|
// src/commands/ads/x/index.ts
|
|
8883
|
-
var xCommand =
|
|
10552
|
+
var xCommand = defineCommand79({
|
|
8884
10553
|
meta: {
|
|
8885
10554
|
name: "x",
|
|
8886
10555
|
description: `X (Twitter) Ads commands. Read campaigns, line items, promoted tweets, creatives, audiences, and analytics.
|
|
@@ -8909,7 +10578,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
8909
10578
|
"promoted-tweets": promotedTweetsCommand,
|
|
8910
10579
|
cards: cardsCommand,
|
|
8911
10580
|
media: mediaCommand,
|
|
8912
|
-
audiences:
|
|
10581
|
+
audiences: audiencesCommand3,
|
|
8913
10582
|
"targeting-criteria": targetingCriteriaCommand,
|
|
8914
10583
|
"targeting-constants": targetingConstantsCommand,
|
|
8915
10584
|
"active-entities": activeEntitiesCommand,
|
|
@@ -8918,7 +10587,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
8918
10587
|
});
|
|
8919
10588
|
|
|
8920
10589
|
// src/commands/ads/index.ts
|
|
8921
|
-
var adsCommand =
|
|
10590
|
+
var adsCommand = defineCommand80({
|
|
8922
10591
|
meta: {
|
|
8923
10592
|
name: "ads",
|
|
8924
10593
|
description: `Ad platform commands. Each platform exposes its own native command surface \u2014 no forced parity.
|
|
@@ -8948,11 +10617,11 @@ Examples:
|
|
|
8948
10617
|
});
|
|
8949
10618
|
|
|
8950
10619
|
// src/commands/canvas/index.ts
|
|
8951
|
-
import { defineCommand as
|
|
10620
|
+
import { defineCommand as defineCommand88 } from "citty";
|
|
8952
10621
|
|
|
8953
10622
|
// src/commands/canvas/catalog.ts
|
|
8954
|
-
import { defineCommand as
|
|
8955
|
-
var catalogCommand =
|
|
10623
|
+
import { defineCommand as defineCommand81 } from "citty";
|
|
10624
|
+
var catalogCommand = defineCommand81({
|
|
8956
10625
|
meta: {
|
|
8957
10626
|
name: "catalog",
|
|
8958
10627
|
description: "Print the agent-facing node catalog (JSON Schema). Includes every registered node grouped by category."
|
|
@@ -8969,9 +10638,9 @@ import { execFile } from "child_process";
|
|
|
8969
10638
|
import { readdir, readFile, stat } from "fs/promises";
|
|
8970
10639
|
import path from "path";
|
|
8971
10640
|
import { promisify } from "util";
|
|
8972
|
-
import { defineCommand as
|
|
10641
|
+
import { defineCommand as defineCommand82 } from "citty";
|
|
8973
10642
|
var execFileAsync = promisify(execFile);
|
|
8974
|
-
var inspectCommand =
|
|
10643
|
+
var inspectCommand = defineCommand82({
|
|
8975
10644
|
meta: {
|
|
8976
10645
|
name: "inspect",
|
|
8977
10646
|
description: "Dump a one-page summary of a canvas run: per-node duration + cache status, list of output files in the run dir, and optionally three thumbnail frames per video output. Pass either a run_id (resolved against --outputs-dir) or an absolute run directory."
|
|
@@ -9080,7 +10749,7 @@ async function probeDuration(filePath) {
|
|
|
9080
10749
|
// src/commands/canvas/run.ts
|
|
9081
10750
|
import { readFile as readFile2 } from "fs/promises";
|
|
9082
10751
|
import path4 from "path";
|
|
9083
|
-
import { defineCommand as
|
|
10752
|
+
import { defineCommand as defineCommand83 } from "citty";
|
|
9084
10753
|
|
|
9085
10754
|
// src/commands/canvas/placeholders.ts
|
|
9086
10755
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
@@ -9150,7 +10819,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
9150
10819
|
}
|
|
9151
10820
|
|
|
9152
10821
|
// src/commands/canvas/run.ts
|
|
9153
|
-
var runCommand =
|
|
10822
|
+
var runCommand = defineCommand83({
|
|
9154
10823
|
meta: { name: "run", description: "Validate and execute a canvas JSON file." },
|
|
9155
10824
|
args: {
|
|
9156
10825
|
file: { type: "positional", required: true, description: "Path to canvas JSON" },
|
|
@@ -9246,30 +10915,30 @@ var runCommand = defineCommand81({
|
|
|
9246
10915
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
9247
10916
|
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
9248
10917
|
import path5 from "path";
|
|
9249
|
-
import { defineCommand as
|
|
10918
|
+
import { defineCommand as defineCommand84 } from "citty";
|
|
9250
10919
|
|
|
9251
10920
|
// src/engine/scaffold/staticAd.ts
|
|
9252
|
-
import { z as
|
|
10921
|
+
import { z as z8 } from "zod";
|
|
9253
10922
|
var GEN_ASPECT_RATIOS = /* @__PURE__ */ new Set(["1:1", "4:5", "9:16", "16:9", "4:3", "3:4", "2:3", "3:2", "21:9"]);
|
|
9254
10923
|
var DEFAULT_ASPECT_RATIO = "9:16";
|
|
9255
|
-
var Blueprint =
|
|
9256
|
-
meta:
|
|
9257
|
-
text_content:
|
|
10924
|
+
var Blueprint = z8.object({
|
|
10925
|
+
meta: z8.object({ estimated_aspect_ratio: z8.string().optional() }).loose().optional(),
|
|
10926
|
+
text_content: z8.array(z8.object({ text: z8.string().optional() }).loose()).optional()
|
|
9258
10927
|
}).loose();
|
|
9259
|
-
var ElementLocator =
|
|
9260
|
-
collection:
|
|
9261
|
-
index:
|
|
10928
|
+
var ElementLocator = z8.object({
|
|
10929
|
+
collection: z8.enum(["subjects", "people", "brands_logos"]),
|
|
10930
|
+
index: z8.number().int().nonnegative()
|
|
9262
10931
|
}).loose();
|
|
9263
|
-
var MainElement =
|
|
10932
|
+
var MainElement = z8.object({
|
|
9264
10933
|
// logo | product | person | animal | badge | other
|
|
9265
|
-
type:
|
|
9266
|
-
label:
|
|
9267
|
-
description:
|
|
9268
|
-
expression:
|
|
9269
|
-
reason:
|
|
10934
|
+
type: z8.string(),
|
|
10935
|
+
label: z8.string().optional(),
|
|
10936
|
+
description: z8.string().optional(),
|
|
10937
|
+
expression: z8.string().nullable().optional(),
|
|
10938
|
+
reason: z8.string().optional(),
|
|
9270
10939
|
locator: ElementLocator.optional()
|
|
9271
10940
|
}).loose();
|
|
9272
|
-
var MainElements =
|
|
10941
|
+
var MainElements = z8.array(MainElement);
|
|
9273
10942
|
function sanitizeId(raw, fallback) {
|
|
9274
10943
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
9275
10944
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -9565,7 +11234,7 @@ async function runVisionPasses(canvas) {
|
|
|
9565
11234
|
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
9566
11235
|
}
|
|
9567
11236
|
}
|
|
9568
|
-
var scaffoldStaticAdCommand =
|
|
11237
|
+
var scaffoldStaticAdCommand = defineCommand84({
|
|
9569
11238
|
meta: {
|
|
9570
11239
|
name: "scaffold-static-ad",
|
|
9571
11240
|
description: "Turn a source/inspiration image into a runnable static-ad canvas. Runs billed passes \u2014 image_describe (the blueprint, baked to prompt.json as the editable 'prompt'), an AI selection of the image's MAIN identity elements, and a structured global-layout pass (the column/row grid with per-region bounds and text sizes) \u2014 then scaffolds a canvas that wires one [TODO] ingest slot per element (logo/product/subject/badge + brand font) into image_generate. Edit prompt.json and drop the real assets, then `baker canvas run` it."
|
|
@@ -9659,7 +11328,7 @@ var scaffoldStaticAdCommand = defineCommand82({
|
|
|
9659
11328
|
// src/commands/canvas/scaffold-video.ts
|
|
9660
11329
|
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
9661
11330
|
import path8 from "path";
|
|
9662
|
-
import { defineCommand as
|
|
11331
|
+
import { defineCommand as defineCommand85 } from "citty";
|
|
9663
11332
|
|
|
9664
11333
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
9665
11334
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -9764,7 +11433,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
|
|
|
9764
11433
|
import { toCardinal as nwNl } from "n2words/nl-NL";
|
|
9765
11434
|
import { toCardinal as nwPl } from "n2words/pl-PL";
|
|
9766
11435
|
import { toCardinal as nwPt } from "n2words/pt-PT";
|
|
9767
|
-
import { z as
|
|
11436
|
+
import { z as z9 } from "zod";
|
|
9768
11437
|
|
|
9769
11438
|
// src/engine/scaffold/lib/shoot-modes.ts
|
|
9770
11439
|
var SHOOT_MODES = [
|
|
@@ -10021,49 +11690,49 @@ function trimArgs(durationS, offsetS = 0) {
|
|
|
10021
11690
|
"{{out.video}}"
|
|
10022
11691
|
];
|
|
10023
11692
|
}
|
|
10024
|
-
var FrameAsset =
|
|
10025
|
-
var DialogueLine =
|
|
10026
|
-
speaker:
|
|
10027
|
-
line:
|
|
11693
|
+
var FrameAsset = z9.object({ url: z9.string().optional() }).loose().optional();
|
|
11694
|
+
var DialogueLine = z9.object({
|
|
11695
|
+
speaker: z9.string().optional(),
|
|
11696
|
+
line: z9.string().optional(),
|
|
10028
11697
|
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
10029
|
-
start_s:
|
|
10030
|
-
end_s:
|
|
10031
|
-
delivery:
|
|
10032
|
-
voice_description:
|
|
11698
|
+
start_s: z9.number().optional(),
|
|
11699
|
+
end_s: z9.number().optional(),
|
|
11700
|
+
delivery: z9.string().optional(),
|
|
11701
|
+
voice_description: z9.string().optional()
|
|
10033
11702
|
}).loose();
|
|
10034
|
-
var Sfx =
|
|
10035
|
-
at_s:
|
|
10036
|
-
duration_s:
|
|
10037
|
-
sound_effect_prompt:
|
|
10038
|
-
description:
|
|
11703
|
+
var Sfx = z9.object({
|
|
11704
|
+
at_s: z9.number().optional(),
|
|
11705
|
+
duration_s: z9.number().optional(),
|
|
11706
|
+
sound_effect_prompt: z9.string().optional(),
|
|
11707
|
+
description: z9.string().optional()
|
|
10039
11708
|
}).loose();
|
|
10040
|
-
var CompositionRegion =
|
|
11709
|
+
var CompositionRegion = z9.object({
|
|
10041
11710
|
// full | top | bottom | left | right | inset
|
|
10042
|
-
panel:
|
|
11711
|
+
panel: z9.string().optional(),
|
|
10043
11712
|
// 9-grid anchor for an `inset` presenter box.
|
|
10044
|
-
position:
|
|
10045
|
-
is_presenter:
|
|
11713
|
+
position: z9.string().optional(),
|
|
11714
|
+
is_presenter: z9.boolean().optional(),
|
|
10046
11715
|
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
10047
|
-
cast_ref:
|
|
10048
|
-
summary:
|
|
10049
|
-
frame_prompt:
|
|
10050
|
-
motion_prompt:
|
|
11716
|
+
cast_ref: z9.string().optional(),
|
|
11717
|
+
summary: z9.string().optional(),
|
|
11718
|
+
frame_prompt: z9.string().optional(),
|
|
11719
|
+
motion_prompt: z9.string().optional()
|
|
10051
11720
|
}).loose();
|
|
10052
|
-
var SceneComposition =
|
|
11721
|
+
var SceneComposition = z9.object({
|
|
10053
11722
|
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
10054
|
-
layout:
|
|
11723
|
+
layout: z9.string().optional(),
|
|
10055
11724
|
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
10056
|
-
split_axis:
|
|
10057
|
-
regions:
|
|
11725
|
+
split_axis: z9.string().optional(),
|
|
11726
|
+
regions: z9.array(CompositionRegion).optional()
|
|
10058
11727
|
}).loose();
|
|
10059
|
-
var CameraMotion =
|
|
10060
|
-
var TranscriptWord =
|
|
10061
|
-
var Scene =
|
|
10062
|
-
start_s:
|
|
10063
|
-
end_s:
|
|
10064
|
-
duration_s:
|
|
10065
|
-
summary:
|
|
10066
|
-
action_detail:
|
|
11728
|
+
var CameraMotion = z9.object({ movement: z9.string().optional(), detail: z9.string().optional() }).loose();
|
|
11729
|
+
var TranscriptWord = z9.object({ text: z9.string().optional() }).loose();
|
|
11730
|
+
var Scene = z9.object({
|
|
11731
|
+
start_s: z9.number().optional(),
|
|
11732
|
+
end_s: z9.number().optional(),
|
|
11733
|
+
duration_s: z9.number().optional(),
|
|
11734
|
+
summary: z9.string().optional(),
|
|
11735
|
+
action_detail: z9.string().optional(),
|
|
10067
11736
|
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
10068
11737
|
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
10069
11738
|
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
@@ -10071,77 +11740,77 @@ var Scene = z7.object({
|
|
|
10071
11740
|
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
10072
11741
|
// grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
|
|
10073
11742
|
// UGC/product mode; a human can override per scene by setting this.
|
|
10074
|
-
shoot_mode:
|
|
11743
|
+
shoot_mode: z9.string().optional(),
|
|
10075
11744
|
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
10076
11745
|
// absent the scene falls back to its shoot mode's default ambience.
|
|
10077
|
-
ambient:
|
|
11746
|
+
ambient: z9.string().optional(),
|
|
10078
11747
|
camera_motion: CameraMotion.optional(),
|
|
10079
|
-
start_frame_prompt:
|
|
10080
|
-
end_frame_prompt:
|
|
10081
|
-
motion_prompt:
|
|
11748
|
+
start_frame_prompt: z9.string().optional(),
|
|
11749
|
+
end_frame_prompt: z9.string().optional(),
|
|
11750
|
+
motion_prompt: z9.string().optional(),
|
|
10082
11751
|
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
10083
11752
|
// script re-craft checklist. Inferred from position when absent.
|
|
10084
|
-
narrative_role:
|
|
11753
|
+
narrative_role: z9.string().optional(),
|
|
10085
11754
|
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
10086
11755
|
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
10087
11756
|
// into the hook's start-frame description so the generator renders that state,
|
|
10088
11757
|
// not a calm influencer (CCA-11).
|
|
10089
|
-
hook_mechanic:
|
|
11758
|
+
hook_mechanic: z9.object({ mechanic: z9.string().optional(), why_it_stops_scroll: z9.string().optional() }).loose().optional(),
|
|
10090
11759
|
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
10091
|
-
scene_setting:
|
|
11760
|
+
scene_setting: z9.string().optional(),
|
|
10092
11761
|
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
10093
11762
|
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
10094
11763
|
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
10095
11764
|
// ignored (nothing follows it).
|
|
10096
|
-
transition_out:
|
|
10097
|
-
dialogue:
|
|
10098
|
-
sfx:
|
|
10099
|
-
overlays:
|
|
10100
|
-
floating_elements:
|
|
10101
|
-
transcript_slice:
|
|
11765
|
+
transition_out: z9.object({ type: z9.string().optional(), description: z9.string().optional() }).loose().optional(),
|
|
11766
|
+
dialogue: z9.array(DialogueLine).optional(),
|
|
11767
|
+
sfx: z9.array(Sfx).optional(),
|
|
11768
|
+
overlays: z9.array(z9.unknown()).optional(),
|
|
11769
|
+
floating_elements: z9.array(z9.unknown()).optional(),
|
|
11770
|
+
transcript_slice: z9.array(TranscriptWord).optional(),
|
|
10102
11771
|
start_frame_asset: FrameAsset,
|
|
10103
11772
|
end_frame_asset: FrameAsset,
|
|
10104
11773
|
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
10105
11774
|
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
10106
11775
|
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
10107
11776
|
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
10108
|
-
continues_previous:
|
|
11777
|
+
continues_previous: z9.boolean().optional()
|
|
10109
11778
|
}).loose();
|
|
10110
|
-
var VideoBlueprint =
|
|
10111
|
-
source:
|
|
10112
|
-
global:
|
|
10113
|
-
music:
|
|
10114
|
-
present:
|
|
10115
|
-
music_prompt:
|
|
11779
|
+
var VideoBlueprint = z9.object({
|
|
11780
|
+
source: z9.object({ aspect_ratio: z9.string().optional(), duration_s: z9.number().optional() }).loose().optional(),
|
|
11781
|
+
global: z9.object({
|
|
11782
|
+
music: z9.object({
|
|
11783
|
+
present: z9.boolean().optional(),
|
|
11784
|
+
music_prompt: z9.string().optional(),
|
|
10116
11785
|
// Absolute second the music enters in the reference (the bed often
|
|
10117
11786
|
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
10118
11787
|
// instead of at 0 so the timing matches.
|
|
10119
|
-
starts_at_s:
|
|
11788
|
+
starts_at_s: z9.number().optional(),
|
|
10120
11789
|
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
10121
11790
|
// reference track. We never reuse it — only style the regenerated bed.
|
|
10122
|
-
identified_track:
|
|
11791
|
+
identified_track: z9.object({ title: z9.string().optional(), artist: z9.string().optional() }).loose().nullish()
|
|
10123
11792
|
}).loose().optional(),
|
|
10124
|
-
cast:
|
|
10125
|
-
|
|
10126
|
-
id:
|
|
10127
|
-
description:
|
|
11793
|
+
cast: z9.array(
|
|
11794
|
+
z9.object({
|
|
11795
|
+
id: z9.string().optional(),
|
|
11796
|
+
description: z9.string().optional(),
|
|
10128
11797
|
// The deconstruct's note on the target-market localization (e.g. "native
|
|
10129
11798
|
// French speaker") — read to derive the spoken-track language code.
|
|
10130
|
-
market_localization_note:
|
|
11799
|
+
market_localization_note: z9.string().optional()
|
|
10131
11800
|
}).loose()
|
|
10132
11801
|
).optional(),
|
|
10133
|
-
voiceover:
|
|
11802
|
+
voiceover: z9.object({
|
|
10134
11803
|
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
10135
11804
|
// voiceover | none → narration over the picture (no lip-sync).
|
|
10136
|
-
mode:
|
|
10137
|
-
voice_description:
|
|
10138
|
-
persona:
|
|
11805
|
+
mode: z9.string().optional(),
|
|
11806
|
+
voice_description: z9.string().optional(),
|
|
11807
|
+
persona: z9.string().optional()
|
|
10139
11808
|
}).loose().optional(),
|
|
10140
11809
|
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
10141
11810
|
// first hex is the dominant brand colour); never to drive frame generation.
|
|
10142
|
-
style:
|
|
11811
|
+
style: z9.object({ palette: z9.array(z9.object({ hex: z9.string().optional() }).loose()).optional() }).loose().optional()
|
|
10143
11812
|
}).loose().optional(),
|
|
10144
|
-
scenes:
|
|
11813
|
+
scenes: z9.array(Scene).min(1)
|
|
10145
11814
|
}).loose();
|
|
10146
11815
|
function injectHookPhysicality(blueprint) {
|
|
10147
11816
|
for (const scene of blueprint.scenes) {
|
|
@@ -10151,26 +11820,26 @@ function injectHookPhysicality(blueprint) {
|
|
|
10151
11820
|
scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
|
|
10152
11821
|
}
|
|
10153
11822
|
}
|
|
10154
|
-
var AppearsItem =
|
|
10155
|
-
var RecurringElement =
|
|
11823
|
+
var AppearsItem = z9.union([z9.number(), z9.object({ scene: z9.number(), edge: z9.string().optional() }).loose()]);
|
|
11824
|
+
var RecurringElement = z9.object({
|
|
10156
11825
|
// person | animal | product | logo | badge | other
|
|
10157
|
-
type:
|
|
10158
|
-
label:
|
|
10159
|
-
description:
|
|
10160
|
-
expression:
|
|
11826
|
+
type: z9.string(),
|
|
11827
|
+
label: z9.string().optional(),
|
|
11828
|
+
description: z9.string().optional(),
|
|
11829
|
+
expression: z9.string().nullable().optional(),
|
|
10161
11830
|
// When the element maps to a global cast entry, its stable id (for annotation).
|
|
10162
|
-
cast_id:
|
|
11831
|
+
cast_id: z9.string().nullable().optional(),
|
|
10163
11832
|
// The label of another element that is the SAME individual as this one, shown
|
|
10164
11833
|
// in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
|
|
10165
11834
|
// pink shirt and believer in a white shirt). Each look gets its own reference
|
|
10166
11835
|
// slot, but the face/identity must stay identical across them.
|
|
10167
|
-
same_as:
|
|
11836
|
+
same_as: z9.string().nullable().optional(),
|
|
10168
11837
|
// Scenes the element appears in. Either a bare list of scene indices (both
|
|
10169
11838
|
// edges) or per-{scene,edge} entries. Both forms are accepted and merged.
|
|
10170
|
-
scenes:
|
|
10171
|
-
appears_in:
|
|
11839
|
+
scenes: z9.array(z9.number()).optional(),
|
|
11840
|
+
appears_in: z9.array(AppearsItem).optional()
|
|
10172
11841
|
}).loose();
|
|
10173
|
-
var RecurringElements =
|
|
11842
|
+
var RecurringElements = z9.array(RecurringElement);
|
|
10174
11843
|
function sanitizeId2(raw, fallback) {
|
|
10175
11844
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
10176
11845
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -11633,25 +13302,25 @@ function buildSfxMusic(blueprint, nodes) {
|
|
|
11633
13302
|
}
|
|
11634
13303
|
return tracks;
|
|
11635
13304
|
}
|
|
11636
|
-
var OverlayStyle =
|
|
11637
|
-
var Overlay =
|
|
11638
|
-
text:
|
|
11639
|
-
appears_at_s:
|
|
11640
|
-
duration_s:
|
|
11641
|
-
position:
|
|
11642
|
-
role:
|
|
11643
|
-
animation:
|
|
11644
|
-
animation_detail:
|
|
13305
|
+
var OverlayStyle = z9.object({ color_hex: z9.string().optional(), background: z9.string().optional(), size: z9.string().optional() }).loose();
|
|
13306
|
+
var Overlay = z9.object({
|
|
13307
|
+
text: z9.string().optional(),
|
|
13308
|
+
appears_at_s: z9.number().optional(),
|
|
13309
|
+
duration_s: z9.number().optional(),
|
|
13310
|
+
position: z9.string().optional(),
|
|
13311
|
+
role: z9.string().optional(),
|
|
13312
|
+
animation: z9.string().optional(),
|
|
13313
|
+
animation_detail: z9.string().optional(),
|
|
11645
13314
|
style: OverlayStyle.optional()
|
|
11646
13315
|
}).loose();
|
|
11647
|
-
var FloatingElement =
|
|
11648
|
-
kind:
|
|
11649
|
-
description:
|
|
11650
|
-
brand_name:
|
|
11651
|
-
what_it_represents:
|
|
11652
|
-
appears_at_s:
|
|
11653
|
-
duration_s:
|
|
11654
|
-
position:
|
|
13316
|
+
var FloatingElement = z9.object({
|
|
13317
|
+
kind: z9.string().optional(),
|
|
13318
|
+
description: z9.string().optional(),
|
|
13319
|
+
brand_name: z9.string().nullish(),
|
|
13320
|
+
what_it_represents: z9.string().optional(),
|
|
13321
|
+
appears_at_s: z9.number().optional(),
|
|
13322
|
+
duration_s: z9.number().optional(),
|
|
13323
|
+
position: z9.string().optional()
|
|
11655
13324
|
}).loose();
|
|
11656
13325
|
function escapeHtml(s) {
|
|
11657
13326
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -11683,7 +13352,7 @@ function positionClass(position) {
|
|
|
11683
13352
|
function collectCaptions(blueprint) {
|
|
11684
13353
|
return blueprint.scenes.flatMap((scene) => {
|
|
11685
13354
|
const sceneStart = scene.start_s ?? 0;
|
|
11686
|
-
const overlays =
|
|
13355
|
+
const overlays = z9.array(Overlay).safeParse(scene.overlays ?? []);
|
|
11687
13356
|
return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
|
|
11688
13357
|
const at = ov.appears_at_s ?? sceneStart;
|
|
11689
13358
|
return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
|
|
@@ -11792,7 +13461,7 @@ function buildOverlayHtml(input) {
|
|
|
11792
13461
|
if (ovParts.length > 0) blocks.push(ovParts.join("\n"));
|
|
11793
13462
|
for (const scene of blueprint.scenes) {
|
|
11794
13463
|
const sceneStart = scene.start_s ?? 0;
|
|
11795
|
-
const floats =
|
|
13464
|
+
const floats = z9.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
11796
13465
|
const parts = (floats.success ? floats.data.map((fe) => floatingStub(fe, sceneStart)) : []).filter(Boolean);
|
|
11797
13466
|
const pip = uiPipStub(scene);
|
|
11798
13467
|
if (pip) parts.push(pip);
|
|
@@ -12049,8 +13718,8 @@ function buildMotionBoard(blueprint) {
|
|
|
12049
13718
|
const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
|
|
12050
13719
|
cursor = end_s;
|
|
12051
13720
|
const spoken = sceneSpokenText(scene);
|
|
12052
|
-
const overlays =
|
|
12053
|
-
const floats =
|
|
13721
|
+
const overlays = z9.array(Overlay).safeParse(scene.overlays ?? []);
|
|
13722
|
+
const floats = z9.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
12054
13723
|
const graphics = [
|
|
12055
13724
|
...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
|
|
12056
13725
|
kind: "text",
|
|
@@ -12491,7 +14160,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
12491
14160
|
return fail2("deconstruct", e instanceof Error ? e.message : String(e));
|
|
12492
14161
|
}
|
|
12493
14162
|
}
|
|
12494
|
-
var scaffoldVideoCommand =
|
|
14163
|
+
var scaffoldVideoCommand = defineCommand85({
|
|
12495
14164
|
meta: {
|
|
12496
14165
|
name: "scaffold-video",
|
|
12497
14166
|
description: "Turn a reference video into a runnable reproduction canvas in one command. Runs billed passes \u2014 video_deconstruct (the full scene-by-scene blueprint + transcript, baked to prompt.json as the editable 'prompt') and an AI selection of the video's RECURRING identity elements (person/animal/product/logo) \u2014 then scaffolds a pipeline where every scene boundary is a static-ad-grade frame (the blueprint as target_blueprint, a reference legend, the real frame as anchor) and each recurring element gets ONE shared [TODO] ingest slot wired into every frame it appears in. The clips feed Seedance an ultra-detailed motion brief (action, camera, dialogue, transcript). Edit prompt.json, drop the real source images, then `baker canvas run`."
|
|
@@ -12636,7 +14305,7 @@ var scaffoldVideoCommand = defineCommand83({
|
|
|
12636
14305
|
// src/commands/canvas/set-prompt.ts
|
|
12637
14306
|
import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
12638
14307
|
import path9 from "path";
|
|
12639
|
-
import { defineCommand as
|
|
14308
|
+
import { defineCommand as defineCommand86 } from "citty";
|
|
12640
14309
|
function setNodePrompt(canvas, nodeId, text) {
|
|
12641
14310
|
const nodes = canvas?.nodes;
|
|
12642
14311
|
if (!Array.isArray(nodes)) throw new Error("canvas has no nodes array");
|
|
@@ -12651,7 +14320,7 @@ function setNodePrompt(canvas, nodeId, text) {
|
|
|
12651
14320
|
newNodes[idx] = newNode;
|
|
12652
14321
|
return { ...canvas, nodes: newNodes };
|
|
12653
14322
|
}
|
|
12654
|
-
var setPromptCommand =
|
|
14323
|
+
var setPromptCommand = defineCommand86({
|
|
12655
14324
|
meta: {
|
|
12656
14325
|
name: "set-prompt",
|
|
12657
14326
|
description: "Safely set a node's params.prompt (a frame description, motion prompt, etc.) without hand-editing the JSON. Prefer --text-file for multi-line/accented copy \u2014 it preserves UTF-8 exactly, unlike shell-quoted jq."
|
|
@@ -12711,8 +14380,8 @@ var setPromptCommand = defineCommand84({
|
|
|
12711
14380
|
// src/commands/canvas/validate.ts
|
|
12712
14381
|
import { readFile as readFile8 } from "fs/promises";
|
|
12713
14382
|
import path10 from "path";
|
|
12714
|
-
import { defineCommand as
|
|
12715
|
-
var validateCommand =
|
|
14383
|
+
import { defineCommand as defineCommand87 } from "citty";
|
|
14384
|
+
var validateCommand = defineCommand87({
|
|
12716
14385
|
meta: {
|
|
12717
14386
|
name: "validate",
|
|
12718
14387
|
description: "Validate a canvas JSON file (no execution). Includes a per-node cost preview and runs each node's deep validators (composition meta checks for hyperframe_render/_snapshot)."
|
|
@@ -12755,7 +14424,7 @@ var validateCommand = defineCommand85({
|
|
|
12755
14424
|
});
|
|
12756
14425
|
|
|
12757
14426
|
// src/commands/canvas/index.ts
|
|
12758
|
-
var canvasCommand =
|
|
14427
|
+
var canvasCommand = defineCommand88({
|
|
12759
14428
|
meta: {
|
|
12760
14429
|
name: "canvas",
|
|
12761
14430
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -12782,10 +14451,10 @@ Subcommands:
|
|
|
12782
14451
|
});
|
|
12783
14452
|
|
|
12784
14453
|
// src/commands/creatives/index.ts
|
|
12785
|
-
import { defineCommand as
|
|
14454
|
+
import { defineCommand as defineCommand90 } from "citty";
|
|
12786
14455
|
|
|
12787
14456
|
// src/commands/creatives/publish.ts
|
|
12788
|
-
import { defineCommand as
|
|
14457
|
+
import { defineCommand as defineCommand89 } from "citty";
|
|
12789
14458
|
|
|
12790
14459
|
// src/commands/images/api.ts
|
|
12791
14460
|
import { readFile as readFile9 } from "fs/promises";
|
|
@@ -12908,7 +14577,7 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
12908
14577
|
sourceReferenceUrl
|
|
12909
14578
|
});
|
|
12910
14579
|
}
|
|
12911
|
-
var publishCommand =
|
|
14580
|
+
var publishCommand = defineCommand89({
|
|
12912
14581
|
meta: {
|
|
12913
14582
|
name: "publish",
|
|
12914
14583
|
description: "Publish a final static creative image to Baker Creatives and print the creative reference JSON."
|
|
@@ -12954,7 +14623,7 @@ var publishCommand = defineCommand87({
|
|
|
12954
14623
|
});
|
|
12955
14624
|
|
|
12956
14625
|
// src/commands/creatives/index.ts
|
|
12957
|
-
var creativesCommand3 =
|
|
14626
|
+
var creativesCommand3 = defineCommand90({
|
|
12958
14627
|
meta: {
|
|
12959
14628
|
name: "creatives",
|
|
12960
14629
|
description: `Publish static ad creatives as first-class Baker outputs.
|
|
@@ -12970,10 +14639,10 @@ Publishing uploads the image to the Company image library, applies the official
|
|
|
12970
14639
|
});
|
|
12971
14640
|
|
|
12972
14641
|
// src/commands/ga4/index.ts
|
|
12973
|
-
import { defineCommand as
|
|
14642
|
+
import { defineCommand as defineCommand94 } from "citty";
|
|
12974
14643
|
|
|
12975
14644
|
// src/commands/ga4/audit.ts
|
|
12976
|
-
import { defineCommand as
|
|
14645
|
+
import { defineCommand as defineCommand91 } from "citty";
|
|
12977
14646
|
|
|
12978
14647
|
// src/commands/ga4/resolve.ts
|
|
12979
14648
|
async function fetchProperties(useCache = true) {
|
|
@@ -13036,7 +14705,7 @@ registerSchema({
|
|
|
13036
14705
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
13037
14706
|
}
|
|
13038
14707
|
});
|
|
13039
|
-
var auditCommand2 =
|
|
14708
|
+
var auditCommand2 = defineCommand91({
|
|
13040
14709
|
meta: {
|
|
13041
14710
|
name: "audit",
|
|
13042
14711
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -13088,7 +14757,7 @@ Examples:
|
|
|
13088
14757
|
});
|
|
13089
14758
|
|
|
13090
14759
|
// src/commands/ga4/properties.ts
|
|
13091
|
-
import { defineCommand as
|
|
14760
|
+
import { defineCommand as defineCommand92 } from "citty";
|
|
13092
14761
|
registerSchema({
|
|
13093
14762
|
command: "ga4.properties",
|
|
13094
14763
|
description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
|
|
@@ -13096,7 +14765,7 @@ registerSchema({
|
|
|
13096
14765
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
13097
14766
|
}
|
|
13098
14767
|
});
|
|
13099
|
-
var propertiesCommand =
|
|
14768
|
+
var propertiesCommand = defineCommand92({
|
|
13100
14769
|
meta: {
|
|
13101
14770
|
name: "properties",
|
|
13102
14771
|
description: `List accessible GA4 properties.
|
|
@@ -13144,9 +14813,9 @@ Examples:
|
|
|
13144
14813
|
});
|
|
13145
14814
|
|
|
13146
14815
|
// src/commands/ga4/query.ts
|
|
13147
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as
|
|
14816
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
|
|
13148
14817
|
import { resolve as resolve2 } from "path";
|
|
13149
|
-
import { defineCommand as
|
|
14818
|
+
import { defineCommand as defineCommand93 } from "citty";
|
|
13150
14819
|
|
|
13151
14820
|
// src/commands/ga4/presets.ts
|
|
13152
14821
|
var GA4_PRESETS = [
|
|
@@ -13235,7 +14904,7 @@ function writeRowsToFile2(filePath, rows, append) {
|
|
|
13235
14904
|
writeFileSync4(filePath, content, "utf-8");
|
|
13236
14905
|
}
|
|
13237
14906
|
} else if (append && existsSync5(filePath)) {
|
|
13238
|
-
const existing = JSON.parse(
|
|
14907
|
+
const existing = JSON.parse(readFileSync8(filePath, "utf-8"));
|
|
13239
14908
|
writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
13240
14909
|
} else {
|
|
13241
14910
|
writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -13278,7 +14947,7 @@ function handleError(err) {
|
|
|
13278
14947
|
});
|
|
13279
14948
|
process.exit(1);
|
|
13280
14949
|
}
|
|
13281
|
-
var queryCommand2 =
|
|
14950
|
+
var queryCommand2 = defineCommand93({
|
|
13282
14951
|
meta: {
|
|
13283
14952
|
name: "query",
|
|
13284
14953
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -13349,7 +15018,7 @@ Free-form (escape hatch):
|
|
|
13349
15018
|
});
|
|
13350
15019
|
|
|
13351
15020
|
// src/commands/ga4/index.ts
|
|
13352
|
-
var ga4Command =
|
|
15021
|
+
var ga4Command = defineCommand94({
|
|
13353
15022
|
meta: {
|
|
13354
15023
|
name: "ga4",
|
|
13355
15024
|
description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
|
|
@@ -13372,12 +15041,12 @@ Examples:
|
|
|
13372
15041
|
});
|
|
13373
15042
|
|
|
13374
15043
|
// src/commands/gsc/index.ts
|
|
13375
|
-
import { defineCommand as
|
|
15044
|
+
import { defineCommand as defineCommand98 } from "citty";
|
|
13376
15045
|
|
|
13377
15046
|
// src/commands/gsc/query.ts
|
|
13378
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as
|
|
15047
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
13379
15048
|
import { resolve as resolve3 } from "path";
|
|
13380
|
-
import { defineCommand as
|
|
15049
|
+
import { defineCommand as defineCommand95 } from "citty";
|
|
13381
15050
|
|
|
13382
15051
|
// src/commands/gsc/presets.ts
|
|
13383
15052
|
var GSC_PRESETS = [
|
|
@@ -13520,7 +15189,7 @@ function writeRowsToFile3(filePath, rows, append) {
|
|
|
13520
15189
|
writeFileSync5(filePath, content, "utf-8");
|
|
13521
15190
|
}
|
|
13522
15191
|
} else if (append && existsSync6(filePath)) {
|
|
13523
|
-
const existing = JSON.parse(
|
|
15192
|
+
const existing = JSON.parse(readFileSync9(filePath, "utf-8"));
|
|
13524
15193
|
writeFileSync5(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
13525
15194
|
} else {
|
|
13526
15195
|
writeFileSync5(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -13565,7 +15234,7 @@ function handleError2(err) {
|
|
|
13565
15234
|
});
|
|
13566
15235
|
process.exit(1);
|
|
13567
15236
|
}
|
|
13568
|
-
var queryCommand3 =
|
|
15237
|
+
var queryCommand3 = defineCommand95({
|
|
13569
15238
|
meta: {
|
|
13570
15239
|
name: "query",
|
|
13571
15240
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -13643,7 +15312,7 @@ Free-form (escape hatch):
|
|
|
13643
15312
|
});
|
|
13644
15313
|
|
|
13645
15314
|
// src/commands/gsc/sitemaps.ts
|
|
13646
|
-
import { defineCommand as
|
|
15315
|
+
import { defineCommand as defineCommand96 } from "citty";
|
|
13647
15316
|
registerSchema({
|
|
13648
15317
|
command: "gsc.sitemaps",
|
|
13649
15318
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -13652,7 +15321,7 @@ registerSchema({
|
|
|
13652
15321
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
13653
15322
|
}
|
|
13654
15323
|
});
|
|
13655
|
-
var sitemapsCommand =
|
|
15324
|
+
var sitemapsCommand = defineCommand96({
|
|
13656
15325
|
meta: {
|
|
13657
15326
|
name: "sitemaps",
|
|
13658
15327
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -13702,7 +15371,7 @@ Examples:
|
|
|
13702
15371
|
});
|
|
13703
15372
|
|
|
13704
15373
|
// src/commands/gsc/sites.ts
|
|
13705
|
-
import { defineCommand as
|
|
15374
|
+
import { defineCommand as defineCommand97 } from "citty";
|
|
13706
15375
|
registerSchema({
|
|
13707
15376
|
command: "gsc.sites",
|
|
13708
15377
|
description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
|
|
@@ -13710,7 +15379,7 @@ registerSchema({
|
|
|
13710
15379
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
13711
15380
|
}
|
|
13712
15381
|
});
|
|
13713
|
-
var sitesCommand =
|
|
15382
|
+
var sitesCommand = defineCommand97({
|
|
13714
15383
|
meta: {
|
|
13715
15384
|
name: "sites",
|
|
13716
15385
|
description: `List verified Search Console sites.
|
|
@@ -13758,7 +15427,7 @@ Examples:
|
|
|
13758
15427
|
});
|
|
13759
15428
|
|
|
13760
15429
|
// src/commands/gsc/index.ts
|
|
13761
|
-
var gscCommand =
|
|
15430
|
+
var gscCommand = defineCommand98({
|
|
13762
15431
|
meta: {
|
|
13763
15432
|
name: "gsc",
|
|
13764
15433
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -13781,10 +15450,10 @@ Examples:
|
|
|
13781
15450
|
});
|
|
13782
15451
|
|
|
13783
15452
|
// src/commands/images/index.ts
|
|
13784
|
-
import { defineCommand as
|
|
15453
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
13785
15454
|
|
|
13786
15455
|
// src/commands/images/crop.ts
|
|
13787
|
-
import { defineCommand as
|
|
15456
|
+
import { defineCommand as defineCommand99 } from "citty";
|
|
13788
15457
|
|
|
13789
15458
|
// src/lib/image/crop-sprite.ts
|
|
13790
15459
|
import sharp from "sharp";
|
|
@@ -13909,7 +15578,7 @@ function emitError2(err) {
|
|
|
13909
15578
|
}
|
|
13910
15579
|
process.exit(1);
|
|
13911
15580
|
}
|
|
13912
|
-
var cropCommand =
|
|
15581
|
+
var cropCommand = defineCommand99({
|
|
13913
15582
|
meta: {
|
|
13914
15583
|
name: "crop",
|
|
13915
15584
|
description: "Crop a rectangular region from an image.\n\nExample: baker images crop sprite.png --x 0 --y 0 --width 64 --height 64 --output icon.png"
|
|
@@ -13945,7 +15614,7 @@ var cropCommand = defineCommand97({
|
|
|
13945
15614
|
});
|
|
13946
15615
|
|
|
13947
15616
|
// src/commands/images/delete.ts
|
|
13948
|
-
import { defineCommand as
|
|
15617
|
+
import { defineCommand as defineCommand100 } from "citty";
|
|
13949
15618
|
registerSchema({
|
|
13950
15619
|
command: "images.delete",
|
|
13951
15620
|
description: "Delete an image by ID",
|
|
@@ -13959,7 +15628,7 @@ registerSchema({
|
|
|
13959
15628
|
}
|
|
13960
15629
|
}
|
|
13961
15630
|
});
|
|
13962
|
-
var deleteCommand =
|
|
15631
|
+
var deleteCommand = defineCommand100({
|
|
13963
15632
|
meta: {
|
|
13964
15633
|
name: "delete",
|
|
13965
15634
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -14000,7 +15669,7 @@ var deleteCommand = defineCommand98({
|
|
|
14000
15669
|
});
|
|
14001
15670
|
|
|
14002
15671
|
// src/commands/images/dimensions.ts
|
|
14003
|
-
import { defineCommand as
|
|
15672
|
+
import { defineCommand as defineCommand101 } from "citty";
|
|
14004
15673
|
|
|
14005
15674
|
// src/lib/image/dimensions.ts
|
|
14006
15675
|
import { imageSize } from "image-size";
|
|
@@ -14023,7 +15692,7 @@ registerSchema({
|
|
|
14023
15692
|
target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
|
|
14024
15693
|
}
|
|
14025
15694
|
});
|
|
14026
|
-
var dimensionsCommand =
|
|
15695
|
+
var dimensionsCommand = defineCommand101({
|
|
14027
15696
|
meta: {
|
|
14028
15697
|
name: "dimensions",
|
|
14029
15698
|
description: "Read image dimensions without decoding the full file.\n\nExample: baker images dimensions ./logo.png\nExample: baker images dimensions https://acme.com/hero.png"
|
|
@@ -14067,7 +15736,7 @@ var dimensionsCommand = defineCommand99({
|
|
|
14067
15736
|
});
|
|
14068
15737
|
|
|
14069
15738
|
// src/commands/images/extract.ts
|
|
14070
|
-
import { defineCommand as
|
|
15739
|
+
import { defineCommand as defineCommand102 } from "citty";
|
|
14071
15740
|
registerSchema({
|
|
14072
15741
|
command: "images.extract",
|
|
14073
15742
|
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
@@ -14083,7 +15752,7 @@ registerSchema({
|
|
|
14083
15752
|
}
|
|
14084
15753
|
}
|
|
14085
15754
|
});
|
|
14086
|
-
var extractCommand =
|
|
15755
|
+
var extractCommand = defineCommand102({
|
|
14087
15756
|
meta: {
|
|
14088
15757
|
name: "extract",
|
|
14089
15758
|
description: "Pull every image from a single URL via Firecrawl. ~$0.001/scrape. Cap auto-ingest at 20.\n\nExample: baker images extract https://stripe.com --auto-ingest 5"
|
|
@@ -14121,7 +15790,7 @@ var extractCommand = defineCommand100({
|
|
|
14121
15790
|
});
|
|
14122
15791
|
|
|
14123
15792
|
// src/commands/images/find.ts
|
|
14124
|
-
import { defineCommand as
|
|
15793
|
+
import { defineCommand as defineCommand103 } from "citty";
|
|
14125
15794
|
registerSchema({
|
|
14126
15795
|
command: "images.find",
|
|
14127
15796
|
description: "Fanout image search: library first, then opted-in external providers.",
|
|
@@ -14153,7 +15822,7 @@ registerSchema({
|
|
|
14153
15822
|
}
|
|
14154
15823
|
}
|
|
14155
15824
|
});
|
|
14156
|
-
var findCommand =
|
|
15825
|
+
var findCommand = defineCommand103({
|
|
14157
15826
|
meta: {
|
|
14158
15827
|
name: "find",
|
|
14159
15828
|
description: "Library-first fanout image search. Opt in to providers with --sources. `--fallback` short-circuits to externals only when library is thin. With --auto-ingest, ingested external hits return Baker-owned URLs.\n\nExample: baker images find 'office' --sources library,magnific --limit 20"
|
|
@@ -14202,7 +15871,7 @@ var findCommand = defineCommand101({
|
|
|
14202
15871
|
|
|
14203
15872
|
// src/commands/images/generate.ts
|
|
14204
15873
|
import { readFile as readFile11 } from "fs/promises";
|
|
14205
|
-
import { defineCommand as
|
|
15874
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
14206
15875
|
import sharp2 from "sharp";
|
|
14207
15876
|
var GENERATE_TIMEOUT_MS = 18e4;
|
|
14208
15877
|
var REFERENCE_MAX_EDGE = 1536;
|
|
@@ -14305,7 +15974,7 @@ async function resolveReferences(spec) {
|
|
|
14305
15974
|
}
|
|
14306
15975
|
return out;
|
|
14307
15976
|
}
|
|
14308
|
-
var generateCommand =
|
|
15977
|
+
var generateCommand = defineCommand104({
|
|
14309
15978
|
meta: {
|
|
14310
15979
|
name: "generate",
|
|
14311
15980
|
description: "Generate an image with AI and store it in the library (cost-tracked per request via OpenRouter usage). Models mirror the canvas: openai/gpt-5.4-image-2 (default \u2014 photoreal, cleanest text, best for ad/landing reproduction), google/gemini-3-pro-image-preview (Nano Banana Pro), google/gemini-3.5-flash & google/gemini-3.1-flash-image-preview (fast, extreme aspect ratios), recraft/recraft-v4.1-pro-vector (vector/SVG-style with palette control). The result is auto-ingested (describe + embed), so the next `baker images library` query finds it. Pass --reference with image URLs and/or local file paths (Pinterest, stock, brand assets, sandbox files) to ground generation in reality.\n\nExamples:\n baker images generate 'a friendly golden retriever sitting in a bright modern living room' --aspect-ratio 16:9\n baker images generate 'hero shot of a matte black water bottle on marble' --model google/gemini-3-pro-image-preview --image-size 2K\n baker images generate 'lifestyle photo matching this mood' --reference 'https://\u2026/ref1.jpg,https://\u2026/ref2.jpg'\n baker images generate 'put this product on a marble countertop, soft daylight' --reference './src/brand/logos/product.png,./refs/kitchen-mood.jpg'\n baker images generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
|
|
@@ -14357,7 +16026,7 @@ var generateCommand = defineCommand102({
|
|
|
14357
16026
|
});
|
|
14358
16027
|
|
|
14359
16028
|
// src/commands/images/get.ts
|
|
14360
|
-
import { defineCommand as
|
|
16029
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
14361
16030
|
registerSchema({
|
|
14362
16031
|
command: "images.get",
|
|
14363
16032
|
description: "Get a single image by ID",
|
|
@@ -14365,7 +16034,7 @@ registerSchema({
|
|
|
14365
16034
|
id: { type: "string", description: "Image ID", required: true }
|
|
14366
16035
|
}
|
|
14367
16036
|
});
|
|
14368
|
-
var getCommand2 =
|
|
16037
|
+
var getCommand2 = defineCommand105({
|
|
14369
16038
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
14370
16039
|
args: {
|
|
14371
16040
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -14401,7 +16070,7 @@ var getCommand2 = defineCommand103({
|
|
|
14401
16070
|
});
|
|
14402
16071
|
|
|
14403
16072
|
// src/commands/images/gif.ts
|
|
14404
|
-
import { defineCommand as
|
|
16073
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
14405
16074
|
registerSchema({
|
|
14406
16075
|
command: "images.gif",
|
|
14407
16076
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -14433,7 +16102,7 @@ registerSchema({
|
|
|
14433
16102
|
}
|
|
14434
16103
|
}
|
|
14435
16104
|
});
|
|
14436
|
-
var gifCommand =
|
|
16105
|
+
var gifCommand = defineCommand106({
|
|
14437
16106
|
meta: {
|
|
14438
16107
|
name: "gif",
|
|
14439
16108
|
description: "Search Giphy for GIFs / reaction memes \u2014 built for paid-social creative (Meta, TikTok, LinkedIn, X). Free API. Each hit carries WebP + GIF + MP4 URLs in providerMeta so you can pick the right format per platform.\n\nExample: baker images gif 'this is fine' --limit 10\nExample: baker images gif 'office reaction' --rating pg --auto-ingest 2\nExample: baker images gif --trending --limit 25"
|
|
@@ -14480,7 +16149,7 @@ var gifCommand = defineCommand104({
|
|
|
14480
16149
|
});
|
|
14481
16150
|
|
|
14482
16151
|
// src/commands/images/google.ts
|
|
14483
|
-
import { defineCommand as
|
|
16152
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
14484
16153
|
registerSchema({
|
|
14485
16154
|
command: "images.google",
|
|
14486
16155
|
description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
|
|
@@ -14516,7 +16185,7 @@ registerSchema({
|
|
|
14516
16185
|
}
|
|
14517
16186
|
}
|
|
14518
16187
|
});
|
|
14519
|
-
var googleCommand2 =
|
|
16188
|
+
var googleCommand2 = defineCommand107({
|
|
14520
16189
|
meta: {
|
|
14521
16190
|
name: "google",
|
|
14522
16191
|
description: "Google Images via the official Custom Search JSON API ($0.005/query, free 100/day). \u26A0 Source unverified \u2014 watermarks, low-res, mislabeled results are common. Use as last resort. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExample: baker images google 'industrial workshop' --type photo --size large --limit 20"
|
|
@@ -14564,7 +16233,7 @@ var googleCommand2 = defineCommand105({
|
|
|
14564
16233
|
});
|
|
14565
16234
|
|
|
14566
16235
|
// src/commands/images/icon.ts
|
|
14567
|
-
import { defineCommand as
|
|
16236
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
14568
16237
|
registerSchema({
|
|
14569
16238
|
command: "images.icon",
|
|
14570
16239
|
description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
|
|
@@ -14590,7 +16259,7 @@ registerSchema({
|
|
|
14590
16259
|
}
|
|
14591
16260
|
}
|
|
14592
16261
|
});
|
|
14593
|
-
var iconCommand =
|
|
16262
|
+
var iconCommand = defineCommand108({
|
|
14594
16263
|
meta: {
|
|
14595
16264
|
name: "icon",
|
|
14596
16265
|
description: "Icon via Iconify (simple-icons, logos, lucide, devicon, heroicons, tabler, phosphor, material-symbols, \u2026). Free CDN, no API key.\n\nExample: baker images icon react --set devicon\nExample: baker images icon lucide:check --color '#0a0a0a'"
|
|
@@ -14630,7 +16299,7 @@ var iconCommand = defineCommand106({
|
|
|
14630
16299
|
});
|
|
14631
16300
|
|
|
14632
16301
|
// src/commands/images/ingest.ts
|
|
14633
|
-
import { defineCommand as
|
|
16302
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
14634
16303
|
registerSchema({
|
|
14635
16304
|
command: "images.ingest",
|
|
14636
16305
|
description: "Ingest a remote image URL into the library (full describe + embed).",
|
|
@@ -14642,7 +16311,7 @@ registerSchema({
|
|
|
14642
16311
|
context: { type: "string", description: "Description context hint", required: false }
|
|
14643
16312
|
}
|
|
14644
16313
|
});
|
|
14645
|
-
var ingestCommand =
|
|
16314
|
+
var ingestCommand = defineCommand109({
|
|
14646
16315
|
meta: {
|
|
14647
16316
|
name: "ingest",
|
|
14648
16317
|
description: "Download a remote URL and store it in the library. Hash-deduped on bytes + externalId.\n\nExample: baker images ingest https://img.freepik.com/free-photo/xyz.jpg --source magnific --external-id 12345"
|
|
@@ -14684,7 +16353,7 @@ var ingestCommand = defineCommand107({
|
|
|
14684
16353
|
});
|
|
14685
16354
|
|
|
14686
16355
|
// src/commands/images/library.ts
|
|
14687
|
-
import { defineCommand as
|
|
16356
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
14688
16357
|
registerSchema({
|
|
14689
16358
|
command: "images.library",
|
|
14690
16359
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -14710,7 +16379,7 @@ registerSchema({
|
|
|
14710
16379
|
}
|
|
14711
16380
|
}
|
|
14712
16381
|
});
|
|
14713
|
-
var libraryCommand =
|
|
16382
|
+
var libraryCommand = defineCommand110({
|
|
14714
16383
|
meta: {
|
|
14715
16384
|
name: "library",
|
|
14716
16385
|
description: "Search the company image library (hybrid BM25 + vector + Cohere rerank). Use this BEFORE any external provider.\n\nExample: baker images library 'hero banner' --aspect-ratio 16:9 --source magnific"
|
|
@@ -14767,7 +16436,7 @@ var libraryCommand = defineCommand108({
|
|
|
14767
16436
|
});
|
|
14768
16437
|
|
|
14769
16438
|
// src/commands/images/logo.ts
|
|
14770
|
-
import { defineCommand as
|
|
16439
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
14771
16440
|
registerSchema({
|
|
14772
16441
|
command: "images.logo",
|
|
14773
16442
|
description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
|
|
@@ -14792,7 +16461,7 @@ registerSchema({
|
|
|
14792
16461
|
}
|
|
14793
16462
|
}
|
|
14794
16463
|
});
|
|
14795
|
-
var logoCommand =
|
|
16464
|
+
var logoCommand = defineCommand111({
|
|
14796
16465
|
meta: {
|
|
14797
16466
|
name: "logo",
|
|
14798
16467
|
description: "Brand logo via Brandfetch CDN. Returns up to 5 variants (icon, light/dark logo, light/dark symbol). Auto-ingests the first variant.\n\nExample: baker images logo stripe.com --variant logo"
|
|
@@ -14830,7 +16499,7 @@ var logoCommand = defineCommand109({
|
|
|
14830
16499
|
});
|
|
14831
16500
|
|
|
14832
16501
|
// src/commands/images/normalize.ts
|
|
14833
|
-
import { defineCommand as
|
|
16502
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
14834
16503
|
|
|
14835
16504
|
// src/lib/image/color-changer.ts
|
|
14836
16505
|
import quantize from "quantize";
|
|
@@ -15562,7 +17231,7 @@ function coerceRawArgs(args) {
|
|
|
15562
17231
|
"dry-run": bool(args["dry-run"])
|
|
15563
17232
|
};
|
|
15564
17233
|
}
|
|
15565
|
-
var normalizeCommand =
|
|
17234
|
+
var normalizeCommand = defineCommand112({
|
|
15566
17235
|
meta: {
|
|
15567
17236
|
name: "normalize",
|
|
15568
17237
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -15617,7 +17286,7 @@ Examples:
|
|
|
15617
17286
|
});
|
|
15618
17287
|
|
|
15619
17288
|
// src/commands/images/pinterest.ts
|
|
15620
|
-
import { defineCommand as
|
|
17289
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
15621
17290
|
registerSchema({
|
|
15622
17291
|
command: "images.pinterest",
|
|
15623
17292
|
description: "Pinterest image search via ScrapeCreators. Reference-grade real-world photography, product styling, interiors, fashion, food, and aesthetic mood boards. Inspect before placing \u2014 Pinterest is unverified, trademark-bearing web content.",
|
|
@@ -15637,7 +17306,7 @@ registerSchema({
|
|
|
15637
17306
|
}
|
|
15638
17307
|
}
|
|
15639
17308
|
});
|
|
15640
|
-
var pinterestCommand =
|
|
17309
|
+
var pinterestCommand = defineCommand113({
|
|
15641
17310
|
meta: {
|
|
15642
17311
|
name: "pinterest",
|
|
15643
17312
|
description: "Pinterest image search via ScrapeCreators ($0.00188/request). Best for photo-realistic reference imagery \u2014 lifestyle, interiors, fashion, food, product styling, and mood boards to brief AI generation against. \u26A0 Unverified, trademark-bearing web content \u2014 inspect and respect rights before placing on a customer page. Browse first; auto-ingest only the pins you commit to.\n\nExamples:\n baker images pinterest 'scandinavian living room'\n baker images pinterest 'minimalist skincare product photography' --limit 20\n baker images pinterest 'cozy coffee shop interior' --auto-ingest 2 --context 'Mood reference for hero photography'"
|
|
@@ -15677,7 +17346,7 @@ var pinterestCommand = defineCommand111({
|
|
|
15677
17346
|
});
|
|
15678
17347
|
|
|
15679
17348
|
// src/commands/images/screenshot.ts
|
|
15680
|
-
import { defineCommand as
|
|
17349
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
15681
17350
|
registerSchema({
|
|
15682
17351
|
command: "images.screenshot",
|
|
15683
17352
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -15693,7 +17362,7 @@ registerSchema({
|
|
|
15693
17362
|
}
|
|
15694
17363
|
}
|
|
15695
17364
|
});
|
|
15696
|
-
var screenshotCommand =
|
|
17365
|
+
var screenshotCommand = defineCommand114({
|
|
15697
17366
|
meta: {
|
|
15698
17367
|
name: "screenshot",
|
|
15699
17368
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -15743,7 +17412,7 @@ var screenshotCommand = defineCommand112({
|
|
|
15743
17412
|
});
|
|
15744
17413
|
|
|
15745
17414
|
// src/commands/images/search.ts
|
|
15746
|
-
import { defineCommand as
|
|
17415
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
15747
17416
|
registerSchema({
|
|
15748
17417
|
command: "images.search",
|
|
15749
17418
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -15759,7 +17428,7 @@ registerSchema({
|
|
|
15759
17428
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
15760
17429
|
}
|
|
15761
17430
|
});
|
|
15762
|
-
var searchCommand =
|
|
17431
|
+
var searchCommand = defineCommand115({
|
|
15763
17432
|
meta: {
|
|
15764
17433
|
name: "search",
|
|
15765
17434
|
description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
|
|
@@ -15819,7 +17488,7 @@ var searchCommand = defineCommand113({
|
|
|
15819
17488
|
});
|
|
15820
17489
|
|
|
15821
17490
|
// src/commands/images/sticker.ts
|
|
15822
|
-
import { defineCommand as
|
|
17491
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
15823
17492
|
registerSchema({
|
|
15824
17493
|
command: "images.sticker",
|
|
15825
17494
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -15851,7 +17520,7 @@ registerSchema({
|
|
|
15851
17520
|
}
|
|
15852
17521
|
}
|
|
15853
17522
|
});
|
|
15854
|
-
var stickerCommand =
|
|
17523
|
+
var stickerCommand = defineCommand116({
|
|
15855
17524
|
meta: {
|
|
15856
17525
|
name: "sticker",
|
|
15857
17526
|
description: "Search Giphy's sticker corpus \u2014 transparent-background WebPs / GIFs ideal for overlaying on ad creative (Meta, TikTok, Stories). Same Giphy free API as `baker images gif`; results carry WebP + GIF + MP4 URLs in providerMeta.\n\nExample: baker images sticker 'thumbs up' --limit 10\nExample: baker images sticker celebration --rating g --auto-ingest 3\nExample: baker images sticker --trending --limit 25"
|
|
@@ -15898,7 +17567,7 @@ var stickerCommand = defineCommand114({
|
|
|
15898
17567
|
});
|
|
15899
17568
|
|
|
15900
17569
|
// src/commands/images/stock.ts
|
|
15901
|
-
import { defineCommand as
|
|
17570
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
15902
17571
|
registerSchema({
|
|
15903
17572
|
command: "images.stock",
|
|
15904
17573
|
description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
|
|
@@ -15956,7 +17625,7 @@ registerSchema({
|
|
|
15956
17625
|
}
|
|
15957
17626
|
}
|
|
15958
17627
|
});
|
|
15959
|
-
var stockCommand =
|
|
17628
|
+
var stockCommand = defineCommand117({
|
|
15960
17629
|
meta: {
|
|
15961
17630
|
name: "stock",
|
|
15962
17631
|
description: "Stock search via Magnific \u2014 Freepik's developer API (~250M assets: photos, vectors, illustrations, icons, PSDs). $0.002/req. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExamples:\n baker images stock 'minimalist office'\n baker images stock 'flat office workers' --type vector\n baker images stock 'hero photo of a kitchen' --type photo --orientation landscape --ai exclude\n baker images stock 'brand pattern' --color '#0a0a0a' --license freemium --auto-ingest 2"
|
|
@@ -16012,7 +17681,7 @@ var stockCommand = defineCommand115({
|
|
|
16012
17681
|
});
|
|
16013
17682
|
|
|
16014
17683
|
// src/lib/tags-command.ts
|
|
16015
|
-
import { defineCommand as
|
|
17684
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
16016
17685
|
function makeTagsCommand(command, label, endpoint) {
|
|
16017
17686
|
registerSchema({
|
|
16018
17687
|
command: `${command}.tags`,
|
|
@@ -16021,7 +17690,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
16021
17690
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
16022
17691
|
}
|
|
16023
17692
|
});
|
|
16024
|
-
return
|
|
17693
|
+
return defineCommand118({
|
|
16025
17694
|
meta: {
|
|
16026
17695
|
name: "tags",
|
|
16027
17696
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -16057,7 +17726,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
16057
17726
|
var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
16058
17727
|
|
|
16059
17728
|
// src/commands/images/upload.ts
|
|
16060
|
-
import { defineCommand as
|
|
17729
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
16061
17730
|
registerSchema({
|
|
16062
17731
|
command: "images.upload",
|
|
16063
17732
|
description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
|
|
@@ -16095,7 +17764,7 @@ registerSchema({
|
|
|
16095
17764
|
function isRemoteUrl2(value) {
|
|
16096
17765
|
return /^https?:\/\//i.test(value);
|
|
16097
17766
|
}
|
|
16098
|
-
var uploadCommand =
|
|
17767
|
+
var uploadCommand = defineCommand119({
|
|
16099
17768
|
meta: {
|
|
16100
17769
|
name: "upload",
|
|
16101
17770
|
description: "Upload an image to the library \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: reads bytes, sends to /api/images/upload, content-type auto-detected from extension.\nRemote: dispatches to /api/images/ingest with hash-dedup on bytes + externalId.\n\nExamples:\n baker images upload ./logo.png --source uploaded\n baker images upload ./cert.png --context 'ISO 27001 badge \u2014 enterprise tier'\n baker images upload https://acme.com/hero.png --source firecrawl --context 'Acme competitor pricing hero'"
|
|
@@ -16188,7 +17857,7 @@ async function uploadLocal(target, args) {
|
|
|
16188
17857
|
}
|
|
16189
17858
|
|
|
16190
17859
|
// src/commands/images/upscale.ts
|
|
16191
|
-
import { defineCommand as
|
|
17860
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
16192
17861
|
registerSchema({
|
|
16193
17862
|
command: "images.upscale",
|
|
16194
17863
|
description: "Upscale a library image via the backend (Replicate, cost-tracked). Waits for completion by default. The image must be status 'ready' and raster (not SVG/AVIF).",
|
|
@@ -16203,7 +17872,7 @@ registerSchema({
|
|
|
16203
17872
|
}
|
|
16204
17873
|
});
|
|
16205
17874
|
var POLL_INTERVAL_MS3 = 1500;
|
|
16206
|
-
var upscaleCommand =
|
|
17875
|
+
var upscaleCommand = defineCommand120({
|
|
16207
17876
|
meta: {
|
|
16208
17877
|
name: "upscale",
|
|
16209
17878
|
description: "Upscale a library image via the Convex backend (Replicate, cost-tracked at $0.05/image). Waits for completion by default.\n\nExample: baker images upscale j571abc123def\nExample: baker images upscale j571abc123def --max-wait 0 # fire-and-forget"
|
|
@@ -16258,7 +17927,7 @@ var upscaleCommand = defineCommand118({
|
|
|
16258
17927
|
});
|
|
16259
17928
|
|
|
16260
17929
|
// src/commands/images/use.ts
|
|
16261
|
-
import { defineCommand as
|
|
17930
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
16262
17931
|
registerSchema({
|
|
16263
17932
|
command: "images.use",
|
|
16264
17933
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -16274,7 +17943,7 @@ registerSchema({
|
|
|
16274
17943
|
}
|
|
16275
17944
|
});
|
|
16276
17945
|
var POLL_INTERVAL_MS4 = 1500;
|
|
16277
|
-
var useCommand =
|
|
17946
|
+
var useCommand = defineCommand121({
|
|
16278
17947
|
meta: {
|
|
16279
17948
|
name: "use",
|
|
16280
17949
|
description: "Sugar over `ingest`: download \u2192 store \u2192 wait until describe + embed complete \u2192 return ready library record.\n\nExample: baker images use https://cdn.example.com/hero.png --source uploaded"
|
|
@@ -16320,7 +17989,7 @@ var useCommand = defineCommand119({
|
|
|
16320
17989
|
});
|
|
16321
17990
|
|
|
16322
17991
|
// src/commands/images/index.ts
|
|
16323
|
-
var imagesCommand =
|
|
17992
|
+
var imagesCommand = defineCommand122({
|
|
16324
17993
|
meta: {
|
|
16325
17994
|
name: "images",
|
|
16326
17995
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -16390,10 +18059,10 @@ Paid transforms (run on the Convex backend, cost-tracked):
|
|
|
16390
18059
|
});
|
|
16391
18060
|
|
|
16392
18061
|
// src/commands/research/index.ts
|
|
16393
|
-
import { defineCommand as
|
|
18062
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
16394
18063
|
|
|
16395
18064
|
// src/commands/research/advertisers.ts
|
|
16396
|
-
import { defineCommand as
|
|
18065
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
16397
18066
|
|
|
16398
18067
|
// src/commands/research/output.ts
|
|
16399
18068
|
var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
|
|
@@ -16506,7 +18175,7 @@ var FIELDS3 = {
|
|
|
16506
18175
|
etv: "Estimated traffic value (USD)",
|
|
16507
18176
|
visibility: "SERP visibility score (0-1)"
|
|
16508
18177
|
};
|
|
16509
|
-
var advertisersCommand =
|
|
18178
|
+
var advertisersCommand = defineCommand123({
|
|
16510
18179
|
meta: {
|
|
16511
18180
|
name: "advertisers",
|
|
16512
18181
|
description: `Find domains competing for a keyword in Google SERPs.
|
|
@@ -16553,7 +18222,7 @@ Examples:
|
|
|
16553
18222
|
});
|
|
16554
18223
|
|
|
16555
18224
|
// src/commands/research/autocomplete.ts
|
|
16556
|
-
import { defineCommand as
|
|
18225
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
16557
18226
|
registerSchema({
|
|
16558
18227
|
command: "research.autocomplete",
|
|
16559
18228
|
description: "Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
|
|
@@ -16576,7 +18245,7 @@ registerSchema({
|
|
|
16576
18245
|
var FIELDS4 = {
|
|
16577
18246
|
suggestion: "Autocomplete suggestion from Google"
|
|
16578
18247
|
};
|
|
16579
|
-
var autocompleteCommand =
|
|
18248
|
+
var autocompleteCommand = defineCommand124({
|
|
16580
18249
|
meta: {
|
|
16581
18250
|
name: "autocomplete",
|
|
16582
18251
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -16622,7 +18291,7 @@ Examples:
|
|
|
16622
18291
|
});
|
|
16623
18292
|
|
|
16624
18293
|
// src/commands/research/countries.ts
|
|
16625
|
-
import { defineCommand as
|
|
18294
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
16626
18295
|
registerSchema({
|
|
16627
18296
|
command: "research.countries",
|
|
16628
18297
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -16679,7 +18348,7 @@ var FIELDS5 = {
|
|
|
16679
18348
|
code: "Country code to pass as --location",
|
|
16680
18349
|
name: "Country name"
|
|
16681
18350
|
};
|
|
16682
|
-
var countriesCommand =
|
|
18351
|
+
var countriesCommand = defineCommand125({
|
|
16683
18352
|
meta: {
|
|
16684
18353
|
name: "countries",
|
|
16685
18354
|
description: "List all supported country codes for --location flag."
|
|
@@ -16690,7 +18359,7 @@ var countriesCommand = defineCommand123({
|
|
|
16690
18359
|
});
|
|
16691
18360
|
|
|
16692
18361
|
// src/commands/research/intent.ts
|
|
16693
|
-
import { defineCommand as
|
|
18362
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
16694
18363
|
registerSchema({
|
|
16695
18364
|
command: "research.intent",
|
|
16696
18365
|
description: "Classify Google Search intent for keywords. Determines if someone searching is looking to buy, research, or navigate. IMPORTANT: If --language is omitted, defaults to English (en). The response includes a query_context object showing which language was used.",
|
|
@@ -16713,7 +18382,7 @@ var FIELDS6 = {
|
|
|
16713
18382
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
16714
18383
|
probability: "Confidence score 0.0-1.0"
|
|
16715
18384
|
};
|
|
16716
|
-
var intentCommand =
|
|
18385
|
+
var intentCommand = defineCommand126({
|
|
16717
18386
|
meta: {
|
|
16718
18387
|
name: "intent",
|
|
16719
18388
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -16761,7 +18430,7 @@ Examples:
|
|
|
16761
18430
|
});
|
|
16762
18431
|
|
|
16763
18432
|
// src/commands/research/keyword-gap.ts
|
|
16764
|
-
import { defineCommand as
|
|
18433
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
16765
18434
|
registerSchema({
|
|
16766
18435
|
command: "research.keyword-gap",
|
|
16767
18436
|
description: "Find keywords a competitor ranks for (organic or paid) that you don't. Discovers expansion opportunities. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
|
|
@@ -16790,7 +18459,7 @@ var FIELDS7 = {
|
|
|
16790
18459
|
cpc: "Cost per click USD",
|
|
16791
18460
|
their_position: "Competitor's ranking position"
|
|
16792
18461
|
};
|
|
16793
|
-
var keywordGapCommand =
|
|
18462
|
+
var keywordGapCommand = defineCommand127({
|
|
16794
18463
|
meta: {
|
|
16795
18464
|
name: "keyword-gap",
|
|
16796
18465
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -16864,7 +18533,7 @@ Examples:
|
|
|
16864
18533
|
});
|
|
16865
18534
|
|
|
16866
18535
|
// src/commands/research/keywords-for-site.ts
|
|
16867
|
-
import { defineCommand as
|
|
18536
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
16868
18537
|
registerSchema({
|
|
16869
18538
|
command: "research.keywords-for-site",
|
|
16870
18539
|
description: "Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
|
|
@@ -16897,7 +18566,7 @@ var FIELDS8 = {
|
|
|
16897
18566
|
competition: "LOW, MEDIUM, or HIGH",
|
|
16898
18567
|
competition_index: "Competition score 0-100"
|
|
16899
18568
|
};
|
|
16900
|
-
var keywordsForSiteCommand =
|
|
18569
|
+
var keywordsForSiteCommand = defineCommand128({
|
|
16901
18570
|
meta: {
|
|
16902
18571
|
name: "keywords-for-site",
|
|
16903
18572
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -16950,7 +18619,7 @@ Examples:
|
|
|
16950
18619
|
});
|
|
16951
18620
|
|
|
16952
18621
|
// src/commands/research/languages.ts
|
|
16953
|
-
import { defineCommand as
|
|
18622
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
16954
18623
|
registerSchema({
|
|
16955
18624
|
command: "research.languages",
|
|
16956
18625
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -16980,7 +18649,7 @@ var FIELDS9 = {
|
|
|
16980
18649
|
code: "Language code to pass as --language",
|
|
16981
18650
|
name: "Language name (also accepted by --language)"
|
|
16982
18651
|
};
|
|
16983
|
-
var languagesCommand2 =
|
|
18652
|
+
var languagesCommand2 = defineCommand129({
|
|
16984
18653
|
meta: {
|
|
16985
18654
|
name: "languages",
|
|
16986
18655
|
description: "List all supported language codes for --language flag."
|
|
@@ -16991,7 +18660,7 @@ var languagesCommand2 = defineCommand127({
|
|
|
16991
18660
|
});
|
|
16992
18661
|
|
|
16993
18662
|
// src/commands/research/lighthouse.ts
|
|
16994
|
-
import { defineCommand as
|
|
18663
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
16995
18664
|
registerSchema({
|
|
16996
18665
|
command: "research.lighthouse",
|
|
16997
18666
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -17010,7 +18679,7 @@ var FIELDS10 = {
|
|
|
17010
18679
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
17011
18680
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
17012
18681
|
};
|
|
17013
|
-
var lighthouseCommand =
|
|
18682
|
+
var lighthouseCommand = defineCommand130({
|
|
17014
18683
|
meta: {
|
|
17015
18684
|
name: "lighthouse",
|
|
17016
18685
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -17048,7 +18717,7 @@ Examples:
|
|
|
17048
18717
|
});
|
|
17049
18718
|
|
|
17050
18719
|
// src/commands/research/relevant-pages.ts
|
|
17051
|
-
import { defineCommand as
|
|
18720
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
17052
18721
|
registerSchema({
|
|
17053
18722
|
command: "research.relevant-pages",
|
|
17054
18723
|
description: "Get the top pages of a competitor domain with organic traffic and ranking data. Shows which pages drive the most traffic. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
|
|
@@ -17074,7 +18743,7 @@ var FIELDS11 = {
|
|
|
17074
18743
|
keywords: "Total organic keywords the page ranks for",
|
|
17075
18744
|
top_10: "Keywords in positions 1-10"
|
|
17076
18745
|
};
|
|
17077
|
-
var relevantPagesCommand =
|
|
18746
|
+
var relevantPagesCommand = defineCommand131({
|
|
17078
18747
|
meta: {
|
|
17079
18748
|
name: "relevant-pages",
|
|
17080
18749
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -17120,7 +18789,7 @@ Examples:
|
|
|
17120
18789
|
});
|
|
17121
18790
|
|
|
17122
18791
|
// src/commands/research/web.ts
|
|
17123
|
-
import { defineCommand as
|
|
18792
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
17124
18793
|
registerSchema({
|
|
17125
18794
|
command: "research.web",
|
|
17126
18795
|
description: "Search the web with AI to answer marketing questions \u2014 competitors, ICP, pricing, pain points, market trends. Three depth levels: medium (quick, default), high (thorough), xhigh (exhaustive deep research).",
|
|
@@ -17171,7 +18840,7 @@ async function runDeepResearch(question) {
|
|
|
17171
18840
|
}
|
|
17172
18841
|
throw new Error("Deep research timed out");
|
|
17173
18842
|
}
|
|
17174
|
-
var webCommand =
|
|
18843
|
+
var webCommand = defineCommand132({
|
|
17175
18844
|
meta: {
|
|
17176
18845
|
name: "web",
|
|
17177
18846
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -17231,7 +18900,7 @@ Examples:
|
|
|
17231
18900
|
});
|
|
17232
18901
|
|
|
17233
18902
|
// src/commands/research/index.ts
|
|
17234
|
-
var researchCommand =
|
|
18903
|
+
var researchCommand = defineCommand133({
|
|
17235
18904
|
meta: {
|
|
17236
18905
|
name: "research",
|
|
17237
18906
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -17271,10 +18940,10 @@ Examples:
|
|
|
17271
18940
|
});
|
|
17272
18941
|
|
|
17273
18942
|
// src/commands/scheduled-actions/index.ts
|
|
17274
|
-
import { defineCommand as
|
|
18943
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
17275
18944
|
|
|
17276
18945
|
// src/commands/scheduled-actions/create.ts
|
|
17277
|
-
import { defineCommand as
|
|
18946
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
17278
18947
|
|
|
17279
18948
|
// src/commands/scheduled-actions/shared.ts
|
|
17280
18949
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -17389,7 +19058,7 @@ registerSchema({
|
|
|
17389
19058
|
prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
|
|
17390
19059
|
}
|
|
17391
19060
|
});
|
|
17392
|
-
var createCommand2 =
|
|
19061
|
+
var createCommand2 = defineCommand134({
|
|
17393
19062
|
meta: {
|
|
17394
19063
|
name: "create",
|
|
17395
19064
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -17438,7 +19107,7 @@ var createCommand2 = defineCommand132({
|
|
|
17438
19107
|
});
|
|
17439
19108
|
|
|
17440
19109
|
// src/commands/scheduled-actions/delete.ts
|
|
17441
|
-
import { defineCommand as
|
|
19110
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
17442
19111
|
registerSchema({
|
|
17443
19112
|
command: "scheduled-actions.delete",
|
|
17444
19113
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -17446,7 +19115,7 @@ registerSchema({
|
|
|
17446
19115
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
17447
19116
|
}
|
|
17448
19117
|
});
|
|
17449
|
-
var deleteCommand2 =
|
|
19118
|
+
var deleteCommand2 = defineCommand135({
|
|
17450
19119
|
meta: {
|
|
17451
19120
|
name: "delete",
|
|
17452
19121
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -17475,7 +19144,7 @@ var deleteCommand2 = defineCommand133({
|
|
|
17475
19144
|
});
|
|
17476
19145
|
|
|
17477
19146
|
// src/commands/scheduled-actions/get.ts
|
|
17478
|
-
import { defineCommand as
|
|
19147
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
17479
19148
|
registerSchema({
|
|
17480
19149
|
command: "scheduled-actions.get",
|
|
17481
19150
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -17483,7 +19152,7 @@ registerSchema({
|
|
|
17483
19152
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
17484
19153
|
}
|
|
17485
19154
|
});
|
|
17486
|
-
var getCommand3 =
|
|
19155
|
+
var getCommand3 = defineCommand136({
|
|
17487
19156
|
meta: {
|
|
17488
19157
|
name: "get",
|
|
17489
19158
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -17520,13 +19189,13 @@ var getCommand3 = defineCommand134({
|
|
|
17520
19189
|
});
|
|
17521
19190
|
|
|
17522
19191
|
// src/commands/scheduled-actions/list.ts
|
|
17523
|
-
import { defineCommand as
|
|
19192
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
17524
19193
|
registerSchema({
|
|
17525
19194
|
command: "scheduled-actions.list",
|
|
17526
19195
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
|
|
17527
19196
|
args: {}
|
|
17528
19197
|
});
|
|
17529
|
-
var
|
|
19198
|
+
var listCommand4 = defineCommand137({
|
|
17530
19199
|
meta: {
|
|
17531
19200
|
name: "list",
|
|
17532
19201
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
|
|
@@ -17547,7 +19216,7 @@ var listCommand3 = defineCommand135({
|
|
|
17547
19216
|
});
|
|
17548
19217
|
|
|
17549
19218
|
// src/commands/scheduled-actions/trigger.ts
|
|
17550
|
-
import { defineCommand as
|
|
19219
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
17551
19220
|
registerSchema({
|
|
17552
19221
|
command: "scheduled-actions.trigger",
|
|
17553
19222
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -17555,7 +19224,7 @@ registerSchema({
|
|
|
17555
19224
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
17556
19225
|
}
|
|
17557
19226
|
});
|
|
17558
|
-
var triggerCommand =
|
|
19227
|
+
var triggerCommand = defineCommand138({
|
|
17559
19228
|
meta: {
|
|
17560
19229
|
name: "trigger",
|
|
17561
19230
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -17592,7 +19261,7 @@ var triggerCommand = defineCommand136({
|
|
|
17592
19261
|
});
|
|
17593
19262
|
|
|
17594
19263
|
// src/commands/scheduled-actions/update.ts
|
|
17595
|
-
import { defineCommand as
|
|
19264
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
17596
19265
|
registerSchema({
|
|
17597
19266
|
command: "scheduled-actions.update",
|
|
17598
19267
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -17617,7 +19286,7 @@ registerSchema({
|
|
|
17617
19286
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
17618
19287
|
}
|
|
17619
19288
|
});
|
|
17620
|
-
var updateCommand2 =
|
|
19289
|
+
var updateCommand2 = defineCommand139({
|
|
17621
19290
|
meta: {
|
|
17622
19291
|
name: "update",
|
|
17623
19292
|
description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
|
|
@@ -17688,7 +19357,7 @@ var updateCommand2 = defineCommand137({
|
|
|
17688
19357
|
});
|
|
17689
19358
|
|
|
17690
19359
|
// src/commands/scheduled-actions/index.ts
|
|
17691
|
-
var scheduledActionsCommand =
|
|
19360
|
+
var scheduledActionsCommand = defineCommand140({
|
|
17692
19361
|
meta: {
|
|
17693
19362
|
name: "scheduled-actions",
|
|
17694
19363
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
|
|
@@ -17704,7 +19373,7 @@ Examples:
|
|
|
17704
19373
|
baker scheduled-actions trigger <id>`
|
|
17705
19374
|
},
|
|
17706
19375
|
subCommands: {
|
|
17707
|
-
list:
|
|
19376
|
+
list: listCommand4,
|
|
17708
19377
|
get: getCommand3,
|
|
17709
19378
|
create: createCommand2,
|
|
17710
19379
|
update: updateCommand2,
|
|
@@ -17714,8 +19383,8 @@ Examples:
|
|
|
17714
19383
|
});
|
|
17715
19384
|
|
|
17716
19385
|
// src/commands/schema.ts
|
|
17717
|
-
import { defineCommand as
|
|
17718
|
-
var schemaCommand =
|
|
19386
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
19387
|
+
var schemaCommand = defineCommand141({
|
|
17719
19388
|
meta: {
|
|
17720
19389
|
name: "schema",
|
|
17721
19390
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -17751,10 +19420,10 @@ var schemaCommand = defineCommand139({
|
|
|
17751
19420
|
});
|
|
17752
19421
|
|
|
17753
19422
|
// src/commands/testimonials/index.ts
|
|
17754
|
-
import { defineCommand as
|
|
19423
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
17755
19424
|
|
|
17756
19425
|
// src/commands/testimonials/get.ts
|
|
17757
|
-
import { defineCommand as
|
|
19426
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
17758
19427
|
registerSchema({
|
|
17759
19428
|
command: "testimonials.get",
|
|
17760
19429
|
description: "Get a single testimonial by ID",
|
|
@@ -17762,7 +19431,7 @@ registerSchema({
|
|
|
17762
19431
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
17763
19432
|
}
|
|
17764
19433
|
});
|
|
17765
|
-
var getCommand4 =
|
|
19434
|
+
var getCommand4 = defineCommand142({
|
|
17766
19435
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
17767
19436
|
args: {
|
|
17768
19437
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -17799,7 +19468,7 @@ var getCommand4 = defineCommand140({
|
|
|
17799
19468
|
});
|
|
17800
19469
|
|
|
17801
19470
|
// src/commands/testimonials/list.ts
|
|
17802
|
-
import { defineCommand as
|
|
19471
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
17803
19472
|
registerSchema({
|
|
17804
19473
|
command: "testimonials.list",
|
|
17805
19474
|
description: "List testimonials with optional filters.",
|
|
@@ -17829,7 +19498,7 @@ registerSchema({
|
|
|
17829
19498
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
17830
19499
|
}
|
|
17831
19500
|
});
|
|
17832
|
-
var
|
|
19501
|
+
var listCommand5 = defineCommand143({
|
|
17833
19502
|
meta: {
|
|
17834
19503
|
name: "list",
|
|
17835
19504
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -17878,7 +19547,7 @@ var listCommand4 = defineCommand141({
|
|
|
17878
19547
|
});
|
|
17879
19548
|
|
|
17880
19549
|
// src/commands/testimonials/search.ts
|
|
17881
|
-
import { defineCommand as
|
|
19550
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
17882
19551
|
registerSchema({
|
|
17883
19552
|
command: "testimonials.search",
|
|
17884
19553
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -17909,7 +19578,7 @@ registerSchema({
|
|
|
17909
19578
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
17910
19579
|
}
|
|
17911
19580
|
});
|
|
17912
|
-
var searchCommand2 =
|
|
19581
|
+
var searchCommand2 = defineCommand144({
|
|
17913
19582
|
meta: {
|
|
17914
19583
|
name: "search",
|
|
17915
19584
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -17983,7 +19652,7 @@ var searchCommand2 = defineCommand142({
|
|
|
17983
19652
|
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
17984
19653
|
|
|
17985
19654
|
// src/commands/testimonials/index.ts
|
|
17986
|
-
var testimonialsCommand =
|
|
19655
|
+
var testimonialsCommand = defineCommand145({
|
|
17987
19656
|
meta: {
|
|
17988
19657
|
name: "testimonials",
|
|
17989
19658
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -17998,16 +19667,16 @@ Examples:
|
|
|
17998
19667
|
subCommands: {
|
|
17999
19668
|
get: getCommand4,
|
|
18000
19669
|
search: searchCommand2,
|
|
18001
|
-
list:
|
|
19670
|
+
list: listCommand5,
|
|
18002
19671
|
tags: tagsCommand3
|
|
18003
19672
|
}
|
|
18004
19673
|
});
|
|
18005
19674
|
|
|
18006
19675
|
// src/commands/videos/index.ts
|
|
18007
|
-
import { defineCommand as
|
|
19676
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
18008
19677
|
|
|
18009
19678
|
// src/commands/videos/delete.ts
|
|
18010
|
-
import { defineCommand as
|
|
19679
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
18011
19680
|
registerSchema({
|
|
18012
19681
|
command: "videos.delete",
|
|
18013
19682
|
description: "Delete a video by ID",
|
|
@@ -18021,7 +19690,7 @@ registerSchema({
|
|
|
18021
19690
|
}
|
|
18022
19691
|
}
|
|
18023
19692
|
});
|
|
18024
|
-
var deleteCommand3 =
|
|
19693
|
+
var deleteCommand3 = defineCommand146({
|
|
18025
19694
|
meta: {
|
|
18026
19695
|
name: "delete",
|
|
18027
19696
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -18062,7 +19731,7 @@ var deleteCommand3 = defineCommand144({
|
|
|
18062
19731
|
});
|
|
18063
19732
|
|
|
18064
19733
|
// src/commands/videos/get.ts
|
|
18065
|
-
import { defineCommand as
|
|
19734
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
18066
19735
|
registerSchema({
|
|
18067
19736
|
command: "videos.get",
|
|
18068
19737
|
description: "Get a single video by ID",
|
|
@@ -18070,7 +19739,7 @@ registerSchema({
|
|
|
18070
19739
|
id: { type: "string", description: "Video ID", required: true }
|
|
18071
19740
|
}
|
|
18072
19741
|
});
|
|
18073
|
-
var getCommand5 =
|
|
19742
|
+
var getCommand5 = defineCommand147({
|
|
18074
19743
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
18075
19744
|
args: {
|
|
18076
19745
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -18107,7 +19776,7 @@ var getCommand5 = defineCommand145({
|
|
|
18107
19776
|
});
|
|
18108
19777
|
|
|
18109
19778
|
// src/commands/videos/search.ts
|
|
18110
|
-
import { defineCommand as
|
|
19779
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
18111
19780
|
registerSchema({
|
|
18112
19781
|
command: "videos.search",
|
|
18113
19782
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -18117,7 +19786,7 @@ registerSchema({
|
|
|
18117
19786
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
18118
19787
|
}
|
|
18119
19788
|
});
|
|
18120
|
-
var searchCommand3 =
|
|
19789
|
+
var searchCommand3 = defineCommand148({
|
|
18121
19790
|
meta: {
|
|
18122
19791
|
name: "search",
|
|
18123
19792
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -18169,7 +19838,7 @@ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
18169
19838
|
// src/commands/videos/upload.ts
|
|
18170
19839
|
import { readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
18171
19840
|
import { extname as extname3 } from "path";
|
|
18172
|
-
import { defineCommand as
|
|
19841
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
18173
19842
|
var MIME_MAP = {
|
|
18174
19843
|
".mp4": "video/mp4",
|
|
18175
19844
|
".mov": "video/quicktime",
|
|
@@ -18203,7 +19872,7 @@ function detectContentType(filePath) {
|
|
|
18203
19872
|
}
|
|
18204
19873
|
return mime;
|
|
18205
19874
|
}
|
|
18206
|
-
var uploadCommand2 =
|
|
19875
|
+
var uploadCommand2 = defineCommand149({
|
|
18207
19876
|
meta: {
|
|
18208
19877
|
name: "upload",
|
|
18209
19878
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -18257,7 +19926,7 @@ var uploadCommand2 = defineCommand147({
|
|
|
18257
19926
|
});
|
|
18258
19927
|
|
|
18259
19928
|
// src/commands/videos/index.ts
|
|
18260
|
-
var videosCommand =
|
|
19929
|
+
var videosCommand = defineCommand150({
|
|
18261
19930
|
meta: {
|
|
18262
19931
|
name: "videos",
|
|
18263
19932
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -18280,10 +19949,10 @@ Examples:
|
|
|
18280
19949
|
});
|
|
18281
19950
|
|
|
18282
19951
|
// src/commands/winning-ads/index.ts
|
|
18283
|
-
import { defineCommand as
|
|
19952
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
18284
19953
|
|
|
18285
19954
|
// src/commands/winning-ads/advertisers.ts
|
|
18286
|
-
import { defineCommand as
|
|
19955
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
18287
19956
|
registerSchema({
|
|
18288
19957
|
command: "winning-ads.advertisers",
|
|
18289
19958
|
description: "Resolve a brand name to advertiser_id(s) in the ad-dna corpus \u2014 to find your OWN advertiser (to --exclude-advertiser) or a competitor (to --advertiser-id).",
|
|
@@ -18296,7 +19965,7 @@ registerSchema({
|
|
|
18296
19965
|
function identity(record) {
|
|
18297
19966
|
return record;
|
|
18298
19967
|
}
|
|
18299
|
-
var advertisersCommand2 =
|
|
19968
|
+
var advertisersCommand2 = defineCommand151({
|
|
18300
19969
|
meta: {
|
|
18301
19970
|
name: "advertisers",
|
|
18302
19971
|
description: 'Resolve a brand name to advertiser_id(s). Use it to find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id. Example: baker winning-ads advertisers "Deel" --output md'
|
|
@@ -18347,7 +20016,7 @@ var advertisersCommand2 = defineCommand149({
|
|
|
18347
20016
|
});
|
|
18348
20017
|
|
|
18349
20018
|
// src/commands/winning-ads/search.ts
|
|
18350
|
-
import { defineCommand as
|
|
20019
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
18351
20020
|
registerSchema({
|
|
18352
20021
|
command: "winning-ads.search",
|
|
18353
20022
|
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.",
|
|
@@ -18455,7 +20124,7 @@ function buildSearchBody(args) {
|
|
|
18455
20124
|
}
|
|
18456
20125
|
return body;
|
|
18457
20126
|
}
|
|
18458
|
-
var searchCommand4 =
|
|
20127
|
+
var searchCommand4 = defineCommand152({
|
|
18459
20128
|
meta: {
|
|
18460
20129
|
name: "search",
|
|
18461
20130
|
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"
|
|
@@ -18567,7 +20236,7 @@ var searchCommand4 = defineCommand150({
|
|
|
18567
20236
|
});
|
|
18568
20237
|
|
|
18569
20238
|
// src/commands/winning-ads/index.ts
|
|
18570
|
-
var winningAdsCommand =
|
|
20239
|
+
var winningAdsCommand = defineCommand153({
|
|
18571
20240
|
meta: {
|
|
18572
20241
|
name: "winning-ads",
|
|
18573
20242
|
description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
|
|
@@ -18591,7 +20260,7 @@ Examples:
|
|
|
18591
20260
|
});
|
|
18592
20261
|
|
|
18593
20262
|
// src/version.ts
|
|
18594
|
-
import { readFileSync as
|
|
20263
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
18595
20264
|
function packageJsonUrl() {
|
|
18596
20265
|
return new URL("../package.json", import.meta.url);
|
|
18597
20266
|
}
|
|
@@ -18603,11 +20272,11 @@ function parsePackageVersion(raw) {
|
|
|
18603
20272
|
throw new Error("Invalid CLI package.json: missing version");
|
|
18604
20273
|
}
|
|
18605
20274
|
function getCliVersion() {
|
|
18606
|
-
return parsePackageVersion(
|
|
20275
|
+
return parsePackageVersion(readFileSync10(packageJsonUrl(), "utf8"));
|
|
18607
20276
|
}
|
|
18608
20277
|
|
|
18609
20278
|
// src/cli.ts
|
|
18610
|
-
var main =
|
|
20279
|
+
var main = defineCommand154({
|
|
18611
20280
|
meta: {
|
|
18612
20281
|
name: "baker",
|
|
18613
20282
|
version: getCliVersion(),
|