@koda-sl/baker-cli 0.104.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 +53 -1
- package/dist/{chunk-3JVYU72O.js → chunk-26K7V346.js} +4 -4
- package/dist/chunk-26K7V346.js.map +1 -0
- package/dist/cli.js +2510 -392
- 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,6 +935,990 @@ 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/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
|
|
1049
|
+
import { z as z3 } from "zod";
|
|
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([
|
|
1485
|
+
"uploaded",
|
|
1486
|
+
"website",
|
|
1487
|
+
"google_testimonial",
|
|
1488
|
+
"trustpilot_testimonial",
|
|
1489
|
+
"instagram",
|
|
1490
|
+
"magnific",
|
|
1491
|
+
"brandfetch",
|
|
1492
|
+
"google_images",
|
|
1493
|
+
"firecrawl",
|
|
1494
|
+
"screenshotone",
|
|
1495
|
+
"iconify",
|
|
1496
|
+
"giphy",
|
|
1497
|
+
"pinterest",
|
|
1498
|
+
"ai_generated"
|
|
1499
|
+
]);
|
|
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()
|
|
1507
|
+
}),
|
|
1508
|
+
status: z5.enum(["pending", "completed"])
|
|
1509
|
+
});
|
|
1510
|
+
var imageDocSchema = z5.object({
|
|
1511
|
+
_id: z5.string(),
|
|
1512
|
+
_creationTime: z5.number(),
|
|
1513
|
+
companyId: z5.string(),
|
|
1514
|
+
storageKey: z5.string(),
|
|
1515
|
+
upscaleConfig: upscaleConfigSchema.optional(),
|
|
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(),
|
|
1536
|
+
status: imageStatusSchema,
|
|
1537
|
+
errorMessage: z5.string().optional(),
|
|
1538
|
+
createdAt: z5.number(),
|
|
1539
|
+
updatedAt: z5.number(),
|
|
1540
|
+
imageUrl: z5.string()
|
|
1541
|
+
});
|
|
1542
|
+
var imageHitSourceSchema = z5.enum([
|
|
1543
|
+
"library",
|
|
1544
|
+
"magnific",
|
|
1545
|
+
"google_images",
|
|
1546
|
+
"brandfetch",
|
|
1547
|
+
"firecrawl",
|
|
1548
|
+
"screenshotone",
|
|
1549
|
+
"iconify",
|
|
1550
|
+
"giphy",
|
|
1551
|
+
"pinterest"
|
|
1552
|
+
]);
|
|
1553
|
+
var imageHitSchema = z5.object({
|
|
1554
|
+
source: imageHitSourceSchema,
|
|
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()
|
|
1573
|
+
});
|
|
1574
|
+
var ingestedImageHitSchema = imageHitSchema.extend({
|
|
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()
|
|
1586
|
+
});
|
|
1587
|
+
function providerHitsResponseSchema() {
|
|
1588
|
+
return z5.object({
|
|
1589
|
+
hits: z5.array(ingestedImageHitSchema),
|
|
1590
|
+
ingested: z5.array(autoIngestItemSchema)
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
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")
|
|
1631
|
+
});
|
|
1632
|
+
var IMAGES_FIND_SOURCES = ["library", "magnific", "google", "iconify", "giphy", "pinterest"];
|
|
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)
|
|
1646
|
+
}),
|
|
1647
|
+
meta: z5.object({
|
|
1648
|
+
counts: z5.record(z5.string(), z5.number()),
|
|
1649
|
+
errors: z5.array(z5.object({ source: imageHitSourceSchema, message: z5.string() }))
|
|
1650
|
+
}),
|
|
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()
|
|
1666
|
+
});
|
|
1667
|
+
var imagesStockResponseSchema = providerHitsResponseSchema();
|
|
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()
|
|
1677
|
+
});
|
|
1678
|
+
var imagesGoogleResponseSchema = providerHitsResponseSchema();
|
|
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()
|
|
1684
|
+
});
|
|
1685
|
+
var imagesPinterestResponseSchema = providerHitsResponseSchema();
|
|
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)
|
|
1690
|
+
]);
|
|
1691
|
+
var imageGenerateModelSchema = z5.enum([
|
|
1692
|
+
"openai/gpt-5.4-image-2",
|
|
1693
|
+
"google/gemini-3.5-flash",
|
|
1694
|
+
"google/gemini-3.1-flash-image-preview",
|
|
1695
|
+
"google/gemini-3-pro-image-preview",
|
|
1696
|
+
"recraft/recraft-v4.1-pro-vector"
|
|
1697
|
+
]);
|
|
1698
|
+
var imagesGenerateRequestSchema = z5.object({
|
|
1699
|
+
prompt: z5.string().min(1),
|
|
1700
|
+
model: imageGenerateModelSchema.optional(),
|
|
1701
|
+
// Aspect ratio + size are validated loosely as strings; the per-model enum
|
|
1702
|
+
// lives in canvas-contract and OpenRouter rejects unsupported combinations.
|
|
1703
|
+
aspectRatio: z5.string().optional(),
|
|
1704
|
+
imageSize: z5.string().optional(),
|
|
1705
|
+
// Recraft v4.1 Pro Vector levers (ignored by other models).
|
|
1706
|
+
strength: z5.coerce.number().min(0).max(1).optional(),
|
|
1707
|
+
rgbColors: z5.array(rgbTriple).optional(),
|
|
1708
|
+
backgroundRgbColor: rgbTriple.optional(),
|
|
1709
|
+
// Public image URLs used as visual references (multi-reference, in order).
|
|
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()
|
|
1730
|
+
});
|
|
1731
|
+
var imagesLogoResponseSchema = providerHitsResponseSchema();
|
|
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()
|
|
1739
|
+
});
|
|
1740
|
+
var imagesIconResponseSchema = providerHitsResponseSchema();
|
|
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()
|
|
1747
|
+
});
|
|
1748
|
+
var imagesExtractResponseSchema = providerHitsResponseSchema();
|
|
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()
|
|
1756
|
+
});
|
|
1757
|
+
var imagesScreenshotResponseSchema = providerHitsResponseSchema();
|
|
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()
|
|
1766
|
+
});
|
|
1767
|
+
var imagesGifResponseSchema = providerHitsResponseSchema();
|
|
1768
|
+
var imagesStickerResponseSchema = providerHitsResponseSchema();
|
|
1769
|
+
var imagesIngestRequestSchema = z5.object({
|
|
1770
|
+
url: z5.string().url(),
|
|
1771
|
+
// Validate source at the HTTP boundary so unknown values produce the standard
|
|
1772
|
+
// `{ code: "BAD_REQUEST", message }` shape instead of a plain Error from
|
|
1773
|
+
// `assertImageSource` inside the action.
|
|
1774
|
+
source: imageSourceSchema,
|
|
1775
|
+
externalId: z5.string().optional(),
|
|
1776
|
+
externalUrl: z5.string().optional(),
|
|
1777
|
+
descriptionContext: z5.string().optional()
|
|
1778
|
+
});
|
|
1779
|
+
var imagesIngestResponseSchema = z5.object({
|
|
1780
|
+
imageId: z5.string(),
|
|
1781
|
+
deduped: z5.boolean(),
|
|
1782
|
+
contentHash: z5.string()
|
|
1783
|
+
});
|
|
1784
|
+
|
|
1785
|
+
// ../api/src/testimonials.ts
|
|
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(),
|
|
1795
|
+
sourceType: testimonialSourceTypeSchema,
|
|
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(),
|
|
1815
|
+
sentiment: testimonialSentimentSchema.optional(),
|
|
1816
|
+
textEmbedding: z6.array(z6.number()).optional(),
|
|
1817
|
+
externalId: z6.string().optional(),
|
|
1818
|
+
contentHash: z6.string().optional(),
|
|
1819
|
+
status: testimonialStatusSchema,
|
|
1820
|
+
errorMessage: z6.string().optional(),
|
|
1821
|
+
createdAt: z6.number(),
|
|
1822
|
+
updatedAt: z6.number()
|
|
1823
|
+
});
|
|
1824
|
+
var testimonialsListRequestSchema = z6.object({
|
|
1825
|
+
source: testimonialSourceTypeSchema.optional(),
|
|
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(),
|
|
1829
|
+
status: testimonialStatusSchema.optional(),
|
|
1830
|
+
sentiment: testimonialSentimentSchema.optional(),
|
|
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(),
|
|
1839
|
+
source: testimonialSourceTypeSchema.optional(),
|
|
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(),
|
|
1843
|
+
status: testimonialStatusSchema.optional(),
|
|
1844
|
+
sentiment: testimonialSentimentSchema.optional(),
|
|
1845
|
+
language: z6.string().min(2).max(5).optional()
|
|
1846
|
+
}).refine(
|
|
1847
|
+
(data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
|
|
1848
|
+
{ message: "rating_min must be less than or equal to rating_max" }
|
|
1849
|
+
);
|
|
1850
|
+
var testimonialsSearchResponseSchema = z6.array(testimonialDocSchema);
|
|
1851
|
+
var testimonialsOutscraperWebhookResponseSchema = z6.object({
|
|
1852
|
+
ok: z6.literal(true),
|
|
1853
|
+
note: z6.string().optional()
|
|
1854
|
+
});
|
|
1855
|
+
|
|
1856
|
+
// ../api/src/videos.ts
|
|
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(),
|
|
1893
|
+
status: videoStatusSchema,
|
|
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) });
|
|
1921
|
+
|
|
938
1922
|
// src/commands/actions/complete.ts
|
|
939
1923
|
import { defineCommand as defineCommand2 } from "citty";
|
|
940
1924
|
registerSchema({
|
|
@@ -1762,7 +2746,7 @@ Examples:
|
|
|
1762
2746
|
});
|
|
1763
2747
|
|
|
1764
2748
|
// src/commands/ads/index.ts
|
|
1765
|
-
import { defineCommand as
|
|
2749
|
+
import { defineCommand as defineCommand80 } from "citty";
|
|
1766
2750
|
|
|
1767
2751
|
// src/commands/ads/google/index.ts
|
|
1768
2752
|
import { defineCommand as defineCommand29 } from "citty";
|
|
@@ -4086,7 +5070,7 @@ Examples:
|
|
|
4086
5070
|
});
|
|
4087
5071
|
|
|
4088
5072
|
// src/commands/ads/linkedin/index.ts
|
|
4089
|
-
import { defineCommand as
|
|
5073
|
+
import { defineCommand as defineCommand49 } from "citty";
|
|
4090
5074
|
|
|
4091
5075
|
// src/commands/ads/linkedin/schemas.ts
|
|
4092
5076
|
registerSchema({
|
|
@@ -4384,6 +5368,293 @@ registerSchema({
|
|
|
4384
5368
|
"skip-cache": { type: "boolean", description: "Bypass cache", required: false }
|
|
4385
5369
|
}
|
|
4386
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
|
+
});
|
|
4387
5658
|
|
|
4388
5659
|
// src/commands/ads/linkedin/account.ts
|
|
4389
5660
|
import { defineCommand as defineCommand30 } from "citty";
|
|
@@ -5238,18 +6509,742 @@ Examples:
|
|
|
5238
6509
|
});
|
|
5239
6510
|
|
|
5240
6511
|
// src/commands/ads/linkedin/campaign-groups.ts
|
|
6512
|
+
import { defineCommand as defineCommand37 } from "citty";
|
|
6513
|
+
|
|
6514
|
+
// src/commands/ads/linkedin/write-commands.ts
|
|
5241
6515
|
import { defineCommand as defineCommand36 } from "citty";
|
|
5242
|
-
|
|
6516
|
+
|
|
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({
|
|
5243
7230
|
meta: {
|
|
5244
7231
|
name: "campaign-groups",
|
|
5245
|
-
description: `List LinkedIn campaign groups.
|
|
7232
|
+
description: `List LinkedIn campaign groups, or stage writes (create/update/pause/resume/duplicate).
|
|
5246
7233
|
|
|
5247
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.
|
|
5248
7236
|
|
|
5249
7237
|
Examples:
|
|
5250
7238
|
baker ads linkedin campaign-groups --account-id 503001492
|
|
5251
7239
|
baker ads linkedin campaign-groups --account-id 503001492 --all-statuses
|
|
5252
|
-
baker ads linkedin campaign-groups --
|
|
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
|
|
5253
7248
|
},
|
|
5254
7249
|
args: {
|
|
5255
7250
|
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
@@ -5282,11 +7277,11 @@ Examples:
|
|
|
5282
7277
|
});
|
|
5283
7278
|
|
|
5284
7279
|
// src/commands/ads/linkedin/campaigns.ts
|
|
5285
|
-
import { defineCommand as
|
|
5286
|
-
var campaignsCommand =
|
|
7280
|
+
import { defineCommand as defineCommand38 } from "citty";
|
|
7281
|
+
var campaignsCommand = defineCommand38({
|
|
5287
7282
|
meta: {
|
|
5288
7283
|
name: "campaigns",
|
|
5289
|
-
description: `List LinkedIn campaigns.
|
|
7284
|
+
description: `List LinkedIn campaigns, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
5290
7285
|
|
|
5291
7286
|
Default: ACTIVE only. The schema includes the audit-relevant settings:
|
|
5292
7287
|
audienceExpansionEnabled \u2014 playbook \xA702 silent budget drain (should be false)
|
|
@@ -5294,10 +7289,22 @@ Default: ACTIVE only. The schema includes the audit-relevant settings:
|
|
|
5294
7289
|
optimizationTargetType \u2014 driver of the bidding strategy
|
|
5295
7290
|
costType \u2014 CPC | CPM | CPV | CPS
|
|
5296
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
|
+
|
|
5297
7295
|
Examples:
|
|
5298
7296
|
baker ads linkedin campaigns --account-id 503001492
|
|
5299
|
-
baker ads linkedin campaigns --account-id 503001492 --
|
|
5300
|
-
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
|
|
5301
7308
|
},
|
|
5302
7309
|
args: {
|
|
5303
7310
|
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
@@ -5332,8 +7339,8 @@ Examples:
|
|
|
5332
7339
|
});
|
|
5333
7340
|
|
|
5334
7341
|
// src/commands/ads/linkedin/conversation.ts
|
|
5335
|
-
import { defineCommand as
|
|
5336
|
-
var conversationCommand =
|
|
7342
|
+
import { defineCommand as defineCommand39 } from "citty";
|
|
7343
|
+
var conversationCommand = defineCommand39({
|
|
5337
7344
|
meta: {
|
|
5338
7345
|
name: "conversation",
|
|
5339
7346
|
description: `Per-button click rates inside Sponsored Messaging / Conversation Ads.
|
|
@@ -5396,7 +7403,7 @@ Examples:
|
|
|
5396
7403
|
});
|
|
5397
7404
|
|
|
5398
7405
|
// src/commands/ads/linkedin/conversions.ts
|
|
5399
|
-
import { defineCommand as
|
|
7406
|
+
import { defineCommand as defineCommand40 } from "citty";
|
|
5400
7407
|
var DAY_MS3 = 864e5;
|
|
5401
7408
|
function healthOf(rules) {
|
|
5402
7409
|
const enabled = rules.filter((r) => r.enabled !== false);
|
|
@@ -5422,7 +7429,7 @@ function healthOf(rules) {
|
|
|
5422
7429
|
wrongLeadDedup: wrongDedup
|
|
5423
7430
|
};
|
|
5424
7431
|
}
|
|
5425
|
-
var listCmd =
|
|
7432
|
+
var listCmd = defineCommand40({
|
|
5426
7433
|
meta: {
|
|
5427
7434
|
name: "list",
|
|
5428
7435
|
description: `List conversion rules on the account.`
|
|
@@ -5450,7 +7457,7 @@ var listCmd = defineCommand39({
|
|
|
5450
7457
|
}
|
|
5451
7458
|
}
|
|
5452
7459
|
});
|
|
5453
|
-
var healthCmd =
|
|
7460
|
+
var healthCmd = defineCommand40({
|
|
5454
7461
|
meta: {
|
|
5455
7462
|
name: "health",
|
|
5456
7463
|
description: `5-point Insight Tag / CAPI health check (playbook \xA707).
|
|
@@ -5480,27 +7487,30 @@ Surfaces:
|
|
|
5480
7487
|
}
|
|
5481
7488
|
}
|
|
5482
7489
|
});
|
|
5483
|
-
var conversionsCommand =
|
|
7490
|
+
var conversionsCommand = defineCommand40({
|
|
5484
7491
|
meta: {
|
|
5485
7492
|
name: "conversions",
|
|
5486
7493
|
description: `Conversion rules \u2014 Insight Tag and Conversions API.
|
|
5487
7494
|
|
|
5488
7495
|
Subcommands:
|
|
5489
7496
|
list \u2014 every rule on the account
|
|
5490
|
-
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)`
|
|
5491
7499
|
},
|
|
5492
7500
|
subCommands: {
|
|
5493
7501
|
list: listCmd,
|
|
5494
|
-
health: healthCmd
|
|
7502
|
+
health: healthCmd,
|
|
7503
|
+
create: conversionsCreateCommand,
|
|
7504
|
+
update: conversionsUpdateCommand
|
|
5495
7505
|
}
|
|
5496
7506
|
});
|
|
5497
7507
|
|
|
5498
7508
|
// src/commands/ads/linkedin/creatives.ts
|
|
5499
|
-
import { defineCommand as
|
|
5500
|
-
var creativesCommand =
|
|
7509
|
+
import { defineCommand as defineCommand41 } from "citty";
|
|
7510
|
+
var creativesCommand = defineCommand41({
|
|
5501
7511
|
meta: {
|
|
5502
7512
|
name: "creatives",
|
|
5503
|
-
description: `List LinkedIn creatives (ads).
|
|
7513
|
+
description: `List LinkedIn creatives (ads), or stage writes (create/update/pause/resume/duplicate).
|
|
5504
7514
|
|
|
5505
7515
|
Defaults to ACTIVE intended-status. Pass --all-statuses or --statuses ACTIVE,PAUSED to widen.
|
|
5506
7516
|
|
|
@@ -5508,10 +7518,20 @@ The 'content' block is opaque (varies by creative type \u2014 image, video, docu
|
|
|
5508
7518
|
spotlight, conversation, dynamic). Use 'reviewStatus' to spot rejected/pending
|
|
5509
7519
|
creatives during an audit.
|
|
5510
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
|
+
|
|
5511
7524
|
Examples:
|
|
5512
7525
|
baker ads linkedin creatives --account-id 503001492
|
|
5513
|
-
baker ads linkedin creatives --
|
|
5514
|
-
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
|
|
5515
7535
|
},
|
|
5516
7536
|
args: {
|
|
5517
7537
|
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
@@ -5546,7 +7566,7 @@ Examples:
|
|
|
5546
7566
|
});
|
|
5547
7567
|
|
|
5548
7568
|
// src/commands/ads/linkedin/demographics.ts
|
|
5549
|
-
import { defineCommand as
|
|
7569
|
+
import { defineCommand as defineCommand42 } from "citty";
|
|
5550
7570
|
var DEFAULT_PIVOTS = ["job-title", "company", "industry", "seniority", "job-function", "company-size"];
|
|
5551
7571
|
function numberOf2(v) {
|
|
5552
7572
|
if (typeof v === "number") return Number.isFinite(v) ? v : 0;
|
|
@@ -5559,7 +7579,7 @@ function numberOf2(v) {
|
|
|
5559
7579
|
function topByImpressions(rows, limit) {
|
|
5560
7580
|
return [...rows].sort((a, b) => numberOf2(b.impressions) - numberOf2(a.impressions)).slice(0, limit);
|
|
5561
7581
|
}
|
|
5562
|
-
var demographicsCommand =
|
|
7582
|
+
var demographicsCommand = defineCommand42({
|
|
5563
7583
|
meta: {
|
|
5564
7584
|
name: "demographics",
|
|
5565
7585
|
description: `Sweep all firmographic pivots in one command \u2014 LinkedIn's superpower.
|
|
@@ -5642,22 +7662,97 @@ Examples:
|
|
|
5642
7662
|
}
|
|
5643
7663
|
}
|
|
5644
7664
|
});
|
|
5645
|
-
function resolveRange(args) {
|
|
5646
|
-
const start = args.start;
|
|
5647
|
-
const end = args.end;
|
|
5648
|
-
if (start) {
|
|
5649
|
-
return { start, end };
|
|
5650
|
-
}
|
|
5651
|
-
const days = args["last-days"] ? Number(args["last-days"]) : 30;
|
|
5652
|
-
if (!Number.isFinite(days) || days < 1) {
|
|
5653
|
-
handleLinkedinError(new Error("Invalid --last-days; must be a positive integer."));
|
|
5654
|
-
}
|
|
5655
|
-
return { start: daysAgoIso(days), end: todayIso() };
|
|
5656
|
-
}
|
|
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
|
+
});
|
|
5657
7752
|
|
|
5658
7753
|
// src/commands/ads/linkedin/facets.ts
|
|
5659
|
-
import { defineCommand as
|
|
5660
|
-
var listCmd2 =
|
|
7754
|
+
import { defineCommand as defineCommand44 } from "citty";
|
|
7755
|
+
var listCmd2 = defineCommand44({
|
|
5661
7756
|
meta: {
|
|
5662
7757
|
name: "list",
|
|
5663
7758
|
description: `List every targeting facet LinkedIn supports.
|
|
@@ -5685,7 +7780,7 @@ seniorities, titles, employers, growthRate, companyCategory, skills, etc.).`
|
|
|
5685
7780
|
}
|
|
5686
7781
|
}
|
|
5687
7782
|
});
|
|
5688
|
-
var valuesCmd =
|
|
7783
|
+
var valuesCmd = defineCommand44({
|
|
5689
7784
|
meta: {
|
|
5690
7785
|
name: "values",
|
|
5691
7786
|
description: `Look up entity values for a single facet \u2014 full list or typeahead search.
|
|
@@ -5726,7 +7821,7 @@ or the full URN (urn:li:adTargetingFacet:industries).`
|
|
|
5726
7821
|
}
|
|
5727
7822
|
}
|
|
5728
7823
|
});
|
|
5729
|
-
var facetsCommand =
|
|
7824
|
+
var facetsCommand = defineCommand44({
|
|
5730
7825
|
meta: {
|
|
5731
7826
|
name: "facets",
|
|
5732
7827
|
description: `LinkedIn targeting facets and entity lookup.
|
|
@@ -5743,8 +7838,8 @@ Subcommands:
|
|
|
5743
7838
|
});
|
|
5744
7839
|
|
|
5745
7840
|
// src/commands/ads/linkedin/forecast.ts
|
|
5746
|
-
import { readFileSync as
|
|
5747
|
-
import { defineCommand as
|
|
7841
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
7842
|
+
import { defineCommand as defineCommand45 } from "citty";
|
|
5748
7843
|
function loadTargeting3(args) {
|
|
5749
7844
|
const inline = args.targeting;
|
|
5750
7845
|
if (inline) {
|
|
@@ -5757,7 +7852,7 @@ function loadTargeting3(args) {
|
|
|
5757
7852
|
const file = args["targeting-file"];
|
|
5758
7853
|
if (file) {
|
|
5759
7854
|
try {
|
|
5760
|
-
return JSON.parse(
|
|
7855
|
+
return JSON.parse(readFileSync7(file, "utf-8"));
|
|
5761
7856
|
} catch (e) {
|
|
5762
7857
|
handleLinkedinError(
|
|
5763
7858
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -5774,7 +7869,7 @@ function parseMoney(raw) {
|
|
|
5774
7869
|
}
|
|
5775
7870
|
return { amount: m[1] ?? "0", currencyCode: m[2] ?? "USD" };
|
|
5776
7871
|
}
|
|
5777
|
-
var forecastCommand =
|
|
7872
|
+
var forecastCommand = defineCommand45({
|
|
5778
7873
|
meta: {
|
|
5779
7874
|
name: "forecast",
|
|
5780
7875
|
description: `Forecast reach + impressions + clicks + spend for a hypothetical campaign.
|
|
@@ -5821,9 +7916,9 @@ Examples:
|
|
|
5821
7916
|
});
|
|
5822
7917
|
|
|
5823
7918
|
// src/commands/ads/linkedin/leads.ts
|
|
5824
|
-
import { defineCommand as
|
|
7919
|
+
import { defineCommand as defineCommand46 } from "citty";
|
|
5825
7920
|
var DAY_MS4 = 864e5;
|
|
5826
|
-
var leadsCommand =
|
|
7921
|
+
var leadsCommand = defineCommand46({
|
|
5827
7922
|
meta: {
|
|
5828
7923
|
name: "leads",
|
|
5829
7924
|
description: `List Lead Gen Form responses (playbook \xA707).
|
|
@@ -5883,7 +7978,7 @@ Examples:
|
|
|
5883
7978
|
});
|
|
5884
7979
|
|
|
5885
7980
|
// src/commands/ads/linkedin/resolve.ts
|
|
5886
|
-
import { defineCommand as
|
|
7981
|
+
import { defineCommand as defineCommand47 } from "citty";
|
|
5887
7982
|
function toOrgUrn(raw) {
|
|
5888
7983
|
const trimmed = raw.trim();
|
|
5889
7984
|
if (trimmed.length === 0) {
|
|
@@ -5894,7 +7989,7 @@ function toOrgUrn(raw) {
|
|
|
5894
7989
|
}
|
|
5895
7990
|
return /^\d+$/.test(trimmed) ? `urn:li:organization:${trimmed}` : null;
|
|
5896
7991
|
}
|
|
5897
|
-
var resolveCommand =
|
|
7992
|
+
var resolveCommand = defineCommand47({
|
|
5898
7993
|
meta: {
|
|
5899
7994
|
name: "resolve",
|
|
5900
7995
|
description: `Resolve organization URNs to company names.
|
|
@@ -5936,8 +8031,8 @@ couldn't be resolved \u2014 typically an org outside LinkedIn's targetable set.`
|
|
|
5936
8031
|
});
|
|
5937
8032
|
|
|
5938
8033
|
// src/commands/ads/linkedin/top-companies.ts
|
|
5939
|
-
import { defineCommand as
|
|
5940
|
-
var topCompaniesCommand =
|
|
8034
|
+
import { defineCommand as defineCommand48 } from "citty";
|
|
8035
|
+
var topCompaniesCommand = defineCommand48({
|
|
5941
8036
|
meta: {
|
|
5942
8037
|
name: "top-companies",
|
|
5943
8038
|
description: `Top companies whose employees saw / clicked / converted on a campaign.
|
|
@@ -6008,7 +8103,7 @@ Examples:
|
|
|
6008
8103
|
});
|
|
6009
8104
|
|
|
6010
8105
|
// src/commands/ads/linkedin/index.ts
|
|
6011
|
-
var linkedinCommand =
|
|
8106
|
+
var linkedinCommand = defineCommand49({
|
|
6012
8107
|
meta: {
|
|
6013
8108
|
name: "linkedin",
|
|
6014
8109
|
description: `LinkedIn Marketing API \u2014 AI-first command surface for B2B ad insights.
|
|
@@ -6034,6 +8129,17 @@ Performance \u2014 the workhorse (3 axes):
|
|
|
6034
8129
|
baker ads linkedin analytics --list-intents
|
|
6035
8130
|
baker ads linkedin analytics --list-pivots
|
|
6036
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
|
+
|
|
6037
8143
|
Account ID format:
|
|
6038
8144
|
--account-id accepts numeric (503001492) or URN (urn:li:sponsoredAccount:503001492).
|
|
6039
8145
|
Set BAKER_LINKEDIN_AD_ACCOUNT_ID env to skip --account-id on every call.`
|
|
@@ -6044,6 +8150,9 @@ Account ID format:
|
|
|
6044
8150
|
"campaign-groups": campaignGroupsCommand,
|
|
6045
8151
|
campaigns: campaignsCommand,
|
|
6046
8152
|
creatives: creativesCommand,
|
|
8153
|
+
audiences: audiencesCommand,
|
|
8154
|
+
"lead-forms": leadFormsCommand,
|
|
8155
|
+
draft: linkedinDraftCommand,
|
|
6047
8156
|
analytics: analyticsCommand,
|
|
6048
8157
|
demographics: demographicsCommand,
|
|
6049
8158
|
"top-companies": topCompaniesCommand,
|
|
@@ -6060,10 +8169,10 @@ Account ID format:
|
|
|
6060
8169
|
});
|
|
6061
8170
|
|
|
6062
8171
|
// src/commands/ads/meta/index.ts
|
|
6063
|
-
import { defineCommand as
|
|
8172
|
+
import { defineCommand as defineCommand62 } from "citty";
|
|
6064
8173
|
|
|
6065
8174
|
// src/commands/ads/meta/account.ts
|
|
6066
|
-
import { defineCommand as
|
|
8175
|
+
import { defineCommand as defineCommand50 } from "citty";
|
|
6067
8176
|
|
|
6068
8177
|
// src/commands/ads/meta/shared.ts
|
|
6069
8178
|
var DAY_MS5 = 864e5;
|
|
@@ -6142,7 +8251,7 @@ function resolveEffectiveStatus(args) {
|
|
|
6142
8251
|
}
|
|
6143
8252
|
|
|
6144
8253
|
// src/commands/ads/meta/account.ts
|
|
6145
|
-
var accountCommand2 =
|
|
8254
|
+
var accountCommand2 = defineCommand50({
|
|
6146
8255
|
meta: {
|
|
6147
8256
|
name: "account",
|
|
6148
8257
|
description: `Show single Meta ad account detail (currency, timezone, balance, business).
|
|
@@ -6169,8 +8278,8 @@ Examples:
|
|
|
6169
8278
|
});
|
|
6170
8279
|
|
|
6171
8280
|
// src/commands/ads/meta/accounts.ts
|
|
6172
|
-
import { defineCommand as
|
|
6173
|
-
var accountsCommand3 =
|
|
8281
|
+
import { defineCommand as defineCommand51 } from "citty";
|
|
8282
|
+
var accountsCommand3 = defineCommand51({
|
|
6174
8283
|
meta: {
|
|
6175
8284
|
name: "accounts",
|
|
6176
8285
|
description: `List Meta ad accounts in this company's connected scope.
|
|
@@ -6218,8 +8327,8 @@ Examples:
|
|
|
6218
8327
|
});
|
|
6219
8328
|
|
|
6220
8329
|
// src/commands/ads/meta/activities.ts
|
|
6221
|
-
import { defineCommand as
|
|
6222
|
-
var activitiesCommand =
|
|
8330
|
+
import { defineCommand as defineCommand52 } from "citty";
|
|
8331
|
+
var activitiesCommand = defineCommand52({
|
|
6223
8332
|
meta: {
|
|
6224
8333
|
name: "activities",
|
|
6225
8334
|
description: `Audit log of recent ad-account changes (created, paused, edited). Default lookback 7 days,
|
|
@@ -6256,8 +8365,8 @@ Examples:
|
|
|
6256
8365
|
});
|
|
6257
8366
|
|
|
6258
8367
|
// src/commands/ads/meta/ads.ts
|
|
6259
|
-
import { defineCommand as
|
|
6260
|
-
var adsListCommand =
|
|
8368
|
+
import { defineCommand as defineCommand53 } from "citty";
|
|
8369
|
+
var adsListCommand = defineCommand53({
|
|
6261
8370
|
meta: {
|
|
6262
8371
|
name: "ads",
|
|
6263
8372
|
description: `List ads in a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -6305,8 +8414,8 @@ Examples:
|
|
|
6305
8414
|
});
|
|
6306
8415
|
|
|
6307
8416
|
// src/commands/ads/meta/adsets.ts
|
|
6308
|
-
import { defineCommand as
|
|
6309
|
-
var adsetsCommand =
|
|
8417
|
+
import { defineCommand as defineCommand54 } from "citty";
|
|
8418
|
+
var adsetsCommand = defineCommand54({
|
|
6310
8419
|
meta: {
|
|
6311
8420
|
name: "adsets",
|
|
6312
8421
|
description: `List ad sets in a Meta ad account, optionally scoped to one campaign. Defaults to ACTIVE only.
|
|
@@ -6348,8 +8457,8 @@ Examples:
|
|
|
6348
8457
|
});
|
|
6349
8458
|
|
|
6350
8459
|
// src/commands/ads/meta/audiences.ts
|
|
6351
|
-
import { defineCommand as
|
|
6352
|
-
var
|
|
8460
|
+
import { defineCommand as defineCommand55 } from "citty";
|
|
8461
|
+
var audiencesCommand2 = defineCommand55({
|
|
6353
8462
|
meta: {
|
|
6354
8463
|
name: "audiences",
|
|
6355
8464
|
description: `List custom audiences for a Meta ad account. Includes lookalikes, website-pixel audiences,
|
|
@@ -6384,8 +8493,8 @@ Examples:
|
|
|
6384
8493
|
});
|
|
6385
8494
|
|
|
6386
8495
|
// src/commands/ads/meta/businesses.ts
|
|
6387
|
-
import { defineCommand as
|
|
6388
|
-
var businessesCommand =
|
|
8496
|
+
import { defineCommand as defineCommand56 } from "citty";
|
|
8497
|
+
var businessesCommand = defineCommand56({
|
|
6389
8498
|
meta: {
|
|
6390
8499
|
name: "businesses",
|
|
6391
8500
|
description: `List Meta Business Manager accounts the connected user has access to. Required for ad-studies and product-catalogs commands.
|
|
@@ -6415,8 +8524,8 @@ Examples:
|
|
|
6415
8524
|
});
|
|
6416
8525
|
|
|
6417
8526
|
// src/commands/ads/meta/campaigns.ts
|
|
6418
|
-
import { defineCommand as
|
|
6419
|
-
var campaignsCommand2 =
|
|
8527
|
+
import { defineCommand as defineCommand57 } from "citty";
|
|
8528
|
+
var campaignsCommand2 = defineCommand57({
|
|
6420
8529
|
meta: {
|
|
6421
8530
|
name: "campaigns",
|
|
6422
8531
|
description: `List campaigns for a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -6460,8 +8569,8 @@ Examples:
|
|
|
6460
8569
|
});
|
|
6461
8570
|
|
|
6462
8571
|
// src/commands/ads/meta/creatives.ts
|
|
6463
|
-
import { defineCommand as
|
|
6464
|
-
var creativesCommand2 =
|
|
8572
|
+
import { defineCommand as defineCommand58 } from "citty";
|
|
8573
|
+
var creativesCommand2 = defineCommand58({
|
|
6465
8574
|
meta: {
|
|
6466
8575
|
name: "creatives",
|
|
6467
8576
|
description: `List ad creatives in an account, or fetch a single creative by ID.
|
|
@@ -6505,7 +8614,7 @@ Examples:
|
|
|
6505
8614
|
});
|
|
6506
8615
|
|
|
6507
8616
|
// src/commands/ads/meta/insights.ts
|
|
6508
|
-
import { defineCommand as
|
|
8617
|
+
import { defineCommand as defineCommand59 } from "citty";
|
|
6509
8618
|
|
|
6510
8619
|
// src/commands/ads/meta/presets.ts
|
|
6511
8620
|
var INSIGHTS_INTENTS = {
|
|
@@ -6710,7 +8819,7 @@ function sortRowsBySpendDesc(rows) {
|
|
|
6710
8819
|
return sb - sa;
|
|
6711
8820
|
});
|
|
6712
8821
|
}
|
|
6713
|
-
var insightsCommand =
|
|
8822
|
+
var insightsCommand = defineCommand59({
|
|
6714
8823
|
meta: {
|
|
6715
8824
|
name: "insights",
|
|
6716
8825
|
description: `Performance reporting \u2014 the main Meta tool for AI agents.
|
|
@@ -6811,8 +8920,8 @@ Async is automatic for heavy queries; pass --async to force it, or --no-async to
|
|
|
6811
8920
|
});
|
|
6812
8921
|
|
|
6813
8922
|
// src/commands/ads/meta/pixels.ts
|
|
6814
|
-
import { defineCommand as
|
|
6815
|
-
var pixelsCommand =
|
|
8923
|
+
import { defineCommand as defineCommand60 } from "citty";
|
|
8924
|
+
var pixelsCommand = defineCommand60({
|
|
6816
8925
|
meta: {
|
|
6817
8926
|
name: "pixels",
|
|
6818
8927
|
description: `List Meta Pixels for an ad account, or fetch firing stats for one pixel.
|
|
@@ -6883,7 +8992,7 @@ function emit(data, args) {
|
|
|
6883
8992
|
|
|
6884
8993
|
// src/commands/ads/meta/preview.ts
|
|
6885
8994
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
6886
|
-
import { defineCommand as
|
|
8995
|
+
import { defineCommand as defineCommand61 } from "citty";
|
|
6887
8996
|
var VALID_AD_FORMATS = [
|
|
6888
8997
|
"DESKTOP_FEED_STANDARD",
|
|
6889
8998
|
"MOBILE_FEED_STANDARD",
|
|
@@ -6917,7 +9026,7 @@ var VALID_AD_FORMATS = [
|
|
|
6917
9026
|
"MARKETPLACE_MOBILE",
|
|
6918
9027
|
"BIZ_DISCO_FEED_MOBILE"
|
|
6919
9028
|
];
|
|
6920
|
-
var previewCommand =
|
|
9029
|
+
var previewCommand = defineCommand61({
|
|
6921
9030
|
meta: {
|
|
6922
9031
|
name: "preview",
|
|
6923
9032
|
description: `Generate a Meta-hosted preview iframe for a creative or ad. Returns iframe HTML which you
|
|
@@ -6964,7 +9073,7 @@ Examples:
|
|
|
6964
9073
|
});
|
|
6965
9074
|
|
|
6966
9075
|
// src/commands/ads/meta/index.ts
|
|
6967
|
-
var metaCommand =
|
|
9076
|
+
var metaCommand = defineCommand62({
|
|
6968
9077
|
meta: {
|
|
6969
9078
|
name: "meta",
|
|
6970
9079
|
description: `Meta Marketing API \u2014 AI-first command surface (Facebook + Instagram ads).
|
|
@@ -7007,7 +9116,7 @@ Audit & review:
|
|
|
7007
9116
|
adsets: adsetsCommand,
|
|
7008
9117
|
ads: adsListCommand,
|
|
7009
9118
|
creatives: creativesCommand2,
|
|
7010
|
-
audiences:
|
|
9119
|
+
audiences: audiencesCommand2,
|
|
7011
9120
|
pixels: pixelsCommand,
|
|
7012
9121
|
activities: activitiesCommand,
|
|
7013
9122
|
insights: insightsCommand,
|
|
@@ -7016,10 +9125,10 @@ Audit & review:
|
|
|
7016
9125
|
});
|
|
7017
9126
|
|
|
7018
9127
|
// src/commands/ads/x/index.ts
|
|
7019
|
-
import { defineCommand as
|
|
9128
|
+
import { defineCommand as defineCommand79 } from "citty";
|
|
7020
9129
|
|
|
7021
9130
|
// src/commands/ads/x/accounts.ts
|
|
7022
|
-
import { defineCommand as
|
|
9131
|
+
import { defineCommand as defineCommand63 } from "citty";
|
|
7023
9132
|
registerSchema({
|
|
7024
9133
|
command: "ads.x.accounts",
|
|
7025
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.",
|
|
@@ -7047,7 +9156,7 @@ function handleAccountsError2(err) {
|
|
|
7047
9156
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
7048
9157
|
process.exit(1);
|
|
7049
9158
|
}
|
|
7050
|
-
var accountsCommand4 =
|
|
9159
|
+
var accountsCommand4 = defineCommand63({
|
|
7051
9160
|
meta: {
|
|
7052
9161
|
name: "accounts",
|
|
7053
9162
|
description: `List accessible X Ads accounts. Returns account IDs needed for all other commands.
|
|
@@ -7087,7 +9196,7 @@ Examples:
|
|
|
7087
9196
|
});
|
|
7088
9197
|
|
|
7089
9198
|
// src/commands/ads/x/active-entities.ts
|
|
7090
|
-
import { defineCommand as
|
|
9199
|
+
import { defineCommand as defineCommand64 } from "citty";
|
|
7091
9200
|
|
|
7092
9201
|
// src/commands/ads/x/error-parser.ts
|
|
7093
9202
|
function mapXErrorCode(message) {
|
|
@@ -7238,7 +9347,7 @@ function parseCsv(v) {
|
|
|
7238
9347
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7239
9348
|
return parts.length > 0 ? parts : void 0;
|
|
7240
9349
|
}
|
|
7241
|
-
var activeEntitiesCommand =
|
|
9350
|
+
var activeEntitiesCommand = defineCommand64({
|
|
7242
9351
|
meta: {
|
|
7243
9352
|
name: "active-entities",
|
|
7244
9353
|
description: `List entities with metric activity in a time range.
|
|
@@ -7296,7 +9405,7 @@ Examples:
|
|
|
7296
9405
|
});
|
|
7297
9406
|
|
|
7298
9407
|
// src/commands/ads/x/audiences.ts
|
|
7299
|
-
import { defineCommand as
|
|
9408
|
+
import { defineCommand as defineCommand65 } from "citty";
|
|
7300
9409
|
registerSchema({
|
|
7301
9410
|
command: "ads.x.audiences",
|
|
7302
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.",
|
|
@@ -7305,7 +9414,7 @@ registerSchema({
|
|
|
7305
9414
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7306
9415
|
}
|
|
7307
9416
|
});
|
|
7308
|
-
var
|
|
9417
|
+
var audiencesCommand3 = defineCommand65({
|
|
7309
9418
|
meta: {
|
|
7310
9419
|
name: "audiences",
|
|
7311
9420
|
description: `List X Ads custom audiences.
|
|
@@ -7354,7 +9463,7 @@ Examples:
|
|
|
7354
9463
|
});
|
|
7355
9464
|
|
|
7356
9465
|
// src/commands/ads/x/campaigns.ts
|
|
7357
|
-
import { defineCommand as
|
|
9466
|
+
import { defineCommand as defineCommand66 } from "citty";
|
|
7358
9467
|
|
|
7359
9468
|
// src/commands/ads/x/run-list.ts
|
|
7360
9469
|
function buildCleanParams(opts) {
|
|
@@ -7417,7 +9526,7 @@ registerSchema({
|
|
|
7417
9526
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7418
9527
|
}
|
|
7419
9528
|
});
|
|
7420
|
-
var campaignsCommand3 =
|
|
9529
|
+
var campaignsCommand3 = defineCommand66({
|
|
7421
9530
|
meta: {
|
|
7422
9531
|
name: "campaigns",
|
|
7423
9532
|
description: `List X Ads campaigns. Returns budget, schedule, funding instrument, status.
|
|
@@ -7459,7 +9568,7 @@ Examples:
|
|
|
7459
9568
|
});
|
|
7460
9569
|
|
|
7461
9570
|
// src/commands/ads/x/cards.ts
|
|
7462
|
-
import { defineCommand as
|
|
9571
|
+
import { defineCommand as defineCommand67 } from "citty";
|
|
7463
9572
|
registerSchema({
|
|
7464
9573
|
command: "ads.x.cards",
|
|
7465
9574
|
description: "List website cards, video cards, and carousels for an X Ads account.",
|
|
@@ -7468,7 +9577,7 @@ registerSchema({
|
|
|
7468
9577
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7469
9578
|
}
|
|
7470
9579
|
});
|
|
7471
|
-
var cardsCommand =
|
|
9580
|
+
var cardsCommand = defineCommand67({
|
|
7472
9581
|
meta: {
|
|
7473
9582
|
name: "cards",
|
|
7474
9583
|
description: `List X Ads cards (rich creatives).
|
|
@@ -7517,7 +9626,7 @@ Examples:
|
|
|
7517
9626
|
});
|
|
7518
9627
|
|
|
7519
9628
|
// src/commands/ads/x/funding.ts
|
|
7520
|
-
import { defineCommand as
|
|
9629
|
+
import { defineCommand as defineCommand68 } from "citty";
|
|
7521
9630
|
registerSchema({
|
|
7522
9631
|
command: "ads.x.funding",
|
|
7523
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.",
|
|
@@ -7526,7 +9635,7 @@ registerSchema({
|
|
|
7526
9635
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7527
9636
|
}
|
|
7528
9637
|
});
|
|
7529
|
-
var fundingCommand =
|
|
9638
|
+
var fundingCommand = defineCommand68({
|
|
7530
9639
|
meta: {
|
|
7531
9640
|
name: "funding",
|
|
7532
9641
|
description: `List funding instruments for an X Ads account.
|
|
@@ -7575,7 +9684,7 @@ Examples:
|
|
|
7575
9684
|
});
|
|
7576
9685
|
|
|
7577
9686
|
// src/commands/ads/x/line-items.ts
|
|
7578
|
-
import { defineCommand as
|
|
9687
|
+
import { defineCommand as defineCommand69 } from "citty";
|
|
7579
9688
|
registerSchema({
|
|
7580
9689
|
command: "ads.x.lineItems",
|
|
7581
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).",
|
|
@@ -7587,7 +9696,7 @@ registerSchema({
|
|
|
7587
9696
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7588
9697
|
}
|
|
7589
9698
|
});
|
|
7590
|
-
var lineItemsCommand =
|
|
9699
|
+
var lineItemsCommand = defineCommand69({
|
|
7591
9700
|
meta: {
|
|
7592
9701
|
name: "line-items",
|
|
7593
9702
|
description: `List X Ads line items (ad groups).
|
|
@@ -7628,7 +9737,7 @@ Examples:
|
|
|
7628
9737
|
});
|
|
7629
9738
|
|
|
7630
9739
|
// src/commands/ads/x/media.ts
|
|
7631
|
-
import { defineCommand as
|
|
9740
|
+
import { defineCommand as defineCommand70 } from "citty";
|
|
7632
9741
|
registerSchema({
|
|
7633
9742
|
command: "ads.x.media",
|
|
7634
9743
|
description: "List media assets in the X Ads media library (images, GIFs, videos). Filter by media-type (IMAGE, GIF, VIDEO).",
|
|
@@ -7638,7 +9747,7 @@ registerSchema({
|
|
|
7638
9747
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7639
9748
|
}
|
|
7640
9749
|
});
|
|
7641
|
-
var mediaCommand =
|
|
9750
|
+
var mediaCommand = defineCommand70({
|
|
7642
9751
|
meta: {
|
|
7643
9752
|
name: "media",
|
|
7644
9753
|
description: `List media assets in the X Ads media library.
|
|
@@ -7690,7 +9799,7 @@ Examples:
|
|
|
7690
9799
|
});
|
|
7691
9800
|
|
|
7692
9801
|
// src/commands/ads/x/promoted-tweets.ts
|
|
7693
|
-
import { defineCommand as
|
|
9802
|
+
import { defineCommand as defineCommand71 } from "citty";
|
|
7694
9803
|
registerSchema({
|
|
7695
9804
|
command: "ads.x.promotedTweets",
|
|
7696
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).",
|
|
@@ -7701,7 +9810,7 @@ registerSchema({
|
|
|
7701
9810
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
7702
9811
|
}
|
|
7703
9812
|
});
|
|
7704
|
-
var promotedTweetsCommand =
|
|
9813
|
+
var promotedTweetsCommand = defineCommand71({
|
|
7705
9814
|
meta: {
|
|
7706
9815
|
name: "promoted-tweets",
|
|
7707
9816
|
description: `List X Ads promoted tweets.
|
|
@@ -7755,11 +9864,11 @@ Examples:
|
|
|
7755
9864
|
});
|
|
7756
9865
|
|
|
7757
9866
|
// src/commands/ads/x/stats/index.ts
|
|
7758
|
-
import { defineCommand as
|
|
9867
|
+
import { defineCommand as defineCommand76 } from "citty";
|
|
7759
9868
|
|
|
7760
9869
|
// src/commands/ads/x/stats/job.ts
|
|
7761
9870
|
import { gunzipSync } from "zlib";
|
|
7762
|
-
import { defineCommand as
|
|
9871
|
+
import { defineCommand as defineCommand72 } from "citty";
|
|
7763
9872
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
7764
9873
|
var DEADLINE_MS = 12 * 60 * 1e3;
|
|
7765
9874
|
var RESULT_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -7829,7 +9938,7 @@ async function pollUntilDone(accountId, jobId) {
|
|
|
7829
9938
|
function buildCacheKey(body) {
|
|
7830
9939
|
return `stats-job:${JSON.stringify(body)}`;
|
|
7831
9940
|
}
|
|
7832
|
-
var statsJobCommand =
|
|
9941
|
+
var statsJobCommand = defineCommand72({
|
|
7833
9942
|
meta: {
|
|
7834
9943
|
name: "job",
|
|
7835
9944
|
description: `Async X Ads stats job, sync from the CLI's perspective. Creates \u2192 polls \u2192 downloads \u2192 returns.
|
|
@@ -7934,7 +10043,7 @@ For fine-grained control (don't wait, poll yourself), use:
|
|
|
7934
10043
|
});
|
|
7935
10044
|
|
|
7936
10045
|
// src/commands/ads/x/stats/job-create.ts
|
|
7937
|
-
import { defineCommand as
|
|
10046
|
+
import { defineCommand as defineCommand73 } from "citty";
|
|
7938
10047
|
registerSchema({
|
|
7939
10048
|
command: "ads.x.statsJobCreate",
|
|
7940
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.",
|
|
@@ -7957,7 +10066,7 @@ function parseCsv3(v) {
|
|
|
7957
10066
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7958
10067
|
return parts.length > 0 ? parts : void 0;
|
|
7959
10068
|
}
|
|
7960
|
-
var statsJobCreateCommand =
|
|
10069
|
+
var statsJobCreateCommand = defineCommand73({
|
|
7961
10070
|
meta: {
|
|
7962
10071
|
name: "job-create",
|
|
7963
10072
|
description: `Create an async X Ads stats job (up to 90 days, supports segmentation).
|
|
@@ -8020,7 +10129,7 @@ Examples:
|
|
|
8020
10129
|
});
|
|
8021
10130
|
|
|
8022
10131
|
// src/commands/ads/x/stats/job-status.ts
|
|
8023
|
-
import { defineCommand as
|
|
10132
|
+
import { defineCommand as defineCommand74 } from "citty";
|
|
8024
10133
|
registerSchema({
|
|
8025
10134
|
command: "ads.x.statsJobStatus",
|
|
8026
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).",
|
|
@@ -8030,7 +10139,7 @@ registerSchema({
|
|
|
8030
10139
|
"job-ids": { type: "string", description: "CSV of job IDs", required: false }
|
|
8031
10140
|
}
|
|
8032
10141
|
});
|
|
8033
|
-
var statsJobStatusCommand =
|
|
10142
|
+
var statsJobStatusCommand = defineCommand74({
|
|
8034
10143
|
meta: {
|
|
8035
10144
|
name: "job-status",
|
|
8036
10145
|
description: `Poll the status of an async X Ads stats job.
|
|
@@ -8071,7 +10180,7 @@ Examples:
|
|
|
8071
10180
|
});
|
|
8072
10181
|
|
|
8073
10182
|
// src/commands/ads/x/stats/sync.ts
|
|
8074
|
-
import { defineCommand as
|
|
10183
|
+
import { defineCommand as defineCommand75 } from "citty";
|
|
8075
10184
|
|
|
8076
10185
|
// src/commands/ads/x/presets.ts
|
|
8077
10186
|
var X_STATS_PRESETS = [
|
|
@@ -8230,7 +10339,7 @@ async function runSync(args, q) {
|
|
|
8230
10339
|
process.exit(1);
|
|
8231
10340
|
}
|
|
8232
10341
|
}
|
|
8233
|
-
var statsSyncCommand =
|
|
10342
|
+
var statsSyncCommand = defineCommand75({
|
|
8234
10343
|
meta: {
|
|
8235
10344
|
name: "sync",
|
|
8236
10345
|
description: `Synchronous X Ads analytics (max 7-day window).
|
|
@@ -8273,7 +10382,7 @@ Examples:
|
|
|
8273
10382
|
});
|
|
8274
10383
|
|
|
8275
10384
|
// src/commands/ads/x/stats/index.ts
|
|
8276
|
-
var statsCommand =
|
|
10385
|
+
var statsCommand = defineCommand76({
|
|
8277
10386
|
meta: {
|
|
8278
10387
|
name: "stats",
|
|
8279
10388
|
description: `X Ads analytics. Sync (\u22647 days, no segmentation) or async jobs (\u226490 days, segmentable).
|
|
@@ -8301,7 +10410,7 @@ Examples:
|
|
|
8301
10410
|
});
|
|
8302
10411
|
|
|
8303
10412
|
// src/commands/ads/x/targeting-constants.ts
|
|
8304
|
-
import { defineCommand as
|
|
10413
|
+
import { defineCommand as defineCommand77 } from "citty";
|
|
8305
10414
|
var ALLOWED_CONSTANTS = [
|
|
8306
10415
|
"locations",
|
|
8307
10416
|
"interests",
|
|
@@ -8329,7 +10438,7 @@ registerSchema({
|
|
|
8329
10438
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8330
10439
|
}
|
|
8331
10440
|
});
|
|
8332
|
-
var targetingConstantsCommand =
|
|
10441
|
+
var targetingConstantsCommand = defineCommand77({
|
|
8333
10442
|
meta: {
|
|
8334
10443
|
name: "targeting-constants",
|
|
8335
10444
|
description: `Lookup X Ads targeting constants.
|
|
@@ -8379,7 +10488,7 @@ Examples:
|
|
|
8379
10488
|
});
|
|
8380
10489
|
|
|
8381
10490
|
// src/commands/ads/x/targeting-criteria.ts
|
|
8382
|
-
import { defineCommand as
|
|
10491
|
+
import { defineCommand as defineCommand78 } from "citty";
|
|
8383
10492
|
registerSchema({
|
|
8384
10493
|
command: "ads.x.targetingCriteria",
|
|
8385
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.",
|
|
@@ -8389,7 +10498,7 @@ registerSchema({
|
|
|
8389
10498
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
8390
10499
|
}
|
|
8391
10500
|
});
|
|
8392
|
-
var targetingCriteriaCommand =
|
|
10501
|
+
var targetingCriteriaCommand = defineCommand78({
|
|
8393
10502
|
meta: {
|
|
8394
10503
|
name: "targeting-criteria",
|
|
8395
10504
|
description: `List targeting criteria attached to line items.
|
|
@@ -8440,7 +10549,7 @@ Examples:
|
|
|
8440
10549
|
});
|
|
8441
10550
|
|
|
8442
10551
|
// src/commands/ads/x/index.ts
|
|
8443
|
-
var xCommand =
|
|
10552
|
+
var xCommand = defineCommand79({
|
|
8444
10553
|
meta: {
|
|
8445
10554
|
name: "x",
|
|
8446
10555
|
description: `X (Twitter) Ads commands. Read campaigns, line items, promoted tweets, creatives, audiences, and analytics.
|
|
@@ -8469,7 +10578,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
8469
10578
|
"promoted-tweets": promotedTweetsCommand,
|
|
8470
10579
|
cards: cardsCommand,
|
|
8471
10580
|
media: mediaCommand,
|
|
8472
|
-
audiences:
|
|
10581
|
+
audiences: audiencesCommand3,
|
|
8473
10582
|
"targeting-criteria": targetingCriteriaCommand,
|
|
8474
10583
|
"targeting-constants": targetingConstantsCommand,
|
|
8475
10584
|
"active-entities": activeEntitiesCommand,
|
|
@@ -8478,7 +10587,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
8478
10587
|
});
|
|
8479
10588
|
|
|
8480
10589
|
// src/commands/ads/index.ts
|
|
8481
|
-
var adsCommand =
|
|
10590
|
+
var adsCommand = defineCommand80({
|
|
8482
10591
|
meta: {
|
|
8483
10592
|
name: "ads",
|
|
8484
10593
|
description: `Ad platform commands. Each platform exposes its own native command surface \u2014 no forced parity.
|
|
@@ -8508,11 +10617,11 @@ Examples:
|
|
|
8508
10617
|
});
|
|
8509
10618
|
|
|
8510
10619
|
// src/commands/canvas/index.ts
|
|
8511
|
-
import { defineCommand as
|
|
10620
|
+
import { defineCommand as defineCommand88 } from "citty";
|
|
8512
10621
|
|
|
8513
10622
|
// src/commands/canvas/catalog.ts
|
|
8514
|
-
import { defineCommand as
|
|
8515
|
-
var catalogCommand =
|
|
10623
|
+
import { defineCommand as defineCommand81 } from "citty";
|
|
10624
|
+
var catalogCommand = defineCommand81({
|
|
8516
10625
|
meta: {
|
|
8517
10626
|
name: "catalog",
|
|
8518
10627
|
description: "Print the agent-facing node catalog (JSON Schema). Includes every registered node grouped by category."
|
|
@@ -8529,9 +10638,9 @@ import { execFile } from "child_process";
|
|
|
8529
10638
|
import { readdir, readFile, stat } from "fs/promises";
|
|
8530
10639
|
import path from "path";
|
|
8531
10640
|
import { promisify } from "util";
|
|
8532
|
-
import { defineCommand as
|
|
10641
|
+
import { defineCommand as defineCommand82 } from "citty";
|
|
8533
10642
|
var execFileAsync = promisify(execFile);
|
|
8534
|
-
var inspectCommand =
|
|
10643
|
+
var inspectCommand = defineCommand82({
|
|
8535
10644
|
meta: {
|
|
8536
10645
|
name: "inspect",
|
|
8537
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."
|
|
@@ -8640,7 +10749,7 @@ async function probeDuration(filePath) {
|
|
|
8640
10749
|
// src/commands/canvas/run.ts
|
|
8641
10750
|
import { readFile as readFile2 } from "fs/promises";
|
|
8642
10751
|
import path4 from "path";
|
|
8643
|
-
import { defineCommand as
|
|
10752
|
+
import { defineCommand as defineCommand83 } from "citty";
|
|
8644
10753
|
|
|
8645
10754
|
// src/commands/canvas/placeholders.ts
|
|
8646
10755
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
@@ -8710,7 +10819,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
8710
10819
|
}
|
|
8711
10820
|
|
|
8712
10821
|
// src/commands/canvas/run.ts
|
|
8713
|
-
var runCommand =
|
|
10822
|
+
var runCommand = defineCommand83({
|
|
8714
10823
|
meta: { name: "run", description: "Validate and execute a canvas JSON file." },
|
|
8715
10824
|
args: {
|
|
8716
10825
|
file: { type: "positional", required: true, description: "Path to canvas JSON" },
|
|
@@ -8806,30 +10915,30 @@ var runCommand = defineCommand81({
|
|
|
8806
10915
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
8807
10916
|
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
8808
10917
|
import path5 from "path";
|
|
8809
|
-
import { defineCommand as
|
|
10918
|
+
import { defineCommand as defineCommand84 } from "citty";
|
|
8810
10919
|
|
|
8811
10920
|
// src/engine/scaffold/staticAd.ts
|
|
8812
|
-
import { z as
|
|
10921
|
+
import { z as z8 } from "zod";
|
|
8813
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"]);
|
|
8814
10923
|
var DEFAULT_ASPECT_RATIO = "9:16";
|
|
8815
|
-
var Blueprint =
|
|
8816
|
-
meta:
|
|
8817
|
-
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()
|
|
8818
10927
|
}).loose();
|
|
8819
|
-
var ElementLocator =
|
|
8820
|
-
collection:
|
|
8821
|
-
index:
|
|
10928
|
+
var ElementLocator = z8.object({
|
|
10929
|
+
collection: z8.enum(["subjects", "people", "brands_logos"]),
|
|
10930
|
+
index: z8.number().int().nonnegative()
|
|
8822
10931
|
}).loose();
|
|
8823
|
-
var MainElement =
|
|
10932
|
+
var MainElement = z8.object({
|
|
8824
10933
|
// logo | product | person | animal | badge | other
|
|
8825
|
-
type:
|
|
8826
|
-
label:
|
|
8827
|
-
description:
|
|
8828
|
-
expression:
|
|
8829
|
-
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(),
|
|
8830
10939
|
locator: ElementLocator.optional()
|
|
8831
10940
|
}).loose();
|
|
8832
|
-
var MainElements =
|
|
10941
|
+
var MainElements = z8.array(MainElement);
|
|
8833
10942
|
function sanitizeId(raw, fallback) {
|
|
8834
10943
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
8835
10944
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -9125,7 +11234,7 @@ async function runVisionPasses(canvas) {
|
|
|
9125
11234
|
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
9126
11235
|
}
|
|
9127
11236
|
}
|
|
9128
|
-
var scaffoldStaticAdCommand =
|
|
11237
|
+
var scaffoldStaticAdCommand = defineCommand84({
|
|
9129
11238
|
meta: {
|
|
9130
11239
|
name: "scaffold-static-ad",
|
|
9131
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."
|
|
@@ -9219,7 +11328,7 @@ var scaffoldStaticAdCommand = defineCommand82({
|
|
|
9219
11328
|
// src/commands/canvas/scaffold-video.ts
|
|
9220
11329
|
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
9221
11330
|
import path8 from "path";
|
|
9222
|
-
import { defineCommand as
|
|
11331
|
+
import { defineCommand as defineCommand85 } from "citty";
|
|
9223
11332
|
|
|
9224
11333
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
9225
11334
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -9324,7 +11433,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
|
|
|
9324
11433
|
import { toCardinal as nwNl } from "n2words/nl-NL";
|
|
9325
11434
|
import { toCardinal as nwPl } from "n2words/pl-PL";
|
|
9326
11435
|
import { toCardinal as nwPt } from "n2words/pt-PT";
|
|
9327
|
-
import { z as
|
|
11436
|
+
import { z as z9 } from "zod";
|
|
9328
11437
|
|
|
9329
11438
|
// src/engine/scaffold/lib/shoot-modes.ts
|
|
9330
11439
|
var SHOOT_MODES = [
|
|
@@ -9581,49 +11690,49 @@ function trimArgs(durationS, offsetS = 0) {
|
|
|
9581
11690
|
"{{out.video}}"
|
|
9582
11691
|
];
|
|
9583
11692
|
}
|
|
9584
|
-
var FrameAsset =
|
|
9585
|
-
var DialogueLine =
|
|
9586
|
-
speaker:
|
|
9587
|
-
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(),
|
|
9588
11697
|
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
9589
|
-
start_s:
|
|
9590
|
-
end_s:
|
|
9591
|
-
delivery:
|
|
9592
|
-
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()
|
|
9593
11702
|
}).loose();
|
|
9594
|
-
var Sfx =
|
|
9595
|
-
at_s:
|
|
9596
|
-
duration_s:
|
|
9597
|
-
sound_effect_prompt:
|
|
9598
|
-
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()
|
|
9599
11708
|
}).loose();
|
|
9600
|
-
var CompositionRegion =
|
|
11709
|
+
var CompositionRegion = z9.object({
|
|
9601
11710
|
// full | top | bottom | left | right | inset
|
|
9602
|
-
panel:
|
|
11711
|
+
panel: z9.string().optional(),
|
|
9603
11712
|
// 9-grid anchor for an `inset` presenter box.
|
|
9604
|
-
position:
|
|
9605
|
-
is_presenter:
|
|
11713
|
+
position: z9.string().optional(),
|
|
11714
|
+
is_presenter: z9.boolean().optional(),
|
|
9606
11715
|
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
9607
|
-
cast_ref:
|
|
9608
|
-
summary:
|
|
9609
|
-
frame_prompt:
|
|
9610
|
-
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()
|
|
9611
11720
|
}).loose();
|
|
9612
|
-
var SceneComposition =
|
|
11721
|
+
var SceneComposition = z9.object({
|
|
9613
11722
|
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
9614
|
-
layout:
|
|
11723
|
+
layout: z9.string().optional(),
|
|
9615
11724
|
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
9616
|
-
split_axis:
|
|
9617
|
-
regions:
|
|
11725
|
+
split_axis: z9.string().optional(),
|
|
11726
|
+
regions: z9.array(CompositionRegion).optional()
|
|
9618
11727
|
}).loose();
|
|
9619
|
-
var CameraMotion =
|
|
9620
|
-
var TranscriptWord =
|
|
9621
|
-
var Scene =
|
|
9622
|
-
start_s:
|
|
9623
|
-
end_s:
|
|
9624
|
-
duration_s:
|
|
9625
|
-
summary:
|
|
9626
|
-
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(),
|
|
9627
11736
|
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
9628
11737
|
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
9629
11738
|
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
@@ -9631,77 +11740,77 @@ var Scene = z4.object({
|
|
|
9631
11740
|
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
9632
11741
|
// grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
|
|
9633
11742
|
// UGC/product mode; a human can override per scene by setting this.
|
|
9634
|
-
shoot_mode:
|
|
11743
|
+
shoot_mode: z9.string().optional(),
|
|
9635
11744
|
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
9636
11745
|
// absent the scene falls back to its shoot mode's default ambience.
|
|
9637
|
-
ambient:
|
|
11746
|
+
ambient: z9.string().optional(),
|
|
9638
11747
|
camera_motion: CameraMotion.optional(),
|
|
9639
|
-
start_frame_prompt:
|
|
9640
|
-
end_frame_prompt:
|
|
9641
|
-
motion_prompt:
|
|
11748
|
+
start_frame_prompt: z9.string().optional(),
|
|
11749
|
+
end_frame_prompt: z9.string().optional(),
|
|
11750
|
+
motion_prompt: z9.string().optional(),
|
|
9642
11751
|
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
9643
11752
|
// script re-craft checklist. Inferred from position when absent.
|
|
9644
|
-
narrative_role:
|
|
11753
|
+
narrative_role: z9.string().optional(),
|
|
9645
11754
|
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
9646
11755
|
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
9647
11756
|
// into the hook's start-frame description so the generator renders that state,
|
|
9648
11757
|
// not a calm influencer (CCA-11).
|
|
9649
|
-
hook_mechanic:
|
|
11758
|
+
hook_mechanic: z9.object({ mechanic: z9.string().optional(), why_it_stops_scroll: z9.string().optional() }).loose().optional(),
|
|
9650
11759
|
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
9651
|
-
scene_setting:
|
|
11760
|
+
scene_setting: z9.string().optional(),
|
|
9652
11761
|
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
9653
11762
|
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
9654
11763
|
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
9655
11764
|
// ignored (nothing follows it).
|
|
9656
|
-
transition_out:
|
|
9657
|
-
dialogue:
|
|
9658
|
-
sfx:
|
|
9659
|
-
overlays:
|
|
9660
|
-
floating_elements:
|
|
9661
|
-
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(),
|
|
9662
11771
|
start_frame_asset: FrameAsset,
|
|
9663
11772
|
end_frame_asset: FrameAsset,
|
|
9664
11773
|
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
9665
11774
|
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
9666
11775
|
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
9667
11776
|
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
9668
|
-
continues_previous:
|
|
11777
|
+
continues_previous: z9.boolean().optional()
|
|
9669
11778
|
}).loose();
|
|
9670
|
-
var VideoBlueprint =
|
|
9671
|
-
source:
|
|
9672
|
-
global:
|
|
9673
|
-
music:
|
|
9674
|
-
present:
|
|
9675
|
-
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(),
|
|
9676
11785
|
// Absolute second the music enters in the reference (the bed often
|
|
9677
11786
|
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
9678
11787
|
// instead of at 0 so the timing matches.
|
|
9679
|
-
starts_at_s:
|
|
11788
|
+
starts_at_s: z9.number().optional(),
|
|
9680
11789
|
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
9681
11790
|
// reference track. We never reuse it — only style the regenerated bed.
|
|
9682
|
-
identified_track:
|
|
11791
|
+
identified_track: z9.object({ title: z9.string().optional(), artist: z9.string().optional() }).loose().nullish()
|
|
9683
11792
|
}).loose().optional(),
|
|
9684
|
-
cast:
|
|
9685
|
-
|
|
9686
|
-
id:
|
|
9687
|
-
description:
|
|
11793
|
+
cast: z9.array(
|
|
11794
|
+
z9.object({
|
|
11795
|
+
id: z9.string().optional(),
|
|
11796
|
+
description: z9.string().optional(),
|
|
9688
11797
|
// The deconstruct's note on the target-market localization (e.g. "native
|
|
9689
11798
|
// French speaker") — read to derive the spoken-track language code.
|
|
9690
|
-
market_localization_note:
|
|
11799
|
+
market_localization_note: z9.string().optional()
|
|
9691
11800
|
}).loose()
|
|
9692
11801
|
).optional(),
|
|
9693
|
-
voiceover:
|
|
11802
|
+
voiceover: z9.object({
|
|
9694
11803
|
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
9695
11804
|
// voiceover | none → narration over the picture (no lip-sync).
|
|
9696
|
-
mode:
|
|
9697
|
-
voice_description:
|
|
9698
|
-
persona:
|
|
11805
|
+
mode: z9.string().optional(),
|
|
11806
|
+
voice_description: z9.string().optional(),
|
|
11807
|
+
persona: z9.string().optional()
|
|
9699
11808
|
}).loose().optional(),
|
|
9700
11809
|
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
9701
11810
|
// first hex is the dominant brand colour); never to drive frame generation.
|
|
9702
|
-
style:
|
|
11811
|
+
style: z9.object({ palette: z9.array(z9.object({ hex: z9.string().optional() }).loose()).optional() }).loose().optional()
|
|
9703
11812
|
}).loose().optional(),
|
|
9704
|
-
scenes:
|
|
11813
|
+
scenes: z9.array(Scene).min(1)
|
|
9705
11814
|
}).loose();
|
|
9706
11815
|
function injectHookPhysicality(blueprint) {
|
|
9707
11816
|
for (const scene of blueprint.scenes) {
|
|
@@ -9711,26 +11820,26 @@ function injectHookPhysicality(blueprint) {
|
|
|
9711
11820
|
scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
|
|
9712
11821
|
}
|
|
9713
11822
|
}
|
|
9714
|
-
var AppearsItem =
|
|
9715
|
-
var RecurringElement =
|
|
11823
|
+
var AppearsItem = z9.union([z9.number(), z9.object({ scene: z9.number(), edge: z9.string().optional() }).loose()]);
|
|
11824
|
+
var RecurringElement = z9.object({
|
|
9716
11825
|
// person | animal | product | logo | badge | other
|
|
9717
|
-
type:
|
|
9718
|
-
label:
|
|
9719
|
-
description:
|
|
9720
|
-
expression:
|
|
11826
|
+
type: z9.string(),
|
|
11827
|
+
label: z9.string().optional(),
|
|
11828
|
+
description: z9.string().optional(),
|
|
11829
|
+
expression: z9.string().nullable().optional(),
|
|
9721
11830
|
// When the element maps to a global cast entry, its stable id (for annotation).
|
|
9722
|
-
cast_id:
|
|
11831
|
+
cast_id: z9.string().nullable().optional(),
|
|
9723
11832
|
// The label of another element that is the SAME individual as this one, shown
|
|
9724
11833
|
// in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
|
|
9725
11834
|
// pink shirt and believer in a white shirt). Each look gets its own reference
|
|
9726
11835
|
// slot, but the face/identity must stay identical across them.
|
|
9727
|
-
same_as:
|
|
11836
|
+
same_as: z9.string().nullable().optional(),
|
|
9728
11837
|
// Scenes the element appears in. Either a bare list of scene indices (both
|
|
9729
11838
|
// edges) or per-{scene,edge} entries. Both forms are accepted and merged.
|
|
9730
|
-
scenes:
|
|
9731
|
-
appears_in:
|
|
11839
|
+
scenes: z9.array(z9.number()).optional(),
|
|
11840
|
+
appears_in: z9.array(AppearsItem).optional()
|
|
9732
11841
|
}).loose();
|
|
9733
|
-
var RecurringElements =
|
|
11842
|
+
var RecurringElements = z9.array(RecurringElement);
|
|
9734
11843
|
function sanitizeId2(raw, fallback) {
|
|
9735
11844
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
9736
11845
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -11193,25 +13302,25 @@ function buildSfxMusic(blueprint, nodes) {
|
|
|
11193
13302
|
}
|
|
11194
13303
|
return tracks;
|
|
11195
13304
|
}
|
|
11196
|
-
var OverlayStyle =
|
|
11197
|
-
var Overlay =
|
|
11198
|
-
text:
|
|
11199
|
-
appears_at_s:
|
|
11200
|
-
duration_s:
|
|
11201
|
-
position:
|
|
11202
|
-
role:
|
|
11203
|
-
animation:
|
|
11204
|
-
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(),
|
|
11205
13314
|
style: OverlayStyle.optional()
|
|
11206
13315
|
}).loose();
|
|
11207
|
-
var FloatingElement =
|
|
11208
|
-
kind:
|
|
11209
|
-
description:
|
|
11210
|
-
brand_name:
|
|
11211
|
-
what_it_represents:
|
|
11212
|
-
appears_at_s:
|
|
11213
|
-
duration_s:
|
|
11214
|
-
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()
|
|
11215
13324
|
}).loose();
|
|
11216
13325
|
function escapeHtml(s) {
|
|
11217
13326
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -11243,7 +13352,7 @@ function positionClass(position) {
|
|
|
11243
13352
|
function collectCaptions(blueprint) {
|
|
11244
13353
|
return blueprint.scenes.flatMap((scene) => {
|
|
11245
13354
|
const sceneStart = scene.start_s ?? 0;
|
|
11246
|
-
const overlays =
|
|
13355
|
+
const overlays = z9.array(Overlay).safeParse(scene.overlays ?? []);
|
|
11247
13356
|
return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
|
|
11248
13357
|
const at = ov.appears_at_s ?? sceneStart;
|
|
11249
13358
|
return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
|
|
@@ -11352,7 +13461,7 @@ function buildOverlayHtml(input) {
|
|
|
11352
13461
|
if (ovParts.length > 0) blocks.push(ovParts.join("\n"));
|
|
11353
13462
|
for (const scene of blueprint.scenes) {
|
|
11354
13463
|
const sceneStart = scene.start_s ?? 0;
|
|
11355
|
-
const floats =
|
|
13464
|
+
const floats = z9.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
11356
13465
|
const parts = (floats.success ? floats.data.map((fe) => floatingStub(fe, sceneStart)) : []).filter(Boolean);
|
|
11357
13466
|
const pip = uiPipStub(scene);
|
|
11358
13467
|
if (pip) parts.push(pip);
|
|
@@ -11609,8 +13718,8 @@ function buildMotionBoard(blueprint) {
|
|
|
11609
13718
|
const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
|
|
11610
13719
|
cursor = end_s;
|
|
11611
13720
|
const spoken = sceneSpokenText(scene);
|
|
11612
|
-
const overlays =
|
|
11613
|
-
const floats =
|
|
13721
|
+
const overlays = z9.array(Overlay).safeParse(scene.overlays ?? []);
|
|
13722
|
+
const floats = z9.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
11614
13723
|
const graphics = [
|
|
11615
13724
|
...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
|
|
11616
13725
|
kind: "text",
|
|
@@ -12051,7 +14160,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
12051
14160
|
return fail2("deconstruct", e instanceof Error ? e.message : String(e));
|
|
12052
14161
|
}
|
|
12053
14162
|
}
|
|
12054
|
-
var scaffoldVideoCommand =
|
|
14163
|
+
var scaffoldVideoCommand = defineCommand85({
|
|
12055
14164
|
meta: {
|
|
12056
14165
|
name: "scaffold-video",
|
|
12057
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`."
|
|
@@ -12196,7 +14305,7 @@ var scaffoldVideoCommand = defineCommand83({
|
|
|
12196
14305
|
// src/commands/canvas/set-prompt.ts
|
|
12197
14306
|
import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
12198
14307
|
import path9 from "path";
|
|
12199
|
-
import { defineCommand as
|
|
14308
|
+
import { defineCommand as defineCommand86 } from "citty";
|
|
12200
14309
|
function setNodePrompt(canvas, nodeId, text) {
|
|
12201
14310
|
const nodes = canvas?.nodes;
|
|
12202
14311
|
if (!Array.isArray(nodes)) throw new Error("canvas has no nodes array");
|
|
@@ -12211,7 +14320,7 @@ function setNodePrompt(canvas, nodeId, text) {
|
|
|
12211
14320
|
newNodes[idx] = newNode;
|
|
12212
14321
|
return { ...canvas, nodes: newNodes };
|
|
12213
14322
|
}
|
|
12214
|
-
var setPromptCommand =
|
|
14323
|
+
var setPromptCommand = defineCommand86({
|
|
12215
14324
|
meta: {
|
|
12216
14325
|
name: "set-prompt",
|
|
12217
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."
|
|
@@ -12271,8 +14380,8 @@ var setPromptCommand = defineCommand84({
|
|
|
12271
14380
|
// src/commands/canvas/validate.ts
|
|
12272
14381
|
import { readFile as readFile8 } from "fs/promises";
|
|
12273
14382
|
import path10 from "path";
|
|
12274
|
-
import { defineCommand as
|
|
12275
|
-
var validateCommand =
|
|
14383
|
+
import { defineCommand as defineCommand87 } from "citty";
|
|
14384
|
+
var validateCommand = defineCommand87({
|
|
12276
14385
|
meta: {
|
|
12277
14386
|
name: "validate",
|
|
12278
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)."
|
|
@@ -12315,7 +14424,7 @@ var validateCommand = defineCommand85({
|
|
|
12315
14424
|
});
|
|
12316
14425
|
|
|
12317
14426
|
// src/commands/canvas/index.ts
|
|
12318
|
-
var canvasCommand =
|
|
14427
|
+
var canvasCommand = defineCommand88({
|
|
12319
14428
|
meta: {
|
|
12320
14429
|
name: "canvas",
|
|
12321
14430
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -12342,10 +14451,10 @@ Subcommands:
|
|
|
12342
14451
|
});
|
|
12343
14452
|
|
|
12344
14453
|
// src/commands/creatives/index.ts
|
|
12345
|
-
import { defineCommand as
|
|
14454
|
+
import { defineCommand as defineCommand90 } from "citty";
|
|
12346
14455
|
|
|
12347
14456
|
// src/commands/creatives/publish.ts
|
|
12348
|
-
import { defineCommand as
|
|
14457
|
+
import { defineCommand as defineCommand89 } from "citty";
|
|
12349
14458
|
|
|
12350
14459
|
// src/commands/images/api.ts
|
|
12351
14460
|
import { readFile as readFile9 } from "fs/promises";
|
|
@@ -12401,7 +14510,7 @@ async function waitForReadyImage(deps, imageId, opts = {}) {
|
|
|
12401
14510
|
let lastStatus = "unknown";
|
|
12402
14511
|
while (Date.now() <= deadline) {
|
|
12403
14512
|
const image = await getImage(deps, imageId);
|
|
12404
|
-
lastStatus = image.status
|
|
14513
|
+
lastStatus = image.status;
|
|
12405
14514
|
if (image.status === "ready") {
|
|
12406
14515
|
return image;
|
|
12407
14516
|
}
|
|
@@ -12468,7 +14577,7 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
12468
14577
|
sourceReferenceUrl
|
|
12469
14578
|
});
|
|
12470
14579
|
}
|
|
12471
|
-
var publishCommand =
|
|
14580
|
+
var publishCommand = defineCommand89({
|
|
12472
14581
|
meta: {
|
|
12473
14582
|
name: "publish",
|
|
12474
14583
|
description: "Publish a final static creative image to Baker Creatives and print the creative reference JSON."
|
|
@@ -12514,7 +14623,7 @@ var publishCommand = defineCommand87({
|
|
|
12514
14623
|
});
|
|
12515
14624
|
|
|
12516
14625
|
// src/commands/creatives/index.ts
|
|
12517
|
-
var creativesCommand3 =
|
|
14626
|
+
var creativesCommand3 = defineCommand90({
|
|
12518
14627
|
meta: {
|
|
12519
14628
|
name: "creatives",
|
|
12520
14629
|
description: `Publish static ad creatives as first-class Baker outputs.
|
|
@@ -12530,10 +14639,10 @@ Publishing uploads the image to the Company image library, applies the official
|
|
|
12530
14639
|
});
|
|
12531
14640
|
|
|
12532
14641
|
// src/commands/ga4/index.ts
|
|
12533
|
-
import { defineCommand as
|
|
14642
|
+
import { defineCommand as defineCommand94 } from "citty";
|
|
12534
14643
|
|
|
12535
14644
|
// src/commands/ga4/audit.ts
|
|
12536
|
-
import { defineCommand as
|
|
14645
|
+
import { defineCommand as defineCommand91 } from "citty";
|
|
12537
14646
|
|
|
12538
14647
|
// src/commands/ga4/resolve.ts
|
|
12539
14648
|
async function fetchProperties(useCache = true) {
|
|
@@ -12596,7 +14705,7 @@ registerSchema({
|
|
|
12596
14705
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12597
14706
|
}
|
|
12598
14707
|
});
|
|
12599
|
-
var auditCommand2 =
|
|
14708
|
+
var auditCommand2 = defineCommand91({
|
|
12600
14709
|
meta: {
|
|
12601
14710
|
name: "audit",
|
|
12602
14711
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -12648,7 +14757,7 @@ Examples:
|
|
|
12648
14757
|
});
|
|
12649
14758
|
|
|
12650
14759
|
// src/commands/ga4/properties.ts
|
|
12651
|
-
import { defineCommand as
|
|
14760
|
+
import { defineCommand as defineCommand92 } from "citty";
|
|
12652
14761
|
registerSchema({
|
|
12653
14762
|
command: "ga4.properties",
|
|
12654
14763
|
description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
|
|
@@ -12656,7 +14765,7 @@ registerSchema({
|
|
|
12656
14765
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
12657
14766
|
}
|
|
12658
14767
|
});
|
|
12659
|
-
var propertiesCommand =
|
|
14768
|
+
var propertiesCommand = defineCommand92({
|
|
12660
14769
|
meta: {
|
|
12661
14770
|
name: "properties",
|
|
12662
14771
|
description: `List accessible GA4 properties.
|
|
@@ -12704,9 +14813,9 @@ Examples:
|
|
|
12704
14813
|
});
|
|
12705
14814
|
|
|
12706
14815
|
// src/commands/ga4/query.ts
|
|
12707
|
-
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";
|
|
12708
14817
|
import { resolve as resolve2 } from "path";
|
|
12709
|
-
import { defineCommand as
|
|
14818
|
+
import { defineCommand as defineCommand93 } from "citty";
|
|
12710
14819
|
|
|
12711
14820
|
// src/commands/ga4/presets.ts
|
|
12712
14821
|
var GA4_PRESETS = [
|
|
@@ -12795,7 +14904,7 @@ function writeRowsToFile2(filePath, rows, append) {
|
|
|
12795
14904
|
writeFileSync4(filePath, content, "utf-8");
|
|
12796
14905
|
}
|
|
12797
14906
|
} else if (append && existsSync5(filePath)) {
|
|
12798
|
-
const existing = JSON.parse(
|
|
14907
|
+
const existing = JSON.parse(readFileSync8(filePath, "utf-8"));
|
|
12799
14908
|
writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
12800
14909
|
} else {
|
|
12801
14910
|
writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -12838,7 +14947,7 @@ function handleError(err) {
|
|
|
12838
14947
|
});
|
|
12839
14948
|
process.exit(1);
|
|
12840
14949
|
}
|
|
12841
|
-
var queryCommand2 =
|
|
14950
|
+
var queryCommand2 = defineCommand93({
|
|
12842
14951
|
meta: {
|
|
12843
14952
|
name: "query",
|
|
12844
14953
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -12909,7 +15018,7 @@ Free-form (escape hatch):
|
|
|
12909
15018
|
});
|
|
12910
15019
|
|
|
12911
15020
|
// src/commands/ga4/index.ts
|
|
12912
|
-
var ga4Command =
|
|
15021
|
+
var ga4Command = defineCommand94({
|
|
12913
15022
|
meta: {
|
|
12914
15023
|
name: "ga4",
|
|
12915
15024
|
description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
|
|
@@ -12932,12 +15041,12 @@ Examples:
|
|
|
12932
15041
|
});
|
|
12933
15042
|
|
|
12934
15043
|
// src/commands/gsc/index.ts
|
|
12935
|
-
import { defineCommand as
|
|
15044
|
+
import { defineCommand as defineCommand98 } from "citty";
|
|
12936
15045
|
|
|
12937
15046
|
// src/commands/gsc/query.ts
|
|
12938
|
-
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";
|
|
12939
15048
|
import { resolve as resolve3 } from "path";
|
|
12940
|
-
import { defineCommand as
|
|
15049
|
+
import { defineCommand as defineCommand95 } from "citty";
|
|
12941
15050
|
|
|
12942
15051
|
// src/commands/gsc/presets.ts
|
|
12943
15052
|
var GSC_PRESETS = [
|
|
@@ -13080,7 +15189,7 @@ function writeRowsToFile3(filePath, rows, append) {
|
|
|
13080
15189
|
writeFileSync5(filePath, content, "utf-8");
|
|
13081
15190
|
}
|
|
13082
15191
|
} else if (append && existsSync6(filePath)) {
|
|
13083
|
-
const existing = JSON.parse(
|
|
15192
|
+
const existing = JSON.parse(readFileSync9(filePath, "utf-8"));
|
|
13084
15193
|
writeFileSync5(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
13085
15194
|
} else {
|
|
13086
15195
|
writeFileSync5(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -13125,7 +15234,7 @@ function handleError2(err) {
|
|
|
13125
15234
|
});
|
|
13126
15235
|
process.exit(1);
|
|
13127
15236
|
}
|
|
13128
|
-
var queryCommand3 =
|
|
15237
|
+
var queryCommand3 = defineCommand95({
|
|
13129
15238
|
meta: {
|
|
13130
15239
|
name: "query",
|
|
13131
15240
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -13203,7 +15312,7 @@ Free-form (escape hatch):
|
|
|
13203
15312
|
});
|
|
13204
15313
|
|
|
13205
15314
|
// src/commands/gsc/sitemaps.ts
|
|
13206
|
-
import { defineCommand as
|
|
15315
|
+
import { defineCommand as defineCommand96 } from "citty";
|
|
13207
15316
|
registerSchema({
|
|
13208
15317
|
command: "gsc.sitemaps",
|
|
13209
15318
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -13212,7 +15321,7 @@ registerSchema({
|
|
|
13212
15321
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
13213
15322
|
}
|
|
13214
15323
|
});
|
|
13215
|
-
var sitemapsCommand =
|
|
15324
|
+
var sitemapsCommand = defineCommand96({
|
|
13216
15325
|
meta: {
|
|
13217
15326
|
name: "sitemaps",
|
|
13218
15327
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -13262,7 +15371,7 @@ Examples:
|
|
|
13262
15371
|
});
|
|
13263
15372
|
|
|
13264
15373
|
// src/commands/gsc/sites.ts
|
|
13265
|
-
import { defineCommand as
|
|
15374
|
+
import { defineCommand as defineCommand97 } from "citty";
|
|
13266
15375
|
registerSchema({
|
|
13267
15376
|
command: "gsc.sites",
|
|
13268
15377
|
description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
|
|
@@ -13270,7 +15379,7 @@ registerSchema({
|
|
|
13270
15379
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
13271
15380
|
}
|
|
13272
15381
|
});
|
|
13273
|
-
var sitesCommand =
|
|
15382
|
+
var sitesCommand = defineCommand97({
|
|
13274
15383
|
meta: {
|
|
13275
15384
|
name: "sites",
|
|
13276
15385
|
description: `List verified Search Console sites.
|
|
@@ -13318,7 +15427,7 @@ Examples:
|
|
|
13318
15427
|
});
|
|
13319
15428
|
|
|
13320
15429
|
// src/commands/gsc/index.ts
|
|
13321
|
-
var gscCommand =
|
|
15430
|
+
var gscCommand = defineCommand98({
|
|
13322
15431
|
meta: {
|
|
13323
15432
|
name: "gsc",
|
|
13324
15433
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -13341,10 +15450,10 @@ Examples:
|
|
|
13341
15450
|
});
|
|
13342
15451
|
|
|
13343
15452
|
// src/commands/images/index.ts
|
|
13344
|
-
import { defineCommand as
|
|
15453
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
13345
15454
|
|
|
13346
15455
|
// src/commands/images/crop.ts
|
|
13347
|
-
import { defineCommand as
|
|
15456
|
+
import { defineCommand as defineCommand99 } from "citty";
|
|
13348
15457
|
|
|
13349
15458
|
// src/lib/image/crop-sprite.ts
|
|
13350
15459
|
import sharp from "sharp";
|
|
@@ -13469,7 +15578,7 @@ function emitError2(err) {
|
|
|
13469
15578
|
}
|
|
13470
15579
|
process.exit(1);
|
|
13471
15580
|
}
|
|
13472
|
-
var cropCommand =
|
|
15581
|
+
var cropCommand = defineCommand99({
|
|
13473
15582
|
meta: {
|
|
13474
15583
|
name: "crop",
|
|
13475
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"
|
|
@@ -13505,7 +15614,7 @@ var cropCommand = defineCommand97({
|
|
|
13505
15614
|
});
|
|
13506
15615
|
|
|
13507
15616
|
// src/commands/images/delete.ts
|
|
13508
|
-
import { defineCommand as
|
|
15617
|
+
import { defineCommand as defineCommand100 } from "citty";
|
|
13509
15618
|
registerSchema({
|
|
13510
15619
|
command: "images.delete",
|
|
13511
15620
|
description: "Delete an image by ID",
|
|
@@ -13519,7 +15628,7 @@ registerSchema({
|
|
|
13519
15628
|
}
|
|
13520
15629
|
}
|
|
13521
15630
|
});
|
|
13522
|
-
var deleteCommand =
|
|
15631
|
+
var deleteCommand = defineCommand100({
|
|
13523
15632
|
meta: {
|
|
13524
15633
|
name: "delete",
|
|
13525
15634
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -13560,7 +15669,7 @@ var deleteCommand = defineCommand98({
|
|
|
13560
15669
|
});
|
|
13561
15670
|
|
|
13562
15671
|
// src/commands/images/dimensions.ts
|
|
13563
|
-
import { defineCommand as
|
|
15672
|
+
import { defineCommand as defineCommand101 } from "citty";
|
|
13564
15673
|
|
|
13565
15674
|
// src/lib/image/dimensions.ts
|
|
13566
15675
|
import { imageSize } from "image-size";
|
|
@@ -13583,7 +15692,7 @@ registerSchema({
|
|
|
13583
15692
|
target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
|
|
13584
15693
|
}
|
|
13585
15694
|
});
|
|
13586
|
-
var dimensionsCommand =
|
|
15695
|
+
var dimensionsCommand = defineCommand101({
|
|
13587
15696
|
meta: {
|
|
13588
15697
|
name: "dimensions",
|
|
13589
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"
|
|
@@ -13627,7 +15736,7 @@ var dimensionsCommand = defineCommand99({
|
|
|
13627
15736
|
});
|
|
13628
15737
|
|
|
13629
15738
|
// src/commands/images/extract.ts
|
|
13630
|
-
import { defineCommand as
|
|
15739
|
+
import { defineCommand as defineCommand102 } from "citty";
|
|
13631
15740
|
registerSchema({
|
|
13632
15741
|
command: "images.extract",
|
|
13633
15742
|
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
@@ -13643,7 +15752,7 @@ registerSchema({
|
|
|
13643
15752
|
}
|
|
13644
15753
|
}
|
|
13645
15754
|
});
|
|
13646
|
-
var extractCommand =
|
|
15755
|
+
var extractCommand = defineCommand102({
|
|
13647
15756
|
meta: {
|
|
13648
15757
|
name: "extract",
|
|
13649
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"
|
|
@@ -13681,7 +15790,7 @@ var extractCommand = defineCommand100({
|
|
|
13681
15790
|
});
|
|
13682
15791
|
|
|
13683
15792
|
// src/commands/images/find.ts
|
|
13684
|
-
import { defineCommand as
|
|
15793
|
+
import { defineCommand as defineCommand103 } from "citty";
|
|
13685
15794
|
registerSchema({
|
|
13686
15795
|
command: "images.find",
|
|
13687
15796
|
description: "Fanout image search: library first, then opted-in external providers.",
|
|
@@ -13713,7 +15822,7 @@ registerSchema({
|
|
|
13713
15822
|
}
|
|
13714
15823
|
}
|
|
13715
15824
|
});
|
|
13716
|
-
var findCommand =
|
|
15825
|
+
var findCommand = defineCommand103({
|
|
13717
15826
|
meta: {
|
|
13718
15827
|
name: "find",
|
|
13719
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"
|
|
@@ -13739,7 +15848,9 @@ var findCommand = defineCommand101({
|
|
|
13739
15848
|
process.exit(1);
|
|
13740
15849
|
}
|
|
13741
15850
|
const body = { query };
|
|
13742
|
-
if (args.sources)
|
|
15851
|
+
if (args.sources) {
|
|
15852
|
+
body.sources = args.sources.split(",").filter(Boolean);
|
|
15853
|
+
}
|
|
13743
15854
|
if (args.limit) body.limit = Number(args.limit);
|
|
13744
15855
|
if (args.fallback) body.fallback = true;
|
|
13745
15856
|
if (args.threshold) body.threshold = Number(args.threshold);
|
|
@@ -13760,7 +15871,7 @@ var findCommand = defineCommand101({
|
|
|
13760
15871
|
|
|
13761
15872
|
// src/commands/images/generate.ts
|
|
13762
15873
|
import { readFile as readFile11 } from "fs/promises";
|
|
13763
|
-
import { defineCommand as
|
|
15874
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
13764
15875
|
import sharp2 from "sharp";
|
|
13765
15876
|
var GENERATE_TIMEOUT_MS = 18e4;
|
|
13766
15877
|
var REFERENCE_MAX_EDGE = 1536;
|
|
@@ -13826,8 +15937,15 @@ function buildGenerateBody(args, prompt) {
|
|
|
13826
15937
|
if (args["aspect-ratio"]) body.aspectRatio = args["aspect-ratio"];
|
|
13827
15938
|
if (args["image-size"]) body.imageSize = args["image-size"];
|
|
13828
15939
|
if (args.strength !== void 0) body.strength = Number(args.strength);
|
|
13829
|
-
if (args["rgb-colors"])
|
|
13830
|
-
|
|
15940
|
+
if (args["rgb-colors"]) {
|
|
15941
|
+
body.rgbColors = parseJsonArg(args["rgb-colors"], "rgb-colors");
|
|
15942
|
+
}
|
|
15943
|
+
if (args["bg-rgb"]) {
|
|
15944
|
+
body.backgroundRgbColor = parseJsonArg(
|
|
15945
|
+
args["bg-rgb"],
|
|
15946
|
+
"bg-rgb"
|
|
15947
|
+
);
|
|
15948
|
+
}
|
|
13831
15949
|
if (args.context) body.descriptionContext = args.context;
|
|
13832
15950
|
return body;
|
|
13833
15951
|
}
|
|
@@ -13856,7 +15974,7 @@ async function resolveReferences(spec) {
|
|
|
13856
15974
|
}
|
|
13857
15975
|
return out;
|
|
13858
15976
|
}
|
|
13859
|
-
var generateCommand =
|
|
15977
|
+
var generateCommand = defineCommand104({
|
|
13860
15978
|
meta: {
|
|
13861
15979
|
name: "generate",
|
|
13862
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]]'"
|
|
@@ -13908,7 +16026,7 @@ var generateCommand = defineCommand102({
|
|
|
13908
16026
|
});
|
|
13909
16027
|
|
|
13910
16028
|
// src/commands/images/get.ts
|
|
13911
|
-
import { defineCommand as
|
|
16029
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
13912
16030
|
registerSchema({
|
|
13913
16031
|
command: "images.get",
|
|
13914
16032
|
description: "Get a single image by ID",
|
|
@@ -13916,7 +16034,7 @@ registerSchema({
|
|
|
13916
16034
|
id: { type: "string", description: "Image ID", required: true }
|
|
13917
16035
|
}
|
|
13918
16036
|
});
|
|
13919
|
-
var getCommand2 =
|
|
16037
|
+
var getCommand2 = defineCommand105({
|
|
13920
16038
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
13921
16039
|
args: {
|
|
13922
16040
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -13952,7 +16070,7 @@ var getCommand2 = defineCommand103({
|
|
|
13952
16070
|
});
|
|
13953
16071
|
|
|
13954
16072
|
// src/commands/images/gif.ts
|
|
13955
|
-
import { defineCommand as
|
|
16073
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
13956
16074
|
registerSchema({
|
|
13957
16075
|
command: "images.gif",
|
|
13958
16076
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -13984,7 +16102,7 @@ registerSchema({
|
|
|
13984
16102
|
}
|
|
13985
16103
|
}
|
|
13986
16104
|
});
|
|
13987
|
-
var gifCommand =
|
|
16105
|
+
var gifCommand = defineCommand106({
|
|
13988
16106
|
meta: {
|
|
13989
16107
|
name: "gif",
|
|
13990
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"
|
|
@@ -14031,7 +16149,7 @@ var gifCommand = defineCommand104({
|
|
|
14031
16149
|
});
|
|
14032
16150
|
|
|
14033
16151
|
// src/commands/images/google.ts
|
|
14034
|
-
import { defineCommand as
|
|
16152
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
14035
16153
|
registerSchema({
|
|
14036
16154
|
command: "images.google",
|
|
14037
16155
|
description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
|
|
@@ -14067,7 +16185,7 @@ registerSchema({
|
|
|
14067
16185
|
}
|
|
14068
16186
|
}
|
|
14069
16187
|
});
|
|
14070
|
-
var googleCommand2 =
|
|
16188
|
+
var googleCommand2 = defineCommand107({
|
|
14071
16189
|
meta: {
|
|
14072
16190
|
name: "google",
|
|
14073
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"
|
|
@@ -14115,7 +16233,7 @@ var googleCommand2 = defineCommand105({
|
|
|
14115
16233
|
});
|
|
14116
16234
|
|
|
14117
16235
|
// src/commands/images/icon.ts
|
|
14118
|
-
import { defineCommand as
|
|
16236
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
14119
16237
|
registerSchema({
|
|
14120
16238
|
command: "images.icon",
|
|
14121
16239
|
description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
|
|
@@ -14141,7 +16259,7 @@ registerSchema({
|
|
|
14141
16259
|
}
|
|
14142
16260
|
}
|
|
14143
16261
|
});
|
|
14144
|
-
var iconCommand =
|
|
16262
|
+
var iconCommand = defineCommand108({
|
|
14145
16263
|
meta: {
|
|
14146
16264
|
name: "icon",
|
|
14147
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'"
|
|
@@ -14181,7 +16299,7 @@ var iconCommand = defineCommand106({
|
|
|
14181
16299
|
});
|
|
14182
16300
|
|
|
14183
16301
|
// src/commands/images/ingest.ts
|
|
14184
|
-
import { defineCommand as
|
|
16302
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
14185
16303
|
registerSchema({
|
|
14186
16304
|
command: "images.ingest",
|
|
14187
16305
|
description: "Ingest a remote image URL into the library (full describe + embed).",
|
|
@@ -14193,7 +16311,7 @@ registerSchema({
|
|
|
14193
16311
|
context: { type: "string", description: "Description context hint", required: false }
|
|
14194
16312
|
}
|
|
14195
16313
|
});
|
|
14196
|
-
var ingestCommand =
|
|
16314
|
+
var ingestCommand = defineCommand109({
|
|
14197
16315
|
meta: {
|
|
14198
16316
|
name: "ingest",
|
|
14199
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"
|
|
@@ -14235,7 +16353,7 @@ var ingestCommand = defineCommand107({
|
|
|
14235
16353
|
});
|
|
14236
16354
|
|
|
14237
16355
|
// src/commands/images/library.ts
|
|
14238
|
-
import { defineCommand as
|
|
16356
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
14239
16357
|
registerSchema({
|
|
14240
16358
|
command: "images.library",
|
|
14241
16359
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -14261,7 +16379,7 @@ registerSchema({
|
|
|
14261
16379
|
}
|
|
14262
16380
|
}
|
|
14263
16381
|
});
|
|
14264
|
-
var libraryCommand =
|
|
16382
|
+
var libraryCommand = defineCommand110({
|
|
14265
16383
|
meta: {
|
|
14266
16384
|
name: "library",
|
|
14267
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"
|
|
@@ -14318,7 +16436,7 @@ var libraryCommand = defineCommand108({
|
|
|
14318
16436
|
});
|
|
14319
16437
|
|
|
14320
16438
|
// src/commands/images/logo.ts
|
|
14321
|
-
import { defineCommand as
|
|
16439
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
14322
16440
|
registerSchema({
|
|
14323
16441
|
command: "images.logo",
|
|
14324
16442
|
description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
|
|
@@ -14343,7 +16461,7 @@ registerSchema({
|
|
|
14343
16461
|
}
|
|
14344
16462
|
}
|
|
14345
16463
|
});
|
|
14346
|
-
var logoCommand =
|
|
16464
|
+
var logoCommand = defineCommand111({
|
|
14347
16465
|
meta: {
|
|
14348
16466
|
name: "logo",
|
|
14349
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"
|
|
@@ -14381,7 +16499,7 @@ var logoCommand = defineCommand109({
|
|
|
14381
16499
|
});
|
|
14382
16500
|
|
|
14383
16501
|
// src/commands/images/normalize.ts
|
|
14384
|
-
import { defineCommand as
|
|
16502
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
14385
16503
|
|
|
14386
16504
|
// src/lib/image/color-changer.ts
|
|
14387
16505
|
import quantize from "quantize";
|
|
@@ -15113,7 +17231,7 @@ function coerceRawArgs(args) {
|
|
|
15113
17231
|
"dry-run": bool(args["dry-run"])
|
|
15114
17232
|
};
|
|
15115
17233
|
}
|
|
15116
|
-
var normalizeCommand =
|
|
17234
|
+
var normalizeCommand = defineCommand112({
|
|
15117
17235
|
meta: {
|
|
15118
17236
|
name: "normalize",
|
|
15119
17237
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -15168,7 +17286,7 @@ Examples:
|
|
|
15168
17286
|
});
|
|
15169
17287
|
|
|
15170
17288
|
// src/commands/images/pinterest.ts
|
|
15171
|
-
import { defineCommand as
|
|
17289
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
15172
17290
|
registerSchema({
|
|
15173
17291
|
command: "images.pinterest",
|
|
15174
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.",
|
|
@@ -15188,7 +17306,7 @@ registerSchema({
|
|
|
15188
17306
|
}
|
|
15189
17307
|
}
|
|
15190
17308
|
});
|
|
15191
|
-
var pinterestCommand =
|
|
17309
|
+
var pinterestCommand = defineCommand113({
|
|
15192
17310
|
meta: {
|
|
15193
17311
|
name: "pinterest",
|
|
15194
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'"
|
|
@@ -15228,7 +17346,7 @@ var pinterestCommand = defineCommand111({
|
|
|
15228
17346
|
});
|
|
15229
17347
|
|
|
15230
17348
|
// src/commands/images/screenshot.ts
|
|
15231
|
-
import { defineCommand as
|
|
17349
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
15232
17350
|
registerSchema({
|
|
15233
17351
|
command: "images.screenshot",
|
|
15234
17352
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -15244,7 +17362,7 @@ registerSchema({
|
|
|
15244
17362
|
}
|
|
15245
17363
|
}
|
|
15246
17364
|
});
|
|
15247
|
-
var screenshotCommand =
|
|
17365
|
+
var screenshotCommand = defineCommand114({
|
|
15248
17366
|
meta: {
|
|
15249
17367
|
name: "screenshot",
|
|
15250
17368
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -15294,7 +17412,7 @@ var screenshotCommand = defineCommand112({
|
|
|
15294
17412
|
});
|
|
15295
17413
|
|
|
15296
17414
|
// src/commands/images/search.ts
|
|
15297
|
-
import { defineCommand as
|
|
17415
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
15298
17416
|
registerSchema({
|
|
15299
17417
|
command: "images.search",
|
|
15300
17418
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -15310,7 +17428,7 @@ registerSchema({
|
|
|
15310
17428
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
15311
17429
|
}
|
|
15312
17430
|
});
|
|
15313
|
-
var searchCommand =
|
|
17431
|
+
var searchCommand = defineCommand115({
|
|
15314
17432
|
meta: {
|
|
15315
17433
|
name: "search",
|
|
15316
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"
|
|
@@ -15370,7 +17488,7 @@ var searchCommand = defineCommand113({
|
|
|
15370
17488
|
});
|
|
15371
17489
|
|
|
15372
17490
|
// src/commands/images/sticker.ts
|
|
15373
|
-
import { defineCommand as
|
|
17491
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
15374
17492
|
registerSchema({
|
|
15375
17493
|
command: "images.sticker",
|
|
15376
17494
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -15402,7 +17520,7 @@ registerSchema({
|
|
|
15402
17520
|
}
|
|
15403
17521
|
}
|
|
15404
17522
|
});
|
|
15405
|
-
var stickerCommand =
|
|
17523
|
+
var stickerCommand = defineCommand116({
|
|
15406
17524
|
meta: {
|
|
15407
17525
|
name: "sticker",
|
|
15408
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"
|
|
@@ -15449,7 +17567,7 @@ var stickerCommand = defineCommand114({
|
|
|
15449
17567
|
});
|
|
15450
17568
|
|
|
15451
17569
|
// src/commands/images/stock.ts
|
|
15452
|
-
import { defineCommand as
|
|
17570
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
15453
17571
|
registerSchema({
|
|
15454
17572
|
command: "images.stock",
|
|
15455
17573
|
description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
|
|
@@ -15507,7 +17625,7 @@ registerSchema({
|
|
|
15507
17625
|
}
|
|
15508
17626
|
}
|
|
15509
17627
|
});
|
|
15510
|
-
var stockCommand =
|
|
17628
|
+
var stockCommand = defineCommand117({
|
|
15511
17629
|
meta: {
|
|
15512
17630
|
name: "stock",
|
|
15513
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"
|
|
@@ -15563,7 +17681,7 @@ var stockCommand = defineCommand115({
|
|
|
15563
17681
|
});
|
|
15564
17682
|
|
|
15565
17683
|
// src/lib/tags-command.ts
|
|
15566
|
-
import { defineCommand as
|
|
17684
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
15567
17685
|
function makeTagsCommand(command, label, endpoint) {
|
|
15568
17686
|
registerSchema({
|
|
15569
17687
|
command: `${command}.tags`,
|
|
@@ -15572,7 +17690,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
15572
17690
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
15573
17691
|
}
|
|
15574
17692
|
});
|
|
15575
|
-
return
|
|
17693
|
+
return defineCommand118({
|
|
15576
17694
|
meta: {
|
|
15577
17695
|
name: "tags",
|
|
15578
17696
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -15608,7 +17726,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
15608
17726
|
var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
15609
17727
|
|
|
15610
17728
|
// src/commands/images/upload.ts
|
|
15611
|
-
import { defineCommand as
|
|
17729
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
15612
17730
|
registerSchema({
|
|
15613
17731
|
command: "images.upload",
|
|
15614
17732
|
description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
|
|
@@ -15646,7 +17764,7 @@ registerSchema({
|
|
|
15646
17764
|
function isRemoteUrl2(value) {
|
|
15647
17765
|
return /^https?:\/\//i.test(value);
|
|
15648
17766
|
}
|
|
15649
|
-
var uploadCommand =
|
|
17767
|
+
var uploadCommand = defineCommand119({
|
|
15650
17768
|
meta: {
|
|
15651
17769
|
name: "upload",
|
|
15652
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'"
|
|
@@ -15739,7 +17857,7 @@ async function uploadLocal(target, args) {
|
|
|
15739
17857
|
}
|
|
15740
17858
|
|
|
15741
17859
|
// src/commands/images/upscale.ts
|
|
15742
|
-
import { defineCommand as
|
|
17860
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
15743
17861
|
registerSchema({
|
|
15744
17862
|
command: "images.upscale",
|
|
15745
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).",
|
|
@@ -15754,7 +17872,7 @@ registerSchema({
|
|
|
15754
17872
|
}
|
|
15755
17873
|
});
|
|
15756
17874
|
var POLL_INTERVAL_MS3 = 1500;
|
|
15757
|
-
var upscaleCommand =
|
|
17875
|
+
var upscaleCommand = defineCommand120({
|
|
15758
17876
|
meta: {
|
|
15759
17877
|
name: "upscale",
|
|
15760
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"
|
|
@@ -15783,10 +17901,10 @@ var upscaleCommand = defineCommand118({
|
|
|
15783
17901
|
writeJson({ ok: true, data: { imageId, status: "completed", image: doc } });
|
|
15784
17902
|
return;
|
|
15785
17903
|
}
|
|
15786
|
-
if (doc.upscaleConfig
|
|
17904
|
+
if (!doc.upscaleConfig) {
|
|
15787
17905
|
writeJson({
|
|
15788
17906
|
ok: false,
|
|
15789
|
-
error: { code: "IMAGE_PROCESSING_ERROR", message:
|
|
17907
|
+
error: { code: "IMAGE_PROCESSING_ERROR", message: "Upscale failed" }
|
|
15790
17908
|
});
|
|
15791
17909
|
process.exit(1);
|
|
15792
17910
|
}
|
|
@@ -15809,7 +17927,7 @@ var upscaleCommand = defineCommand118({
|
|
|
15809
17927
|
});
|
|
15810
17928
|
|
|
15811
17929
|
// src/commands/images/use.ts
|
|
15812
|
-
import { defineCommand as
|
|
17930
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
15813
17931
|
registerSchema({
|
|
15814
17932
|
command: "images.use",
|
|
15815
17933
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -15825,7 +17943,7 @@ registerSchema({
|
|
|
15825
17943
|
}
|
|
15826
17944
|
});
|
|
15827
17945
|
var POLL_INTERVAL_MS4 = 1500;
|
|
15828
|
-
var useCommand =
|
|
17946
|
+
var useCommand = defineCommand121({
|
|
15829
17947
|
meta: {
|
|
15830
17948
|
name: "use",
|
|
15831
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"
|
|
@@ -15871,7 +17989,7 @@ var useCommand = defineCommand119({
|
|
|
15871
17989
|
});
|
|
15872
17990
|
|
|
15873
17991
|
// src/commands/images/index.ts
|
|
15874
|
-
var imagesCommand =
|
|
17992
|
+
var imagesCommand = defineCommand122({
|
|
15875
17993
|
meta: {
|
|
15876
17994
|
name: "images",
|
|
15877
17995
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -15941,10 +18059,10 @@ Paid transforms (run on the Convex backend, cost-tracked):
|
|
|
15941
18059
|
});
|
|
15942
18060
|
|
|
15943
18061
|
// src/commands/research/index.ts
|
|
15944
|
-
import { defineCommand as
|
|
18062
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
15945
18063
|
|
|
15946
18064
|
// src/commands/research/advertisers.ts
|
|
15947
|
-
import { defineCommand as
|
|
18065
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
15948
18066
|
|
|
15949
18067
|
// src/commands/research/output.ts
|
|
15950
18068
|
var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
|
|
@@ -16057,7 +18175,7 @@ var FIELDS3 = {
|
|
|
16057
18175
|
etv: "Estimated traffic value (USD)",
|
|
16058
18176
|
visibility: "SERP visibility score (0-1)"
|
|
16059
18177
|
};
|
|
16060
|
-
var advertisersCommand =
|
|
18178
|
+
var advertisersCommand = defineCommand123({
|
|
16061
18179
|
meta: {
|
|
16062
18180
|
name: "advertisers",
|
|
16063
18181
|
description: `Find domains competing for a keyword in Google SERPs.
|
|
@@ -16104,7 +18222,7 @@ Examples:
|
|
|
16104
18222
|
});
|
|
16105
18223
|
|
|
16106
18224
|
// src/commands/research/autocomplete.ts
|
|
16107
|
-
import { defineCommand as
|
|
18225
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
16108
18226
|
registerSchema({
|
|
16109
18227
|
command: "research.autocomplete",
|
|
16110
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).",
|
|
@@ -16127,7 +18245,7 @@ registerSchema({
|
|
|
16127
18245
|
var FIELDS4 = {
|
|
16128
18246
|
suggestion: "Autocomplete suggestion from Google"
|
|
16129
18247
|
};
|
|
16130
|
-
var autocompleteCommand =
|
|
18248
|
+
var autocompleteCommand = defineCommand124({
|
|
16131
18249
|
meta: {
|
|
16132
18250
|
name: "autocomplete",
|
|
16133
18251
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -16173,7 +18291,7 @@ Examples:
|
|
|
16173
18291
|
});
|
|
16174
18292
|
|
|
16175
18293
|
// src/commands/research/countries.ts
|
|
16176
|
-
import { defineCommand as
|
|
18294
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
16177
18295
|
registerSchema({
|
|
16178
18296
|
command: "research.countries",
|
|
16179
18297
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -16230,7 +18348,7 @@ var FIELDS5 = {
|
|
|
16230
18348
|
code: "Country code to pass as --location",
|
|
16231
18349
|
name: "Country name"
|
|
16232
18350
|
};
|
|
16233
|
-
var countriesCommand =
|
|
18351
|
+
var countriesCommand = defineCommand125({
|
|
16234
18352
|
meta: {
|
|
16235
18353
|
name: "countries",
|
|
16236
18354
|
description: "List all supported country codes for --location flag."
|
|
@@ -16241,7 +18359,7 @@ var countriesCommand = defineCommand123({
|
|
|
16241
18359
|
});
|
|
16242
18360
|
|
|
16243
18361
|
// src/commands/research/intent.ts
|
|
16244
|
-
import { defineCommand as
|
|
18362
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
16245
18363
|
registerSchema({
|
|
16246
18364
|
command: "research.intent",
|
|
16247
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.",
|
|
@@ -16264,7 +18382,7 @@ var FIELDS6 = {
|
|
|
16264
18382
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
16265
18383
|
probability: "Confidence score 0.0-1.0"
|
|
16266
18384
|
};
|
|
16267
|
-
var intentCommand =
|
|
18385
|
+
var intentCommand = defineCommand126({
|
|
16268
18386
|
meta: {
|
|
16269
18387
|
name: "intent",
|
|
16270
18388
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -16312,7 +18430,7 @@ Examples:
|
|
|
16312
18430
|
});
|
|
16313
18431
|
|
|
16314
18432
|
// src/commands/research/keyword-gap.ts
|
|
16315
|
-
import { defineCommand as
|
|
18433
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
16316
18434
|
registerSchema({
|
|
16317
18435
|
command: "research.keyword-gap",
|
|
16318
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.",
|
|
@@ -16341,7 +18459,7 @@ var FIELDS7 = {
|
|
|
16341
18459
|
cpc: "Cost per click USD",
|
|
16342
18460
|
their_position: "Competitor's ranking position"
|
|
16343
18461
|
};
|
|
16344
|
-
var keywordGapCommand =
|
|
18462
|
+
var keywordGapCommand = defineCommand127({
|
|
16345
18463
|
meta: {
|
|
16346
18464
|
name: "keyword-gap",
|
|
16347
18465
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -16415,7 +18533,7 @@ Examples:
|
|
|
16415
18533
|
});
|
|
16416
18534
|
|
|
16417
18535
|
// src/commands/research/keywords-for-site.ts
|
|
16418
|
-
import { defineCommand as
|
|
18536
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
16419
18537
|
registerSchema({
|
|
16420
18538
|
command: "research.keywords-for-site",
|
|
16421
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.",
|
|
@@ -16448,7 +18566,7 @@ var FIELDS8 = {
|
|
|
16448
18566
|
competition: "LOW, MEDIUM, or HIGH",
|
|
16449
18567
|
competition_index: "Competition score 0-100"
|
|
16450
18568
|
};
|
|
16451
|
-
var keywordsForSiteCommand =
|
|
18569
|
+
var keywordsForSiteCommand = defineCommand128({
|
|
16452
18570
|
meta: {
|
|
16453
18571
|
name: "keywords-for-site",
|
|
16454
18572
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -16501,7 +18619,7 @@ Examples:
|
|
|
16501
18619
|
});
|
|
16502
18620
|
|
|
16503
18621
|
// src/commands/research/languages.ts
|
|
16504
|
-
import { defineCommand as
|
|
18622
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
16505
18623
|
registerSchema({
|
|
16506
18624
|
command: "research.languages",
|
|
16507
18625
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -16531,7 +18649,7 @@ var FIELDS9 = {
|
|
|
16531
18649
|
code: "Language code to pass as --language",
|
|
16532
18650
|
name: "Language name (also accepted by --language)"
|
|
16533
18651
|
};
|
|
16534
|
-
var languagesCommand2 =
|
|
18652
|
+
var languagesCommand2 = defineCommand129({
|
|
16535
18653
|
meta: {
|
|
16536
18654
|
name: "languages",
|
|
16537
18655
|
description: "List all supported language codes for --language flag."
|
|
@@ -16542,7 +18660,7 @@ var languagesCommand2 = defineCommand127({
|
|
|
16542
18660
|
});
|
|
16543
18661
|
|
|
16544
18662
|
// src/commands/research/lighthouse.ts
|
|
16545
|
-
import { defineCommand as
|
|
18663
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
16546
18664
|
registerSchema({
|
|
16547
18665
|
command: "research.lighthouse",
|
|
16548
18666
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -16561,7 +18679,7 @@ var FIELDS10 = {
|
|
|
16561
18679
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
16562
18680
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
16563
18681
|
};
|
|
16564
|
-
var lighthouseCommand =
|
|
18682
|
+
var lighthouseCommand = defineCommand130({
|
|
16565
18683
|
meta: {
|
|
16566
18684
|
name: "lighthouse",
|
|
16567
18685
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -16599,7 +18717,7 @@ Examples:
|
|
|
16599
18717
|
});
|
|
16600
18718
|
|
|
16601
18719
|
// src/commands/research/relevant-pages.ts
|
|
16602
|
-
import { defineCommand as
|
|
18720
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
16603
18721
|
registerSchema({
|
|
16604
18722
|
command: "research.relevant-pages",
|
|
16605
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).",
|
|
@@ -16625,7 +18743,7 @@ var FIELDS11 = {
|
|
|
16625
18743
|
keywords: "Total organic keywords the page ranks for",
|
|
16626
18744
|
top_10: "Keywords in positions 1-10"
|
|
16627
18745
|
};
|
|
16628
|
-
var relevantPagesCommand =
|
|
18746
|
+
var relevantPagesCommand = defineCommand131({
|
|
16629
18747
|
meta: {
|
|
16630
18748
|
name: "relevant-pages",
|
|
16631
18749
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -16671,7 +18789,7 @@ Examples:
|
|
|
16671
18789
|
});
|
|
16672
18790
|
|
|
16673
18791
|
// src/commands/research/web.ts
|
|
16674
|
-
import { defineCommand as
|
|
18792
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
16675
18793
|
registerSchema({
|
|
16676
18794
|
command: "research.web",
|
|
16677
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).",
|
|
@@ -16722,7 +18840,7 @@ async function runDeepResearch(question) {
|
|
|
16722
18840
|
}
|
|
16723
18841
|
throw new Error("Deep research timed out");
|
|
16724
18842
|
}
|
|
16725
|
-
var webCommand =
|
|
18843
|
+
var webCommand = defineCommand132({
|
|
16726
18844
|
meta: {
|
|
16727
18845
|
name: "web",
|
|
16728
18846
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -16782,7 +18900,7 @@ Examples:
|
|
|
16782
18900
|
});
|
|
16783
18901
|
|
|
16784
18902
|
// src/commands/research/index.ts
|
|
16785
|
-
var researchCommand =
|
|
18903
|
+
var researchCommand = defineCommand133({
|
|
16786
18904
|
meta: {
|
|
16787
18905
|
name: "research",
|
|
16788
18906
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -16822,10 +18940,10 @@ Examples:
|
|
|
16822
18940
|
});
|
|
16823
18941
|
|
|
16824
18942
|
// src/commands/scheduled-actions/index.ts
|
|
16825
|
-
import { defineCommand as
|
|
18943
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
16826
18944
|
|
|
16827
18945
|
// src/commands/scheduled-actions/create.ts
|
|
16828
|
-
import { defineCommand as
|
|
18946
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
16829
18947
|
|
|
16830
18948
|
// src/commands/scheduled-actions/shared.ts
|
|
16831
18949
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -16940,7 +19058,7 @@ registerSchema({
|
|
|
16940
19058
|
prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
|
|
16941
19059
|
}
|
|
16942
19060
|
});
|
|
16943
|
-
var createCommand2 =
|
|
19061
|
+
var createCommand2 = defineCommand134({
|
|
16944
19062
|
meta: {
|
|
16945
19063
|
name: "create",
|
|
16946
19064
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -16989,7 +19107,7 @@ var createCommand2 = defineCommand132({
|
|
|
16989
19107
|
});
|
|
16990
19108
|
|
|
16991
19109
|
// src/commands/scheduled-actions/delete.ts
|
|
16992
|
-
import { defineCommand as
|
|
19110
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
16993
19111
|
registerSchema({
|
|
16994
19112
|
command: "scheduled-actions.delete",
|
|
16995
19113
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -16997,7 +19115,7 @@ registerSchema({
|
|
|
16997
19115
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
16998
19116
|
}
|
|
16999
19117
|
});
|
|
17000
|
-
var deleteCommand2 =
|
|
19118
|
+
var deleteCommand2 = defineCommand135({
|
|
17001
19119
|
meta: {
|
|
17002
19120
|
name: "delete",
|
|
17003
19121
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -17026,7 +19144,7 @@ var deleteCommand2 = defineCommand133({
|
|
|
17026
19144
|
});
|
|
17027
19145
|
|
|
17028
19146
|
// src/commands/scheduled-actions/get.ts
|
|
17029
|
-
import { defineCommand as
|
|
19147
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
17030
19148
|
registerSchema({
|
|
17031
19149
|
command: "scheduled-actions.get",
|
|
17032
19150
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -17034,7 +19152,7 @@ registerSchema({
|
|
|
17034
19152
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
17035
19153
|
}
|
|
17036
19154
|
});
|
|
17037
|
-
var getCommand3 =
|
|
19155
|
+
var getCommand3 = defineCommand136({
|
|
17038
19156
|
meta: {
|
|
17039
19157
|
name: "get",
|
|
17040
19158
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -17071,13 +19189,13 @@ var getCommand3 = defineCommand134({
|
|
|
17071
19189
|
});
|
|
17072
19190
|
|
|
17073
19191
|
// src/commands/scheduled-actions/list.ts
|
|
17074
|
-
import { defineCommand as
|
|
19192
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
17075
19193
|
registerSchema({
|
|
17076
19194
|
command: "scheduled-actions.list",
|
|
17077
19195
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
|
|
17078
19196
|
args: {}
|
|
17079
19197
|
});
|
|
17080
|
-
var
|
|
19198
|
+
var listCommand4 = defineCommand137({
|
|
17081
19199
|
meta: {
|
|
17082
19200
|
name: "list",
|
|
17083
19201
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
|
|
@@ -17098,7 +19216,7 @@ var listCommand3 = defineCommand135({
|
|
|
17098
19216
|
});
|
|
17099
19217
|
|
|
17100
19218
|
// src/commands/scheduled-actions/trigger.ts
|
|
17101
|
-
import { defineCommand as
|
|
19219
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
17102
19220
|
registerSchema({
|
|
17103
19221
|
command: "scheduled-actions.trigger",
|
|
17104
19222
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -17106,7 +19224,7 @@ registerSchema({
|
|
|
17106
19224
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
17107
19225
|
}
|
|
17108
19226
|
});
|
|
17109
|
-
var triggerCommand =
|
|
19227
|
+
var triggerCommand = defineCommand138({
|
|
17110
19228
|
meta: {
|
|
17111
19229
|
name: "trigger",
|
|
17112
19230
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -17143,7 +19261,7 @@ var triggerCommand = defineCommand136({
|
|
|
17143
19261
|
});
|
|
17144
19262
|
|
|
17145
19263
|
// src/commands/scheduled-actions/update.ts
|
|
17146
|
-
import { defineCommand as
|
|
19264
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
17147
19265
|
registerSchema({
|
|
17148
19266
|
command: "scheduled-actions.update",
|
|
17149
19267
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -17168,7 +19286,7 @@ registerSchema({
|
|
|
17168
19286
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
17169
19287
|
}
|
|
17170
19288
|
});
|
|
17171
|
-
var updateCommand2 =
|
|
19289
|
+
var updateCommand2 = defineCommand139({
|
|
17172
19290
|
meta: {
|
|
17173
19291
|
name: "update",
|
|
17174
19292
|
description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
|
|
@@ -17239,7 +19357,7 @@ var updateCommand2 = defineCommand137({
|
|
|
17239
19357
|
});
|
|
17240
19358
|
|
|
17241
19359
|
// src/commands/scheduled-actions/index.ts
|
|
17242
|
-
var scheduledActionsCommand =
|
|
19360
|
+
var scheduledActionsCommand = defineCommand140({
|
|
17243
19361
|
meta: {
|
|
17244
19362
|
name: "scheduled-actions",
|
|
17245
19363
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
|
|
@@ -17255,7 +19373,7 @@ Examples:
|
|
|
17255
19373
|
baker scheduled-actions trigger <id>`
|
|
17256
19374
|
},
|
|
17257
19375
|
subCommands: {
|
|
17258
|
-
list:
|
|
19376
|
+
list: listCommand4,
|
|
17259
19377
|
get: getCommand3,
|
|
17260
19378
|
create: createCommand2,
|
|
17261
19379
|
update: updateCommand2,
|
|
@@ -17265,8 +19383,8 @@ Examples:
|
|
|
17265
19383
|
});
|
|
17266
19384
|
|
|
17267
19385
|
// src/commands/schema.ts
|
|
17268
|
-
import { defineCommand as
|
|
17269
|
-
var schemaCommand =
|
|
19386
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
19387
|
+
var schemaCommand = defineCommand141({
|
|
17270
19388
|
meta: {
|
|
17271
19389
|
name: "schema",
|
|
17272
19390
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -17302,10 +19420,10 @@ var schemaCommand = defineCommand139({
|
|
|
17302
19420
|
});
|
|
17303
19421
|
|
|
17304
19422
|
// src/commands/testimonials/index.ts
|
|
17305
|
-
import { defineCommand as
|
|
19423
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
17306
19424
|
|
|
17307
19425
|
// src/commands/testimonials/get.ts
|
|
17308
|
-
import { defineCommand as
|
|
19426
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
17309
19427
|
registerSchema({
|
|
17310
19428
|
command: "testimonials.get",
|
|
17311
19429
|
description: "Get a single testimonial by ID",
|
|
@@ -17313,7 +19431,7 @@ registerSchema({
|
|
|
17313
19431
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
17314
19432
|
}
|
|
17315
19433
|
});
|
|
17316
|
-
var getCommand4 =
|
|
19434
|
+
var getCommand4 = defineCommand142({
|
|
17317
19435
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
17318
19436
|
args: {
|
|
17319
19437
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -17350,7 +19468,7 @@ var getCommand4 = defineCommand140({
|
|
|
17350
19468
|
});
|
|
17351
19469
|
|
|
17352
19470
|
// src/commands/testimonials/list.ts
|
|
17353
|
-
import { defineCommand as
|
|
19471
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
17354
19472
|
registerSchema({
|
|
17355
19473
|
command: "testimonials.list",
|
|
17356
19474
|
description: "List testimonials with optional filters.",
|
|
@@ -17380,7 +19498,7 @@ registerSchema({
|
|
|
17380
19498
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
17381
19499
|
}
|
|
17382
19500
|
});
|
|
17383
|
-
var
|
|
19501
|
+
var listCommand5 = defineCommand143({
|
|
17384
19502
|
meta: {
|
|
17385
19503
|
name: "list",
|
|
17386
19504
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -17429,7 +19547,7 @@ var listCommand4 = defineCommand141({
|
|
|
17429
19547
|
});
|
|
17430
19548
|
|
|
17431
19549
|
// src/commands/testimonials/search.ts
|
|
17432
|
-
import { defineCommand as
|
|
19550
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
17433
19551
|
registerSchema({
|
|
17434
19552
|
command: "testimonials.search",
|
|
17435
19553
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -17460,7 +19578,7 @@ registerSchema({
|
|
|
17460
19578
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
17461
19579
|
}
|
|
17462
19580
|
});
|
|
17463
|
-
var searchCommand2 =
|
|
19581
|
+
var searchCommand2 = defineCommand144({
|
|
17464
19582
|
meta: {
|
|
17465
19583
|
name: "search",
|
|
17466
19584
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -17534,7 +19652,7 @@ var searchCommand2 = defineCommand142({
|
|
|
17534
19652
|
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
17535
19653
|
|
|
17536
19654
|
// src/commands/testimonials/index.ts
|
|
17537
|
-
var testimonialsCommand =
|
|
19655
|
+
var testimonialsCommand = defineCommand145({
|
|
17538
19656
|
meta: {
|
|
17539
19657
|
name: "testimonials",
|
|
17540
19658
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -17549,16 +19667,16 @@ Examples:
|
|
|
17549
19667
|
subCommands: {
|
|
17550
19668
|
get: getCommand4,
|
|
17551
19669
|
search: searchCommand2,
|
|
17552
|
-
list:
|
|
19670
|
+
list: listCommand5,
|
|
17553
19671
|
tags: tagsCommand3
|
|
17554
19672
|
}
|
|
17555
19673
|
});
|
|
17556
19674
|
|
|
17557
19675
|
// src/commands/videos/index.ts
|
|
17558
|
-
import { defineCommand as
|
|
19676
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
17559
19677
|
|
|
17560
19678
|
// src/commands/videos/delete.ts
|
|
17561
|
-
import { defineCommand as
|
|
19679
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
17562
19680
|
registerSchema({
|
|
17563
19681
|
command: "videos.delete",
|
|
17564
19682
|
description: "Delete a video by ID",
|
|
@@ -17572,7 +19690,7 @@ registerSchema({
|
|
|
17572
19690
|
}
|
|
17573
19691
|
}
|
|
17574
19692
|
});
|
|
17575
|
-
var deleteCommand3 =
|
|
19693
|
+
var deleteCommand3 = defineCommand146({
|
|
17576
19694
|
meta: {
|
|
17577
19695
|
name: "delete",
|
|
17578
19696
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -17613,7 +19731,7 @@ var deleteCommand3 = defineCommand144({
|
|
|
17613
19731
|
});
|
|
17614
19732
|
|
|
17615
19733
|
// src/commands/videos/get.ts
|
|
17616
|
-
import { defineCommand as
|
|
19734
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
17617
19735
|
registerSchema({
|
|
17618
19736
|
command: "videos.get",
|
|
17619
19737
|
description: "Get a single video by ID",
|
|
@@ -17621,7 +19739,7 @@ registerSchema({
|
|
|
17621
19739
|
id: { type: "string", description: "Video ID", required: true }
|
|
17622
19740
|
}
|
|
17623
19741
|
});
|
|
17624
|
-
var getCommand5 =
|
|
19742
|
+
var getCommand5 = defineCommand147({
|
|
17625
19743
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
17626
19744
|
args: {
|
|
17627
19745
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -17658,7 +19776,7 @@ var getCommand5 = defineCommand145({
|
|
|
17658
19776
|
});
|
|
17659
19777
|
|
|
17660
19778
|
// src/commands/videos/search.ts
|
|
17661
|
-
import { defineCommand as
|
|
19779
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
17662
19780
|
registerSchema({
|
|
17663
19781
|
command: "videos.search",
|
|
17664
19782
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -17668,7 +19786,7 @@ registerSchema({
|
|
|
17668
19786
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
17669
19787
|
}
|
|
17670
19788
|
});
|
|
17671
|
-
var searchCommand3 =
|
|
19789
|
+
var searchCommand3 = defineCommand148({
|
|
17672
19790
|
meta: {
|
|
17673
19791
|
name: "search",
|
|
17674
19792
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -17720,7 +19838,7 @@ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
17720
19838
|
// src/commands/videos/upload.ts
|
|
17721
19839
|
import { readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
17722
19840
|
import { extname as extname3 } from "path";
|
|
17723
|
-
import { defineCommand as
|
|
19841
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
17724
19842
|
var MIME_MAP = {
|
|
17725
19843
|
".mp4": "video/mp4",
|
|
17726
19844
|
".mov": "video/quicktime",
|
|
@@ -17754,7 +19872,7 @@ function detectContentType(filePath) {
|
|
|
17754
19872
|
}
|
|
17755
19873
|
return mime;
|
|
17756
19874
|
}
|
|
17757
|
-
var uploadCommand2 =
|
|
19875
|
+
var uploadCommand2 = defineCommand149({
|
|
17758
19876
|
meta: {
|
|
17759
19877
|
name: "upload",
|
|
17760
19878
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -17808,7 +19926,7 @@ var uploadCommand2 = defineCommand147({
|
|
|
17808
19926
|
});
|
|
17809
19927
|
|
|
17810
19928
|
// src/commands/videos/index.ts
|
|
17811
|
-
var videosCommand =
|
|
19929
|
+
var videosCommand = defineCommand150({
|
|
17812
19930
|
meta: {
|
|
17813
19931
|
name: "videos",
|
|
17814
19932
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -17831,10 +19949,10 @@ Examples:
|
|
|
17831
19949
|
});
|
|
17832
19950
|
|
|
17833
19951
|
// src/commands/winning-ads/index.ts
|
|
17834
|
-
import { defineCommand as
|
|
19952
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
17835
19953
|
|
|
17836
19954
|
// src/commands/winning-ads/advertisers.ts
|
|
17837
|
-
import { defineCommand as
|
|
19955
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
17838
19956
|
registerSchema({
|
|
17839
19957
|
command: "winning-ads.advertisers",
|
|
17840
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).",
|
|
@@ -17847,7 +19965,7 @@ registerSchema({
|
|
|
17847
19965
|
function identity(record) {
|
|
17848
19966
|
return record;
|
|
17849
19967
|
}
|
|
17850
|
-
var advertisersCommand2 =
|
|
19968
|
+
var advertisersCommand2 = defineCommand151({
|
|
17851
19969
|
meta: {
|
|
17852
19970
|
name: "advertisers",
|
|
17853
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'
|
|
@@ -17898,7 +20016,7 @@ var advertisersCommand2 = defineCommand149({
|
|
|
17898
20016
|
});
|
|
17899
20017
|
|
|
17900
20018
|
// src/commands/winning-ads/search.ts
|
|
17901
|
-
import { defineCommand as
|
|
20019
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
17902
20020
|
registerSchema({
|
|
17903
20021
|
command: "winning-ads.search",
|
|
17904
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.",
|
|
@@ -18006,7 +20124,7 @@ function buildSearchBody(args) {
|
|
|
18006
20124
|
}
|
|
18007
20125
|
return body;
|
|
18008
20126
|
}
|
|
18009
|
-
var searchCommand4 =
|
|
20127
|
+
var searchCommand4 = defineCommand152({
|
|
18010
20128
|
meta: {
|
|
18011
20129
|
name: "search",
|
|
18012
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"
|
|
@@ -18118,7 +20236,7 @@ var searchCommand4 = defineCommand150({
|
|
|
18118
20236
|
});
|
|
18119
20237
|
|
|
18120
20238
|
// src/commands/winning-ads/index.ts
|
|
18121
|
-
var winningAdsCommand =
|
|
20239
|
+
var winningAdsCommand = defineCommand153({
|
|
18122
20240
|
meta: {
|
|
18123
20241
|
name: "winning-ads",
|
|
18124
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.
|
|
@@ -18142,7 +20260,7 @@ Examples:
|
|
|
18142
20260
|
});
|
|
18143
20261
|
|
|
18144
20262
|
// src/version.ts
|
|
18145
|
-
import { readFileSync as
|
|
20263
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
18146
20264
|
function packageJsonUrl() {
|
|
18147
20265
|
return new URL("../package.json", import.meta.url);
|
|
18148
20266
|
}
|
|
@@ -18154,11 +20272,11 @@ function parsePackageVersion(raw) {
|
|
|
18154
20272
|
throw new Error("Invalid CLI package.json: missing version");
|
|
18155
20273
|
}
|
|
18156
20274
|
function getCliVersion() {
|
|
18157
|
-
return parsePackageVersion(
|
|
20275
|
+
return parsePackageVersion(readFileSync10(packageJsonUrl(), "utf8"));
|
|
18158
20276
|
}
|
|
18159
20277
|
|
|
18160
20278
|
// src/cli.ts
|
|
18161
|
-
var main =
|
|
20279
|
+
var main = defineCommand154({
|
|
18162
20280
|
meta: {
|
|
18163
20281
|
name: "baker",
|
|
18164
20282
|
version: getCliVersion(),
|