@koda-sl/baker-cli 0.113.2 → 0.114.0-dev.249eaa8ed
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 +44 -0
- package/dist/{chunk-7K2YAWUT.js → chunk-5AWO4BHJ.js} +4 -4
- package/dist/chunk-5AWO4BHJ.js.map +1 -0
- package/dist/cli.js +2188 -486
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7K2YAWUT.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
generateCatalog,
|
|
13
13
|
resolveConcurrency,
|
|
14
14
|
validateCanvasDeep
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5AWO4BHJ.js";
|
|
16
16
|
|
|
17
17
|
// src/cli.ts
|
|
18
|
-
import { defineCommand as
|
|
18
|
+
import { defineCommand as defineCommand157, runMain } from "citty";
|
|
19
19
|
|
|
20
20
|
// src/commands/actions/index.ts
|
|
21
21
|
import { defineCommand as defineCommand18 } from "citty";
|
|
@@ -2847,10 +2847,10 @@ Examples:
|
|
|
2847
2847
|
});
|
|
2848
2848
|
|
|
2849
2849
|
// src/commands/ads/index.ts
|
|
2850
|
-
import { defineCommand as
|
|
2850
|
+
import { defineCommand as defineCommand82 } from "citty";
|
|
2851
2851
|
|
|
2852
2852
|
// src/commands/ads/google/index.ts
|
|
2853
|
-
import { defineCommand as
|
|
2853
|
+
import { defineCommand as defineCommand31 } from "citty";
|
|
2854
2854
|
|
|
2855
2855
|
// src/commands/ads/google/accounts.ts
|
|
2856
2856
|
import { defineCommand as defineCommand19 } from "citty";
|
|
@@ -3268,6 +3268,28 @@ function buildCommand(query, ctx) {
|
|
|
3268
3268
|
return `baker ads google query "${query}" --customer-id ${ctx.customerId}`;
|
|
3269
3269
|
}
|
|
3270
3270
|
var CORRECTION_RULES = [
|
|
3271
|
+
// 0. EXPECTED_REFERENCED_FIELD_IN_SELECT_CLAUSE — some resources (e.g. campaign_budget)
|
|
3272
|
+
// require fields filtered in WHERE to also be selected. The error names the exact field,
|
|
3273
|
+
// so add it to SELECT and retry. Kept first: field-specific rules below must not shadow
|
|
3274
|
+
// this with an unrelated rewrite when the named field happens to match their pattern.
|
|
3275
|
+
{
|
|
3276
|
+
matchApiError: /must be present in SELECT clause:\s*'([\w.]+)'/i,
|
|
3277
|
+
fix: (ctx) => {
|
|
3278
|
+
const field = ctx.apiErrorMessage?.match(/must be present in SELECT clause:\s*'([\w.]+)'/i)?.[1];
|
|
3279
|
+
if (!field) {
|
|
3280
|
+
return {
|
|
3281
|
+
action: "add_required_field",
|
|
3282
|
+
explanation: "Add the field named in the error to the SELECT clause and retry"
|
|
3283
|
+
};
|
|
3284
|
+
}
|
|
3285
|
+
const corrected = ctx.originalQuery.replace(/SELECT\s+/i, `SELECT ${field}, `);
|
|
3286
|
+
return {
|
|
3287
|
+
action: "add_required_field",
|
|
3288
|
+
correctedCommand: buildCommand(corrected, ctx),
|
|
3289
|
+
explanation: `${field} is used in WHERE but this resource requires it in SELECT too \u2014 added it`
|
|
3290
|
+
};
|
|
3291
|
+
}
|
|
3292
|
+
},
|
|
3271
3293
|
// 1. bare keyword.text → ad_group_criterion.keyword.text (leaves <resource>.keyword.text untouched)
|
|
3272
3294
|
{
|
|
3273
3295
|
matchQuery: /(?<![\w.])keyword\.text\b/,
|
|
@@ -3503,6 +3525,20 @@ var CORRECTION_RULES = [
|
|
|
3503
3525
|
};
|
|
3504
3526
|
}
|
|
3505
3527
|
},
|
|
3528
|
+
// 15b. asset.<type>_asset.final_urls → asset.final_urls (final URLs live on the asset
|
|
3529
|
+
// itself; the typed sub-message only carries type-specific fields like link_text)
|
|
3530
|
+
{
|
|
3531
|
+
matchQuery: /asset\.\w+_asset\.final_(mobile_)?urls\b/,
|
|
3532
|
+
matchApiError: /asset\.\w+_asset\.final_(mobile_)?urls/i,
|
|
3533
|
+
fix: (ctx) => {
|
|
3534
|
+
const corrected = ctx.originalQuery.replace(/asset\.\w+_asset\.final_(mobile_)?urls\b/g, "asset.final_$1urls");
|
|
3535
|
+
return {
|
|
3536
|
+
action: "retry_with_modified_query",
|
|
3537
|
+
correctedCommand: buildCommand(corrected, ctx),
|
|
3538
|
+
explanation: "Final URLs are on the asset itself \u2014 use asset.final_urls, not asset.<type>_asset.final_urls"
|
|
3539
|
+
};
|
|
3540
|
+
}
|
|
3541
|
+
},
|
|
3506
3542
|
// 16. Rate limit / quota
|
|
3507
3543
|
{
|
|
3508
3544
|
matchApiError: /RESOURCE_EXHAUSTED|quota.*exceeded|rate.*limit/i,
|
|
@@ -3630,6 +3666,7 @@ var CORRECTION_RULES = [
|
|
|
3630
3666
|
|
|
3631
3667
|
// src/commands/ads/google/error-parser.ts
|
|
3632
3668
|
function mapErrorCode(message) {
|
|
3669
|
+
if (/must be present in SELECT clause/i.test(message)) return "MISSING_SELECT_FIELD";
|
|
3633
3670
|
if (/field.*not.*found|unrecognized.*field|not.*valid.*field/i.test(message)) return "FIELD_NOT_FOUND";
|
|
3634
3671
|
if (/not.*valid.*resource|cannot.*select.*from/i.test(message)) return "WRONG_RESOURCE";
|
|
3635
3672
|
if (/operator|CONTAINS|LIKE/i.test(message)) return "INVALID_OPERATOR";
|
|
@@ -3835,11 +3872,1112 @@ Examples:
|
|
|
3835
3872
|
}
|
|
3836
3873
|
});
|
|
3837
3874
|
|
|
3875
|
+
// src/commands/ads/google/draft.ts
|
|
3876
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
3877
|
+
|
|
3878
|
+
// src/commands/ads/google/write-shared.ts
|
|
3879
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
3880
|
+
|
|
3881
|
+
// ../api/src/ads-google/limits.ts
|
|
3882
|
+
var GOOGLE_ADS_LIMITS = {
|
|
3883
|
+
budget: {
|
|
3884
|
+
nameMax: 255,
|
|
3885
|
+
amountMicrosMin: 1
|
|
3886
|
+
},
|
|
3887
|
+
campaign: {
|
|
3888
|
+
nameMax: 255
|
|
3889
|
+
},
|
|
3890
|
+
adGroup: {
|
|
3891
|
+
nameMax: 255
|
|
3892
|
+
},
|
|
3893
|
+
keyword: {
|
|
3894
|
+
textMax: 80,
|
|
3895
|
+
wordsMax: 10
|
|
3896
|
+
},
|
|
3897
|
+
responsiveSearchAd: {
|
|
3898
|
+
headlinesMin: 3,
|
|
3899
|
+
headlinesMax: 15,
|
|
3900
|
+
headlineTextMax: 30,
|
|
3901
|
+
descriptionsMin: 2,
|
|
3902
|
+
descriptionsMax: 4,
|
|
3903
|
+
descriptionTextMax: 90,
|
|
3904
|
+
pathMax: 15
|
|
3905
|
+
},
|
|
3906
|
+
responsiveDisplayAd: {
|
|
3907
|
+
headlinesMin: 1,
|
|
3908
|
+
headlinesMax: 5,
|
|
3909
|
+
headlineTextMax: 30,
|
|
3910
|
+
longHeadlineTextMax: 90,
|
|
3911
|
+
descriptionsMin: 1,
|
|
3912
|
+
descriptionsMax: 5,
|
|
3913
|
+
descriptionTextMax: 90,
|
|
3914
|
+
businessNameMax: 25
|
|
3915
|
+
},
|
|
3916
|
+
sharedSet: {
|
|
3917
|
+
nameMax: 255
|
|
3918
|
+
},
|
|
3919
|
+
asset: {
|
|
3920
|
+
sitelinkLinkTextMax: 25,
|
|
3921
|
+
sitelinkDescriptionMax: 35,
|
|
3922
|
+
calloutTextMax: 25,
|
|
3923
|
+
structuredSnippetHeaderMax: 25,
|
|
3924
|
+
structuredSnippetValuesMin: 3,
|
|
3925
|
+
structuredSnippetValuesMax: 10
|
|
3926
|
+
},
|
|
3927
|
+
conversionAction: {
|
|
3928
|
+
nameMax: 255
|
|
3929
|
+
},
|
|
3930
|
+
audience: {
|
|
3931
|
+
nameMax: 255
|
|
3932
|
+
},
|
|
3933
|
+
biddingStrategy: {
|
|
3934
|
+
nameMax: 255
|
|
3935
|
+
},
|
|
3936
|
+
label: {
|
|
3937
|
+
nameMax: 255
|
|
3938
|
+
}
|
|
3939
|
+
};
|
|
3940
|
+
var KEYWORD_MATCH_TYPES = ["EXACT", "PHRASE", "BROAD"];
|
|
3941
|
+
var ADVERTISING_CHANNEL_TYPES = [
|
|
3942
|
+
"SEARCH",
|
|
3943
|
+
"DISPLAY",
|
|
3944
|
+
"SHOPPING",
|
|
3945
|
+
"VIDEO",
|
|
3946
|
+
"PERFORMANCE_MAX",
|
|
3947
|
+
"DEMAND_GEN",
|
|
3948
|
+
"MULTI_CHANNEL",
|
|
3949
|
+
"LOCAL",
|
|
3950
|
+
"SMART",
|
|
3951
|
+
"TRAVEL",
|
|
3952
|
+
"HOTEL",
|
|
3953
|
+
"DISCOVERY"
|
|
3954
|
+
];
|
|
3955
|
+
var ADVERTISING_CHANNEL_SUB_TYPES = [
|
|
3956
|
+
"SEARCH_MOBILE_APP",
|
|
3957
|
+
"DISPLAY_MOBILE_APP",
|
|
3958
|
+
"SEARCH_EXPRESS",
|
|
3959
|
+
"DISPLAY_EXPRESS",
|
|
3960
|
+
"SHOPPING_SMART_ADS",
|
|
3961
|
+
"DISPLAY_GMAIL_AD",
|
|
3962
|
+
"DISPLAY_SMART_CAMPAIGN",
|
|
3963
|
+
"VIDEO_OUTSTREAM",
|
|
3964
|
+
"VIDEO_ACTION",
|
|
3965
|
+
"VIDEO_NON_SKIPPABLE",
|
|
3966
|
+
"APP_CAMPAIGN",
|
|
3967
|
+
"APP_CAMPAIGN_FOR_ENGAGEMENT",
|
|
3968
|
+
"LOCAL_CAMPAIGN",
|
|
3969
|
+
"SHOPPING_COMPARISON_LISTING_ADS",
|
|
3970
|
+
"SEARCH_MOBILE_APP_ENGAGEMENT",
|
|
3971
|
+
"TRAVEL_ACTIVITIES"
|
|
3972
|
+
];
|
|
3973
|
+
var BIDDING_STRATEGY_TYPES = [
|
|
3974
|
+
"MANUAL_CPC",
|
|
3975
|
+
"MAXIMIZE_CONVERSIONS",
|
|
3976
|
+
"MAXIMIZE_CONVERSION_VALUE",
|
|
3977
|
+
"TARGET_SPEND",
|
|
3978
|
+
"TARGET_CPA",
|
|
3979
|
+
"TARGET_ROAS",
|
|
3980
|
+
"TARGET_IMPRESSION_SHARE",
|
|
3981
|
+
"MANUAL_CPM",
|
|
3982
|
+
"MANUAL_CPV",
|
|
3983
|
+
"PERCENT_CPC"
|
|
3984
|
+
];
|
|
3985
|
+
var BUDGET_DELIVERY_METHODS = ["STANDARD", "ACCELERATED"];
|
|
3986
|
+
var AD_GROUP_TYPES = [
|
|
3987
|
+
"SEARCH_STANDARD",
|
|
3988
|
+
"DISPLAY_STANDARD",
|
|
3989
|
+
"SHOPPING_PRODUCT_ADS",
|
|
3990
|
+
"VIDEO_BUMPER",
|
|
3991
|
+
"VIDEO_TRUE_VIEW_IN_STREAM",
|
|
3992
|
+
"VIDEO_TRUE_VIEW_IN_DISPLAY",
|
|
3993
|
+
"VIDEO_NON_SKIPPABLE_IN_STREAM",
|
|
3994
|
+
"VIDEO_OUTSTREAM",
|
|
3995
|
+
"DEMAND_GEN_AD"
|
|
3996
|
+
];
|
|
3997
|
+
var SHARED_SET_TYPES = [
|
|
3998
|
+
"NEGATIVE_KEYWORDS",
|
|
3999
|
+
"NEGATIVE_PLACEMENTS",
|
|
4000
|
+
"ACCOUNT_LEVEL_NEGATIVE_KEYWORDS"
|
|
4001
|
+
];
|
|
4002
|
+
var STAGEABLE_CREATE_STATUSES2 = ["ENABLED", "PAUSED"];
|
|
4003
|
+
var PINNED_FIELDS = ["HEADLINE_1", "HEADLINE_2", "HEADLINE_3", "DESCRIPTION_1", "DESCRIPTION_2"];
|
|
4004
|
+
var CONVERSION_ACTION_CATEGORIES = [
|
|
4005
|
+
"DEFAULT",
|
|
4006
|
+
"PAGE_VIEW",
|
|
4007
|
+
"PURCHASE",
|
|
4008
|
+
"SIGNUP",
|
|
4009
|
+
"LEAD",
|
|
4010
|
+
"DOWNLOAD",
|
|
4011
|
+
"ADD_TO_CART",
|
|
4012
|
+
"BEGIN_CHECKOUT",
|
|
4013
|
+
"SUBSCRIBE_PAID",
|
|
4014
|
+
"PHONE_CALL_LEAD",
|
|
4015
|
+
"SUBMIT_LEAD_FORM",
|
|
4016
|
+
"BOOK_APPOINTMENT",
|
|
4017
|
+
"REQUEST_QUOTE",
|
|
4018
|
+
"CONTACT"
|
|
4019
|
+
];
|
|
4020
|
+
var CONVERSION_ACTION_TYPES = [
|
|
4021
|
+
"WEBPAGE",
|
|
4022
|
+
"UPLOAD_CLICKS",
|
|
4023
|
+
"UPLOAD_CALLS",
|
|
4024
|
+
"WEBSITE_CALL",
|
|
4025
|
+
"GOOGLE_ANALYTICS_4_CUSTOM"
|
|
4026
|
+
];
|
|
4027
|
+
var CONVERSION_COUNTING_TYPES = ["ONE_PER_CLICK", "MANY_PER_CLICK"];
|
|
4028
|
+
var USER_LIST_TYPES = ["CRM_BASED", "RULE_BASED", "LOGICAL", "BASIC", "LOOKALIKE"];
|
|
4029
|
+
var ASSET_FIELD_TYPES = [
|
|
4030
|
+
"SITELINK",
|
|
4031
|
+
"CALLOUT",
|
|
4032
|
+
"STRUCTURED_SNIPPET",
|
|
4033
|
+
"CALL",
|
|
4034
|
+
"PRICE",
|
|
4035
|
+
"PROMOTION",
|
|
4036
|
+
"MOBILE_APP",
|
|
4037
|
+
"HEADLINE",
|
|
4038
|
+
"DESCRIPTION",
|
|
4039
|
+
"LOGO",
|
|
4040
|
+
"MARKETING_IMAGE",
|
|
4041
|
+
"BUSINESS_NAME"
|
|
4042
|
+
];
|
|
4043
|
+
var DEVICE_TYPES = ["MOBILE", "TABLET", "DESKTOP", "CONNECTED_TV", "OTHER"];
|
|
4044
|
+
var DAYS_OF_WEEK = ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"];
|
|
4045
|
+
var CAMPAIGN_OBJECTIVES = [
|
|
4046
|
+
"SALES",
|
|
4047
|
+
"LEADS",
|
|
4048
|
+
"WEBSITE_TRAFFIC",
|
|
4049
|
+
"PRODUCT_BRAND_CONSIDERATION",
|
|
4050
|
+
"BRAND_AWARENESS_REACH",
|
|
4051
|
+
"APP_PROMOTION",
|
|
4052
|
+
"LOCAL_STORE_VISITS"
|
|
4053
|
+
];
|
|
4054
|
+
var MICROS_PER_UNIT = 1e6;
|
|
4055
|
+
function toMicros(amount) {
|
|
4056
|
+
return Math.round(amount * MICROS_PER_UNIT);
|
|
4057
|
+
}
|
|
4058
|
+
var PLAYBOOK_DAILY_BUDGET_FLOOR_MICROS = 10 * MICROS_PER_UNIT;
|
|
4059
|
+
var TEMP_REF_REGEX2 = /^g_temp_[A-Za-z0-9_-]{2,}$/;
|
|
4060
|
+
var NUMERIC_ID_REGEX2 = /^\d+$/;
|
|
4061
|
+
var RESOURCE_NAME_REGEX = /^customers\/\d+\/[A-Za-z]+\/[-\w~]+$/;
|
|
4062
|
+
var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
|
|
4063
|
+
var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
|
|
4064
|
+
|
|
4065
|
+
// ../api/src/ads-google/ops.ts
|
|
4066
|
+
import { z as z8 } from "zod";
|
|
4067
|
+
var tempRefSchema2 = z8.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
|
|
4068
|
+
var refSchema = z8.union([
|
|
4069
|
+
z8.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
|
|
4070
|
+
z8.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
|
|
4071
|
+
tempRefSchema2
|
|
4072
|
+
]);
|
|
4073
|
+
var targetRefSchema = refSchema;
|
|
4074
|
+
var microsSchema = z8.number().int().positive("expected a positive micros amount");
|
|
4075
|
+
var httpsUrlSchema2 = z8.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
|
|
4076
|
+
var customerIdSchema = z8.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
|
|
4077
|
+
var stageableStatusSchema2 = z8.enum(STAGEABLE_CREATE_STATUSES2);
|
|
4078
|
+
var matchTypeSchema = z8.enum(KEYWORD_MATCH_TYPES);
|
|
4079
|
+
var keywordTextSchema = z8.string().min(1).max(GOOGLE_ADS_LIMITS.keyword.textMax).refine((t) => t.trim().split(/\s+/).length <= GOOGLE_ADS_LIMITS.keyword.wordsMax, "keyword exceeds 10 words");
|
|
4080
|
+
var budgetCreateSchema = z8.object({
|
|
4081
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
|
|
4082
|
+
amountMicros: microsSchema,
|
|
4083
|
+
deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
|
|
4084
|
+
explicitlyShared: z8.boolean().default(false)
|
|
4085
|
+
});
|
|
4086
|
+
var budgetUpdateSchema = z8.object({
|
|
4087
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
|
|
4088
|
+
amountMicros: microsSchema.optional(),
|
|
4089
|
+
deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).optional()
|
|
4090
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4091
|
+
var biddingConfigSchema = z8.object({
|
|
4092
|
+
type: z8.enum(BIDDING_STRATEGY_TYPES),
|
|
4093
|
+
targetCpaMicros: microsSchema.optional(),
|
|
4094
|
+
targetRoas: z8.number().positive().optional(),
|
|
4095
|
+
cpcBidCeilingMicros: microsSchema.optional(),
|
|
4096
|
+
enhancedCpcEnabled: z8.boolean().optional()
|
|
4097
|
+
}).superRefine((p, ctx) => {
|
|
4098
|
+
if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
|
|
4099
|
+
ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
|
|
4100
|
+
}
|
|
4101
|
+
if (p.type === "TARGET_ROAS" && p.targetRoas === void 0) {
|
|
4102
|
+
ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
|
|
4103
|
+
}
|
|
4104
|
+
});
|
|
4105
|
+
var networkSettingsSchema = z8.object({
|
|
4106
|
+
targetGoogleSearch: z8.boolean().optional(),
|
|
4107
|
+
targetSearchNetwork: z8.boolean().optional(),
|
|
4108
|
+
targetContentNetwork: z8.boolean().optional(),
|
|
4109
|
+
targetPartnerSearchNetwork: z8.boolean().optional()
|
|
4110
|
+
});
|
|
4111
|
+
var dateSchema = z8.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
|
|
4112
|
+
var campaignCreateSchema2 = z8.object({
|
|
4113
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
|
|
4114
|
+
channelType: z8.enum(ADVERTISING_CHANNEL_TYPES),
|
|
4115
|
+
channelSubType: z8.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
|
|
4116
|
+
budget: refSchema,
|
|
4117
|
+
/** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
|
|
4118
|
+
bidding: biddingConfigSchema.optional(),
|
|
4119
|
+
biddingStrategy: refSchema.optional(),
|
|
4120
|
+
networkSettings: networkSettingsSchema.optional(),
|
|
4121
|
+
startDate: dateSchema.optional(),
|
|
4122
|
+
endDate: dateSchema.optional(),
|
|
4123
|
+
/** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
|
|
4124
|
+
objective: z8.enum(CAMPAIGN_OBJECTIVES).optional(),
|
|
4125
|
+
status: stageableStatusSchema2.default("PAUSED")
|
|
4126
|
+
}).superRefine((p, ctx) => {
|
|
4127
|
+
if (!p.bidding && !p.biddingStrategy) {
|
|
4128
|
+
ctx.addIssue({
|
|
4129
|
+
code: "custom",
|
|
4130
|
+
path: ["bidding"],
|
|
4131
|
+
message: "set an inline bidding strategy or reference a portfolio biddingStrategy"
|
|
4132
|
+
});
|
|
4133
|
+
}
|
|
4134
|
+
if (p.bidding && p.biddingStrategy) {
|
|
4135
|
+
ctx.addIssue({
|
|
4136
|
+
code: "custom",
|
|
4137
|
+
path: ["bidding"],
|
|
4138
|
+
message: "use inline bidding OR a portfolio biddingStrategy, not both"
|
|
4139
|
+
});
|
|
4140
|
+
}
|
|
4141
|
+
if (p.channelType === "PERFORMANCE_MAX" && p.bidding && p.bidding.type === "MANUAL_CPC") {
|
|
4142
|
+
ctx.addIssue({ code: "custom", path: ["bidding"], message: "Performance Max does not support Manual CPC" });
|
|
4143
|
+
}
|
|
4144
|
+
if (p.startDate && p.endDate && p.endDate <= p.startDate) {
|
|
4145
|
+
ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
|
|
4146
|
+
}
|
|
4147
|
+
});
|
|
4148
|
+
var campaignUpdateSchema2 = z8.object({
|
|
4149
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
|
|
4150
|
+
budget: refSchema.optional(),
|
|
4151
|
+
bidding: biddingConfigSchema.optional(),
|
|
4152
|
+
networkSettings: networkSettingsSchema.optional(),
|
|
4153
|
+
startDate: dateSchema.optional(),
|
|
4154
|
+
endDate: dateSchema.optional(),
|
|
4155
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4156
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4157
|
+
var adGroupCreateSchema = z8.object({
|
|
4158
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
|
|
4159
|
+
campaign: refSchema,
|
|
4160
|
+
type: z8.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
|
|
4161
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4162
|
+
status: stageableStatusSchema2.default("PAUSED")
|
|
4163
|
+
});
|
|
4164
|
+
var adGroupUpdateSchema = z8.object({
|
|
4165
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
|
|
4166
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4167
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4168
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4169
|
+
var keywordAddSchema = z8.object({
|
|
4170
|
+
adGroup: refSchema,
|
|
4171
|
+
text: keywordTextSchema,
|
|
4172
|
+
matchType: matchTypeSchema,
|
|
4173
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4174
|
+
finalUrls: z8.array(httpsUrlSchema2).optional(),
|
|
4175
|
+
status: stageableStatusSchema2.default("ENABLED")
|
|
4176
|
+
});
|
|
4177
|
+
var keywordUpdateSchema = z8.object({
|
|
4178
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4179
|
+
finalUrls: z8.array(httpsUrlSchema2).optional(),
|
|
4180
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4181
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4182
|
+
var negativeKeywordAddSchema = z8.object({
|
|
4183
|
+
level: z8.enum(["adGroup", "campaign"]),
|
|
4184
|
+
parent: refSchema,
|
|
4185
|
+
text: keywordTextSchema,
|
|
4186
|
+
matchType: matchTypeSchema
|
|
4187
|
+
});
|
|
4188
|
+
var sharedSetCreateSchema = z8.object({
|
|
4189
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
|
|
4190
|
+
type: z8.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
|
|
4191
|
+
});
|
|
4192
|
+
var sharedSetMemberAddSchema = z8.object({
|
|
4193
|
+
sharedSet: refSchema,
|
|
4194
|
+
text: keywordTextSchema,
|
|
4195
|
+
matchType: matchTypeSchema
|
|
4196
|
+
});
|
|
4197
|
+
var campaignSharedSetAttachSchema = z8.object({
|
|
4198
|
+
campaign: refSchema,
|
|
4199
|
+
sharedSet: refSchema
|
|
4200
|
+
});
|
|
4201
|
+
var adTextAssetSchema = z8.object({
|
|
4202
|
+
text: z8.string().min(1),
|
|
4203
|
+
pinnedField: z8.enum(PINNED_FIELDS).optional()
|
|
4204
|
+
});
|
|
4205
|
+
var responsiveSearchAdSchema = z8.object({
|
|
4206
|
+
format: z8.literal("responsiveSearch"),
|
|
4207
|
+
headlines: z8.array(
|
|
4208
|
+
adTextAssetSchema.refine(
|
|
4209
|
+
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
|
|
4210
|
+
"headline exceeds 30 chars"
|
|
4211
|
+
)
|
|
4212
|
+
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
|
|
4213
|
+
descriptions: z8.array(
|
|
4214
|
+
adTextAssetSchema.refine(
|
|
4215
|
+
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
|
|
4216
|
+
"description exceeds 90 chars"
|
|
4217
|
+
)
|
|
4218
|
+
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
|
|
4219
|
+
path1: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
|
|
4220
|
+
path2: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
|
|
4221
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4222
|
+
});
|
|
4223
|
+
var responsiveDisplayAdSchema = z8.object({
|
|
4224
|
+
format: z8.literal("responsiveDisplay"),
|
|
4225
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
|
|
4226
|
+
longHeadline: z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
|
|
4227
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
|
|
4228
|
+
businessName: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
|
|
4229
|
+
marketingImageAssets: z8.array(refSchema).optional(),
|
|
4230
|
+
logoImageAssets: z8.array(refSchema).optional(),
|
|
4231
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4232
|
+
});
|
|
4233
|
+
var performanceMaxAssetGroupSchema = z8.object({
|
|
4234
|
+
format: z8.literal("performanceMaxAssetGroup"),
|
|
4235
|
+
name: z8.string().min(1).max(255),
|
|
4236
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(30) })).min(3).max(15),
|
|
4237
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(2).max(5),
|
|
4238
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1),
|
|
4239
|
+
imageAssets: z8.array(refSchema).optional(),
|
|
4240
|
+
logoAssets: z8.array(refSchema).optional()
|
|
4241
|
+
});
|
|
4242
|
+
var callAdSchema = z8.object({
|
|
4243
|
+
format: z8.literal("call"),
|
|
4244
|
+
countryCode: z8.string().length(2),
|
|
4245
|
+
phoneNumber: z8.string().min(3),
|
|
4246
|
+
headline1: z8.string().min(1).max(30),
|
|
4247
|
+
headline2: z8.string().min(1).max(30),
|
|
4248
|
+
description1: z8.string().min(1).max(90),
|
|
4249
|
+
description2: z8.string().min(1).max(90),
|
|
4250
|
+
businessName: z8.string().min(1).max(25),
|
|
4251
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4252
|
+
});
|
|
4253
|
+
var appAdSchema = z8.object({
|
|
4254
|
+
format: z8.literal("app"),
|
|
4255
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(30) })).min(1),
|
|
4256
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1)
|
|
4257
|
+
});
|
|
4258
|
+
var videoAdSchema = z8.object({
|
|
4259
|
+
format: z8.literal("video"),
|
|
4260
|
+
youtubeVideoId: z8.string().min(1),
|
|
4261
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4262
|
+
});
|
|
4263
|
+
var demandGenAdSchema = z8.object({
|
|
4264
|
+
format: z8.literal("demandGen"),
|
|
4265
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(40) })).min(1).max(5),
|
|
4266
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1).max(5),
|
|
4267
|
+
businessName: z8.string().min(1).max(25),
|
|
4268
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1),
|
|
4269
|
+
imageAssets: z8.array(refSchema).optional()
|
|
4270
|
+
});
|
|
4271
|
+
var adContentSchema = z8.discriminatedUnion("format", [
|
|
4272
|
+
responsiveSearchAdSchema,
|
|
4273
|
+
responsiveDisplayAdSchema,
|
|
4274
|
+
performanceMaxAssetGroupSchema,
|
|
4275
|
+
callAdSchema,
|
|
4276
|
+
appAdSchema,
|
|
4277
|
+
videoAdSchema,
|
|
4278
|
+
demandGenAdSchema
|
|
4279
|
+
]);
|
|
4280
|
+
var adCreateSchema = z8.object({
|
|
4281
|
+
adGroup: refSchema,
|
|
4282
|
+
status: stageableStatusSchema2.default("PAUSED"),
|
|
4283
|
+
content: adContentSchema
|
|
4284
|
+
});
|
|
4285
|
+
var adUpdateSchema = z8.object({
|
|
4286
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
|
|
4287
|
+
/** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
|
|
4288
|
+
content: z8.record(z8.string(), z8.unknown()).optional()
|
|
4289
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4290
|
+
var textAssetSchema = z8.object({ type: z8.literal("text"), text: z8.string().min(1) });
|
|
4291
|
+
var imageAssetSchema = z8.object({
|
|
4292
|
+
type: z8.literal("image"),
|
|
4293
|
+
imageId: z8.string().min(1),
|
|
4294
|
+
name: z8.string().optional()
|
|
4295
|
+
});
|
|
4296
|
+
var youtubeVideoAssetSchema = z8.object({
|
|
4297
|
+
type: z8.literal("youtubeVideo"),
|
|
4298
|
+
youtubeVideoId: z8.string().min(1),
|
|
4299
|
+
name: z8.string().optional()
|
|
4300
|
+
});
|
|
4301
|
+
var sitelinkAssetSchema = z8.object({
|
|
4302
|
+
type: z8.literal("sitelink"),
|
|
4303
|
+
linkText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
|
|
4304
|
+
description1: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4305
|
+
description2: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4306
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4307
|
+
});
|
|
4308
|
+
var calloutAssetSchema = z8.object({
|
|
4309
|
+
type: z8.literal("callout"),
|
|
4310
|
+
calloutText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
|
|
4311
|
+
});
|
|
4312
|
+
var structuredSnippetAssetSchema = z8.object({
|
|
4313
|
+
type: z8.literal("structuredSnippet"),
|
|
4314
|
+
header: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
|
|
4315
|
+
values: z8.array(z8.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
|
|
4316
|
+
});
|
|
4317
|
+
var callToActionAssetSchema = z8.object({ type: z8.literal("callToAction"), callToAction: z8.string().min(1) });
|
|
4318
|
+
var assetCreateSchema = z8.discriminatedUnion("type", [
|
|
4319
|
+
textAssetSchema,
|
|
4320
|
+
imageAssetSchema,
|
|
4321
|
+
youtubeVideoAssetSchema,
|
|
4322
|
+
sitelinkAssetSchema,
|
|
4323
|
+
calloutAssetSchema,
|
|
4324
|
+
structuredSnippetAssetSchema,
|
|
4325
|
+
callToActionAssetSchema
|
|
4326
|
+
]);
|
|
4327
|
+
var assetLinkAttachSchema = z8.object({
|
|
4328
|
+
level: z8.enum(["campaign", "adGroup", "customer"]),
|
|
4329
|
+
parent: refSchema.optional(),
|
|
4330
|
+
asset: refSchema,
|
|
4331
|
+
fieldType: z8.enum(ASSET_FIELD_TYPES)
|
|
4332
|
+
}).superRefine((value, ctx) => {
|
|
4333
|
+
if (value.level !== "customer" && !value.parent) {
|
|
4334
|
+
ctx.addIssue({
|
|
4335
|
+
code: z8.ZodIssueCode.custom,
|
|
4336
|
+
path: ["parent"],
|
|
4337
|
+
message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
|
|
4338
|
+
});
|
|
4339
|
+
}
|
|
4340
|
+
});
|
|
4341
|
+
var audienceCreateSchema2 = z8.object({
|
|
4342
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
|
|
4343
|
+
type: z8.enum(USER_LIST_TYPES).default("BASIC"),
|
|
4344
|
+
description: z8.string().optional(),
|
|
4345
|
+
/** Customer-match members (crm-based) — file-first for large lists. */
|
|
4346
|
+
members: z8.array(z8.record(z8.string(), z8.string())).optional(),
|
|
4347
|
+
sourceFileRef: z8.string().optional()
|
|
4348
|
+
});
|
|
4349
|
+
var audienceCriterionAttachSchema = z8.object({
|
|
4350
|
+
level: z8.enum(["campaign", "adGroup"]),
|
|
4351
|
+
parent: refSchema,
|
|
4352
|
+
userList: refSchema,
|
|
4353
|
+
negative: z8.boolean().default(false)
|
|
4354
|
+
});
|
|
4355
|
+
var conversionActionCreateSchema = z8.object({
|
|
4356
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
|
|
4357
|
+
type: z8.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
|
|
4358
|
+
category: z8.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
|
|
4359
|
+
countingType: z8.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
|
|
4360
|
+
defaultValueMicros: microsSchema.optional(),
|
|
4361
|
+
defaultCurrencyCode: z8.string().length(3).optional(),
|
|
4362
|
+
clickThroughLookbackWindowDays: z8.number().int().positive().optional(),
|
|
4363
|
+
viewThroughLookbackWindowDays: z8.number().int().positive().optional(),
|
|
4364
|
+
status: z8.enum(["ENABLED", "PAUSED"]).default("ENABLED")
|
|
4365
|
+
});
|
|
4366
|
+
var conversionActionUpdateSchema = z8.object({
|
|
4367
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
|
|
4368
|
+
category: z8.enum(CONVERSION_ACTION_CATEGORIES).optional(),
|
|
4369
|
+
countingType: z8.enum(CONVERSION_COUNTING_TYPES).optional(),
|
|
4370
|
+
defaultValueMicros: microsSchema.optional(),
|
|
4371
|
+
status: z8.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
|
|
4372
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4373
|
+
var biddingStrategyCreateSchema = z8.object({
|
|
4374
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
|
|
4375
|
+
config: biddingConfigSchema
|
|
4376
|
+
}).superRefine((p, ctx) => {
|
|
4377
|
+
if (p.config.type === "MANUAL_CPC") {
|
|
4378
|
+
ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
|
|
4379
|
+
}
|
|
4380
|
+
});
|
|
4381
|
+
var biddingStrategyUpdateSchema = z8.object({
|
|
4382
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
|
|
4383
|
+
config: biddingConfigSchema.optional()
|
|
4384
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4385
|
+
var labelCreateSchema = z8.object({
|
|
4386
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
|
|
4387
|
+
backgroundColor: z8.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
|
|
4388
|
+
description: z8.string().optional()
|
|
4389
|
+
});
|
|
4390
|
+
var labelAttachSchema = z8.object({
|
|
4391
|
+
level: z8.enum(["campaign", "adGroup", "ad"]),
|
|
4392
|
+
parent: refSchema,
|
|
4393
|
+
label: refSchema
|
|
4394
|
+
});
|
|
4395
|
+
var locationCriterionSchema = z8.object({
|
|
4396
|
+
criterionType: z8.literal("location"),
|
|
4397
|
+
geoTargetConstant: z8.union([z8.string().regex(GEO_TARGET_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
|
|
4398
|
+
});
|
|
4399
|
+
var languageCriterionSchema = z8.object({
|
|
4400
|
+
criterionType: z8.literal("language"),
|
|
4401
|
+
languageConstant: z8.union([z8.string().regex(LANGUAGE_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
|
|
4402
|
+
});
|
|
4403
|
+
var adScheduleCriterionSchema = z8.object({
|
|
4404
|
+
criterionType: z8.literal("adSchedule"),
|
|
4405
|
+
dayOfWeek: z8.enum(DAYS_OF_WEEK),
|
|
4406
|
+
startHour: z8.number().int().min(0).max(23),
|
|
4407
|
+
startMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
|
|
4408
|
+
endHour: z8.number().int().min(0).max(24),
|
|
4409
|
+
endMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
|
|
4410
|
+
});
|
|
4411
|
+
var deviceCriterionSchema = z8.object({
|
|
4412
|
+
criterionType: z8.literal("device"),
|
|
4413
|
+
device: z8.enum(DEVICE_TYPES),
|
|
4414
|
+
bidModifier: z8.number().min(0.1).max(10).optional()
|
|
4415
|
+
});
|
|
4416
|
+
var campaignCriterionAddSchema = z8.object({
|
|
4417
|
+
campaign: refSchema,
|
|
4418
|
+
negative: z8.boolean().default(false),
|
|
4419
|
+
criterion: z8.discriminatedUnion("criterionType", [
|
|
4420
|
+
locationCriterionSchema,
|
|
4421
|
+
languageCriterionSchema,
|
|
4422
|
+
adScheduleCriterionSchema,
|
|
4423
|
+
deviceCriterionSchema
|
|
4424
|
+
])
|
|
4425
|
+
});
|
|
4426
|
+
var GOOGLE_DRAFT_OP_KINDS = [
|
|
4427
|
+
"google.budget.create",
|
|
4428
|
+
"google.budget.update",
|
|
4429
|
+
"google.campaign.create",
|
|
4430
|
+
"google.campaign.update",
|
|
4431
|
+
"google.campaign.pause",
|
|
4432
|
+
"google.campaign.resume",
|
|
4433
|
+
"google.campaign.remove",
|
|
4434
|
+
"google.adGroup.create",
|
|
4435
|
+
"google.adGroup.update",
|
|
4436
|
+
"google.adGroup.pause",
|
|
4437
|
+
"google.adGroup.resume",
|
|
4438
|
+
"google.adGroup.remove",
|
|
4439
|
+
"google.keyword.add",
|
|
4440
|
+
"google.keyword.update",
|
|
4441
|
+
"google.keyword.remove",
|
|
4442
|
+
"google.negativeKeyword.add",
|
|
4443
|
+
"google.negativeKeyword.remove",
|
|
4444
|
+
"google.sharedSet.create",
|
|
4445
|
+
"google.sharedSetMember.add",
|
|
4446
|
+
"google.sharedSetMember.remove",
|
|
4447
|
+
"google.campaignSharedSet.attach",
|
|
4448
|
+
"google.campaignSharedSet.detach",
|
|
4449
|
+
"google.ad.create",
|
|
4450
|
+
"google.ad.update",
|
|
4451
|
+
"google.ad.pause",
|
|
4452
|
+
"google.ad.resume",
|
|
4453
|
+
"google.ad.remove",
|
|
4454
|
+
"google.asset.create",
|
|
4455
|
+
"google.assetLink.attach",
|
|
4456
|
+
"google.assetLink.detach",
|
|
4457
|
+
"google.audience.create",
|
|
4458
|
+
"google.audienceCriterion.attach",
|
|
4459
|
+
"google.audienceCriterion.detach",
|
|
4460
|
+
"google.conversionAction.create",
|
|
4461
|
+
"google.conversionAction.update",
|
|
4462
|
+
"google.biddingStrategy.create",
|
|
4463
|
+
"google.biddingStrategy.update",
|
|
4464
|
+
"google.label.create",
|
|
4465
|
+
"google.label.attach",
|
|
4466
|
+
"google.campaignCriterion.add",
|
|
4467
|
+
"google.campaignCriterion.remove"
|
|
4468
|
+
];
|
|
4469
|
+
var googleDraftOpKindSchema = z8.enum(GOOGLE_DRAFT_OP_KINDS);
|
|
4470
|
+
function createOp2(kind, payload) {
|
|
4471
|
+
return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, payload });
|
|
4472
|
+
}
|
|
4473
|
+
function updateOp2(kind, payload) {
|
|
4474
|
+
return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
|
|
4475
|
+
}
|
|
4476
|
+
function targetOp(kind) {
|
|
4477
|
+
return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
|
|
4478
|
+
}
|
|
4479
|
+
var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
|
|
4480
|
+
createOp2("google.budget.create", budgetCreateSchema),
|
|
4481
|
+
updateOp2("google.budget.update", budgetUpdateSchema),
|
|
4482
|
+
createOp2("google.campaign.create", campaignCreateSchema2),
|
|
4483
|
+
updateOp2("google.campaign.update", campaignUpdateSchema2),
|
|
4484
|
+
targetOp("google.campaign.pause"),
|
|
4485
|
+
targetOp("google.campaign.resume"),
|
|
4486
|
+
targetOp("google.campaign.remove"),
|
|
4487
|
+
createOp2("google.adGroup.create", adGroupCreateSchema),
|
|
4488
|
+
updateOp2("google.adGroup.update", adGroupUpdateSchema),
|
|
4489
|
+
targetOp("google.adGroup.pause"),
|
|
4490
|
+
targetOp("google.adGroup.resume"),
|
|
4491
|
+
targetOp("google.adGroup.remove"),
|
|
4492
|
+
createOp2("google.keyword.add", keywordAddSchema),
|
|
4493
|
+
updateOp2("google.keyword.update", keywordUpdateSchema),
|
|
4494
|
+
targetOp("google.keyword.remove"),
|
|
4495
|
+
createOp2("google.negativeKeyword.add", negativeKeywordAddSchema),
|
|
4496
|
+
targetOp("google.negativeKeyword.remove"),
|
|
4497
|
+
createOp2("google.sharedSet.create", sharedSetCreateSchema),
|
|
4498
|
+
createOp2("google.sharedSetMember.add", sharedSetMemberAddSchema),
|
|
4499
|
+
targetOp("google.sharedSetMember.remove"),
|
|
4500
|
+
createOp2("google.campaignSharedSet.attach", campaignSharedSetAttachSchema),
|
|
4501
|
+
targetOp("google.campaignSharedSet.detach"),
|
|
4502
|
+
createOp2("google.ad.create", adCreateSchema),
|
|
4503
|
+
updateOp2("google.ad.update", adUpdateSchema),
|
|
4504
|
+
targetOp("google.ad.pause"),
|
|
4505
|
+
targetOp("google.ad.resume"),
|
|
4506
|
+
targetOp("google.ad.remove"),
|
|
4507
|
+
createOp2("google.asset.create", assetCreateSchema),
|
|
4508
|
+
createOp2("google.assetLink.attach", assetLinkAttachSchema),
|
|
4509
|
+
targetOp("google.assetLink.detach"),
|
|
4510
|
+
createOp2("google.audience.create", audienceCreateSchema2),
|
|
4511
|
+
createOp2("google.audienceCriterion.attach", audienceCriterionAttachSchema),
|
|
4512
|
+
targetOp("google.audienceCriterion.detach"),
|
|
4513
|
+
createOp2("google.conversionAction.create", conversionActionCreateSchema),
|
|
4514
|
+
updateOp2("google.conversionAction.update", conversionActionUpdateSchema),
|
|
4515
|
+
createOp2("google.biddingStrategy.create", biddingStrategyCreateSchema),
|
|
4516
|
+
updateOp2("google.biddingStrategy.update", biddingStrategyUpdateSchema),
|
|
4517
|
+
createOp2("google.label.create", labelCreateSchema),
|
|
4518
|
+
createOp2("google.label.attach", labelAttachSchema),
|
|
4519
|
+
createOp2("google.campaignCriterion.add", campaignCriterionAddSchema),
|
|
4520
|
+
targetOp("google.campaignCriterion.remove")
|
|
4521
|
+
]);
|
|
4522
|
+
|
|
4523
|
+
// ../api/src/ads-google/wire.ts
|
|
4524
|
+
import { z as z9 } from "zod";
|
|
4525
|
+
var googleWriteModeSchema = z9.enum(["live", "simulated"]);
|
|
4526
|
+
var googleDraftOpResultSchema = z9.object({
|
|
4527
|
+
status: z9.enum(["applied", "simulated", "failed", "skipped"]),
|
|
4528
|
+
resourceName: z9.string().optional(),
|
|
4529
|
+
error: z9.string().optional(),
|
|
4530
|
+
skippedBecause: z9.string().optional(),
|
|
4531
|
+
executedAt: z9.number().optional()
|
|
4532
|
+
});
|
|
4533
|
+
var googleDraftStageRequestSchema = z9.object({
|
|
4534
|
+
chatId: z9.string(),
|
|
4535
|
+
op: googleDraftOpInputSchema
|
|
4536
|
+
});
|
|
4537
|
+
var googleDraftStageResponseSchema = z9.object({
|
|
4538
|
+
staged: z9.literal(true),
|
|
4539
|
+
ref: z9.string(),
|
|
4540
|
+
kind: googleDraftOpKindSchema,
|
|
4541
|
+
mode: googleWriteModeSchema,
|
|
4542
|
+
dependsOn: z9.array(z9.string()),
|
|
4543
|
+
summary: z9.string(),
|
|
4544
|
+
warnings: z9.array(z9.string()),
|
|
4545
|
+
/** True when the op amended an already-staged op in place instead of appending a new one. */
|
|
4546
|
+
amended: z9.boolean().optional()
|
|
4547
|
+
});
|
|
4548
|
+
var GOOGLE_DRAFT_BATCH_MAX = 500;
|
|
4549
|
+
var googleDraftStageBatchRequestSchema = z9.object({
|
|
4550
|
+
chatId: z9.string(),
|
|
4551
|
+
ops: z9.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
|
|
4552
|
+
});
|
|
4553
|
+
var googleDraftStageBatchResponseSchema = z9.object({
|
|
4554
|
+
staged: z9.literal(true),
|
|
4555
|
+
mode: googleWriteModeSchema,
|
|
4556
|
+
count: z9.number(),
|
|
4557
|
+
ops: z9.array(
|
|
4558
|
+
z9.object({
|
|
4559
|
+
ref: z9.string(),
|
|
4560
|
+
kind: googleDraftOpKindSchema,
|
|
4561
|
+
dependsOn: z9.array(z9.string()),
|
|
4562
|
+
summary: z9.string(),
|
|
4563
|
+
warnings: z9.array(z9.string())
|
|
4564
|
+
})
|
|
4565
|
+
)
|
|
4566
|
+
});
|
|
4567
|
+
var googleDraftOpViewSchema = z9.object({
|
|
4568
|
+
ref: z9.string(),
|
|
4569
|
+
kind: googleDraftOpKindSchema,
|
|
4570
|
+
customerId: z9.string(),
|
|
4571
|
+
target: z9.string().optional(),
|
|
4572
|
+
dependsOn: z9.array(z9.string()),
|
|
4573
|
+
summary: z9.string(),
|
|
4574
|
+
stagedAt: z9.number(),
|
|
4575
|
+
result: googleDraftOpResultSchema.optional()
|
|
4576
|
+
});
|
|
4577
|
+
var googleDraftListRequestSchema = z9.object({
|
|
4578
|
+
chatId: z9.string()
|
|
4579
|
+
});
|
|
4580
|
+
var googleDraftAdvisorySchema = z9.object({
|
|
4581
|
+
scope: z9.enum(["campaign", "adGroup"]),
|
|
4582
|
+
message: z9.string()
|
|
4583
|
+
});
|
|
4584
|
+
var googleDraftStatusCollectionSchema = z9.object({
|
|
4585
|
+
label: z9.string(),
|
|
4586
|
+
added: z9.number(),
|
|
4587
|
+
removed: z9.number(),
|
|
4588
|
+
existing: z9.number()
|
|
4589
|
+
});
|
|
4590
|
+
var googleDraftChangeOperationSchema = z9.enum(["create", "update", "pause", "resume", "remove"]);
|
|
4591
|
+
var googleDraftStatusNodeSchema = z9.lazy(
|
|
4592
|
+
() => z9.object({
|
|
4593
|
+
entity: z9.string(),
|
|
4594
|
+
name: z9.string(),
|
|
4595
|
+
operation: googleDraftChangeOperationSchema.optional(),
|
|
4596
|
+
existing: z9.boolean(),
|
|
4597
|
+
collections: z9.array(googleDraftStatusCollectionSchema),
|
|
4598
|
+
children: z9.array(googleDraftStatusNodeSchema)
|
|
4599
|
+
})
|
|
4600
|
+
);
|
|
4601
|
+
var googleDraftListResponseSchema = z9.object({
|
|
4602
|
+
status: z9.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
4603
|
+
mode: googleWriteModeSchema,
|
|
4604
|
+
count: z9.number(),
|
|
4605
|
+
ops: z9.array(googleDraftOpViewSchema),
|
|
4606
|
+
/** Grouped campaign ▸ ad group ▸ ad tree for the readable CLI status view. */
|
|
4607
|
+
tree: z9.array(googleDraftStatusNodeSchema).optional(),
|
|
4608
|
+
/** Non-blocking completeness advisories for the whole draft. */
|
|
4609
|
+
advisories: z9.array(googleDraftAdvisorySchema).optional()
|
|
4610
|
+
});
|
|
4611
|
+
var googleDraftRemoveRequestSchema = z9.object({
|
|
4612
|
+
chatId: z9.string(),
|
|
4613
|
+
ref: z9.string()
|
|
4614
|
+
});
|
|
4615
|
+
var googleDraftRemoveResponseSchema = z9.object({
|
|
4616
|
+
/** The requested ref plus any dependents removed by cascade. */
|
|
4617
|
+
removed: z9.array(z9.string())
|
|
4618
|
+
});
|
|
4619
|
+
var googleDraftClearRequestSchema = z9.object({
|
|
4620
|
+
chatId: z9.string()
|
|
4621
|
+
});
|
|
4622
|
+
var googleDraftClearResponseSchema = z9.object({
|
|
4623
|
+
cleared: z9.number()
|
|
4624
|
+
});
|
|
4625
|
+
var googleFieldErrorSchema = z9.object({
|
|
4626
|
+
path: z9.string(),
|
|
4627
|
+
message: z9.string()
|
|
4628
|
+
});
|
|
4629
|
+
var googleDraftErrorResponseSchema = z9.object({
|
|
4630
|
+
code: z9.string(),
|
|
4631
|
+
error: z9.string(),
|
|
4632
|
+
fields: z9.array(googleFieldErrorSchema).optional()
|
|
4633
|
+
});
|
|
4634
|
+
|
|
4635
|
+
// src/commands/ads/google/draft-status.ts
|
|
4636
|
+
var OPERATION_LABELS = {
|
|
4637
|
+
create: "Creating",
|
|
4638
|
+
update: "Updating",
|
|
4639
|
+
pause: "Pausing",
|
|
4640
|
+
resume: "Resuming",
|
|
4641
|
+
remove: "Removing"
|
|
4642
|
+
};
|
|
4643
|
+
function badge(node) {
|
|
4644
|
+
const label = node.operation ? OPERATION_LABELS[node.operation] : void 0;
|
|
4645
|
+
if (label) {
|
|
4646
|
+
return label;
|
|
4647
|
+
}
|
|
4648
|
+
return node.existing ? "on Google Ads" : "staged";
|
|
4649
|
+
}
|
|
4650
|
+
function collectionLine(collection) {
|
|
4651
|
+
const parts = [];
|
|
4652
|
+
if (collection.added > 0) {
|
|
4653
|
+
parts.push(`+${collection.added}`);
|
|
4654
|
+
}
|
|
4655
|
+
if (collection.existing > 0) {
|
|
4656
|
+
parts.push(`${collection.existing} existing`);
|
|
4657
|
+
}
|
|
4658
|
+
if (collection.removed > 0) {
|
|
4659
|
+
parts.push(`-${collection.removed}`);
|
|
4660
|
+
}
|
|
4661
|
+
return parts.length > 0 ? `${collection.label}: ${parts.join(", ")}` : void 0;
|
|
4662
|
+
}
|
|
4663
|
+
function renderNode(node, depth, lines) {
|
|
4664
|
+
const indent = " ".repeat(depth);
|
|
4665
|
+
lines.push(`${indent}\u2022 ${node.name} \xB7 ${badge(node)}`);
|
|
4666
|
+
for (const collection of node.collections) {
|
|
4667
|
+
const line = collectionLine(collection);
|
|
4668
|
+
if (line) {
|
|
4669
|
+
lines.push(`${indent} ${line}`);
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
for (const child of node.children) {
|
|
4673
|
+
renderNode(child, depth + 1, lines);
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
var RESOURCE_ENTITIES = /* @__PURE__ */ new Set([
|
|
4677
|
+
"sharedSet",
|
|
4678
|
+
"biddingStrategy",
|
|
4679
|
+
"audience",
|
|
4680
|
+
"conversionAction",
|
|
4681
|
+
"label",
|
|
4682
|
+
"budget",
|
|
4683
|
+
"asset"
|
|
4684
|
+
]);
|
|
4685
|
+
function renderSection(title, nodes, lines) {
|
|
4686
|
+
if (nodes.length === 0) {
|
|
4687
|
+
return;
|
|
4688
|
+
}
|
|
4689
|
+
lines.push("");
|
|
4690
|
+
lines.push(title);
|
|
4691
|
+
for (const node of nodes) {
|
|
4692
|
+
renderNode(node, 1, lines);
|
|
4693
|
+
}
|
|
4694
|
+
}
|
|
4695
|
+
function renderAdvisories(data, lines) {
|
|
4696
|
+
const advisories = data.advisories ?? [];
|
|
4697
|
+
if (advisories.length === 0) {
|
|
4698
|
+
return;
|
|
4699
|
+
}
|
|
4700
|
+
lines.push("");
|
|
4701
|
+
lines.push("Advisories (non-blocking \u2014 build these out for a higher-performance campaign)");
|
|
4702
|
+
for (const advisory of advisories) {
|
|
4703
|
+
lines.push(` \u2022 ${advisory.message}`);
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
function renderDraftStatus(data) {
|
|
4707
|
+
if (data.status === "none" || data.count === 0) {
|
|
4708
|
+
return "No staged Google Ads changes on this chat.";
|
|
4709
|
+
}
|
|
4710
|
+
const modeNote = data.mode === "live" ? "Live \u2014 publishing writes directly to Google Ads." : "Simulated \u2014 publishing completes the whole draft without calling Google Ads.";
|
|
4711
|
+
const lines = [
|
|
4712
|
+
`Google Ads \u2014 ${data.count} staged change${data.count === 1 ? "" : "s"} \xB7 ${data.mode}`,
|
|
4713
|
+
modeNote
|
|
4714
|
+
];
|
|
4715
|
+
const tree = data.tree ?? [];
|
|
4716
|
+
renderSection(
|
|
4717
|
+
"Shared resources",
|
|
4718
|
+
tree.filter((node) => RESOURCE_ENTITIES.has(node.entity)),
|
|
4719
|
+
lines
|
|
4720
|
+
);
|
|
4721
|
+
renderSection(
|
|
4722
|
+
"Campaigns",
|
|
4723
|
+
tree.filter((node) => node.entity === "campaign"),
|
|
4724
|
+
lines
|
|
4725
|
+
);
|
|
4726
|
+
const rest = tree.filter((node) => !RESOURCE_ENTITIES.has(node.entity) && node.entity !== "campaign");
|
|
4727
|
+
renderSection("Other", rest, lines);
|
|
4728
|
+
renderAdvisories(data, lines);
|
|
4729
|
+
return lines.join("\n");
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4732
|
+
// src/commands/ads/google/write-shared.ts
|
|
4733
|
+
function failWriteValidation(message) {
|
|
4734
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
4735
|
+
process.exit(1);
|
|
4736
|
+
}
|
|
4737
|
+
function requireCustomerId(args) {
|
|
4738
|
+
const raw = args["customer-id"] ?? args.customerId;
|
|
4739
|
+
if (!raw || !/^\d{10}$/.test(raw)) {
|
|
4740
|
+
failWriteValidation("pass --customer-id as the 10-digit Google Ads customer id (no dashes)");
|
|
4741
|
+
}
|
|
4742
|
+
return raw;
|
|
4743
|
+
}
|
|
4744
|
+
function requireTarget(args, entity) {
|
|
4745
|
+
const positional = Array.isArray(args._) ? args._[0] : void 0;
|
|
4746
|
+
const target = args.id ?? args.target ?? positional;
|
|
4747
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
4748
|
+
failWriteValidation(`pass the ${entity} resource name or id as the positional argument`);
|
|
4749
|
+
}
|
|
4750
|
+
return target;
|
|
4751
|
+
}
|
|
4752
|
+
function requireStringFlag(value, flag) {
|
|
4753
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
4754
|
+
failWriteValidation(`${flag} is required`);
|
|
4755
|
+
}
|
|
4756
|
+
return value;
|
|
4757
|
+
}
|
|
4758
|
+
function microsFlag(value, flag) {
|
|
4759
|
+
if (value === void 0 || value === null || value === "") {
|
|
4760
|
+
return void 0;
|
|
4761
|
+
}
|
|
4762
|
+
const num = Number(value);
|
|
4763
|
+
if (Number.isNaN(num) || num <= 0) {
|
|
4764
|
+
failWriteValidation(`${flag} must be a positive amount (major currency units, e.g. 50 or 50.00)`);
|
|
4765
|
+
}
|
|
4766
|
+
return toMicros(num);
|
|
4767
|
+
}
|
|
4768
|
+
function listFlag(value) {
|
|
4769
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
4770
|
+
return void 0;
|
|
4771
|
+
}
|
|
4772
|
+
const items = value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
4773
|
+
return items.length > 0 ? items : void 0;
|
|
4774
|
+
}
|
|
4775
|
+
var MATCH_TYPES = /* @__PURE__ */ new Set(["EXACT", "PHRASE", "BROAD"]);
|
|
4776
|
+
function parseKeywordEntry(raw, defaultMatch) {
|
|
4777
|
+
const colon = raw.lastIndexOf(":");
|
|
4778
|
+
if (colon > 0) {
|
|
4779
|
+
const suffix = raw.slice(colon + 1).trim().toUpperCase();
|
|
4780
|
+
if (MATCH_TYPES.has(suffix)) {
|
|
4781
|
+
return { text: raw.slice(0, colon).trim(), matchType: suffix };
|
|
4782
|
+
}
|
|
4783
|
+
failWriteValidation(`"${raw}": ":${raw.slice(colon + 1)}" is not a match type (EXACT | PHRASE | BROAD)`);
|
|
4784
|
+
}
|
|
4785
|
+
if (!defaultMatch) {
|
|
4786
|
+
failWriteValidation(`"${raw}" has no match type \u2014 add a :EXACT/:PHRASE/:BROAD suffix or pass --match-type`);
|
|
4787
|
+
}
|
|
4788
|
+
return { text: raw, matchType: defaultMatch };
|
|
4789
|
+
}
|
|
4790
|
+
function rawTextEntries(value) {
|
|
4791
|
+
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
4792
|
+
return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
4793
|
+
}
|
|
4794
|
+
function rawFileEntries(path12) {
|
|
4795
|
+
if (typeof path12 !== "string" || path12.length === 0) {
|
|
4796
|
+
return [];
|
|
4797
|
+
}
|
|
4798
|
+
return readFileSync3(path12, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
4799
|
+
}
|
|
4800
|
+
function keywordEntries(args) {
|
|
4801
|
+
const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
|
|
4802
|
+
const raw = [...rawTextEntries(args.text), ...rawFileEntries(args.file)];
|
|
4803
|
+
if (raw.length === 0) {
|
|
4804
|
+
failWriteValidation("pass keywords via --text (comma-separated) and/or --file (one per line)");
|
|
4805
|
+
}
|
|
4806
|
+
if (raw.length > GOOGLE_DRAFT_BATCH_MAX) {
|
|
4807
|
+
failWriteValidation(`${raw.length} keywords exceeds the batch limit of ${GOOGLE_DRAFT_BATCH_MAX}`);
|
|
4808
|
+
}
|
|
4809
|
+
const entries = [];
|
|
4810
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4811
|
+
for (const item of raw) {
|
|
4812
|
+
const entry = parseKeywordEntry(item, defaultMatch);
|
|
4813
|
+
const key = `${entry.text}\0${entry.matchType}`;
|
|
4814
|
+
if (!seen.has(key)) {
|
|
4815
|
+
seen.add(key);
|
|
4816
|
+
entries.push(entry);
|
|
4817
|
+
}
|
|
4818
|
+
}
|
|
4819
|
+
return entries;
|
|
4820
|
+
}
|
|
4821
|
+
function loadJsonFileArg(path12) {
|
|
4822
|
+
if (typeof path12 !== "string" || path12.length === 0) {
|
|
4823
|
+
return {};
|
|
4824
|
+
}
|
|
4825
|
+
try {
|
|
4826
|
+
const parsed = JSON.parse(readFileSync3(path12, "utf8"));
|
|
4827
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4828
|
+
failWriteValidation(`${path12} must contain a JSON object`);
|
|
4829
|
+
}
|
|
4830
|
+
return parsed;
|
|
4831
|
+
} catch (err) {
|
|
4832
|
+
if (err instanceof SyntaxError) {
|
|
4833
|
+
failWriteValidation(`${path12} is not valid JSON: ${err.message}`);
|
|
4834
|
+
}
|
|
4835
|
+
throw err;
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
function mergePayload(file, flags) {
|
|
4839
|
+
const merged = { ...file };
|
|
4840
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
4841
|
+
if (value !== void 0) {
|
|
4842
|
+
merged[key] = value;
|
|
4843
|
+
}
|
|
4844
|
+
}
|
|
4845
|
+
return merged;
|
|
4846
|
+
}
|
|
4847
|
+
function handleGoogleError(err) {
|
|
4848
|
+
if (err instanceof ApiError) {
|
|
4849
|
+
writeJsonEnvelope({ ok: false, error: { code: err.code ?? "API_ERROR", message: err.message } });
|
|
4850
|
+
process.exit(1);
|
|
4851
|
+
}
|
|
4852
|
+
writeJsonEnvelope({
|
|
4853
|
+
ok: false,
|
|
4854
|
+
error: { code: "UNKNOWN", message: err instanceof Error ? err.message : String(err) }
|
|
4855
|
+
});
|
|
4856
|
+
process.exit(1);
|
|
4857
|
+
}
|
|
4858
|
+
async function stageGoogleOp(raw) {
|
|
4859
|
+
const preflight = googleDraftOpInputSchema.safeParse(raw);
|
|
4860
|
+
if (!preflight.success) {
|
|
4861
|
+
const fields = preflight.error.issues.map((issue) => ({ path: issue.path.join("."), message: issue.message }));
|
|
4862
|
+
writeJsonEnvelope({
|
|
4863
|
+
ok: false,
|
|
4864
|
+
error: {
|
|
4865
|
+
code: "VALIDATION_ERROR",
|
|
4866
|
+
message: fields.map((f) => f.path ? `${f.path}: ${f.message}` : f.message).join("; "),
|
|
4867
|
+
fields
|
|
4868
|
+
}
|
|
4869
|
+
});
|
|
4870
|
+
process.exit(1);
|
|
4871
|
+
}
|
|
4872
|
+
try {
|
|
4873
|
+
const chatId = requireChatId();
|
|
4874
|
+
const response = await apiPost("/api/ads/google/draft/stage", { chatId, op: preflight.data });
|
|
4875
|
+
writeJsonEnvelope(response);
|
|
4876
|
+
} catch (err) {
|
|
4877
|
+
handleGoogleError(err);
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
async function stageCreate(kind, customerId, payload) {
|
|
4881
|
+
await stageGoogleOp({ kind, customerId, payload });
|
|
4882
|
+
}
|
|
4883
|
+
async function stageGoogleOps(rawOps) {
|
|
4884
|
+
if (rawOps.length === 1 && rawOps[0]) {
|
|
4885
|
+
await stageGoogleOp(rawOps[0]);
|
|
4886
|
+
return;
|
|
4887
|
+
}
|
|
4888
|
+
const ops = [];
|
|
4889
|
+
for (const [index, raw] of rawOps.entries()) {
|
|
4890
|
+
const preflight = googleDraftOpInputSchema.safeParse(raw);
|
|
4891
|
+
if (!preflight.success) {
|
|
4892
|
+
const fields = preflight.error.issues.map((issue) => ({
|
|
4893
|
+
path: `ops[${index}].${issue.path.join(".")}`,
|
|
4894
|
+
message: issue.message
|
|
4895
|
+
}));
|
|
4896
|
+
writeJsonEnvelope({
|
|
4897
|
+
ok: false,
|
|
4898
|
+
error: {
|
|
4899
|
+
code: "VALIDATION_ERROR",
|
|
4900
|
+
message: fields.map((f) => `${f.path}: ${f.message}`).join("; "),
|
|
4901
|
+
fields
|
|
4902
|
+
}
|
|
4903
|
+
});
|
|
4904
|
+
process.exit(1);
|
|
4905
|
+
}
|
|
4906
|
+
ops.push(preflight.data);
|
|
4907
|
+
}
|
|
4908
|
+
try {
|
|
4909
|
+
const chatId = requireChatId();
|
|
4910
|
+
const response = await apiPost("/api/ads/google/draft/stage-batch", { chatId, ops });
|
|
4911
|
+
writeJsonEnvelope(response);
|
|
4912
|
+
} catch (err) {
|
|
4913
|
+
handleGoogleError(err);
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
async function stageUpdate(kind, customerId, target, payload) {
|
|
4917
|
+
await stageGoogleOp({ kind, customerId, target, payload });
|
|
4918
|
+
}
|
|
4919
|
+
async function stageTarget(kind, customerId, target) {
|
|
4920
|
+
await stageGoogleOp({ kind, customerId, target });
|
|
4921
|
+
}
|
|
4922
|
+
async function draftAction(path12, body) {
|
|
4923
|
+
try {
|
|
4924
|
+
const chatId = requireChatId();
|
|
4925
|
+
const response = await apiPost(path12, { chatId, ...body });
|
|
4926
|
+
writeJsonEnvelope(response);
|
|
4927
|
+
} catch (err) {
|
|
4928
|
+
handleGoogleError(err);
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
async function draftListAction(json) {
|
|
4932
|
+
try {
|
|
4933
|
+
const chatId = requireChatId();
|
|
4934
|
+
const response = await apiPost("/api/ads/google/draft", { chatId });
|
|
4935
|
+
if (json || !response.ok || !response.data) {
|
|
4936
|
+
writeJsonEnvelope(response);
|
|
4937
|
+
return;
|
|
4938
|
+
}
|
|
4939
|
+
process.stdout.write(`${renderDraftStatus(response.data)}
|
|
4940
|
+
`);
|
|
4941
|
+
} catch (err) {
|
|
4942
|
+
handleGoogleError(err);
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
|
|
4946
|
+
// src/commands/ads/google/draft.ts
|
|
4947
|
+
var draftCommand2 = defineCommand22({
|
|
4948
|
+
meta: { name: "draft", description: "List, remove, or clear staged Google Ads write ops for this chat" },
|
|
4949
|
+
subCommands: {
|
|
4950
|
+
list: defineCommand22({
|
|
4951
|
+
meta: {
|
|
4952
|
+
name: "list",
|
|
4953
|
+
description: "Review everything staged as a campaign \u25B8 ad group \u25B8 ad tree (--json for the raw envelope)"
|
|
4954
|
+
},
|
|
4955
|
+
args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable tree" } },
|
|
4956
|
+
run: async ({ args }) => {
|
|
4957
|
+
await draftListAction(args.json === true);
|
|
4958
|
+
}
|
|
4959
|
+
}),
|
|
4960
|
+
remove: defineCommand22({
|
|
4961
|
+
meta: { name: "remove", description: "Remove one staged op (cascades to dependents)" },
|
|
4962
|
+
args: { ref: { type: "positional", description: "Staged op ref (g_temp_* or target)", required: false } },
|
|
4963
|
+
run: async ({ args }) => {
|
|
4964
|
+
await draftAction("/api/ads/google/draft/remove", { ref: requireTarget(args, "op") });
|
|
4965
|
+
}
|
|
4966
|
+
}),
|
|
4967
|
+
clear: defineCommand22({
|
|
4968
|
+
meta: { name: "clear", description: "Discard all staged ops on this chat" },
|
|
4969
|
+
run: async () => {
|
|
4970
|
+
await draftAction("/api/ads/google/draft/clear", {});
|
|
4971
|
+
}
|
|
4972
|
+
})
|
|
4973
|
+
}
|
|
4974
|
+
});
|
|
4975
|
+
|
|
3838
4976
|
// src/commands/ads/google/keywords/index.ts
|
|
3839
|
-
import { defineCommand as
|
|
4977
|
+
import { defineCommand as defineCommand27 } from "citty";
|
|
3840
4978
|
|
|
3841
4979
|
// src/commands/ads/google/keywords/discover.ts
|
|
3842
|
-
import { defineCommand as
|
|
4980
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
3843
4981
|
|
|
3844
4982
|
// src/geo-context.ts
|
|
3845
4983
|
var GOOGLE_ADS_LOCATIONS = [
|
|
@@ -4114,7 +5252,7 @@ function handleKeywordError(err) {
|
|
|
4114
5252
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
4115
5253
|
process.exit(1);
|
|
4116
5254
|
}
|
|
4117
|
-
var discoverCommand =
|
|
5255
|
+
var discoverCommand = defineCommand23({
|
|
4118
5256
|
meta: {
|
|
4119
5257
|
name: "discover",
|
|
4120
5258
|
description: `Discover new keyword ideas from seed keywords or competitor URLs.
|
|
@@ -4176,7 +5314,7 @@ Examples:
|
|
|
4176
5314
|
});
|
|
4177
5315
|
|
|
4178
5316
|
// src/commands/ads/google/keywords/languages.ts
|
|
4179
|
-
import { defineCommand as
|
|
5317
|
+
import { defineCommand as defineCommand24 } from "citty";
|
|
4180
5318
|
registerSchema({
|
|
4181
5319
|
command: "ads.google.keywords.languages",
|
|
4182
5320
|
description: "List all supported language IDs for --language flag in Google Ads keyword commands.",
|
|
@@ -4186,7 +5324,7 @@ var FIELDS = {
|
|
|
4186
5324
|
id: "Language ID to pass as --language",
|
|
4187
5325
|
name: "Language name"
|
|
4188
5326
|
};
|
|
4189
|
-
var languagesCommand =
|
|
5327
|
+
var languagesCommand = defineCommand24({
|
|
4190
5328
|
meta: {
|
|
4191
5329
|
name: "languages",
|
|
4192
5330
|
description: "List all supported language IDs for --language flag."
|
|
@@ -4197,7 +5335,7 @@ var languagesCommand = defineCommand23({
|
|
|
4197
5335
|
});
|
|
4198
5336
|
|
|
4199
5337
|
// src/commands/ads/google/keywords/locations.ts
|
|
4200
|
-
import { defineCommand as
|
|
5338
|
+
import { defineCommand as defineCommand25 } from "citty";
|
|
4201
5339
|
registerSchema({
|
|
4202
5340
|
command: "ads.google.keywords.locations",
|
|
4203
5341
|
description: "List all supported geo target IDs for --location flag in Google Ads keyword commands.",
|
|
@@ -4207,7 +5345,7 @@ var FIELDS2 = {
|
|
|
4207
5345
|
id: "Geo target ID to pass as --location",
|
|
4208
5346
|
name: "Country/region name"
|
|
4209
5347
|
};
|
|
4210
|
-
var locationsCommand =
|
|
5348
|
+
var locationsCommand = defineCommand25({
|
|
4211
5349
|
meta: {
|
|
4212
5350
|
name: "locations",
|
|
4213
5351
|
description: "List all supported geo target IDs for --location flag."
|
|
@@ -4218,7 +5356,7 @@ var locationsCommand = defineCommand24({
|
|
|
4218
5356
|
});
|
|
4219
5357
|
|
|
4220
5358
|
// src/commands/ads/google/keywords/metrics.ts
|
|
4221
|
-
import { defineCommand as
|
|
5359
|
+
import { defineCommand as defineCommand26 } from "citty";
|
|
4222
5360
|
registerSchema({
|
|
4223
5361
|
command: "ads.google.keywords.metrics",
|
|
4224
5362
|
description: "Get historical metrics for specific keywords. Returns { historical_metrics: [...] } with snake_case fields matching the Google Ads API. IMPORTANT: If --location and --language are omitted, defaults to United States (2840) and English (1000). The response includes a query_context object showing which location/language were used.",
|
|
@@ -4242,7 +5380,7 @@ registerSchema({
|
|
|
4242
5380
|
output: { type: "string", description: "Format: json|csv|jsonl|md", required: false, default: "json" }
|
|
4243
5381
|
}
|
|
4244
5382
|
});
|
|
4245
|
-
var metricsCommand =
|
|
5383
|
+
var metricsCommand = defineCommand26({
|
|
4246
5384
|
meta: {
|
|
4247
5385
|
name: "metrics",
|
|
4248
5386
|
description: `Get historical search metrics for specific keywords.
|
|
@@ -4329,7 +5467,7 @@ Examples:
|
|
|
4329
5467
|
});
|
|
4330
5468
|
|
|
4331
5469
|
// src/commands/ads/google/keywords/index.ts
|
|
4332
|
-
var keywordsCommand =
|
|
5470
|
+
var keywordsCommand = defineCommand27({
|
|
4333
5471
|
meta: {
|
|
4334
5472
|
name: "keywords",
|
|
4335
5473
|
description: `Keyword research tools. Subcommands: discover, metrics, locations, languages.
|
|
@@ -4349,8 +5487,8 @@ Examples:
|
|
|
4349
5487
|
});
|
|
4350
5488
|
|
|
4351
5489
|
// src/commands/ads/google/library/index.ts
|
|
4352
|
-
import { defineCommand as
|
|
4353
|
-
var listAdvertisers =
|
|
5490
|
+
import { defineCommand as defineCommand28 } from "citty";
|
|
5491
|
+
var listAdvertisers = defineCommand28({
|
|
4354
5492
|
meta: {
|
|
4355
5493
|
name: "list-advertisers",
|
|
4356
5494
|
description: "List tracked Google advertisers and their accounts"
|
|
@@ -4367,7 +5505,7 @@ var listAdvertisers = defineCommand27({
|
|
|
4367
5505
|
}
|
|
4368
5506
|
}
|
|
4369
5507
|
});
|
|
4370
|
-
var syncStatus =
|
|
5508
|
+
var syncStatus = defineCommand28({
|
|
4371
5509
|
meta: {
|
|
4372
5510
|
name: "sync-status",
|
|
4373
5511
|
description: "Check the sync status and ad counts of a Google account"
|
|
@@ -4387,7 +5525,7 @@ var syncStatus = defineCommand27({
|
|
|
4387
5525
|
writeAdsJson({ ok: true, data });
|
|
4388
5526
|
}
|
|
4389
5527
|
});
|
|
4390
|
-
var searchAds =
|
|
5528
|
+
var searchAds = defineCommand28({
|
|
4391
5529
|
meta: {
|
|
4392
5530
|
name: "search-ads",
|
|
4393
5531
|
description: "Search and filter Google ads for an account"
|
|
@@ -4444,7 +5582,7 @@ var searchAds = defineCommand27({
|
|
|
4444
5582
|
}
|
|
4445
5583
|
}
|
|
4446
5584
|
});
|
|
4447
|
-
var searchAdvertiser =
|
|
5585
|
+
var searchAdvertiser = defineCommand28({
|
|
4448
5586
|
meta: {
|
|
4449
5587
|
name: "search-advertiser",
|
|
4450
5588
|
description: "Search for an advertiser on the Google Ads Transparency Center"
|
|
@@ -4479,7 +5617,7 @@ var searchAdvertiser = defineCommand27({
|
|
|
4479
5617
|
function sleep(ms) {
|
|
4480
5618
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
4481
5619
|
}
|
|
4482
|
-
var track =
|
|
5620
|
+
var track = defineCommand28({
|
|
4483
5621
|
meta: {
|
|
4484
5622
|
name: "track",
|
|
4485
5623
|
description: "Track a new Google advertiser (from search results). Waits for initial sync to complete before returning."
|
|
@@ -4537,7 +5675,7 @@ var track = defineCommand27({
|
|
|
4537
5675
|
process.exit(1);
|
|
4538
5676
|
}
|
|
4539
5677
|
});
|
|
4540
|
-
var sync =
|
|
5678
|
+
var sync = defineCommand28({
|
|
4541
5679
|
meta: {
|
|
4542
5680
|
name: "sync",
|
|
4543
5681
|
description: "Trigger an immediate sync for a Google account. Waits for completion before returning."
|
|
@@ -4581,7 +5719,7 @@ var sync = defineCommand27({
|
|
|
4581
5719
|
process.exit(1);
|
|
4582
5720
|
}
|
|
4583
5721
|
});
|
|
4584
|
-
var searchCompetitors =
|
|
5722
|
+
var searchCompetitors = defineCommand28({
|
|
4585
5723
|
meta: {
|
|
4586
5724
|
name: "search-competitors",
|
|
4587
5725
|
description: "Search for competitors running Google ads for a keyword (DataForSEO)"
|
|
@@ -4613,7 +5751,7 @@ var searchCompetitors = defineCommand27({
|
|
|
4613
5751
|
}
|
|
4614
5752
|
}
|
|
4615
5753
|
});
|
|
4616
|
-
var library =
|
|
5754
|
+
var library = defineCommand28({
|
|
4617
5755
|
meta: {
|
|
4618
5756
|
name: "library",
|
|
4619
5757
|
description: "Manage and search the Google Ads Library"
|
|
@@ -4630,9 +5768,9 @@ var library = defineCommand27({
|
|
|
4630
5768
|
});
|
|
4631
5769
|
|
|
4632
5770
|
// src/commands/ads/google/query.ts
|
|
4633
|
-
import { appendFileSync, existsSync as existsSync3, readFileSync as
|
|
5771
|
+
import { appendFileSync, existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
4634
5772
|
import { resolve } from "path";
|
|
4635
|
-
import { defineCommand as
|
|
5773
|
+
import { defineCommand as defineCommand29 } from "citty";
|
|
4636
5774
|
|
|
4637
5775
|
// src/commands/ads/google/preflight.ts
|
|
4638
5776
|
function buildCommand2(query, customerId) {
|
|
@@ -4653,6 +5791,24 @@ function applyAutoFixes(query, limit) {
|
|
|
4653
5791
|
corrected = corrected.replace(/shopping_performance_view\.product_(\w+)/g, "segments.product_$1");
|
|
4654
5792
|
warnings.push({ code: "FIELD_RENAMED", message: "shopping_performance_view.product_* \u2192 segments.product_*" });
|
|
4655
5793
|
}
|
|
5794
|
+
if (/asset\.\w+_asset\.final_(mobile_)?urls\b/.test(corrected)) {
|
|
5795
|
+
corrected = corrected.replace(/asset\.\w+_asset\.final_(mobile_)?urls\b/g, "asset.final_$1urls");
|
|
5796
|
+
warnings.push({ code: "FIELD_RENAMED", message: "asset.<type>_asset.final_urls \u2192 asset.final_urls" });
|
|
5797
|
+
}
|
|
5798
|
+
if (/FROM\s+campaign_budget\b/i.test(corrected)) {
|
|
5799
|
+
const whereClause = corrected.split(/\bWHERE\b/i)[1] ?? "";
|
|
5800
|
+
const selectClause = corrected.split(/\bFROM\b/i)[0] ?? "";
|
|
5801
|
+
const missing = [...new Set(whereClause.match(/campaign\.[\w.]+/g) ?? [])].filter(
|
|
5802
|
+
(field) => !selectClause.includes(field)
|
|
5803
|
+
);
|
|
5804
|
+
if (missing.length > 0) {
|
|
5805
|
+
corrected = corrected.replace(/SELECT\s+/i, `SELECT ${missing.join(", ")}, `);
|
|
5806
|
+
warnings.push({
|
|
5807
|
+
code: "REQUIRED_FIELD_ADDED",
|
|
5808
|
+
message: `Added ${missing.join(", ")} to SELECT \u2014 campaign_budget queries must select campaign fields used in WHERE`
|
|
5809
|
+
});
|
|
5810
|
+
}
|
|
5811
|
+
}
|
|
4656
5812
|
if (/campaign\.status\s*=\s*'ACTIVE'/i.test(corrected)) {
|
|
4657
5813
|
corrected = corrected.replace(/campaign\.status\s*=\s*'ACTIVE'/gi, "campaign.status = 'ENABLED'");
|
|
4658
5814
|
warnings.push({ code: "ENUM_CORRECTED", message: "campaign.status ACTIVE \u2192 ENABLED" });
|
|
@@ -4924,7 +6080,7 @@ function writeRowsToFile(filePath, rows, fields, append) {
|
|
|
4924
6080
|
`, "utf-8");
|
|
4925
6081
|
}
|
|
4926
6082
|
} else if (append && existsSync3(filePath)) {
|
|
4927
|
-
const existing = JSON.parse(
|
|
6083
|
+
const existing = JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
4928
6084
|
writeFileSync2(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
4929
6085
|
} else {
|
|
4930
6086
|
writeFileSync2(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -5088,7 +6244,7 @@ function handleQueryError(err, finalQuery, customerId) {
|
|
|
5088
6244
|
});
|
|
5089
6245
|
process.exit(1);
|
|
5090
6246
|
}
|
|
5091
|
-
var queryCommand =
|
|
6247
|
+
var queryCommand = defineCommand29({
|
|
5092
6248
|
meta: {
|
|
5093
6249
|
name: "query",
|
|
5094
6250
|
description: `Run GAQL queries against Google Ads. Supports raw GAQL, presets, pagination, file export, and caching.
|
|
@@ -5145,8 +6301,546 @@ Examples:
|
|
|
5145
6301
|
}
|
|
5146
6302
|
});
|
|
5147
6303
|
|
|
6304
|
+
// src/commands/ads/google/write-commands.ts
|
|
6305
|
+
import { defineCommand as defineCommand30 } from "citty";
|
|
6306
|
+
var customerIdArg = { "customer-id": { type: "string", description: "10-digit Google Ads customer id" } };
|
|
6307
|
+
var fileArg = {
|
|
6308
|
+
file: { type: "string", description: "JSON file with the full op payload (flags override)" }
|
|
6309
|
+
};
|
|
6310
|
+
var budgetsCommand = defineCommand30({
|
|
6311
|
+
meta: { name: "budgets", description: "Stage campaign budget create/update" },
|
|
6312
|
+
subCommands: {
|
|
6313
|
+
create: defineCommand30({
|
|
6314
|
+
meta: { name: "create", description: "Stage a campaign budget" },
|
|
6315
|
+
args: {
|
|
6316
|
+
...customerIdArg,
|
|
6317
|
+
...fileArg,
|
|
6318
|
+
name: { type: "string", description: "Budget name" },
|
|
6319
|
+
amount: { type: "string", description: "Daily amount in major currency units (e.g. 50)" },
|
|
6320
|
+
delivery: { type: "string", description: "STANDARD | ACCELERATED" },
|
|
6321
|
+
shared: { type: "boolean", description: "Explicitly shared budget" }
|
|
6322
|
+
},
|
|
6323
|
+
run: async ({ args }) => {
|
|
6324
|
+
const customerId = requireCustomerId(args);
|
|
6325
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6326
|
+
name: args.name,
|
|
6327
|
+
amountMicros: microsFlag(args.amount, "--amount"),
|
|
6328
|
+
deliveryMethod: args.delivery,
|
|
6329
|
+
explicitlyShared: args.shared || void 0
|
|
6330
|
+
});
|
|
6331
|
+
await stageCreate("google.budget.create", customerId, payload);
|
|
6332
|
+
}
|
|
6333
|
+
}),
|
|
6334
|
+
update: defineCommand30({
|
|
6335
|
+
meta: { name: "update", description: "Stage a budget update" },
|
|
6336
|
+
args: {
|
|
6337
|
+
...customerIdArg,
|
|
6338
|
+
...fileArg,
|
|
6339
|
+
name: { type: "string" },
|
|
6340
|
+
amount: { type: "string", description: "New daily amount in major currency units" },
|
|
6341
|
+
delivery: { type: "string" }
|
|
6342
|
+
},
|
|
6343
|
+
run: async ({ args }) => {
|
|
6344
|
+
const customerId = requireCustomerId(args);
|
|
6345
|
+
const target = requireTarget(args, "budget");
|
|
6346
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6347
|
+
name: args.name,
|
|
6348
|
+
amountMicros: microsFlag(args.amount, "--amount"),
|
|
6349
|
+
deliveryMethod: args.delivery
|
|
6350
|
+
});
|
|
6351
|
+
await stageUpdate("google.budget.update", customerId, target, payload);
|
|
6352
|
+
}
|
|
6353
|
+
})
|
|
6354
|
+
}
|
|
6355
|
+
});
|
|
6356
|
+
function biddingFromFlags(args) {
|
|
6357
|
+
const type = args["bidding-strategy"];
|
|
6358
|
+
if (!type) {
|
|
6359
|
+
return void 0;
|
|
6360
|
+
}
|
|
6361
|
+
return {
|
|
6362
|
+
type,
|
|
6363
|
+
targetCpaMicros: microsFlag(args["target-cpa"], "--target-cpa"),
|
|
6364
|
+
targetRoas: args["target-roas"] !== void 0 ? Number(args["target-roas"]) : void 0
|
|
6365
|
+
};
|
|
6366
|
+
}
|
|
6367
|
+
var campaignsCommand = defineCommand30({
|
|
6368
|
+
meta: { name: "campaigns", description: "Stage campaign create/update/pause/resume/remove" },
|
|
6369
|
+
subCommands: {
|
|
6370
|
+
create: defineCommand30({
|
|
6371
|
+
meta: { name: "create", description: "Stage a campaign" },
|
|
6372
|
+
args: {
|
|
6373
|
+
...customerIdArg,
|
|
6374
|
+
...fileArg,
|
|
6375
|
+
name: { type: "string" },
|
|
6376
|
+
"channel-type": {
|
|
6377
|
+
type: "string",
|
|
6378
|
+
description: "SEARCH | DISPLAY | SHOPPING | VIDEO | PERFORMANCE_MAX | DEMAND_GEN | \u2026"
|
|
6379
|
+
},
|
|
6380
|
+
"sub-type": { type: "string", description: "Advertising channel sub-type" },
|
|
6381
|
+
"budget-ref": { type: "string", description: "Budget ref (g_temp_*, id, or resource name)" },
|
|
6382
|
+
"bidding-strategy": {
|
|
6383
|
+
type: "string",
|
|
6384
|
+
description: "MANUAL_CPC | MAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS | \u2026"
|
|
6385
|
+
},
|
|
6386
|
+
"target-cpa": { type: "string", description: "Target CPA (major units) for TARGET_CPA" },
|
|
6387
|
+
"target-roas": { type: "string", description: "Target ROAS (e.g. 4.0) for TARGET_ROAS" },
|
|
6388
|
+
objective: { type: "string", description: "Advisory UI objective (SALES, LEADS, \u2026)" },
|
|
6389
|
+
"start-date": { type: "string", description: "YYYY-MM-DD" },
|
|
6390
|
+
"end-date": { type: "string", description: "YYYY-MM-DD" },
|
|
6391
|
+
status: { type: "string", description: "ENABLED | PAUSED (default PAUSED)" }
|
|
6392
|
+
},
|
|
6393
|
+
run: async ({ args }) => {
|
|
6394
|
+
const customerId = requireCustomerId(args);
|
|
6395
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6396
|
+
name: args.name,
|
|
6397
|
+
channelType: args["channel-type"],
|
|
6398
|
+
channelSubType: args["sub-type"],
|
|
6399
|
+
budget: args["budget-ref"],
|
|
6400
|
+
bidding: biddingFromFlags(args),
|
|
6401
|
+
objective: args.objective,
|
|
6402
|
+
startDate: args["start-date"],
|
|
6403
|
+
endDate: args["end-date"],
|
|
6404
|
+
status: args.status
|
|
6405
|
+
});
|
|
6406
|
+
await stageCreate("google.campaign.create", customerId, payload);
|
|
6407
|
+
}
|
|
6408
|
+
}),
|
|
6409
|
+
update: defineCommand30({
|
|
6410
|
+
meta: { name: "update", description: "Stage a campaign update" },
|
|
6411
|
+
args: {
|
|
6412
|
+
...customerIdArg,
|
|
6413
|
+
...fileArg,
|
|
6414
|
+
name: { type: "string" },
|
|
6415
|
+
"budget-ref": { type: "string" },
|
|
6416
|
+
"bidding-strategy": { type: "string" },
|
|
6417
|
+
"target-cpa": { type: "string" },
|
|
6418
|
+
"target-roas": { type: "string" },
|
|
6419
|
+
status: { type: "string" }
|
|
6420
|
+
},
|
|
6421
|
+
run: async ({ args }) => {
|
|
6422
|
+
const customerId = requireCustomerId(args);
|
|
6423
|
+
const target = requireTarget(args, "campaign");
|
|
6424
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6425
|
+
name: args.name,
|
|
6426
|
+
budget: args["budget-ref"],
|
|
6427
|
+
bidding: biddingFromFlags(args),
|
|
6428
|
+
status: args.status
|
|
6429
|
+
});
|
|
6430
|
+
await stageUpdate("google.campaign.update", customerId, target, payload);
|
|
6431
|
+
}
|
|
6432
|
+
}),
|
|
6433
|
+
pause: statusCommand2("google.campaign.pause", "campaign"),
|
|
6434
|
+
resume: statusCommand2("google.campaign.resume", "campaign"),
|
|
6435
|
+
remove: statusCommand2("google.campaign.remove", "campaign")
|
|
6436
|
+
}
|
|
6437
|
+
});
|
|
6438
|
+
function statusCommand2(kind, entity) {
|
|
6439
|
+
return defineCommand30({
|
|
6440
|
+
meta: { name: kind.split(".")[2], description: `Stage a ${entity} ${kind.split(".")[2]}` },
|
|
6441
|
+
args: {
|
|
6442
|
+
...customerIdArg,
|
|
6443
|
+
id: { type: "positional", description: `${entity} resource name or id`, required: false }
|
|
6444
|
+
},
|
|
6445
|
+
run: async ({ args }) => {
|
|
6446
|
+
const customerId = requireCustomerId(args);
|
|
6447
|
+
await stageTarget(kind, customerId, requireTarget(args, entity));
|
|
6448
|
+
}
|
|
6449
|
+
});
|
|
6450
|
+
}
|
|
6451
|
+
var adGroupsCommand = defineCommand30({
|
|
6452
|
+
meta: { name: "ad-groups", description: "Stage ad group create/update/pause/resume/remove" },
|
|
6453
|
+
subCommands: {
|
|
6454
|
+
create: defineCommand30({
|
|
6455
|
+
meta: { name: "create", description: "Stage an ad group" },
|
|
6456
|
+
args: {
|
|
6457
|
+
...customerIdArg,
|
|
6458
|
+
...fileArg,
|
|
6459
|
+
name: { type: "string" },
|
|
6460
|
+
"campaign-ref": { type: "string", description: "Campaign ref (g_temp_*, id, or resource name)" },
|
|
6461
|
+
type: { type: "string", description: "Ad group type (default SEARCH_STANDARD)" },
|
|
6462
|
+
"cpc-bid": { type: "string", description: "Default CPC bid in major units" },
|
|
6463
|
+
status: { type: "string" }
|
|
6464
|
+
},
|
|
6465
|
+
run: async ({ args }) => {
|
|
6466
|
+
const customerId = requireCustomerId(args);
|
|
6467
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6468
|
+
name: args.name,
|
|
6469
|
+
campaign: args["campaign-ref"],
|
|
6470
|
+
type: args.type,
|
|
6471
|
+
cpcBidMicros: microsFlag(args["cpc-bid"], "--cpc-bid"),
|
|
6472
|
+
status: args.status
|
|
6473
|
+
});
|
|
6474
|
+
await stageCreate("google.adGroup.create", customerId, payload);
|
|
6475
|
+
}
|
|
6476
|
+
}),
|
|
6477
|
+
update: defineCommand30({
|
|
6478
|
+
meta: { name: "update", description: "Stage an ad group update" },
|
|
6479
|
+
args: {
|
|
6480
|
+
...customerIdArg,
|
|
6481
|
+
...fileArg,
|
|
6482
|
+
name: { type: "string" },
|
|
6483
|
+
"cpc-bid": { type: "string" },
|
|
6484
|
+
status: { type: "string" }
|
|
6485
|
+
},
|
|
6486
|
+
run: async ({ args }) => {
|
|
6487
|
+
const customerId = requireCustomerId(args);
|
|
6488
|
+
const target = requireTarget(args, "ad group");
|
|
6489
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6490
|
+
name: args.name,
|
|
6491
|
+
cpcBidMicros: microsFlag(args["cpc-bid"], "--cpc-bid"),
|
|
6492
|
+
status: args.status
|
|
6493
|
+
});
|
|
6494
|
+
await stageUpdate("google.adGroup.update", customerId, target, payload);
|
|
6495
|
+
}
|
|
6496
|
+
}),
|
|
6497
|
+
pause: statusCommand2("google.adGroup.pause", "ad group"),
|
|
6498
|
+
resume: statusCommand2("google.adGroup.resume", "ad group"),
|
|
6499
|
+
remove: statusCommand2("google.adGroup.remove", "ad group")
|
|
6500
|
+
}
|
|
6501
|
+
});
|
|
6502
|
+
var keywordWriteSubcommands = {
|
|
6503
|
+
add: defineCommand30({
|
|
6504
|
+
meta: { name: "add", description: "Add keyword(s) to an ad group \u2014 one --text or a whole batch" },
|
|
6505
|
+
args: {
|
|
6506
|
+
...customerIdArg,
|
|
6507
|
+
"ad-group-ref": { type: "string", description: "Ad group ref (g_temp_*, id, or resource name)" },
|
|
6508
|
+
text: {
|
|
6509
|
+
type: "string",
|
|
6510
|
+
description: 'Keyword text \u2014 comma-separate for a batch, optional ":EXACT|:PHRASE|:BROAD" suffix per entry'
|
|
6511
|
+
},
|
|
6512
|
+
file: { type: "string", description: "Text file with one keyword[:MATCH_TYPE] per line" },
|
|
6513
|
+
"match-type": { type: "string", description: "Default match type: EXACT | PHRASE | BROAD" },
|
|
6514
|
+
"cpc-bid": { type: "string", description: "Keyword CPC bid in major units (applies to all)" },
|
|
6515
|
+
"final-url": { type: "string", description: "Keyword-level final URL (applies to all)" }
|
|
6516
|
+
},
|
|
6517
|
+
run: async ({ args }) => {
|
|
6518
|
+
const customerId = requireCustomerId(args);
|
|
6519
|
+
const adGroup = requireStringFlag(args["ad-group-ref"], "--ad-group-ref");
|
|
6520
|
+
const cpcBidMicros = microsFlag(args["cpc-bid"], "--cpc-bid");
|
|
6521
|
+
const finalUrls = args["final-url"] ? [args["final-url"]] : void 0;
|
|
6522
|
+
await stageGoogleOps(
|
|
6523
|
+
keywordEntries(args).map((entry) => ({
|
|
6524
|
+
kind: "google.keyword.add",
|
|
6525
|
+
customerId,
|
|
6526
|
+
payload: { adGroup, text: entry.text, matchType: entry.matchType, cpcBidMicros, finalUrls }
|
|
6527
|
+
}))
|
|
6528
|
+
);
|
|
6529
|
+
}
|
|
6530
|
+
}),
|
|
6531
|
+
update: defineCommand30({
|
|
6532
|
+
meta: { name: "update", description: "Update a keyword" },
|
|
6533
|
+
args: { ...customerIdArg, "cpc-bid": { type: "string" }, status: { type: "string" } },
|
|
6534
|
+
run: async ({ args }) => {
|
|
6535
|
+
const customerId = requireCustomerId(args);
|
|
6536
|
+
await stageUpdate("google.keyword.update", customerId, requireTarget(args, "keyword"), {
|
|
6537
|
+
cpcBidMicros: microsFlag(args["cpc-bid"], "--cpc-bid"),
|
|
6538
|
+
status: args.status
|
|
6539
|
+
});
|
|
6540
|
+
}
|
|
6541
|
+
}),
|
|
6542
|
+
remove: statusCommand2("google.keyword.remove", "keyword")
|
|
6543
|
+
};
|
|
6544
|
+
var negativeKeywordsCommand = defineCommand30({
|
|
6545
|
+
meta: { name: "negative-keywords", description: "Stage negative keyword add/remove (ad-group or campaign level)" },
|
|
6546
|
+
subCommands: {
|
|
6547
|
+
add: defineCommand30({
|
|
6548
|
+
meta: { name: "add", description: "Add negative keyword(s) \u2014 one --text or a whole batch" },
|
|
6549
|
+
args: {
|
|
6550
|
+
...customerIdArg,
|
|
6551
|
+
level: { type: "string", description: "adGroup | campaign" },
|
|
6552
|
+
"parent-ref": { type: "string", description: "Ad group or campaign ref" },
|
|
6553
|
+
text: {
|
|
6554
|
+
type: "string",
|
|
6555
|
+
description: 'Keyword text \u2014 comma-separate for a batch, optional ":MATCH_TYPE" suffix per entry'
|
|
6556
|
+
},
|
|
6557
|
+
file: { type: "string", description: "Text file with one keyword[:MATCH_TYPE] per line" },
|
|
6558
|
+
"match-type": { type: "string", description: "Default match type: EXACT | PHRASE | BROAD" }
|
|
6559
|
+
},
|
|
6560
|
+
run: async ({ args }) => {
|
|
6561
|
+
const customerId = requireCustomerId(args);
|
|
6562
|
+
const level = requireStringFlag(args.level, "--level");
|
|
6563
|
+
const parent = requireStringFlag(args["parent-ref"], "--parent-ref");
|
|
6564
|
+
await stageGoogleOps(
|
|
6565
|
+
keywordEntries(args).map((entry) => ({
|
|
6566
|
+
kind: "google.negativeKeyword.add",
|
|
6567
|
+
customerId,
|
|
6568
|
+
payload: { level, parent, text: entry.text, matchType: entry.matchType }
|
|
6569
|
+
}))
|
|
6570
|
+
);
|
|
6571
|
+
}
|
|
6572
|
+
}),
|
|
6573
|
+
remove: statusCommand2("google.negativeKeyword.remove", "negative keyword")
|
|
6574
|
+
}
|
|
6575
|
+
});
|
|
6576
|
+
var keywordListsCommand = defineCommand30({
|
|
6577
|
+
meta: {
|
|
6578
|
+
name: "keyword-lists",
|
|
6579
|
+
description: "Stage shared negative keyword lists (create/add/attach/detach). Build at least one shared negative list (brand, competitor, junk-intent terms) and attach it to every campaign to protect spend."
|
|
6580
|
+
},
|
|
6581
|
+
subCommands: {
|
|
6582
|
+
create: defineCommand30({
|
|
6583
|
+
meta: { name: "create", description: "Create a shared negative keyword list" },
|
|
6584
|
+
args: {
|
|
6585
|
+
...customerIdArg,
|
|
6586
|
+
name: { type: "string" },
|
|
6587
|
+
type: {
|
|
6588
|
+
type: "string",
|
|
6589
|
+
description: "NEGATIVE_KEYWORDS (default) | NEGATIVE_PLACEMENTS | ACCOUNT_LEVEL_NEGATIVE_KEYWORDS"
|
|
6590
|
+
}
|
|
6591
|
+
},
|
|
6592
|
+
run: async ({ args }) => {
|
|
6593
|
+
const customerId = requireCustomerId(args);
|
|
6594
|
+
await stageCreate("google.sharedSet.create", customerId, {
|
|
6595
|
+
name: requireStringFlag(args.name, "--name"),
|
|
6596
|
+
type: args.type
|
|
6597
|
+
});
|
|
6598
|
+
}
|
|
6599
|
+
}),
|
|
6600
|
+
add: defineCommand30({
|
|
6601
|
+
meta: { name: "add", description: "Add keyword(s) to a shared list \u2014 one --text or a whole batch" },
|
|
6602
|
+
args: {
|
|
6603
|
+
...customerIdArg,
|
|
6604
|
+
"list-ref": { type: "string", description: "Shared set ref" },
|
|
6605
|
+
text: {
|
|
6606
|
+
type: "string",
|
|
6607
|
+
description: 'Keyword text \u2014 comma-separate for a batch, optional ":MATCH_TYPE" suffix per entry'
|
|
6608
|
+
},
|
|
6609
|
+
file: { type: "string", description: "Text file with one keyword[:MATCH_TYPE] per line" },
|
|
6610
|
+
"match-type": { type: "string", description: "Default match type: EXACT | PHRASE | BROAD" }
|
|
6611
|
+
},
|
|
6612
|
+
run: async ({ args }) => {
|
|
6613
|
+
const customerId = requireCustomerId(args);
|
|
6614
|
+
const sharedSet = requireStringFlag(args["list-ref"], "--list-ref");
|
|
6615
|
+
await stageGoogleOps(
|
|
6616
|
+
keywordEntries(args).map((entry) => ({
|
|
6617
|
+
kind: "google.sharedSetMember.add",
|
|
6618
|
+
customerId,
|
|
6619
|
+
payload: { sharedSet, text: entry.text, matchType: entry.matchType }
|
|
6620
|
+
}))
|
|
6621
|
+
);
|
|
6622
|
+
}
|
|
6623
|
+
}),
|
|
6624
|
+
attach: defineCommand30({
|
|
6625
|
+
meta: { name: "attach", description: "Attach a keyword list to a campaign" },
|
|
6626
|
+
args: { ...customerIdArg, "campaign-ref": { type: "string" }, "list-ref": { type: "string" } },
|
|
6627
|
+
run: async ({ args }) => {
|
|
6628
|
+
const customerId = requireCustomerId(args);
|
|
6629
|
+
await stageCreate("google.campaignSharedSet.attach", customerId, {
|
|
6630
|
+
campaign: requireStringFlag(args["campaign-ref"], "--campaign-ref"),
|
|
6631
|
+
sharedSet: requireStringFlag(args["list-ref"], "--list-ref")
|
|
6632
|
+
});
|
|
6633
|
+
}
|
|
6634
|
+
}),
|
|
6635
|
+
detach: statusCommand2("google.campaignSharedSet.detach", "campaign shared set")
|
|
6636
|
+
}
|
|
6637
|
+
});
|
|
6638
|
+
function rsaContentFromFlags(args) {
|
|
6639
|
+
const headlines = listFlag(args.headlines);
|
|
6640
|
+
const descriptions = listFlag(args.descriptions);
|
|
6641
|
+
if (!headlines || !descriptions) {
|
|
6642
|
+
failWriteValidation("responsive search ads need --headlines and --descriptions (comma-separated), or use --file");
|
|
6643
|
+
}
|
|
6644
|
+
const finalUrls = listFlag(args["final-url"]);
|
|
6645
|
+
if (!finalUrls) {
|
|
6646
|
+
failWriteValidation("--final-url is required for a responsive search ad");
|
|
6647
|
+
}
|
|
6648
|
+
return {
|
|
6649
|
+
format: "responsiveSearch",
|
|
6650
|
+
headlines: headlines.map((text) => ({ text })),
|
|
6651
|
+
descriptions: descriptions.map((text) => ({ text })),
|
|
6652
|
+
path1: args.path1,
|
|
6653
|
+
path2: args.path2,
|
|
6654
|
+
finalUrls
|
|
6655
|
+
};
|
|
6656
|
+
}
|
|
6657
|
+
var adsCommand = defineCommand30({
|
|
6658
|
+
meta: { name: "ads", description: "Stage ad create/update/pause/resume/remove" },
|
|
6659
|
+
subCommands: {
|
|
6660
|
+
create: defineCommand30({
|
|
6661
|
+
meta: {
|
|
6662
|
+
name: "create",
|
|
6663
|
+
description: "Stage an ad (responsive search via flags; other formats via --file). RSA needs 3\u201315 headlines and 2\u20134 descriptions \u2014 give Google 8\u201312 varied headlines to test, and stage 2\u20134 ads per ad group."
|
|
6664
|
+
},
|
|
6665
|
+
args: {
|
|
6666
|
+
...customerIdArg,
|
|
6667
|
+
...fileArg,
|
|
6668
|
+
"ad-group-ref": { type: "string", description: "Ad group ref" },
|
|
6669
|
+
format: {
|
|
6670
|
+
type: "string",
|
|
6671
|
+
description: "responsiveSearch (default) | responsiveDisplay | performanceMaxAssetGroup | call | app | video | demandGen"
|
|
6672
|
+
},
|
|
6673
|
+
headlines: { type: "string", description: "Comma-separated headlines (RSA)" },
|
|
6674
|
+
descriptions: { type: "string", description: "Comma-separated descriptions (RSA)" },
|
|
6675
|
+
path1: { type: "string" },
|
|
6676
|
+
path2: { type: "string" },
|
|
6677
|
+
"final-url": { type: "string", description: "Comma-separated final URLs" },
|
|
6678
|
+
status: { type: "string" }
|
|
6679
|
+
},
|
|
6680
|
+
run: async ({ args }) => {
|
|
6681
|
+
const customerId = requireCustomerId(args);
|
|
6682
|
+
const file = loadJsonFileArg(args.file);
|
|
6683
|
+
const format = args.format ?? "responsiveSearch";
|
|
6684
|
+
const content = file.content ?? (format === "responsiveSearch" ? rsaContentFromFlags(args) : failWriteValidation(`--format ${format} needs --file with the ad content`));
|
|
6685
|
+
await stageCreate("google.ad.create", customerId, {
|
|
6686
|
+
adGroup: requireStringFlag(args["ad-group-ref"] ?? file.adGroup, "--ad-group-ref"),
|
|
6687
|
+
status: args.status ?? file.status,
|
|
6688
|
+
content
|
|
6689
|
+
});
|
|
6690
|
+
}
|
|
6691
|
+
}),
|
|
6692
|
+
update: defineCommand30({
|
|
6693
|
+
meta: { name: "update", description: "Stage an ad update" },
|
|
6694
|
+
args: { ...customerIdArg, ...fileArg, status: { type: "string" } },
|
|
6695
|
+
run: async ({ args }) => {
|
|
6696
|
+
const customerId = requireCustomerId(args);
|
|
6697
|
+
const file = loadJsonFileArg(args.file);
|
|
6698
|
+
await stageUpdate(
|
|
6699
|
+
"google.ad.update",
|
|
6700
|
+
customerId,
|
|
6701
|
+
requireTarget(args, "ad"),
|
|
6702
|
+
mergePayload(file, { status: args.status })
|
|
6703
|
+
);
|
|
6704
|
+
}
|
|
6705
|
+
}),
|
|
6706
|
+
pause: statusCommand2("google.ad.pause", "ad"),
|
|
6707
|
+
resume: statusCommand2("google.ad.resume", "ad"),
|
|
6708
|
+
remove: statusCommand2("google.ad.remove", "ad")
|
|
6709
|
+
}
|
|
6710
|
+
});
|
|
6711
|
+
function fileCreateCommand(name, kind, description) {
|
|
6712
|
+
return defineCommand30({
|
|
6713
|
+
meta: { name, description },
|
|
6714
|
+
args: { ...customerIdArg, ...fileArg },
|
|
6715
|
+
run: async ({ args }) => {
|
|
6716
|
+
const customerId = requireCustomerId(args);
|
|
6717
|
+
const payload = loadJsonFileArg(args.file);
|
|
6718
|
+
if (Object.keys(payload).length === 0) {
|
|
6719
|
+
failWriteValidation(`${kind} needs --file with the op payload`);
|
|
6720
|
+
}
|
|
6721
|
+
await stageGoogleOp({ kind, customerId, payload });
|
|
6722
|
+
}
|
|
6723
|
+
});
|
|
6724
|
+
}
|
|
6725
|
+
var assetsCommand = defineCommand30({
|
|
6726
|
+
meta: {
|
|
6727
|
+
name: "assets",
|
|
6728
|
+
description: "Stage asset create + asset-link attach/detach (via --file). For a high-performance Search campaign add \u22654 sitelinks, \u22653 callouts, and \u22651 structured snippet per campaign."
|
|
6729
|
+
},
|
|
6730
|
+
subCommands: {
|
|
6731
|
+
create: fileCreateCommand(
|
|
6732
|
+
"create",
|
|
6733
|
+
"google.asset.create",
|
|
6734
|
+
"Stage an asset (text/image/sitelink/callout/structuredSnippet/\u2026)"
|
|
6735
|
+
),
|
|
6736
|
+
attach: fileCreateCommand("attach", "google.assetLink.attach", "Attach an asset to a campaign/adGroup/customer"),
|
|
6737
|
+
detach: statusCommand2("google.assetLink.detach", "asset link")
|
|
6738
|
+
}
|
|
6739
|
+
});
|
|
6740
|
+
var audiencesCommand = defineCommand30({
|
|
6741
|
+
meta: { name: "audiences", description: "Stage audience (user list) create + criterion attach/detach (via --file)" },
|
|
6742
|
+
subCommands: {
|
|
6743
|
+
create: fileCreateCommand("create", "google.audience.create", "Stage a user-list audience"),
|
|
6744
|
+
attach: fileCreateCommand(
|
|
6745
|
+
"attach",
|
|
6746
|
+
"google.audienceCriterion.attach",
|
|
6747
|
+
"Target/exclude an audience on a campaign/adGroup"
|
|
6748
|
+
),
|
|
6749
|
+
detach: statusCommand2("google.audienceCriterion.detach", "audience criterion")
|
|
6750
|
+
}
|
|
6751
|
+
});
|
|
6752
|
+
var conversionsCommand = defineCommand30({
|
|
6753
|
+
meta: { name: "conversions", description: "Stage conversion action create/update (via --file)" },
|
|
6754
|
+
subCommands: {
|
|
6755
|
+
create: fileCreateCommand("create", "google.conversionAction.create", "Stage a conversion action"),
|
|
6756
|
+
update: defineCommand30({
|
|
6757
|
+
meta: { name: "update", description: "Stage a conversion action update" },
|
|
6758
|
+
args: { ...customerIdArg, ...fileArg },
|
|
6759
|
+
run: async ({ args }) => {
|
|
6760
|
+
const customerId = requireCustomerId(args);
|
|
6761
|
+
await stageUpdate(
|
|
6762
|
+
"google.conversionAction.update",
|
|
6763
|
+
customerId,
|
|
6764
|
+
requireTarget(args, "conversion action"),
|
|
6765
|
+
loadJsonFileArg(args.file)
|
|
6766
|
+
);
|
|
6767
|
+
}
|
|
6768
|
+
})
|
|
6769
|
+
}
|
|
6770
|
+
});
|
|
6771
|
+
var biddingStrategiesCommand = defineCommand30({
|
|
6772
|
+
meta: { name: "bidding-strategies", description: "Stage portfolio bidding strategy create/update (via --file)" },
|
|
6773
|
+
subCommands: {
|
|
6774
|
+
create: fileCreateCommand("create", "google.biddingStrategy.create", "Stage a portfolio bidding strategy"),
|
|
6775
|
+
update: defineCommand30({
|
|
6776
|
+
meta: { name: "update", description: "Stage a portfolio bidding strategy update" },
|
|
6777
|
+
args: { ...customerIdArg, ...fileArg },
|
|
6778
|
+
run: async ({ args }) => {
|
|
6779
|
+
const customerId = requireCustomerId(args);
|
|
6780
|
+
await stageUpdate(
|
|
6781
|
+
"google.biddingStrategy.update",
|
|
6782
|
+
customerId,
|
|
6783
|
+
requireTarget(args, "bidding strategy"),
|
|
6784
|
+
loadJsonFileArg(args.file)
|
|
6785
|
+
);
|
|
6786
|
+
}
|
|
6787
|
+
})
|
|
6788
|
+
}
|
|
6789
|
+
});
|
|
6790
|
+
var labelsCommand = defineCommand30({
|
|
6791
|
+
meta: { name: "labels", description: "Stage label create + attach (via --file)" },
|
|
6792
|
+
subCommands: {
|
|
6793
|
+
create: defineCommand30({
|
|
6794
|
+
meta: { name: "create", description: "Create a label" },
|
|
6795
|
+
args: {
|
|
6796
|
+
...customerIdArg,
|
|
6797
|
+
name: { type: "string" },
|
|
6798
|
+
"background-color": { type: "string" },
|
|
6799
|
+
description: { type: "string" }
|
|
6800
|
+
},
|
|
6801
|
+
run: async ({ args }) => {
|
|
6802
|
+
const customerId = requireCustomerId(args);
|
|
6803
|
+
await stageCreate("google.label.create", customerId, {
|
|
6804
|
+
name: requireStringFlag(args.name, "--name"),
|
|
6805
|
+
backgroundColor: args["background-color"],
|
|
6806
|
+
description: args.description
|
|
6807
|
+
});
|
|
6808
|
+
}
|
|
6809
|
+
}),
|
|
6810
|
+
attach: fileCreateCommand("attach", "google.label.attach", "Attach a label to a campaign/adGroup/ad")
|
|
6811
|
+
}
|
|
6812
|
+
});
|
|
6813
|
+
var campaignCriteriaCommand = defineCommand30({
|
|
6814
|
+
meta: {
|
|
6815
|
+
name: "campaign-criteria",
|
|
6816
|
+
description: "Stage campaign criteria (location/language/adSchedule/device) add/remove (via --file)"
|
|
6817
|
+
},
|
|
6818
|
+
subCommands: {
|
|
6819
|
+
add: fileCreateCommand("add", "google.campaignCriterion.add", "Add a campaign criterion"),
|
|
6820
|
+
remove: statusCommand2("google.campaignCriterion.remove", "campaign criterion")
|
|
6821
|
+
}
|
|
6822
|
+
});
|
|
6823
|
+
var googleWriteCommands = {
|
|
6824
|
+
budgets: budgetsCommand,
|
|
6825
|
+
campaigns: campaignsCommand,
|
|
6826
|
+
"ad-groups": adGroupsCommand,
|
|
6827
|
+
"negative-keywords": negativeKeywordsCommand,
|
|
6828
|
+
"keyword-lists": keywordListsCommand,
|
|
6829
|
+
ads: adsCommand,
|
|
6830
|
+
assets: assetsCommand,
|
|
6831
|
+
audiences: audiencesCommand,
|
|
6832
|
+
conversions: conversionsCommand,
|
|
6833
|
+
"bidding-strategies": biddingStrategiesCommand,
|
|
6834
|
+
labels: labelsCommand,
|
|
6835
|
+
"campaign-criteria": campaignCriteriaCommand
|
|
6836
|
+
};
|
|
6837
|
+
|
|
5148
6838
|
// src/commands/ads/google/index.ts
|
|
5149
|
-
var
|
|
6839
|
+
var keywordsWithWrites = defineCommand31({
|
|
6840
|
+
meta: keywordsCommand.meta,
|
|
6841
|
+
subCommands: { ...keywordsCommand.subCommands, ...keywordWriteSubcommands }
|
|
6842
|
+
});
|
|
6843
|
+
var googleCommand = defineCommand31({
|
|
5150
6844
|
meta: {
|
|
5151
6845
|
name: "google",
|
|
5152
6846
|
description: `Google Ads commands. Query campaigns, keywords, search terms, and more via GAQL.
|
|
@@ -5161,20 +6855,28 @@ Examples:
|
|
|
5161
6855
|
baker ads google query --preset campaign-performance --customer-id 1234567890
|
|
5162
6856
|
baker ads google currency --customer-id 1234567890
|
|
5163
6857
|
baker ads google keywords discover --customer-id 1234567890 --seeds "running shoes"
|
|
5164
|
-
baker ads google library list-advertisers \u2014 list tracked Google advertisers
|
|
6858
|
+
baker ads google library list-advertisers \u2014 list tracked Google advertisers
|
|
6859
|
+
|
|
6860
|
+
Staged writes (never touch Google until the chat is published):
|
|
6861
|
+
baker ads google budgets create --customer-id 1234567890 --name "Search" --amount 50
|
|
6862
|
+
baker ads google campaigns create --customer-id 1234567890 --name "Brand" --channel-type SEARCH --budget-ref g_temp_\u2026 --bidding-strategy MANUAL_CPC
|
|
6863
|
+
baker ads google keyword-lists create --customer-id 1234567890 --name "Brand exclusions"
|
|
6864
|
+
baker ads google draft list \u2014 review staged Google Ads changes`
|
|
5165
6865
|
},
|
|
5166
6866
|
subCommands: {
|
|
5167
6867
|
accounts: accountsCommand,
|
|
5168
6868
|
currency: currencyCommand,
|
|
5169
6869
|
changes: changesCommand,
|
|
5170
6870
|
query: queryCommand,
|
|
5171
|
-
keywords:
|
|
5172
|
-
library
|
|
6871
|
+
keywords: keywordsWithWrites,
|
|
6872
|
+
library,
|
|
6873
|
+
...googleWriteCommands,
|
|
6874
|
+
draft: draftCommand2
|
|
5173
6875
|
}
|
|
5174
6876
|
});
|
|
5175
6877
|
|
|
5176
6878
|
// src/commands/ads/linkedin/index.ts
|
|
5177
|
-
import { defineCommand as
|
|
6879
|
+
import { defineCommand as defineCommand51 } from "citty";
|
|
5178
6880
|
|
|
5179
6881
|
// src/commands/ads/linkedin/schemas.ts
|
|
5180
6882
|
registerSchema({
|
|
@@ -5835,7 +7537,7 @@ registerSchema({
|
|
|
5835
7537
|
});
|
|
5836
7538
|
|
|
5837
7539
|
// src/commands/ads/linkedin/account.ts
|
|
5838
|
-
import { defineCommand as
|
|
7540
|
+
import { defineCommand as defineCommand32 } from "citty";
|
|
5839
7541
|
|
|
5840
7542
|
// src/commands/ads/linkedin/shared.ts
|
|
5841
7543
|
var DAY_MS2 = 864e5;
|
|
@@ -5938,7 +7640,7 @@ function resolveStatusFilter(args) {
|
|
|
5938
7640
|
}
|
|
5939
7641
|
|
|
5940
7642
|
// src/commands/ads/linkedin/account.ts
|
|
5941
|
-
var accountCommand =
|
|
7643
|
+
var accountCommand = defineCommand32({
|
|
5942
7644
|
meta: {
|
|
5943
7645
|
name: "account",
|
|
5944
7646
|
description: `Single LinkedIn ad account detail (currency, status, type).
|
|
@@ -5972,9 +7674,9 @@ Examples:
|
|
|
5972
7674
|
});
|
|
5973
7675
|
|
|
5974
7676
|
// src/commands/ads/linkedin/accounts.ts
|
|
5975
|
-
import { defineCommand as
|
|
7677
|
+
import { defineCommand as defineCommand33 } from "citty";
|
|
5976
7678
|
var ACCOUNTS_TTL_MS = 60 * 60 * 1e3;
|
|
5977
|
-
var accountsCommand2 =
|
|
7679
|
+
var accountsCommand2 = defineCommand33({
|
|
5978
7680
|
meta: {
|
|
5979
7681
|
name: "accounts",
|
|
5980
7682
|
description: `List LinkedIn ad accounts in this company's connected scope.
|
|
@@ -6022,7 +7724,7 @@ Examples:
|
|
|
6022
7724
|
});
|
|
6023
7725
|
|
|
6024
7726
|
// src/commands/ads/linkedin/analytics.ts
|
|
6025
|
-
import { defineCommand as
|
|
7727
|
+
import { defineCommand as defineCommand34 } from "citty";
|
|
6026
7728
|
|
|
6027
7729
|
// src/commands/ads/linkedin/presets.ts
|
|
6028
7730
|
var INTENTS = {
|
|
@@ -6294,7 +7996,7 @@ function numberOf(v) {
|
|
|
6294
7996
|
}
|
|
6295
7997
|
return 0;
|
|
6296
7998
|
}
|
|
6297
|
-
var analyticsCommand =
|
|
7999
|
+
var analyticsCommand = defineCommand34({
|
|
6298
8000
|
meta: {
|
|
6299
8001
|
name: "analytics",
|
|
6300
8002
|
description: `Performance reporting \u2014 the workhorse for AI agents.
|
|
@@ -6421,8 +8123,8 @@ Examples \u2014 common AI questions:
|
|
|
6421
8123
|
});
|
|
6422
8124
|
|
|
6423
8125
|
// src/commands/ads/linkedin/audience-size.ts
|
|
6424
|
-
import { readFileSync as
|
|
6425
|
-
import { defineCommand as
|
|
8126
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
8127
|
+
import { defineCommand as defineCommand35 } from "citty";
|
|
6426
8128
|
function loadTargeting(args) {
|
|
6427
8129
|
const inline = args.targeting;
|
|
6428
8130
|
if (inline) {
|
|
@@ -6435,7 +8137,7 @@ function loadTargeting(args) {
|
|
|
6435
8137
|
const file = args["targeting-file"];
|
|
6436
8138
|
if (file) {
|
|
6437
8139
|
try {
|
|
6438
|
-
return JSON.parse(
|
|
8140
|
+
return JSON.parse(readFileSync5(file, "utf-8"));
|
|
6439
8141
|
} catch (e) {
|
|
6440
8142
|
handleLinkedinError(
|
|
6441
8143
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -6444,7 +8146,7 @@ function loadTargeting(args) {
|
|
|
6444
8146
|
}
|
|
6445
8147
|
handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
|
|
6446
8148
|
}
|
|
6447
|
-
var audienceSizeCommand =
|
|
8149
|
+
var audienceSizeCommand = defineCommand35({
|
|
6448
8150
|
meta: {
|
|
6449
8151
|
name: "audience-size",
|
|
6450
8152
|
description: `Estimate audience size for a targeting payload \u2014 pre-launch sanity check.
|
|
@@ -6489,7 +8191,7 @@ Examples:
|
|
|
6489
8191
|
});
|
|
6490
8192
|
|
|
6491
8193
|
// src/commands/ads/linkedin/audit.ts
|
|
6492
|
-
import { defineCommand as
|
|
8194
|
+
import { defineCommand as defineCommand36 } from "citty";
|
|
6493
8195
|
var SEVERITY_RANK = {
|
|
6494
8196
|
critical: 0,
|
|
6495
8197
|
high: 1,
|
|
@@ -6548,7 +8250,7 @@ function noteOf(f) {
|
|
|
6548
8250
|
const fix = f.fix?.explanation ?? "";
|
|
6549
8251
|
return [fix, ev].filter(Boolean).join(" \u2014 ");
|
|
6550
8252
|
}
|
|
6551
|
-
var auditCommand =
|
|
8253
|
+
var auditCommand = defineCommand36({
|
|
6552
8254
|
meta: {
|
|
6553
8255
|
name: "audit",
|
|
6554
8256
|
description: `Run a LinkedIn Ads playbook audit \u2014 30+ checks across Settings, Tracking,
|
|
@@ -6614,8 +8316,8 @@ Examples:
|
|
|
6614
8316
|
});
|
|
6615
8317
|
|
|
6616
8318
|
// src/commands/ads/linkedin/bid-pricing.ts
|
|
6617
|
-
import { readFileSync as
|
|
6618
|
-
import { defineCommand as
|
|
8319
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
8320
|
+
import { defineCommand as defineCommand37 } from "citty";
|
|
6619
8321
|
function loadTargeting2(args) {
|
|
6620
8322
|
const inline = args.targeting;
|
|
6621
8323
|
if (inline) {
|
|
@@ -6628,7 +8330,7 @@ function loadTargeting2(args) {
|
|
|
6628
8330
|
const file = args["targeting-file"];
|
|
6629
8331
|
if (file) {
|
|
6630
8332
|
try {
|
|
6631
|
-
return JSON.parse(
|
|
8333
|
+
return JSON.parse(readFileSync6(file, "utf-8"));
|
|
6632
8334
|
} catch (e) {
|
|
6633
8335
|
handleLinkedinError(
|
|
6634
8336
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -6637,7 +8339,7 @@ function loadTargeting2(args) {
|
|
|
6637
8339
|
}
|
|
6638
8340
|
handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
|
|
6639
8341
|
}
|
|
6640
|
-
var bidPricingCommand =
|
|
8342
|
+
var bidPricingCommand = defineCommand37({
|
|
6641
8343
|
meta: {
|
|
6642
8344
|
name: "bid-pricing",
|
|
6643
8345
|
description: `Get LinkedIn's suggested bid range for a targeting + objective + cost type.
|
|
@@ -6687,40 +8389,40 @@ Examples:
|
|
|
6687
8389
|
});
|
|
6688
8390
|
|
|
6689
8391
|
// src/commands/ads/linkedin/campaign-groups.ts
|
|
6690
|
-
import { defineCommand as
|
|
8392
|
+
import { defineCommand as defineCommand39 } from "citty";
|
|
6691
8393
|
|
|
6692
8394
|
// src/commands/ads/linkedin/write-commands.ts
|
|
6693
|
-
import { defineCommand as
|
|
8395
|
+
import { defineCommand as defineCommand38 } from "citty";
|
|
6694
8396
|
|
|
6695
8397
|
// src/commands/ads/linkedin/write-shared.ts
|
|
6696
8398
|
import { createHash as createHash2 } from "crypto";
|
|
6697
|
-
import { readFileSync as
|
|
8399
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
6698
8400
|
function bareAccountId(args) {
|
|
6699
8401
|
const raw = resolveAccountIdArg(args);
|
|
6700
8402
|
return raw.replace(/^urn:li:sponsoredAccount:/, "").replace(/^sponsoredAccount:/, "");
|
|
6701
8403
|
}
|
|
6702
|
-
function
|
|
8404
|
+
function failWriteValidation2(message) {
|
|
6703
8405
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
6704
8406
|
process.exit(1);
|
|
6705
8407
|
}
|
|
6706
|
-
function
|
|
8408
|
+
function loadJsonFileArg2(path12) {
|
|
6707
8409
|
if (typeof path12 !== "string" || path12.length === 0) {
|
|
6708
8410
|
return {};
|
|
6709
8411
|
}
|
|
6710
8412
|
try {
|
|
6711
|
-
const parsed = JSON.parse(
|
|
8413
|
+
const parsed = JSON.parse(readFileSync7(path12, "utf8"));
|
|
6712
8414
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
6713
|
-
|
|
8415
|
+
failWriteValidation2(`${path12} must contain a JSON object`);
|
|
6714
8416
|
}
|
|
6715
8417
|
return parsed;
|
|
6716
8418
|
} catch (err) {
|
|
6717
8419
|
if (err instanceof SyntaxError) {
|
|
6718
|
-
|
|
8420
|
+
failWriteValidation2(`${path12} is not valid JSON: ${err.message}`);
|
|
6719
8421
|
}
|
|
6720
8422
|
throw err;
|
|
6721
8423
|
}
|
|
6722
8424
|
}
|
|
6723
|
-
function
|
|
8425
|
+
function mergePayload2(file, flags) {
|
|
6724
8426
|
const merged = { ...file };
|
|
6725
8427
|
for (const [key, value] of Object.entries(flags)) {
|
|
6726
8428
|
if (value !== void 0) {
|
|
@@ -6737,7 +8439,7 @@ function parseMoneyFlag(amount, currency, flag) {
|
|
|
6737
8439
|
return { amount: String(amount) };
|
|
6738
8440
|
}
|
|
6739
8441
|
if (typeof currency !== "string" || currency.length !== 3) {
|
|
6740
|
-
|
|
8442
|
+
failWriteValidation2(`${flag} got an invalid --currency (expected a 3-letter code like EUR)`);
|
|
6741
8443
|
}
|
|
6742
8444
|
return { amount: String(amount), currencyCode: currency.toUpperCase() };
|
|
6743
8445
|
}
|
|
@@ -6751,7 +8453,7 @@ function parseDateFlag(value, flag) {
|
|
|
6751
8453
|
}
|
|
6752
8454
|
const parsed = Date.parse(raw);
|
|
6753
8455
|
if (Number.isNaN(parsed)) {
|
|
6754
|
-
|
|
8456
|
+
failWriteValidation2(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);
|
|
6755
8457
|
}
|
|
6756
8458
|
return parsed;
|
|
6757
8459
|
}
|
|
@@ -6766,7 +8468,7 @@ function parseOnOffFlag(value, flag) {
|
|
|
6766
8468
|
if (raw === "off" || raw === "false") {
|
|
6767
8469
|
return false;
|
|
6768
8470
|
}
|
|
6769
|
-
|
|
8471
|
+
failWriteValidation2(`${flag} must be on|off`);
|
|
6770
8472
|
}
|
|
6771
8473
|
function parseLocaleFlag(value) {
|
|
6772
8474
|
if (value === void 0 || value === null || value === "") {
|
|
@@ -6774,7 +8476,7 @@ function parseLocaleFlag(value) {
|
|
|
6774
8476
|
}
|
|
6775
8477
|
const match = /^([a-z]{2})[_-]([A-Za-z]{2})$/.exec(String(value));
|
|
6776
8478
|
if (!match) {
|
|
6777
|
-
|
|
8479
|
+
failWriteValidation2("--locale must look like en_US (language_COUNTRY)");
|
|
6778
8480
|
}
|
|
6779
8481
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
6780
8482
|
}
|
|
@@ -6782,10 +8484,10 @@ function loadTargetingFileArg(path12) {
|
|
|
6782
8484
|
if (typeof path12 !== "string" || path12.length === 0) {
|
|
6783
8485
|
return void 0;
|
|
6784
8486
|
}
|
|
6785
|
-
const parsed =
|
|
8487
|
+
const parsed = loadJsonFileArg2(path12);
|
|
6786
8488
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
6787
8489
|
if (!criteria.include) {
|
|
6788
|
-
|
|
8490
|
+
failWriteValidation2(
|
|
6789
8491
|
`${path12} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
6790
8492
|
);
|
|
6791
8493
|
}
|
|
@@ -6825,10 +8527,10 @@ function parseListFileArg(path12, maxRows) {
|
|
|
6825
8527
|
if (typeof path12 !== "string" || path12.length === 0) {
|
|
6826
8528
|
return void 0;
|
|
6827
8529
|
}
|
|
6828
|
-
const raw =
|
|
8530
|
+
const raw = readFileSync7(path12, "utf8");
|
|
6829
8531
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
6830
8532
|
if (lines.length < 2) {
|
|
6831
|
-
|
|
8533
|
+
failWriteValidation2(`${path12} needs a header row and at least one data row`);
|
|
6832
8534
|
}
|
|
6833
8535
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
6834
8536
|
const rows = [];
|
|
@@ -6847,7 +8549,7 @@ function parseListFileArg(path12, maxRows) {
|
|
|
6847
8549
|
}
|
|
6848
8550
|
}
|
|
6849
8551
|
if (rows.length > maxRows) {
|
|
6850
|
-
|
|
8552
|
+
failWriteValidation2(`${path12} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
6851
8553
|
}
|
|
6852
8554
|
return { columns, rows };
|
|
6853
8555
|
}
|
|
@@ -6883,10 +8585,10 @@ async function stageStatusChange(input) {
|
|
|
6883
8585
|
const payload = input.kind === "creative.update" ? { intendedStatus: input.status } : { status: input.status };
|
|
6884
8586
|
await stageOp({ kind: input.kind, accountId: input.accountId, target: input.target, payload });
|
|
6885
8587
|
}
|
|
6886
|
-
function
|
|
8588
|
+
function requireTarget2(args, entity) {
|
|
6887
8589
|
const target = args.id ?? args.target;
|
|
6888
8590
|
if (typeof target !== "string" || target.length === 0) {
|
|
6889
|
-
|
|
8591
|
+
failWriteValidation2(`pass the ${entity} id or URN as the positional argument`);
|
|
6890
8592
|
}
|
|
6891
8593
|
return target;
|
|
6892
8594
|
}
|
|
@@ -6905,7 +8607,7 @@ function runScheduleFromFlags(args) {
|
|
|
6905
8607
|
}
|
|
6906
8608
|
return { ...start !== void 0 ? { start } : {}, ...end !== void 0 ? { end } : {} };
|
|
6907
8609
|
}
|
|
6908
|
-
var campaignGroupsCreateCommand =
|
|
8610
|
+
var campaignGroupsCreateCommand = defineCommand38({
|
|
6909
8611
|
meta: {
|
|
6910
8612
|
name: "create",
|
|
6911
8613
|
description: `Stage a new campaign group. ${STAGED_NOTE}
|
|
@@ -6923,7 +8625,7 @@ Example: baker ads linkedin campaign-groups create --name "Q3 ABM" --start 2026-
|
|
|
6923
8625
|
},
|
|
6924
8626
|
run: async ({ args }) => {
|
|
6925
8627
|
const accountId = bareAccountId(args);
|
|
6926
|
-
const payload =
|
|
8628
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
6927
8629
|
name: args.name,
|
|
6928
8630
|
runSchedule: runScheduleFromFlags(args),
|
|
6929
8631
|
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
@@ -6932,7 +8634,7 @@ Example: baker ads linkedin campaign-groups create --name "Q3 ABM" --start 2026-
|
|
|
6932
8634
|
await stageOp({ kind: "campaignGroup.create", accountId, payload });
|
|
6933
8635
|
}
|
|
6934
8636
|
});
|
|
6935
|
-
var campaignGroupsUpdateCommand =
|
|
8637
|
+
var campaignGroupsUpdateCommand = defineCommand38({
|
|
6936
8638
|
meta: {
|
|
6937
8639
|
name: "update",
|
|
6938
8640
|
description: `Stage changes to an existing campaign group. ${STAGED_NOTE}
|
|
@@ -6952,7 +8654,7 @@ Example: baker ads linkedin campaign-groups update 635137195 --total-budget 8000
|
|
|
6952
8654
|
},
|
|
6953
8655
|
run: async ({ args }) => {
|
|
6954
8656
|
const accountId = bareAccountId(args);
|
|
6955
|
-
const payload =
|
|
8657
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
6956
8658
|
name: args.name,
|
|
6957
8659
|
runSchedule: runScheduleFromFlags(args),
|
|
6958
8660
|
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
@@ -6961,7 +8663,7 @@ Example: baker ads linkedin campaign-groups update 635137195 --total-budget 8000
|
|
|
6961
8663
|
await stageOp({
|
|
6962
8664
|
kind: "campaignGroup.update",
|
|
6963
8665
|
accountId,
|
|
6964
|
-
target:
|
|
8666
|
+
target: requireTarget2(args, "campaign group"),
|
|
6965
8667
|
payload
|
|
6966
8668
|
});
|
|
6967
8669
|
}
|
|
@@ -7010,7 +8712,7 @@ var campaignFlagArgs = {
|
|
|
7010
8712
|
status: { type: "string", description: "DRAFT|ACTIVE|PAUSED" },
|
|
7011
8713
|
file: { type: "string", description: "JSON file with the full payload; flags override file keys" }
|
|
7012
8714
|
};
|
|
7013
|
-
var campaignsCreateCommand =
|
|
8715
|
+
var campaignsCreateCommand = defineCommand38({
|
|
7014
8716
|
meta: {
|
|
7015
8717
|
name: "create",
|
|
7016
8718
|
description: `Stage a new campaign. ${STAGED_NOTE}
|
|
@@ -7020,14 +8722,14 @@ Example: baker ads linkedin campaigns create --name "ABM Tier-1" --group li_temp
|
|
|
7020
8722
|
args: campaignFlagArgs,
|
|
7021
8723
|
run: async ({ args }) => {
|
|
7022
8724
|
const accountId = bareAccountId(args);
|
|
7023
|
-
const payload =
|
|
8725
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), campaignPayloadFromFlags(args));
|
|
7024
8726
|
if (payload.locale === void 0) {
|
|
7025
8727
|
payload.locale = { country: "US", language: "en" };
|
|
7026
8728
|
}
|
|
7027
8729
|
await stageOp({ kind: "campaign.create", accountId, payload });
|
|
7028
8730
|
}
|
|
7029
8731
|
});
|
|
7030
|
-
var campaignsUpdateCommand =
|
|
8732
|
+
var campaignsUpdateCommand = defineCommand38({
|
|
7031
8733
|
meta: {
|
|
7032
8734
|
name: "update",
|
|
7033
8735
|
description: `Stage changes to an existing campaign (budget, bid, targeting, flags, schedule, status). ${STAGED_NOTE}
|
|
@@ -7045,18 +8747,18 @@ Example: baker ads linkedin campaigns update 123456 --daily-budget 100 --currenc
|
|
|
7045
8747
|
flags.type = void 0;
|
|
7046
8748
|
flags.locale = void 0;
|
|
7047
8749
|
flags.associatedEntity = void 0;
|
|
7048
|
-
const payload =
|
|
8750
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), flags);
|
|
7049
8751
|
await stageOp({
|
|
7050
8752
|
kind: "campaign.update",
|
|
7051
8753
|
accountId,
|
|
7052
|
-
target:
|
|
8754
|
+
target: requireTarget2(args, "campaign"),
|
|
7053
8755
|
payload
|
|
7054
8756
|
});
|
|
7055
8757
|
}
|
|
7056
8758
|
});
|
|
7057
8759
|
function statusSugarCommand(entity, kind, name) {
|
|
7058
8760
|
const status = name === "pause" ? "PAUSED" : name === "resume" ? "ACTIVE" : "ARCHIVED";
|
|
7059
|
-
return
|
|
8761
|
+
return defineCommand38({
|
|
7060
8762
|
meta: {
|
|
7061
8763
|
name,
|
|
7062
8764
|
description: `Stage a status change to ${status}. ${STAGED_NOTE}
|
|
@@ -7070,7 +8772,7 @@ Example: baker ads linkedin ${entity} ${name} 123456`
|
|
|
7070
8772
|
await stageStatusChange({
|
|
7071
8773
|
kind,
|
|
7072
8774
|
accountId: bareAccountId(args),
|
|
7073
|
-
target:
|
|
8775
|
+
target: requireTarget2(args, entity.replace(/-/g, " ").replace(/s$/, "")),
|
|
7074
8776
|
status
|
|
7075
8777
|
});
|
|
7076
8778
|
}
|
|
@@ -7084,7 +8786,7 @@ var campaignGroupsResumeCommand = statusSugarCommand("campaign-groups", "campaig
|
|
|
7084
8786
|
var creativesPauseCommand = statusSugarCommand("creatives", "creative.update", "pause");
|
|
7085
8787
|
var creativesResumeCommand = statusSugarCommand("creatives", "creative.update", "resume");
|
|
7086
8788
|
function duplicateCommand(entity, cliGroup) {
|
|
7087
|
-
return
|
|
8789
|
+
return defineCommand38({
|
|
7088
8790
|
meta: {
|
|
7089
8791
|
name: "duplicate",
|
|
7090
8792
|
description: `Stage a copy of an existing ${entity} as a new DRAFT create (playbook: duplicate, never link-to-original). ${STAGED_NOTE}
|
|
@@ -7099,14 +8801,14 @@ Example: baker ads linkedin ${cliGroup} duplicate 123456 --name "New variant"`
|
|
|
7099
8801
|
run: async ({ args }) => {
|
|
7100
8802
|
try {
|
|
7101
8803
|
const chatId = requireChatId();
|
|
7102
|
-
const overrides =
|
|
8804
|
+
const overrides = mergePayload2(loadJsonFileArg2(args.file), { name: args.name });
|
|
7103
8805
|
const response = await apiPost(
|
|
7104
8806
|
"/api/ads/linkedin/draft/duplicate",
|
|
7105
8807
|
{
|
|
7106
8808
|
chatId,
|
|
7107
8809
|
accountId: bareAccountId(args),
|
|
7108
8810
|
entity,
|
|
7109
|
-
sourceId:
|
|
8811
|
+
sourceId: requireTarget2(args, entity),
|
|
7110
8812
|
...Object.keys(overrides).length > 0 ? { overrides } : {}
|
|
7111
8813
|
}
|
|
7112
8814
|
);
|
|
@@ -7119,7 +8821,7 @@ Example: baker ads linkedin ${cliGroup} duplicate 123456 --name "New variant"`
|
|
|
7119
8821
|
}
|
|
7120
8822
|
var campaignsDuplicateCommand = duplicateCommand("campaign", "campaigns");
|
|
7121
8823
|
var campaignGroupsDuplicateCommand = duplicateCommand("campaignGroup", "campaign-groups");
|
|
7122
|
-
var creativesDuplicateCommand =
|
|
8824
|
+
var creativesDuplicateCommand = defineCommand38({
|
|
7123
8825
|
meta: {
|
|
7124
8826
|
name: "duplicate",
|
|
7125
8827
|
description: `Stage a copy of an existing ad, optionally with new content \u2014 the ONLY way to change copy/media/URL on a live ad (LinkedIn makes ad content immutable). ${STAGED_NOTE}
|
|
@@ -7157,10 +8859,10 @@ Examples:
|
|
|
7157
8859
|
run: async ({ args }) => {
|
|
7158
8860
|
try {
|
|
7159
8861
|
const chatId = requireChatId();
|
|
7160
|
-
const file =
|
|
8862
|
+
const file = loadJsonFileArg2(args.file);
|
|
7161
8863
|
const fileContent = file.content !== null && typeof file.content === "object" && !Array.isArray(file.content) ? file.content : {};
|
|
7162
8864
|
const content = { ...fileContent, ...creativeContentPatch(args) };
|
|
7163
|
-
const overrides =
|
|
8865
|
+
const overrides = mergePayload2(file, {
|
|
7164
8866
|
campaign: args.campaign,
|
|
7165
8867
|
intendedStatus: args["intended-status"] ? String(args["intended-status"]).toUpperCase() : void 0,
|
|
7166
8868
|
content: Object.keys(content).length > 0 ? content : void 0
|
|
@@ -7171,7 +8873,7 @@ Examples:
|
|
|
7171
8873
|
chatId,
|
|
7172
8874
|
accountId: bareAccountId(args),
|
|
7173
8875
|
entity: "creative",
|
|
7174
|
-
sourceId:
|
|
8876
|
+
sourceId: requireTarget2(args, "creative"),
|
|
7175
8877
|
...Object.keys(overrides).length > 0 ? { overrides } : {},
|
|
7176
8878
|
...args.replace ? { replace: true } : {}
|
|
7177
8879
|
}
|
|
@@ -7196,7 +8898,7 @@ var CREATIVE_FORMATS = [
|
|
|
7196
8898
|
"event",
|
|
7197
8899
|
"article"
|
|
7198
8900
|
];
|
|
7199
|
-
var creativesCreateCommand =
|
|
8901
|
+
var creativesCreateCommand = defineCommand38({
|
|
7200
8902
|
meta: {
|
|
7201
8903
|
name: "create",
|
|
7202
8904
|
description: `Stage a new creative (ad). ${STAGED_NOTE}
|
|
@@ -7232,13 +8934,13 @@ Examples:
|
|
|
7232
8934
|
run: async ({ args }) => {
|
|
7233
8935
|
const accountId = bareAccountId(args);
|
|
7234
8936
|
if (!args.campaign) {
|
|
7235
|
-
|
|
8937
|
+
failWriteValidation2("--campaign is required (id, URN, or li_temp_* ref)");
|
|
7236
8938
|
}
|
|
7237
8939
|
const format = args.format ? String(args.format) : void 0;
|
|
7238
8940
|
if (!format || !CREATIVE_FORMATS.includes(format)) {
|
|
7239
|
-
|
|
8941
|
+
failWriteValidation2(`--format must be one of ${CREATIVE_FORMATS.join("|")}`);
|
|
7240
8942
|
}
|
|
7241
|
-
const content =
|
|
8943
|
+
const content = mergePayload2(loadJsonFileArg2(args.file), {
|
|
7242
8944
|
format,
|
|
7243
8945
|
commentary: args.intro,
|
|
7244
8946
|
imageId: args["image-id"],
|
|
@@ -7297,7 +8999,7 @@ function creativeContentPatch(args) {
|
|
|
7297
8999
|
}
|
|
7298
9000
|
return patch;
|
|
7299
9001
|
}
|
|
7300
|
-
var creativesUpdateCommand =
|
|
9002
|
+
var creativesUpdateCommand = defineCommand38({
|
|
7301
9003
|
meta: {
|
|
7302
9004
|
name: "update",
|
|
7303
9005
|
description: `Stage changes to an existing creative, or amend a creative staged in this chat by passing its li_temp_* ref. ${STAGED_NOTE}
|
|
@@ -7329,13 +9031,13 @@ Examples:
|
|
|
7329
9031
|
},
|
|
7330
9032
|
run: async ({ args }) => {
|
|
7331
9033
|
const accountId = bareAccountId(args);
|
|
7332
|
-
const target =
|
|
7333
|
-
const file =
|
|
9034
|
+
const target = requireTarget2(args, "creative");
|
|
9035
|
+
const file = loadJsonFileArg2(args.file);
|
|
7334
9036
|
const contentPatch = creativeContentPatch(args);
|
|
7335
9037
|
const intendedStatus = args["intended-status"] ? String(args["intended-status"]).toUpperCase() : void 0;
|
|
7336
9038
|
const fileContent = file.content !== null && typeof file.content === "object" && !Array.isArray(file.content) ? file.content : {};
|
|
7337
9039
|
const content = { ...fileContent, ...contentPatch };
|
|
7338
|
-
const payload =
|
|
9040
|
+
const payload = mergePayload2(file, {
|
|
7339
9041
|
intendedStatus,
|
|
7340
9042
|
name: args.name,
|
|
7341
9043
|
content: Object.keys(content).length > 0 ? content : void 0
|
|
@@ -7345,7 +9047,7 @@ Examples:
|
|
|
7345
9047
|
});
|
|
7346
9048
|
var AUDIENCE_TYPES2 = ["company-list", "user-list", "retargeting", "engagement"];
|
|
7347
9049
|
var INLINE_ROWS_MAX = 1e4;
|
|
7348
|
-
var audiencesCreateCommand =
|
|
9050
|
+
var audiencesCreateCommand = defineCommand38({
|
|
7349
9051
|
meta: {
|
|
7350
9052
|
name: "create",
|
|
7351
9053
|
description: `Stage a new matched audience. ${STAGED_NOTE}
|
|
@@ -7362,7 +9064,7 @@ Example: baker ads linkedin audiences create --name "ABM Tier-1" --type company-
|
|
|
7362
9064
|
run: async ({ args }) => {
|
|
7363
9065
|
const accountId = bareAccountId(args);
|
|
7364
9066
|
const list = parseListFileArg(args["list-file"], INLINE_ROWS_MAX);
|
|
7365
|
-
const raw = args.file ?
|
|
9067
|
+
const raw = args.file ? loadJsonFileArg2(args.file) : void 0;
|
|
7366
9068
|
await stageOp({
|
|
7367
9069
|
kind: "audience.create",
|
|
7368
9070
|
accountId,
|
|
@@ -7375,7 +9077,7 @@ Example: baker ads linkedin audiences create --name "ABM Tier-1" --type company-
|
|
|
7375
9077
|
});
|
|
7376
9078
|
}
|
|
7377
9079
|
});
|
|
7378
|
-
var audiencesUploadCommand =
|
|
9080
|
+
var audiencesUploadCommand = defineCommand38({
|
|
7379
9081
|
meta: {
|
|
7380
9082
|
name: "upload",
|
|
7381
9083
|
description: `Stage a list upload into an existing audience segment. ${STAGED_NOTE}
|
|
@@ -7390,20 +9092,20 @@ Example: baker ads linkedin audiences upload urn:li:dmpSegment:42 --list-file mo
|
|
|
7390
9092
|
const accountId = bareAccountId(args);
|
|
7391
9093
|
const list = parseListFileArg(args["list-file"], INLINE_ROWS_MAX);
|
|
7392
9094
|
if (!list) {
|
|
7393
|
-
|
|
9095
|
+
failWriteValidation2("--list-file is required");
|
|
7394
9096
|
}
|
|
7395
9097
|
await stageOp({
|
|
7396
9098
|
kind: "audience.uploadList",
|
|
7397
9099
|
accountId,
|
|
7398
9100
|
payload: {
|
|
7399
|
-
segment:
|
|
9101
|
+
segment: requireTarget2(args, "audience segment"),
|
|
7400
9102
|
listColumns: list.columns,
|
|
7401
9103
|
listRows: list.rows
|
|
7402
9104
|
}
|
|
7403
9105
|
});
|
|
7404
9106
|
}
|
|
7405
9107
|
});
|
|
7406
|
-
var
|
|
9108
|
+
var audiencesCommand2 = defineCommand38({
|
|
7407
9109
|
meta: {
|
|
7408
9110
|
name: "audiences",
|
|
7409
9111
|
description: "Stage LinkedIn matched-audience changes (create lists, upload rows). Staged until publish \u2014 never hits the API directly."
|
|
@@ -7413,7 +9115,7 @@ var audiencesCommand = defineCommand36({
|
|
|
7413
9115
|
upload: audiencesUploadCommand
|
|
7414
9116
|
}
|
|
7415
9117
|
});
|
|
7416
|
-
var conversionsCreateCommand =
|
|
9118
|
+
var conversionsCreateCommand = defineCommand38({
|
|
7417
9119
|
meta: {
|
|
7418
9120
|
name: "create",
|
|
7419
9121
|
description: `Stage a new conversion rule. ${STAGED_NOTE}
|
|
@@ -7432,7 +9134,7 @@ Example: baker ads linkedin conversions create --name "Demo booked" --type LEAD
|
|
|
7432
9134
|
},
|
|
7433
9135
|
run: async ({ args }) => {
|
|
7434
9136
|
const accountId = bareAccountId(args);
|
|
7435
|
-
const payload =
|
|
9137
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
7436
9138
|
name: args.name,
|
|
7437
9139
|
type: args.type ? String(args.type).toUpperCase() : void 0,
|
|
7438
9140
|
conversionMethod: args.method ? String(args.method).toUpperCase() : void 0,
|
|
@@ -7444,7 +9146,7 @@ Example: baker ads linkedin conversions create --name "Demo booked" --type LEAD
|
|
|
7444
9146
|
await stageOp({ kind: "conversion.create", accountId, payload });
|
|
7445
9147
|
}
|
|
7446
9148
|
});
|
|
7447
|
-
var conversionsUpdateCommand =
|
|
9149
|
+
var conversionsUpdateCommand = defineCommand38({
|
|
7448
9150
|
meta: {
|
|
7449
9151
|
name: "update",
|
|
7450
9152
|
description: `Stage changes to a conversion rule (windows, name, enabled). ${STAGED_NOTE}
|
|
@@ -7462,7 +9164,7 @@ Example: baker ads linkedin conversions update 104988516 --post-click-window 30
|
|
|
7462
9164
|
},
|
|
7463
9165
|
run: async ({ args }) => {
|
|
7464
9166
|
const accountId = bareAccountId(args);
|
|
7465
|
-
const payload =
|
|
9167
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
7466
9168
|
name: args.name,
|
|
7467
9169
|
postClickAttributionWindowSize: args["post-click-window"] ? Number(args["post-click-window"]) : void 0,
|
|
7468
9170
|
viewThroughAttributionWindowSize: args["view-window"] ? Number(args["view-window"]) : void 0,
|
|
@@ -7472,12 +9174,12 @@ Example: baker ads linkedin conversions update 104988516 --post-click-window 30
|
|
|
7472
9174
|
await stageOp({
|
|
7473
9175
|
kind: "conversion.update",
|
|
7474
9176
|
accountId,
|
|
7475
|
-
target:
|
|
9177
|
+
target: requireTarget2(args, "conversion rule"),
|
|
7476
9178
|
payload
|
|
7477
9179
|
});
|
|
7478
9180
|
}
|
|
7479
9181
|
});
|
|
7480
|
-
var leadFormsCreateCommand =
|
|
9182
|
+
var leadFormsCreateCommand = defineCommand38({
|
|
7481
9183
|
meta: {
|
|
7482
9184
|
name: "create",
|
|
7483
9185
|
description: `Stage a new Lead Gen Form from a JSON file. ${STAGED_NOTE}
|
|
@@ -7490,11 +9192,11 @@ The file needs: name, headline (\u226460), privacyPolicyUrl, questions[] (\u2264
|
|
|
7490
9192
|
},
|
|
7491
9193
|
run: async ({ args }) => {
|
|
7492
9194
|
const accountId = bareAccountId(args);
|
|
7493
|
-
const payload =
|
|
9195
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), { name: args.name });
|
|
7494
9196
|
await stageOp({ kind: "leadForm.create", accountId, payload });
|
|
7495
9197
|
}
|
|
7496
9198
|
});
|
|
7497
|
-
var leadFormsUpdateCommand =
|
|
9199
|
+
var leadFormsUpdateCommand = defineCommand38({
|
|
7498
9200
|
meta: {
|
|
7499
9201
|
name: "update",
|
|
7500
9202
|
description: `Stage changes to a Lead Gen Form from a JSON file. ${STAGED_NOTE}`
|
|
@@ -7507,16 +9209,16 @@ var leadFormsUpdateCommand = defineCommand36({
|
|
|
7507
9209
|
},
|
|
7508
9210
|
run: async ({ args }) => {
|
|
7509
9211
|
const accountId = bareAccountId(args);
|
|
7510
|
-
const payload =
|
|
9212
|
+
const payload = mergePayload2({ raw: loadJsonFileArg2(args.file) }, { name: args.name });
|
|
7511
9213
|
await stageOp({
|
|
7512
9214
|
kind: "leadForm.update",
|
|
7513
9215
|
accountId,
|
|
7514
|
-
target:
|
|
9216
|
+
target: requireTarget2(args, "lead form"),
|
|
7515
9217
|
payload
|
|
7516
9218
|
});
|
|
7517
9219
|
}
|
|
7518
9220
|
});
|
|
7519
|
-
var leadFormsCommand =
|
|
9221
|
+
var leadFormsCommand = defineCommand38({
|
|
7520
9222
|
meta: {
|
|
7521
9223
|
name: "lead-forms",
|
|
7522
9224
|
description: "Stage LinkedIn Lead Gen Form changes (file-first). Staged until publish \u2014 never hits the API directly."
|
|
@@ -7528,7 +9230,7 @@ var leadFormsCommand = defineCommand36({
|
|
|
7528
9230
|
});
|
|
7529
9231
|
|
|
7530
9232
|
// src/commands/ads/linkedin/campaign-groups.ts
|
|
7531
|
-
var campaignGroupsCommand =
|
|
9233
|
+
var campaignGroupsCommand = defineCommand39({
|
|
7532
9234
|
meta: {
|
|
7533
9235
|
name: "campaign-groups",
|
|
7534
9236
|
description: `List LinkedIn campaign groups, or stage writes (create/update/pause/resume/duplicate).
|
|
@@ -7579,8 +9281,8 @@ Examples:
|
|
|
7579
9281
|
});
|
|
7580
9282
|
|
|
7581
9283
|
// src/commands/ads/linkedin/campaigns.ts
|
|
7582
|
-
import { defineCommand as
|
|
7583
|
-
var
|
|
9284
|
+
import { defineCommand as defineCommand40 } from "citty";
|
|
9285
|
+
var campaignsCommand2 = defineCommand40({
|
|
7584
9286
|
meta: {
|
|
7585
9287
|
name: "campaigns",
|
|
7586
9288
|
description: `List LinkedIn campaigns, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
@@ -7641,8 +9343,8 @@ Examples:
|
|
|
7641
9343
|
});
|
|
7642
9344
|
|
|
7643
9345
|
// src/commands/ads/linkedin/conversation.ts
|
|
7644
|
-
import { defineCommand as
|
|
7645
|
-
var conversationCommand =
|
|
9346
|
+
import { defineCommand as defineCommand41 } from "citty";
|
|
9347
|
+
var conversationCommand = defineCommand41({
|
|
7646
9348
|
meta: {
|
|
7647
9349
|
name: "conversation",
|
|
7648
9350
|
description: `Per-button click rates inside Sponsored Messaging / Conversation Ads.
|
|
@@ -7705,7 +9407,7 @@ Examples:
|
|
|
7705
9407
|
});
|
|
7706
9408
|
|
|
7707
9409
|
// src/commands/ads/linkedin/conversions.ts
|
|
7708
|
-
import { defineCommand as
|
|
9410
|
+
import { defineCommand as defineCommand42 } from "citty";
|
|
7709
9411
|
var DAY_MS3 = 864e5;
|
|
7710
9412
|
function healthOf(rules) {
|
|
7711
9413
|
const enabled = rules.filter((r) => r.enabled !== false);
|
|
@@ -7731,7 +9433,7 @@ function healthOf(rules) {
|
|
|
7731
9433
|
wrongLeadDedup: wrongDedup
|
|
7732
9434
|
};
|
|
7733
9435
|
}
|
|
7734
|
-
var listCmd =
|
|
9436
|
+
var listCmd = defineCommand42({
|
|
7735
9437
|
meta: {
|
|
7736
9438
|
name: "list",
|
|
7737
9439
|
description: `List conversion rules on the account.`
|
|
@@ -7759,7 +9461,7 @@ var listCmd = defineCommand40({
|
|
|
7759
9461
|
}
|
|
7760
9462
|
}
|
|
7761
9463
|
});
|
|
7762
|
-
var healthCmd =
|
|
9464
|
+
var healthCmd = defineCommand42({
|
|
7763
9465
|
meta: {
|
|
7764
9466
|
name: "health",
|
|
7765
9467
|
description: `5-point Insight Tag / CAPI health check (playbook \xA707).
|
|
@@ -7789,7 +9491,7 @@ Surfaces:
|
|
|
7789
9491
|
}
|
|
7790
9492
|
}
|
|
7791
9493
|
});
|
|
7792
|
-
var
|
|
9494
|
+
var conversionsCommand2 = defineCommand42({
|
|
7793
9495
|
meta: {
|
|
7794
9496
|
name: "conversions",
|
|
7795
9497
|
description: `Conversion rules \u2014 Insight Tag and Conversions API.
|
|
@@ -7808,8 +9510,8 @@ Subcommands:
|
|
|
7808
9510
|
});
|
|
7809
9511
|
|
|
7810
9512
|
// src/commands/ads/linkedin/creatives.ts
|
|
7811
|
-
import { defineCommand as
|
|
7812
|
-
var creativesCommand =
|
|
9513
|
+
import { defineCommand as defineCommand43 } from "citty";
|
|
9514
|
+
var creativesCommand = defineCommand43({
|
|
7813
9515
|
meta: {
|
|
7814
9516
|
name: "creatives",
|
|
7815
9517
|
description: `List LinkedIn creatives (ads), or stage writes (create/update/pause/resume/duplicate).
|
|
@@ -7868,7 +9570,7 @@ Examples:
|
|
|
7868
9570
|
});
|
|
7869
9571
|
|
|
7870
9572
|
// src/commands/ads/linkedin/demographics.ts
|
|
7871
|
-
import { defineCommand as
|
|
9573
|
+
import { defineCommand as defineCommand44 } from "citty";
|
|
7872
9574
|
var DEFAULT_PIVOTS = ["job-title", "company", "industry", "seniority", "job-function", "company-size"];
|
|
7873
9575
|
function numberOf2(v) {
|
|
7874
9576
|
if (typeof v === "number") return Number.isFinite(v) ? v : 0;
|
|
@@ -7881,7 +9583,7 @@ function numberOf2(v) {
|
|
|
7881
9583
|
function topByImpressions(rows, limit) {
|
|
7882
9584
|
return [...rows].sort((a, b) => numberOf2(b.impressions) - numberOf2(a.impressions)).slice(0, limit);
|
|
7883
9585
|
}
|
|
7884
|
-
var demographicsCommand =
|
|
9586
|
+
var demographicsCommand = defineCommand44({
|
|
7885
9587
|
meta: {
|
|
7886
9588
|
name: "demographics",
|
|
7887
9589
|
description: `Sweep all firmographic pivots in one command \u2014 LinkedIn's superpower.
|
|
@@ -7978,7 +9680,7 @@ function resolveRange(args) {
|
|
|
7978
9680
|
}
|
|
7979
9681
|
|
|
7980
9682
|
// src/commands/ads/linkedin/draft.ts
|
|
7981
|
-
import { defineCommand as
|
|
9683
|
+
import { defineCommand as defineCommand45 } from "citty";
|
|
7982
9684
|
async function listDraft() {
|
|
7983
9685
|
try {
|
|
7984
9686
|
const chatId = requireChatId();
|
|
@@ -7990,14 +9692,14 @@ async function listDraft() {
|
|
|
7990
9692
|
handleLinkedinError(err);
|
|
7991
9693
|
}
|
|
7992
9694
|
}
|
|
7993
|
-
var listCommand3 =
|
|
9695
|
+
var listCommand3 = defineCommand45({
|
|
7994
9696
|
meta: {
|
|
7995
9697
|
name: "list",
|
|
7996
9698
|
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"
|
|
7997
9699
|
},
|
|
7998
9700
|
run: listDraft
|
|
7999
9701
|
});
|
|
8000
|
-
var removeCommand2 =
|
|
9702
|
+
var removeCommand2 = defineCommand45({
|
|
8001
9703
|
meta: {
|
|
8002
9704
|
name: "remove",
|
|
8003
9705
|
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"
|
|
@@ -8022,7 +9724,7 @@ var removeCommand2 = defineCommand43({
|
|
|
8022
9724
|
}
|
|
8023
9725
|
}
|
|
8024
9726
|
});
|
|
8025
|
-
var clearCommand2 =
|
|
9727
|
+
var clearCommand2 = defineCommand45({
|
|
8026
9728
|
meta: {
|
|
8027
9729
|
name: "clear",
|
|
8028
9730
|
description: "Discard ALL staged LinkedIn ops in this chat's draft \u2014 nothing will apply on publish. Example: baker ads linkedin draft clear"
|
|
@@ -8039,7 +9741,7 @@ var clearCommand2 = defineCommand43({
|
|
|
8039
9741
|
}
|
|
8040
9742
|
}
|
|
8041
9743
|
});
|
|
8042
|
-
var linkedinDraftCommand =
|
|
9744
|
+
var linkedinDraftCommand = defineCommand45({
|
|
8043
9745
|
meta: {
|
|
8044
9746
|
name: "draft",
|
|
8045
9747
|
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."
|
|
@@ -8053,8 +9755,8 @@ var linkedinDraftCommand = defineCommand43({
|
|
|
8053
9755
|
});
|
|
8054
9756
|
|
|
8055
9757
|
// src/commands/ads/linkedin/facets.ts
|
|
8056
|
-
import { defineCommand as
|
|
8057
|
-
var listCmd2 =
|
|
9758
|
+
import { defineCommand as defineCommand46 } from "citty";
|
|
9759
|
+
var listCmd2 = defineCommand46({
|
|
8058
9760
|
meta: {
|
|
8059
9761
|
name: "list",
|
|
8060
9762
|
description: `List every targeting facet LinkedIn supports.
|
|
@@ -8082,7 +9784,7 @@ seniorities, titles, employers, growthRate, companyCategory, skills, etc.).`
|
|
|
8082
9784
|
}
|
|
8083
9785
|
}
|
|
8084
9786
|
});
|
|
8085
|
-
var valuesCmd =
|
|
9787
|
+
var valuesCmd = defineCommand46({
|
|
8086
9788
|
meta: {
|
|
8087
9789
|
name: "values",
|
|
8088
9790
|
description: `Look up entity values for a single facet \u2014 full list or typeahead search.
|
|
@@ -8123,7 +9825,7 @@ or the full URN (urn:li:adTargetingFacet:industries).`
|
|
|
8123
9825
|
}
|
|
8124
9826
|
}
|
|
8125
9827
|
});
|
|
8126
|
-
var facetsCommand =
|
|
9828
|
+
var facetsCommand = defineCommand46({
|
|
8127
9829
|
meta: {
|
|
8128
9830
|
name: "facets",
|
|
8129
9831
|
description: `LinkedIn targeting facets and entity lookup.
|
|
@@ -8140,8 +9842,8 @@ Subcommands:
|
|
|
8140
9842
|
});
|
|
8141
9843
|
|
|
8142
9844
|
// src/commands/ads/linkedin/forecast.ts
|
|
8143
|
-
import { readFileSync as
|
|
8144
|
-
import { defineCommand as
|
|
9845
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
9846
|
+
import { defineCommand as defineCommand47 } from "citty";
|
|
8145
9847
|
function loadTargeting3(args) {
|
|
8146
9848
|
const inline = args.targeting;
|
|
8147
9849
|
if (inline) {
|
|
@@ -8154,7 +9856,7 @@ function loadTargeting3(args) {
|
|
|
8154
9856
|
const file = args["targeting-file"];
|
|
8155
9857
|
if (file) {
|
|
8156
9858
|
try {
|
|
8157
|
-
return JSON.parse(
|
|
9859
|
+
return JSON.parse(readFileSync8(file, "utf-8"));
|
|
8158
9860
|
} catch (e) {
|
|
8159
9861
|
handleLinkedinError(
|
|
8160
9862
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -8171,7 +9873,7 @@ function parseMoney(raw) {
|
|
|
8171
9873
|
}
|
|
8172
9874
|
return { amount: m[1] ?? "0", currencyCode: m[2] ?? "USD" };
|
|
8173
9875
|
}
|
|
8174
|
-
var forecastCommand =
|
|
9876
|
+
var forecastCommand = defineCommand47({
|
|
8175
9877
|
meta: {
|
|
8176
9878
|
name: "forecast",
|
|
8177
9879
|
description: `Forecast reach + impressions + clicks + spend for a hypothetical campaign.
|
|
@@ -8218,9 +9920,9 @@ Examples:
|
|
|
8218
9920
|
});
|
|
8219
9921
|
|
|
8220
9922
|
// src/commands/ads/linkedin/leads.ts
|
|
8221
|
-
import { defineCommand as
|
|
9923
|
+
import { defineCommand as defineCommand48 } from "citty";
|
|
8222
9924
|
var DAY_MS4 = 864e5;
|
|
8223
|
-
var leadsCommand =
|
|
9925
|
+
var leadsCommand = defineCommand48({
|
|
8224
9926
|
meta: {
|
|
8225
9927
|
name: "leads",
|
|
8226
9928
|
description: `List Lead Gen Form responses (playbook \xA707).
|
|
@@ -8280,7 +9982,7 @@ Examples:
|
|
|
8280
9982
|
});
|
|
8281
9983
|
|
|
8282
9984
|
// src/commands/ads/linkedin/resolve.ts
|
|
8283
|
-
import { defineCommand as
|
|
9985
|
+
import { defineCommand as defineCommand49 } from "citty";
|
|
8284
9986
|
function toOrgUrn(raw) {
|
|
8285
9987
|
const trimmed = raw.trim();
|
|
8286
9988
|
if (trimmed.length === 0) {
|
|
@@ -8291,7 +9993,7 @@ function toOrgUrn(raw) {
|
|
|
8291
9993
|
}
|
|
8292
9994
|
return /^\d+$/.test(trimmed) ? `urn:li:organization:${trimmed}` : null;
|
|
8293
9995
|
}
|
|
8294
|
-
var resolveCommand =
|
|
9996
|
+
var resolveCommand = defineCommand49({
|
|
8295
9997
|
meta: {
|
|
8296
9998
|
name: "resolve",
|
|
8297
9999
|
description: `Resolve organization URNs to company names.
|
|
@@ -8333,8 +10035,8 @@ couldn't be resolved \u2014 typically an org outside LinkedIn's targetable set.`
|
|
|
8333
10035
|
});
|
|
8334
10036
|
|
|
8335
10037
|
// src/commands/ads/linkedin/top-companies.ts
|
|
8336
|
-
import { defineCommand as
|
|
8337
|
-
var topCompaniesCommand =
|
|
10038
|
+
import { defineCommand as defineCommand50 } from "citty";
|
|
10039
|
+
var topCompaniesCommand = defineCommand50({
|
|
8338
10040
|
meta: {
|
|
8339
10041
|
name: "top-companies",
|
|
8340
10042
|
description: `Top companies whose employees saw / clicked / converted on a campaign.
|
|
@@ -8405,7 +10107,7 @@ Examples:
|
|
|
8405
10107
|
});
|
|
8406
10108
|
|
|
8407
10109
|
// src/commands/ads/linkedin/index.ts
|
|
8408
|
-
var linkedinCommand =
|
|
10110
|
+
var linkedinCommand = defineCommand51({
|
|
8409
10111
|
meta: {
|
|
8410
10112
|
name: "linkedin",
|
|
8411
10113
|
description: `LinkedIn Marketing API \u2014 AI-first command surface for B2B ad insights.
|
|
@@ -8450,9 +10152,9 @@ Account ID format:
|
|
|
8450
10152
|
accounts: accountsCommand2,
|
|
8451
10153
|
account: accountCommand,
|
|
8452
10154
|
"campaign-groups": campaignGroupsCommand,
|
|
8453
|
-
campaigns:
|
|
10155
|
+
campaigns: campaignsCommand2,
|
|
8454
10156
|
creatives: creativesCommand,
|
|
8455
|
-
audiences:
|
|
10157
|
+
audiences: audiencesCommand2,
|
|
8456
10158
|
"lead-forms": leadFormsCommand,
|
|
8457
10159
|
draft: linkedinDraftCommand,
|
|
8458
10160
|
analytics: analyticsCommand,
|
|
@@ -8464,17 +10166,17 @@ Account ID format:
|
|
|
8464
10166
|
"bid-pricing": bidPricingCommand,
|
|
8465
10167
|
forecast: forecastCommand,
|
|
8466
10168
|
leads: leadsCommand,
|
|
8467
|
-
conversions:
|
|
10169
|
+
conversions: conversionsCommand2,
|
|
8468
10170
|
conversation: conversationCommand,
|
|
8469
10171
|
audit: auditCommand
|
|
8470
10172
|
}
|
|
8471
10173
|
});
|
|
8472
10174
|
|
|
8473
10175
|
// src/commands/ads/meta/index.ts
|
|
8474
|
-
import { defineCommand as
|
|
10176
|
+
import { defineCommand as defineCommand64 } from "citty";
|
|
8475
10177
|
|
|
8476
10178
|
// src/commands/ads/meta/account.ts
|
|
8477
|
-
import { defineCommand as
|
|
10179
|
+
import { defineCommand as defineCommand52 } from "citty";
|
|
8478
10180
|
|
|
8479
10181
|
// src/commands/ads/meta/shared.ts
|
|
8480
10182
|
var DAY_MS5 = 864e5;
|
|
@@ -8553,7 +10255,7 @@ function resolveEffectiveStatus(args) {
|
|
|
8553
10255
|
}
|
|
8554
10256
|
|
|
8555
10257
|
// src/commands/ads/meta/account.ts
|
|
8556
|
-
var accountCommand2 =
|
|
10258
|
+
var accountCommand2 = defineCommand52({
|
|
8557
10259
|
meta: {
|
|
8558
10260
|
name: "account",
|
|
8559
10261
|
description: `Show single Meta ad account detail (currency, timezone, balance, business).
|
|
@@ -8580,8 +10282,8 @@ Examples:
|
|
|
8580
10282
|
});
|
|
8581
10283
|
|
|
8582
10284
|
// src/commands/ads/meta/accounts.ts
|
|
8583
|
-
import { defineCommand as
|
|
8584
|
-
var accountsCommand3 =
|
|
10285
|
+
import { defineCommand as defineCommand53 } from "citty";
|
|
10286
|
+
var accountsCommand3 = defineCommand53({
|
|
8585
10287
|
meta: {
|
|
8586
10288
|
name: "accounts",
|
|
8587
10289
|
description: `List Meta ad accounts in this company's connected scope.
|
|
@@ -8629,8 +10331,8 @@ Examples:
|
|
|
8629
10331
|
});
|
|
8630
10332
|
|
|
8631
10333
|
// src/commands/ads/meta/activities.ts
|
|
8632
|
-
import { defineCommand as
|
|
8633
|
-
var activitiesCommand =
|
|
10334
|
+
import { defineCommand as defineCommand54 } from "citty";
|
|
10335
|
+
var activitiesCommand = defineCommand54({
|
|
8634
10336
|
meta: {
|
|
8635
10337
|
name: "activities",
|
|
8636
10338
|
description: `Audit log of recent ad-account changes (created, paused, edited). Default lookback 7 days,
|
|
@@ -8667,8 +10369,8 @@ Examples:
|
|
|
8667
10369
|
});
|
|
8668
10370
|
|
|
8669
10371
|
// src/commands/ads/meta/ads.ts
|
|
8670
|
-
import { defineCommand as
|
|
8671
|
-
var adsListCommand =
|
|
10372
|
+
import { defineCommand as defineCommand55 } from "citty";
|
|
10373
|
+
var adsListCommand = defineCommand55({
|
|
8672
10374
|
meta: {
|
|
8673
10375
|
name: "ads",
|
|
8674
10376
|
description: `List ads in a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -8716,8 +10418,8 @@ Examples:
|
|
|
8716
10418
|
});
|
|
8717
10419
|
|
|
8718
10420
|
// src/commands/ads/meta/adsets.ts
|
|
8719
|
-
import { defineCommand as
|
|
8720
|
-
var adsetsCommand =
|
|
10421
|
+
import { defineCommand as defineCommand56 } from "citty";
|
|
10422
|
+
var adsetsCommand = defineCommand56({
|
|
8721
10423
|
meta: {
|
|
8722
10424
|
name: "adsets",
|
|
8723
10425
|
description: `List ad sets in a Meta ad account, optionally scoped to one campaign. Defaults to ACTIVE only.
|
|
@@ -8759,8 +10461,8 @@ Examples:
|
|
|
8759
10461
|
});
|
|
8760
10462
|
|
|
8761
10463
|
// src/commands/ads/meta/audiences.ts
|
|
8762
|
-
import { defineCommand as
|
|
8763
|
-
var
|
|
10464
|
+
import { defineCommand as defineCommand57 } from "citty";
|
|
10465
|
+
var audiencesCommand3 = defineCommand57({
|
|
8764
10466
|
meta: {
|
|
8765
10467
|
name: "audiences",
|
|
8766
10468
|
description: `List custom audiences for a Meta ad account. Includes lookalikes, website-pixel audiences,
|
|
@@ -8795,8 +10497,8 @@ Examples:
|
|
|
8795
10497
|
});
|
|
8796
10498
|
|
|
8797
10499
|
// src/commands/ads/meta/businesses.ts
|
|
8798
|
-
import { defineCommand as
|
|
8799
|
-
var businessesCommand =
|
|
10500
|
+
import { defineCommand as defineCommand58 } from "citty";
|
|
10501
|
+
var businessesCommand = defineCommand58({
|
|
8800
10502
|
meta: {
|
|
8801
10503
|
name: "businesses",
|
|
8802
10504
|
description: `List Meta Business Manager accounts the connected user has access to. Required for ad-studies and product-catalogs commands.
|
|
@@ -8826,8 +10528,8 @@ Examples:
|
|
|
8826
10528
|
});
|
|
8827
10529
|
|
|
8828
10530
|
// src/commands/ads/meta/campaigns.ts
|
|
8829
|
-
import { defineCommand as
|
|
8830
|
-
var
|
|
10531
|
+
import { defineCommand as defineCommand59 } from "citty";
|
|
10532
|
+
var campaignsCommand3 = defineCommand59({
|
|
8831
10533
|
meta: {
|
|
8832
10534
|
name: "campaigns",
|
|
8833
10535
|
description: `List campaigns for a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -8871,8 +10573,8 @@ Examples:
|
|
|
8871
10573
|
});
|
|
8872
10574
|
|
|
8873
10575
|
// src/commands/ads/meta/creatives.ts
|
|
8874
|
-
import { defineCommand as
|
|
8875
|
-
var creativesCommand2 =
|
|
10576
|
+
import { defineCommand as defineCommand60 } from "citty";
|
|
10577
|
+
var creativesCommand2 = defineCommand60({
|
|
8876
10578
|
meta: {
|
|
8877
10579
|
name: "creatives",
|
|
8878
10580
|
description: `List ad creatives in an account, or fetch a single creative by ID.
|
|
@@ -8916,7 +10618,7 @@ Examples:
|
|
|
8916
10618
|
});
|
|
8917
10619
|
|
|
8918
10620
|
// src/commands/ads/meta/insights.ts
|
|
8919
|
-
import { defineCommand as
|
|
10621
|
+
import { defineCommand as defineCommand61 } from "citty";
|
|
8920
10622
|
|
|
8921
10623
|
// src/commands/ads/meta/presets.ts
|
|
8922
10624
|
var INSIGHTS_INTENTS = {
|
|
@@ -9121,7 +10823,7 @@ function sortRowsBySpendDesc(rows) {
|
|
|
9121
10823
|
return sb - sa;
|
|
9122
10824
|
});
|
|
9123
10825
|
}
|
|
9124
|
-
var insightsCommand =
|
|
10826
|
+
var insightsCommand = defineCommand61({
|
|
9125
10827
|
meta: {
|
|
9126
10828
|
name: "insights",
|
|
9127
10829
|
description: `Performance reporting \u2014 the main Meta tool for AI agents.
|
|
@@ -9222,8 +10924,8 @@ Async is automatic for heavy queries; pass --async to force it, or --no-async to
|
|
|
9222
10924
|
});
|
|
9223
10925
|
|
|
9224
10926
|
// src/commands/ads/meta/pixels.ts
|
|
9225
|
-
import { defineCommand as
|
|
9226
|
-
var pixelsCommand =
|
|
10927
|
+
import { defineCommand as defineCommand62 } from "citty";
|
|
10928
|
+
var pixelsCommand = defineCommand62({
|
|
9227
10929
|
meta: {
|
|
9228
10930
|
name: "pixels",
|
|
9229
10931
|
description: `List Meta Pixels for an ad account, or fetch firing stats for one pixel.
|
|
@@ -9294,7 +10996,7 @@ function emit(data, args) {
|
|
|
9294
10996
|
|
|
9295
10997
|
// src/commands/ads/meta/preview.ts
|
|
9296
10998
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
9297
|
-
import { defineCommand as
|
|
10999
|
+
import { defineCommand as defineCommand63 } from "citty";
|
|
9298
11000
|
var VALID_AD_FORMATS = [
|
|
9299
11001
|
"DESKTOP_FEED_STANDARD",
|
|
9300
11002
|
"MOBILE_FEED_STANDARD",
|
|
@@ -9328,7 +11030,7 @@ var VALID_AD_FORMATS = [
|
|
|
9328
11030
|
"MARKETPLACE_MOBILE",
|
|
9329
11031
|
"BIZ_DISCO_FEED_MOBILE"
|
|
9330
11032
|
];
|
|
9331
|
-
var previewCommand =
|
|
11033
|
+
var previewCommand = defineCommand63({
|
|
9332
11034
|
meta: {
|
|
9333
11035
|
name: "preview",
|
|
9334
11036
|
description: `Generate a Meta-hosted preview iframe for a creative or ad. Returns iframe HTML which you
|
|
@@ -9375,7 +11077,7 @@ Examples:
|
|
|
9375
11077
|
});
|
|
9376
11078
|
|
|
9377
11079
|
// src/commands/ads/meta/index.ts
|
|
9378
|
-
var metaCommand =
|
|
11080
|
+
var metaCommand = defineCommand64({
|
|
9379
11081
|
meta: {
|
|
9380
11082
|
name: "meta",
|
|
9381
11083
|
description: `Meta Marketing API \u2014 AI-first command surface (Facebook + Instagram ads).
|
|
@@ -9414,11 +11116,11 @@ Audit & review:
|
|
|
9414
11116
|
accounts: accountsCommand3,
|
|
9415
11117
|
account: accountCommand2,
|
|
9416
11118
|
businesses: businessesCommand,
|
|
9417
|
-
campaigns:
|
|
11119
|
+
campaigns: campaignsCommand3,
|
|
9418
11120
|
adsets: adsetsCommand,
|
|
9419
11121
|
ads: adsListCommand,
|
|
9420
11122
|
creatives: creativesCommand2,
|
|
9421
|
-
audiences:
|
|
11123
|
+
audiences: audiencesCommand3,
|
|
9422
11124
|
pixels: pixelsCommand,
|
|
9423
11125
|
activities: activitiesCommand,
|
|
9424
11126
|
insights: insightsCommand,
|
|
@@ -9427,10 +11129,10 @@ Audit & review:
|
|
|
9427
11129
|
});
|
|
9428
11130
|
|
|
9429
11131
|
// src/commands/ads/x/index.ts
|
|
9430
|
-
import { defineCommand as
|
|
11132
|
+
import { defineCommand as defineCommand81 } from "citty";
|
|
9431
11133
|
|
|
9432
11134
|
// src/commands/ads/x/accounts.ts
|
|
9433
|
-
import { defineCommand as
|
|
11135
|
+
import { defineCommand as defineCommand65 } from "citty";
|
|
9434
11136
|
registerSchema({
|
|
9435
11137
|
command: "ads.x.accounts",
|
|
9436
11138
|
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.",
|
|
@@ -9458,7 +11160,7 @@ function handleAccountsError2(err) {
|
|
|
9458
11160
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
9459
11161
|
process.exit(1);
|
|
9460
11162
|
}
|
|
9461
|
-
var accountsCommand4 =
|
|
11163
|
+
var accountsCommand4 = defineCommand65({
|
|
9462
11164
|
meta: {
|
|
9463
11165
|
name: "accounts",
|
|
9464
11166
|
description: `List accessible X Ads accounts. Returns account IDs needed for all other commands.
|
|
@@ -9498,7 +11200,7 @@ Examples:
|
|
|
9498
11200
|
});
|
|
9499
11201
|
|
|
9500
11202
|
// src/commands/ads/x/active-entities.ts
|
|
9501
|
-
import { defineCommand as
|
|
11203
|
+
import { defineCommand as defineCommand66 } from "citty";
|
|
9502
11204
|
|
|
9503
11205
|
// src/commands/ads/x/error-parser.ts
|
|
9504
11206
|
function mapXErrorCode(message) {
|
|
@@ -9649,7 +11351,7 @@ function parseCsv(v) {
|
|
|
9649
11351
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
9650
11352
|
return parts.length > 0 ? parts : void 0;
|
|
9651
11353
|
}
|
|
9652
|
-
var activeEntitiesCommand =
|
|
11354
|
+
var activeEntitiesCommand = defineCommand66({
|
|
9653
11355
|
meta: {
|
|
9654
11356
|
name: "active-entities",
|
|
9655
11357
|
description: `List entities with metric activity in a time range.
|
|
@@ -9707,7 +11409,7 @@ Examples:
|
|
|
9707
11409
|
});
|
|
9708
11410
|
|
|
9709
11411
|
// src/commands/ads/x/audiences.ts
|
|
9710
|
-
import { defineCommand as
|
|
11412
|
+
import { defineCommand as defineCommand67 } from "citty";
|
|
9711
11413
|
registerSchema({
|
|
9712
11414
|
command: "ads.x.audiences",
|
|
9713
11415
|
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.",
|
|
@@ -9716,7 +11418,7 @@ registerSchema({
|
|
|
9716
11418
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9717
11419
|
}
|
|
9718
11420
|
});
|
|
9719
|
-
var
|
|
11421
|
+
var audiencesCommand4 = defineCommand67({
|
|
9720
11422
|
meta: {
|
|
9721
11423
|
name: "audiences",
|
|
9722
11424
|
description: `List X Ads custom audiences.
|
|
@@ -9765,7 +11467,7 @@ Examples:
|
|
|
9765
11467
|
});
|
|
9766
11468
|
|
|
9767
11469
|
// src/commands/ads/x/campaigns.ts
|
|
9768
|
-
import { defineCommand as
|
|
11470
|
+
import { defineCommand as defineCommand68 } from "citty";
|
|
9769
11471
|
|
|
9770
11472
|
// src/commands/ads/x/run-list.ts
|
|
9771
11473
|
function buildCleanParams(opts) {
|
|
@@ -9828,7 +11530,7 @@ registerSchema({
|
|
|
9828
11530
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9829
11531
|
}
|
|
9830
11532
|
});
|
|
9831
|
-
var
|
|
11533
|
+
var campaignsCommand4 = defineCommand68({
|
|
9832
11534
|
meta: {
|
|
9833
11535
|
name: "campaigns",
|
|
9834
11536
|
description: `List X Ads campaigns. Returns budget, schedule, funding instrument, status.
|
|
@@ -9870,7 +11572,7 @@ Examples:
|
|
|
9870
11572
|
});
|
|
9871
11573
|
|
|
9872
11574
|
// src/commands/ads/x/cards.ts
|
|
9873
|
-
import { defineCommand as
|
|
11575
|
+
import { defineCommand as defineCommand69 } from "citty";
|
|
9874
11576
|
registerSchema({
|
|
9875
11577
|
command: "ads.x.cards",
|
|
9876
11578
|
description: "List website cards, video cards, and carousels for an X Ads account.",
|
|
@@ -9879,7 +11581,7 @@ registerSchema({
|
|
|
9879
11581
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9880
11582
|
}
|
|
9881
11583
|
});
|
|
9882
|
-
var cardsCommand =
|
|
11584
|
+
var cardsCommand = defineCommand69({
|
|
9883
11585
|
meta: {
|
|
9884
11586
|
name: "cards",
|
|
9885
11587
|
description: `List X Ads cards (rich creatives).
|
|
@@ -9928,7 +11630,7 @@ Examples:
|
|
|
9928
11630
|
});
|
|
9929
11631
|
|
|
9930
11632
|
// src/commands/ads/x/funding.ts
|
|
9931
|
-
import { defineCommand as
|
|
11633
|
+
import { defineCommand as defineCommand70 } from "citty";
|
|
9932
11634
|
registerSchema({
|
|
9933
11635
|
command: "ads.x.funding",
|
|
9934
11636
|
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.",
|
|
@@ -9937,7 +11639,7 @@ registerSchema({
|
|
|
9937
11639
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9938
11640
|
}
|
|
9939
11641
|
});
|
|
9940
|
-
var fundingCommand =
|
|
11642
|
+
var fundingCommand = defineCommand70({
|
|
9941
11643
|
meta: {
|
|
9942
11644
|
name: "funding",
|
|
9943
11645
|
description: `List funding instruments for an X Ads account.
|
|
@@ -9986,7 +11688,7 @@ Examples:
|
|
|
9986
11688
|
});
|
|
9987
11689
|
|
|
9988
11690
|
// src/commands/ads/x/line-items.ts
|
|
9989
|
-
import { defineCommand as
|
|
11691
|
+
import { defineCommand as defineCommand71 } from "citty";
|
|
9990
11692
|
registerSchema({
|
|
9991
11693
|
command: "ads.x.lineItems",
|
|
9992
11694
|
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).",
|
|
@@ -9998,7 +11700,7 @@ registerSchema({
|
|
|
9998
11700
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9999
11701
|
}
|
|
10000
11702
|
});
|
|
10001
|
-
var lineItemsCommand =
|
|
11703
|
+
var lineItemsCommand = defineCommand71({
|
|
10002
11704
|
meta: {
|
|
10003
11705
|
name: "line-items",
|
|
10004
11706
|
description: `List X Ads line items (ad groups).
|
|
@@ -10039,7 +11741,7 @@ Examples:
|
|
|
10039
11741
|
});
|
|
10040
11742
|
|
|
10041
11743
|
// src/commands/ads/x/media.ts
|
|
10042
|
-
import { defineCommand as
|
|
11744
|
+
import { defineCommand as defineCommand72 } from "citty";
|
|
10043
11745
|
registerSchema({
|
|
10044
11746
|
command: "ads.x.media",
|
|
10045
11747
|
description: "List media assets in the X Ads media library (images, GIFs, videos). Filter by media-type (IMAGE, GIF, VIDEO).",
|
|
@@ -10049,7 +11751,7 @@ registerSchema({
|
|
|
10049
11751
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10050
11752
|
}
|
|
10051
11753
|
});
|
|
10052
|
-
var mediaCommand =
|
|
11754
|
+
var mediaCommand = defineCommand72({
|
|
10053
11755
|
meta: {
|
|
10054
11756
|
name: "media",
|
|
10055
11757
|
description: `List media assets in the X Ads media library.
|
|
@@ -10101,7 +11803,7 @@ Examples:
|
|
|
10101
11803
|
});
|
|
10102
11804
|
|
|
10103
11805
|
// src/commands/ads/x/promoted-tweets.ts
|
|
10104
|
-
import { defineCommand as
|
|
11806
|
+
import { defineCommand as defineCommand73 } from "citty";
|
|
10105
11807
|
registerSchema({
|
|
10106
11808
|
command: "ads.x.promotedTweets",
|
|
10107
11809
|
description: "List promoted tweets for an X Ads account. Returns id, line_item_id, tweet_id, approval_status. Filter by line-item-ids (CSV).",
|
|
@@ -10112,7 +11814,7 @@ registerSchema({
|
|
|
10112
11814
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10113
11815
|
}
|
|
10114
11816
|
});
|
|
10115
|
-
var promotedTweetsCommand =
|
|
11817
|
+
var promotedTweetsCommand = defineCommand73({
|
|
10116
11818
|
meta: {
|
|
10117
11819
|
name: "promoted-tweets",
|
|
10118
11820
|
description: `List X Ads promoted tweets.
|
|
@@ -10166,11 +11868,11 @@ Examples:
|
|
|
10166
11868
|
});
|
|
10167
11869
|
|
|
10168
11870
|
// src/commands/ads/x/stats/index.ts
|
|
10169
|
-
import { defineCommand as
|
|
11871
|
+
import { defineCommand as defineCommand78 } from "citty";
|
|
10170
11872
|
|
|
10171
11873
|
// src/commands/ads/x/stats/job.ts
|
|
10172
11874
|
import { gunzipSync } from "zlib";
|
|
10173
|
-
import { defineCommand as
|
|
11875
|
+
import { defineCommand as defineCommand74 } from "citty";
|
|
10174
11876
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
10175
11877
|
var DEADLINE_MS = 12 * 60 * 1e3;
|
|
10176
11878
|
var RESULT_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -10240,7 +11942,7 @@ async function pollUntilDone(accountId, jobId) {
|
|
|
10240
11942
|
function buildCacheKey(body) {
|
|
10241
11943
|
return `stats-job:${JSON.stringify(body)}`;
|
|
10242
11944
|
}
|
|
10243
|
-
var statsJobCommand =
|
|
11945
|
+
var statsJobCommand = defineCommand74({
|
|
10244
11946
|
meta: {
|
|
10245
11947
|
name: "job",
|
|
10246
11948
|
description: `Async X Ads stats job, sync from the CLI's perspective. Creates \u2192 polls \u2192 downloads \u2192 returns.
|
|
@@ -10345,7 +12047,7 @@ For fine-grained control (don't wait, poll yourself), use:
|
|
|
10345
12047
|
});
|
|
10346
12048
|
|
|
10347
12049
|
// src/commands/ads/x/stats/job-create.ts
|
|
10348
|
-
import { defineCommand as
|
|
12050
|
+
import { defineCommand as defineCommand75 } from "citty";
|
|
10349
12051
|
registerSchema({
|
|
10350
12052
|
command: "ads.x.statsJobCreate",
|
|
10351
12053
|
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.",
|
|
@@ -10368,7 +12070,7 @@ function parseCsv3(v) {
|
|
|
10368
12070
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
10369
12071
|
return parts.length > 0 ? parts : void 0;
|
|
10370
12072
|
}
|
|
10371
|
-
var statsJobCreateCommand =
|
|
12073
|
+
var statsJobCreateCommand = defineCommand75({
|
|
10372
12074
|
meta: {
|
|
10373
12075
|
name: "job-create",
|
|
10374
12076
|
description: `Create an async X Ads stats job (up to 90 days, supports segmentation).
|
|
@@ -10431,7 +12133,7 @@ Examples:
|
|
|
10431
12133
|
});
|
|
10432
12134
|
|
|
10433
12135
|
// src/commands/ads/x/stats/job-status.ts
|
|
10434
|
-
import { defineCommand as
|
|
12136
|
+
import { defineCommand as defineCommand76 } from "citty";
|
|
10435
12137
|
registerSchema({
|
|
10436
12138
|
command: "ads.x.statsJobStatus",
|
|
10437
12139
|
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).",
|
|
@@ -10441,7 +12143,7 @@ registerSchema({
|
|
|
10441
12143
|
"job-ids": { type: "string", description: "CSV of job IDs", required: false }
|
|
10442
12144
|
}
|
|
10443
12145
|
});
|
|
10444
|
-
var statsJobStatusCommand =
|
|
12146
|
+
var statsJobStatusCommand = defineCommand76({
|
|
10445
12147
|
meta: {
|
|
10446
12148
|
name: "job-status",
|
|
10447
12149
|
description: `Poll the status of an async X Ads stats job.
|
|
@@ -10482,7 +12184,7 @@ Examples:
|
|
|
10482
12184
|
});
|
|
10483
12185
|
|
|
10484
12186
|
// src/commands/ads/x/stats/sync.ts
|
|
10485
|
-
import { defineCommand as
|
|
12187
|
+
import { defineCommand as defineCommand77 } from "citty";
|
|
10486
12188
|
|
|
10487
12189
|
// src/commands/ads/x/presets.ts
|
|
10488
12190
|
var X_STATS_PRESETS = [
|
|
@@ -10641,7 +12343,7 @@ async function runSync(args, q) {
|
|
|
10641
12343
|
process.exit(1);
|
|
10642
12344
|
}
|
|
10643
12345
|
}
|
|
10644
|
-
var statsSyncCommand =
|
|
12346
|
+
var statsSyncCommand = defineCommand77({
|
|
10645
12347
|
meta: {
|
|
10646
12348
|
name: "sync",
|
|
10647
12349
|
description: `Synchronous X Ads analytics (max 7-day window).
|
|
@@ -10684,7 +12386,7 @@ Examples:
|
|
|
10684
12386
|
});
|
|
10685
12387
|
|
|
10686
12388
|
// src/commands/ads/x/stats/index.ts
|
|
10687
|
-
var statsCommand =
|
|
12389
|
+
var statsCommand = defineCommand78({
|
|
10688
12390
|
meta: {
|
|
10689
12391
|
name: "stats",
|
|
10690
12392
|
description: `X Ads analytics. Sync (\u22647 days, no segmentation) or async jobs (\u226490 days, segmentable).
|
|
@@ -10712,7 +12414,7 @@ Examples:
|
|
|
10712
12414
|
});
|
|
10713
12415
|
|
|
10714
12416
|
// src/commands/ads/x/targeting-constants.ts
|
|
10715
|
-
import { defineCommand as
|
|
12417
|
+
import { defineCommand as defineCommand79 } from "citty";
|
|
10716
12418
|
var ALLOWED_CONSTANTS = [
|
|
10717
12419
|
"locations",
|
|
10718
12420
|
"interests",
|
|
@@ -10740,7 +12442,7 @@ registerSchema({
|
|
|
10740
12442
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10741
12443
|
}
|
|
10742
12444
|
});
|
|
10743
|
-
var targetingConstantsCommand =
|
|
12445
|
+
var targetingConstantsCommand = defineCommand79({
|
|
10744
12446
|
meta: {
|
|
10745
12447
|
name: "targeting-constants",
|
|
10746
12448
|
description: `Lookup X Ads targeting constants.
|
|
@@ -10790,7 +12492,7 @@ Examples:
|
|
|
10790
12492
|
});
|
|
10791
12493
|
|
|
10792
12494
|
// src/commands/ads/x/targeting-criteria.ts
|
|
10793
|
-
import { defineCommand as
|
|
12495
|
+
import { defineCommand as defineCommand80 } from "citty";
|
|
10794
12496
|
registerSchema({
|
|
10795
12497
|
command: "ads.x.targetingCriteria",
|
|
10796
12498
|
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.",
|
|
@@ -10800,7 +12502,7 @@ registerSchema({
|
|
|
10800
12502
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10801
12503
|
}
|
|
10802
12504
|
});
|
|
10803
|
-
var targetingCriteriaCommand =
|
|
12505
|
+
var targetingCriteriaCommand = defineCommand80({
|
|
10804
12506
|
meta: {
|
|
10805
12507
|
name: "targeting-criteria",
|
|
10806
12508
|
description: `List targeting criteria attached to line items.
|
|
@@ -10851,7 +12553,7 @@ Examples:
|
|
|
10851
12553
|
});
|
|
10852
12554
|
|
|
10853
12555
|
// src/commands/ads/x/index.ts
|
|
10854
|
-
var xCommand =
|
|
12556
|
+
var xCommand = defineCommand81({
|
|
10855
12557
|
meta: {
|
|
10856
12558
|
name: "x",
|
|
10857
12559
|
description: `X (Twitter) Ads commands. Read campaigns, line items, promoted tweets, creatives, audiences, and analytics.
|
|
@@ -10875,12 +12577,12 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
10875
12577
|
subCommands: {
|
|
10876
12578
|
accounts: accountsCommand4,
|
|
10877
12579
|
funding: fundingCommand,
|
|
10878
|
-
campaigns:
|
|
12580
|
+
campaigns: campaignsCommand4,
|
|
10879
12581
|
"line-items": lineItemsCommand,
|
|
10880
12582
|
"promoted-tweets": promotedTweetsCommand,
|
|
10881
12583
|
cards: cardsCommand,
|
|
10882
12584
|
media: mediaCommand,
|
|
10883
|
-
audiences:
|
|
12585
|
+
audiences: audiencesCommand4,
|
|
10884
12586
|
"targeting-criteria": targetingCriteriaCommand,
|
|
10885
12587
|
"targeting-constants": targetingConstantsCommand,
|
|
10886
12588
|
"active-entities": activeEntitiesCommand,
|
|
@@ -10889,7 +12591,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
10889
12591
|
});
|
|
10890
12592
|
|
|
10891
12593
|
// src/commands/ads/index.ts
|
|
10892
|
-
var
|
|
12594
|
+
var adsCommand2 = defineCommand82({
|
|
10893
12595
|
meta: {
|
|
10894
12596
|
name: "ads",
|
|
10895
12597
|
description: `Ad platform commands. Each platform exposes its own native command surface \u2014 no forced parity.
|
|
@@ -10919,11 +12621,11 @@ Examples:
|
|
|
10919
12621
|
});
|
|
10920
12622
|
|
|
10921
12623
|
// src/commands/canvas/index.ts
|
|
10922
|
-
import { defineCommand as
|
|
12624
|
+
import { defineCommand as defineCommand90 } from "citty";
|
|
10923
12625
|
|
|
10924
12626
|
// src/commands/canvas/catalog.ts
|
|
10925
|
-
import { defineCommand as
|
|
10926
|
-
var catalogCommand =
|
|
12627
|
+
import { defineCommand as defineCommand83 } from "citty";
|
|
12628
|
+
var catalogCommand = defineCommand83({
|
|
10927
12629
|
meta: {
|
|
10928
12630
|
name: "catalog",
|
|
10929
12631
|
description: "Print the agent-facing node catalog (JSON Schema). Includes every registered node grouped by category."
|
|
@@ -10940,9 +12642,9 @@ import { execFile } from "child_process";
|
|
|
10940
12642
|
import { readdir, readFile, stat } from "fs/promises";
|
|
10941
12643
|
import path from "path";
|
|
10942
12644
|
import { promisify } from "util";
|
|
10943
|
-
import { defineCommand as
|
|
12645
|
+
import { defineCommand as defineCommand84 } from "citty";
|
|
10944
12646
|
var execFileAsync = promisify(execFile);
|
|
10945
|
-
var inspectCommand =
|
|
12647
|
+
var inspectCommand = defineCommand84({
|
|
10946
12648
|
meta: {
|
|
10947
12649
|
name: "inspect",
|
|
10948
12650
|
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."
|
|
@@ -11051,7 +12753,7 @@ async function probeDuration(filePath) {
|
|
|
11051
12753
|
// src/commands/canvas/run.ts
|
|
11052
12754
|
import { readFile as readFile2 } from "fs/promises";
|
|
11053
12755
|
import path4 from "path";
|
|
11054
|
-
import { defineCommand as
|
|
12756
|
+
import { defineCommand as defineCommand85 } from "citty";
|
|
11055
12757
|
|
|
11056
12758
|
// src/commands/canvas/placeholders.ts
|
|
11057
12759
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
@@ -11121,7 +12823,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
11121
12823
|
}
|
|
11122
12824
|
|
|
11123
12825
|
// src/commands/canvas/run.ts
|
|
11124
|
-
var runCommand =
|
|
12826
|
+
var runCommand = defineCommand85({
|
|
11125
12827
|
meta: { name: "run", description: "Validate and execute a canvas JSON file." },
|
|
11126
12828
|
args: {
|
|
11127
12829
|
file: { type: "positional", required: true, description: "Path to canvas JSON" },
|
|
@@ -11233,30 +12935,30 @@ var runCommand = defineCommand83({
|
|
|
11233
12935
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
11234
12936
|
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
11235
12937
|
import path6 from "path";
|
|
11236
|
-
import { defineCommand as
|
|
12938
|
+
import { defineCommand as defineCommand86 } from "citty";
|
|
11237
12939
|
|
|
11238
12940
|
// src/engine/scaffold/staticAd.ts
|
|
11239
|
-
import { z as
|
|
12941
|
+
import { z as z10 } from "zod";
|
|
11240
12942
|
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"]);
|
|
11241
12943
|
var DEFAULT_ASPECT_RATIO = "9:16";
|
|
11242
|
-
var Blueprint =
|
|
11243
|
-
meta:
|
|
11244
|
-
text_content:
|
|
12944
|
+
var Blueprint = z10.object({
|
|
12945
|
+
meta: z10.object({ estimated_aspect_ratio: z10.string().optional() }).loose().optional(),
|
|
12946
|
+
text_content: z10.array(z10.object({ text: z10.string().optional() }).loose()).optional()
|
|
11245
12947
|
}).loose();
|
|
11246
|
-
var ElementLocator =
|
|
11247
|
-
collection:
|
|
11248
|
-
index:
|
|
12948
|
+
var ElementLocator = z10.object({
|
|
12949
|
+
collection: z10.enum(["subjects", "people", "brands_logos"]),
|
|
12950
|
+
index: z10.number().int().nonnegative()
|
|
11249
12951
|
}).loose();
|
|
11250
|
-
var MainElement =
|
|
12952
|
+
var MainElement = z10.object({
|
|
11251
12953
|
// logo | product | person | animal | badge | other
|
|
11252
|
-
type:
|
|
11253
|
-
label:
|
|
11254
|
-
description:
|
|
11255
|
-
expression:
|
|
11256
|
-
reason:
|
|
12954
|
+
type: z10.string(),
|
|
12955
|
+
label: z10.string().optional(),
|
|
12956
|
+
description: z10.string().optional(),
|
|
12957
|
+
expression: z10.string().nullable().optional(),
|
|
12958
|
+
reason: z10.string().optional(),
|
|
11257
12959
|
locator: ElementLocator.optional()
|
|
11258
12960
|
}).loose();
|
|
11259
|
-
var MainElements =
|
|
12961
|
+
var MainElements = z10.array(MainElement);
|
|
11260
12962
|
function sanitizeId(raw, fallback) {
|
|
11261
12963
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
11262
12964
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -11580,7 +13282,7 @@ async function runVisionPasses(canvas) {
|
|
|
11580
13282
|
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
11581
13283
|
}
|
|
11582
13284
|
}
|
|
11583
|
-
var scaffoldStaticAdCommand =
|
|
13285
|
+
var scaffoldStaticAdCommand = defineCommand86({
|
|
11584
13286
|
meta: {
|
|
11585
13287
|
name: "scaffold-static-ad",
|
|
11586
13288
|
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."
|
|
@@ -11676,7 +13378,7 @@ var scaffoldStaticAdCommand = defineCommand84({
|
|
|
11676
13378
|
// src/commands/canvas/scaffold-video.ts
|
|
11677
13379
|
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
11678
13380
|
import path9 from "path";
|
|
11679
|
-
import { defineCommand as
|
|
13381
|
+
import { defineCommand as defineCommand87 } from "citty";
|
|
11680
13382
|
|
|
11681
13383
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
11682
13384
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -11781,7 +13483,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
|
|
|
11781
13483
|
import { toCardinal as nwNl } from "n2words/nl-NL";
|
|
11782
13484
|
import { toCardinal as nwPl } from "n2words/pl-PL";
|
|
11783
13485
|
import { toCardinal as nwPt } from "n2words/pt-PT";
|
|
11784
|
-
import { z as
|
|
13486
|
+
import { z as z11 } from "zod";
|
|
11785
13487
|
|
|
11786
13488
|
// src/engine/scaffold/lib/shoot-modes.ts
|
|
11787
13489
|
var SHOOT_MODES = [
|
|
@@ -12081,49 +13783,49 @@ function trimArgs(durationS, offsetS = 0, dims) {
|
|
|
12081
13783
|
"{{out.video}}"
|
|
12082
13784
|
];
|
|
12083
13785
|
}
|
|
12084
|
-
var FrameAsset =
|
|
12085
|
-
var DialogueLine =
|
|
12086
|
-
speaker:
|
|
12087
|
-
line:
|
|
13786
|
+
var FrameAsset = z11.object({ url: z11.string().optional() }).loose().optional();
|
|
13787
|
+
var DialogueLine = z11.object({
|
|
13788
|
+
speaker: z11.string().optional(),
|
|
13789
|
+
line: z11.string().optional(),
|
|
12088
13790
|
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
12089
|
-
start_s:
|
|
12090
|
-
end_s:
|
|
12091
|
-
delivery:
|
|
12092
|
-
voice_description:
|
|
13791
|
+
start_s: z11.number().optional(),
|
|
13792
|
+
end_s: z11.number().optional(),
|
|
13793
|
+
delivery: z11.string().optional(),
|
|
13794
|
+
voice_description: z11.string().optional()
|
|
12093
13795
|
}).loose();
|
|
12094
|
-
var Sfx =
|
|
12095
|
-
at_s:
|
|
12096
|
-
duration_s:
|
|
12097
|
-
sound_effect_prompt:
|
|
12098
|
-
description:
|
|
13796
|
+
var Sfx = z11.object({
|
|
13797
|
+
at_s: z11.number().optional(),
|
|
13798
|
+
duration_s: z11.number().optional(),
|
|
13799
|
+
sound_effect_prompt: z11.string().optional(),
|
|
13800
|
+
description: z11.string().optional()
|
|
12099
13801
|
}).loose();
|
|
12100
|
-
var CompositionRegion =
|
|
13802
|
+
var CompositionRegion = z11.object({
|
|
12101
13803
|
// full | top | bottom | left | right | inset
|
|
12102
|
-
panel:
|
|
13804
|
+
panel: z11.string().optional(),
|
|
12103
13805
|
// 9-grid anchor for an `inset` presenter box.
|
|
12104
|
-
position:
|
|
12105
|
-
is_presenter:
|
|
13806
|
+
position: z11.string().optional(),
|
|
13807
|
+
is_presenter: z11.boolean().optional(),
|
|
12106
13808
|
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
12107
|
-
cast_ref:
|
|
12108
|
-
summary:
|
|
12109
|
-
frame_prompt:
|
|
12110
|
-
motion_prompt:
|
|
13809
|
+
cast_ref: z11.string().optional(),
|
|
13810
|
+
summary: z11.string().optional(),
|
|
13811
|
+
frame_prompt: z11.string().optional(),
|
|
13812
|
+
motion_prompt: z11.string().optional()
|
|
12111
13813
|
}).loose();
|
|
12112
|
-
var SceneComposition =
|
|
13814
|
+
var SceneComposition = z11.object({
|
|
12113
13815
|
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
12114
|
-
layout:
|
|
13816
|
+
layout: z11.string().optional(),
|
|
12115
13817
|
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
12116
|
-
split_axis:
|
|
12117
|
-
regions:
|
|
13818
|
+
split_axis: z11.string().optional(),
|
|
13819
|
+
regions: z11.array(CompositionRegion).optional()
|
|
12118
13820
|
}).loose();
|
|
12119
|
-
var CameraMotion =
|
|
12120
|
-
var TranscriptWord =
|
|
12121
|
-
var Scene =
|
|
12122
|
-
start_s:
|
|
12123
|
-
end_s:
|
|
12124
|
-
duration_s:
|
|
12125
|
-
summary:
|
|
12126
|
-
action_detail:
|
|
13821
|
+
var CameraMotion = z11.object({ movement: z11.string().optional(), detail: z11.string().optional() }).loose();
|
|
13822
|
+
var TranscriptWord = z11.object({ text: z11.string().optional() }).loose();
|
|
13823
|
+
var Scene = z11.object({
|
|
13824
|
+
start_s: z11.number().optional(),
|
|
13825
|
+
end_s: z11.number().optional(),
|
|
13826
|
+
duration_s: z11.number().optional(),
|
|
13827
|
+
summary: z11.string().optional(),
|
|
13828
|
+
action_detail: z11.string().optional(),
|
|
12127
13829
|
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
12128
13830
|
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
12129
13831
|
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
@@ -12131,77 +13833,77 @@ var Scene = z9.object({
|
|
|
12131
13833
|
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
12132
13834
|
// grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
|
|
12133
13835
|
// UGC/product mode; a human can override per scene by setting this.
|
|
12134
|
-
shoot_mode:
|
|
13836
|
+
shoot_mode: z11.string().optional(),
|
|
12135
13837
|
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
12136
13838
|
// absent the scene falls back to its shoot mode's default ambience.
|
|
12137
|
-
ambient:
|
|
13839
|
+
ambient: z11.string().optional(),
|
|
12138
13840
|
camera_motion: CameraMotion.optional(),
|
|
12139
|
-
start_frame_prompt:
|
|
12140
|
-
end_frame_prompt:
|
|
12141
|
-
motion_prompt:
|
|
13841
|
+
start_frame_prompt: z11.string().optional(),
|
|
13842
|
+
end_frame_prompt: z11.string().optional(),
|
|
13843
|
+
motion_prompt: z11.string().optional(),
|
|
12142
13844
|
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
12143
13845
|
// script re-craft checklist. Inferred from position when absent.
|
|
12144
|
-
narrative_role:
|
|
13846
|
+
narrative_role: z11.string().optional(),
|
|
12145
13847
|
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
12146
13848
|
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
12147
13849
|
// into the hook's start-frame description so the generator renders that state,
|
|
12148
13850
|
// not a calm influencer (CCA-11).
|
|
12149
|
-
hook_mechanic:
|
|
13851
|
+
hook_mechanic: z11.object({ mechanic: z11.string().optional(), why_it_stops_scroll: z11.string().optional() }).loose().optional(),
|
|
12150
13852
|
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
12151
|
-
scene_setting:
|
|
13853
|
+
scene_setting: z11.string().optional(),
|
|
12152
13854
|
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
12153
13855
|
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
12154
13856
|
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
12155
13857
|
// ignored (nothing follows it).
|
|
12156
|
-
transition_out:
|
|
12157
|
-
dialogue:
|
|
12158
|
-
sfx:
|
|
12159
|
-
overlays:
|
|
12160
|
-
floating_elements:
|
|
12161
|
-
transcript_slice:
|
|
13858
|
+
transition_out: z11.object({ type: z11.string().optional(), description: z11.string().optional() }).loose().optional(),
|
|
13859
|
+
dialogue: z11.array(DialogueLine).optional(),
|
|
13860
|
+
sfx: z11.array(Sfx).optional(),
|
|
13861
|
+
overlays: z11.array(z11.unknown()).optional(),
|
|
13862
|
+
floating_elements: z11.array(z11.unknown()).optional(),
|
|
13863
|
+
transcript_slice: z11.array(TranscriptWord).optional(),
|
|
12162
13864
|
start_frame_asset: FrameAsset,
|
|
12163
13865
|
end_frame_asset: FrameAsset,
|
|
12164
13866
|
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
12165
13867
|
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
12166
13868
|
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
12167
13869
|
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
12168
|
-
continues_previous:
|
|
13870
|
+
continues_previous: z11.boolean().optional()
|
|
12169
13871
|
}).loose();
|
|
12170
|
-
var VideoBlueprint =
|
|
12171
|
-
source:
|
|
12172
|
-
global:
|
|
12173
|
-
music:
|
|
12174
|
-
present:
|
|
12175
|
-
music_prompt:
|
|
13872
|
+
var VideoBlueprint = z11.object({
|
|
13873
|
+
source: z11.object({ aspect_ratio: z11.string().optional(), duration_s: z11.number().optional() }).loose().optional(),
|
|
13874
|
+
global: z11.object({
|
|
13875
|
+
music: z11.object({
|
|
13876
|
+
present: z11.boolean().optional(),
|
|
13877
|
+
music_prompt: z11.string().optional(),
|
|
12176
13878
|
// Absolute second the music enters in the reference (the bed often
|
|
12177
13879
|
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
12178
13880
|
// instead of at 0 so the timing matches.
|
|
12179
|
-
starts_at_s:
|
|
13881
|
+
starts_at_s: z11.number().optional(),
|
|
12180
13882
|
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
12181
13883
|
// reference track. We never reuse it — only style the regenerated bed.
|
|
12182
|
-
identified_track:
|
|
13884
|
+
identified_track: z11.object({ title: z11.string().optional(), artist: z11.string().optional() }).loose().nullish()
|
|
12183
13885
|
}).loose().optional(),
|
|
12184
|
-
cast:
|
|
12185
|
-
|
|
12186
|
-
id:
|
|
12187
|
-
description:
|
|
13886
|
+
cast: z11.array(
|
|
13887
|
+
z11.object({
|
|
13888
|
+
id: z11.string().optional(),
|
|
13889
|
+
description: z11.string().optional(),
|
|
12188
13890
|
// The deconstruct's note on the target-market localization (e.g. "native
|
|
12189
13891
|
// French speaker") — read to derive the spoken-track language code.
|
|
12190
|
-
market_localization_note:
|
|
13892
|
+
market_localization_note: z11.string().optional()
|
|
12191
13893
|
}).loose()
|
|
12192
13894
|
).optional(),
|
|
12193
|
-
voiceover:
|
|
13895
|
+
voiceover: z11.object({
|
|
12194
13896
|
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
12195
13897
|
// voiceover | none → narration over the picture (no lip-sync).
|
|
12196
|
-
mode:
|
|
12197
|
-
voice_description:
|
|
12198
|
-
persona:
|
|
13898
|
+
mode: z11.string().optional(),
|
|
13899
|
+
voice_description: z11.string().optional(),
|
|
13900
|
+
persona: z11.string().optional()
|
|
12199
13901
|
}).loose().optional(),
|
|
12200
13902
|
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
12201
13903
|
// first hex is the dominant brand colour); never to drive frame generation.
|
|
12202
|
-
style:
|
|
13904
|
+
style: z11.object({ palette: z11.array(z11.object({ hex: z11.string().optional() }).loose()).optional() }).loose().optional()
|
|
12203
13905
|
}).loose().optional(),
|
|
12204
|
-
scenes:
|
|
13906
|
+
scenes: z11.array(Scene).min(1)
|
|
12205
13907
|
}).loose();
|
|
12206
13908
|
function injectHookPhysicality(blueprint) {
|
|
12207
13909
|
for (const scene of blueprint.scenes) {
|
|
@@ -12211,26 +13913,26 @@ function injectHookPhysicality(blueprint) {
|
|
|
12211
13913
|
scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
|
|
12212
13914
|
}
|
|
12213
13915
|
}
|
|
12214
|
-
var AppearsItem =
|
|
12215
|
-
var RecurringElement =
|
|
13916
|
+
var AppearsItem = z11.union([z11.number(), z11.object({ scene: z11.number(), edge: z11.string().optional() }).loose()]);
|
|
13917
|
+
var RecurringElement = z11.object({
|
|
12216
13918
|
// person | animal | product | logo | badge | other
|
|
12217
|
-
type:
|
|
12218
|
-
label:
|
|
12219
|
-
description:
|
|
12220
|
-
expression:
|
|
13919
|
+
type: z11.string(),
|
|
13920
|
+
label: z11.string().optional(),
|
|
13921
|
+
description: z11.string().optional(),
|
|
13922
|
+
expression: z11.string().nullable().optional(),
|
|
12221
13923
|
// When the element maps to a global cast entry, its stable id (for annotation).
|
|
12222
|
-
cast_id:
|
|
13924
|
+
cast_id: z11.string().nullable().optional(),
|
|
12223
13925
|
// The label of another element that is the SAME individual as this one, shown
|
|
12224
13926
|
// in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
|
|
12225
13927
|
// pink shirt and believer in a white shirt). Each look gets its own reference
|
|
12226
13928
|
// slot, but the face/identity must stay identical across them.
|
|
12227
|
-
same_as:
|
|
13929
|
+
same_as: z11.string().nullable().optional(),
|
|
12228
13930
|
// Scenes the element appears in. Either a bare list of scene indices (both
|
|
12229
13931
|
// edges) or per-{scene,edge} entries. Both forms are accepted and merged.
|
|
12230
|
-
scenes:
|
|
12231
|
-
appears_in:
|
|
13932
|
+
scenes: z11.array(z11.number()).optional(),
|
|
13933
|
+
appears_in: z11.array(AppearsItem).optional()
|
|
12232
13934
|
}).loose();
|
|
12233
|
-
var RecurringElements =
|
|
13935
|
+
var RecurringElements = z11.array(RecurringElement);
|
|
12234
13936
|
function sanitizeId2(raw, fallback) {
|
|
12235
13937
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
12236
13938
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -13756,25 +15458,25 @@ function buildSfxMusic(blueprint, nodes) {
|
|
|
13756
15458
|
}
|
|
13757
15459
|
return tracks;
|
|
13758
15460
|
}
|
|
13759
|
-
var OverlayStyle =
|
|
13760
|
-
var Overlay =
|
|
13761
|
-
text:
|
|
13762
|
-
appears_at_s:
|
|
13763
|
-
duration_s:
|
|
13764
|
-
position:
|
|
13765
|
-
role:
|
|
13766
|
-
animation:
|
|
13767
|
-
animation_detail:
|
|
15461
|
+
var OverlayStyle = z11.object({ color_hex: z11.string().optional(), background: z11.string().optional(), size: z11.string().optional() }).loose();
|
|
15462
|
+
var Overlay = z11.object({
|
|
15463
|
+
text: z11.string().optional(),
|
|
15464
|
+
appears_at_s: z11.number().optional(),
|
|
15465
|
+
duration_s: z11.number().optional(),
|
|
15466
|
+
position: z11.string().optional(),
|
|
15467
|
+
role: z11.string().optional(),
|
|
15468
|
+
animation: z11.string().optional(),
|
|
15469
|
+
animation_detail: z11.string().optional(),
|
|
13768
15470
|
style: OverlayStyle.optional()
|
|
13769
15471
|
}).loose();
|
|
13770
|
-
var FloatingElement =
|
|
13771
|
-
kind:
|
|
13772
|
-
description:
|
|
13773
|
-
brand_name:
|
|
13774
|
-
what_it_represents:
|
|
13775
|
-
appears_at_s:
|
|
13776
|
-
duration_s:
|
|
13777
|
-
position:
|
|
15472
|
+
var FloatingElement = z11.object({
|
|
15473
|
+
kind: z11.string().optional(),
|
|
15474
|
+
description: z11.string().optional(),
|
|
15475
|
+
brand_name: z11.string().nullish(),
|
|
15476
|
+
what_it_represents: z11.string().optional(),
|
|
15477
|
+
appears_at_s: z11.number().optional(),
|
|
15478
|
+
duration_s: z11.number().optional(),
|
|
15479
|
+
position: z11.string().optional()
|
|
13778
15480
|
}).loose();
|
|
13779
15481
|
function escapeHtml(s) {
|
|
13780
15482
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -13806,7 +15508,7 @@ function positionClass(position) {
|
|
|
13806
15508
|
function collectCaptions(blueprint) {
|
|
13807
15509
|
return blueprint.scenes.flatMap((scene) => {
|
|
13808
15510
|
const sceneStart = scene.start_s ?? 0;
|
|
13809
|
-
const overlays =
|
|
15511
|
+
const overlays = z11.array(Overlay).safeParse(scene.overlays ?? []);
|
|
13810
15512
|
return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
|
|
13811
15513
|
const at = ov.appears_at_s ?? sceneStart;
|
|
13812
15514
|
return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
|
|
@@ -13935,7 +15637,7 @@ function buildOverlayHtml(input) {
|
|
|
13935
15637
|
};
|
|
13936
15638
|
for (const scene of blueprint.scenes) {
|
|
13937
15639
|
const sceneStart = scene.start_s ?? 0;
|
|
13938
|
-
const floats =
|
|
15640
|
+
const floats = z11.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
13939
15641
|
const parts = (floats.success ? floats.data.filter((fe) => keepFloat(fe, sceneStart)).map((fe) => floatingStub(fe, sceneStart)) : []).filter(Boolean);
|
|
13940
15642
|
const pip = uiPipStub(scene);
|
|
13941
15643
|
if (pip) parts.push(pip);
|
|
@@ -14196,8 +15898,8 @@ function buildMotionBoard(blueprint) {
|
|
|
14196
15898
|
const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
|
|
14197
15899
|
cursor = end_s;
|
|
14198
15900
|
const spoken = sceneSpokenText(scene);
|
|
14199
|
-
const overlays =
|
|
14200
|
-
const floats =
|
|
15901
|
+
const overlays = z11.array(Overlay).safeParse(scene.overlays ?? []);
|
|
15902
|
+
const floats = z11.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
14201
15903
|
const graphics = [
|
|
14202
15904
|
...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
|
|
14203
15905
|
kind: "text",
|
|
@@ -14659,7 +16361,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
14659
16361
|
return fail2("deconstruct", e instanceof Error ? e.message : String(e));
|
|
14660
16362
|
}
|
|
14661
16363
|
}
|
|
14662
|
-
var scaffoldVideoCommand =
|
|
16364
|
+
var scaffoldVideoCommand = defineCommand87({
|
|
14663
16365
|
meta: {
|
|
14664
16366
|
name: "scaffold-video",
|
|
14665
16367
|
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`."
|
|
@@ -14828,7 +16530,7 @@ var scaffoldVideoCommand = defineCommand85({
|
|
|
14828
16530
|
// src/commands/canvas/set-prompt.ts
|
|
14829
16531
|
import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
14830
16532
|
import path10 from "path";
|
|
14831
|
-
import { defineCommand as
|
|
16533
|
+
import { defineCommand as defineCommand88 } from "citty";
|
|
14832
16534
|
function setNodePrompt(canvas, nodeId, text) {
|
|
14833
16535
|
const nodes = canvas?.nodes;
|
|
14834
16536
|
if (!Array.isArray(nodes)) throw new Error("canvas has no nodes array");
|
|
@@ -14843,7 +16545,7 @@ function setNodePrompt(canvas, nodeId, text) {
|
|
|
14843
16545
|
newNodes[idx] = newNode;
|
|
14844
16546
|
return { ...canvas, nodes: newNodes };
|
|
14845
16547
|
}
|
|
14846
|
-
var setPromptCommand =
|
|
16548
|
+
var setPromptCommand = defineCommand88({
|
|
14847
16549
|
meta: {
|
|
14848
16550
|
name: "set-prompt",
|
|
14849
16551
|
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."
|
|
@@ -14903,8 +16605,8 @@ var setPromptCommand = defineCommand86({
|
|
|
14903
16605
|
// src/commands/canvas/validate.ts
|
|
14904
16606
|
import { readFile as readFile8 } from "fs/promises";
|
|
14905
16607
|
import path11 from "path";
|
|
14906
|
-
import { defineCommand as
|
|
14907
|
-
var validateCommand =
|
|
16608
|
+
import { defineCommand as defineCommand89 } from "citty";
|
|
16609
|
+
var validateCommand = defineCommand89({
|
|
14908
16610
|
meta: {
|
|
14909
16611
|
name: "validate",
|
|
14910
16612
|
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)."
|
|
@@ -14947,7 +16649,7 @@ var validateCommand = defineCommand87({
|
|
|
14947
16649
|
});
|
|
14948
16650
|
|
|
14949
16651
|
// src/commands/canvas/index.ts
|
|
14950
|
-
var canvasCommand =
|
|
16652
|
+
var canvasCommand = defineCommand90({
|
|
14951
16653
|
meta: {
|
|
14952
16654
|
name: "canvas",
|
|
14953
16655
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -14974,10 +16676,10 @@ Subcommands:
|
|
|
14974
16676
|
});
|
|
14975
16677
|
|
|
14976
16678
|
// src/commands/creatives/index.ts
|
|
14977
|
-
import { defineCommand as
|
|
16679
|
+
import { defineCommand as defineCommand92 } from "citty";
|
|
14978
16680
|
|
|
14979
16681
|
// src/commands/creatives/publish.ts
|
|
14980
|
-
import { defineCommand as
|
|
16682
|
+
import { defineCommand as defineCommand91 } from "citty";
|
|
14981
16683
|
|
|
14982
16684
|
// src/commands/images/api.ts
|
|
14983
16685
|
import { readFile as readFile9 } from "fs/promises";
|
|
@@ -15100,7 +16802,7 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
15100
16802
|
sourceReferenceUrl
|
|
15101
16803
|
});
|
|
15102
16804
|
}
|
|
15103
|
-
var publishCommand =
|
|
16805
|
+
var publishCommand = defineCommand91({
|
|
15104
16806
|
meta: {
|
|
15105
16807
|
name: "publish",
|
|
15106
16808
|
description: "Publish a final static creative image to Baker Creatives and print the creative reference JSON."
|
|
@@ -15146,7 +16848,7 @@ var publishCommand = defineCommand89({
|
|
|
15146
16848
|
});
|
|
15147
16849
|
|
|
15148
16850
|
// src/commands/creatives/index.ts
|
|
15149
|
-
var creativesCommand3 =
|
|
16851
|
+
var creativesCommand3 = defineCommand92({
|
|
15150
16852
|
meta: {
|
|
15151
16853
|
name: "creatives",
|
|
15152
16854
|
description: `Publish static ad creatives as first-class Baker outputs.
|
|
@@ -15162,10 +16864,10 @@ Publishing uploads the image to the Company image library, applies the official
|
|
|
15162
16864
|
});
|
|
15163
16865
|
|
|
15164
16866
|
// src/commands/ga4/index.ts
|
|
15165
|
-
import { defineCommand as
|
|
16867
|
+
import { defineCommand as defineCommand96 } from "citty";
|
|
15166
16868
|
|
|
15167
16869
|
// src/commands/ga4/audit.ts
|
|
15168
|
-
import { defineCommand as
|
|
16870
|
+
import { defineCommand as defineCommand93 } from "citty";
|
|
15169
16871
|
|
|
15170
16872
|
// src/commands/ga4/resolve.ts
|
|
15171
16873
|
async function fetchProperties(useCache = true) {
|
|
@@ -15228,7 +16930,7 @@ registerSchema({
|
|
|
15228
16930
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15229
16931
|
}
|
|
15230
16932
|
});
|
|
15231
|
-
var auditCommand2 =
|
|
16933
|
+
var auditCommand2 = defineCommand93({
|
|
15232
16934
|
meta: {
|
|
15233
16935
|
name: "audit",
|
|
15234
16936
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -15280,7 +16982,7 @@ Examples:
|
|
|
15280
16982
|
});
|
|
15281
16983
|
|
|
15282
16984
|
// src/commands/ga4/properties.ts
|
|
15283
|
-
import { defineCommand as
|
|
16985
|
+
import { defineCommand as defineCommand94 } from "citty";
|
|
15284
16986
|
registerSchema({
|
|
15285
16987
|
command: "ga4.properties",
|
|
15286
16988
|
description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
|
|
@@ -15288,7 +16990,7 @@ registerSchema({
|
|
|
15288
16990
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15289
16991
|
}
|
|
15290
16992
|
});
|
|
15291
|
-
var propertiesCommand =
|
|
16993
|
+
var propertiesCommand = defineCommand94({
|
|
15292
16994
|
meta: {
|
|
15293
16995
|
name: "properties",
|
|
15294
16996
|
description: `List accessible GA4 properties.
|
|
@@ -15336,9 +17038,9 @@ Examples:
|
|
|
15336
17038
|
});
|
|
15337
17039
|
|
|
15338
17040
|
// src/commands/ga4/query.ts
|
|
15339
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as
|
|
17041
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
|
|
15340
17042
|
import { resolve as resolve2 } from "path";
|
|
15341
|
-
import { defineCommand as
|
|
17043
|
+
import { defineCommand as defineCommand95 } from "citty";
|
|
15342
17044
|
|
|
15343
17045
|
// src/commands/ga4/presets.ts
|
|
15344
17046
|
var GA4_PRESETS = [
|
|
@@ -15427,7 +17129,7 @@ function writeRowsToFile2(filePath, rows, append) {
|
|
|
15427
17129
|
writeFileSync4(filePath, content, "utf-8");
|
|
15428
17130
|
}
|
|
15429
17131
|
} else if (append && existsSync5(filePath)) {
|
|
15430
|
-
const existing = JSON.parse(
|
|
17132
|
+
const existing = JSON.parse(readFileSync9(filePath, "utf-8"));
|
|
15431
17133
|
writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
15432
17134
|
} else {
|
|
15433
17135
|
writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -15470,7 +17172,7 @@ function handleError(err) {
|
|
|
15470
17172
|
});
|
|
15471
17173
|
process.exit(1);
|
|
15472
17174
|
}
|
|
15473
|
-
var queryCommand2 =
|
|
17175
|
+
var queryCommand2 = defineCommand95({
|
|
15474
17176
|
meta: {
|
|
15475
17177
|
name: "query",
|
|
15476
17178
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -15541,7 +17243,7 @@ Free-form (escape hatch):
|
|
|
15541
17243
|
});
|
|
15542
17244
|
|
|
15543
17245
|
// src/commands/ga4/index.ts
|
|
15544
|
-
var ga4Command =
|
|
17246
|
+
var ga4Command = defineCommand96({
|
|
15545
17247
|
meta: {
|
|
15546
17248
|
name: "ga4",
|
|
15547
17249
|
description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
|
|
@@ -15564,12 +17266,12 @@ Examples:
|
|
|
15564
17266
|
});
|
|
15565
17267
|
|
|
15566
17268
|
// src/commands/gsc/index.ts
|
|
15567
|
-
import { defineCommand as
|
|
17269
|
+
import { defineCommand as defineCommand100 } from "citty";
|
|
15568
17270
|
|
|
15569
17271
|
// src/commands/gsc/query.ts
|
|
15570
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as
|
|
17272
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
15571
17273
|
import { resolve as resolve3 } from "path";
|
|
15572
|
-
import { defineCommand as
|
|
17274
|
+
import { defineCommand as defineCommand97 } from "citty";
|
|
15573
17275
|
|
|
15574
17276
|
// src/commands/gsc/presets.ts
|
|
15575
17277
|
var GSC_PRESETS = [
|
|
@@ -15712,7 +17414,7 @@ function writeRowsToFile3(filePath, rows, append) {
|
|
|
15712
17414
|
writeFileSync5(filePath, content, "utf-8");
|
|
15713
17415
|
}
|
|
15714
17416
|
} else if (append && existsSync6(filePath)) {
|
|
15715
|
-
const existing = JSON.parse(
|
|
17417
|
+
const existing = JSON.parse(readFileSync10(filePath, "utf-8"));
|
|
15716
17418
|
writeFileSync5(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
15717
17419
|
} else {
|
|
15718
17420
|
writeFileSync5(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -15757,7 +17459,7 @@ function handleError2(err) {
|
|
|
15757
17459
|
});
|
|
15758
17460
|
process.exit(1);
|
|
15759
17461
|
}
|
|
15760
|
-
var queryCommand3 =
|
|
17462
|
+
var queryCommand3 = defineCommand97({
|
|
15761
17463
|
meta: {
|
|
15762
17464
|
name: "query",
|
|
15763
17465
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -15835,7 +17537,7 @@ Free-form (escape hatch):
|
|
|
15835
17537
|
});
|
|
15836
17538
|
|
|
15837
17539
|
// src/commands/gsc/sitemaps.ts
|
|
15838
|
-
import { defineCommand as
|
|
17540
|
+
import { defineCommand as defineCommand98 } from "citty";
|
|
15839
17541
|
registerSchema({
|
|
15840
17542
|
command: "gsc.sitemaps",
|
|
15841
17543
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -15844,7 +17546,7 @@ registerSchema({
|
|
|
15844
17546
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15845
17547
|
}
|
|
15846
17548
|
});
|
|
15847
|
-
var sitemapsCommand =
|
|
17549
|
+
var sitemapsCommand = defineCommand98({
|
|
15848
17550
|
meta: {
|
|
15849
17551
|
name: "sitemaps",
|
|
15850
17552
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -15894,7 +17596,7 @@ Examples:
|
|
|
15894
17596
|
});
|
|
15895
17597
|
|
|
15896
17598
|
// src/commands/gsc/sites.ts
|
|
15897
|
-
import { defineCommand as
|
|
17599
|
+
import { defineCommand as defineCommand99 } from "citty";
|
|
15898
17600
|
registerSchema({
|
|
15899
17601
|
command: "gsc.sites",
|
|
15900
17602
|
description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
|
|
@@ -15902,7 +17604,7 @@ registerSchema({
|
|
|
15902
17604
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15903
17605
|
}
|
|
15904
17606
|
});
|
|
15905
|
-
var sitesCommand =
|
|
17607
|
+
var sitesCommand = defineCommand99({
|
|
15906
17608
|
meta: {
|
|
15907
17609
|
name: "sites",
|
|
15908
17610
|
description: `List verified Search Console sites.
|
|
@@ -15950,7 +17652,7 @@ Examples:
|
|
|
15950
17652
|
});
|
|
15951
17653
|
|
|
15952
17654
|
// src/commands/gsc/index.ts
|
|
15953
|
-
var gscCommand =
|
|
17655
|
+
var gscCommand = defineCommand100({
|
|
15954
17656
|
meta: {
|
|
15955
17657
|
name: "gsc",
|
|
15956
17658
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -15973,10 +17675,10 @@ Examples:
|
|
|
15973
17675
|
});
|
|
15974
17676
|
|
|
15975
17677
|
// src/commands/images/index.ts
|
|
15976
|
-
import { defineCommand as
|
|
17678
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
15977
17679
|
|
|
15978
17680
|
// src/commands/images/crop.ts
|
|
15979
|
-
import { defineCommand as
|
|
17681
|
+
import { defineCommand as defineCommand101 } from "citty";
|
|
15980
17682
|
|
|
15981
17683
|
// src/lib/image/crop-sprite.ts
|
|
15982
17684
|
import sharp from "sharp";
|
|
@@ -16101,7 +17803,7 @@ function emitError2(err) {
|
|
|
16101
17803
|
}
|
|
16102
17804
|
process.exit(1);
|
|
16103
17805
|
}
|
|
16104
|
-
var cropCommand =
|
|
17806
|
+
var cropCommand = defineCommand101({
|
|
16105
17807
|
meta: {
|
|
16106
17808
|
name: "crop",
|
|
16107
17809
|
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"
|
|
@@ -16137,7 +17839,7 @@ var cropCommand = defineCommand99({
|
|
|
16137
17839
|
});
|
|
16138
17840
|
|
|
16139
17841
|
// src/commands/images/delete.ts
|
|
16140
|
-
import { defineCommand as
|
|
17842
|
+
import { defineCommand as defineCommand102 } from "citty";
|
|
16141
17843
|
registerSchema({
|
|
16142
17844
|
command: "images.delete",
|
|
16143
17845
|
description: "Delete an image by ID",
|
|
@@ -16151,7 +17853,7 @@ registerSchema({
|
|
|
16151
17853
|
}
|
|
16152
17854
|
}
|
|
16153
17855
|
});
|
|
16154
|
-
var deleteCommand =
|
|
17856
|
+
var deleteCommand = defineCommand102({
|
|
16155
17857
|
meta: {
|
|
16156
17858
|
name: "delete",
|
|
16157
17859
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -16192,7 +17894,7 @@ var deleteCommand = defineCommand100({
|
|
|
16192
17894
|
});
|
|
16193
17895
|
|
|
16194
17896
|
// src/commands/images/dimensions.ts
|
|
16195
|
-
import { defineCommand as
|
|
17897
|
+
import { defineCommand as defineCommand103 } from "citty";
|
|
16196
17898
|
|
|
16197
17899
|
// src/lib/image/dimensions.ts
|
|
16198
17900
|
import { imageSize } from "image-size";
|
|
@@ -16215,7 +17917,7 @@ registerSchema({
|
|
|
16215
17917
|
target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
|
|
16216
17918
|
}
|
|
16217
17919
|
});
|
|
16218
|
-
var dimensionsCommand =
|
|
17920
|
+
var dimensionsCommand = defineCommand103({
|
|
16219
17921
|
meta: {
|
|
16220
17922
|
name: "dimensions",
|
|
16221
17923
|
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"
|
|
@@ -16259,7 +17961,7 @@ var dimensionsCommand = defineCommand101({
|
|
|
16259
17961
|
});
|
|
16260
17962
|
|
|
16261
17963
|
// src/commands/images/extract.ts
|
|
16262
|
-
import { defineCommand as
|
|
17964
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
16263
17965
|
registerSchema({
|
|
16264
17966
|
command: "images.extract",
|
|
16265
17967
|
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
@@ -16275,7 +17977,7 @@ registerSchema({
|
|
|
16275
17977
|
}
|
|
16276
17978
|
}
|
|
16277
17979
|
});
|
|
16278
|
-
var extractCommand =
|
|
17980
|
+
var extractCommand = defineCommand104({
|
|
16279
17981
|
meta: {
|
|
16280
17982
|
name: "extract",
|
|
16281
17983
|
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"
|
|
@@ -16313,7 +18015,7 @@ var extractCommand = defineCommand102({
|
|
|
16313
18015
|
});
|
|
16314
18016
|
|
|
16315
18017
|
// src/commands/images/find.ts
|
|
16316
|
-
import { defineCommand as
|
|
18018
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
16317
18019
|
registerSchema({
|
|
16318
18020
|
command: "images.find",
|
|
16319
18021
|
description: "Fanout image search: library first, then opted-in external providers.",
|
|
@@ -16345,7 +18047,7 @@ registerSchema({
|
|
|
16345
18047
|
}
|
|
16346
18048
|
}
|
|
16347
18049
|
});
|
|
16348
|
-
var findCommand =
|
|
18050
|
+
var findCommand = defineCommand105({
|
|
16349
18051
|
meta: {
|
|
16350
18052
|
name: "find",
|
|
16351
18053
|
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"
|
|
@@ -16394,7 +18096,7 @@ var findCommand = defineCommand103({
|
|
|
16394
18096
|
|
|
16395
18097
|
// src/commands/images/generate.ts
|
|
16396
18098
|
import { readFile as readFile11 } from "fs/promises";
|
|
16397
|
-
import { defineCommand as
|
|
18099
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
16398
18100
|
import sharp2 from "sharp";
|
|
16399
18101
|
var GENERATE_TIMEOUT_MS = 18e4;
|
|
16400
18102
|
var REFERENCE_MAX_EDGE = 1536;
|
|
@@ -16497,7 +18199,7 @@ async function resolveReferences(spec) {
|
|
|
16497
18199
|
}
|
|
16498
18200
|
return out;
|
|
16499
18201
|
}
|
|
16500
|
-
var generateCommand =
|
|
18202
|
+
var generateCommand = defineCommand106({
|
|
16501
18203
|
meta: {
|
|
16502
18204
|
name: "generate",
|
|
16503
18205
|
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]]'"
|
|
@@ -16549,7 +18251,7 @@ var generateCommand = defineCommand104({
|
|
|
16549
18251
|
});
|
|
16550
18252
|
|
|
16551
18253
|
// src/commands/images/get.ts
|
|
16552
|
-
import { defineCommand as
|
|
18254
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
16553
18255
|
registerSchema({
|
|
16554
18256
|
command: "images.get",
|
|
16555
18257
|
description: "Get a single image by ID",
|
|
@@ -16557,7 +18259,7 @@ registerSchema({
|
|
|
16557
18259
|
id: { type: "string", description: "Image ID", required: true }
|
|
16558
18260
|
}
|
|
16559
18261
|
});
|
|
16560
|
-
var getCommand2 =
|
|
18262
|
+
var getCommand2 = defineCommand107({
|
|
16561
18263
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
16562
18264
|
args: {
|
|
16563
18265
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -16593,7 +18295,7 @@ var getCommand2 = defineCommand105({
|
|
|
16593
18295
|
});
|
|
16594
18296
|
|
|
16595
18297
|
// src/commands/images/gif.ts
|
|
16596
|
-
import { defineCommand as
|
|
18298
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
16597
18299
|
registerSchema({
|
|
16598
18300
|
command: "images.gif",
|
|
16599
18301
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -16625,7 +18327,7 @@ registerSchema({
|
|
|
16625
18327
|
}
|
|
16626
18328
|
}
|
|
16627
18329
|
});
|
|
16628
|
-
var gifCommand =
|
|
18330
|
+
var gifCommand = defineCommand108({
|
|
16629
18331
|
meta: {
|
|
16630
18332
|
name: "gif",
|
|
16631
18333
|
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"
|
|
@@ -16672,7 +18374,7 @@ var gifCommand = defineCommand106({
|
|
|
16672
18374
|
});
|
|
16673
18375
|
|
|
16674
18376
|
// src/commands/images/google.ts
|
|
16675
|
-
import { defineCommand as
|
|
18377
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
16676
18378
|
registerSchema({
|
|
16677
18379
|
command: "images.google",
|
|
16678
18380
|
description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
|
|
@@ -16708,7 +18410,7 @@ registerSchema({
|
|
|
16708
18410
|
}
|
|
16709
18411
|
}
|
|
16710
18412
|
});
|
|
16711
|
-
var googleCommand2 =
|
|
18413
|
+
var googleCommand2 = defineCommand109({
|
|
16712
18414
|
meta: {
|
|
16713
18415
|
name: "google",
|
|
16714
18416
|
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"
|
|
@@ -16756,7 +18458,7 @@ var googleCommand2 = defineCommand107({
|
|
|
16756
18458
|
});
|
|
16757
18459
|
|
|
16758
18460
|
// src/commands/images/icon.ts
|
|
16759
|
-
import { defineCommand as
|
|
18461
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
16760
18462
|
registerSchema({
|
|
16761
18463
|
command: "images.icon",
|
|
16762
18464
|
description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
|
|
@@ -16782,7 +18484,7 @@ registerSchema({
|
|
|
16782
18484
|
}
|
|
16783
18485
|
}
|
|
16784
18486
|
});
|
|
16785
|
-
var iconCommand =
|
|
18487
|
+
var iconCommand = defineCommand110({
|
|
16786
18488
|
meta: {
|
|
16787
18489
|
name: "icon",
|
|
16788
18490
|
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'"
|
|
@@ -16822,7 +18524,7 @@ var iconCommand = defineCommand108({
|
|
|
16822
18524
|
});
|
|
16823
18525
|
|
|
16824
18526
|
// src/commands/images/ingest.ts
|
|
16825
|
-
import { defineCommand as
|
|
18527
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
16826
18528
|
registerSchema({
|
|
16827
18529
|
command: "images.ingest",
|
|
16828
18530
|
description: "Ingest a remote image URL into the library (full describe + embed).",
|
|
@@ -16834,7 +18536,7 @@ registerSchema({
|
|
|
16834
18536
|
context: { type: "string", description: "Description context hint", required: false }
|
|
16835
18537
|
}
|
|
16836
18538
|
});
|
|
16837
|
-
var ingestCommand =
|
|
18539
|
+
var ingestCommand = defineCommand111({
|
|
16838
18540
|
meta: {
|
|
16839
18541
|
name: "ingest",
|
|
16840
18542
|
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"
|
|
@@ -16876,7 +18578,7 @@ var ingestCommand = defineCommand109({
|
|
|
16876
18578
|
});
|
|
16877
18579
|
|
|
16878
18580
|
// src/commands/images/library.ts
|
|
16879
|
-
import { defineCommand as
|
|
18581
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
16880
18582
|
registerSchema({
|
|
16881
18583
|
command: "images.library",
|
|
16882
18584
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -16902,7 +18604,7 @@ registerSchema({
|
|
|
16902
18604
|
}
|
|
16903
18605
|
}
|
|
16904
18606
|
});
|
|
16905
|
-
var libraryCommand =
|
|
18607
|
+
var libraryCommand = defineCommand112({
|
|
16906
18608
|
meta: {
|
|
16907
18609
|
name: "library",
|
|
16908
18610
|
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"
|
|
@@ -16959,7 +18661,7 @@ var libraryCommand = defineCommand110({
|
|
|
16959
18661
|
});
|
|
16960
18662
|
|
|
16961
18663
|
// src/commands/images/logo.ts
|
|
16962
|
-
import { defineCommand as
|
|
18664
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
16963
18665
|
registerSchema({
|
|
16964
18666
|
command: "images.logo",
|
|
16965
18667
|
description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
|
|
@@ -16984,7 +18686,7 @@ registerSchema({
|
|
|
16984
18686
|
}
|
|
16985
18687
|
}
|
|
16986
18688
|
});
|
|
16987
|
-
var logoCommand =
|
|
18689
|
+
var logoCommand = defineCommand113({
|
|
16988
18690
|
meta: {
|
|
16989
18691
|
name: "logo",
|
|
16990
18692
|
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"
|
|
@@ -17022,7 +18724,7 @@ var logoCommand = defineCommand111({
|
|
|
17022
18724
|
});
|
|
17023
18725
|
|
|
17024
18726
|
// src/commands/images/normalize.ts
|
|
17025
|
-
import { defineCommand as
|
|
18727
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
17026
18728
|
|
|
17027
18729
|
// src/lib/image/color-changer.ts
|
|
17028
18730
|
import quantize from "quantize";
|
|
@@ -17754,7 +19456,7 @@ function coerceRawArgs(args) {
|
|
|
17754
19456
|
"dry-run": bool(args["dry-run"])
|
|
17755
19457
|
};
|
|
17756
19458
|
}
|
|
17757
|
-
var normalizeCommand =
|
|
19459
|
+
var normalizeCommand = defineCommand114({
|
|
17758
19460
|
meta: {
|
|
17759
19461
|
name: "normalize",
|
|
17760
19462
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -17809,7 +19511,7 @@ Examples:
|
|
|
17809
19511
|
});
|
|
17810
19512
|
|
|
17811
19513
|
// src/commands/images/pinterest.ts
|
|
17812
|
-
import { defineCommand as
|
|
19514
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
17813
19515
|
registerSchema({
|
|
17814
19516
|
command: "images.pinterest",
|
|
17815
19517
|
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.",
|
|
@@ -17829,7 +19531,7 @@ registerSchema({
|
|
|
17829
19531
|
}
|
|
17830
19532
|
}
|
|
17831
19533
|
});
|
|
17832
|
-
var pinterestCommand =
|
|
19534
|
+
var pinterestCommand = defineCommand115({
|
|
17833
19535
|
meta: {
|
|
17834
19536
|
name: "pinterest",
|
|
17835
19537
|
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'"
|
|
@@ -17869,7 +19571,7 @@ var pinterestCommand = defineCommand113({
|
|
|
17869
19571
|
});
|
|
17870
19572
|
|
|
17871
19573
|
// src/commands/images/screenshot.ts
|
|
17872
|
-
import { defineCommand as
|
|
19574
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
17873
19575
|
registerSchema({
|
|
17874
19576
|
command: "images.screenshot",
|
|
17875
19577
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -17885,7 +19587,7 @@ registerSchema({
|
|
|
17885
19587
|
}
|
|
17886
19588
|
}
|
|
17887
19589
|
});
|
|
17888
|
-
var screenshotCommand =
|
|
19590
|
+
var screenshotCommand = defineCommand116({
|
|
17889
19591
|
meta: {
|
|
17890
19592
|
name: "screenshot",
|
|
17891
19593
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -17935,7 +19637,7 @@ var screenshotCommand = defineCommand114({
|
|
|
17935
19637
|
});
|
|
17936
19638
|
|
|
17937
19639
|
// src/commands/images/search.ts
|
|
17938
|
-
import { defineCommand as
|
|
19640
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
17939
19641
|
registerSchema({
|
|
17940
19642
|
command: "images.search",
|
|
17941
19643
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -17951,7 +19653,7 @@ registerSchema({
|
|
|
17951
19653
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
17952
19654
|
}
|
|
17953
19655
|
});
|
|
17954
|
-
var searchCommand =
|
|
19656
|
+
var searchCommand = defineCommand117({
|
|
17955
19657
|
meta: {
|
|
17956
19658
|
name: "search",
|
|
17957
19659
|
description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
|
|
@@ -18011,7 +19713,7 @@ var searchCommand = defineCommand115({
|
|
|
18011
19713
|
});
|
|
18012
19714
|
|
|
18013
19715
|
// src/commands/images/sticker.ts
|
|
18014
|
-
import { defineCommand as
|
|
19716
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
18015
19717
|
registerSchema({
|
|
18016
19718
|
command: "images.sticker",
|
|
18017
19719
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -18043,7 +19745,7 @@ registerSchema({
|
|
|
18043
19745
|
}
|
|
18044
19746
|
}
|
|
18045
19747
|
});
|
|
18046
|
-
var stickerCommand =
|
|
19748
|
+
var stickerCommand = defineCommand118({
|
|
18047
19749
|
meta: {
|
|
18048
19750
|
name: "sticker",
|
|
18049
19751
|
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"
|
|
@@ -18090,7 +19792,7 @@ var stickerCommand = defineCommand116({
|
|
|
18090
19792
|
});
|
|
18091
19793
|
|
|
18092
19794
|
// src/commands/images/stock.ts
|
|
18093
|
-
import { defineCommand as
|
|
19795
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
18094
19796
|
registerSchema({
|
|
18095
19797
|
command: "images.stock",
|
|
18096
19798
|
description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
|
|
@@ -18148,7 +19850,7 @@ registerSchema({
|
|
|
18148
19850
|
}
|
|
18149
19851
|
}
|
|
18150
19852
|
});
|
|
18151
|
-
var stockCommand =
|
|
19853
|
+
var stockCommand = defineCommand119({
|
|
18152
19854
|
meta: {
|
|
18153
19855
|
name: "stock",
|
|
18154
19856
|
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"
|
|
@@ -18204,7 +19906,7 @@ var stockCommand = defineCommand117({
|
|
|
18204
19906
|
});
|
|
18205
19907
|
|
|
18206
19908
|
// src/lib/tags-command.ts
|
|
18207
|
-
import { defineCommand as
|
|
19909
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
18208
19910
|
function makeTagsCommand(command, label, endpoint) {
|
|
18209
19911
|
registerSchema({
|
|
18210
19912
|
command: `${command}.tags`,
|
|
@@ -18213,7 +19915,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
18213
19915
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
18214
19916
|
}
|
|
18215
19917
|
});
|
|
18216
|
-
return
|
|
19918
|
+
return defineCommand120({
|
|
18217
19919
|
meta: {
|
|
18218
19920
|
name: "tags",
|
|
18219
19921
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -18249,7 +19951,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
18249
19951
|
var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
18250
19952
|
|
|
18251
19953
|
// src/commands/images/upload.ts
|
|
18252
|
-
import { defineCommand as
|
|
19954
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
18253
19955
|
registerSchema({
|
|
18254
19956
|
command: "images.upload",
|
|
18255
19957
|
description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
|
|
@@ -18287,7 +19989,7 @@ registerSchema({
|
|
|
18287
19989
|
function isRemoteUrl2(value) {
|
|
18288
19990
|
return /^https?:\/\//i.test(value);
|
|
18289
19991
|
}
|
|
18290
|
-
var uploadCommand =
|
|
19992
|
+
var uploadCommand = defineCommand121({
|
|
18291
19993
|
meta: {
|
|
18292
19994
|
name: "upload",
|
|
18293
19995
|
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'"
|
|
@@ -18380,7 +20082,7 @@ async function uploadLocal(target, args) {
|
|
|
18380
20082
|
}
|
|
18381
20083
|
|
|
18382
20084
|
// src/commands/images/upscale.ts
|
|
18383
|
-
import { defineCommand as
|
|
20085
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
18384
20086
|
registerSchema({
|
|
18385
20087
|
command: "images.upscale",
|
|
18386
20088
|
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).",
|
|
@@ -18395,7 +20097,7 @@ registerSchema({
|
|
|
18395
20097
|
}
|
|
18396
20098
|
});
|
|
18397
20099
|
var POLL_INTERVAL_MS3 = 1500;
|
|
18398
|
-
var upscaleCommand =
|
|
20100
|
+
var upscaleCommand = defineCommand122({
|
|
18399
20101
|
meta: {
|
|
18400
20102
|
name: "upscale",
|
|
18401
20103
|
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"
|
|
@@ -18450,7 +20152,7 @@ var upscaleCommand = defineCommand120({
|
|
|
18450
20152
|
});
|
|
18451
20153
|
|
|
18452
20154
|
// src/commands/images/use.ts
|
|
18453
|
-
import { defineCommand as
|
|
20155
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
18454
20156
|
registerSchema({
|
|
18455
20157
|
command: "images.use",
|
|
18456
20158
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -18466,7 +20168,7 @@ registerSchema({
|
|
|
18466
20168
|
}
|
|
18467
20169
|
});
|
|
18468
20170
|
var POLL_INTERVAL_MS4 = 1500;
|
|
18469
|
-
var useCommand =
|
|
20171
|
+
var useCommand = defineCommand123({
|
|
18470
20172
|
meta: {
|
|
18471
20173
|
name: "use",
|
|
18472
20174
|
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"
|
|
@@ -18512,7 +20214,7 @@ var useCommand = defineCommand121({
|
|
|
18512
20214
|
});
|
|
18513
20215
|
|
|
18514
20216
|
// src/commands/images/index.ts
|
|
18515
|
-
var imagesCommand =
|
|
20217
|
+
var imagesCommand = defineCommand124({
|
|
18516
20218
|
meta: {
|
|
18517
20219
|
name: "images",
|
|
18518
20220
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -18582,7 +20284,7 @@ Paid transforms (run on the Convex backend, cost-tracked):
|
|
|
18582
20284
|
});
|
|
18583
20285
|
|
|
18584
20286
|
// src/commands/mcp/index.ts
|
|
18585
|
-
import { defineCommand as
|
|
20287
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
18586
20288
|
var SCOPES = ["user", "user_org", "company", "org"];
|
|
18587
20289
|
function parseScope(raw) {
|
|
18588
20290
|
const scope = raw === void 0 ? "company" : String(raw);
|
|
@@ -18621,7 +20323,7 @@ registerSchema({
|
|
|
18621
20323
|
description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
|
|
18622
20324
|
args: {}
|
|
18623
20325
|
});
|
|
18624
|
-
var listCommand4 =
|
|
20326
|
+
var listCommand4 = defineCommand125({
|
|
18625
20327
|
meta: { name: "list", description: "List custom MCP servers visible to this company's chats." },
|
|
18626
20328
|
run: async () => {
|
|
18627
20329
|
try {
|
|
@@ -18646,7 +20348,7 @@ registerSchema({
|
|
|
18646
20348
|
header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
|
|
18647
20349
|
}
|
|
18648
20350
|
});
|
|
18649
|
-
var addCommand =
|
|
20351
|
+
var addCommand = defineCommand125({
|
|
18650
20352
|
meta: {
|
|
18651
20353
|
name: "add",
|
|
18652
20354
|
description: `Register a custom MCP server. Tools appear as mcp__<name>__* on the NEXT message.
|
|
@@ -18687,7 +20389,7 @@ registerSchema({
|
|
|
18687
20389
|
description: "Remove a company custom MCP server by name.",
|
|
18688
20390
|
args: { name: { type: "string", description: "Server name to remove", required: true } }
|
|
18689
20391
|
});
|
|
18690
|
-
var removeCommand3 =
|
|
20392
|
+
var removeCommand3 = defineCommand125({
|
|
18691
20393
|
meta: {
|
|
18692
20394
|
name: "remove",
|
|
18693
20395
|
description: `Remove a company custom MCP server by name.
|
|
@@ -18709,7 +20411,7 @@ Example:
|
|
|
18709
20411
|
}
|
|
18710
20412
|
}
|
|
18711
20413
|
});
|
|
18712
|
-
var mcpCommand =
|
|
20414
|
+
var mcpCommand = defineCommand125({
|
|
18713
20415
|
meta: {
|
|
18714
20416
|
name: "mcp",
|
|
18715
20417
|
description: `Custom MCP servers for this company \u2014 point the agent at any HTTPS MCP endpoint.
|
|
@@ -18733,10 +20435,10 @@ Examples:
|
|
|
18733
20435
|
});
|
|
18734
20436
|
|
|
18735
20437
|
// src/commands/research/index.ts
|
|
18736
|
-
import { defineCommand as
|
|
20438
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
18737
20439
|
|
|
18738
20440
|
// src/commands/research/advertisers.ts
|
|
18739
|
-
import { defineCommand as
|
|
20441
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
18740
20442
|
|
|
18741
20443
|
// src/commands/research/output.ts
|
|
18742
20444
|
var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
|
|
@@ -18849,7 +20551,7 @@ var FIELDS3 = {
|
|
|
18849
20551
|
etv: "Estimated traffic value (USD)",
|
|
18850
20552
|
visibility: "SERP visibility score (0-1)"
|
|
18851
20553
|
};
|
|
18852
|
-
var advertisersCommand =
|
|
20554
|
+
var advertisersCommand = defineCommand126({
|
|
18853
20555
|
meta: {
|
|
18854
20556
|
name: "advertisers",
|
|
18855
20557
|
description: `Find domains competing for a keyword in Google SERPs.
|
|
@@ -18896,7 +20598,7 @@ Examples:
|
|
|
18896
20598
|
});
|
|
18897
20599
|
|
|
18898
20600
|
// src/commands/research/autocomplete.ts
|
|
18899
|
-
import { defineCommand as
|
|
20601
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
18900
20602
|
registerSchema({
|
|
18901
20603
|
command: "research.autocomplete",
|
|
18902
20604
|
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).",
|
|
@@ -18919,7 +20621,7 @@ registerSchema({
|
|
|
18919
20621
|
var FIELDS4 = {
|
|
18920
20622
|
suggestion: "Autocomplete suggestion from Google"
|
|
18921
20623
|
};
|
|
18922
|
-
var autocompleteCommand =
|
|
20624
|
+
var autocompleteCommand = defineCommand127({
|
|
18923
20625
|
meta: {
|
|
18924
20626
|
name: "autocomplete",
|
|
18925
20627
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -18965,7 +20667,7 @@ Examples:
|
|
|
18965
20667
|
});
|
|
18966
20668
|
|
|
18967
20669
|
// src/commands/research/countries.ts
|
|
18968
|
-
import { defineCommand as
|
|
20670
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
18969
20671
|
registerSchema({
|
|
18970
20672
|
command: "research.countries",
|
|
18971
20673
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -19022,7 +20724,7 @@ var FIELDS5 = {
|
|
|
19022
20724
|
code: "Country code to pass as --location",
|
|
19023
20725
|
name: "Country name"
|
|
19024
20726
|
};
|
|
19025
|
-
var countriesCommand =
|
|
20727
|
+
var countriesCommand = defineCommand128({
|
|
19026
20728
|
meta: {
|
|
19027
20729
|
name: "countries",
|
|
19028
20730
|
description: "List all supported country codes for --location flag."
|
|
@@ -19033,7 +20735,7 @@ var countriesCommand = defineCommand126({
|
|
|
19033
20735
|
});
|
|
19034
20736
|
|
|
19035
20737
|
// src/commands/research/intent.ts
|
|
19036
|
-
import { defineCommand as
|
|
20738
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
19037
20739
|
registerSchema({
|
|
19038
20740
|
command: "research.intent",
|
|
19039
20741
|
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.",
|
|
@@ -19056,7 +20758,7 @@ var FIELDS6 = {
|
|
|
19056
20758
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
19057
20759
|
probability: "Confidence score 0.0-1.0"
|
|
19058
20760
|
};
|
|
19059
|
-
var intentCommand =
|
|
20761
|
+
var intentCommand = defineCommand129({
|
|
19060
20762
|
meta: {
|
|
19061
20763
|
name: "intent",
|
|
19062
20764
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -19104,7 +20806,7 @@ Examples:
|
|
|
19104
20806
|
});
|
|
19105
20807
|
|
|
19106
20808
|
// src/commands/research/keyword-gap.ts
|
|
19107
|
-
import { defineCommand as
|
|
20809
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
19108
20810
|
registerSchema({
|
|
19109
20811
|
command: "research.keyword-gap",
|
|
19110
20812
|
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.",
|
|
@@ -19133,7 +20835,7 @@ var FIELDS7 = {
|
|
|
19133
20835
|
cpc: "Cost per click USD",
|
|
19134
20836
|
their_position: "Competitor's ranking position"
|
|
19135
20837
|
};
|
|
19136
|
-
var keywordGapCommand =
|
|
20838
|
+
var keywordGapCommand = defineCommand130({
|
|
19137
20839
|
meta: {
|
|
19138
20840
|
name: "keyword-gap",
|
|
19139
20841
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -19207,7 +20909,7 @@ Examples:
|
|
|
19207
20909
|
});
|
|
19208
20910
|
|
|
19209
20911
|
// src/commands/research/keywords-for-site.ts
|
|
19210
|
-
import { defineCommand as
|
|
20912
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
19211
20913
|
registerSchema({
|
|
19212
20914
|
command: "research.keywords-for-site",
|
|
19213
20915
|
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.",
|
|
@@ -19240,7 +20942,7 @@ var FIELDS8 = {
|
|
|
19240
20942
|
competition: "LOW, MEDIUM, or HIGH",
|
|
19241
20943
|
competition_index: "Competition score 0-100"
|
|
19242
20944
|
};
|
|
19243
|
-
var keywordsForSiteCommand =
|
|
20945
|
+
var keywordsForSiteCommand = defineCommand131({
|
|
19244
20946
|
meta: {
|
|
19245
20947
|
name: "keywords-for-site",
|
|
19246
20948
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -19293,7 +20995,7 @@ Examples:
|
|
|
19293
20995
|
});
|
|
19294
20996
|
|
|
19295
20997
|
// src/commands/research/languages.ts
|
|
19296
|
-
import { defineCommand as
|
|
20998
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
19297
20999
|
registerSchema({
|
|
19298
21000
|
command: "research.languages",
|
|
19299
21001
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -19323,7 +21025,7 @@ var FIELDS9 = {
|
|
|
19323
21025
|
code: "Language code to pass as --language",
|
|
19324
21026
|
name: "Language name (also accepted by --language)"
|
|
19325
21027
|
};
|
|
19326
|
-
var languagesCommand2 =
|
|
21028
|
+
var languagesCommand2 = defineCommand132({
|
|
19327
21029
|
meta: {
|
|
19328
21030
|
name: "languages",
|
|
19329
21031
|
description: "List all supported language codes for --language flag."
|
|
@@ -19334,7 +21036,7 @@ var languagesCommand2 = defineCommand130({
|
|
|
19334
21036
|
});
|
|
19335
21037
|
|
|
19336
21038
|
// src/commands/research/lighthouse.ts
|
|
19337
|
-
import { defineCommand as
|
|
21039
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
19338
21040
|
registerSchema({
|
|
19339
21041
|
command: "research.lighthouse",
|
|
19340
21042
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -19353,7 +21055,7 @@ var FIELDS10 = {
|
|
|
19353
21055
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
19354
21056
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
19355
21057
|
};
|
|
19356
|
-
var lighthouseCommand =
|
|
21058
|
+
var lighthouseCommand = defineCommand133({
|
|
19357
21059
|
meta: {
|
|
19358
21060
|
name: "lighthouse",
|
|
19359
21061
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -19391,7 +21093,7 @@ Examples:
|
|
|
19391
21093
|
});
|
|
19392
21094
|
|
|
19393
21095
|
// src/commands/research/relevant-pages.ts
|
|
19394
|
-
import { defineCommand as
|
|
21096
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
19395
21097
|
registerSchema({
|
|
19396
21098
|
command: "research.relevant-pages",
|
|
19397
21099
|
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).",
|
|
@@ -19417,7 +21119,7 @@ var FIELDS11 = {
|
|
|
19417
21119
|
keywords: "Total organic keywords the page ranks for",
|
|
19418
21120
|
top_10: "Keywords in positions 1-10"
|
|
19419
21121
|
};
|
|
19420
|
-
var relevantPagesCommand =
|
|
21122
|
+
var relevantPagesCommand = defineCommand134({
|
|
19421
21123
|
meta: {
|
|
19422
21124
|
name: "relevant-pages",
|
|
19423
21125
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -19463,7 +21165,7 @@ Examples:
|
|
|
19463
21165
|
});
|
|
19464
21166
|
|
|
19465
21167
|
// src/commands/research/web.ts
|
|
19466
|
-
import { defineCommand as
|
|
21168
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
19467
21169
|
registerSchema({
|
|
19468
21170
|
command: "research.web",
|
|
19469
21171
|
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).",
|
|
@@ -19514,7 +21216,7 @@ async function runDeepResearch(question) {
|
|
|
19514
21216
|
}
|
|
19515
21217
|
throw new Error("Deep research timed out");
|
|
19516
21218
|
}
|
|
19517
|
-
var webCommand =
|
|
21219
|
+
var webCommand = defineCommand135({
|
|
19518
21220
|
meta: {
|
|
19519
21221
|
name: "web",
|
|
19520
21222
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -19574,7 +21276,7 @@ Examples:
|
|
|
19574
21276
|
});
|
|
19575
21277
|
|
|
19576
21278
|
// src/commands/research/index.ts
|
|
19577
|
-
var researchCommand =
|
|
21279
|
+
var researchCommand = defineCommand136({
|
|
19578
21280
|
meta: {
|
|
19579
21281
|
name: "research",
|
|
19580
21282
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -19614,10 +21316,10 @@ Examples:
|
|
|
19614
21316
|
});
|
|
19615
21317
|
|
|
19616
21318
|
// src/commands/scheduled-actions/index.ts
|
|
19617
|
-
import { defineCommand as
|
|
21319
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
19618
21320
|
|
|
19619
21321
|
// src/commands/scheduled-actions/create.ts
|
|
19620
|
-
import { defineCommand as
|
|
21322
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
19621
21323
|
|
|
19622
21324
|
// src/commands/scheduled-actions/shared.ts
|
|
19623
21325
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -19732,7 +21434,7 @@ registerSchema({
|
|
|
19732
21434
|
prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
|
|
19733
21435
|
}
|
|
19734
21436
|
});
|
|
19735
|
-
var createCommand2 =
|
|
21437
|
+
var createCommand2 = defineCommand137({
|
|
19736
21438
|
meta: {
|
|
19737
21439
|
name: "create",
|
|
19738
21440
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -19781,7 +21483,7 @@ var createCommand2 = defineCommand135({
|
|
|
19781
21483
|
});
|
|
19782
21484
|
|
|
19783
21485
|
// src/commands/scheduled-actions/delete.ts
|
|
19784
|
-
import { defineCommand as
|
|
21486
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
19785
21487
|
registerSchema({
|
|
19786
21488
|
command: "scheduled-actions.delete",
|
|
19787
21489
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -19789,7 +21491,7 @@ registerSchema({
|
|
|
19789
21491
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
19790
21492
|
}
|
|
19791
21493
|
});
|
|
19792
|
-
var deleteCommand2 =
|
|
21494
|
+
var deleteCommand2 = defineCommand138({
|
|
19793
21495
|
meta: {
|
|
19794
21496
|
name: "delete",
|
|
19795
21497
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -19818,7 +21520,7 @@ var deleteCommand2 = defineCommand136({
|
|
|
19818
21520
|
});
|
|
19819
21521
|
|
|
19820
21522
|
// src/commands/scheduled-actions/get.ts
|
|
19821
|
-
import { defineCommand as
|
|
21523
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
19822
21524
|
registerSchema({
|
|
19823
21525
|
command: "scheduled-actions.get",
|
|
19824
21526
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -19826,7 +21528,7 @@ registerSchema({
|
|
|
19826
21528
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
19827
21529
|
}
|
|
19828
21530
|
});
|
|
19829
|
-
var getCommand3 =
|
|
21531
|
+
var getCommand3 = defineCommand139({
|
|
19830
21532
|
meta: {
|
|
19831
21533
|
name: "get",
|
|
19832
21534
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -19863,13 +21565,13 @@ var getCommand3 = defineCommand137({
|
|
|
19863
21565
|
});
|
|
19864
21566
|
|
|
19865
21567
|
// src/commands/scheduled-actions/list.ts
|
|
19866
|
-
import { defineCommand as
|
|
21568
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
19867
21569
|
registerSchema({
|
|
19868
21570
|
command: "scheduled-actions.list",
|
|
19869
21571
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
|
|
19870
21572
|
args: {}
|
|
19871
21573
|
});
|
|
19872
|
-
var listCommand5 =
|
|
21574
|
+
var listCommand5 = defineCommand140({
|
|
19873
21575
|
meta: {
|
|
19874
21576
|
name: "list",
|
|
19875
21577
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
|
|
@@ -19890,7 +21592,7 @@ var listCommand5 = defineCommand138({
|
|
|
19890
21592
|
});
|
|
19891
21593
|
|
|
19892
21594
|
// src/commands/scheduled-actions/trigger.ts
|
|
19893
|
-
import { defineCommand as
|
|
21595
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
19894
21596
|
registerSchema({
|
|
19895
21597
|
command: "scheduled-actions.trigger",
|
|
19896
21598
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -19898,7 +21600,7 @@ registerSchema({
|
|
|
19898
21600
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
19899
21601
|
}
|
|
19900
21602
|
});
|
|
19901
|
-
var triggerCommand =
|
|
21603
|
+
var triggerCommand = defineCommand141({
|
|
19902
21604
|
meta: {
|
|
19903
21605
|
name: "trigger",
|
|
19904
21606
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -19935,7 +21637,7 @@ var triggerCommand = defineCommand139({
|
|
|
19935
21637
|
});
|
|
19936
21638
|
|
|
19937
21639
|
// src/commands/scheduled-actions/update.ts
|
|
19938
|
-
import { defineCommand as
|
|
21640
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
19939
21641
|
registerSchema({
|
|
19940
21642
|
command: "scheduled-actions.update",
|
|
19941
21643
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -19960,7 +21662,7 @@ registerSchema({
|
|
|
19960
21662
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
19961
21663
|
}
|
|
19962
21664
|
});
|
|
19963
|
-
var updateCommand2 =
|
|
21665
|
+
var updateCommand2 = defineCommand142({
|
|
19964
21666
|
meta: {
|
|
19965
21667
|
name: "update",
|
|
19966
21668
|
description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
|
|
@@ -20031,7 +21733,7 @@ var updateCommand2 = defineCommand140({
|
|
|
20031
21733
|
});
|
|
20032
21734
|
|
|
20033
21735
|
// src/commands/scheduled-actions/index.ts
|
|
20034
|
-
var scheduledActionsCommand =
|
|
21736
|
+
var scheduledActionsCommand = defineCommand143({
|
|
20035
21737
|
meta: {
|
|
20036
21738
|
name: "scheduled-actions",
|
|
20037
21739
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
|
|
@@ -20057,8 +21759,8 @@ Examples:
|
|
|
20057
21759
|
});
|
|
20058
21760
|
|
|
20059
21761
|
// src/commands/schema.ts
|
|
20060
|
-
import { defineCommand as
|
|
20061
|
-
var schemaCommand =
|
|
21762
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
21763
|
+
var schemaCommand = defineCommand144({
|
|
20062
21764
|
meta: {
|
|
20063
21765
|
name: "schema",
|
|
20064
21766
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -20094,10 +21796,10 @@ var schemaCommand = defineCommand142({
|
|
|
20094
21796
|
});
|
|
20095
21797
|
|
|
20096
21798
|
// src/commands/testimonials/index.ts
|
|
20097
|
-
import { defineCommand as
|
|
21799
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
20098
21800
|
|
|
20099
21801
|
// src/commands/testimonials/get.ts
|
|
20100
|
-
import { defineCommand as
|
|
21802
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
20101
21803
|
registerSchema({
|
|
20102
21804
|
command: "testimonials.get",
|
|
20103
21805
|
description: "Get a single testimonial by ID",
|
|
@@ -20105,7 +21807,7 @@ registerSchema({
|
|
|
20105
21807
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
20106
21808
|
}
|
|
20107
21809
|
});
|
|
20108
|
-
var getCommand4 =
|
|
21810
|
+
var getCommand4 = defineCommand145({
|
|
20109
21811
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
20110
21812
|
args: {
|
|
20111
21813
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -20142,7 +21844,7 @@ var getCommand4 = defineCommand143({
|
|
|
20142
21844
|
});
|
|
20143
21845
|
|
|
20144
21846
|
// src/commands/testimonials/list.ts
|
|
20145
|
-
import { defineCommand as
|
|
21847
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
20146
21848
|
registerSchema({
|
|
20147
21849
|
command: "testimonials.list",
|
|
20148
21850
|
description: "List testimonials with optional filters.",
|
|
@@ -20172,7 +21874,7 @@ registerSchema({
|
|
|
20172
21874
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
20173
21875
|
}
|
|
20174
21876
|
});
|
|
20175
|
-
var listCommand6 =
|
|
21877
|
+
var listCommand6 = defineCommand146({
|
|
20176
21878
|
meta: {
|
|
20177
21879
|
name: "list",
|
|
20178
21880
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -20221,7 +21923,7 @@ var listCommand6 = defineCommand144({
|
|
|
20221
21923
|
});
|
|
20222
21924
|
|
|
20223
21925
|
// src/commands/testimonials/search.ts
|
|
20224
|
-
import { defineCommand as
|
|
21926
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
20225
21927
|
registerSchema({
|
|
20226
21928
|
command: "testimonials.search",
|
|
20227
21929
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -20252,7 +21954,7 @@ registerSchema({
|
|
|
20252
21954
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
20253
21955
|
}
|
|
20254
21956
|
});
|
|
20255
|
-
var searchCommand2 =
|
|
21957
|
+
var searchCommand2 = defineCommand147({
|
|
20256
21958
|
meta: {
|
|
20257
21959
|
name: "search",
|
|
20258
21960
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -20326,7 +22028,7 @@ var searchCommand2 = defineCommand145({
|
|
|
20326
22028
|
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
20327
22029
|
|
|
20328
22030
|
// src/commands/testimonials/index.ts
|
|
20329
|
-
var testimonialsCommand =
|
|
22031
|
+
var testimonialsCommand = defineCommand148({
|
|
20330
22032
|
meta: {
|
|
20331
22033
|
name: "testimonials",
|
|
20332
22034
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -20347,10 +22049,10 @@ Examples:
|
|
|
20347
22049
|
});
|
|
20348
22050
|
|
|
20349
22051
|
// src/commands/videos/index.ts
|
|
20350
|
-
import { defineCommand as
|
|
22052
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
20351
22053
|
|
|
20352
22054
|
// src/commands/videos/delete.ts
|
|
20353
|
-
import { defineCommand as
|
|
22055
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
20354
22056
|
registerSchema({
|
|
20355
22057
|
command: "videos.delete",
|
|
20356
22058
|
description: "Delete a video by ID",
|
|
@@ -20364,7 +22066,7 @@ registerSchema({
|
|
|
20364
22066
|
}
|
|
20365
22067
|
}
|
|
20366
22068
|
});
|
|
20367
|
-
var deleteCommand3 =
|
|
22069
|
+
var deleteCommand3 = defineCommand149({
|
|
20368
22070
|
meta: {
|
|
20369
22071
|
name: "delete",
|
|
20370
22072
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -20405,7 +22107,7 @@ var deleteCommand3 = defineCommand147({
|
|
|
20405
22107
|
});
|
|
20406
22108
|
|
|
20407
22109
|
// src/commands/videos/get.ts
|
|
20408
|
-
import { defineCommand as
|
|
22110
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
20409
22111
|
registerSchema({
|
|
20410
22112
|
command: "videos.get",
|
|
20411
22113
|
description: "Get a single video by ID",
|
|
@@ -20413,7 +22115,7 @@ registerSchema({
|
|
|
20413
22115
|
id: { type: "string", description: "Video ID", required: true }
|
|
20414
22116
|
}
|
|
20415
22117
|
});
|
|
20416
|
-
var getCommand5 =
|
|
22118
|
+
var getCommand5 = defineCommand150({
|
|
20417
22119
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
20418
22120
|
args: {
|
|
20419
22121
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -20450,7 +22152,7 @@ var getCommand5 = defineCommand148({
|
|
|
20450
22152
|
});
|
|
20451
22153
|
|
|
20452
22154
|
// src/commands/videos/search.ts
|
|
20453
|
-
import { defineCommand as
|
|
22155
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
20454
22156
|
registerSchema({
|
|
20455
22157
|
command: "videos.search",
|
|
20456
22158
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -20460,7 +22162,7 @@ registerSchema({
|
|
|
20460
22162
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
20461
22163
|
}
|
|
20462
22164
|
});
|
|
20463
|
-
var searchCommand3 =
|
|
22165
|
+
var searchCommand3 = defineCommand151({
|
|
20464
22166
|
meta: {
|
|
20465
22167
|
name: "search",
|
|
20466
22168
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -20512,7 +22214,7 @@ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
20512
22214
|
// src/commands/videos/upload.ts
|
|
20513
22215
|
import { readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
20514
22216
|
import { extname as extname3 } from "path";
|
|
20515
|
-
import { defineCommand as
|
|
22217
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
20516
22218
|
var MIME_MAP = {
|
|
20517
22219
|
".mp4": "video/mp4",
|
|
20518
22220
|
".mov": "video/quicktime",
|
|
@@ -20546,7 +22248,7 @@ function detectContentType(filePath) {
|
|
|
20546
22248
|
}
|
|
20547
22249
|
return mime;
|
|
20548
22250
|
}
|
|
20549
|
-
var uploadCommand2 =
|
|
22251
|
+
var uploadCommand2 = defineCommand152({
|
|
20550
22252
|
meta: {
|
|
20551
22253
|
name: "upload",
|
|
20552
22254
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -20600,7 +22302,7 @@ var uploadCommand2 = defineCommand150({
|
|
|
20600
22302
|
});
|
|
20601
22303
|
|
|
20602
22304
|
// src/commands/videos/index.ts
|
|
20603
|
-
var videosCommand =
|
|
22305
|
+
var videosCommand = defineCommand153({
|
|
20604
22306
|
meta: {
|
|
20605
22307
|
name: "videos",
|
|
20606
22308
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -20623,10 +22325,10 @@ Examples:
|
|
|
20623
22325
|
});
|
|
20624
22326
|
|
|
20625
22327
|
// src/commands/winning-ads/index.ts
|
|
20626
|
-
import { defineCommand as
|
|
22328
|
+
import { defineCommand as defineCommand156 } from "citty";
|
|
20627
22329
|
|
|
20628
22330
|
// src/commands/winning-ads/advertisers.ts
|
|
20629
|
-
import { defineCommand as
|
|
22331
|
+
import { defineCommand as defineCommand154 } from "citty";
|
|
20630
22332
|
registerSchema({
|
|
20631
22333
|
command: "winning-ads.advertisers",
|
|
20632
22334
|
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).",
|
|
@@ -20639,7 +22341,7 @@ registerSchema({
|
|
|
20639
22341
|
function identity(record) {
|
|
20640
22342
|
return record;
|
|
20641
22343
|
}
|
|
20642
|
-
var advertisersCommand2 =
|
|
22344
|
+
var advertisersCommand2 = defineCommand154({
|
|
20643
22345
|
meta: {
|
|
20644
22346
|
name: "advertisers",
|
|
20645
22347
|
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'
|
|
@@ -20690,7 +22392,7 @@ var advertisersCommand2 = defineCommand152({
|
|
|
20690
22392
|
});
|
|
20691
22393
|
|
|
20692
22394
|
// src/commands/winning-ads/search.ts
|
|
20693
|
-
import { defineCommand as
|
|
22395
|
+
import { defineCommand as defineCommand155 } from "citty";
|
|
20694
22396
|
registerSchema({
|
|
20695
22397
|
command: "winning-ads.search",
|
|
20696
22398
|
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.",
|
|
@@ -20798,7 +22500,7 @@ function buildSearchBody(args) {
|
|
|
20798
22500
|
}
|
|
20799
22501
|
return body;
|
|
20800
22502
|
}
|
|
20801
|
-
var searchCommand4 =
|
|
22503
|
+
var searchCommand4 = defineCommand155({
|
|
20802
22504
|
meta: {
|
|
20803
22505
|
name: "search",
|
|
20804
22506
|
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"
|
|
@@ -20910,7 +22612,7 @@ var searchCommand4 = defineCommand153({
|
|
|
20910
22612
|
});
|
|
20911
22613
|
|
|
20912
22614
|
// src/commands/winning-ads/index.ts
|
|
20913
|
-
var winningAdsCommand =
|
|
22615
|
+
var winningAdsCommand = defineCommand156({
|
|
20914
22616
|
meta: {
|
|
20915
22617
|
name: "winning-ads",
|
|
20916
22618
|
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.
|
|
@@ -20934,7 +22636,7 @@ Examples:
|
|
|
20934
22636
|
});
|
|
20935
22637
|
|
|
20936
22638
|
// src/version.ts
|
|
20937
|
-
import { readFileSync as
|
|
22639
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
20938
22640
|
function packageJsonUrl() {
|
|
20939
22641
|
return new URL("../package.json", import.meta.url);
|
|
20940
22642
|
}
|
|
@@ -20946,11 +22648,11 @@ function parsePackageVersion(raw) {
|
|
|
20946
22648
|
throw new Error("Invalid CLI package.json: missing version");
|
|
20947
22649
|
}
|
|
20948
22650
|
function getCliVersion() {
|
|
20949
|
-
return parsePackageVersion(
|
|
22651
|
+
return parsePackageVersion(readFileSync11(packageJsonUrl(), "utf8"));
|
|
20950
22652
|
}
|
|
20951
22653
|
|
|
20952
22654
|
// src/cli.ts
|
|
20953
|
-
var main =
|
|
22655
|
+
var main = defineCommand157({
|
|
20954
22656
|
meta: {
|
|
20955
22657
|
name: "baker",
|
|
20956
22658
|
version: getCliVersion(),
|
|
@@ -20965,7 +22667,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
20965
22667
|
subCommands: {
|
|
20966
22668
|
actions: actionsCommand,
|
|
20967
22669
|
"scheduled-actions": scheduledActionsCommand,
|
|
20968
|
-
ads:
|
|
22670
|
+
ads: adsCommand2,
|
|
20969
22671
|
ga4: ga4Command,
|
|
20970
22672
|
gsc: gscCommand,
|
|
20971
22673
|
research: researchCommand,
|