@koda-sl/baker-cli 0.112.1 → 0.113.0-dev.78e242dda
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 +41 -0
- package/dist/{chunk-3JVYU72O.js → chunk-26K7V346.js} +4 -4
- package/dist/chunk-26K7V346.js.map +1 -0
- package/dist/cli.js +2039 -486
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3JVYU72O.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
defaultRegistry,
|
|
10
10
|
generateCatalog,
|
|
11
11
|
validateCanvasDeep
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-26K7V346.js";
|
|
13
13
|
|
|
14
14
|
// src/cli.ts
|
|
15
|
-
import { defineCommand as
|
|
15
|
+
import { defineCommand as defineCommand157, runMain } from "citty";
|
|
16
16
|
|
|
17
17
|
// src/commands/actions/index.ts
|
|
18
18
|
import { defineCommand as defineCommand18 } from "citty";
|
|
@@ -2844,10 +2844,10 @@ Examples:
|
|
|
2844
2844
|
});
|
|
2845
2845
|
|
|
2846
2846
|
// src/commands/ads/index.ts
|
|
2847
|
-
import { defineCommand as
|
|
2847
|
+
import { defineCommand as defineCommand82 } from "citty";
|
|
2848
2848
|
|
|
2849
2849
|
// src/commands/ads/google/index.ts
|
|
2850
|
-
import { defineCommand as
|
|
2850
|
+
import { defineCommand as defineCommand31 } from "citty";
|
|
2851
2851
|
|
|
2852
2852
|
// src/commands/ads/google/accounts.ts
|
|
2853
2853
|
import { defineCommand as defineCommand19 } from "citty";
|
|
@@ -3265,6 +3265,28 @@ function buildCommand(query, ctx) {
|
|
|
3265
3265
|
return `baker ads google query "${query}" --customer-id ${ctx.customerId}`;
|
|
3266
3266
|
}
|
|
3267
3267
|
var CORRECTION_RULES = [
|
|
3268
|
+
// 0. EXPECTED_REFERENCED_FIELD_IN_SELECT_CLAUSE — some resources (e.g. campaign_budget)
|
|
3269
|
+
// require fields filtered in WHERE to also be selected. The error names the exact field,
|
|
3270
|
+
// so add it to SELECT and retry. Kept first: field-specific rules below must not shadow
|
|
3271
|
+
// this with an unrelated rewrite when the named field happens to match their pattern.
|
|
3272
|
+
{
|
|
3273
|
+
matchApiError: /must be present in SELECT clause:\s*'([\w.]+)'/i,
|
|
3274
|
+
fix: (ctx) => {
|
|
3275
|
+
const field = ctx.apiErrorMessage?.match(/must be present in SELECT clause:\s*'([\w.]+)'/i)?.[1];
|
|
3276
|
+
if (!field) {
|
|
3277
|
+
return {
|
|
3278
|
+
action: "add_required_field",
|
|
3279
|
+
explanation: "Add the field named in the error to the SELECT clause and retry"
|
|
3280
|
+
};
|
|
3281
|
+
}
|
|
3282
|
+
const corrected = ctx.originalQuery.replace(/SELECT\s+/i, `SELECT ${field}, `);
|
|
3283
|
+
return {
|
|
3284
|
+
action: "add_required_field",
|
|
3285
|
+
correctedCommand: buildCommand(corrected, ctx),
|
|
3286
|
+
explanation: `${field} is used in WHERE but this resource requires it in SELECT too \u2014 added it`
|
|
3287
|
+
};
|
|
3288
|
+
}
|
|
3289
|
+
},
|
|
3268
3290
|
// 1. bare keyword.text → ad_group_criterion.keyword.text (leaves <resource>.keyword.text untouched)
|
|
3269
3291
|
{
|
|
3270
3292
|
matchQuery: /(?<![\w.])keyword\.text\b/,
|
|
@@ -3500,6 +3522,20 @@ var CORRECTION_RULES = [
|
|
|
3500
3522
|
};
|
|
3501
3523
|
}
|
|
3502
3524
|
},
|
|
3525
|
+
// 15b. asset.<type>_asset.final_urls → asset.final_urls (final URLs live on the asset
|
|
3526
|
+
// itself; the typed sub-message only carries type-specific fields like link_text)
|
|
3527
|
+
{
|
|
3528
|
+
matchQuery: /asset\.\w+_asset\.final_(mobile_)?urls\b/,
|
|
3529
|
+
matchApiError: /asset\.\w+_asset\.final_(mobile_)?urls/i,
|
|
3530
|
+
fix: (ctx) => {
|
|
3531
|
+
const corrected = ctx.originalQuery.replace(/asset\.\w+_asset\.final_(mobile_)?urls\b/g, "asset.final_$1urls");
|
|
3532
|
+
return {
|
|
3533
|
+
action: "retry_with_modified_query",
|
|
3534
|
+
correctedCommand: buildCommand(corrected, ctx),
|
|
3535
|
+
explanation: "Final URLs are on the asset itself \u2014 use asset.final_urls, not asset.<type>_asset.final_urls"
|
|
3536
|
+
};
|
|
3537
|
+
}
|
|
3538
|
+
},
|
|
3503
3539
|
// 16. Rate limit / quota
|
|
3504
3540
|
{
|
|
3505
3541
|
matchApiError: /RESOURCE_EXHAUSTED|quota.*exceeded|rate.*limit/i,
|
|
@@ -3627,6 +3663,7 @@ var CORRECTION_RULES = [
|
|
|
3627
3663
|
|
|
3628
3664
|
// src/commands/ads/google/error-parser.ts
|
|
3629
3665
|
function mapErrorCode(message) {
|
|
3666
|
+
if (/must be present in SELECT clause/i.test(message)) return "MISSING_SELECT_FIELD";
|
|
3630
3667
|
if (/field.*not.*found|unrecognized.*field|not.*valid.*field/i.test(message)) return "FIELD_NOT_FOUND";
|
|
3631
3668
|
if (/not.*valid.*resource|cannot.*select.*from/i.test(message)) return "WRONG_RESOURCE";
|
|
3632
3669
|
if (/operator|CONTAINS|LIKE/i.test(message)) return "INVALID_OPERATOR";
|
|
@@ -3832,11 +3869,972 @@ Examples:
|
|
|
3832
3869
|
}
|
|
3833
3870
|
});
|
|
3834
3871
|
|
|
3872
|
+
// src/commands/ads/google/draft.ts
|
|
3873
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
3874
|
+
|
|
3875
|
+
// src/commands/ads/google/write-shared.ts
|
|
3876
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
3877
|
+
|
|
3878
|
+
// ../api/src/ads-google/limits.ts
|
|
3879
|
+
var GOOGLE_ADS_LIMITS = {
|
|
3880
|
+
budget: {
|
|
3881
|
+
nameMax: 255,
|
|
3882
|
+
amountMicrosMin: 1
|
|
3883
|
+
},
|
|
3884
|
+
campaign: {
|
|
3885
|
+
nameMax: 255
|
|
3886
|
+
},
|
|
3887
|
+
adGroup: {
|
|
3888
|
+
nameMax: 255
|
|
3889
|
+
},
|
|
3890
|
+
keyword: {
|
|
3891
|
+
textMax: 80,
|
|
3892
|
+
wordsMax: 10
|
|
3893
|
+
},
|
|
3894
|
+
responsiveSearchAd: {
|
|
3895
|
+
headlinesMin: 3,
|
|
3896
|
+
headlinesMax: 15,
|
|
3897
|
+
headlineTextMax: 30,
|
|
3898
|
+
descriptionsMin: 2,
|
|
3899
|
+
descriptionsMax: 4,
|
|
3900
|
+
descriptionTextMax: 90,
|
|
3901
|
+
pathMax: 15
|
|
3902
|
+
},
|
|
3903
|
+
responsiveDisplayAd: {
|
|
3904
|
+
headlinesMin: 1,
|
|
3905
|
+
headlinesMax: 5,
|
|
3906
|
+
headlineTextMax: 30,
|
|
3907
|
+
longHeadlineTextMax: 90,
|
|
3908
|
+
descriptionsMin: 1,
|
|
3909
|
+
descriptionsMax: 5,
|
|
3910
|
+
descriptionTextMax: 90,
|
|
3911
|
+
businessNameMax: 25
|
|
3912
|
+
},
|
|
3913
|
+
sharedSet: {
|
|
3914
|
+
nameMax: 255
|
|
3915
|
+
},
|
|
3916
|
+
asset: {
|
|
3917
|
+
sitelinkLinkTextMax: 25,
|
|
3918
|
+
sitelinkDescriptionMax: 35,
|
|
3919
|
+
calloutTextMax: 25,
|
|
3920
|
+
structuredSnippetHeaderMax: 25,
|
|
3921
|
+
structuredSnippetValuesMin: 3,
|
|
3922
|
+
structuredSnippetValuesMax: 10
|
|
3923
|
+
},
|
|
3924
|
+
conversionAction: {
|
|
3925
|
+
nameMax: 255
|
|
3926
|
+
},
|
|
3927
|
+
audience: {
|
|
3928
|
+
nameMax: 255
|
|
3929
|
+
},
|
|
3930
|
+
biddingStrategy: {
|
|
3931
|
+
nameMax: 255
|
|
3932
|
+
},
|
|
3933
|
+
label: {
|
|
3934
|
+
nameMax: 255
|
|
3935
|
+
}
|
|
3936
|
+
};
|
|
3937
|
+
var KEYWORD_MATCH_TYPES = ["EXACT", "PHRASE", "BROAD"];
|
|
3938
|
+
var ADVERTISING_CHANNEL_TYPES = [
|
|
3939
|
+
"SEARCH",
|
|
3940
|
+
"DISPLAY",
|
|
3941
|
+
"SHOPPING",
|
|
3942
|
+
"VIDEO",
|
|
3943
|
+
"PERFORMANCE_MAX",
|
|
3944
|
+
"DEMAND_GEN",
|
|
3945
|
+
"MULTI_CHANNEL",
|
|
3946
|
+
"LOCAL",
|
|
3947
|
+
"SMART",
|
|
3948
|
+
"TRAVEL",
|
|
3949
|
+
"HOTEL",
|
|
3950
|
+
"DISCOVERY"
|
|
3951
|
+
];
|
|
3952
|
+
var ADVERTISING_CHANNEL_SUB_TYPES = [
|
|
3953
|
+
"SEARCH_MOBILE_APP",
|
|
3954
|
+
"DISPLAY_MOBILE_APP",
|
|
3955
|
+
"SEARCH_EXPRESS",
|
|
3956
|
+
"DISPLAY_EXPRESS",
|
|
3957
|
+
"SHOPPING_SMART_ADS",
|
|
3958
|
+
"DISPLAY_GMAIL_AD",
|
|
3959
|
+
"DISPLAY_SMART_CAMPAIGN",
|
|
3960
|
+
"VIDEO_OUTSTREAM",
|
|
3961
|
+
"VIDEO_ACTION",
|
|
3962
|
+
"VIDEO_NON_SKIPPABLE",
|
|
3963
|
+
"APP_CAMPAIGN",
|
|
3964
|
+
"APP_CAMPAIGN_FOR_ENGAGEMENT",
|
|
3965
|
+
"LOCAL_CAMPAIGN",
|
|
3966
|
+
"SHOPPING_COMPARISON_LISTING_ADS",
|
|
3967
|
+
"SEARCH_MOBILE_APP_ENGAGEMENT",
|
|
3968
|
+
"TRAVEL_ACTIVITIES"
|
|
3969
|
+
];
|
|
3970
|
+
var BIDDING_STRATEGY_TYPES = [
|
|
3971
|
+
"MANUAL_CPC",
|
|
3972
|
+
"MAXIMIZE_CONVERSIONS",
|
|
3973
|
+
"MAXIMIZE_CONVERSION_VALUE",
|
|
3974
|
+
"TARGET_SPEND",
|
|
3975
|
+
"TARGET_CPA",
|
|
3976
|
+
"TARGET_ROAS",
|
|
3977
|
+
"TARGET_IMPRESSION_SHARE",
|
|
3978
|
+
"MANUAL_CPM",
|
|
3979
|
+
"MANUAL_CPV",
|
|
3980
|
+
"PERCENT_CPC"
|
|
3981
|
+
];
|
|
3982
|
+
var BUDGET_DELIVERY_METHODS = ["STANDARD", "ACCELERATED"];
|
|
3983
|
+
var AD_GROUP_TYPES = [
|
|
3984
|
+
"SEARCH_STANDARD",
|
|
3985
|
+
"DISPLAY_STANDARD",
|
|
3986
|
+
"SHOPPING_PRODUCT_ADS",
|
|
3987
|
+
"VIDEO_BUMPER",
|
|
3988
|
+
"VIDEO_TRUE_VIEW_IN_STREAM",
|
|
3989
|
+
"VIDEO_TRUE_VIEW_IN_DISPLAY",
|
|
3990
|
+
"VIDEO_NON_SKIPPABLE_IN_STREAM",
|
|
3991
|
+
"VIDEO_OUTSTREAM",
|
|
3992
|
+
"DEMAND_GEN_AD"
|
|
3993
|
+
];
|
|
3994
|
+
var SHARED_SET_TYPES = [
|
|
3995
|
+
"NEGATIVE_KEYWORDS",
|
|
3996
|
+
"NEGATIVE_PLACEMENTS",
|
|
3997
|
+
"ACCOUNT_LEVEL_NEGATIVE_KEYWORDS"
|
|
3998
|
+
];
|
|
3999
|
+
var STAGEABLE_CREATE_STATUSES2 = ["ENABLED", "PAUSED"];
|
|
4000
|
+
var PINNED_FIELDS = ["HEADLINE_1", "HEADLINE_2", "HEADLINE_3", "DESCRIPTION_1", "DESCRIPTION_2"];
|
|
4001
|
+
var CONVERSION_ACTION_CATEGORIES = [
|
|
4002
|
+
"DEFAULT",
|
|
4003
|
+
"PAGE_VIEW",
|
|
4004
|
+
"PURCHASE",
|
|
4005
|
+
"SIGNUP",
|
|
4006
|
+
"LEAD",
|
|
4007
|
+
"DOWNLOAD",
|
|
4008
|
+
"ADD_TO_CART",
|
|
4009
|
+
"BEGIN_CHECKOUT",
|
|
4010
|
+
"SUBSCRIBE_PAID",
|
|
4011
|
+
"PHONE_CALL_LEAD",
|
|
4012
|
+
"SUBMIT_LEAD_FORM",
|
|
4013
|
+
"BOOK_APPOINTMENT",
|
|
4014
|
+
"REQUEST_QUOTE",
|
|
4015
|
+
"CONTACT"
|
|
4016
|
+
];
|
|
4017
|
+
var CONVERSION_ACTION_TYPES = [
|
|
4018
|
+
"WEBPAGE",
|
|
4019
|
+
"UPLOAD_CLICKS",
|
|
4020
|
+
"UPLOAD_CALLS",
|
|
4021
|
+
"WEBSITE_CALL",
|
|
4022
|
+
"GOOGLE_ANALYTICS_4_CUSTOM"
|
|
4023
|
+
];
|
|
4024
|
+
var CONVERSION_COUNTING_TYPES = ["ONE_PER_CLICK", "MANY_PER_CLICK"];
|
|
4025
|
+
var USER_LIST_TYPES = ["CRM_BASED", "RULE_BASED", "LOGICAL", "BASIC", "LOOKALIKE"];
|
|
4026
|
+
var ASSET_FIELD_TYPES = [
|
|
4027
|
+
"SITELINK",
|
|
4028
|
+
"CALLOUT",
|
|
4029
|
+
"STRUCTURED_SNIPPET",
|
|
4030
|
+
"CALL",
|
|
4031
|
+
"PRICE",
|
|
4032
|
+
"PROMOTION",
|
|
4033
|
+
"MOBILE_APP",
|
|
4034
|
+
"HEADLINE",
|
|
4035
|
+
"DESCRIPTION",
|
|
4036
|
+
"LOGO",
|
|
4037
|
+
"MARKETING_IMAGE",
|
|
4038
|
+
"BUSINESS_NAME"
|
|
4039
|
+
];
|
|
4040
|
+
var DEVICE_TYPES = ["MOBILE", "TABLET", "DESKTOP", "CONNECTED_TV", "OTHER"];
|
|
4041
|
+
var DAYS_OF_WEEK = ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"];
|
|
4042
|
+
var CAMPAIGN_OBJECTIVES = [
|
|
4043
|
+
"SALES",
|
|
4044
|
+
"LEADS",
|
|
4045
|
+
"WEBSITE_TRAFFIC",
|
|
4046
|
+
"PRODUCT_BRAND_CONSIDERATION",
|
|
4047
|
+
"BRAND_AWARENESS_REACH",
|
|
4048
|
+
"APP_PROMOTION",
|
|
4049
|
+
"LOCAL_STORE_VISITS"
|
|
4050
|
+
];
|
|
4051
|
+
var MICROS_PER_UNIT = 1e6;
|
|
4052
|
+
function toMicros(amount) {
|
|
4053
|
+
return Math.round(amount * MICROS_PER_UNIT);
|
|
4054
|
+
}
|
|
4055
|
+
var PLAYBOOK_DAILY_BUDGET_FLOOR_MICROS = 10 * MICROS_PER_UNIT;
|
|
4056
|
+
var TEMP_REF_REGEX2 = /^g_temp_[A-Za-z0-9_-]{2,}$/;
|
|
4057
|
+
var NUMERIC_ID_REGEX2 = /^\d+$/;
|
|
4058
|
+
var RESOURCE_NAME_REGEX = /^customers\/\d+\/[A-Za-z]+\/[-\w~]+$/;
|
|
4059
|
+
var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
|
|
4060
|
+
var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
|
|
4061
|
+
|
|
4062
|
+
// ../api/src/ads-google/ops.ts
|
|
4063
|
+
import { z as z8 } from "zod";
|
|
4064
|
+
var tempRefSchema2 = z8.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
|
|
4065
|
+
var refSchema = z8.union([
|
|
4066
|
+
z8.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
|
|
4067
|
+
z8.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
|
|
4068
|
+
tempRefSchema2
|
|
4069
|
+
]);
|
|
4070
|
+
var targetRefSchema = refSchema;
|
|
4071
|
+
var microsSchema = z8.number().int().positive("expected a positive micros amount");
|
|
4072
|
+
var httpsUrlSchema2 = z8.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
|
|
4073
|
+
var customerIdSchema = z8.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
|
|
4074
|
+
var stageableStatusSchema2 = z8.enum(STAGEABLE_CREATE_STATUSES2);
|
|
4075
|
+
var matchTypeSchema = z8.enum(KEYWORD_MATCH_TYPES);
|
|
4076
|
+
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");
|
|
4077
|
+
var budgetCreateSchema = z8.object({
|
|
4078
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
|
|
4079
|
+
amountMicros: microsSchema,
|
|
4080
|
+
deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
|
|
4081
|
+
explicitlyShared: z8.boolean().default(false)
|
|
4082
|
+
});
|
|
4083
|
+
var budgetUpdateSchema = z8.object({
|
|
4084
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
|
|
4085
|
+
amountMicros: microsSchema.optional(),
|
|
4086
|
+
deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).optional()
|
|
4087
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4088
|
+
var biddingConfigSchema = z8.object({
|
|
4089
|
+
type: z8.enum(BIDDING_STRATEGY_TYPES),
|
|
4090
|
+
targetCpaMicros: microsSchema.optional(),
|
|
4091
|
+
targetRoas: z8.number().positive().optional(),
|
|
4092
|
+
cpcBidCeilingMicros: microsSchema.optional(),
|
|
4093
|
+
enhancedCpcEnabled: z8.boolean().optional()
|
|
4094
|
+
}).superRefine((p, ctx) => {
|
|
4095
|
+
if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
|
|
4096
|
+
ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
|
|
4097
|
+
}
|
|
4098
|
+
if (p.type === "TARGET_ROAS" && p.targetRoas === void 0) {
|
|
4099
|
+
ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
|
|
4100
|
+
}
|
|
4101
|
+
});
|
|
4102
|
+
var networkSettingsSchema = z8.object({
|
|
4103
|
+
targetGoogleSearch: z8.boolean().optional(),
|
|
4104
|
+
targetSearchNetwork: z8.boolean().optional(),
|
|
4105
|
+
targetContentNetwork: z8.boolean().optional(),
|
|
4106
|
+
targetPartnerSearchNetwork: z8.boolean().optional()
|
|
4107
|
+
});
|
|
4108
|
+
var dateSchema = z8.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
|
|
4109
|
+
var campaignCreateSchema2 = z8.object({
|
|
4110
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
|
|
4111
|
+
channelType: z8.enum(ADVERTISING_CHANNEL_TYPES),
|
|
4112
|
+
channelSubType: z8.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
|
|
4113
|
+
budget: refSchema,
|
|
4114
|
+
/** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
|
|
4115
|
+
bidding: biddingConfigSchema.optional(),
|
|
4116
|
+
biddingStrategy: refSchema.optional(),
|
|
4117
|
+
networkSettings: networkSettingsSchema.optional(),
|
|
4118
|
+
startDate: dateSchema.optional(),
|
|
4119
|
+
endDate: dateSchema.optional(),
|
|
4120
|
+
/** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
|
|
4121
|
+
objective: z8.enum(CAMPAIGN_OBJECTIVES).optional(),
|
|
4122
|
+
status: stageableStatusSchema2.default("PAUSED")
|
|
4123
|
+
}).superRefine((p, ctx) => {
|
|
4124
|
+
if (!p.bidding && !p.biddingStrategy) {
|
|
4125
|
+
ctx.addIssue({
|
|
4126
|
+
code: "custom",
|
|
4127
|
+
path: ["bidding"],
|
|
4128
|
+
message: "set an inline bidding strategy or reference a portfolio biddingStrategy"
|
|
4129
|
+
});
|
|
4130
|
+
}
|
|
4131
|
+
if (p.bidding && p.biddingStrategy) {
|
|
4132
|
+
ctx.addIssue({
|
|
4133
|
+
code: "custom",
|
|
4134
|
+
path: ["bidding"],
|
|
4135
|
+
message: "use inline bidding OR a portfolio biddingStrategy, not both"
|
|
4136
|
+
});
|
|
4137
|
+
}
|
|
4138
|
+
if (p.channelType === "PERFORMANCE_MAX" && p.bidding && p.bidding.type === "MANUAL_CPC") {
|
|
4139
|
+
ctx.addIssue({ code: "custom", path: ["bidding"], message: "Performance Max does not support Manual CPC" });
|
|
4140
|
+
}
|
|
4141
|
+
if (p.startDate && p.endDate && p.endDate <= p.startDate) {
|
|
4142
|
+
ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
|
|
4143
|
+
}
|
|
4144
|
+
});
|
|
4145
|
+
var campaignUpdateSchema2 = z8.object({
|
|
4146
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
|
|
4147
|
+
budget: refSchema.optional(),
|
|
4148
|
+
bidding: biddingConfigSchema.optional(),
|
|
4149
|
+
networkSettings: networkSettingsSchema.optional(),
|
|
4150
|
+
startDate: dateSchema.optional(),
|
|
4151
|
+
endDate: dateSchema.optional(),
|
|
4152
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4153
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4154
|
+
var adGroupCreateSchema = z8.object({
|
|
4155
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
|
|
4156
|
+
campaign: refSchema,
|
|
4157
|
+
type: z8.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
|
|
4158
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4159
|
+
status: stageableStatusSchema2.default("PAUSED")
|
|
4160
|
+
});
|
|
4161
|
+
var adGroupUpdateSchema = z8.object({
|
|
4162
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
|
|
4163
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4164
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4165
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4166
|
+
var keywordAddSchema = z8.object({
|
|
4167
|
+
adGroup: refSchema,
|
|
4168
|
+
text: keywordTextSchema,
|
|
4169
|
+
matchType: matchTypeSchema,
|
|
4170
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4171
|
+
finalUrls: z8.array(httpsUrlSchema2).optional(),
|
|
4172
|
+
status: stageableStatusSchema2.default("ENABLED")
|
|
4173
|
+
});
|
|
4174
|
+
var keywordUpdateSchema = z8.object({
|
|
4175
|
+
cpcBidMicros: microsSchema.optional(),
|
|
4176
|
+
finalUrls: z8.array(httpsUrlSchema2).optional(),
|
|
4177
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4178
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4179
|
+
var negativeKeywordAddSchema = z8.object({
|
|
4180
|
+
level: z8.enum(["adGroup", "campaign"]),
|
|
4181
|
+
parent: refSchema,
|
|
4182
|
+
text: keywordTextSchema,
|
|
4183
|
+
matchType: matchTypeSchema
|
|
4184
|
+
});
|
|
4185
|
+
var sharedSetCreateSchema = z8.object({
|
|
4186
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
|
|
4187
|
+
type: z8.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
|
|
4188
|
+
});
|
|
4189
|
+
var sharedSetMemberAddSchema = z8.object({
|
|
4190
|
+
sharedSet: refSchema,
|
|
4191
|
+
text: keywordTextSchema,
|
|
4192
|
+
matchType: matchTypeSchema
|
|
4193
|
+
});
|
|
4194
|
+
var campaignSharedSetAttachSchema = z8.object({
|
|
4195
|
+
campaign: refSchema,
|
|
4196
|
+
sharedSet: refSchema
|
|
4197
|
+
});
|
|
4198
|
+
var adTextAssetSchema = z8.object({
|
|
4199
|
+
text: z8.string().min(1),
|
|
4200
|
+
pinnedField: z8.enum(PINNED_FIELDS).optional()
|
|
4201
|
+
});
|
|
4202
|
+
var responsiveSearchAdSchema = z8.object({
|
|
4203
|
+
format: z8.literal("responsiveSearch"),
|
|
4204
|
+
headlines: z8.array(
|
|
4205
|
+
adTextAssetSchema.refine(
|
|
4206
|
+
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
|
|
4207
|
+
"headline exceeds 30 chars"
|
|
4208
|
+
)
|
|
4209
|
+
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
|
|
4210
|
+
descriptions: z8.array(
|
|
4211
|
+
adTextAssetSchema.refine(
|
|
4212
|
+
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
|
|
4213
|
+
"description exceeds 90 chars"
|
|
4214
|
+
)
|
|
4215
|
+
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
|
|
4216
|
+
path1: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
|
|
4217
|
+
path2: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
|
|
4218
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4219
|
+
});
|
|
4220
|
+
var responsiveDisplayAdSchema = z8.object({
|
|
4221
|
+
format: z8.literal("responsiveDisplay"),
|
|
4222
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
|
|
4223
|
+
longHeadline: z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
|
|
4224
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
|
|
4225
|
+
businessName: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
|
|
4226
|
+
marketingImageAssets: z8.array(refSchema).optional(),
|
|
4227
|
+
logoImageAssets: z8.array(refSchema).optional(),
|
|
4228
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4229
|
+
});
|
|
4230
|
+
var performanceMaxAssetGroupSchema = z8.object({
|
|
4231
|
+
format: z8.literal("performanceMaxAssetGroup"),
|
|
4232
|
+
name: z8.string().min(1).max(255),
|
|
4233
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(30) })).min(3).max(15),
|
|
4234
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(2).max(5),
|
|
4235
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1),
|
|
4236
|
+
imageAssets: z8.array(refSchema).optional(),
|
|
4237
|
+
logoAssets: z8.array(refSchema).optional()
|
|
4238
|
+
});
|
|
4239
|
+
var callAdSchema = z8.object({
|
|
4240
|
+
format: z8.literal("call"),
|
|
4241
|
+
countryCode: z8.string().length(2),
|
|
4242
|
+
phoneNumber: z8.string().min(3),
|
|
4243
|
+
headline1: z8.string().min(1).max(30),
|
|
4244
|
+
headline2: z8.string().min(1).max(30),
|
|
4245
|
+
description1: z8.string().min(1).max(90),
|
|
4246
|
+
description2: z8.string().min(1).max(90),
|
|
4247
|
+
businessName: z8.string().min(1).max(25),
|
|
4248
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4249
|
+
});
|
|
4250
|
+
var appAdSchema = z8.object({
|
|
4251
|
+
format: z8.literal("app"),
|
|
4252
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(30) })).min(1),
|
|
4253
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1)
|
|
4254
|
+
});
|
|
4255
|
+
var videoAdSchema = z8.object({
|
|
4256
|
+
format: z8.literal("video"),
|
|
4257
|
+
youtubeVideoId: z8.string().min(1),
|
|
4258
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4259
|
+
});
|
|
4260
|
+
var demandGenAdSchema = z8.object({
|
|
4261
|
+
format: z8.literal("demandGen"),
|
|
4262
|
+
headlines: z8.array(z8.object({ text: z8.string().min(1).max(40) })).min(1).max(5),
|
|
4263
|
+
descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1).max(5),
|
|
4264
|
+
businessName: z8.string().min(1).max(25),
|
|
4265
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1),
|
|
4266
|
+
imageAssets: z8.array(refSchema).optional()
|
|
4267
|
+
});
|
|
4268
|
+
var adContentSchema = z8.discriminatedUnion("format", [
|
|
4269
|
+
responsiveSearchAdSchema,
|
|
4270
|
+
responsiveDisplayAdSchema,
|
|
4271
|
+
performanceMaxAssetGroupSchema,
|
|
4272
|
+
callAdSchema,
|
|
4273
|
+
appAdSchema,
|
|
4274
|
+
videoAdSchema,
|
|
4275
|
+
demandGenAdSchema
|
|
4276
|
+
]);
|
|
4277
|
+
var adCreateSchema = z8.object({
|
|
4278
|
+
adGroup: refSchema,
|
|
4279
|
+
status: stageableStatusSchema2.default("PAUSED"),
|
|
4280
|
+
content: adContentSchema
|
|
4281
|
+
});
|
|
4282
|
+
var adUpdateSchema = z8.object({
|
|
4283
|
+
status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
|
|
4284
|
+
/** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
|
|
4285
|
+
content: z8.record(z8.string(), z8.unknown()).optional()
|
|
4286
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4287
|
+
var textAssetSchema = z8.object({ type: z8.literal("text"), text: z8.string().min(1) });
|
|
4288
|
+
var imageAssetSchema = z8.object({
|
|
4289
|
+
type: z8.literal("image"),
|
|
4290
|
+
imageId: z8.string().min(1),
|
|
4291
|
+
name: z8.string().optional()
|
|
4292
|
+
});
|
|
4293
|
+
var youtubeVideoAssetSchema = z8.object({
|
|
4294
|
+
type: z8.literal("youtubeVideo"),
|
|
4295
|
+
youtubeVideoId: z8.string().min(1),
|
|
4296
|
+
name: z8.string().optional()
|
|
4297
|
+
});
|
|
4298
|
+
var sitelinkAssetSchema = z8.object({
|
|
4299
|
+
type: z8.literal("sitelink"),
|
|
4300
|
+
linkText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
|
|
4301
|
+
description1: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4302
|
+
description2: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4303
|
+
finalUrls: z8.array(httpsUrlSchema2).min(1)
|
|
4304
|
+
});
|
|
4305
|
+
var calloutAssetSchema = z8.object({
|
|
4306
|
+
type: z8.literal("callout"),
|
|
4307
|
+
calloutText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
|
|
4308
|
+
});
|
|
4309
|
+
var structuredSnippetAssetSchema = z8.object({
|
|
4310
|
+
type: z8.literal("structuredSnippet"),
|
|
4311
|
+
header: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
|
|
4312
|
+
values: z8.array(z8.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
|
|
4313
|
+
});
|
|
4314
|
+
var callToActionAssetSchema = z8.object({ type: z8.literal("callToAction"), callToAction: z8.string().min(1) });
|
|
4315
|
+
var assetCreateSchema = z8.discriminatedUnion("type", [
|
|
4316
|
+
textAssetSchema,
|
|
4317
|
+
imageAssetSchema,
|
|
4318
|
+
youtubeVideoAssetSchema,
|
|
4319
|
+
sitelinkAssetSchema,
|
|
4320
|
+
calloutAssetSchema,
|
|
4321
|
+
structuredSnippetAssetSchema,
|
|
4322
|
+
callToActionAssetSchema
|
|
4323
|
+
]);
|
|
4324
|
+
var assetLinkAttachSchema = z8.object({
|
|
4325
|
+
level: z8.enum(["campaign", "adGroup", "customer"]),
|
|
4326
|
+
parent: refSchema.optional(),
|
|
4327
|
+
asset: refSchema,
|
|
4328
|
+
fieldType: z8.enum(ASSET_FIELD_TYPES)
|
|
4329
|
+
}).superRefine((value, ctx) => {
|
|
4330
|
+
if (value.level !== "customer" && !value.parent) {
|
|
4331
|
+
ctx.addIssue({
|
|
4332
|
+
code: z8.ZodIssueCode.custom,
|
|
4333
|
+
path: ["parent"],
|
|
4334
|
+
message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
|
|
4335
|
+
});
|
|
4336
|
+
}
|
|
4337
|
+
});
|
|
4338
|
+
var audienceCreateSchema2 = z8.object({
|
|
4339
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
|
|
4340
|
+
type: z8.enum(USER_LIST_TYPES).default("BASIC"),
|
|
4341
|
+
description: z8.string().optional(),
|
|
4342
|
+
/** Customer-match members (crm-based) — file-first for large lists. */
|
|
4343
|
+
members: z8.array(z8.record(z8.string(), z8.string())).optional(),
|
|
4344
|
+
sourceFileRef: z8.string().optional()
|
|
4345
|
+
});
|
|
4346
|
+
var audienceCriterionAttachSchema = z8.object({
|
|
4347
|
+
level: z8.enum(["campaign", "adGroup"]),
|
|
4348
|
+
parent: refSchema,
|
|
4349
|
+
userList: refSchema,
|
|
4350
|
+
negative: z8.boolean().default(false)
|
|
4351
|
+
});
|
|
4352
|
+
var conversionActionCreateSchema = z8.object({
|
|
4353
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
|
|
4354
|
+
type: z8.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
|
|
4355
|
+
category: z8.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
|
|
4356
|
+
countingType: z8.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
|
|
4357
|
+
defaultValueMicros: microsSchema.optional(),
|
|
4358
|
+
defaultCurrencyCode: z8.string().length(3).optional(),
|
|
4359
|
+
clickThroughLookbackWindowDays: z8.number().int().positive().optional(),
|
|
4360
|
+
viewThroughLookbackWindowDays: z8.number().int().positive().optional(),
|
|
4361
|
+
status: z8.enum(["ENABLED", "PAUSED"]).default("ENABLED")
|
|
4362
|
+
});
|
|
4363
|
+
var conversionActionUpdateSchema = z8.object({
|
|
4364
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
|
|
4365
|
+
category: z8.enum(CONVERSION_ACTION_CATEGORIES).optional(),
|
|
4366
|
+
countingType: z8.enum(CONVERSION_COUNTING_TYPES).optional(),
|
|
4367
|
+
defaultValueMicros: microsSchema.optional(),
|
|
4368
|
+
status: z8.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
|
|
4369
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4370
|
+
var biddingStrategyCreateSchema = z8.object({
|
|
4371
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
|
|
4372
|
+
config: biddingConfigSchema
|
|
4373
|
+
}).superRefine((p, ctx) => {
|
|
4374
|
+
if (p.config.type === "MANUAL_CPC") {
|
|
4375
|
+
ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
|
|
4376
|
+
}
|
|
4377
|
+
});
|
|
4378
|
+
var biddingStrategyUpdateSchema = z8.object({
|
|
4379
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
|
|
4380
|
+
config: biddingConfigSchema.optional()
|
|
4381
|
+
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4382
|
+
var labelCreateSchema = z8.object({
|
|
4383
|
+
name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
|
|
4384
|
+
backgroundColor: z8.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
|
|
4385
|
+
description: z8.string().optional()
|
|
4386
|
+
});
|
|
4387
|
+
var labelAttachSchema = z8.object({
|
|
4388
|
+
level: z8.enum(["campaign", "adGroup", "ad"]),
|
|
4389
|
+
parent: refSchema,
|
|
4390
|
+
label: refSchema
|
|
4391
|
+
});
|
|
4392
|
+
var locationCriterionSchema = z8.object({
|
|
4393
|
+
criterionType: z8.literal("location"),
|
|
4394
|
+
geoTargetConstant: z8.union([z8.string().regex(GEO_TARGET_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
|
|
4395
|
+
});
|
|
4396
|
+
var languageCriterionSchema = z8.object({
|
|
4397
|
+
criterionType: z8.literal("language"),
|
|
4398
|
+
languageConstant: z8.union([z8.string().regex(LANGUAGE_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
|
|
4399
|
+
});
|
|
4400
|
+
var adScheduleCriterionSchema = z8.object({
|
|
4401
|
+
criterionType: z8.literal("adSchedule"),
|
|
4402
|
+
dayOfWeek: z8.enum(DAYS_OF_WEEK),
|
|
4403
|
+
startHour: z8.number().int().min(0).max(23),
|
|
4404
|
+
startMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
|
|
4405
|
+
endHour: z8.number().int().min(0).max(24),
|
|
4406
|
+
endMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
|
|
4407
|
+
});
|
|
4408
|
+
var deviceCriterionSchema = z8.object({
|
|
4409
|
+
criterionType: z8.literal("device"),
|
|
4410
|
+
device: z8.enum(DEVICE_TYPES),
|
|
4411
|
+
bidModifier: z8.number().min(0.1).max(10).optional()
|
|
4412
|
+
});
|
|
4413
|
+
var campaignCriterionAddSchema = z8.object({
|
|
4414
|
+
campaign: refSchema,
|
|
4415
|
+
negative: z8.boolean().default(false),
|
|
4416
|
+
criterion: z8.discriminatedUnion("criterionType", [
|
|
4417
|
+
locationCriterionSchema,
|
|
4418
|
+
languageCriterionSchema,
|
|
4419
|
+
adScheduleCriterionSchema,
|
|
4420
|
+
deviceCriterionSchema
|
|
4421
|
+
])
|
|
4422
|
+
});
|
|
4423
|
+
var GOOGLE_DRAFT_OP_KINDS = [
|
|
4424
|
+
"google.budget.create",
|
|
4425
|
+
"google.budget.update",
|
|
4426
|
+
"google.campaign.create",
|
|
4427
|
+
"google.campaign.update",
|
|
4428
|
+
"google.campaign.pause",
|
|
4429
|
+
"google.campaign.resume",
|
|
4430
|
+
"google.campaign.remove",
|
|
4431
|
+
"google.adGroup.create",
|
|
4432
|
+
"google.adGroup.update",
|
|
4433
|
+
"google.adGroup.pause",
|
|
4434
|
+
"google.adGroup.resume",
|
|
4435
|
+
"google.adGroup.remove",
|
|
4436
|
+
"google.keyword.add",
|
|
4437
|
+
"google.keyword.update",
|
|
4438
|
+
"google.keyword.remove",
|
|
4439
|
+
"google.negativeKeyword.add",
|
|
4440
|
+
"google.negativeKeyword.remove",
|
|
4441
|
+
"google.sharedSet.create",
|
|
4442
|
+
"google.sharedSetMember.add",
|
|
4443
|
+
"google.sharedSetMember.remove",
|
|
4444
|
+
"google.campaignSharedSet.attach",
|
|
4445
|
+
"google.campaignSharedSet.detach",
|
|
4446
|
+
"google.ad.create",
|
|
4447
|
+
"google.ad.update",
|
|
4448
|
+
"google.ad.pause",
|
|
4449
|
+
"google.ad.resume",
|
|
4450
|
+
"google.ad.remove",
|
|
4451
|
+
"google.asset.create",
|
|
4452
|
+
"google.assetLink.attach",
|
|
4453
|
+
"google.assetLink.detach",
|
|
4454
|
+
"google.audience.create",
|
|
4455
|
+
"google.audienceCriterion.attach",
|
|
4456
|
+
"google.audienceCriterion.detach",
|
|
4457
|
+
"google.conversionAction.create",
|
|
4458
|
+
"google.conversionAction.update",
|
|
4459
|
+
"google.biddingStrategy.create",
|
|
4460
|
+
"google.biddingStrategy.update",
|
|
4461
|
+
"google.label.create",
|
|
4462
|
+
"google.label.attach",
|
|
4463
|
+
"google.campaignCriterion.add",
|
|
4464
|
+
"google.campaignCriterion.remove"
|
|
4465
|
+
];
|
|
4466
|
+
var googleDraftOpKindSchema = z8.enum(GOOGLE_DRAFT_OP_KINDS);
|
|
4467
|
+
function createOp2(kind, payload) {
|
|
4468
|
+
return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, payload });
|
|
4469
|
+
}
|
|
4470
|
+
function updateOp2(kind, payload) {
|
|
4471
|
+
return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
|
|
4472
|
+
}
|
|
4473
|
+
function targetOp(kind) {
|
|
4474
|
+
return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
|
|
4475
|
+
}
|
|
4476
|
+
var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
|
|
4477
|
+
createOp2("google.budget.create", budgetCreateSchema),
|
|
4478
|
+
updateOp2("google.budget.update", budgetUpdateSchema),
|
|
4479
|
+
createOp2("google.campaign.create", campaignCreateSchema2),
|
|
4480
|
+
updateOp2("google.campaign.update", campaignUpdateSchema2),
|
|
4481
|
+
targetOp("google.campaign.pause"),
|
|
4482
|
+
targetOp("google.campaign.resume"),
|
|
4483
|
+
targetOp("google.campaign.remove"),
|
|
4484
|
+
createOp2("google.adGroup.create", adGroupCreateSchema),
|
|
4485
|
+
updateOp2("google.adGroup.update", adGroupUpdateSchema),
|
|
4486
|
+
targetOp("google.adGroup.pause"),
|
|
4487
|
+
targetOp("google.adGroup.resume"),
|
|
4488
|
+
targetOp("google.adGroup.remove"),
|
|
4489
|
+
createOp2("google.keyword.add", keywordAddSchema),
|
|
4490
|
+
updateOp2("google.keyword.update", keywordUpdateSchema),
|
|
4491
|
+
targetOp("google.keyword.remove"),
|
|
4492
|
+
createOp2("google.negativeKeyword.add", negativeKeywordAddSchema),
|
|
4493
|
+
targetOp("google.negativeKeyword.remove"),
|
|
4494
|
+
createOp2("google.sharedSet.create", sharedSetCreateSchema),
|
|
4495
|
+
createOp2("google.sharedSetMember.add", sharedSetMemberAddSchema),
|
|
4496
|
+
targetOp("google.sharedSetMember.remove"),
|
|
4497
|
+
createOp2("google.campaignSharedSet.attach", campaignSharedSetAttachSchema),
|
|
4498
|
+
targetOp("google.campaignSharedSet.detach"),
|
|
4499
|
+
createOp2("google.ad.create", adCreateSchema),
|
|
4500
|
+
updateOp2("google.ad.update", adUpdateSchema),
|
|
4501
|
+
targetOp("google.ad.pause"),
|
|
4502
|
+
targetOp("google.ad.resume"),
|
|
4503
|
+
targetOp("google.ad.remove"),
|
|
4504
|
+
createOp2("google.asset.create", assetCreateSchema),
|
|
4505
|
+
createOp2("google.assetLink.attach", assetLinkAttachSchema),
|
|
4506
|
+
targetOp("google.assetLink.detach"),
|
|
4507
|
+
createOp2("google.audience.create", audienceCreateSchema2),
|
|
4508
|
+
createOp2("google.audienceCriterion.attach", audienceCriterionAttachSchema),
|
|
4509
|
+
targetOp("google.audienceCriterion.detach"),
|
|
4510
|
+
createOp2("google.conversionAction.create", conversionActionCreateSchema),
|
|
4511
|
+
updateOp2("google.conversionAction.update", conversionActionUpdateSchema),
|
|
4512
|
+
createOp2("google.biddingStrategy.create", biddingStrategyCreateSchema),
|
|
4513
|
+
updateOp2("google.biddingStrategy.update", biddingStrategyUpdateSchema),
|
|
4514
|
+
createOp2("google.label.create", labelCreateSchema),
|
|
4515
|
+
createOp2("google.label.attach", labelAttachSchema),
|
|
4516
|
+
createOp2("google.campaignCriterion.add", campaignCriterionAddSchema),
|
|
4517
|
+
targetOp("google.campaignCriterion.remove")
|
|
4518
|
+
]);
|
|
4519
|
+
|
|
4520
|
+
// ../api/src/ads-google/wire.ts
|
|
4521
|
+
import { z as z9 } from "zod";
|
|
4522
|
+
var googleWriteModeSchema = z9.enum(["live", "simulated"]);
|
|
4523
|
+
var googleDraftOpResultSchema = z9.object({
|
|
4524
|
+
status: z9.enum(["applied", "simulated", "failed", "skipped"]),
|
|
4525
|
+
resourceName: z9.string().optional(),
|
|
4526
|
+
error: z9.string().optional(),
|
|
4527
|
+
skippedBecause: z9.string().optional(),
|
|
4528
|
+
executedAt: z9.number().optional()
|
|
4529
|
+
});
|
|
4530
|
+
var googleDraftStageRequestSchema = z9.object({
|
|
4531
|
+
chatId: z9.string(),
|
|
4532
|
+
op: googleDraftOpInputSchema
|
|
4533
|
+
});
|
|
4534
|
+
var googleDraftStageResponseSchema = z9.object({
|
|
4535
|
+
staged: z9.literal(true),
|
|
4536
|
+
ref: z9.string(),
|
|
4537
|
+
kind: googleDraftOpKindSchema,
|
|
4538
|
+
mode: googleWriteModeSchema,
|
|
4539
|
+
dependsOn: z9.array(z9.string()),
|
|
4540
|
+
summary: z9.string(),
|
|
4541
|
+
warnings: z9.array(z9.string()),
|
|
4542
|
+
/** True when the op amended an already-staged op in place instead of appending a new one. */
|
|
4543
|
+
amended: z9.boolean().optional()
|
|
4544
|
+
});
|
|
4545
|
+
var GOOGLE_DRAFT_BATCH_MAX = 500;
|
|
4546
|
+
var googleDraftStageBatchRequestSchema = z9.object({
|
|
4547
|
+
chatId: z9.string(),
|
|
4548
|
+
ops: z9.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
|
|
4549
|
+
});
|
|
4550
|
+
var googleDraftStageBatchResponseSchema = z9.object({
|
|
4551
|
+
staged: z9.literal(true),
|
|
4552
|
+
mode: googleWriteModeSchema,
|
|
4553
|
+
count: z9.number(),
|
|
4554
|
+
ops: z9.array(
|
|
4555
|
+
z9.object({
|
|
4556
|
+
ref: z9.string(),
|
|
4557
|
+
kind: googleDraftOpKindSchema,
|
|
4558
|
+
dependsOn: z9.array(z9.string()),
|
|
4559
|
+
summary: z9.string(),
|
|
4560
|
+
warnings: z9.array(z9.string())
|
|
4561
|
+
})
|
|
4562
|
+
)
|
|
4563
|
+
});
|
|
4564
|
+
var googleDraftOpViewSchema = z9.object({
|
|
4565
|
+
ref: z9.string(),
|
|
4566
|
+
kind: googleDraftOpKindSchema,
|
|
4567
|
+
customerId: z9.string(),
|
|
4568
|
+
target: z9.string().optional(),
|
|
4569
|
+
dependsOn: z9.array(z9.string()),
|
|
4570
|
+
summary: z9.string(),
|
|
4571
|
+
stagedAt: z9.number(),
|
|
4572
|
+
result: googleDraftOpResultSchema.optional()
|
|
4573
|
+
});
|
|
4574
|
+
var googleDraftListRequestSchema = z9.object({
|
|
4575
|
+
chatId: z9.string()
|
|
4576
|
+
});
|
|
4577
|
+
var googleDraftListResponseSchema = z9.object({
|
|
4578
|
+
status: z9.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
4579
|
+
mode: googleWriteModeSchema,
|
|
4580
|
+
count: z9.number(),
|
|
4581
|
+
ops: z9.array(googleDraftOpViewSchema)
|
|
4582
|
+
});
|
|
4583
|
+
var googleDraftRemoveRequestSchema = z9.object({
|
|
4584
|
+
chatId: z9.string(),
|
|
4585
|
+
ref: z9.string()
|
|
4586
|
+
});
|
|
4587
|
+
var googleDraftRemoveResponseSchema = z9.object({
|
|
4588
|
+
/** The requested ref plus any dependents removed by cascade. */
|
|
4589
|
+
removed: z9.array(z9.string())
|
|
4590
|
+
});
|
|
4591
|
+
var googleDraftClearRequestSchema = z9.object({
|
|
4592
|
+
chatId: z9.string()
|
|
4593
|
+
});
|
|
4594
|
+
var googleDraftClearResponseSchema = z9.object({
|
|
4595
|
+
cleared: z9.number()
|
|
4596
|
+
});
|
|
4597
|
+
var googleFieldErrorSchema = z9.object({
|
|
4598
|
+
path: z9.string(),
|
|
4599
|
+
message: z9.string()
|
|
4600
|
+
});
|
|
4601
|
+
var googleDraftErrorResponseSchema = z9.object({
|
|
4602
|
+
code: z9.string(),
|
|
4603
|
+
error: z9.string(),
|
|
4604
|
+
fields: z9.array(googleFieldErrorSchema).optional()
|
|
4605
|
+
});
|
|
4606
|
+
|
|
4607
|
+
// src/commands/ads/google/write-shared.ts
|
|
4608
|
+
function failWriteValidation(message) {
|
|
4609
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
4610
|
+
process.exit(1);
|
|
4611
|
+
}
|
|
4612
|
+
function requireCustomerId(args) {
|
|
4613
|
+
const raw = args["customer-id"] ?? args.customerId;
|
|
4614
|
+
if (!raw || !/^\d{10}$/.test(raw)) {
|
|
4615
|
+
failWriteValidation("pass --customer-id as the 10-digit Google Ads customer id (no dashes)");
|
|
4616
|
+
}
|
|
4617
|
+
return raw;
|
|
4618
|
+
}
|
|
4619
|
+
function requireTarget(args, entity) {
|
|
4620
|
+
const positional = Array.isArray(args._) ? args._[0] : void 0;
|
|
4621
|
+
const target = args.id ?? args.target ?? positional;
|
|
4622
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
4623
|
+
failWriteValidation(`pass the ${entity} resource name or id as the positional argument`);
|
|
4624
|
+
}
|
|
4625
|
+
return target;
|
|
4626
|
+
}
|
|
4627
|
+
function requireStringFlag(value, flag) {
|
|
4628
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
4629
|
+
failWriteValidation(`${flag} is required`);
|
|
4630
|
+
}
|
|
4631
|
+
return value;
|
|
4632
|
+
}
|
|
4633
|
+
function microsFlag(value, flag) {
|
|
4634
|
+
if (value === void 0 || value === null || value === "") {
|
|
4635
|
+
return void 0;
|
|
4636
|
+
}
|
|
4637
|
+
const num = Number(value);
|
|
4638
|
+
if (Number.isNaN(num) || num <= 0) {
|
|
4639
|
+
failWriteValidation(`${flag} must be a positive amount (major currency units, e.g. 50 or 50.00)`);
|
|
4640
|
+
}
|
|
4641
|
+
return toMicros(num);
|
|
4642
|
+
}
|
|
4643
|
+
function listFlag(value) {
|
|
4644
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
4645
|
+
return void 0;
|
|
4646
|
+
}
|
|
4647
|
+
const items = value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
4648
|
+
return items.length > 0 ? items : void 0;
|
|
4649
|
+
}
|
|
4650
|
+
var MATCH_TYPES = /* @__PURE__ */ new Set(["EXACT", "PHRASE", "BROAD"]);
|
|
4651
|
+
function parseKeywordEntry(raw, defaultMatch) {
|
|
4652
|
+
const colon = raw.lastIndexOf(":");
|
|
4653
|
+
if (colon > 0) {
|
|
4654
|
+
const suffix = raw.slice(colon + 1).trim().toUpperCase();
|
|
4655
|
+
if (MATCH_TYPES.has(suffix)) {
|
|
4656
|
+
return { text: raw.slice(0, colon).trim(), matchType: suffix };
|
|
4657
|
+
}
|
|
4658
|
+
failWriteValidation(`"${raw}": ":${raw.slice(colon + 1)}" is not a match type (EXACT | PHRASE | BROAD)`);
|
|
4659
|
+
}
|
|
4660
|
+
if (!defaultMatch) {
|
|
4661
|
+
failWriteValidation(`"${raw}" has no match type \u2014 add a :EXACT/:PHRASE/:BROAD suffix or pass --match-type`);
|
|
4662
|
+
}
|
|
4663
|
+
return { text: raw, matchType: defaultMatch };
|
|
4664
|
+
}
|
|
4665
|
+
function rawTextEntries(value) {
|
|
4666
|
+
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
4667
|
+
return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
4668
|
+
}
|
|
4669
|
+
function rawFileEntries(path12) {
|
|
4670
|
+
if (typeof path12 !== "string" || path12.length === 0) {
|
|
4671
|
+
return [];
|
|
4672
|
+
}
|
|
4673
|
+
return readFileSync3(path12, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
4674
|
+
}
|
|
4675
|
+
function keywordEntries(args) {
|
|
4676
|
+
const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
|
|
4677
|
+
const raw = [...rawTextEntries(args.text), ...rawFileEntries(args.file)];
|
|
4678
|
+
if (raw.length === 0) {
|
|
4679
|
+
failWriteValidation("pass keywords via --text (comma-separated) and/or --file (one per line)");
|
|
4680
|
+
}
|
|
4681
|
+
if (raw.length > GOOGLE_DRAFT_BATCH_MAX) {
|
|
4682
|
+
failWriteValidation(`${raw.length} keywords exceeds the batch limit of ${GOOGLE_DRAFT_BATCH_MAX}`);
|
|
4683
|
+
}
|
|
4684
|
+
const entries = [];
|
|
4685
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4686
|
+
for (const item of raw) {
|
|
4687
|
+
const entry = parseKeywordEntry(item, defaultMatch);
|
|
4688
|
+
const key = `${entry.text}\0${entry.matchType}`;
|
|
4689
|
+
if (!seen.has(key)) {
|
|
4690
|
+
seen.add(key);
|
|
4691
|
+
entries.push(entry);
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
return entries;
|
|
4695
|
+
}
|
|
4696
|
+
function loadJsonFileArg(path12) {
|
|
4697
|
+
if (typeof path12 !== "string" || path12.length === 0) {
|
|
4698
|
+
return {};
|
|
4699
|
+
}
|
|
4700
|
+
try {
|
|
4701
|
+
const parsed = JSON.parse(readFileSync3(path12, "utf8"));
|
|
4702
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4703
|
+
failWriteValidation(`${path12} must contain a JSON object`);
|
|
4704
|
+
}
|
|
4705
|
+
return parsed;
|
|
4706
|
+
} catch (err) {
|
|
4707
|
+
if (err instanceof SyntaxError) {
|
|
4708
|
+
failWriteValidation(`${path12} is not valid JSON: ${err.message}`);
|
|
4709
|
+
}
|
|
4710
|
+
throw err;
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
function mergePayload(file, flags) {
|
|
4714
|
+
const merged = { ...file };
|
|
4715
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
4716
|
+
if (value !== void 0) {
|
|
4717
|
+
merged[key] = value;
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
return merged;
|
|
4721
|
+
}
|
|
4722
|
+
function handleGoogleError(err) {
|
|
4723
|
+
if (err instanceof ApiError) {
|
|
4724
|
+
writeJsonEnvelope({ ok: false, error: { code: err.code ?? "API_ERROR", message: err.message } });
|
|
4725
|
+
process.exit(1);
|
|
4726
|
+
}
|
|
4727
|
+
writeJsonEnvelope({
|
|
4728
|
+
ok: false,
|
|
4729
|
+
error: { code: "UNKNOWN", message: err instanceof Error ? err.message : String(err) }
|
|
4730
|
+
});
|
|
4731
|
+
process.exit(1);
|
|
4732
|
+
}
|
|
4733
|
+
async function stageGoogleOp(raw) {
|
|
4734
|
+
const preflight = googleDraftOpInputSchema.safeParse(raw);
|
|
4735
|
+
if (!preflight.success) {
|
|
4736
|
+
const fields = preflight.error.issues.map((issue) => ({ path: issue.path.join("."), message: issue.message }));
|
|
4737
|
+
writeJsonEnvelope({
|
|
4738
|
+
ok: false,
|
|
4739
|
+
error: {
|
|
4740
|
+
code: "VALIDATION_ERROR",
|
|
4741
|
+
message: fields.map((f) => f.path ? `${f.path}: ${f.message}` : f.message).join("; "),
|
|
4742
|
+
fields
|
|
4743
|
+
}
|
|
4744
|
+
});
|
|
4745
|
+
process.exit(1);
|
|
4746
|
+
}
|
|
4747
|
+
try {
|
|
4748
|
+
const chatId = requireChatId();
|
|
4749
|
+
const response = await apiPost("/api/ads/google/draft/stage", { chatId, op: preflight.data });
|
|
4750
|
+
writeJsonEnvelope(response);
|
|
4751
|
+
} catch (err) {
|
|
4752
|
+
handleGoogleError(err);
|
|
4753
|
+
}
|
|
4754
|
+
}
|
|
4755
|
+
async function stageCreate(kind, customerId, payload) {
|
|
4756
|
+
await stageGoogleOp({ kind, customerId, payload });
|
|
4757
|
+
}
|
|
4758
|
+
async function stageGoogleOps(rawOps) {
|
|
4759
|
+
if (rawOps.length === 1 && rawOps[0]) {
|
|
4760
|
+
await stageGoogleOp(rawOps[0]);
|
|
4761
|
+
return;
|
|
4762
|
+
}
|
|
4763
|
+
const ops = [];
|
|
4764
|
+
for (const [index, raw] of rawOps.entries()) {
|
|
4765
|
+
const preflight = googleDraftOpInputSchema.safeParse(raw);
|
|
4766
|
+
if (!preflight.success) {
|
|
4767
|
+
const fields = preflight.error.issues.map((issue) => ({
|
|
4768
|
+
path: `ops[${index}].${issue.path.join(".")}`,
|
|
4769
|
+
message: issue.message
|
|
4770
|
+
}));
|
|
4771
|
+
writeJsonEnvelope({
|
|
4772
|
+
ok: false,
|
|
4773
|
+
error: {
|
|
4774
|
+
code: "VALIDATION_ERROR",
|
|
4775
|
+
message: fields.map((f) => `${f.path}: ${f.message}`).join("; "),
|
|
4776
|
+
fields
|
|
4777
|
+
}
|
|
4778
|
+
});
|
|
4779
|
+
process.exit(1);
|
|
4780
|
+
}
|
|
4781
|
+
ops.push(preflight.data);
|
|
4782
|
+
}
|
|
4783
|
+
try {
|
|
4784
|
+
const chatId = requireChatId();
|
|
4785
|
+
const response = await apiPost("/api/ads/google/draft/stage-batch", { chatId, ops });
|
|
4786
|
+
writeJsonEnvelope(response);
|
|
4787
|
+
} catch (err) {
|
|
4788
|
+
handleGoogleError(err);
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
async function stageUpdate(kind, customerId, target, payload) {
|
|
4792
|
+
await stageGoogleOp({ kind, customerId, target, payload });
|
|
4793
|
+
}
|
|
4794
|
+
async function stageTarget(kind, customerId, target) {
|
|
4795
|
+
await stageGoogleOp({ kind, customerId, target });
|
|
4796
|
+
}
|
|
4797
|
+
async function draftAction(path12, body) {
|
|
4798
|
+
try {
|
|
4799
|
+
const chatId = requireChatId();
|
|
4800
|
+
const response = await apiPost(path12, { chatId, ...body });
|
|
4801
|
+
writeJsonEnvelope(response);
|
|
4802
|
+
} catch (err) {
|
|
4803
|
+
handleGoogleError(err);
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
|
|
4807
|
+
// src/commands/ads/google/draft.ts
|
|
4808
|
+
var draftCommand2 = defineCommand22({
|
|
4809
|
+
meta: { name: "draft", description: "List, remove, or clear staged Google Ads write ops for this chat" },
|
|
4810
|
+
subCommands: {
|
|
4811
|
+
list: defineCommand22({
|
|
4812
|
+
meta: { name: "list", description: "List staged ops (with lineage, mode, and results)" },
|
|
4813
|
+
run: async () => {
|
|
4814
|
+
await draftAction("/api/ads/google/draft", {});
|
|
4815
|
+
}
|
|
4816
|
+
}),
|
|
4817
|
+
remove: defineCommand22({
|
|
4818
|
+
meta: { name: "remove", description: "Remove one staged op (cascades to dependents)" },
|
|
4819
|
+
args: { ref: { type: "positional", description: "Staged op ref (g_temp_* or target)", required: false } },
|
|
4820
|
+
run: async ({ args }) => {
|
|
4821
|
+
await draftAction("/api/ads/google/draft/remove", { ref: requireTarget(args, "op") });
|
|
4822
|
+
}
|
|
4823
|
+
}),
|
|
4824
|
+
clear: defineCommand22({
|
|
4825
|
+
meta: { name: "clear", description: "Discard all staged ops on this chat" },
|
|
4826
|
+
run: async () => {
|
|
4827
|
+
await draftAction("/api/ads/google/draft/clear", {});
|
|
4828
|
+
}
|
|
4829
|
+
})
|
|
4830
|
+
}
|
|
4831
|
+
});
|
|
4832
|
+
|
|
3835
4833
|
// src/commands/ads/google/keywords/index.ts
|
|
3836
|
-
import { defineCommand as
|
|
4834
|
+
import { defineCommand as defineCommand27 } from "citty";
|
|
3837
4835
|
|
|
3838
4836
|
// src/commands/ads/google/keywords/discover.ts
|
|
3839
|
-
import { defineCommand as
|
|
4837
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
3840
4838
|
|
|
3841
4839
|
// src/geo-context.ts
|
|
3842
4840
|
var GOOGLE_ADS_LOCATIONS = [
|
|
@@ -4111,7 +5109,7 @@ function handleKeywordError(err) {
|
|
|
4111
5109
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
4112
5110
|
process.exit(1);
|
|
4113
5111
|
}
|
|
4114
|
-
var discoverCommand =
|
|
5112
|
+
var discoverCommand = defineCommand23({
|
|
4115
5113
|
meta: {
|
|
4116
5114
|
name: "discover",
|
|
4117
5115
|
description: `Discover new keyword ideas from seed keywords or competitor URLs.
|
|
@@ -4173,7 +5171,7 @@ Examples:
|
|
|
4173
5171
|
});
|
|
4174
5172
|
|
|
4175
5173
|
// src/commands/ads/google/keywords/languages.ts
|
|
4176
|
-
import { defineCommand as
|
|
5174
|
+
import { defineCommand as defineCommand24 } from "citty";
|
|
4177
5175
|
registerSchema({
|
|
4178
5176
|
command: "ads.google.keywords.languages",
|
|
4179
5177
|
description: "List all supported language IDs for --language flag in Google Ads keyword commands.",
|
|
@@ -4183,7 +5181,7 @@ var FIELDS = {
|
|
|
4183
5181
|
id: "Language ID to pass as --language",
|
|
4184
5182
|
name: "Language name"
|
|
4185
5183
|
};
|
|
4186
|
-
var languagesCommand =
|
|
5184
|
+
var languagesCommand = defineCommand24({
|
|
4187
5185
|
meta: {
|
|
4188
5186
|
name: "languages",
|
|
4189
5187
|
description: "List all supported language IDs for --language flag."
|
|
@@ -4194,7 +5192,7 @@ var languagesCommand = defineCommand23({
|
|
|
4194
5192
|
});
|
|
4195
5193
|
|
|
4196
5194
|
// src/commands/ads/google/keywords/locations.ts
|
|
4197
|
-
import { defineCommand as
|
|
5195
|
+
import { defineCommand as defineCommand25 } from "citty";
|
|
4198
5196
|
registerSchema({
|
|
4199
5197
|
command: "ads.google.keywords.locations",
|
|
4200
5198
|
description: "List all supported geo target IDs for --location flag in Google Ads keyword commands.",
|
|
@@ -4204,7 +5202,7 @@ var FIELDS2 = {
|
|
|
4204
5202
|
id: "Geo target ID to pass as --location",
|
|
4205
5203
|
name: "Country/region name"
|
|
4206
5204
|
};
|
|
4207
|
-
var locationsCommand =
|
|
5205
|
+
var locationsCommand = defineCommand25({
|
|
4208
5206
|
meta: {
|
|
4209
5207
|
name: "locations",
|
|
4210
5208
|
description: "List all supported geo target IDs for --location flag."
|
|
@@ -4215,7 +5213,7 @@ var locationsCommand = defineCommand24({
|
|
|
4215
5213
|
});
|
|
4216
5214
|
|
|
4217
5215
|
// src/commands/ads/google/keywords/metrics.ts
|
|
4218
|
-
import { defineCommand as
|
|
5216
|
+
import { defineCommand as defineCommand26 } from "citty";
|
|
4219
5217
|
registerSchema({
|
|
4220
5218
|
command: "ads.google.keywords.metrics",
|
|
4221
5219
|
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.",
|
|
@@ -4239,7 +5237,7 @@ registerSchema({
|
|
|
4239
5237
|
output: { type: "string", description: "Format: json|csv|jsonl|md", required: false, default: "json" }
|
|
4240
5238
|
}
|
|
4241
5239
|
});
|
|
4242
|
-
var metricsCommand =
|
|
5240
|
+
var metricsCommand = defineCommand26({
|
|
4243
5241
|
meta: {
|
|
4244
5242
|
name: "metrics",
|
|
4245
5243
|
description: `Get historical search metrics for specific keywords.
|
|
@@ -4326,7 +5324,7 @@ Examples:
|
|
|
4326
5324
|
});
|
|
4327
5325
|
|
|
4328
5326
|
// src/commands/ads/google/keywords/index.ts
|
|
4329
|
-
var keywordsCommand =
|
|
5327
|
+
var keywordsCommand = defineCommand27({
|
|
4330
5328
|
meta: {
|
|
4331
5329
|
name: "keywords",
|
|
4332
5330
|
description: `Keyword research tools. Subcommands: discover, metrics, locations, languages.
|
|
@@ -4346,8 +5344,8 @@ Examples:
|
|
|
4346
5344
|
});
|
|
4347
5345
|
|
|
4348
5346
|
// src/commands/ads/google/library/index.ts
|
|
4349
|
-
import { defineCommand as
|
|
4350
|
-
var listAdvertisers =
|
|
5347
|
+
import { defineCommand as defineCommand28 } from "citty";
|
|
5348
|
+
var listAdvertisers = defineCommand28({
|
|
4351
5349
|
meta: {
|
|
4352
5350
|
name: "list-advertisers",
|
|
4353
5351
|
description: "List tracked Google advertisers and their accounts"
|
|
@@ -4364,7 +5362,7 @@ var listAdvertisers = defineCommand27({
|
|
|
4364
5362
|
}
|
|
4365
5363
|
}
|
|
4366
5364
|
});
|
|
4367
|
-
var syncStatus =
|
|
5365
|
+
var syncStatus = defineCommand28({
|
|
4368
5366
|
meta: {
|
|
4369
5367
|
name: "sync-status",
|
|
4370
5368
|
description: "Check the sync status and ad counts of a Google account"
|
|
@@ -4384,7 +5382,7 @@ var syncStatus = defineCommand27({
|
|
|
4384
5382
|
writeAdsJson({ ok: true, data });
|
|
4385
5383
|
}
|
|
4386
5384
|
});
|
|
4387
|
-
var searchAds =
|
|
5385
|
+
var searchAds = defineCommand28({
|
|
4388
5386
|
meta: {
|
|
4389
5387
|
name: "search-ads",
|
|
4390
5388
|
description: "Search and filter Google ads for an account"
|
|
@@ -4441,7 +5439,7 @@ var searchAds = defineCommand27({
|
|
|
4441
5439
|
}
|
|
4442
5440
|
}
|
|
4443
5441
|
});
|
|
4444
|
-
var searchAdvertiser =
|
|
5442
|
+
var searchAdvertiser = defineCommand28({
|
|
4445
5443
|
meta: {
|
|
4446
5444
|
name: "search-advertiser",
|
|
4447
5445
|
description: "Search for an advertiser on the Google Ads Transparency Center"
|
|
@@ -4476,7 +5474,7 @@ var searchAdvertiser = defineCommand27({
|
|
|
4476
5474
|
function sleep(ms) {
|
|
4477
5475
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
4478
5476
|
}
|
|
4479
|
-
var track =
|
|
5477
|
+
var track = defineCommand28({
|
|
4480
5478
|
meta: {
|
|
4481
5479
|
name: "track",
|
|
4482
5480
|
description: "Track a new Google advertiser (from search results). Waits for initial sync to complete before returning."
|
|
@@ -4534,7 +5532,7 @@ var track = defineCommand27({
|
|
|
4534
5532
|
process.exit(1);
|
|
4535
5533
|
}
|
|
4536
5534
|
});
|
|
4537
|
-
var sync =
|
|
5535
|
+
var sync = defineCommand28({
|
|
4538
5536
|
meta: {
|
|
4539
5537
|
name: "sync",
|
|
4540
5538
|
description: "Trigger an immediate sync for a Google account. Waits for completion before returning."
|
|
@@ -4578,7 +5576,7 @@ var sync = defineCommand27({
|
|
|
4578
5576
|
process.exit(1);
|
|
4579
5577
|
}
|
|
4580
5578
|
});
|
|
4581
|
-
var searchCompetitors =
|
|
5579
|
+
var searchCompetitors = defineCommand28({
|
|
4582
5580
|
meta: {
|
|
4583
5581
|
name: "search-competitors",
|
|
4584
5582
|
description: "Search for competitors running Google ads for a keyword (DataForSEO)"
|
|
@@ -4610,7 +5608,7 @@ var searchCompetitors = defineCommand27({
|
|
|
4610
5608
|
}
|
|
4611
5609
|
}
|
|
4612
5610
|
});
|
|
4613
|
-
var library =
|
|
5611
|
+
var library = defineCommand28({
|
|
4614
5612
|
meta: {
|
|
4615
5613
|
name: "library",
|
|
4616
5614
|
description: "Manage and search the Google Ads Library"
|
|
@@ -4627,9 +5625,9 @@ var library = defineCommand27({
|
|
|
4627
5625
|
});
|
|
4628
5626
|
|
|
4629
5627
|
// src/commands/ads/google/query.ts
|
|
4630
|
-
import { appendFileSync, existsSync as existsSync3, readFileSync as
|
|
5628
|
+
import { appendFileSync, existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
4631
5629
|
import { resolve } from "path";
|
|
4632
|
-
import { defineCommand as
|
|
5630
|
+
import { defineCommand as defineCommand29 } from "citty";
|
|
4633
5631
|
|
|
4634
5632
|
// src/commands/ads/google/preflight.ts
|
|
4635
5633
|
function buildCommand2(query, customerId) {
|
|
@@ -4650,6 +5648,24 @@ function applyAutoFixes(query, limit) {
|
|
|
4650
5648
|
corrected = corrected.replace(/shopping_performance_view\.product_(\w+)/g, "segments.product_$1");
|
|
4651
5649
|
warnings.push({ code: "FIELD_RENAMED", message: "shopping_performance_view.product_* \u2192 segments.product_*" });
|
|
4652
5650
|
}
|
|
5651
|
+
if (/asset\.\w+_asset\.final_(mobile_)?urls\b/.test(corrected)) {
|
|
5652
|
+
corrected = corrected.replace(/asset\.\w+_asset\.final_(mobile_)?urls\b/g, "asset.final_$1urls");
|
|
5653
|
+
warnings.push({ code: "FIELD_RENAMED", message: "asset.<type>_asset.final_urls \u2192 asset.final_urls" });
|
|
5654
|
+
}
|
|
5655
|
+
if (/FROM\s+campaign_budget\b/i.test(corrected)) {
|
|
5656
|
+
const whereClause = corrected.split(/\bWHERE\b/i)[1] ?? "";
|
|
5657
|
+
const selectClause = corrected.split(/\bFROM\b/i)[0] ?? "";
|
|
5658
|
+
const missing = [...new Set(whereClause.match(/campaign\.[\w.]+/g) ?? [])].filter(
|
|
5659
|
+
(field) => !selectClause.includes(field)
|
|
5660
|
+
);
|
|
5661
|
+
if (missing.length > 0) {
|
|
5662
|
+
corrected = corrected.replace(/SELECT\s+/i, `SELECT ${missing.join(", ")}, `);
|
|
5663
|
+
warnings.push({
|
|
5664
|
+
code: "REQUIRED_FIELD_ADDED",
|
|
5665
|
+
message: `Added ${missing.join(", ")} to SELECT \u2014 campaign_budget queries must select campaign fields used in WHERE`
|
|
5666
|
+
});
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
4653
5669
|
if (/campaign\.status\s*=\s*'ACTIVE'/i.test(corrected)) {
|
|
4654
5670
|
corrected = corrected.replace(/campaign\.status\s*=\s*'ACTIVE'/gi, "campaign.status = 'ENABLED'");
|
|
4655
5671
|
warnings.push({ code: "ENUM_CORRECTED", message: "campaign.status ACTIVE \u2192 ENABLED" });
|
|
@@ -4921,7 +5937,7 @@ function writeRowsToFile(filePath, rows, fields, append) {
|
|
|
4921
5937
|
`, "utf-8");
|
|
4922
5938
|
}
|
|
4923
5939
|
} else if (append && existsSync3(filePath)) {
|
|
4924
|
-
const existing = JSON.parse(
|
|
5940
|
+
const existing = JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
4925
5941
|
writeFileSync2(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
4926
5942
|
} else {
|
|
4927
5943
|
writeFileSync2(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -5085,7 +6101,7 @@ function handleQueryError(err, finalQuery, customerId) {
|
|
|
5085
6101
|
});
|
|
5086
6102
|
process.exit(1);
|
|
5087
6103
|
}
|
|
5088
|
-
var queryCommand =
|
|
6104
|
+
var queryCommand = defineCommand29({
|
|
5089
6105
|
meta: {
|
|
5090
6106
|
name: "query",
|
|
5091
6107
|
description: `Run GAQL queries against Google Ads. Supports raw GAQL, presets, pagination, file export, and caching.
|
|
@@ -5142,8 +6158,537 @@ Examples:
|
|
|
5142
6158
|
}
|
|
5143
6159
|
});
|
|
5144
6160
|
|
|
6161
|
+
// src/commands/ads/google/write-commands.ts
|
|
6162
|
+
import { defineCommand as defineCommand30 } from "citty";
|
|
6163
|
+
var customerIdArg = { "customer-id": { type: "string", description: "10-digit Google Ads customer id" } };
|
|
6164
|
+
var fileArg = {
|
|
6165
|
+
file: { type: "string", description: "JSON file with the full op payload (flags override)" }
|
|
6166
|
+
};
|
|
6167
|
+
var budgetsCommand = defineCommand30({
|
|
6168
|
+
meta: { name: "budgets", description: "Stage campaign budget create/update" },
|
|
6169
|
+
subCommands: {
|
|
6170
|
+
create: defineCommand30({
|
|
6171
|
+
meta: { name: "create", description: "Stage a campaign budget" },
|
|
6172
|
+
args: {
|
|
6173
|
+
...customerIdArg,
|
|
6174
|
+
...fileArg,
|
|
6175
|
+
name: { type: "string", description: "Budget name" },
|
|
6176
|
+
amount: { type: "string", description: "Daily amount in major currency units (e.g. 50)" },
|
|
6177
|
+
delivery: { type: "string", description: "STANDARD | ACCELERATED" },
|
|
6178
|
+
shared: { type: "boolean", description: "Explicitly shared budget" }
|
|
6179
|
+
},
|
|
6180
|
+
run: async ({ args }) => {
|
|
6181
|
+
const customerId = requireCustomerId(args);
|
|
6182
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6183
|
+
name: args.name,
|
|
6184
|
+
amountMicros: microsFlag(args.amount, "--amount"),
|
|
6185
|
+
deliveryMethod: args.delivery,
|
|
6186
|
+
explicitlyShared: args.shared || void 0
|
|
6187
|
+
});
|
|
6188
|
+
await stageCreate("google.budget.create", customerId, payload);
|
|
6189
|
+
}
|
|
6190
|
+
}),
|
|
6191
|
+
update: defineCommand30({
|
|
6192
|
+
meta: { name: "update", description: "Stage a budget update" },
|
|
6193
|
+
args: {
|
|
6194
|
+
...customerIdArg,
|
|
6195
|
+
...fileArg,
|
|
6196
|
+
name: { type: "string" },
|
|
6197
|
+
amount: { type: "string", description: "New daily amount in major currency units" },
|
|
6198
|
+
delivery: { type: "string" }
|
|
6199
|
+
},
|
|
6200
|
+
run: async ({ args }) => {
|
|
6201
|
+
const customerId = requireCustomerId(args);
|
|
6202
|
+
const target = requireTarget(args, "budget");
|
|
6203
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6204
|
+
name: args.name,
|
|
6205
|
+
amountMicros: microsFlag(args.amount, "--amount"),
|
|
6206
|
+
deliveryMethod: args.delivery
|
|
6207
|
+
});
|
|
6208
|
+
await stageUpdate("google.budget.update", customerId, target, payload);
|
|
6209
|
+
}
|
|
6210
|
+
})
|
|
6211
|
+
}
|
|
6212
|
+
});
|
|
6213
|
+
function biddingFromFlags(args) {
|
|
6214
|
+
const type = args["bidding-strategy"];
|
|
6215
|
+
if (!type) {
|
|
6216
|
+
return void 0;
|
|
6217
|
+
}
|
|
6218
|
+
return {
|
|
6219
|
+
type,
|
|
6220
|
+
targetCpaMicros: microsFlag(args["target-cpa"], "--target-cpa"),
|
|
6221
|
+
targetRoas: args["target-roas"] !== void 0 ? Number(args["target-roas"]) : void 0
|
|
6222
|
+
};
|
|
6223
|
+
}
|
|
6224
|
+
var campaignsCommand = defineCommand30({
|
|
6225
|
+
meta: { name: "campaigns", description: "Stage campaign create/update/pause/resume/remove" },
|
|
6226
|
+
subCommands: {
|
|
6227
|
+
create: defineCommand30({
|
|
6228
|
+
meta: { name: "create", description: "Stage a campaign" },
|
|
6229
|
+
args: {
|
|
6230
|
+
...customerIdArg,
|
|
6231
|
+
...fileArg,
|
|
6232
|
+
name: { type: "string" },
|
|
6233
|
+
"channel-type": {
|
|
6234
|
+
type: "string",
|
|
6235
|
+
description: "SEARCH | DISPLAY | SHOPPING | VIDEO | PERFORMANCE_MAX | DEMAND_GEN | \u2026"
|
|
6236
|
+
},
|
|
6237
|
+
"sub-type": { type: "string", description: "Advertising channel sub-type" },
|
|
6238
|
+
"budget-ref": { type: "string", description: "Budget ref (g_temp_*, id, or resource name)" },
|
|
6239
|
+
"bidding-strategy": {
|
|
6240
|
+
type: "string",
|
|
6241
|
+
description: "MANUAL_CPC | MAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS | \u2026"
|
|
6242
|
+
},
|
|
6243
|
+
"target-cpa": { type: "string", description: "Target CPA (major units) for TARGET_CPA" },
|
|
6244
|
+
"target-roas": { type: "string", description: "Target ROAS (e.g. 4.0) for TARGET_ROAS" },
|
|
6245
|
+
objective: { type: "string", description: "Advisory UI objective (SALES, LEADS, \u2026)" },
|
|
6246
|
+
"start-date": { type: "string", description: "YYYY-MM-DD" },
|
|
6247
|
+
"end-date": { type: "string", description: "YYYY-MM-DD" },
|
|
6248
|
+
status: { type: "string", description: "ENABLED | PAUSED (default PAUSED)" }
|
|
6249
|
+
},
|
|
6250
|
+
run: async ({ args }) => {
|
|
6251
|
+
const customerId = requireCustomerId(args);
|
|
6252
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6253
|
+
name: args.name,
|
|
6254
|
+
channelType: args["channel-type"],
|
|
6255
|
+
channelSubType: args["sub-type"],
|
|
6256
|
+
budget: args["budget-ref"],
|
|
6257
|
+
bidding: biddingFromFlags(args),
|
|
6258
|
+
objective: args.objective,
|
|
6259
|
+
startDate: args["start-date"],
|
|
6260
|
+
endDate: args["end-date"],
|
|
6261
|
+
status: args.status
|
|
6262
|
+
});
|
|
6263
|
+
await stageCreate("google.campaign.create", customerId, payload);
|
|
6264
|
+
}
|
|
6265
|
+
}),
|
|
6266
|
+
update: defineCommand30({
|
|
6267
|
+
meta: { name: "update", description: "Stage a campaign update" },
|
|
6268
|
+
args: {
|
|
6269
|
+
...customerIdArg,
|
|
6270
|
+
...fileArg,
|
|
6271
|
+
name: { type: "string" },
|
|
6272
|
+
"budget-ref": { type: "string" },
|
|
6273
|
+
"bidding-strategy": { type: "string" },
|
|
6274
|
+
"target-cpa": { type: "string" },
|
|
6275
|
+
"target-roas": { type: "string" },
|
|
6276
|
+
status: { type: "string" }
|
|
6277
|
+
},
|
|
6278
|
+
run: async ({ args }) => {
|
|
6279
|
+
const customerId = requireCustomerId(args);
|
|
6280
|
+
const target = requireTarget(args, "campaign");
|
|
6281
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6282
|
+
name: args.name,
|
|
6283
|
+
budget: args["budget-ref"],
|
|
6284
|
+
bidding: biddingFromFlags(args),
|
|
6285
|
+
status: args.status
|
|
6286
|
+
});
|
|
6287
|
+
await stageUpdate("google.campaign.update", customerId, target, payload);
|
|
6288
|
+
}
|
|
6289
|
+
}),
|
|
6290
|
+
pause: statusCommand2("google.campaign.pause", "campaign"),
|
|
6291
|
+
resume: statusCommand2("google.campaign.resume", "campaign"),
|
|
6292
|
+
remove: statusCommand2("google.campaign.remove", "campaign")
|
|
6293
|
+
}
|
|
6294
|
+
});
|
|
6295
|
+
function statusCommand2(kind, entity) {
|
|
6296
|
+
return defineCommand30({
|
|
6297
|
+
meta: { name: kind.split(".")[2], description: `Stage a ${entity} ${kind.split(".")[2]}` },
|
|
6298
|
+
args: {
|
|
6299
|
+
...customerIdArg,
|
|
6300
|
+
id: { type: "positional", description: `${entity} resource name or id`, required: false }
|
|
6301
|
+
},
|
|
6302
|
+
run: async ({ args }) => {
|
|
6303
|
+
const customerId = requireCustomerId(args);
|
|
6304
|
+
await stageTarget(kind, customerId, requireTarget(args, entity));
|
|
6305
|
+
}
|
|
6306
|
+
});
|
|
6307
|
+
}
|
|
6308
|
+
var adGroupsCommand = defineCommand30({
|
|
6309
|
+
meta: { name: "ad-groups", description: "Stage ad group create/update/pause/resume/remove" },
|
|
6310
|
+
subCommands: {
|
|
6311
|
+
create: defineCommand30({
|
|
6312
|
+
meta: { name: "create", description: "Stage an ad group" },
|
|
6313
|
+
args: {
|
|
6314
|
+
...customerIdArg,
|
|
6315
|
+
...fileArg,
|
|
6316
|
+
name: { type: "string" },
|
|
6317
|
+
"campaign-ref": { type: "string", description: "Campaign ref (g_temp_*, id, or resource name)" },
|
|
6318
|
+
type: { type: "string", description: "Ad group type (default SEARCH_STANDARD)" },
|
|
6319
|
+
"cpc-bid": { type: "string", description: "Default CPC bid in major units" },
|
|
6320
|
+
status: { type: "string" }
|
|
6321
|
+
},
|
|
6322
|
+
run: async ({ args }) => {
|
|
6323
|
+
const customerId = requireCustomerId(args);
|
|
6324
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6325
|
+
name: args.name,
|
|
6326
|
+
campaign: args["campaign-ref"],
|
|
6327
|
+
type: args.type,
|
|
6328
|
+
cpcBidMicros: microsFlag(args["cpc-bid"], "--cpc-bid"),
|
|
6329
|
+
status: args.status
|
|
6330
|
+
});
|
|
6331
|
+
await stageCreate("google.adGroup.create", customerId, payload);
|
|
6332
|
+
}
|
|
6333
|
+
}),
|
|
6334
|
+
update: defineCommand30({
|
|
6335
|
+
meta: { name: "update", description: "Stage an ad group update" },
|
|
6336
|
+
args: {
|
|
6337
|
+
...customerIdArg,
|
|
6338
|
+
...fileArg,
|
|
6339
|
+
name: { type: "string" },
|
|
6340
|
+
"cpc-bid": { type: "string" },
|
|
6341
|
+
status: { type: "string" }
|
|
6342
|
+
},
|
|
6343
|
+
run: async ({ args }) => {
|
|
6344
|
+
const customerId = requireCustomerId(args);
|
|
6345
|
+
const target = requireTarget(args, "ad group");
|
|
6346
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
6347
|
+
name: args.name,
|
|
6348
|
+
cpcBidMicros: microsFlag(args["cpc-bid"], "--cpc-bid"),
|
|
6349
|
+
status: args.status
|
|
6350
|
+
});
|
|
6351
|
+
await stageUpdate("google.adGroup.update", customerId, target, payload);
|
|
6352
|
+
}
|
|
6353
|
+
}),
|
|
6354
|
+
pause: statusCommand2("google.adGroup.pause", "ad group"),
|
|
6355
|
+
resume: statusCommand2("google.adGroup.resume", "ad group"),
|
|
6356
|
+
remove: statusCommand2("google.adGroup.remove", "ad group")
|
|
6357
|
+
}
|
|
6358
|
+
});
|
|
6359
|
+
var keywordWriteSubcommands = {
|
|
6360
|
+
add: defineCommand30({
|
|
6361
|
+
meta: { name: "add", description: "Add keyword(s) to an ad group \u2014 one --text or a whole batch" },
|
|
6362
|
+
args: {
|
|
6363
|
+
...customerIdArg,
|
|
6364
|
+
"ad-group-ref": { type: "string", description: "Ad group ref (g_temp_*, id, or resource name)" },
|
|
6365
|
+
text: {
|
|
6366
|
+
type: "string",
|
|
6367
|
+
description: 'Keyword text \u2014 comma-separate for a batch, optional ":EXACT|:PHRASE|:BROAD" suffix per entry'
|
|
6368
|
+
},
|
|
6369
|
+
file: { type: "string", description: "Text file with one keyword[:MATCH_TYPE] per line" },
|
|
6370
|
+
"match-type": { type: "string", description: "Default match type: EXACT | PHRASE | BROAD" },
|
|
6371
|
+
"cpc-bid": { type: "string", description: "Keyword CPC bid in major units (applies to all)" },
|
|
6372
|
+
"final-url": { type: "string", description: "Keyword-level final URL (applies to all)" }
|
|
6373
|
+
},
|
|
6374
|
+
run: async ({ args }) => {
|
|
6375
|
+
const customerId = requireCustomerId(args);
|
|
6376
|
+
const adGroup = requireStringFlag(args["ad-group-ref"], "--ad-group-ref");
|
|
6377
|
+
const cpcBidMicros = microsFlag(args["cpc-bid"], "--cpc-bid");
|
|
6378
|
+
const finalUrls = args["final-url"] ? [args["final-url"]] : void 0;
|
|
6379
|
+
await stageGoogleOps(
|
|
6380
|
+
keywordEntries(args).map((entry) => ({
|
|
6381
|
+
kind: "google.keyword.add",
|
|
6382
|
+
customerId,
|
|
6383
|
+
payload: { adGroup, text: entry.text, matchType: entry.matchType, cpcBidMicros, finalUrls }
|
|
6384
|
+
}))
|
|
6385
|
+
);
|
|
6386
|
+
}
|
|
6387
|
+
}),
|
|
6388
|
+
update: defineCommand30({
|
|
6389
|
+
meta: { name: "update", description: "Update a keyword" },
|
|
6390
|
+
args: { ...customerIdArg, "cpc-bid": { type: "string" }, status: { type: "string" } },
|
|
6391
|
+
run: async ({ args }) => {
|
|
6392
|
+
const customerId = requireCustomerId(args);
|
|
6393
|
+
await stageUpdate("google.keyword.update", customerId, requireTarget(args, "keyword"), {
|
|
6394
|
+
cpcBidMicros: microsFlag(args["cpc-bid"], "--cpc-bid"),
|
|
6395
|
+
status: args.status
|
|
6396
|
+
});
|
|
6397
|
+
}
|
|
6398
|
+
}),
|
|
6399
|
+
remove: statusCommand2("google.keyword.remove", "keyword")
|
|
6400
|
+
};
|
|
6401
|
+
var negativeKeywordsCommand = defineCommand30({
|
|
6402
|
+
meta: { name: "negative-keywords", description: "Stage negative keyword add/remove (ad-group or campaign level)" },
|
|
6403
|
+
subCommands: {
|
|
6404
|
+
add: defineCommand30({
|
|
6405
|
+
meta: { name: "add", description: "Add negative keyword(s) \u2014 one --text or a whole batch" },
|
|
6406
|
+
args: {
|
|
6407
|
+
...customerIdArg,
|
|
6408
|
+
level: { type: "string", description: "adGroup | campaign" },
|
|
6409
|
+
"parent-ref": { type: "string", description: "Ad group or campaign ref" },
|
|
6410
|
+
text: {
|
|
6411
|
+
type: "string",
|
|
6412
|
+
description: 'Keyword text \u2014 comma-separate for a batch, optional ":MATCH_TYPE" suffix per entry'
|
|
6413
|
+
},
|
|
6414
|
+
file: { type: "string", description: "Text file with one keyword[:MATCH_TYPE] per line" },
|
|
6415
|
+
"match-type": { type: "string", description: "Default match type: EXACT | PHRASE | BROAD" }
|
|
6416
|
+
},
|
|
6417
|
+
run: async ({ args }) => {
|
|
6418
|
+
const customerId = requireCustomerId(args);
|
|
6419
|
+
const level = requireStringFlag(args.level, "--level");
|
|
6420
|
+
const parent = requireStringFlag(args["parent-ref"], "--parent-ref");
|
|
6421
|
+
await stageGoogleOps(
|
|
6422
|
+
keywordEntries(args).map((entry) => ({
|
|
6423
|
+
kind: "google.negativeKeyword.add",
|
|
6424
|
+
customerId,
|
|
6425
|
+
payload: { level, parent, text: entry.text, matchType: entry.matchType }
|
|
6426
|
+
}))
|
|
6427
|
+
);
|
|
6428
|
+
}
|
|
6429
|
+
}),
|
|
6430
|
+
remove: statusCommand2("google.negativeKeyword.remove", "negative keyword")
|
|
6431
|
+
}
|
|
6432
|
+
});
|
|
6433
|
+
var keywordListsCommand = defineCommand30({
|
|
6434
|
+
meta: { name: "keyword-lists", description: "Stage shared negative keyword lists (create/add/attach/detach)" },
|
|
6435
|
+
subCommands: {
|
|
6436
|
+
create: defineCommand30({
|
|
6437
|
+
meta: { name: "create", description: "Create a shared negative keyword list" },
|
|
6438
|
+
args: {
|
|
6439
|
+
...customerIdArg,
|
|
6440
|
+
name: { type: "string" },
|
|
6441
|
+
type: {
|
|
6442
|
+
type: "string",
|
|
6443
|
+
description: "NEGATIVE_KEYWORDS (default) | NEGATIVE_PLACEMENTS | ACCOUNT_LEVEL_NEGATIVE_KEYWORDS"
|
|
6444
|
+
}
|
|
6445
|
+
},
|
|
6446
|
+
run: async ({ args }) => {
|
|
6447
|
+
const customerId = requireCustomerId(args);
|
|
6448
|
+
await stageCreate("google.sharedSet.create", customerId, {
|
|
6449
|
+
name: requireStringFlag(args.name, "--name"),
|
|
6450
|
+
type: args.type
|
|
6451
|
+
});
|
|
6452
|
+
}
|
|
6453
|
+
}),
|
|
6454
|
+
add: defineCommand30({
|
|
6455
|
+
meta: { name: "add", description: "Add keyword(s) to a shared list \u2014 one --text or a whole batch" },
|
|
6456
|
+
args: {
|
|
6457
|
+
...customerIdArg,
|
|
6458
|
+
"list-ref": { type: "string", description: "Shared set ref" },
|
|
6459
|
+
text: {
|
|
6460
|
+
type: "string",
|
|
6461
|
+
description: 'Keyword text \u2014 comma-separate for a batch, optional ":MATCH_TYPE" suffix per entry'
|
|
6462
|
+
},
|
|
6463
|
+
file: { type: "string", description: "Text file with one keyword[:MATCH_TYPE] per line" },
|
|
6464
|
+
"match-type": { type: "string", description: "Default match type: EXACT | PHRASE | BROAD" }
|
|
6465
|
+
},
|
|
6466
|
+
run: async ({ args }) => {
|
|
6467
|
+
const customerId = requireCustomerId(args);
|
|
6468
|
+
const sharedSet = requireStringFlag(args["list-ref"], "--list-ref");
|
|
6469
|
+
await stageGoogleOps(
|
|
6470
|
+
keywordEntries(args).map((entry) => ({
|
|
6471
|
+
kind: "google.sharedSetMember.add",
|
|
6472
|
+
customerId,
|
|
6473
|
+
payload: { sharedSet, text: entry.text, matchType: entry.matchType }
|
|
6474
|
+
}))
|
|
6475
|
+
);
|
|
6476
|
+
}
|
|
6477
|
+
}),
|
|
6478
|
+
attach: defineCommand30({
|
|
6479
|
+
meta: { name: "attach", description: "Attach a keyword list to a campaign" },
|
|
6480
|
+
args: { ...customerIdArg, "campaign-ref": { type: "string" }, "list-ref": { type: "string" } },
|
|
6481
|
+
run: async ({ args }) => {
|
|
6482
|
+
const customerId = requireCustomerId(args);
|
|
6483
|
+
await stageCreate("google.campaignSharedSet.attach", customerId, {
|
|
6484
|
+
campaign: requireStringFlag(args["campaign-ref"], "--campaign-ref"),
|
|
6485
|
+
sharedSet: requireStringFlag(args["list-ref"], "--list-ref")
|
|
6486
|
+
});
|
|
6487
|
+
}
|
|
6488
|
+
}),
|
|
6489
|
+
detach: statusCommand2("google.campaignSharedSet.detach", "campaign shared set")
|
|
6490
|
+
}
|
|
6491
|
+
});
|
|
6492
|
+
function rsaContentFromFlags(args) {
|
|
6493
|
+
const headlines = listFlag(args.headlines);
|
|
6494
|
+
const descriptions = listFlag(args.descriptions);
|
|
6495
|
+
if (!headlines || !descriptions) {
|
|
6496
|
+
failWriteValidation("responsive search ads need --headlines and --descriptions (comma-separated), or use --file");
|
|
6497
|
+
}
|
|
6498
|
+
const finalUrls = listFlag(args["final-url"]);
|
|
6499
|
+
if (!finalUrls) {
|
|
6500
|
+
failWriteValidation("--final-url is required for a responsive search ad");
|
|
6501
|
+
}
|
|
6502
|
+
return {
|
|
6503
|
+
format: "responsiveSearch",
|
|
6504
|
+
headlines: headlines.map((text) => ({ text })),
|
|
6505
|
+
descriptions: descriptions.map((text) => ({ text })),
|
|
6506
|
+
path1: args.path1,
|
|
6507
|
+
path2: args.path2,
|
|
6508
|
+
finalUrls
|
|
6509
|
+
};
|
|
6510
|
+
}
|
|
6511
|
+
var adsCommand = defineCommand30({
|
|
6512
|
+
meta: { name: "ads", description: "Stage ad create/update/pause/resume/remove" },
|
|
6513
|
+
subCommands: {
|
|
6514
|
+
create: defineCommand30({
|
|
6515
|
+
meta: { name: "create", description: "Stage an ad (responsive search via flags; other formats via --file)" },
|
|
6516
|
+
args: {
|
|
6517
|
+
...customerIdArg,
|
|
6518
|
+
...fileArg,
|
|
6519
|
+
"ad-group-ref": { type: "string", description: "Ad group ref" },
|
|
6520
|
+
format: {
|
|
6521
|
+
type: "string",
|
|
6522
|
+
description: "responsiveSearch (default) | responsiveDisplay | performanceMaxAssetGroup | call | app | video | demandGen"
|
|
6523
|
+
},
|
|
6524
|
+
headlines: { type: "string", description: "Comma-separated headlines (RSA)" },
|
|
6525
|
+
descriptions: { type: "string", description: "Comma-separated descriptions (RSA)" },
|
|
6526
|
+
path1: { type: "string" },
|
|
6527
|
+
path2: { type: "string" },
|
|
6528
|
+
"final-url": { type: "string", description: "Comma-separated final URLs" },
|
|
6529
|
+
status: { type: "string" }
|
|
6530
|
+
},
|
|
6531
|
+
run: async ({ args }) => {
|
|
6532
|
+
const customerId = requireCustomerId(args);
|
|
6533
|
+
const file = loadJsonFileArg(args.file);
|
|
6534
|
+
const format = args.format ?? "responsiveSearch";
|
|
6535
|
+
const content = file.content ?? (format === "responsiveSearch" ? rsaContentFromFlags(args) : failWriteValidation(`--format ${format} needs --file with the ad content`));
|
|
6536
|
+
await stageCreate("google.ad.create", customerId, {
|
|
6537
|
+
adGroup: requireStringFlag(args["ad-group-ref"] ?? file.adGroup, "--ad-group-ref"),
|
|
6538
|
+
status: args.status ?? file.status,
|
|
6539
|
+
content
|
|
6540
|
+
});
|
|
6541
|
+
}
|
|
6542
|
+
}),
|
|
6543
|
+
update: defineCommand30({
|
|
6544
|
+
meta: { name: "update", description: "Stage an ad update" },
|
|
6545
|
+
args: { ...customerIdArg, ...fileArg, status: { type: "string" } },
|
|
6546
|
+
run: async ({ args }) => {
|
|
6547
|
+
const customerId = requireCustomerId(args);
|
|
6548
|
+
const file = loadJsonFileArg(args.file);
|
|
6549
|
+
await stageUpdate(
|
|
6550
|
+
"google.ad.update",
|
|
6551
|
+
customerId,
|
|
6552
|
+
requireTarget(args, "ad"),
|
|
6553
|
+
mergePayload(file, { status: args.status })
|
|
6554
|
+
);
|
|
6555
|
+
}
|
|
6556
|
+
}),
|
|
6557
|
+
pause: statusCommand2("google.ad.pause", "ad"),
|
|
6558
|
+
resume: statusCommand2("google.ad.resume", "ad"),
|
|
6559
|
+
remove: statusCommand2("google.ad.remove", "ad")
|
|
6560
|
+
}
|
|
6561
|
+
});
|
|
6562
|
+
function fileCreateCommand(name, kind, description) {
|
|
6563
|
+
return defineCommand30({
|
|
6564
|
+
meta: { name, description },
|
|
6565
|
+
args: { ...customerIdArg, ...fileArg },
|
|
6566
|
+
run: async ({ args }) => {
|
|
6567
|
+
const customerId = requireCustomerId(args);
|
|
6568
|
+
const payload = loadJsonFileArg(args.file);
|
|
6569
|
+
if (Object.keys(payload).length === 0) {
|
|
6570
|
+
failWriteValidation(`${kind} needs --file with the op payload`);
|
|
6571
|
+
}
|
|
6572
|
+
await stageGoogleOp({ kind, customerId, payload });
|
|
6573
|
+
}
|
|
6574
|
+
});
|
|
6575
|
+
}
|
|
6576
|
+
var assetsCommand = defineCommand30({
|
|
6577
|
+
meta: { name: "assets", description: "Stage asset create + asset-link attach/detach (via --file)" },
|
|
6578
|
+
subCommands: {
|
|
6579
|
+
create: fileCreateCommand(
|
|
6580
|
+
"create",
|
|
6581
|
+
"google.asset.create",
|
|
6582
|
+
"Stage an asset (text/image/sitelink/callout/structuredSnippet/\u2026)"
|
|
6583
|
+
),
|
|
6584
|
+
attach: fileCreateCommand("attach", "google.assetLink.attach", "Attach an asset to a campaign/adGroup/customer"),
|
|
6585
|
+
detach: statusCommand2("google.assetLink.detach", "asset link")
|
|
6586
|
+
}
|
|
6587
|
+
});
|
|
6588
|
+
var audiencesCommand = defineCommand30({
|
|
6589
|
+
meta: { name: "audiences", description: "Stage audience (user list) create + criterion attach/detach (via --file)" },
|
|
6590
|
+
subCommands: {
|
|
6591
|
+
create: fileCreateCommand("create", "google.audience.create", "Stage a user-list audience"),
|
|
6592
|
+
attach: fileCreateCommand(
|
|
6593
|
+
"attach",
|
|
6594
|
+
"google.audienceCriterion.attach",
|
|
6595
|
+
"Target/exclude an audience on a campaign/adGroup"
|
|
6596
|
+
),
|
|
6597
|
+
detach: statusCommand2("google.audienceCriterion.detach", "audience criterion")
|
|
6598
|
+
}
|
|
6599
|
+
});
|
|
6600
|
+
var conversionsCommand = defineCommand30({
|
|
6601
|
+
meta: { name: "conversions", description: "Stage conversion action create/update (via --file)" },
|
|
6602
|
+
subCommands: {
|
|
6603
|
+
create: fileCreateCommand("create", "google.conversionAction.create", "Stage a conversion action"),
|
|
6604
|
+
update: defineCommand30({
|
|
6605
|
+
meta: { name: "update", description: "Stage a conversion action update" },
|
|
6606
|
+
args: { ...customerIdArg, ...fileArg },
|
|
6607
|
+
run: async ({ args }) => {
|
|
6608
|
+
const customerId = requireCustomerId(args);
|
|
6609
|
+
await stageUpdate(
|
|
6610
|
+
"google.conversionAction.update",
|
|
6611
|
+
customerId,
|
|
6612
|
+
requireTarget(args, "conversion action"),
|
|
6613
|
+
loadJsonFileArg(args.file)
|
|
6614
|
+
);
|
|
6615
|
+
}
|
|
6616
|
+
})
|
|
6617
|
+
}
|
|
6618
|
+
});
|
|
6619
|
+
var biddingStrategiesCommand = defineCommand30({
|
|
6620
|
+
meta: { name: "bidding-strategies", description: "Stage portfolio bidding strategy create/update (via --file)" },
|
|
6621
|
+
subCommands: {
|
|
6622
|
+
create: fileCreateCommand("create", "google.biddingStrategy.create", "Stage a portfolio bidding strategy"),
|
|
6623
|
+
update: defineCommand30({
|
|
6624
|
+
meta: { name: "update", description: "Stage a portfolio bidding strategy update" },
|
|
6625
|
+
args: { ...customerIdArg, ...fileArg },
|
|
6626
|
+
run: async ({ args }) => {
|
|
6627
|
+
const customerId = requireCustomerId(args);
|
|
6628
|
+
await stageUpdate(
|
|
6629
|
+
"google.biddingStrategy.update",
|
|
6630
|
+
customerId,
|
|
6631
|
+
requireTarget(args, "bidding strategy"),
|
|
6632
|
+
loadJsonFileArg(args.file)
|
|
6633
|
+
);
|
|
6634
|
+
}
|
|
6635
|
+
})
|
|
6636
|
+
}
|
|
6637
|
+
});
|
|
6638
|
+
var labelsCommand = defineCommand30({
|
|
6639
|
+
meta: { name: "labels", description: "Stage label create + attach (via --file)" },
|
|
6640
|
+
subCommands: {
|
|
6641
|
+
create: defineCommand30({
|
|
6642
|
+
meta: { name: "create", description: "Create a label" },
|
|
6643
|
+
args: {
|
|
6644
|
+
...customerIdArg,
|
|
6645
|
+
name: { type: "string" },
|
|
6646
|
+
"background-color": { type: "string" },
|
|
6647
|
+
description: { type: "string" }
|
|
6648
|
+
},
|
|
6649
|
+
run: async ({ args }) => {
|
|
6650
|
+
const customerId = requireCustomerId(args);
|
|
6651
|
+
await stageCreate("google.label.create", customerId, {
|
|
6652
|
+
name: requireStringFlag(args.name, "--name"),
|
|
6653
|
+
backgroundColor: args["background-color"],
|
|
6654
|
+
description: args.description
|
|
6655
|
+
});
|
|
6656
|
+
}
|
|
6657
|
+
}),
|
|
6658
|
+
attach: fileCreateCommand("attach", "google.label.attach", "Attach a label to a campaign/adGroup/ad")
|
|
6659
|
+
}
|
|
6660
|
+
});
|
|
6661
|
+
var campaignCriteriaCommand = defineCommand30({
|
|
6662
|
+
meta: {
|
|
6663
|
+
name: "campaign-criteria",
|
|
6664
|
+
description: "Stage campaign criteria (location/language/adSchedule/device) add/remove (via --file)"
|
|
6665
|
+
},
|
|
6666
|
+
subCommands: {
|
|
6667
|
+
add: fileCreateCommand("add", "google.campaignCriterion.add", "Add a campaign criterion"),
|
|
6668
|
+
remove: statusCommand2("google.campaignCriterion.remove", "campaign criterion")
|
|
6669
|
+
}
|
|
6670
|
+
});
|
|
6671
|
+
var googleWriteCommands = {
|
|
6672
|
+
budgets: budgetsCommand,
|
|
6673
|
+
campaigns: campaignsCommand,
|
|
6674
|
+
"ad-groups": adGroupsCommand,
|
|
6675
|
+
"negative-keywords": negativeKeywordsCommand,
|
|
6676
|
+
"keyword-lists": keywordListsCommand,
|
|
6677
|
+
ads: adsCommand,
|
|
6678
|
+
assets: assetsCommand,
|
|
6679
|
+
audiences: audiencesCommand,
|
|
6680
|
+
conversions: conversionsCommand,
|
|
6681
|
+
"bidding-strategies": biddingStrategiesCommand,
|
|
6682
|
+
labels: labelsCommand,
|
|
6683
|
+
"campaign-criteria": campaignCriteriaCommand
|
|
6684
|
+
};
|
|
6685
|
+
|
|
5145
6686
|
// src/commands/ads/google/index.ts
|
|
5146
|
-
var
|
|
6687
|
+
var keywordsWithWrites = defineCommand31({
|
|
6688
|
+
meta: keywordsCommand.meta,
|
|
6689
|
+
subCommands: { ...keywordsCommand.subCommands, ...keywordWriteSubcommands }
|
|
6690
|
+
});
|
|
6691
|
+
var googleCommand = defineCommand31({
|
|
5147
6692
|
meta: {
|
|
5148
6693
|
name: "google",
|
|
5149
6694
|
description: `Google Ads commands. Query campaigns, keywords, search terms, and more via GAQL.
|
|
@@ -5158,20 +6703,28 @@ Examples:
|
|
|
5158
6703
|
baker ads google query --preset campaign-performance --customer-id 1234567890
|
|
5159
6704
|
baker ads google currency --customer-id 1234567890
|
|
5160
6705
|
baker ads google keywords discover --customer-id 1234567890 --seeds "running shoes"
|
|
5161
|
-
baker ads google library list-advertisers \u2014 list tracked Google advertisers
|
|
6706
|
+
baker ads google library list-advertisers \u2014 list tracked Google advertisers
|
|
6707
|
+
|
|
6708
|
+
Staged writes (never touch Google until the chat is published):
|
|
6709
|
+
baker ads google budgets create --customer-id 1234567890 --name "Search" --amount 50
|
|
6710
|
+
baker ads google campaigns create --customer-id 1234567890 --name "Brand" --channel-type SEARCH --budget-ref g_temp_\u2026 --bidding-strategy MANUAL_CPC
|
|
6711
|
+
baker ads google keyword-lists create --customer-id 1234567890 --name "Brand exclusions"
|
|
6712
|
+
baker ads google draft list \u2014 review staged Google Ads changes`
|
|
5162
6713
|
},
|
|
5163
6714
|
subCommands: {
|
|
5164
6715
|
accounts: accountsCommand,
|
|
5165
6716
|
currency: currencyCommand,
|
|
5166
6717
|
changes: changesCommand,
|
|
5167
6718
|
query: queryCommand,
|
|
5168
|
-
keywords:
|
|
5169
|
-
library
|
|
6719
|
+
keywords: keywordsWithWrites,
|
|
6720
|
+
library,
|
|
6721
|
+
...googleWriteCommands,
|
|
6722
|
+
draft: draftCommand2
|
|
5170
6723
|
}
|
|
5171
6724
|
});
|
|
5172
6725
|
|
|
5173
6726
|
// src/commands/ads/linkedin/index.ts
|
|
5174
|
-
import { defineCommand as
|
|
6727
|
+
import { defineCommand as defineCommand51 } from "citty";
|
|
5175
6728
|
|
|
5176
6729
|
// src/commands/ads/linkedin/schemas.ts
|
|
5177
6730
|
registerSchema({
|
|
@@ -5832,7 +7385,7 @@ registerSchema({
|
|
|
5832
7385
|
});
|
|
5833
7386
|
|
|
5834
7387
|
// src/commands/ads/linkedin/account.ts
|
|
5835
|
-
import { defineCommand as
|
|
7388
|
+
import { defineCommand as defineCommand32 } from "citty";
|
|
5836
7389
|
|
|
5837
7390
|
// src/commands/ads/linkedin/shared.ts
|
|
5838
7391
|
var DAY_MS2 = 864e5;
|
|
@@ -5935,7 +7488,7 @@ function resolveStatusFilter(args) {
|
|
|
5935
7488
|
}
|
|
5936
7489
|
|
|
5937
7490
|
// src/commands/ads/linkedin/account.ts
|
|
5938
|
-
var accountCommand =
|
|
7491
|
+
var accountCommand = defineCommand32({
|
|
5939
7492
|
meta: {
|
|
5940
7493
|
name: "account",
|
|
5941
7494
|
description: `Single LinkedIn ad account detail (currency, status, type).
|
|
@@ -5969,9 +7522,9 @@ Examples:
|
|
|
5969
7522
|
});
|
|
5970
7523
|
|
|
5971
7524
|
// src/commands/ads/linkedin/accounts.ts
|
|
5972
|
-
import { defineCommand as
|
|
7525
|
+
import { defineCommand as defineCommand33 } from "citty";
|
|
5973
7526
|
var ACCOUNTS_TTL_MS = 60 * 60 * 1e3;
|
|
5974
|
-
var accountsCommand2 =
|
|
7527
|
+
var accountsCommand2 = defineCommand33({
|
|
5975
7528
|
meta: {
|
|
5976
7529
|
name: "accounts",
|
|
5977
7530
|
description: `List LinkedIn ad accounts in this company's connected scope.
|
|
@@ -6019,7 +7572,7 @@ Examples:
|
|
|
6019
7572
|
});
|
|
6020
7573
|
|
|
6021
7574
|
// src/commands/ads/linkedin/analytics.ts
|
|
6022
|
-
import { defineCommand as
|
|
7575
|
+
import { defineCommand as defineCommand34 } from "citty";
|
|
6023
7576
|
|
|
6024
7577
|
// src/commands/ads/linkedin/presets.ts
|
|
6025
7578
|
var INTENTS = {
|
|
@@ -6291,7 +7844,7 @@ function numberOf(v) {
|
|
|
6291
7844
|
}
|
|
6292
7845
|
return 0;
|
|
6293
7846
|
}
|
|
6294
|
-
var analyticsCommand =
|
|
7847
|
+
var analyticsCommand = defineCommand34({
|
|
6295
7848
|
meta: {
|
|
6296
7849
|
name: "analytics",
|
|
6297
7850
|
description: `Performance reporting \u2014 the workhorse for AI agents.
|
|
@@ -6418,8 +7971,8 @@ Examples \u2014 common AI questions:
|
|
|
6418
7971
|
});
|
|
6419
7972
|
|
|
6420
7973
|
// src/commands/ads/linkedin/audience-size.ts
|
|
6421
|
-
import { readFileSync as
|
|
6422
|
-
import { defineCommand as
|
|
7974
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
7975
|
+
import { defineCommand as defineCommand35 } from "citty";
|
|
6423
7976
|
function loadTargeting(args) {
|
|
6424
7977
|
const inline = args.targeting;
|
|
6425
7978
|
if (inline) {
|
|
@@ -6432,7 +7985,7 @@ function loadTargeting(args) {
|
|
|
6432
7985
|
const file = args["targeting-file"];
|
|
6433
7986
|
if (file) {
|
|
6434
7987
|
try {
|
|
6435
|
-
return JSON.parse(
|
|
7988
|
+
return JSON.parse(readFileSync5(file, "utf-8"));
|
|
6436
7989
|
} catch (e) {
|
|
6437
7990
|
handleLinkedinError(
|
|
6438
7991
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -6441,7 +7994,7 @@ function loadTargeting(args) {
|
|
|
6441
7994
|
}
|
|
6442
7995
|
handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
|
|
6443
7996
|
}
|
|
6444
|
-
var audienceSizeCommand =
|
|
7997
|
+
var audienceSizeCommand = defineCommand35({
|
|
6445
7998
|
meta: {
|
|
6446
7999
|
name: "audience-size",
|
|
6447
8000
|
description: `Estimate audience size for a targeting payload \u2014 pre-launch sanity check.
|
|
@@ -6486,7 +8039,7 @@ Examples:
|
|
|
6486
8039
|
});
|
|
6487
8040
|
|
|
6488
8041
|
// src/commands/ads/linkedin/audit.ts
|
|
6489
|
-
import { defineCommand as
|
|
8042
|
+
import { defineCommand as defineCommand36 } from "citty";
|
|
6490
8043
|
var SEVERITY_RANK = {
|
|
6491
8044
|
critical: 0,
|
|
6492
8045
|
high: 1,
|
|
@@ -6545,7 +8098,7 @@ function noteOf(f) {
|
|
|
6545
8098
|
const fix = f.fix?.explanation ?? "";
|
|
6546
8099
|
return [fix, ev].filter(Boolean).join(" \u2014 ");
|
|
6547
8100
|
}
|
|
6548
|
-
var auditCommand =
|
|
8101
|
+
var auditCommand = defineCommand36({
|
|
6549
8102
|
meta: {
|
|
6550
8103
|
name: "audit",
|
|
6551
8104
|
description: `Run a LinkedIn Ads playbook audit \u2014 30+ checks across Settings, Tracking,
|
|
@@ -6611,8 +8164,8 @@ Examples:
|
|
|
6611
8164
|
});
|
|
6612
8165
|
|
|
6613
8166
|
// src/commands/ads/linkedin/bid-pricing.ts
|
|
6614
|
-
import { readFileSync as
|
|
6615
|
-
import { defineCommand as
|
|
8167
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
8168
|
+
import { defineCommand as defineCommand37 } from "citty";
|
|
6616
8169
|
function loadTargeting2(args) {
|
|
6617
8170
|
const inline = args.targeting;
|
|
6618
8171
|
if (inline) {
|
|
@@ -6625,7 +8178,7 @@ function loadTargeting2(args) {
|
|
|
6625
8178
|
const file = args["targeting-file"];
|
|
6626
8179
|
if (file) {
|
|
6627
8180
|
try {
|
|
6628
|
-
return JSON.parse(
|
|
8181
|
+
return JSON.parse(readFileSync6(file, "utf-8"));
|
|
6629
8182
|
} catch (e) {
|
|
6630
8183
|
handleLinkedinError(
|
|
6631
8184
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -6634,7 +8187,7 @@ function loadTargeting2(args) {
|
|
|
6634
8187
|
}
|
|
6635
8188
|
handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
|
|
6636
8189
|
}
|
|
6637
|
-
var bidPricingCommand =
|
|
8190
|
+
var bidPricingCommand = defineCommand37({
|
|
6638
8191
|
meta: {
|
|
6639
8192
|
name: "bid-pricing",
|
|
6640
8193
|
description: `Get LinkedIn's suggested bid range for a targeting + objective + cost type.
|
|
@@ -6684,40 +8237,40 @@ Examples:
|
|
|
6684
8237
|
});
|
|
6685
8238
|
|
|
6686
8239
|
// src/commands/ads/linkedin/campaign-groups.ts
|
|
6687
|
-
import { defineCommand as
|
|
8240
|
+
import { defineCommand as defineCommand39 } from "citty";
|
|
6688
8241
|
|
|
6689
8242
|
// src/commands/ads/linkedin/write-commands.ts
|
|
6690
|
-
import { defineCommand as
|
|
8243
|
+
import { defineCommand as defineCommand38 } from "citty";
|
|
6691
8244
|
|
|
6692
8245
|
// src/commands/ads/linkedin/write-shared.ts
|
|
6693
8246
|
import { createHash as createHash2 } from "crypto";
|
|
6694
|
-
import { readFileSync as
|
|
8247
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
6695
8248
|
function bareAccountId(args) {
|
|
6696
8249
|
const raw = resolveAccountIdArg(args);
|
|
6697
8250
|
return raw.replace(/^urn:li:sponsoredAccount:/, "").replace(/^sponsoredAccount:/, "");
|
|
6698
8251
|
}
|
|
6699
|
-
function
|
|
8252
|
+
function failWriteValidation2(message) {
|
|
6700
8253
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
6701
8254
|
process.exit(1);
|
|
6702
8255
|
}
|
|
6703
|
-
function
|
|
8256
|
+
function loadJsonFileArg2(path12) {
|
|
6704
8257
|
if (typeof path12 !== "string" || path12.length === 0) {
|
|
6705
8258
|
return {};
|
|
6706
8259
|
}
|
|
6707
8260
|
try {
|
|
6708
|
-
const parsed = JSON.parse(
|
|
8261
|
+
const parsed = JSON.parse(readFileSync7(path12, "utf8"));
|
|
6709
8262
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
6710
|
-
|
|
8263
|
+
failWriteValidation2(`${path12} must contain a JSON object`);
|
|
6711
8264
|
}
|
|
6712
8265
|
return parsed;
|
|
6713
8266
|
} catch (err) {
|
|
6714
8267
|
if (err instanceof SyntaxError) {
|
|
6715
|
-
|
|
8268
|
+
failWriteValidation2(`${path12} is not valid JSON: ${err.message}`);
|
|
6716
8269
|
}
|
|
6717
8270
|
throw err;
|
|
6718
8271
|
}
|
|
6719
8272
|
}
|
|
6720
|
-
function
|
|
8273
|
+
function mergePayload2(file, flags) {
|
|
6721
8274
|
const merged = { ...file };
|
|
6722
8275
|
for (const [key, value] of Object.entries(flags)) {
|
|
6723
8276
|
if (value !== void 0) {
|
|
@@ -6734,7 +8287,7 @@ function parseMoneyFlag(amount, currency, flag) {
|
|
|
6734
8287
|
return { amount: String(amount) };
|
|
6735
8288
|
}
|
|
6736
8289
|
if (typeof currency !== "string" || currency.length !== 3) {
|
|
6737
|
-
|
|
8290
|
+
failWriteValidation2(`${flag} got an invalid --currency (expected a 3-letter code like EUR)`);
|
|
6738
8291
|
}
|
|
6739
8292
|
return { amount: String(amount), currencyCode: currency.toUpperCase() };
|
|
6740
8293
|
}
|
|
@@ -6748,7 +8301,7 @@ function parseDateFlag(value, flag) {
|
|
|
6748
8301
|
}
|
|
6749
8302
|
const parsed = Date.parse(raw);
|
|
6750
8303
|
if (Number.isNaN(parsed)) {
|
|
6751
|
-
|
|
8304
|
+
failWriteValidation2(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);
|
|
6752
8305
|
}
|
|
6753
8306
|
return parsed;
|
|
6754
8307
|
}
|
|
@@ -6763,7 +8316,7 @@ function parseOnOffFlag(value, flag) {
|
|
|
6763
8316
|
if (raw === "off" || raw === "false") {
|
|
6764
8317
|
return false;
|
|
6765
8318
|
}
|
|
6766
|
-
|
|
8319
|
+
failWriteValidation2(`${flag} must be on|off`);
|
|
6767
8320
|
}
|
|
6768
8321
|
function parseLocaleFlag(value) {
|
|
6769
8322
|
if (value === void 0 || value === null || value === "") {
|
|
@@ -6771,7 +8324,7 @@ function parseLocaleFlag(value) {
|
|
|
6771
8324
|
}
|
|
6772
8325
|
const match = /^([a-z]{2})[_-]([A-Za-z]{2})$/.exec(String(value));
|
|
6773
8326
|
if (!match) {
|
|
6774
|
-
|
|
8327
|
+
failWriteValidation2("--locale must look like en_US (language_COUNTRY)");
|
|
6775
8328
|
}
|
|
6776
8329
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
6777
8330
|
}
|
|
@@ -6779,10 +8332,10 @@ function loadTargetingFileArg(path12) {
|
|
|
6779
8332
|
if (typeof path12 !== "string" || path12.length === 0) {
|
|
6780
8333
|
return void 0;
|
|
6781
8334
|
}
|
|
6782
|
-
const parsed =
|
|
8335
|
+
const parsed = loadJsonFileArg2(path12);
|
|
6783
8336
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
6784
8337
|
if (!criteria.include) {
|
|
6785
|
-
|
|
8338
|
+
failWriteValidation2(
|
|
6786
8339
|
`${path12} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
6787
8340
|
);
|
|
6788
8341
|
}
|
|
@@ -6822,10 +8375,10 @@ function parseListFileArg(path12, maxRows) {
|
|
|
6822
8375
|
if (typeof path12 !== "string" || path12.length === 0) {
|
|
6823
8376
|
return void 0;
|
|
6824
8377
|
}
|
|
6825
|
-
const raw =
|
|
8378
|
+
const raw = readFileSync7(path12, "utf8");
|
|
6826
8379
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
6827
8380
|
if (lines.length < 2) {
|
|
6828
|
-
|
|
8381
|
+
failWriteValidation2(`${path12} needs a header row and at least one data row`);
|
|
6829
8382
|
}
|
|
6830
8383
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
6831
8384
|
const rows = [];
|
|
@@ -6844,7 +8397,7 @@ function parseListFileArg(path12, maxRows) {
|
|
|
6844
8397
|
}
|
|
6845
8398
|
}
|
|
6846
8399
|
if (rows.length > maxRows) {
|
|
6847
|
-
|
|
8400
|
+
failWriteValidation2(`${path12} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
6848
8401
|
}
|
|
6849
8402
|
return { columns, rows };
|
|
6850
8403
|
}
|
|
@@ -6880,10 +8433,10 @@ async function stageStatusChange(input) {
|
|
|
6880
8433
|
const payload = input.kind === "creative.update" ? { intendedStatus: input.status } : { status: input.status };
|
|
6881
8434
|
await stageOp({ kind: input.kind, accountId: input.accountId, target: input.target, payload });
|
|
6882
8435
|
}
|
|
6883
|
-
function
|
|
8436
|
+
function requireTarget2(args, entity) {
|
|
6884
8437
|
const target = args.id ?? args.target;
|
|
6885
8438
|
if (typeof target !== "string" || target.length === 0) {
|
|
6886
|
-
|
|
8439
|
+
failWriteValidation2(`pass the ${entity} id or URN as the positional argument`);
|
|
6887
8440
|
}
|
|
6888
8441
|
return target;
|
|
6889
8442
|
}
|
|
@@ -6902,7 +8455,7 @@ function runScheduleFromFlags(args) {
|
|
|
6902
8455
|
}
|
|
6903
8456
|
return { ...start !== void 0 ? { start } : {}, ...end !== void 0 ? { end } : {} };
|
|
6904
8457
|
}
|
|
6905
|
-
var campaignGroupsCreateCommand =
|
|
8458
|
+
var campaignGroupsCreateCommand = defineCommand38({
|
|
6906
8459
|
meta: {
|
|
6907
8460
|
name: "create",
|
|
6908
8461
|
description: `Stage a new campaign group. ${STAGED_NOTE}
|
|
@@ -6920,7 +8473,7 @@ Example: baker ads linkedin campaign-groups create --name "Q3 ABM" --start 2026-
|
|
|
6920
8473
|
},
|
|
6921
8474
|
run: async ({ args }) => {
|
|
6922
8475
|
const accountId = bareAccountId(args);
|
|
6923
|
-
const payload =
|
|
8476
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
6924
8477
|
name: args.name,
|
|
6925
8478
|
runSchedule: runScheduleFromFlags(args),
|
|
6926
8479
|
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
@@ -6929,7 +8482,7 @@ Example: baker ads linkedin campaign-groups create --name "Q3 ABM" --start 2026-
|
|
|
6929
8482
|
await stageOp({ kind: "campaignGroup.create", accountId, payload });
|
|
6930
8483
|
}
|
|
6931
8484
|
});
|
|
6932
|
-
var campaignGroupsUpdateCommand =
|
|
8485
|
+
var campaignGroupsUpdateCommand = defineCommand38({
|
|
6933
8486
|
meta: {
|
|
6934
8487
|
name: "update",
|
|
6935
8488
|
description: `Stage changes to an existing campaign group. ${STAGED_NOTE}
|
|
@@ -6949,7 +8502,7 @@ Example: baker ads linkedin campaign-groups update 635137195 --total-budget 8000
|
|
|
6949
8502
|
},
|
|
6950
8503
|
run: async ({ args }) => {
|
|
6951
8504
|
const accountId = bareAccountId(args);
|
|
6952
|
-
const payload =
|
|
8505
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
6953
8506
|
name: args.name,
|
|
6954
8507
|
runSchedule: runScheduleFromFlags(args),
|
|
6955
8508
|
totalBudget: parseMoneyFlag(args["total-budget"], args.currency, "--total-budget"),
|
|
@@ -6958,7 +8511,7 @@ Example: baker ads linkedin campaign-groups update 635137195 --total-budget 8000
|
|
|
6958
8511
|
await stageOp({
|
|
6959
8512
|
kind: "campaignGroup.update",
|
|
6960
8513
|
accountId,
|
|
6961
|
-
target:
|
|
8514
|
+
target: requireTarget2(args, "campaign group"),
|
|
6962
8515
|
payload
|
|
6963
8516
|
});
|
|
6964
8517
|
}
|
|
@@ -7007,7 +8560,7 @@ var campaignFlagArgs = {
|
|
|
7007
8560
|
status: { type: "string", description: "DRAFT|ACTIVE|PAUSED" },
|
|
7008
8561
|
file: { type: "string", description: "JSON file with the full payload; flags override file keys" }
|
|
7009
8562
|
};
|
|
7010
|
-
var campaignsCreateCommand =
|
|
8563
|
+
var campaignsCreateCommand = defineCommand38({
|
|
7011
8564
|
meta: {
|
|
7012
8565
|
name: "create",
|
|
7013
8566
|
description: `Stage a new campaign. ${STAGED_NOTE}
|
|
@@ -7017,14 +8570,14 @@ Example: baker ads linkedin campaigns create --name "ABM Tier-1" --group li_temp
|
|
|
7017
8570
|
args: campaignFlagArgs,
|
|
7018
8571
|
run: async ({ args }) => {
|
|
7019
8572
|
const accountId = bareAccountId(args);
|
|
7020
|
-
const payload =
|
|
8573
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), campaignPayloadFromFlags(args));
|
|
7021
8574
|
if (payload.locale === void 0) {
|
|
7022
8575
|
payload.locale = { country: "US", language: "en" };
|
|
7023
8576
|
}
|
|
7024
8577
|
await stageOp({ kind: "campaign.create", accountId, payload });
|
|
7025
8578
|
}
|
|
7026
8579
|
});
|
|
7027
|
-
var campaignsUpdateCommand =
|
|
8580
|
+
var campaignsUpdateCommand = defineCommand38({
|
|
7028
8581
|
meta: {
|
|
7029
8582
|
name: "update",
|
|
7030
8583
|
description: `Stage changes to an existing campaign (budget, bid, targeting, flags, schedule, status). ${STAGED_NOTE}
|
|
@@ -7042,18 +8595,18 @@ Example: baker ads linkedin campaigns update 123456 --daily-budget 100 --currenc
|
|
|
7042
8595
|
flags.type = void 0;
|
|
7043
8596
|
flags.locale = void 0;
|
|
7044
8597
|
flags.associatedEntity = void 0;
|
|
7045
|
-
const payload =
|
|
8598
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), flags);
|
|
7046
8599
|
await stageOp({
|
|
7047
8600
|
kind: "campaign.update",
|
|
7048
8601
|
accountId,
|
|
7049
|
-
target:
|
|
8602
|
+
target: requireTarget2(args, "campaign"),
|
|
7050
8603
|
payload
|
|
7051
8604
|
});
|
|
7052
8605
|
}
|
|
7053
8606
|
});
|
|
7054
8607
|
function statusSugarCommand(entity, kind, name) {
|
|
7055
8608
|
const status = name === "pause" ? "PAUSED" : name === "resume" ? "ACTIVE" : "ARCHIVED";
|
|
7056
|
-
return
|
|
8609
|
+
return defineCommand38({
|
|
7057
8610
|
meta: {
|
|
7058
8611
|
name,
|
|
7059
8612
|
description: `Stage a status change to ${status}. ${STAGED_NOTE}
|
|
@@ -7067,7 +8620,7 @@ Example: baker ads linkedin ${entity} ${name} 123456`
|
|
|
7067
8620
|
await stageStatusChange({
|
|
7068
8621
|
kind,
|
|
7069
8622
|
accountId: bareAccountId(args),
|
|
7070
|
-
target:
|
|
8623
|
+
target: requireTarget2(args, entity.replace(/-/g, " ").replace(/s$/, "")),
|
|
7071
8624
|
status
|
|
7072
8625
|
});
|
|
7073
8626
|
}
|
|
@@ -7081,7 +8634,7 @@ var campaignGroupsResumeCommand = statusSugarCommand("campaign-groups", "campaig
|
|
|
7081
8634
|
var creativesPauseCommand = statusSugarCommand("creatives", "creative.update", "pause");
|
|
7082
8635
|
var creativesResumeCommand = statusSugarCommand("creatives", "creative.update", "resume");
|
|
7083
8636
|
function duplicateCommand(entity, cliGroup) {
|
|
7084
|
-
return
|
|
8637
|
+
return defineCommand38({
|
|
7085
8638
|
meta: {
|
|
7086
8639
|
name: "duplicate",
|
|
7087
8640
|
description: `Stage a copy of an existing ${entity} as a new DRAFT create (playbook: duplicate, never link-to-original). ${STAGED_NOTE}
|
|
@@ -7096,14 +8649,14 @@ Example: baker ads linkedin ${cliGroup} duplicate 123456 --name "New variant"`
|
|
|
7096
8649
|
run: async ({ args }) => {
|
|
7097
8650
|
try {
|
|
7098
8651
|
const chatId = requireChatId();
|
|
7099
|
-
const overrides =
|
|
8652
|
+
const overrides = mergePayload2(loadJsonFileArg2(args.file), { name: args.name });
|
|
7100
8653
|
const response = await apiPost(
|
|
7101
8654
|
"/api/ads/linkedin/draft/duplicate",
|
|
7102
8655
|
{
|
|
7103
8656
|
chatId,
|
|
7104
8657
|
accountId: bareAccountId(args),
|
|
7105
8658
|
entity,
|
|
7106
|
-
sourceId:
|
|
8659
|
+
sourceId: requireTarget2(args, entity),
|
|
7107
8660
|
...Object.keys(overrides).length > 0 ? { overrides } : {}
|
|
7108
8661
|
}
|
|
7109
8662
|
);
|
|
@@ -7116,7 +8669,7 @@ Example: baker ads linkedin ${cliGroup} duplicate 123456 --name "New variant"`
|
|
|
7116
8669
|
}
|
|
7117
8670
|
var campaignsDuplicateCommand = duplicateCommand("campaign", "campaigns");
|
|
7118
8671
|
var campaignGroupsDuplicateCommand = duplicateCommand("campaignGroup", "campaign-groups");
|
|
7119
|
-
var creativesDuplicateCommand =
|
|
8672
|
+
var creativesDuplicateCommand = defineCommand38({
|
|
7120
8673
|
meta: {
|
|
7121
8674
|
name: "duplicate",
|
|
7122
8675
|
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}
|
|
@@ -7154,10 +8707,10 @@ Examples:
|
|
|
7154
8707
|
run: async ({ args }) => {
|
|
7155
8708
|
try {
|
|
7156
8709
|
const chatId = requireChatId();
|
|
7157
|
-
const file =
|
|
8710
|
+
const file = loadJsonFileArg2(args.file);
|
|
7158
8711
|
const fileContent = file.content !== null && typeof file.content === "object" && !Array.isArray(file.content) ? file.content : {};
|
|
7159
8712
|
const content = { ...fileContent, ...creativeContentPatch(args) };
|
|
7160
|
-
const overrides =
|
|
8713
|
+
const overrides = mergePayload2(file, {
|
|
7161
8714
|
campaign: args.campaign,
|
|
7162
8715
|
intendedStatus: args["intended-status"] ? String(args["intended-status"]).toUpperCase() : void 0,
|
|
7163
8716
|
content: Object.keys(content).length > 0 ? content : void 0
|
|
@@ -7168,7 +8721,7 @@ Examples:
|
|
|
7168
8721
|
chatId,
|
|
7169
8722
|
accountId: bareAccountId(args),
|
|
7170
8723
|
entity: "creative",
|
|
7171
|
-
sourceId:
|
|
8724
|
+
sourceId: requireTarget2(args, "creative"),
|
|
7172
8725
|
...Object.keys(overrides).length > 0 ? { overrides } : {},
|
|
7173
8726
|
...args.replace ? { replace: true } : {}
|
|
7174
8727
|
}
|
|
@@ -7193,7 +8746,7 @@ var CREATIVE_FORMATS = [
|
|
|
7193
8746
|
"event",
|
|
7194
8747
|
"article"
|
|
7195
8748
|
];
|
|
7196
|
-
var creativesCreateCommand =
|
|
8749
|
+
var creativesCreateCommand = defineCommand38({
|
|
7197
8750
|
meta: {
|
|
7198
8751
|
name: "create",
|
|
7199
8752
|
description: `Stage a new creative (ad). ${STAGED_NOTE}
|
|
@@ -7229,13 +8782,13 @@ Examples:
|
|
|
7229
8782
|
run: async ({ args }) => {
|
|
7230
8783
|
const accountId = bareAccountId(args);
|
|
7231
8784
|
if (!args.campaign) {
|
|
7232
|
-
|
|
8785
|
+
failWriteValidation2("--campaign is required (id, URN, or li_temp_* ref)");
|
|
7233
8786
|
}
|
|
7234
8787
|
const format = args.format ? String(args.format) : void 0;
|
|
7235
8788
|
if (!format || !CREATIVE_FORMATS.includes(format)) {
|
|
7236
|
-
|
|
8789
|
+
failWriteValidation2(`--format must be one of ${CREATIVE_FORMATS.join("|")}`);
|
|
7237
8790
|
}
|
|
7238
|
-
const content =
|
|
8791
|
+
const content = mergePayload2(loadJsonFileArg2(args.file), {
|
|
7239
8792
|
format,
|
|
7240
8793
|
commentary: args.intro,
|
|
7241
8794
|
imageId: args["image-id"],
|
|
@@ -7294,7 +8847,7 @@ function creativeContentPatch(args) {
|
|
|
7294
8847
|
}
|
|
7295
8848
|
return patch;
|
|
7296
8849
|
}
|
|
7297
|
-
var creativesUpdateCommand =
|
|
8850
|
+
var creativesUpdateCommand = defineCommand38({
|
|
7298
8851
|
meta: {
|
|
7299
8852
|
name: "update",
|
|
7300
8853
|
description: `Stage changes to an existing creative, or amend a creative staged in this chat by passing its li_temp_* ref. ${STAGED_NOTE}
|
|
@@ -7326,13 +8879,13 @@ Examples:
|
|
|
7326
8879
|
},
|
|
7327
8880
|
run: async ({ args }) => {
|
|
7328
8881
|
const accountId = bareAccountId(args);
|
|
7329
|
-
const target =
|
|
7330
|
-
const file =
|
|
8882
|
+
const target = requireTarget2(args, "creative");
|
|
8883
|
+
const file = loadJsonFileArg2(args.file);
|
|
7331
8884
|
const contentPatch = creativeContentPatch(args);
|
|
7332
8885
|
const intendedStatus = args["intended-status"] ? String(args["intended-status"]).toUpperCase() : void 0;
|
|
7333
8886
|
const fileContent = file.content !== null && typeof file.content === "object" && !Array.isArray(file.content) ? file.content : {};
|
|
7334
8887
|
const content = { ...fileContent, ...contentPatch };
|
|
7335
|
-
const payload =
|
|
8888
|
+
const payload = mergePayload2(file, {
|
|
7336
8889
|
intendedStatus,
|
|
7337
8890
|
name: args.name,
|
|
7338
8891
|
content: Object.keys(content).length > 0 ? content : void 0
|
|
@@ -7342,7 +8895,7 @@ Examples:
|
|
|
7342
8895
|
});
|
|
7343
8896
|
var AUDIENCE_TYPES2 = ["company-list", "user-list", "retargeting", "engagement"];
|
|
7344
8897
|
var INLINE_ROWS_MAX = 1e4;
|
|
7345
|
-
var audiencesCreateCommand =
|
|
8898
|
+
var audiencesCreateCommand = defineCommand38({
|
|
7346
8899
|
meta: {
|
|
7347
8900
|
name: "create",
|
|
7348
8901
|
description: `Stage a new matched audience. ${STAGED_NOTE}
|
|
@@ -7359,7 +8912,7 @@ Example: baker ads linkedin audiences create --name "ABM Tier-1" --type company-
|
|
|
7359
8912
|
run: async ({ args }) => {
|
|
7360
8913
|
const accountId = bareAccountId(args);
|
|
7361
8914
|
const list = parseListFileArg(args["list-file"], INLINE_ROWS_MAX);
|
|
7362
|
-
const raw = args.file ?
|
|
8915
|
+
const raw = args.file ? loadJsonFileArg2(args.file) : void 0;
|
|
7363
8916
|
await stageOp({
|
|
7364
8917
|
kind: "audience.create",
|
|
7365
8918
|
accountId,
|
|
@@ -7372,7 +8925,7 @@ Example: baker ads linkedin audiences create --name "ABM Tier-1" --type company-
|
|
|
7372
8925
|
});
|
|
7373
8926
|
}
|
|
7374
8927
|
});
|
|
7375
|
-
var audiencesUploadCommand =
|
|
8928
|
+
var audiencesUploadCommand = defineCommand38({
|
|
7376
8929
|
meta: {
|
|
7377
8930
|
name: "upload",
|
|
7378
8931
|
description: `Stage a list upload into an existing audience segment. ${STAGED_NOTE}
|
|
@@ -7387,20 +8940,20 @@ Example: baker ads linkedin audiences upload urn:li:dmpSegment:42 --list-file mo
|
|
|
7387
8940
|
const accountId = bareAccountId(args);
|
|
7388
8941
|
const list = parseListFileArg(args["list-file"], INLINE_ROWS_MAX);
|
|
7389
8942
|
if (!list) {
|
|
7390
|
-
|
|
8943
|
+
failWriteValidation2("--list-file is required");
|
|
7391
8944
|
}
|
|
7392
8945
|
await stageOp({
|
|
7393
8946
|
kind: "audience.uploadList",
|
|
7394
8947
|
accountId,
|
|
7395
8948
|
payload: {
|
|
7396
|
-
segment:
|
|
8949
|
+
segment: requireTarget2(args, "audience segment"),
|
|
7397
8950
|
listColumns: list.columns,
|
|
7398
8951
|
listRows: list.rows
|
|
7399
8952
|
}
|
|
7400
8953
|
});
|
|
7401
8954
|
}
|
|
7402
8955
|
});
|
|
7403
|
-
var
|
|
8956
|
+
var audiencesCommand2 = defineCommand38({
|
|
7404
8957
|
meta: {
|
|
7405
8958
|
name: "audiences",
|
|
7406
8959
|
description: "Stage LinkedIn matched-audience changes (create lists, upload rows). Staged until publish \u2014 never hits the API directly."
|
|
@@ -7410,7 +8963,7 @@ var audiencesCommand = defineCommand36({
|
|
|
7410
8963
|
upload: audiencesUploadCommand
|
|
7411
8964
|
}
|
|
7412
8965
|
});
|
|
7413
|
-
var conversionsCreateCommand =
|
|
8966
|
+
var conversionsCreateCommand = defineCommand38({
|
|
7414
8967
|
meta: {
|
|
7415
8968
|
name: "create",
|
|
7416
8969
|
description: `Stage a new conversion rule. ${STAGED_NOTE}
|
|
@@ -7429,7 +8982,7 @@ Example: baker ads linkedin conversions create --name "Demo booked" --type LEAD
|
|
|
7429
8982
|
},
|
|
7430
8983
|
run: async ({ args }) => {
|
|
7431
8984
|
const accountId = bareAccountId(args);
|
|
7432
|
-
const payload =
|
|
8985
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
7433
8986
|
name: args.name,
|
|
7434
8987
|
type: args.type ? String(args.type).toUpperCase() : void 0,
|
|
7435
8988
|
conversionMethod: args.method ? String(args.method).toUpperCase() : void 0,
|
|
@@ -7441,7 +8994,7 @@ Example: baker ads linkedin conversions create --name "Demo booked" --type LEAD
|
|
|
7441
8994
|
await stageOp({ kind: "conversion.create", accountId, payload });
|
|
7442
8995
|
}
|
|
7443
8996
|
});
|
|
7444
|
-
var conversionsUpdateCommand =
|
|
8997
|
+
var conversionsUpdateCommand = defineCommand38({
|
|
7445
8998
|
meta: {
|
|
7446
8999
|
name: "update",
|
|
7447
9000
|
description: `Stage changes to a conversion rule (windows, name, enabled). ${STAGED_NOTE}
|
|
@@ -7459,7 +9012,7 @@ Example: baker ads linkedin conversions update 104988516 --post-click-window 30
|
|
|
7459
9012
|
},
|
|
7460
9013
|
run: async ({ args }) => {
|
|
7461
9014
|
const accountId = bareAccountId(args);
|
|
7462
|
-
const payload =
|
|
9015
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), {
|
|
7463
9016
|
name: args.name,
|
|
7464
9017
|
postClickAttributionWindowSize: args["post-click-window"] ? Number(args["post-click-window"]) : void 0,
|
|
7465
9018
|
viewThroughAttributionWindowSize: args["view-window"] ? Number(args["view-window"]) : void 0,
|
|
@@ -7469,12 +9022,12 @@ Example: baker ads linkedin conversions update 104988516 --post-click-window 30
|
|
|
7469
9022
|
await stageOp({
|
|
7470
9023
|
kind: "conversion.update",
|
|
7471
9024
|
accountId,
|
|
7472
|
-
target:
|
|
9025
|
+
target: requireTarget2(args, "conversion rule"),
|
|
7473
9026
|
payload
|
|
7474
9027
|
});
|
|
7475
9028
|
}
|
|
7476
9029
|
});
|
|
7477
|
-
var leadFormsCreateCommand =
|
|
9030
|
+
var leadFormsCreateCommand = defineCommand38({
|
|
7478
9031
|
meta: {
|
|
7479
9032
|
name: "create",
|
|
7480
9033
|
description: `Stage a new Lead Gen Form from a JSON file. ${STAGED_NOTE}
|
|
@@ -7487,11 +9040,11 @@ The file needs: name, headline (\u226460), privacyPolicyUrl, questions[] (\u2264
|
|
|
7487
9040
|
},
|
|
7488
9041
|
run: async ({ args }) => {
|
|
7489
9042
|
const accountId = bareAccountId(args);
|
|
7490
|
-
const payload =
|
|
9043
|
+
const payload = mergePayload2(loadJsonFileArg2(args.file), { name: args.name });
|
|
7491
9044
|
await stageOp({ kind: "leadForm.create", accountId, payload });
|
|
7492
9045
|
}
|
|
7493
9046
|
});
|
|
7494
|
-
var leadFormsUpdateCommand =
|
|
9047
|
+
var leadFormsUpdateCommand = defineCommand38({
|
|
7495
9048
|
meta: {
|
|
7496
9049
|
name: "update",
|
|
7497
9050
|
description: `Stage changes to a Lead Gen Form from a JSON file. ${STAGED_NOTE}`
|
|
@@ -7504,16 +9057,16 @@ var leadFormsUpdateCommand = defineCommand36({
|
|
|
7504
9057
|
},
|
|
7505
9058
|
run: async ({ args }) => {
|
|
7506
9059
|
const accountId = bareAccountId(args);
|
|
7507
|
-
const payload =
|
|
9060
|
+
const payload = mergePayload2({ raw: loadJsonFileArg2(args.file) }, { name: args.name });
|
|
7508
9061
|
await stageOp({
|
|
7509
9062
|
kind: "leadForm.update",
|
|
7510
9063
|
accountId,
|
|
7511
|
-
target:
|
|
9064
|
+
target: requireTarget2(args, "lead form"),
|
|
7512
9065
|
payload
|
|
7513
9066
|
});
|
|
7514
9067
|
}
|
|
7515
9068
|
});
|
|
7516
|
-
var leadFormsCommand =
|
|
9069
|
+
var leadFormsCommand = defineCommand38({
|
|
7517
9070
|
meta: {
|
|
7518
9071
|
name: "lead-forms",
|
|
7519
9072
|
description: "Stage LinkedIn Lead Gen Form changes (file-first). Staged until publish \u2014 never hits the API directly."
|
|
@@ -7525,7 +9078,7 @@ var leadFormsCommand = defineCommand36({
|
|
|
7525
9078
|
});
|
|
7526
9079
|
|
|
7527
9080
|
// src/commands/ads/linkedin/campaign-groups.ts
|
|
7528
|
-
var campaignGroupsCommand =
|
|
9081
|
+
var campaignGroupsCommand = defineCommand39({
|
|
7529
9082
|
meta: {
|
|
7530
9083
|
name: "campaign-groups",
|
|
7531
9084
|
description: `List LinkedIn campaign groups, or stage writes (create/update/pause/resume/duplicate).
|
|
@@ -7576,8 +9129,8 @@ Examples:
|
|
|
7576
9129
|
});
|
|
7577
9130
|
|
|
7578
9131
|
// src/commands/ads/linkedin/campaigns.ts
|
|
7579
|
-
import { defineCommand as
|
|
7580
|
-
var
|
|
9132
|
+
import { defineCommand as defineCommand40 } from "citty";
|
|
9133
|
+
var campaignsCommand2 = defineCommand40({
|
|
7581
9134
|
meta: {
|
|
7582
9135
|
name: "campaigns",
|
|
7583
9136
|
description: `List LinkedIn campaigns, or stage writes (create/update/pause/resume/archive/duplicate).
|
|
@@ -7638,8 +9191,8 @@ Examples:
|
|
|
7638
9191
|
});
|
|
7639
9192
|
|
|
7640
9193
|
// src/commands/ads/linkedin/conversation.ts
|
|
7641
|
-
import { defineCommand as
|
|
7642
|
-
var conversationCommand =
|
|
9194
|
+
import { defineCommand as defineCommand41 } from "citty";
|
|
9195
|
+
var conversationCommand = defineCommand41({
|
|
7643
9196
|
meta: {
|
|
7644
9197
|
name: "conversation",
|
|
7645
9198
|
description: `Per-button click rates inside Sponsored Messaging / Conversation Ads.
|
|
@@ -7702,7 +9255,7 @@ Examples:
|
|
|
7702
9255
|
});
|
|
7703
9256
|
|
|
7704
9257
|
// src/commands/ads/linkedin/conversions.ts
|
|
7705
|
-
import { defineCommand as
|
|
9258
|
+
import { defineCommand as defineCommand42 } from "citty";
|
|
7706
9259
|
var DAY_MS3 = 864e5;
|
|
7707
9260
|
function healthOf(rules) {
|
|
7708
9261
|
const enabled = rules.filter((r) => r.enabled !== false);
|
|
@@ -7728,7 +9281,7 @@ function healthOf(rules) {
|
|
|
7728
9281
|
wrongLeadDedup: wrongDedup
|
|
7729
9282
|
};
|
|
7730
9283
|
}
|
|
7731
|
-
var listCmd =
|
|
9284
|
+
var listCmd = defineCommand42({
|
|
7732
9285
|
meta: {
|
|
7733
9286
|
name: "list",
|
|
7734
9287
|
description: `List conversion rules on the account.`
|
|
@@ -7756,7 +9309,7 @@ var listCmd = defineCommand40({
|
|
|
7756
9309
|
}
|
|
7757
9310
|
}
|
|
7758
9311
|
});
|
|
7759
|
-
var healthCmd =
|
|
9312
|
+
var healthCmd = defineCommand42({
|
|
7760
9313
|
meta: {
|
|
7761
9314
|
name: "health",
|
|
7762
9315
|
description: `5-point Insight Tag / CAPI health check (playbook \xA707).
|
|
@@ -7786,7 +9339,7 @@ Surfaces:
|
|
|
7786
9339
|
}
|
|
7787
9340
|
}
|
|
7788
9341
|
});
|
|
7789
|
-
var
|
|
9342
|
+
var conversionsCommand2 = defineCommand42({
|
|
7790
9343
|
meta: {
|
|
7791
9344
|
name: "conversions",
|
|
7792
9345
|
description: `Conversion rules \u2014 Insight Tag and Conversions API.
|
|
@@ -7805,8 +9358,8 @@ Subcommands:
|
|
|
7805
9358
|
});
|
|
7806
9359
|
|
|
7807
9360
|
// src/commands/ads/linkedin/creatives.ts
|
|
7808
|
-
import { defineCommand as
|
|
7809
|
-
var creativesCommand =
|
|
9361
|
+
import { defineCommand as defineCommand43 } from "citty";
|
|
9362
|
+
var creativesCommand = defineCommand43({
|
|
7810
9363
|
meta: {
|
|
7811
9364
|
name: "creatives",
|
|
7812
9365
|
description: `List LinkedIn creatives (ads), or stage writes (create/update/pause/resume/duplicate).
|
|
@@ -7865,7 +9418,7 @@ Examples:
|
|
|
7865
9418
|
});
|
|
7866
9419
|
|
|
7867
9420
|
// src/commands/ads/linkedin/demographics.ts
|
|
7868
|
-
import { defineCommand as
|
|
9421
|
+
import { defineCommand as defineCommand44 } from "citty";
|
|
7869
9422
|
var DEFAULT_PIVOTS = ["job-title", "company", "industry", "seniority", "job-function", "company-size"];
|
|
7870
9423
|
function numberOf2(v) {
|
|
7871
9424
|
if (typeof v === "number") return Number.isFinite(v) ? v : 0;
|
|
@@ -7878,7 +9431,7 @@ function numberOf2(v) {
|
|
|
7878
9431
|
function topByImpressions(rows, limit) {
|
|
7879
9432
|
return [...rows].sort((a, b) => numberOf2(b.impressions) - numberOf2(a.impressions)).slice(0, limit);
|
|
7880
9433
|
}
|
|
7881
|
-
var demographicsCommand =
|
|
9434
|
+
var demographicsCommand = defineCommand44({
|
|
7882
9435
|
meta: {
|
|
7883
9436
|
name: "demographics",
|
|
7884
9437
|
description: `Sweep all firmographic pivots in one command \u2014 LinkedIn's superpower.
|
|
@@ -7975,7 +9528,7 @@ function resolveRange(args) {
|
|
|
7975
9528
|
}
|
|
7976
9529
|
|
|
7977
9530
|
// src/commands/ads/linkedin/draft.ts
|
|
7978
|
-
import { defineCommand as
|
|
9531
|
+
import { defineCommand as defineCommand45 } from "citty";
|
|
7979
9532
|
async function listDraft() {
|
|
7980
9533
|
try {
|
|
7981
9534
|
const chatId = requireChatId();
|
|
@@ -7987,14 +9540,14 @@ async function listDraft() {
|
|
|
7987
9540
|
handleLinkedinError(err);
|
|
7988
9541
|
}
|
|
7989
9542
|
}
|
|
7990
|
-
var listCommand3 =
|
|
9543
|
+
var listCommand3 = defineCommand45({
|
|
7991
9544
|
meta: {
|
|
7992
9545
|
name: "list",
|
|
7993
9546
|
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"
|
|
7994
9547
|
},
|
|
7995
9548
|
run: listDraft
|
|
7996
9549
|
});
|
|
7997
|
-
var removeCommand2 =
|
|
9550
|
+
var removeCommand2 = defineCommand45({
|
|
7998
9551
|
meta: {
|
|
7999
9552
|
name: "remove",
|
|
8000
9553
|
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"
|
|
@@ -8019,7 +9572,7 @@ var removeCommand2 = defineCommand43({
|
|
|
8019
9572
|
}
|
|
8020
9573
|
}
|
|
8021
9574
|
});
|
|
8022
|
-
var clearCommand2 =
|
|
9575
|
+
var clearCommand2 = defineCommand45({
|
|
8023
9576
|
meta: {
|
|
8024
9577
|
name: "clear",
|
|
8025
9578
|
description: "Discard ALL staged LinkedIn ops in this chat's draft \u2014 nothing will apply on publish. Example: baker ads linkedin draft clear"
|
|
@@ -8036,7 +9589,7 @@ var clearCommand2 = defineCommand43({
|
|
|
8036
9589
|
}
|
|
8037
9590
|
}
|
|
8038
9591
|
});
|
|
8039
|
-
var linkedinDraftCommand =
|
|
9592
|
+
var linkedinDraftCommand = defineCommand45({
|
|
8040
9593
|
meta: {
|
|
8041
9594
|
name: "draft",
|
|
8042
9595
|
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."
|
|
@@ -8050,8 +9603,8 @@ var linkedinDraftCommand = defineCommand43({
|
|
|
8050
9603
|
});
|
|
8051
9604
|
|
|
8052
9605
|
// src/commands/ads/linkedin/facets.ts
|
|
8053
|
-
import { defineCommand as
|
|
8054
|
-
var listCmd2 =
|
|
9606
|
+
import { defineCommand as defineCommand46 } from "citty";
|
|
9607
|
+
var listCmd2 = defineCommand46({
|
|
8055
9608
|
meta: {
|
|
8056
9609
|
name: "list",
|
|
8057
9610
|
description: `List every targeting facet LinkedIn supports.
|
|
@@ -8079,7 +9632,7 @@ seniorities, titles, employers, growthRate, companyCategory, skills, etc.).`
|
|
|
8079
9632
|
}
|
|
8080
9633
|
}
|
|
8081
9634
|
});
|
|
8082
|
-
var valuesCmd =
|
|
9635
|
+
var valuesCmd = defineCommand46({
|
|
8083
9636
|
meta: {
|
|
8084
9637
|
name: "values",
|
|
8085
9638
|
description: `Look up entity values for a single facet \u2014 full list or typeahead search.
|
|
@@ -8120,7 +9673,7 @@ or the full URN (urn:li:adTargetingFacet:industries).`
|
|
|
8120
9673
|
}
|
|
8121
9674
|
}
|
|
8122
9675
|
});
|
|
8123
|
-
var facetsCommand =
|
|
9676
|
+
var facetsCommand = defineCommand46({
|
|
8124
9677
|
meta: {
|
|
8125
9678
|
name: "facets",
|
|
8126
9679
|
description: `LinkedIn targeting facets and entity lookup.
|
|
@@ -8137,8 +9690,8 @@ Subcommands:
|
|
|
8137
9690
|
});
|
|
8138
9691
|
|
|
8139
9692
|
// src/commands/ads/linkedin/forecast.ts
|
|
8140
|
-
import { readFileSync as
|
|
8141
|
-
import { defineCommand as
|
|
9693
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
9694
|
+
import { defineCommand as defineCommand47 } from "citty";
|
|
8142
9695
|
function loadTargeting3(args) {
|
|
8143
9696
|
const inline = args.targeting;
|
|
8144
9697
|
if (inline) {
|
|
@@ -8151,7 +9704,7 @@ function loadTargeting3(args) {
|
|
|
8151
9704
|
const file = args["targeting-file"];
|
|
8152
9705
|
if (file) {
|
|
8153
9706
|
try {
|
|
8154
|
-
return JSON.parse(
|
|
9707
|
+
return JSON.parse(readFileSync8(file, "utf-8"));
|
|
8155
9708
|
} catch (e) {
|
|
8156
9709
|
handleLinkedinError(
|
|
8157
9710
|
new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`)
|
|
@@ -8168,7 +9721,7 @@ function parseMoney(raw) {
|
|
|
8168
9721
|
}
|
|
8169
9722
|
return { amount: m[1] ?? "0", currencyCode: m[2] ?? "USD" };
|
|
8170
9723
|
}
|
|
8171
|
-
var forecastCommand =
|
|
9724
|
+
var forecastCommand = defineCommand47({
|
|
8172
9725
|
meta: {
|
|
8173
9726
|
name: "forecast",
|
|
8174
9727
|
description: `Forecast reach + impressions + clicks + spend for a hypothetical campaign.
|
|
@@ -8215,9 +9768,9 @@ Examples:
|
|
|
8215
9768
|
});
|
|
8216
9769
|
|
|
8217
9770
|
// src/commands/ads/linkedin/leads.ts
|
|
8218
|
-
import { defineCommand as
|
|
9771
|
+
import { defineCommand as defineCommand48 } from "citty";
|
|
8219
9772
|
var DAY_MS4 = 864e5;
|
|
8220
|
-
var leadsCommand =
|
|
9773
|
+
var leadsCommand = defineCommand48({
|
|
8221
9774
|
meta: {
|
|
8222
9775
|
name: "leads",
|
|
8223
9776
|
description: `List Lead Gen Form responses (playbook \xA707).
|
|
@@ -8277,7 +9830,7 @@ Examples:
|
|
|
8277
9830
|
});
|
|
8278
9831
|
|
|
8279
9832
|
// src/commands/ads/linkedin/resolve.ts
|
|
8280
|
-
import { defineCommand as
|
|
9833
|
+
import { defineCommand as defineCommand49 } from "citty";
|
|
8281
9834
|
function toOrgUrn(raw) {
|
|
8282
9835
|
const trimmed = raw.trim();
|
|
8283
9836
|
if (trimmed.length === 0) {
|
|
@@ -8288,7 +9841,7 @@ function toOrgUrn(raw) {
|
|
|
8288
9841
|
}
|
|
8289
9842
|
return /^\d+$/.test(trimmed) ? `urn:li:organization:${trimmed}` : null;
|
|
8290
9843
|
}
|
|
8291
|
-
var resolveCommand =
|
|
9844
|
+
var resolveCommand = defineCommand49({
|
|
8292
9845
|
meta: {
|
|
8293
9846
|
name: "resolve",
|
|
8294
9847
|
description: `Resolve organization URNs to company names.
|
|
@@ -8330,8 +9883,8 @@ couldn't be resolved \u2014 typically an org outside LinkedIn's targetable set.`
|
|
|
8330
9883
|
});
|
|
8331
9884
|
|
|
8332
9885
|
// src/commands/ads/linkedin/top-companies.ts
|
|
8333
|
-
import { defineCommand as
|
|
8334
|
-
var topCompaniesCommand =
|
|
9886
|
+
import { defineCommand as defineCommand50 } from "citty";
|
|
9887
|
+
var topCompaniesCommand = defineCommand50({
|
|
8335
9888
|
meta: {
|
|
8336
9889
|
name: "top-companies",
|
|
8337
9890
|
description: `Top companies whose employees saw / clicked / converted on a campaign.
|
|
@@ -8402,7 +9955,7 @@ Examples:
|
|
|
8402
9955
|
});
|
|
8403
9956
|
|
|
8404
9957
|
// src/commands/ads/linkedin/index.ts
|
|
8405
|
-
var linkedinCommand =
|
|
9958
|
+
var linkedinCommand = defineCommand51({
|
|
8406
9959
|
meta: {
|
|
8407
9960
|
name: "linkedin",
|
|
8408
9961
|
description: `LinkedIn Marketing API \u2014 AI-first command surface for B2B ad insights.
|
|
@@ -8447,9 +10000,9 @@ Account ID format:
|
|
|
8447
10000
|
accounts: accountsCommand2,
|
|
8448
10001
|
account: accountCommand,
|
|
8449
10002
|
"campaign-groups": campaignGroupsCommand,
|
|
8450
|
-
campaigns:
|
|
10003
|
+
campaigns: campaignsCommand2,
|
|
8451
10004
|
creatives: creativesCommand,
|
|
8452
|
-
audiences:
|
|
10005
|
+
audiences: audiencesCommand2,
|
|
8453
10006
|
"lead-forms": leadFormsCommand,
|
|
8454
10007
|
draft: linkedinDraftCommand,
|
|
8455
10008
|
analytics: analyticsCommand,
|
|
@@ -8461,17 +10014,17 @@ Account ID format:
|
|
|
8461
10014
|
"bid-pricing": bidPricingCommand,
|
|
8462
10015
|
forecast: forecastCommand,
|
|
8463
10016
|
leads: leadsCommand,
|
|
8464
|
-
conversions:
|
|
10017
|
+
conversions: conversionsCommand2,
|
|
8465
10018
|
conversation: conversationCommand,
|
|
8466
10019
|
audit: auditCommand
|
|
8467
10020
|
}
|
|
8468
10021
|
});
|
|
8469
10022
|
|
|
8470
10023
|
// src/commands/ads/meta/index.ts
|
|
8471
|
-
import { defineCommand as
|
|
10024
|
+
import { defineCommand as defineCommand64 } from "citty";
|
|
8472
10025
|
|
|
8473
10026
|
// src/commands/ads/meta/account.ts
|
|
8474
|
-
import { defineCommand as
|
|
10027
|
+
import { defineCommand as defineCommand52 } from "citty";
|
|
8475
10028
|
|
|
8476
10029
|
// src/commands/ads/meta/shared.ts
|
|
8477
10030
|
var DAY_MS5 = 864e5;
|
|
@@ -8550,7 +10103,7 @@ function resolveEffectiveStatus(args) {
|
|
|
8550
10103
|
}
|
|
8551
10104
|
|
|
8552
10105
|
// src/commands/ads/meta/account.ts
|
|
8553
|
-
var accountCommand2 =
|
|
10106
|
+
var accountCommand2 = defineCommand52({
|
|
8554
10107
|
meta: {
|
|
8555
10108
|
name: "account",
|
|
8556
10109
|
description: `Show single Meta ad account detail (currency, timezone, balance, business).
|
|
@@ -8577,8 +10130,8 @@ Examples:
|
|
|
8577
10130
|
});
|
|
8578
10131
|
|
|
8579
10132
|
// src/commands/ads/meta/accounts.ts
|
|
8580
|
-
import { defineCommand as
|
|
8581
|
-
var accountsCommand3 =
|
|
10133
|
+
import { defineCommand as defineCommand53 } from "citty";
|
|
10134
|
+
var accountsCommand3 = defineCommand53({
|
|
8582
10135
|
meta: {
|
|
8583
10136
|
name: "accounts",
|
|
8584
10137
|
description: `List Meta ad accounts in this company's connected scope.
|
|
@@ -8626,8 +10179,8 @@ Examples:
|
|
|
8626
10179
|
});
|
|
8627
10180
|
|
|
8628
10181
|
// src/commands/ads/meta/activities.ts
|
|
8629
|
-
import { defineCommand as
|
|
8630
|
-
var activitiesCommand =
|
|
10182
|
+
import { defineCommand as defineCommand54 } from "citty";
|
|
10183
|
+
var activitiesCommand = defineCommand54({
|
|
8631
10184
|
meta: {
|
|
8632
10185
|
name: "activities",
|
|
8633
10186
|
description: `Audit log of recent ad-account changes (created, paused, edited). Default lookback 7 days,
|
|
@@ -8664,8 +10217,8 @@ Examples:
|
|
|
8664
10217
|
});
|
|
8665
10218
|
|
|
8666
10219
|
// src/commands/ads/meta/ads.ts
|
|
8667
|
-
import { defineCommand as
|
|
8668
|
-
var adsListCommand =
|
|
10220
|
+
import { defineCommand as defineCommand55 } from "citty";
|
|
10221
|
+
var adsListCommand = defineCommand55({
|
|
8669
10222
|
meta: {
|
|
8670
10223
|
name: "ads",
|
|
8671
10224
|
description: `List ads in a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -8713,8 +10266,8 @@ Examples:
|
|
|
8713
10266
|
});
|
|
8714
10267
|
|
|
8715
10268
|
// src/commands/ads/meta/adsets.ts
|
|
8716
|
-
import { defineCommand as
|
|
8717
|
-
var adsetsCommand =
|
|
10269
|
+
import { defineCommand as defineCommand56 } from "citty";
|
|
10270
|
+
var adsetsCommand = defineCommand56({
|
|
8718
10271
|
meta: {
|
|
8719
10272
|
name: "adsets",
|
|
8720
10273
|
description: `List ad sets in a Meta ad account, optionally scoped to one campaign. Defaults to ACTIVE only.
|
|
@@ -8756,8 +10309,8 @@ Examples:
|
|
|
8756
10309
|
});
|
|
8757
10310
|
|
|
8758
10311
|
// src/commands/ads/meta/audiences.ts
|
|
8759
|
-
import { defineCommand as
|
|
8760
|
-
var
|
|
10312
|
+
import { defineCommand as defineCommand57 } from "citty";
|
|
10313
|
+
var audiencesCommand3 = defineCommand57({
|
|
8761
10314
|
meta: {
|
|
8762
10315
|
name: "audiences",
|
|
8763
10316
|
description: `List custom audiences for a Meta ad account. Includes lookalikes, website-pixel audiences,
|
|
@@ -8792,8 +10345,8 @@ Examples:
|
|
|
8792
10345
|
});
|
|
8793
10346
|
|
|
8794
10347
|
// src/commands/ads/meta/businesses.ts
|
|
8795
|
-
import { defineCommand as
|
|
8796
|
-
var businessesCommand =
|
|
10348
|
+
import { defineCommand as defineCommand58 } from "citty";
|
|
10349
|
+
var businessesCommand = defineCommand58({
|
|
8797
10350
|
meta: {
|
|
8798
10351
|
name: "businesses",
|
|
8799
10352
|
description: `List Meta Business Manager accounts the connected user has access to. Required for ad-studies and product-catalogs commands.
|
|
@@ -8823,8 +10376,8 @@ Examples:
|
|
|
8823
10376
|
});
|
|
8824
10377
|
|
|
8825
10378
|
// src/commands/ads/meta/campaigns.ts
|
|
8826
|
-
import { defineCommand as
|
|
8827
|
-
var
|
|
10379
|
+
import { defineCommand as defineCommand59 } from "citty";
|
|
10380
|
+
var campaignsCommand3 = defineCommand59({
|
|
8828
10381
|
meta: {
|
|
8829
10382
|
name: "campaigns",
|
|
8830
10383
|
description: `List campaigns for a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
|
|
@@ -8868,8 +10421,8 @@ Examples:
|
|
|
8868
10421
|
});
|
|
8869
10422
|
|
|
8870
10423
|
// src/commands/ads/meta/creatives.ts
|
|
8871
|
-
import { defineCommand as
|
|
8872
|
-
var creativesCommand2 =
|
|
10424
|
+
import { defineCommand as defineCommand60 } from "citty";
|
|
10425
|
+
var creativesCommand2 = defineCommand60({
|
|
8873
10426
|
meta: {
|
|
8874
10427
|
name: "creatives",
|
|
8875
10428
|
description: `List ad creatives in an account, or fetch a single creative by ID.
|
|
@@ -8913,7 +10466,7 @@ Examples:
|
|
|
8913
10466
|
});
|
|
8914
10467
|
|
|
8915
10468
|
// src/commands/ads/meta/insights.ts
|
|
8916
|
-
import { defineCommand as
|
|
10469
|
+
import { defineCommand as defineCommand61 } from "citty";
|
|
8917
10470
|
|
|
8918
10471
|
// src/commands/ads/meta/presets.ts
|
|
8919
10472
|
var INSIGHTS_INTENTS = {
|
|
@@ -9118,7 +10671,7 @@ function sortRowsBySpendDesc(rows) {
|
|
|
9118
10671
|
return sb - sa;
|
|
9119
10672
|
});
|
|
9120
10673
|
}
|
|
9121
|
-
var insightsCommand =
|
|
10674
|
+
var insightsCommand = defineCommand61({
|
|
9122
10675
|
meta: {
|
|
9123
10676
|
name: "insights",
|
|
9124
10677
|
description: `Performance reporting \u2014 the main Meta tool for AI agents.
|
|
@@ -9219,8 +10772,8 @@ Async is automatic for heavy queries; pass --async to force it, or --no-async to
|
|
|
9219
10772
|
});
|
|
9220
10773
|
|
|
9221
10774
|
// src/commands/ads/meta/pixels.ts
|
|
9222
|
-
import { defineCommand as
|
|
9223
|
-
var pixelsCommand =
|
|
10775
|
+
import { defineCommand as defineCommand62 } from "citty";
|
|
10776
|
+
var pixelsCommand = defineCommand62({
|
|
9224
10777
|
meta: {
|
|
9225
10778
|
name: "pixels",
|
|
9226
10779
|
description: `List Meta Pixels for an ad account, or fetch firing stats for one pixel.
|
|
@@ -9291,7 +10844,7 @@ function emit(data, args) {
|
|
|
9291
10844
|
|
|
9292
10845
|
// src/commands/ads/meta/preview.ts
|
|
9293
10846
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
9294
|
-
import { defineCommand as
|
|
10847
|
+
import { defineCommand as defineCommand63 } from "citty";
|
|
9295
10848
|
var VALID_AD_FORMATS = [
|
|
9296
10849
|
"DESKTOP_FEED_STANDARD",
|
|
9297
10850
|
"MOBILE_FEED_STANDARD",
|
|
@@ -9325,7 +10878,7 @@ var VALID_AD_FORMATS = [
|
|
|
9325
10878
|
"MARKETPLACE_MOBILE",
|
|
9326
10879
|
"BIZ_DISCO_FEED_MOBILE"
|
|
9327
10880
|
];
|
|
9328
|
-
var previewCommand =
|
|
10881
|
+
var previewCommand = defineCommand63({
|
|
9329
10882
|
meta: {
|
|
9330
10883
|
name: "preview",
|
|
9331
10884
|
description: `Generate a Meta-hosted preview iframe for a creative or ad. Returns iframe HTML which you
|
|
@@ -9372,7 +10925,7 @@ Examples:
|
|
|
9372
10925
|
});
|
|
9373
10926
|
|
|
9374
10927
|
// src/commands/ads/meta/index.ts
|
|
9375
|
-
var metaCommand =
|
|
10928
|
+
var metaCommand = defineCommand64({
|
|
9376
10929
|
meta: {
|
|
9377
10930
|
name: "meta",
|
|
9378
10931
|
description: `Meta Marketing API \u2014 AI-first command surface (Facebook + Instagram ads).
|
|
@@ -9411,11 +10964,11 @@ Audit & review:
|
|
|
9411
10964
|
accounts: accountsCommand3,
|
|
9412
10965
|
account: accountCommand2,
|
|
9413
10966
|
businesses: businessesCommand,
|
|
9414
|
-
campaigns:
|
|
10967
|
+
campaigns: campaignsCommand3,
|
|
9415
10968
|
adsets: adsetsCommand,
|
|
9416
10969
|
ads: adsListCommand,
|
|
9417
10970
|
creatives: creativesCommand2,
|
|
9418
|
-
audiences:
|
|
10971
|
+
audiences: audiencesCommand3,
|
|
9419
10972
|
pixels: pixelsCommand,
|
|
9420
10973
|
activities: activitiesCommand,
|
|
9421
10974
|
insights: insightsCommand,
|
|
@@ -9424,10 +10977,10 @@ Audit & review:
|
|
|
9424
10977
|
});
|
|
9425
10978
|
|
|
9426
10979
|
// src/commands/ads/x/index.ts
|
|
9427
|
-
import { defineCommand as
|
|
10980
|
+
import { defineCommand as defineCommand81 } from "citty";
|
|
9428
10981
|
|
|
9429
10982
|
// src/commands/ads/x/accounts.ts
|
|
9430
|
-
import { defineCommand as
|
|
10983
|
+
import { defineCommand as defineCommand65 } from "citty";
|
|
9431
10984
|
registerSchema({
|
|
9432
10985
|
command: "ads.x.accounts",
|
|
9433
10986
|
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.",
|
|
@@ -9455,7 +11008,7 @@ function handleAccountsError2(err) {
|
|
|
9455
11008
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
9456
11009
|
process.exit(1);
|
|
9457
11010
|
}
|
|
9458
|
-
var accountsCommand4 =
|
|
11011
|
+
var accountsCommand4 = defineCommand65({
|
|
9459
11012
|
meta: {
|
|
9460
11013
|
name: "accounts",
|
|
9461
11014
|
description: `List accessible X Ads accounts. Returns account IDs needed for all other commands.
|
|
@@ -9495,7 +11048,7 @@ Examples:
|
|
|
9495
11048
|
});
|
|
9496
11049
|
|
|
9497
11050
|
// src/commands/ads/x/active-entities.ts
|
|
9498
|
-
import { defineCommand as
|
|
11051
|
+
import { defineCommand as defineCommand66 } from "citty";
|
|
9499
11052
|
|
|
9500
11053
|
// src/commands/ads/x/error-parser.ts
|
|
9501
11054
|
function mapXErrorCode(message) {
|
|
@@ -9646,7 +11199,7 @@ function parseCsv(v) {
|
|
|
9646
11199
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
9647
11200
|
return parts.length > 0 ? parts : void 0;
|
|
9648
11201
|
}
|
|
9649
|
-
var activeEntitiesCommand =
|
|
11202
|
+
var activeEntitiesCommand = defineCommand66({
|
|
9650
11203
|
meta: {
|
|
9651
11204
|
name: "active-entities",
|
|
9652
11205
|
description: `List entities with metric activity in a time range.
|
|
@@ -9704,7 +11257,7 @@ Examples:
|
|
|
9704
11257
|
});
|
|
9705
11258
|
|
|
9706
11259
|
// src/commands/ads/x/audiences.ts
|
|
9707
|
-
import { defineCommand as
|
|
11260
|
+
import { defineCommand as defineCommand67 } from "citty";
|
|
9708
11261
|
registerSchema({
|
|
9709
11262
|
command: "ads.x.audiences",
|
|
9710
11263
|
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.",
|
|
@@ -9713,7 +11266,7 @@ registerSchema({
|
|
|
9713
11266
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9714
11267
|
}
|
|
9715
11268
|
});
|
|
9716
|
-
var
|
|
11269
|
+
var audiencesCommand4 = defineCommand67({
|
|
9717
11270
|
meta: {
|
|
9718
11271
|
name: "audiences",
|
|
9719
11272
|
description: `List X Ads custom audiences.
|
|
@@ -9762,7 +11315,7 @@ Examples:
|
|
|
9762
11315
|
});
|
|
9763
11316
|
|
|
9764
11317
|
// src/commands/ads/x/campaigns.ts
|
|
9765
|
-
import { defineCommand as
|
|
11318
|
+
import { defineCommand as defineCommand68 } from "citty";
|
|
9766
11319
|
|
|
9767
11320
|
// src/commands/ads/x/run-list.ts
|
|
9768
11321
|
function buildCleanParams(opts) {
|
|
@@ -9825,7 +11378,7 @@ registerSchema({
|
|
|
9825
11378
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9826
11379
|
}
|
|
9827
11380
|
});
|
|
9828
|
-
var
|
|
11381
|
+
var campaignsCommand4 = defineCommand68({
|
|
9829
11382
|
meta: {
|
|
9830
11383
|
name: "campaigns",
|
|
9831
11384
|
description: `List X Ads campaigns. Returns budget, schedule, funding instrument, status.
|
|
@@ -9867,7 +11420,7 @@ Examples:
|
|
|
9867
11420
|
});
|
|
9868
11421
|
|
|
9869
11422
|
// src/commands/ads/x/cards.ts
|
|
9870
|
-
import { defineCommand as
|
|
11423
|
+
import { defineCommand as defineCommand69 } from "citty";
|
|
9871
11424
|
registerSchema({
|
|
9872
11425
|
command: "ads.x.cards",
|
|
9873
11426
|
description: "List website cards, video cards, and carousels for an X Ads account.",
|
|
@@ -9876,7 +11429,7 @@ registerSchema({
|
|
|
9876
11429
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9877
11430
|
}
|
|
9878
11431
|
});
|
|
9879
|
-
var cardsCommand =
|
|
11432
|
+
var cardsCommand = defineCommand69({
|
|
9880
11433
|
meta: {
|
|
9881
11434
|
name: "cards",
|
|
9882
11435
|
description: `List X Ads cards (rich creatives).
|
|
@@ -9925,7 +11478,7 @@ Examples:
|
|
|
9925
11478
|
});
|
|
9926
11479
|
|
|
9927
11480
|
// src/commands/ads/x/funding.ts
|
|
9928
|
-
import { defineCommand as
|
|
11481
|
+
import { defineCommand as defineCommand70 } from "citty";
|
|
9929
11482
|
registerSchema({
|
|
9930
11483
|
command: "ads.x.funding",
|
|
9931
11484
|
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.",
|
|
@@ -9934,7 +11487,7 @@ registerSchema({
|
|
|
9934
11487
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9935
11488
|
}
|
|
9936
11489
|
});
|
|
9937
|
-
var fundingCommand =
|
|
11490
|
+
var fundingCommand = defineCommand70({
|
|
9938
11491
|
meta: {
|
|
9939
11492
|
name: "funding",
|
|
9940
11493
|
description: `List funding instruments for an X Ads account.
|
|
@@ -9983,7 +11536,7 @@ Examples:
|
|
|
9983
11536
|
});
|
|
9984
11537
|
|
|
9985
11538
|
// src/commands/ads/x/line-items.ts
|
|
9986
|
-
import { defineCommand as
|
|
11539
|
+
import { defineCommand as defineCommand71 } from "citty";
|
|
9987
11540
|
registerSchema({
|
|
9988
11541
|
command: "ads.x.lineItems",
|
|
9989
11542
|
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).",
|
|
@@ -9995,7 +11548,7 @@ registerSchema({
|
|
|
9995
11548
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
9996
11549
|
}
|
|
9997
11550
|
});
|
|
9998
|
-
var lineItemsCommand =
|
|
11551
|
+
var lineItemsCommand = defineCommand71({
|
|
9999
11552
|
meta: {
|
|
10000
11553
|
name: "line-items",
|
|
10001
11554
|
description: `List X Ads line items (ad groups).
|
|
@@ -10036,7 +11589,7 @@ Examples:
|
|
|
10036
11589
|
});
|
|
10037
11590
|
|
|
10038
11591
|
// src/commands/ads/x/media.ts
|
|
10039
|
-
import { defineCommand as
|
|
11592
|
+
import { defineCommand as defineCommand72 } from "citty";
|
|
10040
11593
|
registerSchema({
|
|
10041
11594
|
command: "ads.x.media",
|
|
10042
11595
|
description: "List media assets in the X Ads media library (images, GIFs, videos). Filter by media-type (IMAGE, GIF, VIDEO).",
|
|
@@ -10046,7 +11599,7 @@ registerSchema({
|
|
|
10046
11599
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10047
11600
|
}
|
|
10048
11601
|
});
|
|
10049
|
-
var mediaCommand =
|
|
11602
|
+
var mediaCommand = defineCommand72({
|
|
10050
11603
|
meta: {
|
|
10051
11604
|
name: "media",
|
|
10052
11605
|
description: `List media assets in the X Ads media library.
|
|
@@ -10098,7 +11651,7 @@ Examples:
|
|
|
10098
11651
|
});
|
|
10099
11652
|
|
|
10100
11653
|
// src/commands/ads/x/promoted-tweets.ts
|
|
10101
|
-
import { defineCommand as
|
|
11654
|
+
import { defineCommand as defineCommand73 } from "citty";
|
|
10102
11655
|
registerSchema({
|
|
10103
11656
|
command: "ads.x.promotedTweets",
|
|
10104
11657
|
description: "List promoted tweets for an X Ads account. Returns id, line_item_id, tweet_id, approval_status. Filter by line-item-ids (CSV).",
|
|
@@ -10109,7 +11662,7 @@ registerSchema({
|
|
|
10109
11662
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10110
11663
|
}
|
|
10111
11664
|
});
|
|
10112
|
-
var promotedTweetsCommand =
|
|
11665
|
+
var promotedTweetsCommand = defineCommand73({
|
|
10113
11666
|
meta: {
|
|
10114
11667
|
name: "promoted-tweets",
|
|
10115
11668
|
description: `List X Ads promoted tweets.
|
|
@@ -10163,11 +11716,11 @@ Examples:
|
|
|
10163
11716
|
});
|
|
10164
11717
|
|
|
10165
11718
|
// src/commands/ads/x/stats/index.ts
|
|
10166
|
-
import { defineCommand as
|
|
11719
|
+
import { defineCommand as defineCommand78 } from "citty";
|
|
10167
11720
|
|
|
10168
11721
|
// src/commands/ads/x/stats/job.ts
|
|
10169
11722
|
import { gunzipSync } from "zlib";
|
|
10170
|
-
import { defineCommand as
|
|
11723
|
+
import { defineCommand as defineCommand74 } from "citty";
|
|
10171
11724
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
10172
11725
|
var DEADLINE_MS = 12 * 60 * 1e3;
|
|
10173
11726
|
var RESULT_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -10237,7 +11790,7 @@ async function pollUntilDone(accountId, jobId) {
|
|
|
10237
11790
|
function buildCacheKey(body) {
|
|
10238
11791
|
return `stats-job:${JSON.stringify(body)}`;
|
|
10239
11792
|
}
|
|
10240
|
-
var statsJobCommand =
|
|
11793
|
+
var statsJobCommand = defineCommand74({
|
|
10241
11794
|
meta: {
|
|
10242
11795
|
name: "job",
|
|
10243
11796
|
description: `Async X Ads stats job, sync from the CLI's perspective. Creates \u2192 polls \u2192 downloads \u2192 returns.
|
|
@@ -10342,7 +11895,7 @@ For fine-grained control (don't wait, poll yourself), use:
|
|
|
10342
11895
|
});
|
|
10343
11896
|
|
|
10344
11897
|
// src/commands/ads/x/stats/job-create.ts
|
|
10345
|
-
import { defineCommand as
|
|
11898
|
+
import { defineCommand as defineCommand75 } from "citty";
|
|
10346
11899
|
registerSchema({
|
|
10347
11900
|
command: "ads.x.statsJobCreate",
|
|
10348
11901
|
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.",
|
|
@@ -10365,7 +11918,7 @@ function parseCsv3(v) {
|
|
|
10365
11918
|
const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
10366
11919
|
return parts.length > 0 ? parts : void 0;
|
|
10367
11920
|
}
|
|
10368
|
-
var statsJobCreateCommand =
|
|
11921
|
+
var statsJobCreateCommand = defineCommand75({
|
|
10369
11922
|
meta: {
|
|
10370
11923
|
name: "job-create",
|
|
10371
11924
|
description: `Create an async X Ads stats job (up to 90 days, supports segmentation).
|
|
@@ -10428,7 +11981,7 @@ Examples:
|
|
|
10428
11981
|
});
|
|
10429
11982
|
|
|
10430
11983
|
// src/commands/ads/x/stats/job-status.ts
|
|
10431
|
-
import { defineCommand as
|
|
11984
|
+
import { defineCommand as defineCommand76 } from "citty";
|
|
10432
11985
|
registerSchema({
|
|
10433
11986
|
command: "ads.x.statsJobStatus",
|
|
10434
11987
|
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).",
|
|
@@ -10438,7 +11991,7 @@ registerSchema({
|
|
|
10438
11991
|
"job-ids": { type: "string", description: "CSV of job IDs", required: false }
|
|
10439
11992
|
}
|
|
10440
11993
|
});
|
|
10441
|
-
var statsJobStatusCommand =
|
|
11994
|
+
var statsJobStatusCommand = defineCommand76({
|
|
10442
11995
|
meta: {
|
|
10443
11996
|
name: "job-status",
|
|
10444
11997
|
description: `Poll the status of an async X Ads stats job.
|
|
@@ -10479,7 +12032,7 @@ Examples:
|
|
|
10479
12032
|
});
|
|
10480
12033
|
|
|
10481
12034
|
// src/commands/ads/x/stats/sync.ts
|
|
10482
|
-
import { defineCommand as
|
|
12035
|
+
import { defineCommand as defineCommand77 } from "citty";
|
|
10483
12036
|
|
|
10484
12037
|
// src/commands/ads/x/presets.ts
|
|
10485
12038
|
var X_STATS_PRESETS = [
|
|
@@ -10638,7 +12191,7 @@ async function runSync(args, q) {
|
|
|
10638
12191
|
process.exit(1);
|
|
10639
12192
|
}
|
|
10640
12193
|
}
|
|
10641
|
-
var statsSyncCommand =
|
|
12194
|
+
var statsSyncCommand = defineCommand77({
|
|
10642
12195
|
meta: {
|
|
10643
12196
|
name: "sync",
|
|
10644
12197
|
description: `Synchronous X Ads analytics (max 7-day window).
|
|
@@ -10681,7 +12234,7 @@ Examples:
|
|
|
10681
12234
|
});
|
|
10682
12235
|
|
|
10683
12236
|
// src/commands/ads/x/stats/index.ts
|
|
10684
|
-
var statsCommand =
|
|
12237
|
+
var statsCommand = defineCommand78({
|
|
10685
12238
|
meta: {
|
|
10686
12239
|
name: "stats",
|
|
10687
12240
|
description: `X Ads analytics. Sync (\u22647 days, no segmentation) or async jobs (\u226490 days, segmentable).
|
|
@@ -10709,7 +12262,7 @@ Examples:
|
|
|
10709
12262
|
});
|
|
10710
12263
|
|
|
10711
12264
|
// src/commands/ads/x/targeting-constants.ts
|
|
10712
|
-
import { defineCommand as
|
|
12265
|
+
import { defineCommand as defineCommand79 } from "citty";
|
|
10713
12266
|
var ALLOWED_CONSTANTS = [
|
|
10714
12267
|
"locations",
|
|
10715
12268
|
"interests",
|
|
@@ -10737,7 +12290,7 @@ registerSchema({
|
|
|
10737
12290
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10738
12291
|
}
|
|
10739
12292
|
});
|
|
10740
|
-
var targetingConstantsCommand =
|
|
12293
|
+
var targetingConstantsCommand = defineCommand79({
|
|
10741
12294
|
meta: {
|
|
10742
12295
|
name: "targeting-constants",
|
|
10743
12296
|
description: `Lookup X Ads targeting constants.
|
|
@@ -10787,7 +12340,7 @@ Examples:
|
|
|
10787
12340
|
});
|
|
10788
12341
|
|
|
10789
12342
|
// src/commands/ads/x/targeting-criteria.ts
|
|
10790
|
-
import { defineCommand as
|
|
12343
|
+
import { defineCommand as defineCommand80 } from "citty";
|
|
10791
12344
|
registerSchema({
|
|
10792
12345
|
command: "ads.x.targetingCriteria",
|
|
10793
12346
|
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.",
|
|
@@ -10797,7 +12350,7 @@ registerSchema({
|
|
|
10797
12350
|
"no-cache": { type: "boolean", description: "Skip cache", required: false }
|
|
10798
12351
|
}
|
|
10799
12352
|
});
|
|
10800
|
-
var targetingCriteriaCommand =
|
|
12353
|
+
var targetingCriteriaCommand = defineCommand80({
|
|
10801
12354
|
meta: {
|
|
10802
12355
|
name: "targeting-criteria",
|
|
10803
12356
|
description: `List targeting criteria attached to line items.
|
|
@@ -10848,7 +12401,7 @@ Examples:
|
|
|
10848
12401
|
});
|
|
10849
12402
|
|
|
10850
12403
|
// src/commands/ads/x/index.ts
|
|
10851
|
-
var xCommand =
|
|
12404
|
+
var xCommand = defineCommand81({
|
|
10852
12405
|
meta: {
|
|
10853
12406
|
name: "x",
|
|
10854
12407
|
description: `X (Twitter) Ads commands. Read campaigns, line items, promoted tweets, creatives, audiences, and analytics.
|
|
@@ -10872,12 +12425,12 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
10872
12425
|
subCommands: {
|
|
10873
12426
|
accounts: accountsCommand4,
|
|
10874
12427
|
funding: fundingCommand,
|
|
10875
|
-
campaigns:
|
|
12428
|
+
campaigns: campaignsCommand4,
|
|
10876
12429
|
"line-items": lineItemsCommand,
|
|
10877
12430
|
"promoted-tweets": promotedTweetsCommand,
|
|
10878
12431
|
cards: cardsCommand,
|
|
10879
12432
|
media: mediaCommand,
|
|
10880
|
-
audiences:
|
|
12433
|
+
audiences: audiencesCommand4,
|
|
10881
12434
|
"targeting-criteria": targetingCriteriaCommand,
|
|
10882
12435
|
"targeting-constants": targetingConstantsCommand,
|
|
10883
12436
|
"active-entities": activeEntitiesCommand,
|
|
@@ -10886,7 +12439,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
|
|
|
10886
12439
|
});
|
|
10887
12440
|
|
|
10888
12441
|
// src/commands/ads/index.ts
|
|
10889
|
-
var
|
|
12442
|
+
var adsCommand2 = defineCommand82({
|
|
10890
12443
|
meta: {
|
|
10891
12444
|
name: "ads",
|
|
10892
12445
|
description: `Ad platform commands. Each platform exposes its own native command surface \u2014 no forced parity.
|
|
@@ -10916,11 +12469,11 @@ Examples:
|
|
|
10916
12469
|
});
|
|
10917
12470
|
|
|
10918
12471
|
// src/commands/canvas/index.ts
|
|
10919
|
-
import { defineCommand as
|
|
12472
|
+
import { defineCommand as defineCommand90 } from "citty";
|
|
10920
12473
|
|
|
10921
12474
|
// src/commands/canvas/catalog.ts
|
|
10922
|
-
import { defineCommand as
|
|
10923
|
-
var catalogCommand =
|
|
12475
|
+
import { defineCommand as defineCommand83 } from "citty";
|
|
12476
|
+
var catalogCommand = defineCommand83({
|
|
10924
12477
|
meta: {
|
|
10925
12478
|
name: "catalog",
|
|
10926
12479
|
description: "Print the agent-facing node catalog (JSON Schema). Includes every registered node grouped by category."
|
|
@@ -10937,9 +12490,9 @@ import { execFile } from "child_process";
|
|
|
10937
12490
|
import { readdir, readFile, stat } from "fs/promises";
|
|
10938
12491
|
import path from "path";
|
|
10939
12492
|
import { promisify } from "util";
|
|
10940
|
-
import { defineCommand as
|
|
12493
|
+
import { defineCommand as defineCommand84 } from "citty";
|
|
10941
12494
|
var execFileAsync = promisify(execFile);
|
|
10942
|
-
var inspectCommand =
|
|
12495
|
+
var inspectCommand = defineCommand84({
|
|
10943
12496
|
meta: {
|
|
10944
12497
|
name: "inspect",
|
|
10945
12498
|
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."
|
|
@@ -11048,7 +12601,7 @@ async function probeDuration(filePath) {
|
|
|
11048
12601
|
// src/commands/canvas/run.ts
|
|
11049
12602
|
import { readFile as readFile2 } from "fs/promises";
|
|
11050
12603
|
import path4 from "path";
|
|
11051
|
-
import { defineCommand as
|
|
12604
|
+
import { defineCommand as defineCommand85 } from "citty";
|
|
11052
12605
|
|
|
11053
12606
|
// src/commands/canvas/placeholders.ts
|
|
11054
12607
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
@@ -11118,7 +12671,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
11118
12671
|
}
|
|
11119
12672
|
|
|
11120
12673
|
// src/commands/canvas/run.ts
|
|
11121
|
-
var runCommand =
|
|
12674
|
+
var runCommand = defineCommand85({
|
|
11122
12675
|
meta: { name: "run", description: "Validate and execute a canvas JSON file." },
|
|
11123
12676
|
args: {
|
|
11124
12677
|
file: { type: "positional", required: true, description: "Path to canvas JSON" },
|
|
@@ -11214,30 +12767,30 @@ var runCommand = defineCommand83({
|
|
|
11214
12767
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
11215
12768
|
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
11216
12769
|
import path6 from "path";
|
|
11217
|
-
import { defineCommand as
|
|
12770
|
+
import { defineCommand as defineCommand86 } from "citty";
|
|
11218
12771
|
|
|
11219
12772
|
// src/engine/scaffold/staticAd.ts
|
|
11220
|
-
import { z as
|
|
12773
|
+
import { z as z10 } from "zod";
|
|
11221
12774
|
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"]);
|
|
11222
12775
|
var DEFAULT_ASPECT_RATIO = "9:16";
|
|
11223
|
-
var Blueprint =
|
|
11224
|
-
meta:
|
|
11225
|
-
text_content:
|
|
12776
|
+
var Blueprint = z10.object({
|
|
12777
|
+
meta: z10.object({ estimated_aspect_ratio: z10.string().optional() }).loose().optional(),
|
|
12778
|
+
text_content: z10.array(z10.object({ text: z10.string().optional() }).loose()).optional()
|
|
11226
12779
|
}).loose();
|
|
11227
|
-
var ElementLocator =
|
|
11228
|
-
collection:
|
|
11229
|
-
index:
|
|
12780
|
+
var ElementLocator = z10.object({
|
|
12781
|
+
collection: z10.enum(["subjects", "people", "brands_logos"]),
|
|
12782
|
+
index: z10.number().int().nonnegative()
|
|
11230
12783
|
}).loose();
|
|
11231
|
-
var MainElement =
|
|
12784
|
+
var MainElement = z10.object({
|
|
11232
12785
|
// logo | product | person | animal | badge | other
|
|
11233
|
-
type:
|
|
11234
|
-
label:
|
|
11235
|
-
description:
|
|
11236
|
-
expression:
|
|
11237
|
-
reason:
|
|
12786
|
+
type: z10.string(),
|
|
12787
|
+
label: z10.string().optional(),
|
|
12788
|
+
description: z10.string().optional(),
|
|
12789
|
+
expression: z10.string().nullable().optional(),
|
|
12790
|
+
reason: z10.string().optional(),
|
|
11238
12791
|
locator: ElementLocator.optional()
|
|
11239
12792
|
}).loose();
|
|
11240
|
-
var MainElements =
|
|
12793
|
+
var MainElements = z10.array(MainElement);
|
|
11241
12794
|
function sanitizeId(raw, fallback) {
|
|
11242
12795
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
11243
12796
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -11560,7 +13113,7 @@ async function runVisionPasses(canvas) {
|
|
|
11560
13113
|
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
11561
13114
|
}
|
|
11562
13115
|
}
|
|
11563
|
-
var scaffoldStaticAdCommand =
|
|
13116
|
+
var scaffoldStaticAdCommand = defineCommand86({
|
|
11564
13117
|
meta: {
|
|
11565
13118
|
name: "scaffold-static-ad",
|
|
11566
13119
|
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."
|
|
@@ -11656,7 +13209,7 @@ var scaffoldStaticAdCommand = defineCommand84({
|
|
|
11656
13209
|
// src/commands/canvas/scaffold-video.ts
|
|
11657
13210
|
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
11658
13211
|
import path9 from "path";
|
|
11659
|
-
import { defineCommand as
|
|
13212
|
+
import { defineCommand as defineCommand87 } from "citty";
|
|
11660
13213
|
|
|
11661
13214
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
11662
13215
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -11761,7 +13314,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
|
|
|
11761
13314
|
import { toCardinal as nwNl } from "n2words/nl-NL";
|
|
11762
13315
|
import { toCardinal as nwPl } from "n2words/pl-PL";
|
|
11763
13316
|
import { toCardinal as nwPt } from "n2words/pt-PT";
|
|
11764
|
-
import { z as
|
|
13317
|
+
import { z as z11 } from "zod";
|
|
11765
13318
|
|
|
11766
13319
|
// src/engine/scaffold/lib/shoot-modes.ts
|
|
11767
13320
|
var SHOOT_MODES = [
|
|
@@ -12018,49 +13571,49 @@ function trimArgs(durationS, offsetS = 0) {
|
|
|
12018
13571
|
"{{out.video}}"
|
|
12019
13572
|
];
|
|
12020
13573
|
}
|
|
12021
|
-
var FrameAsset =
|
|
12022
|
-
var DialogueLine =
|
|
12023
|
-
speaker:
|
|
12024
|
-
line:
|
|
13574
|
+
var FrameAsset = z11.object({ url: z11.string().optional() }).loose().optional();
|
|
13575
|
+
var DialogueLine = z11.object({
|
|
13576
|
+
speaker: z11.string().optional(),
|
|
13577
|
+
line: z11.string().optional(),
|
|
12025
13578
|
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
12026
|
-
start_s:
|
|
12027
|
-
end_s:
|
|
12028
|
-
delivery:
|
|
12029
|
-
voice_description:
|
|
13579
|
+
start_s: z11.number().optional(),
|
|
13580
|
+
end_s: z11.number().optional(),
|
|
13581
|
+
delivery: z11.string().optional(),
|
|
13582
|
+
voice_description: z11.string().optional()
|
|
12030
13583
|
}).loose();
|
|
12031
|
-
var Sfx =
|
|
12032
|
-
at_s:
|
|
12033
|
-
duration_s:
|
|
12034
|
-
sound_effect_prompt:
|
|
12035
|
-
description:
|
|
13584
|
+
var Sfx = z11.object({
|
|
13585
|
+
at_s: z11.number().optional(),
|
|
13586
|
+
duration_s: z11.number().optional(),
|
|
13587
|
+
sound_effect_prompt: z11.string().optional(),
|
|
13588
|
+
description: z11.string().optional()
|
|
12036
13589
|
}).loose();
|
|
12037
|
-
var CompositionRegion =
|
|
13590
|
+
var CompositionRegion = z11.object({
|
|
12038
13591
|
// full | top | bottom | left | right | inset
|
|
12039
|
-
panel:
|
|
13592
|
+
panel: z11.string().optional(),
|
|
12040
13593
|
// 9-grid anchor for an `inset` presenter box.
|
|
12041
|
-
position:
|
|
12042
|
-
is_presenter:
|
|
13594
|
+
position: z11.string().optional(),
|
|
13595
|
+
is_presenter: z11.boolean().optional(),
|
|
12043
13596
|
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
12044
|
-
cast_ref:
|
|
12045
|
-
summary:
|
|
12046
|
-
frame_prompt:
|
|
12047
|
-
motion_prompt:
|
|
13597
|
+
cast_ref: z11.string().optional(),
|
|
13598
|
+
summary: z11.string().optional(),
|
|
13599
|
+
frame_prompt: z11.string().optional(),
|
|
13600
|
+
motion_prompt: z11.string().optional()
|
|
12048
13601
|
}).loose();
|
|
12049
|
-
var SceneComposition =
|
|
13602
|
+
var SceneComposition = z11.object({
|
|
12050
13603
|
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
12051
|
-
layout:
|
|
13604
|
+
layout: z11.string().optional(),
|
|
12052
13605
|
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
12053
|
-
split_axis:
|
|
12054
|
-
regions:
|
|
13606
|
+
split_axis: z11.string().optional(),
|
|
13607
|
+
regions: z11.array(CompositionRegion).optional()
|
|
12055
13608
|
}).loose();
|
|
12056
|
-
var CameraMotion =
|
|
12057
|
-
var TranscriptWord =
|
|
12058
|
-
var Scene =
|
|
12059
|
-
start_s:
|
|
12060
|
-
end_s:
|
|
12061
|
-
duration_s:
|
|
12062
|
-
summary:
|
|
12063
|
-
action_detail:
|
|
13609
|
+
var CameraMotion = z11.object({ movement: z11.string().optional(), detail: z11.string().optional() }).loose();
|
|
13610
|
+
var TranscriptWord = z11.object({ text: z11.string().optional() }).loose();
|
|
13611
|
+
var Scene = z11.object({
|
|
13612
|
+
start_s: z11.number().optional(),
|
|
13613
|
+
end_s: z11.number().optional(),
|
|
13614
|
+
duration_s: z11.number().optional(),
|
|
13615
|
+
summary: z11.string().optional(),
|
|
13616
|
+
action_detail: z11.string().optional(),
|
|
12064
13617
|
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
12065
13618
|
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
12066
13619
|
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
@@ -12068,77 +13621,77 @@ var Scene = z9.object({
|
|
|
12068
13621
|
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
12069
13622
|
// grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
|
|
12070
13623
|
// UGC/product mode; a human can override per scene by setting this.
|
|
12071
|
-
shoot_mode:
|
|
13624
|
+
shoot_mode: z11.string().optional(),
|
|
12072
13625
|
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
12073
13626
|
// absent the scene falls back to its shoot mode's default ambience.
|
|
12074
|
-
ambient:
|
|
13627
|
+
ambient: z11.string().optional(),
|
|
12075
13628
|
camera_motion: CameraMotion.optional(),
|
|
12076
|
-
start_frame_prompt:
|
|
12077
|
-
end_frame_prompt:
|
|
12078
|
-
motion_prompt:
|
|
13629
|
+
start_frame_prompt: z11.string().optional(),
|
|
13630
|
+
end_frame_prompt: z11.string().optional(),
|
|
13631
|
+
motion_prompt: z11.string().optional(),
|
|
12079
13632
|
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
12080
13633
|
// script re-craft checklist. Inferred from position when absent.
|
|
12081
|
-
narrative_role:
|
|
13634
|
+
narrative_role: z11.string().optional(),
|
|
12082
13635
|
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
12083
13636
|
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
12084
13637
|
// into the hook's start-frame description so the generator renders that state,
|
|
12085
13638
|
// not a calm influencer (CCA-11).
|
|
12086
|
-
hook_mechanic:
|
|
13639
|
+
hook_mechanic: z11.object({ mechanic: z11.string().optional(), why_it_stops_scroll: z11.string().optional() }).loose().optional(),
|
|
12087
13640
|
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
12088
|
-
scene_setting:
|
|
13641
|
+
scene_setting: z11.string().optional(),
|
|
12089
13642
|
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
12090
13643
|
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
12091
13644
|
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
12092
13645
|
// ignored (nothing follows it).
|
|
12093
|
-
transition_out:
|
|
12094
|
-
dialogue:
|
|
12095
|
-
sfx:
|
|
12096
|
-
overlays:
|
|
12097
|
-
floating_elements:
|
|
12098
|
-
transcript_slice:
|
|
13646
|
+
transition_out: z11.object({ type: z11.string().optional(), description: z11.string().optional() }).loose().optional(),
|
|
13647
|
+
dialogue: z11.array(DialogueLine).optional(),
|
|
13648
|
+
sfx: z11.array(Sfx).optional(),
|
|
13649
|
+
overlays: z11.array(z11.unknown()).optional(),
|
|
13650
|
+
floating_elements: z11.array(z11.unknown()).optional(),
|
|
13651
|
+
transcript_slice: z11.array(TranscriptWord).optional(),
|
|
12099
13652
|
start_frame_asset: FrameAsset,
|
|
12100
13653
|
end_frame_asset: FrameAsset,
|
|
12101
13654
|
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
12102
13655
|
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
12103
13656
|
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
12104
13657
|
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
12105
|
-
continues_previous:
|
|
13658
|
+
continues_previous: z11.boolean().optional()
|
|
12106
13659
|
}).loose();
|
|
12107
|
-
var VideoBlueprint =
|
|
12108
|
-
source:
|
|
12109
|
-
global:
|
|
12110
|
-
music:
|
|
12111
|
-
present:
|
|
12112
|
-
music_prompt:
|
|
13660
|
+
var VideoBlueprint = z11.object({
|
|
13661
|
+
source: z11.object({ aspect_ratio: z11.string().optional(), duration_s: z11.number().optional() }).loose().optional(),
|
|
13662
|
+
global: z11.object({
|
|
13663
|
+
music: z11.object({
|
|
13664
|
+
present: z11.boolean().optional(),
|
|
13665
|
+
music_prompt: z11.string().optional(),
|
|
12113
13666
|
// Absolute second the music enters in the reference (the bed often
|
|
12114
13667
|
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
12115
13668
|
// instead of at 0 so the timing matches.
|
|
12116
|
-
starts_at_s:
|
|
13669
|
+
starts_at_s: z11.number().optional(),
|
|
12117
13670
|
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
12118
13671
|
// reference track. We never reuse it — only style the regenerated bed.
|
|
12119
|
-
identified_track:
|
|
13672
|
+
identified_track: z11.object({ title: z11.string().optional(), artist: z11.string().optional() }).loose().nullish()
|
|
12120
13673
|
}).loose().optional(),
|
|
12121
|
-
cast:
|
|
12122
|
-
|
|
12123
|
-
id:
|
|
12124
|
-
description:
|
|
13674
|
+
cast: z11.array(
|
|
13675
|
+
z11.object({
|
|
13676
|
+
id: z11.string().optional(),
|
|
13677
|
+
description: z11.string().optional(),
|
|
12125
13678
|
// The deconstruct's note on the target-market localization (e.g. "native
|
|
12126
13679
|
// French speaker") — read to derive the spoken-track language code.
|
|
12127
|
-
market_localization_note:
|
|
13680
|
+
market_localization_note: z11.string().optional()
|
|
12128
13681
|
}).loose()
|
|
12129
13682
|
).optional(),
|
|
12130
|
-
voiceover:
|
|
13683
|
+
voiceover: z11.object({
|
|
12131
13684
|
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
12132
13685
|
// voiceover | none → narration over the picture (no lip-sync).
|
|
12133
|
-
mode:
|
|
12134
|
-
voice_description:
|
|
12135
|
-
persona:
|
|
13686
|
+
mode: z11.string().optional(),
|
|
13687
|
+
voice_description: z11.string().optional(),
|
|
13688
|
+
persona: z11.string().optional()
|
|
12136
13689
|
}).loose().optional(),
|
|
12137
13690
|
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
12138
13691
|
// first hex is the dominant brand colour); never to drive frame generation.
|
|
12139
|
-
style:
|
|
13692
|
+
style: z11.object({ palette: z11.array(z11.object({ hex: z11.string().optional() }).loose()).optional() }).loose().optional()
|
|
12140
13693
|
}).loose().optional(),
|
|
12141
|
-
scenes:
|
|
13694
|
+
scenes: z11.array(Scene).min(1)
|
|
12142
13695
|
}).loose();
|
|
12143
13696
|
function injectHookPhysicality(blueprint) {
|
|
12144
13697
|
for (const scene of blueprint.scenes) {
|
|
@@ -12148,26 +13701,26 @@ function injectHookPhysicality(blueprint) {
|
|
|
12148
13701
|
scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
|
|
12149
13702
|
}
|
|
12150
13703
|
}
|
|
12151
|
-
var AppearsItem =
|
|
12152
|
-
var RecurringElement =
|
|
13704
|
+
var AppearsItem = z11.union([z11.number(), z11.object({ scene: z11.number(), edge: z11.string().optional() }).loose()]);
|
|
13705
|
+
var RecurringElement = z11.object({
|
|
12153
13706
|
// person | animal | product | logo | badge | other
|
|
12154
|
-
type:
|
|
12155
|
-
label:
|
|
12156
|
-
description:
|
|
12157
|
-
expression:
|
|
13707
|
+
type: z11.string(),
|
|
13708
|
+
label: z11.string().optional(),
|
|
13709
|
+
description: z11.string().optional(),
|
|
13710
|
+
expression: z11.string().nullable().optional(),
|
|
12158
13711
|
// When the element maps to a global cast entry, its stable id (for annotation).
|
|
12159
|
-
cast_id:
|
|
13712
|
+
cast_id: z11.string().nullable().optional(),
|
|
12160
13713
|
// The label of another element that is the SAME individual as this one, shown
|
|
12161
13714
|
// in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
|
|
12162
13715
|
// pink shirt and believer in a white shirt). Each look gets its own reference
|
|
12163
13716
|
// slot, but the face/identity must stay identical across them.
|
|
12164
|
-
same_as:
|
|
13717
|
+
same_as: z11.string().nullable().optional(),
|
|
12165
13718
|
// Scenes the element appears in. Either a bare list of scene indices (both
|
|
12166
13719
|
// edges) or per-{scene,edge} entries. Both forms are accepted and merged.
|
|
12167
|
-
scenes:
|
|
12168
|
-
appears_in:
|
|
13720
|
+
scenes: z11.array(z11.number()).optional(),
|
|
13721
|
+
appears_in: z11.array(AppearsItem).optional()
|
|
12169
13722
|
}).loose();
|
|
12170
|
-
var RecurringElements =
|
|
13723
|
+
var RecurringElements = z11.array(RecurringElement);
|
|
12171
13724
|
function sanitizeId2(raw, fallback) {
|
|
12172
13725
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
12173
13726
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -13630,25 +15183,25 @@ function buildSfxMusic(blueprint, nodes) {
|
|
|
13630
15183
|
}
|
|
13631
15184
|
return tracks;
|
|
13632
15185
|
}
|
|
13633
|
-
var OverlayStyle =
|
|
13634
|
-
var Overlay =
|
|
13635
|
-
text:
|
|
13636
|
-
appears_at_s:
|
|
13637
|
-
duration_s:
|
|
13638
|
-
position:
|
|
13639
|
-
role:
|
|
13640
|
-
animation:
|
|
13641
|
-
animation_detail:
|
|
15186
|
+
var OverlayStyle = z11.object({ color_hex: z11.string().optional(), background: z11.string().optional(), size: z11.string().optional() }).loose();
|
|
15187
|
+
var Overlay = z11.object({
|
|
15188
|
+
text: z11.string().optional(),
|
|
15189
|
+
appears_at_s: z11.number().optional(),
|
|
15190
|
+
duration_s: z11.number().optional(),
|
|
15191
|
+
position: z11.string().optional(),
|
|
15192
|
+
role: z11.string().optional(),
|
|
15193
|
+
animation: z11.string().optional(),
|
|
15194
|
+
animation_detail: z11.string().optional(),
|
|
13642
15195
|
style: OverlayStyle.optional()
|
|
13643
15196
|
}).loose();
|
|
13644
|
-
var FloatingElement =
|
|
13645
|
-
kind:
|
|
13646
|
-
description:
|
|
13647
|
-
brand_name:
|
|
13648
|
-
what_it_represents:
|
|
13649
|
-
appears_at_s:
|
|
13650
|
-
duration_s:
|
|
13651
|
-
position:
|
|
15197
|
+
var FloatingElement = z11.object({
|
|
15198
|
+
kind: z11.string().optional(),
|
|
15199
|
+
description: z11.string().optional(),
|
|
15200
|
+
brand_name: z11.string().nullish(),
|
|
15201
|
+
what_it_represents: z11.string().optional(),
|
|
15202
|
+
appears_at_s: z11.number().optional(),
|
|
15203
|
+
duration_s: z11.number().optional(),
|
|
15204
|
+
position: z11.string().optional()
|
|
13652
15205
|
}).loose();
|
|
13653
15206
|
function escapeHtml(s) {
|
|
13654
15207
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -13680,7 +15233,7 @@ function positionClass(position) {
|
|
|
13680
15233
|
function collectCaptions(blueprint) {
|
|
13681
15234
|
return blueprint.scenes.flatMap((scene) => {
|
|
13682
15235
|
const sceneStart = scene.start_s ?? 0;
|
|
13683
|
-
const overlays =
|
|
15236
|
+
const overlays = z11.array(Overlay).safeParse(scene.overlays ?? []);
|
|
13684
15237
|
return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
|
|
13685
15238
|
const at = ov.appears_at_s ?? sceneStart;
|
|
13686
15239
|
return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
|
|
@@ -13789,7 +15342,7 @@ function buildOverlayHtml(input) {
|
|
|
13789
15342
|
if (ovParts.length > 0) blocks.push(ovParts.join("\n"));
|
|
13790
15343
|
for (const scene of blueprint.scenes) {
|
|
13791
15344
|
const sceneStart = scene.start_s ?? 0;
|
|
13792
|
-
const floats =
|
|
15345
|
+
const floats = z11.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
13793
15346
|
const parts = (floats.success ? floats.data.map((fe) => floatingStub(fe, sceneStart)) : []).filter(Boolean);
|
|
13794
15347
|
const pip = uiPipStub(scene);
|
|
13795
15348
|
if (pip) parts.push(pip);
|
|
@@ -14046,8 +15599,8 @@ function buildMotionBoard(blueprint) {
|
|
|
14046
15599
|
const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
|
|
14047
15600
|
cursor = end_s;
|
|
14048
15601
|
const spoken = sceneSpokenText(scene);
|
|
14049
|
-
const overlays =
|
|
14050
|
-
const floats =
|
|
15602
|
+
const overlays = z11.array(Overlay).safeParse(scene.overlays ?? []);
|
|
15603
|
+
const floats = z11.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
14051
15604
|
const graphics = [
|
|
14052
15605
|
...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
|
|
14053
15606
|
kind: "text",
|
|
@@ -14488,7 +16041,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
|
|
|
14488
16041
|
return fail2("deconstruct", e instanceof Error ? e.message : String(e));
|
|
14489
16042
|
}
|
|
14490
16043
|
}
|
|
14491
|
-
var scaffoldVideoCommand =
|
|
16044
|
+
var scaffoldVideoCommand = defineCommand87({
|
|
14492
16045
|
meta: {
|
|
14493
16046
|
name: "scaffold-video",
|
|
14494
16047
|
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`."
|
|
@@ -14633,7 +16186,7 @@ var scaffoldVideoCommand = defineCommand85({
|
|
|
14633
16186
|
// src/commands/canvas/set-prompt.ts
|
|
14634
16187
|
import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
14635
16188
|
import path10 from "path";
|
|
14636
|
-
import { defineCommand as
|
|
16189
|
+
import { defineCommand as defineCommand88 } from "citty";
|
|
14637
16190
|
function setNodePrompt(canvas, nodeId, text) {
|
|
14638
16191
|
const nodes = canvas?.nodes;
|
|
14639
16192
|
if (!Array.isArray(nodes)) throw new Error("canvas has no nodes array");
|
|
@@ -14648,7 +16201,7 @@ function setNodePrompt(canvas, nodeId, text) {
|
|
|
14648
16201
|
newNodes[idx] = newNode;
|
|
14649
16202
|
return { ...canvas, nodes: newNodes };
|
|
14650
16203
|
}
|
|
14651
|
-
var setPromptCommand =
|
|
16204
|
+
var setPromptCommand = defineCommand88({
|
|
14652
16205
|
meta: {
|
|
14653
16206
|
name: "set-prompt",
|
|
14654
16207
|
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."
|
|
@@ -14708,8 +16261,8 @@ var setPromptCommand = defineCommand86({
|
|
|
14708
16261
|
// src/commands/canvas/validate.ts
|
|
14709
16262
|
import { readFile as readFile8 } from "fs/promises";
|
|
14710
16263
|
import path11 from "path";
|
|
14711
|
-
import { defineCommand as
|
|
14712
|
-
var validateCommand =
|
|
16264
|
+
import { defineCommand as defineCommand89 } from "citty";
|
|
16265
|
+
var validateCommand = defineCommand89({
|
|
14713
16266
|
meta: {
|
|
14714
16267
|
name: "validate",
|
|
14715
16268
|
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)."
|
|
@@ -14752,7 +16305,7 @@ var validateCommand = defineCommand87({
|
|
|
14752
16305
|
});
|
|
14753
16306
|
|
|
14754
16307
|
// src/commands/canvas/index.ts
|
|
14755
|
-
var canvasCommand =
|
|
16308
|
+
var canvasCommand = defineCommand90({
|
|
14756
16309
|
meta: {
|
|
14757
16310
|
name: "canvas",
|
|
14758
16311
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
@@ -14779,10 +16332,10 @@ Subcommands:
|
|
|
14779
16332
|
});
|
|
14780
16333
|
|
|
14781
16334
|
// src/commands/creatives/index.ts
|
|
14782
|
-
import { defineCommand as
|
|
16335
|
+
import { defineCommand as defineCommand92 } from "citty";
|
|
14783
16336
|
|
|
14784
16337
|
// src/commands/creatives/publish.ts
|
|
14785
|
-
import { defineCommand as
|
|
16338
|
+
import { defineCommand as defineCommand91 } from "citty";
|
|
14786
16339
|
|
|
14787
16340
|
// src/commands/images/api.ts
|
|
14788
16341
|
import { readFile as readFile9 } from "fs/promises";
|
|
@@ -14905,7 +16458,7 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
14905
16458
|
sourceReferenceUrl
|
|
14906
16459
|
});
|
|
14907
16460
|
}
|
|
14908
|
-
var publishCommand =
|
|
16461
|
+
var publishCommand = defineCommand91({
|
|
14909
16462
|
meta: {
|
|
14910
16463
|
name: "publish",
|
|
14911
16464
|
description: "Publish a final static creative image to Baker Creatives and print the creative reference JSON."
|
|
@@ -14951,7 +16504,7 @@ var publishCommand = defineCommand89({
|
|
|
14951
16504
|
});
|
|
14952
16505
|
|
|
14953
16506
|
// src/commands/creatives/index.ts
|
|
14954
|
-
var creativesCommand3 =
|
|
16507
|
+
var creativesCommand3 = defineCommand92({
|
|
14955
16508
|
meta: {
|
|
14956
16509
|
name: "creatives",
|
|
14957
16510
|
description: `Publish static ad creatives as first-class Baker outputs.
|
|
@@ -14967,10 +16520,10 @@ Publishing uploads the image to the Company image library, applies the official
|
|
|
14967
16520
|
});
|
|
14968
16521
|
|
|
14969
16522
|
// src/commands/ga4/index.ts
|
|
14970
|
-
import { defineCommand as
|
|
16523
|
+
import { defineCommand as defineCommand96 } from "citty";
|
|
14971
16524
|
|
|
14972
16525
|
// src/commands/ga4/audit.ts
|
|
14973
|
-
import { defineCommand as
|
|
16526
|
+
import { defineCommand as defineCommand93 } from "citty";
|
|
14974
16527
|
|
|
14975
16528
|
// src/commands/ga4/resolve.ts
|
|
14976
16529
|
async function fetchProperties(useCache = true) {
|
|
@@ -15033,7 +16586,7 @@ registerSchema({
|
|
|
15033
16586
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15034
16587
|
}
|
|
15035
16588
|
});
|
|
15036
|
-
var auditCommand2 =
|
|
16589
|
+
var auditCommand2 = defineCommand93({
|
|
15037
16590
|
meta: {
|
|
15038
16591
|
name: "audit",
|
|
15039
16592
|
description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
|
|
@@ -15085,7 +16638,7 @@ Examples:
|
|
|
15085
16638
|
});
|
|
15086
16639
|
|
|
15087
16640
|
// src/commands/ga4/properties.ts
|
|
15088
|
-
import { defineCommand as
|
|
16641
|
+
import { defineCommand as defineCommand94 } from "citty";
|
|
15089
16642
|
registerSchema({
|
|
15090
16643
|
command: "ga4.properties",
|
|
15091
16644
|
description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
|
|
@@ -15093,7 +16646,7 @@ registerSchema({
|
|
|
15093
16646
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15094
16647
|
}
|
|
15095
16648
|
});
|
|
15096
|
-
var propertiesCommand =
|
|
16649
|
+
var propertiesCommand = defineCommand94({
|
|
15097
16650
|
meta: {
|
|
15098
16651
|
name: "properties",
|
|
15099
16652
|
description: `List accessible GA4 properties.
|
|
@@ -15141,9 +16694,9 @@ Examples:
|
|
|
15141
16694
|
});
|
|
15142
16695
|
|
|
15143
16696
|
// src/commands/ga4/query.ts
|
|
15144
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as
|
|
16697
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
|
|
15145
16698
|
import { resolve as resolve2 } from "path";
|
|
15146
|
-
import { defineCommand as
|
|
16699
|
+
import { defineCommand as defineCommand95 } from "citty";
|
|
15147
16700
|
|
|
15148
16701
|
// src/commands/ga4/presets.ts
|
|
15149
16702
|
var GA4_PRESETS = [
|
|
@@ -15232,7 +16785,7 @@ function writeRowsToFile2(filePath, rows, append) {
|
|
|
15232
16785
|
writeFileSync4(filePath, content, "utf-8");
|
|
15233
16786
|
}
|
|
15234
16787
|
} else if (append && existsSync5(filePath)) {
|
|
15235
|
-
const existing = JSON.parse(
|
|
16788
|
+
const existing = JSON.parse(readFileSync9(filePath, "utf-8"));
|
|
15236
16789
|
writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
15237
16790
|
} else {
|
|
15238
16791
|
writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -15275,7 +16828,7 @@ function handleError(err) {
|
|
|
15275
16828
|
});
|
|
15276
16829
|
process.exit(1);
|
|
15277
16830
|
}
|
|
15278
|
-
var queryCommand2 =
|
|
16831
|
+
var queryCommand2 = defineCommand95({
|
|
15279
16832
|
meta: {
|
|
15280
16833
|
name: "query",
|
|
15281
16834
|
description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
|
|
@@ -15346,7 +16899,7 @@ Free-form (escape hatch):
|
|
|
15346
16899
|
});
|
|
15347
16900
|
|
|
15348
16901
|
// src/commands/ga4/index.ts
|
|
15349
|
-
var ga4Command =
|
|
16902
|
+
var ga4Command = defineCommand96({
|
|
15350
16903
|
meta: {
|
|
15351
16904
|
name: "ga4",
|
|
15352
16905
|
description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
|
|
@@ -15369,12 +16922,12 @@ Examples:
|
|
|
15369
16922
|
});
|
|
15370
16923
|
|
|
15371
16924
|
// src/commands/gsc/index.ts
|
|
15372
|
-
import { defineCommand as
|
|
16925
|
+
import { defineCommand as defineCommand100 } from "citty";
|
|
15373
16926
|
|
|
15374
16927
|
// src/commands/gsc/query.ts
|
|
15375
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as
|
|
16928
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
15376
16929
|
import { resolve as resolve3 } from "path";
|
|
15377
|
-
import { defineCommand as
|
|
16930
|
+
import { defineCommand as defineCommand97 } from "citty";
|
|
15378
16931
|
|
|
15379
16932
|
// src/commands/gsc/presets.ts
|
|
15380
16933
|
var GSC_PRESETS = [
|
|
@@ -15517,7 +17070,7 @@ function writeRowsToFile3(filePath, rows, append) {
|
|
|
15517
17070
|
writeFileSync5(filePath, content, "utf-8");
|
|
15518
17071
|
}
|
|
15519
17072
|
} else if (append && existsSync6(filePath)) {
|
|
15520
|
-
const existing = JSON.parse(
|
|
17073
|
+
const existing = JSON.parse(readFileSync10(filePath, "utf-8"));
|
|
15521
17074
|
writeFileSync5(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
|
|
15522
17075
|
} else {
|
|
15523
17076
|
writeFileSync5(filePath, JSON.stringify(rows, null, 2), "utf-8");
|
|
@@ -15562,7 +17115,7 @@ function handleError2(err) {
|
|
|
15562
17115
|
});
|
|
15563
17116
|
process.exit(1);
|
|
15564
17117
|
}
|
|
15565
|
-
var queryCommand3 =
|
|
17118
|
+
var queryCommand3 = defineCommand97({
|
|
15566
17119
|
meta: {
|
|
15567
17120
|
name: "query",
|
|
15568
17121
|
description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
|
|
@@ -15640,7 +17193,7 @@ Free-form (escape hatch):
|
|
|
15640
17193
|
});
|
|
15641
17194
|
|
|
15642
17195
|
// src/commands/gsc/sitemaps.ts
|
|
15643
|
-
import { defineCommand as
|
|
17196
|
+
import { defineCommand as defineCommand98 } from "citty";
|
|
15644
17197
|
registerSchema({
|
|
15645
17198
|
command: "gsc.sitemaps",
|
|
15646
17199
|
description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
|
|
@@ -15649,7 +17202,7 @@ registerSchema({
|
|
|
15649
17202
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15650
17203
|
}
|
|
15651
17204
|
});
|
|
15652
|
-
var sitemapsCommand =
|
|
17205
|
+
var sitemapsCommand = defineCommand98({
|
|
15653
17206
|
meta: {
|
|
15654
17207
|
name: "sitemaps",
|
|
15655
17208
|
description: `List sitemaps for a site. Check health and errors.
|
|
@@ -15699,7 +17252,7 @@ Examples:
|
|
|
15699
17252
|
});
|
|
15700
17253
|
|
|
15701
17254
|
// src/commands/gsc/sites.ts
|
|
15702
|
-
import { defineCommand as
|
|
17255
|
+
import { defineCommand as defineCommand99 } from "citty";
|
|
15703
17256
|
registerSchema({
|
|
15704
17257
|
command: "gsc.sites",
|
|
15705
17258
|
description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
|
|
@@ -15707,7 +17260,7 @@ registerSchema({
|
|
|
15707
17260
|
"no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
|
|
15708
17261
|
}
|
|
15709
17262
|
});
|
|
15710
|
-
var sitesCommand =
|
|
17263
|
+
var sitesCommand = defineCommand99({
|
|
15711
17264
|
meta: {
|
|
15712
17265
|
name: "sites",
|
|
15713
17266
|
description: `List verified Search Console sites.
|
|
@@ -15755,7 +17308,7 @@ Examples:
|
|
|
15755
17308
|
});
|
|
15756
17309
|
|
|
15757
17310
|
// src/commands/gsc/index.ts
|
|
15758
|
-
var gscCommand =
|
|
17311
|
+
var gscCommand = defineCommand100({
|
|
15759
17312
|
meta: {
|
|
15760
17313
|
name: "gsc",
|
|
15761
17314
|
description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
|
|
@@ -15778,10 +17331,10 @@ Examples:
|
|
|
15778
17331
|
});
|
|
15779
17332
|
|
|
15780
17333
|
// src/commands/images/index.ts
|
|
15781
|
-
import { defineCommand as
|
|
17334
|
+
import { defineCommand as defineCommand124 } from "citty";
|
|
15782
17335
|
|
|
15783
17336
|
// src/commands/images/crop.ts
|
|
15784
|
-
import { defineCommand as
|
|
17337
|
+
import { defineCommand as defineCommand101 } from "citty";
|
|
15785
17338
|
|
|
15786
17339
|
// src/lib/image/crop-sprite.ts
|
|
15787
17340
|
import sharp from "sharp";
|
|
@@ -15906,7 +17459,7 @@ function emitError2(err) {
|
|
|
15906
17459
|
}
|
|
15907
17460
|
process.exit(1);
|
|
15908
17461
|
}
|
|
15909
|
-
var cropCommand =
|
|
17462
|
+
var cropCommand = defineCommand101({
|
|
15910
17463
|
meta: {
|
|
15911
17464
|
name: "crop",
|
|
15912
17465
|
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"
|
|
@@ -15942,7 +17495,7 @@ var cropCommand = defineCommand99({
|
|
|
15942
17495
|
});
|
|
15943
17496
|
|
|
15944
17497
|
// src/commands/images/delete.ts
|
|
15945
|
-
import { defineCommand as
|
|
17498
|
+
import { defineCommand as defineCommand102 } from "citty";
|
|
15946
17499
|
registerSchema({
|
|
15947
17500
|
command: "images.delete",
|
|
15948
17501
|
description: "Delete an image by ID",
|
|
@@ -15956,7 +17509,7 @@ registerSchema({
|
|
|
15956
17509
|
}
|
|
15957
17510
|
}
|
|
15958
17511
|
});
|
|
15959
|
-
var deleteCommand =
|
|
17512
|
+
var deleteCommand = defineCommand102({
|
|
15960
17513
|
meta: {
|
|
15961
17514
|
name: "delete",
|
|
15962
17515
|
description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
|
|
@@ -15997,7 +17550,7 @@ var deleteCommand = defineCommand100({
|
|
|
15997
17550
|
});
|
|
15998
17551
|
|
|
15999
17552
|
// src/commands/images/dimensions.ts
|
|
16000
|
-
import { defineCommand as
|
|
17553
|
+
import { defineCommand as defineCommand103 } from "citty";
|
|
16001
17554
|
|
|
16002
17555
|
// src/lib/image/dimensions.ts
|
|
16003
17556
|
import { imageSize } from "image-size";
|
|
@@ -16020,7 +17573,7 @@ registerSchema({
|
|
|
16020
17573
|
target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
|
|
16021
17574
|
}
|
|
16022
17575
|
});
|
|
16023
|
-
var dimensionsCommand =
|
|
17576
|
+
var dimensionsCommand = defineCommand103({
|
|
16024
17577
|
meta: {
|
|
16025
17578
|
name: "dimensions",
|
|
16026
17579
|
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"
|
|
@@ -16064,7 +17617,7 @@ var dimensionsCommand = defineCommand101({
|
|
|
16064
17617
|
});
|
|
16065
17618
|
|
|
16066
17619
|
// src/commands/images/extract.ts
|
|
16067
|
-
import { defineCommand as
|
|
17620
|
+
import { defineCommand as defineCommand104 } from "citty";
|
|
16068
17621
|
registerSchema({
|
|
16069
17622
|
command: "images.extract",
|
|
16070
17623
|
description: "Extract images from a URL via Firecrawl (formats: images).",
|
|
@@ -16080,7 +17633,7 @@ registerSchema({
|
|
|
16080
17633
|
}
|
|
16081
17634
|
}
|
|
16082
17635
|
});
|
|
16083
|
-
var extractCommand =
|
|
17636
|
+
var extractCommand = defineCommand104({
|
|
16084
17637
|
meta: {
|
|
16085
17638
|
name: "extract",
|
|
16086
17639
|
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"
|
|
@@ -16118,7 +17671,7 @@ var extractCommand = defineCommand102({
|
|
|
16118
17671
|
});
|
|
16119
17672
|
|
|
16120
17673
|
// src/commands/images/find.ts
|
|
16121
|
-
import { defineCommand as
|
|
17674
|
+
import { defineCommand as defineCommand105 } from "citty";
|
|
16122
17675
|
registerSchema({
|
|
16123
17676
|
command: "images.find",
|
|
16124
17677
|
description: "Fanout image search: library first, then opted-in external providers.",
|
|
@@ -16150,7 +17703,7 @@ registerSchema({
|
|
|
16150
17703
|
}
|
|
16151
17704
|
}
|
|
16152
17705
|
});
|
|
16153
|
-
var findCommand =
|
|
17706
|
+
var findCommand = defineCommand105({
|
|
16154
17707
|
meta: {
|
|
16155
17708
|
name: "find",
|
|
16156
17709
|
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"
|
|
@@ -16199,7 +17752,7 @@ var findCommand = defineCommand103({
|
|
|
16199
17752
|
|
|
16200
17753
|
// src/commands/images/generate.ts
|
|
16201
17754
|
import { readFile as readFile11 } from "fs/promises";
|
|
16202
|
-
import { defineCommand as
|
|
17755
|
+
import { defineCommand as defineCommand106 } from "citty";
|
|
16203
17756
|
import sharp2 from "sharp";
|
|
16204
17757
|
var GENERATE_TIMEOUT_MS = 18e4;
|
|
16205
17758
|
var REFERENCE_MAX_EDGE = 1536;
|
|
@@ -16302,7 +17855,7 @@ async function resolveReferences(spec) {
|
|
|
16302
17855
|
}
|
|
16303
17856
|
return out;
|
|
16304
17857
|
}
|
|
16305
|
-
var generateCommand =
|
|
17858
|
+
var generateCommand = defineCommand106({
|
|
16306
17859
|
meta: {
|
|
16307
17860
|
name: "generate",
|
|
16308
17861
|
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]]'"
|
|
@@ -16354,7 +17907,7 @@ var generateCommand = defineCommand104({
|
|
|
16354
17907
|
});
|
|
16355
17908
|
|
|
16356
17909
|
// src/commands/images/get.ts
|
|
16357
|
-
import { defineCommand as
|
|
17910
|
+
import { defineCommand as defineCommand107 } from "citty";
|
|
16358
17911
|
registerSchema({
|
|
16359
17912
|
command: "images.get",
|
|
16360
17913
|
description: "Get a single image by ID",
|
|
@@ -16362,7 +17915,7 @@ registerSchema({
|
|
|
16362
17915
|
id: { type: "string", description: "Image ID", required: true }
|
|
16363
17916
|
}
|
|
16364
17917
|
});
|
|
16365
|
-
var getCommand2 =
|
|
17918
|
+
var getCommand2 = defineCommand107({
|
|
16366
17919
|
meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
|
|
16367
17920
|
args: {
|
|
16368
17921
|
id: { type: "positional", description: "Image ID", required: false },
|
|
@@ -16398,7 +17951,7 @@ var getCommand2 = defineCommand105({
|
|
|
16398
17951
|
});
|
|
16399
17952
|
|
|
16400
17953
|
// src/commands/images/gif.ts
|
|
16401
|
-
import { defineCommand as
|
|
17954
|
+
import { defineCommand as defineCommand108 } from "citty";
|
|
16402
17955
|
registerSchema({
|
|
16403
17956
|
command: "images.gif",
|
|
16404
17957
|
description: "Search Giphy for GIFs / reaction memes (paid social creative).",
|
|
@@ -16430,7 +17983,7 @@ registerSchema({
|
|
|
16430
17983
|
}
|
|
16431
17984
|
}
|
|
16432
17985
|
});
|
|
16433
|
-
var gifCommand =
|
|
17986
|
+
var gifCommand = defineCommand108({
|
|
16434
17987
|
meta: {
|
|
16435
17988
|
name: "gif",
|
|
16436
17989
|
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"
|
|
@@ -16477,7 +18030,7 @@ var gifCommand = defineCommand106({
|
|
|
16477
18030
|
});
|
|
16478
18031
|
|
|
16479
18032
|
// src/commands/images/google.ts
|
|
16480
|
-
import { defineCommand as
|
|
18033
|
+
import { defineCommand as defineCommand109 } from "citty";
|
|
16481
18034
|
registerSchema({
|
|
16482
18035
|
command: "images.google",
|
|
16483
18036
|
description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
|
|
@@ -16513,7 +18066,7 @@ registerSchema({
|
|
|
16513
18066
|
}
|
|
16514
18067
|
}
|
|
16515
18068
|
});
|
|
16516
|
-
var googleCommand2 =
|
|
18069
|
+
var googleCommand2 = defineCommand109({
|
|
16517
18070
|
meta: {
|
|
16518
18071
|
name: "google",
|
|
16519
18072
|
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"
|
|
@@ -16561,7 +18114,7 @@ var googleCommand2 = defineCommand107({
|
|
|
16561
18114
|
});
|
|
16562
18115
|
|
|
16563
18116
|
// src/commands/images/icon.ts
|
|
16564
|
-
import { defineCommand as
|
|
18117
|
+
import { defineCommand as defineCommand110 } from "citty";
|
|
16565
18118
|
registerSchema({
|
|
16566
18119
|
command: "images.icon",
|
|
16567
18120
|
description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
|
|
@@ -16587,7 +18140,7 @@ registerSchema({
|
|
|
16587
18140
|
}
|
|
16588
18141
|
}
|
|
16589
18142
|
});
|
|
16590
|
-
var iconCommand =
|
|
18143
|
+
var iconCommand = defineCommand110({
|
|
16591
18144
|
meta: {
|
|
16592
18145
|
name: "icon",
|
|
16593
18146
|
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'"
|
|
@@ -16627,7 +18180,7 @@ var iconCommand = defineCommand108({
|
|
|
16627
18180
|
});
|
|
16628
18181
|
|
|
16629
18182
|
// src/commands/images/ingest.ts
|
|
16630
|
-
import { defineCommand as
|
|
18183
|
+
import { defineCommand as defineCommand111 } from "citty";
|
|
16631
18184
|
registerSchema({
|
|
16632
18185
|
command: "images.ingest",
|
|
16633
18186
|
description: "Ingest a remote image URL into the library (full describe + embed).",
|
|
@@ -16639,7 +18192,7 @@ registerSchema({
|
|
|
16639
18192
|
context: { type: "string", description: "Description context hint", required: false }
|
|
16640
18193
|
}
|
|
16641
18194
|
});
|
|
16642
|
-
var ingestCommand =
|
|
18195
|
+
var ingestCommand = defineCommand111({
|
|
16643
18196
|
meta: {
|
|
16644
18197
|
name: "ingest",
|
|
16645
18198
|
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"
|
|
@@ -16681,7 +18234,7 @@ var ingestCommand = defineCommand109({
|
|
|
16681
18234
|
});
|
|
16682
18235
|
|
|
16683
18236
|
// src/commands/images/library.ts
|
|
16684
|
-
import { defineCommand as
|
|
18237
|
+
import { defineCommand as defineCommand112 } from "citty";
|
|
16685
18238
|
registerSchema({
|
|
16686
18239
|
command: "images.library",
|
|
16687
18240
|
description: "Search the company image library. Returns only ready images.",
|
|
@@ -16707,7 +18260,7 @@ registerSchema({
|
|
|
16707
18260
|
}
|
|
16708
18261
|
}
|
|
16709
18262
|
});
|
|
16710
|
-
var libraryCommand =
|
|
18263
|
+
var libraryCommand = defineCommand112({
|
|
16711
18264
|
meta: {
|
|
16712
18265
|
name: "library",
|
|
16713
18266
|
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"
|
|
@@ -16764,7 +18317,7 @@ var libraryCommand = defineCommand110({
|
|
|
16764
18317
|
});
|
|
16765
18318
|
|
|
16766
18319
|
// src/commands/images/logo.ts
|
|
16767
|
-
import { defineCommand as
|
|
18320
|
+
import { defineCommand as defineCommand113 } from "citty";
|
|
16768
18321
|
registerSchema({
|
|
16769
18322
|
command: "images.logo",
|
|
16770
18323
|
description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
|
|
@@ -16789,7 +18342,7 @@ registerSchema({
|
|
|
16789
18342
|
}
|
|
16790
18343
|
}
|
|
16791
18344
|
});
|
|
16792
|
-
var logoCommand =
|
|
18345
|
+
var logoCommand = defineCommand113({
|
|
16793
18346
|
meta: {
|
|
16794
18347
|
name: "logo",
|
|
16795
18348
|
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"
|
|
@@ -16827,7 +18380,7 @@ var logoCommand = defineCommand111({
|
|
|
16827
18380
|
});
|
|
16828
18381
|
|
|
16829
18382
|
// src/commands/images/normalize.ts
|
|
16830
|
-
import { defineCommand as
|
|
18383
|
+
import { defineCommand as defineCommand114 } from "citty";
|
|
16831
18384
|
|
|
16832
18385
|
// src/lib/image/color-changer.ts
|
|
16833
18386
|
import quantize from "quantize";
|
|
@@ -17559,7 +19112,7 @@ function coerceRawArgs(args) {
|
|
|
17559
19112
|
"dry-run": bool(args["dry-run"])
|
|
17560
19113
|
};
|
|
17561
19114
|
}
|
|
17562
|
-
var normalizeCommand =
|
|
19115
|
+
var normalizeCommand = defineCommand114({
|
|
17563
19116
|
meta: {
|
|
17564
19117
|
name: "normalize",
|
|
17565
19118
|
description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
|
|
@@ -17614,7 +19167,7 @@ Examples:
|
|
|
17614
19167
|
});
|
|
17615
19168
|
|
|
17616
19169
|
// src/commands/images/pinterest.ts
|
|
17617
|
-
import { defineCommand as
|
|
19170
|
+
import { defineCommand as defineCommand115 } from "citty";
|
|
17618
19171
|
registerSchema({
|
|
17619
19172
|
command: "images.pinterest",
|
|
17620
19173
|
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.",
|
|
@@ -17634,7 +19187,7 @@ registerSchema({
|
|
|
17634
19187
|
}
|
|
17635
19188
|
}
|
|
17636
19189
|
});
|
|
17637
|
-
var pinterestCommand =
|
|
19190
|
+
var pinterestCommand = defineCommand115({
|
|
17638
19191
|
meta: {
|
|
17639
19192
|
name: "pinterest",
|
|
17640
19193
|
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'"
|
|
@@ -17674,7 +19227,7 @@ var pinterestCommand = defineCommand113({
|
|
|
17674
19227
|
});
|
|
17675
19228
|
|
|
17676
19229
|
// src/commands/images/screenshot.ts
|
|
17677
|
-
import { defineCommand as
|
|
19230
|
+
import { defineCommand as defineCommand116 } from "citty";
|
|
17678
19231
|
registerSchema({
|
|
17679
19232
|
command: "images.screenshot",
|
|
17680
19233
|
description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
|
|
@@ -17690,7 +19243,7 @@ registerSchema({
|
|
|
17690
19243
|
}
|
|
17691
19244
|
}
|
|
17692
19245
|
});
|
|
17693
|
-
var screenshotCommand =
|
|
19246
|
+
var screenshotCommand = defineCommand116({
|
|
17694
19247
|
meta: {
|
|
17695
19248
|
name: "screenshot",
|
|
17696
19249
|
description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
|
|
@@ -17740,7 +19293,7 @@ var screenshotCommand = defineCommand114({
|
|
|
17740
19293
|
});
|
|
17741
19294
|
|
|
17742
19295
|
// src/commands/images/search.ts
|
|
17743
|
-
import { defineCommand as
|
|
19296
|
+
import { defineCommand as defineCommand117 } from "citty";
|
|
17744
19297
|
registerSchema({
|
|
17745
19298
|
command: "images.search",
|
|
17746
19299
|
description: "Search images by text query. Only returns ready images.",
|
|
@@ -17756,7 +19309,7 @@ registerSchema({
|
|
|
17756
19309
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
17757
19310
|
}
|
|
17758
19311
|
});
|
|
17759
|
-
var searchCommand =
|
|
19312
|
+
var searchCommand = defineCommand117({
|
|
17760
19313
|
meta: {
|
|
17761
19314
|
name: "search",
|
|
17762
19315
|
description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
|
|
@@ -17816,7 +19369,7 @@ var searchCommand = defineCommand115({
|
|
|
17816
19369
|
});
|
|
17817
19370
|
|
|
17818
19371
|
// src/commands/images/sticker.ts
|
|
17819
|
-
import { defineCommand as
|
|
19372
|
+
import { defineCommand as defineCommand118 } from "citty";
|
|
17820
19373
|
registerSchema({
|
|
17821
19374
|
command: "images.sticker",
|
|
17822
19375
|
description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
|
|
@@ -17848,7 +19401,7 @@ registerSchema({
|
|
|
17848
19401
|
}
|
|
17849
19402
|
}
|
|
17850
19403
|
});
|
|
17851
|
-
var stickerCommand =
|
|
19404
|
+
var stickerCommand = defineCommand118({
|
|
17852
19405
|
meta: {
|
|
17853
19406
|
name: "sticker",
|
|
17854
19407
|
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"
|
|
@@ -17895,7 +19448,7 @@ var stickerCommand = defineCommand116({
|
|
|
17895
19448
|
});
|
|
17896
19449
|
|
|
17897
19450
|
// src/commands/images/stock.ts
|
|
17898
|
-
import { defineCommand as
|
|
19451
|
+
import { defineCommand as defineCommand119 } from "citty";
|
|
17899
19452
|
registerSchema({
|
|
17900
19453
|
command: "images.stock",
|
|
17901
19454
|
description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
|
|
@@ -17953,7 +19506,7 @@ registerSchema({
|
|
|
17953
19506
|
}
|
|
17954
19507
|
}
|
|
17955
19508
|
});
|
|
17956
|
-
var stockCommand =
|
|
19509
|
+
var stockCommand = defineCommand119({
|
|
17957
19510
|
meta: {
|
|
17958
19511
|
name: "stock",
|
|
17959
19512
|
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"
|
|
@@ -18009,7 +19562,7 @@ var stockCommand = defineCommand117({
|
|
|
18009
19562
|
});
|
|
18010
19563
|
|
|
18011
19564
|
// src/lib/tags-command.ts
|
|
18012
|
-
import { defineCommand as
|
|
19565
|
+
import { defineCommand as defineCommand120 } from "citty";
|
|
18013
19566
|
function makeTagsCommand(command, label, endpoint) {
|
|
18014
19567
|
registerSchema({
|
|
18015
19568
|
command: `${command}.tags`,
|
|
@@ -18018,7 +19571,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
18018
19571
|
output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
|
|
18019
19572
|
}
|
|
18020
19573
|
});
|
|
18021
|
-
return
|
|
19574
|
+
return defineCommand120({
|
|
18022
19575
|
meta: {
|
|
18023
19576
|
name: "tags",
|
|
18024
19577
|
description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
|
|
@@ -18054,7 +19607,7 @@ function makeTagsCommand(command, label, endpoint) {
|
|
|
18054
19607
|
var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
|
|
18055
19608
|
|
|
18056
19609
|
// src/commands/images/upload.ts
|
|
18057
|
-
import { defineCommand as
|
|
19610
|
+
import { defineCommand as defineCommand121 } from "citty";
|
|
18058
19611
|
registerSchema({
|
|
18059
19612
|
command: "images.upload",
|
|
18060
19613
|
description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
|
|
@@ -18092,7 +19645,7 @@ registerSchema({
|
|
|
18092
19645
|
function isRemoteUrl2(value) {
|
|
18093
19646
|
return /^https?:\/\//i.test(value);
|
|
18094
19647
|
}
|
|
18095
|
-
var uploadCommand =
|
|
19648
|
+
var uploadCommand = defineCommand121({
|
|
18096
19649
|
meta: {
|
|
18097
19650
|
name: "upload",
|
|
18098
19651
|
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'"
|
|
@@ -18185,7 +19738,7 @@ async function uploadLocal(target, args) {
|
|
|
18185
19738
|
}
|
|
18186
19739
|
|
|
18187
19740
|
// src/commands/images/upscale.ts
|
|
18188
|
-
import { defineCommand as
|
|
19741
|
+
import { defineCommand as defineCommand122 } from "citty";
|
|
18189
19742
|
registerSchema({
|
|
18190
19743
|
command: "images.upscale",
|
|
18191
19744
|
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).",
|
|
@@ -18200,7 +19753,7 @@ registerSchema({
|
|
|
18200
19753
|
}
|
|
18201
19754
|
});
|
|
18202
19755
|
var POLL_INTERVAL_MS3 = 1500;
|
|
18203
|
-
var upscaleCommand =
|
|
19756
|
+
var upscaleCommand = defineCommand122({
|
|
18204
19757
|
meta: {
|
|
18205
19758
|
name: "upscale",
|
|
18206
19759
|
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"
|
|
@@ -18255,7 +19808,7 @@ var upscaleCommand = defineCommand120({
|
|
|
18255
19808
|
});
|
|
18256
19809
|
|
|
18257
19810
|
// src/commands/images/use.ts
|
|
18258
|
-
import { defineCommand as
|
|
19811
|
+
import { defineCommand as defineCommand123 } from "citty";
|
|
18259
19812
|
registerSchema({
|
|
18260
19813
|
command: "images.use",
|
|
18261
19814
|
description: "Ingest a URL and wait for the library record to be ready.",
|
|
@@ -18271,7 +19824,7 @@ registerSchema({
|
|
|
18271
19824
|
}
|
|
18272
19825
|
});
|
|
18273
19826
|
var POLL_INTERVAL_MS4 = 1500;
|
|
18274
|
-
var useCommand =
|
|
19827
|
+
var useCommand = defineCommand123({
|
|
18275
19828
|
meta: {
|
|
18276
19829
|
name: "use",
|
|
18277
19830
|
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"
|
|
@@ -18317,7 +19870,7 @@ var useCommand = defineCommand121({
|
|
|
18317
19870
|
});
|
|
18318
19871
|
|
|
18319
19872
|
// src/commands/images/index.ts
|
|
18320
|
-
var imagesCommand =
|
|
19873
|
+
var imagesCommand = defineCommand124({
|
|
18321
19874
|
meta: {
|
|
18322
19875
|
name: "images",
|
|
18323
19876
|
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
@@ -18387,7 +19940,7 @@ Paid transforms (run on the Convex backend, cost-tracked):
|
|
|
18387
19940
|
});
|
|
18388
19941
|
|
|
18389
19942
|
// src/commands/mcp/index.ts
|
|
18390
|
-
import { defineCommand as
|
|
19943
|
+
import { defineCommand as defineCommand125 } from "citty";
|
|
18391
19944
|
var SCOPES = ["user", "company", "org"];
|
|
18392
19945
|
function parseScope(raw) {
|
|
18393
19946
|
const scope = raw === void 0 ? "company" : String(raw);
|
|
@@ -18426,7 +19979,7 @@ registerSchema({
|
|
|
18426
19979
|
description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
|
|
18427
19980
|
args: {}
|
|
18428
19981
|
});
|
|
18429
|
-
var listCommand4 =
|
|
19982
|
+
var listCommand4 = defineCommand125({
|
|
18430
19983
|
meta: { name: "list", description: "List custom MCP servers visible to this company's chats." },
|
|
18431
19984
|
run: async () => {
|
|
18432
19985
|
try {
|
|
@@ -18451,7 +20004,7 @@ registerSchema({
|
|
|
18451
20004
|
header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
|
|
18452
20005
|
}
|
|
18453
20006
|
});
|
|
18454
|
-
var addCommand =
|
|
20007
|
+
var addCommand = defineCommand125({
|
|
18455
20008
|
meta: {
|
|
18456
20009
|
name: "add",
|
|
18457
20010
|
description: `Register a custom MCP server. Tools appear as mcp__<name>__* on the NEXT message.
|
|
@@ -18492,7 +20045,7 @@ registerSchema({
|
|
|
18492
20045
|
description: "Remove a company custom MCP server by name.",
|
|
18493
20046
|
args: { name: { type: "string", description: "Server name to remove", required: true } }
|
|
18494
20047
|
});
|
|
18495
|
-
var removeCommand3 =
|
|
20048
|
+
var removeCommand3 = defineCommand125({
|
|
18496
20049
|
meta: {
|
|
18497
20050
|
name: "remove",
|
|
18498
20051
|
description: `Remove a company custom MCP server by name.
|
|
@@ -18514,7 +20067,7 @@ Example:
|
|
|
18514
20067
|
}
|
|
18515
20068
|
}
|
|
18516
20069
|
});
|
|
18517
|
-
var mcpCommand =
|
|
20070
|
+
var mcpCommand = defineCommand125({
|
|
18518
20071
|
meta: {
|
|
18519
20072
|
name: "mcp",
|
|
18520
20073
|
description: `Custom MCP servers for this company \u2014 point the agent at any HTTPS MCP endpoint.
|
|
@@ -18538,10 +20091,10 @@ Examples:
|
|
|
18538
20091
|
});
|
|
18539
20092
|
|
|
18540
20093
|
// src/commands/research/index.ts
|
|
18541
|
-
import { defineCommand as
|
|
20094
|
+
import { defineCommand as defineCommand136 } from "citty";
|
|
18542
20095
|
|
|
18543
20096
|
// src/commands/research/advertisers.ts
|
|
18544
|
-
import { defineCommand as
|
|
20097
|
+
import { defineCommand as defineCommand126 } from "citty";
|
|
18545
20098
|
|
|
18546
20099
|
// src/commands/research/output.ts
|
|
18547
20100
|
var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
|
|
@@ -18654,7 +20207,7 @@ var FIELDS3 = {
|
|
|
18654
20207
|
etv: "Estimated traffic value (USD)",
|
|
18655
20208
|
visibility: "SERP visibility score (0-1)"
|
|
18656
20209
|
};
|
|
18657
|
-
var advertisersCommand =
|
|
20210
|
+
var advertisersCommand = defineCommand126({
|
|
18658
20211
|
meta: {
|
|
18659
20212
|
name: "advertisers",
|
|
18660
20213
|
description: `Find domains competing for a keyword in Google SERPs.
|
|
@@ -18701,7 +20254,7 @@ Examples:
|
|
|
18701
20254
|
});
|
|
18702
20255
|
|
|
18703
20256
|
// src/commands/research/autocomplete.ts
|
|
18704
|
-
import { defineCommand as
|
|
20257
|
+
import { defineCommand as defineCommand127 } from "citty";
|
|
18705
20258
|
registerSchema({
|
|
18706
20259
|
command: "research.autocomplete",
|
|
18707
20260
|
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).",
|
|
@@ -18724,7 +20277,7 @@ registerSchema({
|
|
|
18724
20277
|
var FIELDS4 = {
|
|
18725
20278
|
suggestion: "Autocomplete suggestion from Google"
|
|
18726
20279
|
};
|
|
18727
|
-
var autocompleteCommand =
|
|
20280
|
+
var autocompleteCommand = defineCommand127({
|
|
18728
20281
|
meta: {
|
|
18729
20282
|
name: "autocomplete",
|
|
18730
20283
|
description: `Get Google Autocomplete suggestions for keyword expansion.
|
|
@@ -18770,7 +20323,7 @@ Examples:
|
|
|
18770
20323
|
});
|
|
18771
20324
|
|
|
18772
20325
|
// src/commands/research/countries.ts
|
|
18773
|
-
import { defineCommand as
|
|
20326
|
+
import { defineCommand as defineCommand128 } from "citty";
|
|
18774
20327
|
registerSchema({
|
|
18775
20328
|
command: "research.countries",
|
|
18776
20329
|
description: "List all supported country codes for --location flag in research commands.",
|
|
@@ -18827,7 +20380,7 @@ var FIELDS5 = {
|
|
|
18827
20380
|
code: "Country code to pass as --location",
|
|
18828
20381
|
name: "Country name"
|
|
18829
20382
|
};
|
|
18830
|
-
var countriesCommand =
|
|
20383
|
+
var countriesCommand = defineCommand128({
|
|
18831
20384
|
meta: {
|
|
18832
20385
|
name: "countries",
|
|
18833
20386
|
description: "List all supported country codes for --location flag."
|
|
@@ -18838,7 +20391,7 @@ var countriesCommand = defineCommand126({
|
|
|
18838
20391
|
});
|
|
18839
20392
|
|
|
18840
20393
|
// src/commands/research/intent.ts
|
|
18841
|
-
import { defineCommand as
|
|
20394
|
+
import { defineCommand as defineCommand129 } from "citty";
|
|
18842
20395
|
registerSchema({
|
|
18843
20396
|
command: "research.intent",
|
|
18844
20397
|
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.",
|
|
@@ -18861,7 +20414,7 @@ var FIELDS6 = {
|
|
|
18861
20414
|
intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
|
|
18862
20415
|
probability: "Confidence score 0.0-1.0"
|
|
18863
20416
|
};
|
|
18864
|
-
var intentCommand =
|
|
20417
|
+
var intentCommand = defineCommand129({
|
|
18865
20418
|
meta: {
|
|
18866
20419
|
name: "intent",
|
|
18867
20420
|
description: `Classify Google Search intent for keywords. Returns intent type and confidence.
|
|
@@ -18909,7 +20462,7 @@ Examples:
|
|
|
18909
20462
|
});
|
|
18910
20463
|
|
|
18911
20464
|
// src/commands/research/keyword-gap.ts
|
|
18912
|
-
import { defineCommand as
|
|
20465
|
+
import { defineCommand as defineCommand130 } from "citty";
|
|
18913
20466
|
registerSchema({
|
|
18914
20467
|
command: "research.keyword-gap",
|
|
18915
20468
|
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.",
|
|
@@ -18938,7 +20491,7 @@ var FIELDS7 = {
|
|
|
18938
20491
|
cpc: "Cost per click USD",
|
|
18939
20492
|
their_position: "Competitor's ranking position"
|
|
18940
20493
|
};
|
|
18941
|
-
var keywordGapCommand =
|
|
20494
|
+
var keywordGapCommand = defineCommand130({
|
|
18942
20495
|
meta: {
|
|
18943
20496
|
name: "keyword-gap",
|
|
18944
20497
|
description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
|
|
@@ -19012,7 +20565,7 @@ Examples:
|
|
|
19012
20565
|
});
|
|
19013
20566
|
|
|
19014
20567
|
// src/commands/research/keywords-for-site.ts
|
|
19015
|
-
import { defineCommand as
|
|
20568
|
+
import { defineCommand as defineCommand131 } from "citty";
|
|
19016
20569
|
registerSchema({
|
|
19017
20570
|
command: "research.keywords-for-site",
|
|
19018
20571
|
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.",
|
|
@@ -19045,7 +20598,7 @@ var FIELDS8 = {
|
|
|
19045
20598
|
competition: "LOW, MEDIUM, or HIGH",
|
|
19046
20599
|
competition_index: "Competition score 0-100"
|
|
19047
20600
|
};
|
|
19048
|
-
var keywordsForSiteCommand =
|
|
20601
|
+
var keywordsForSiteCommand = defineCommand131({
|
|
19049
20602
|
meta: {
|
|
19050
20603
|
name: "keywords-for-site",
|
|
19051
20604
|
description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
|
|
@@ -19098,7 +20651,7 @@ Examples:
|
|
|
19098
20651
|
});
|
|
19099
20652
|
|
|
19100
20653
|
// src/commands/research/languages.ts
|
|
19101
|
-
import { defineCommand as
|
|
20654
|
+
import { defineCommand as defineCommand132 } from "citty";
|
|
19102
20655
|
registerSchema({
|
|
19103
20656
|
command: "research.languages",
|
|
19104
20657
|
description: "List all supported language codes for --language flag in research commands.",
|
|
@@ -19128,7 +20681,7 @@ var FIELDS9 = {
|
|
|
19128
20681
|
code: "Language code to pass as --language",
|
|
19129
20682
|
name: "Language name (also accepted by --language)"
|
|
19130
20683
|
};
|
|
19131
|
-
var languagesCommand2 =
|
|
20684
|
+
var languagesCommand2 = defineCommand132({
|
|
19132
20685
|
meta: {
|
|
19133
20686
|
name: "languages",
|
|
19134
20687
|
description: "List all supported language codes for --language flag."
|
|
@@ -19139,7 +20692,7 @@ var languagesCommand2 = defineCommand130({
|
|
|
19139
20692
|
});
|
|
19140
20693
|
|
|
19141
20694
|
// src/commands/research/lighthouse.ts
|
|
19142
|
-
import { defineCommand as
|
|
20695
|
+
import { defineCommand as defineCommand133 } from "citty";
|
|
19143
20696
|
registerSchema({
|
|
19144
20697
|
command: "research.lighthouse",
|
|
19145
20698
|
description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
|
|
@@ -19158,7 +20711,7 @@ var FIELDS10 = {
|
|
|
19158
20711
|
speed_index_ms: "Speed Index in ms (good: < 3400)",
|
|
19159
20712
|
interactive_ms: "Time to Interactive in ms (good: < 3800)"
|
|
19160
20713
|
};
|
|
19161
|
-
var lighthouseCommand =
|
|
20714
|
+
var lighthouseCommand = defineCommand133({
|
|
19162
20715
|
meta: {
|
|
19163
20716
|
name: "lighthouse",
|
|
19164
20717
|
description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
|
|
@@ -19196,7 +20749,7 @@ Examples:
|
|
|
19196
20749
|
});
|
|
19197
20750
|
|
|
19198
20751
|
// src/commands/research/relevant-pages.ts
|
|
19199
|
-
import { defineCommand as
|
|
20752
|
+
import { defineCommand as defineCommand134 } from "citty";
|
|
19200
20753
|
registerSchema({
|
|
19201
20754
|
command: "research.relevant-pages",
|
|
19202
20755
|
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).",
|
|
@@ -19222,7 +20775,7 @@ var FIELDS11 = {
|
|
|
19222
20775
|
keywords: "Total organic keywords the page ranks for",
|
|
19223
20776
|
top_10: "Keywords in positions 1-10"
|
|
19224
20777
|
};
|
|
19225
|
-
var relevantPagesCommand =
|
|
20778
|
+
var relevantPagesCommand = defineCommand134({
|
|
19226
20779
|
meta: {
|
|
19227
20780
|
name: "relevant-pages",
|
|
19228
20781
|
description: `Get the top pages of a competitor domain with traffic data.
|
|
@@ -19268,7 +20821,7 @@ Examples:
|
|
|
19268
20821
|
});
|
|
19269
20822
|
|
|
19270
20823
|
// src/commands/research/web.ts
|
|
19271
|
-
import { defineCommand as
|
|
20824
|
+
import { defineCommand as defineCommand135 } from "citty";
|
|
19272
20825
|
registerSchema({
|
|
19273
20826
|
command: "research.web",
|
|
19274
20827
|
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).",
|
|
@@ -19319,7 +20872,7 @@ async function runDeepResearch(question) {
|
|
|
19319
20872
|
}
|
|
19320
20873
|
throw new Error("Deep research timed out");
|
|
19321
20874
|
}
|
|
19322
|
-
var webCommand =
|
|
20875
|
+
var webCommand = defineCommand135({
|
|
19323
20876
|
meta: {
|
|
19324
20877
|
name: "web",
|
|
19325
20878
|
description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
|
|
@@ -19379,7 +20932,7 @@ Examples:
|
|
|
19379
20932
|
});
|
|
19380
20933
|
|
|
19381
20934
|
// src/commands/research/index.ts
|
|
19382
|
-
var researchCommand =
|
|
20935
|
+
var researchCommand = defineCommand136({
|
|
19383
20936
|
meta: {
|
|
19384
20937
|
name: "research",
|
|
19385
20938
|
description: `Competitive intelligence and AI-powered research commands.
|
|
@@ -19419,10 +20972,10 @@ Examples:
|
|
|
19419
20972
|
});
|
|
19420
20973
|
|
|
19421
20974
|
// src/commands/scheduled-actions/index.ts
|
|
19422
|
-
import { defineCommand as
|
|
20975
|
+
import { defineCommand as defineCommand143 } from "citty";
|
|
19423
20976
|
|
|
19424
20977
|
// src/commands/scheduled-actions/create.ts
|
|
19425
|
-
import { defineCommand as
|
|
20978
|
+
import { defineCommand as defineCommand137 } from "citty";
|
|
19426
20979
|
|
|
19427
20980
|
// src/commands/scheduled-actions/shared.ts
|
|
19428
20981
|
var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
|
|
@@ -19537,7 +21090,7 @@ registerSchema({
|
|
|
19537
21090
|
prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
|
|
19538
21091
|
}
|
|
19539
21092
|
});
|
|
19540
|
-
var createCommand2 =
|
|
21093
|
+
var createCommand2 = defineCommand137({
|
|
19541
21094
|
meta: {
|
|
19542
21095
|
name: "create",
|
|
19543
21096
|
description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
|
|
@@ -19586,7 +21139,7 @@ var createCommand2 = defineCommand135({
|
|
|
19586
21139
|
});
|
|
19587
21140
|
|
|
19588
21141
|
// src/commands/scheduled-actions/delete.ts
|
|
19589
|
-
import { defineCommand as
|
|
21142
|
+
import { defineCommand as defineCommand138 } from "citty";
|
|
19590
21143
|
registerSchema({
|
|
19591
21144
|
command: "scheduled-actions.delete",
|
|
19592
21145
|
description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
|
|
@@ -19594,7 +21147,7 @@ registerSchema({
|
|
|
19594
21147
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
19595
21148
|
}
|
|
19596
21149
|
});
|
|
19597
|
-
var deleteCommand2 =
|
|
21150
|
+
var deleteCommand2 = defineCommand138({
|
|
19598
21151
|
meta: {
|
|
19599
21152
|
name: "delete",
|
|
19600
21153
|
description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
|
|
@@ -19623,7 +21176,7 @@ var deleteCommand2 = defineCommand136({
|
|
|
19623
21176
|
});
|
|
19624
21177
|
|
|
19625
21178
|
// src/commands/scheduled-actions/get.ts
|
|
19626
|
-
import { defineCommand as
|
|
21179
|
+
import { defineCommand as defineCommand139 } from "citty";
|
|
19627
21180
|
registerSchema({
|
|
19628
21181
|
command: "scheduled-actions.get",
|
|
19629
21182
|
description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
|
|
@@ -19631,7 +21184,7 @@ registerSchema({
|
|
|
19631
21184
|
id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
|
|
19632
21185
|
}
|
|
19633
21186
|
});
|
|
19634
|
-
var getCommand3 =
|
|
21187
|
+
var getCommand3 = defineCommand139({
|
|
19635
21188
|
meta: {
|
|
19636
21189
|
name: "get",
|
|
19637
21190
|
description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
|
|
@@ -19668,13 +21221,13 @@ var getCommand3 = defineCommand137({
|
|
|
19668
21221
|
});
|
|
19669
21222
|
|
|
19670
21223
|
// src/commands/scheduled-actions/list.ts
|
|
19671
|
-
import { defineCommand as
|
|
21224
|
+
import { defineCommand as defineCommand140 } from "citty";
|
|
19672
21225
|
registerSchema({
|
|
19673
21226
|
command: "scheduled-actions.list",
|
|
19674
21227
|
description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
|
|
19675
21228
|
args: {}
|
|
19676
21229
|
});
|
|
19677
|
-
var listCommand5 =
|
|
21230
|
+
var listCommand5 = defineCommand140({
|
|
19678
21231
|
meta: {
|
|
19679
21232
|
name: "list",
|
|
19680
21233
|
description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
|
|
@@ -19695,7 +21248,7 @@ var listCommand5 = defineCommand138({
|
|
|
19695
21248
|
});
|
|
19696
21249
|
|
|
19697
21250
|
// src/commands/scheduled-actions/trigger.ts
|
|
19698
|
-
import { defineCommand as
|
|
21251
|
+
import { defineCommand as defineCommand141 } from "citty";
|
|
19699
21252
|
registerSchema({
|
|
19700
21253
|
command: "scheduled-actions.trigger",
|
|
19701
21254
|
description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
|
|
@@ -19703,7 +21256,7 @@ registerSchema({
|
|
|
19703
21256
|
id: { type: "string", description: "Published scheduled action ID", required: true }
|
|
19704
21257
|
}
|
|
19705
21258
|
});
|
|
19706
|
-
var triggerCommand =
|
|
21259
|
+
var triggerCommand = defineCommand141({
|
|
19707
21260
|
meta: {
|
|
19708
21261
|
name: "trigger",
|
|
19709
21262
|
description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
|
|
@@ -19740,7 +21293,7 @@ var triggerCommand = defineCommand139({
|
|
|
19740
21293
|
});
|
|
19741
21294
|
|
|
19742
21295
|
// src/commands/scheduled-actions/update.ts
|
|
19743
|
-
import { defineCommand as
|
|
21296
|
+
import { defineCommand as defineCommand142 } from "citty";
|
|
19744
21297
|
registerSchema({
|
|
19745
21298
|
command: "scheduled-actions.update",
|
|
19746
21299
|
description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
|
|
@@ -19765,7 +21318,7 @@ registerSchema({
|
|
|
19765
21318
|
prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
|
|
19766
21319
|
}
|
|
19767
21320
|
});
|
|
19768
|
-
var updateCommand2 =
|
|
21321
|
+
var updateCommand2 = defineCommand142({
|
|
19769
21322
|
meta: {
|
|
19770
21323
|
name: "update",
|
|
19771
21324
|
description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
|
|
@@ -19836,7 +21389,7 @@ var updateCommand2 = defineCommand140({
|
|
|
19836
21389
|
});
|
|
19837
21390
|
|
|
19838
21391
|
// src/commands/scheduled-actions/index.ts
|
|
19839
|
-
var scheduledActionsCommand =
|
|
21392
|
+
var scheduledActionsCommand = defineCommand143({
|
|
19840
21393
|
meta: {
|
|
19841
21394
|
name: "scheduled-actions",
|
|
19842
21395
|
description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
|
|
@@ -19862,8 +21415,8 @@ Examples:
|
|
|
19862
21415
|
});
|
|
19863
21416
|
|
|
19864
21417
|
// src/commands/schema.ts
|
|
19865
|
-
import { defineCommand as
|
|
19866
|
-
var schemaCommand =
|
|
21418
|
+
import { defineCommand as defineCommand144 } from "citty";
|
|
21419
|
+
var schemaCommand = defineCommand144({
|
|
19867
21420
|
meta: {
|
|
19868
21421
|
name: "schema",
|
|
19869
21422
|
description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
|
|
@@ -19899,10 +21452,10 @@ var schemaCommand = defineCommand142({
|
|
|
19899
21452
|
});
|
|
19900
21453
|
|
|
19901
21454
|
// src/commands/testimonials/index.ts
|
|
19902
|
-
import { defineCommand as
|
|
21455
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
19903
21456
|
|
|
19904
21457
|
// src/commands/testimonials/get.ts
|
|
19905
|
-
import { defineCommand as
|
|
21458
|
+
import { defineCommand as defineCommand145 } from "citty";
|
|
19906
21459
|
registerSchema({
|
|
19907
21460
|
command: "testimonials.get",
|
|
19908
21461
|
description: "Get a single testimonial by ID",
|
|
@@ -19910,7 +21463,7 @@ registerSchema({
|
|
|
19910
21463
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
19911
21464
|
}
|
|
19912
21465
|
});
|
|
19913
|
-
var getCommand4 =
|
|
21466
|
+
var getCommand4 = defineCommand145({
|
|
19914
21467
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
19915
21468
|
args: {
|
|
19916
21469
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -19947,7 +21500,7 @@ var getCommand4 = defineCommand143({
|
|
|
19947
21500
|
});
|
|
19948
21501
|
|
|
19949
21502
|
// src/commands/testimonials/list.ts
|
|
19950
|
-
import { defineCommand as
|
|
21503
|
+
import { defineCommand as defineCommand146 } from "citty";
|
|
19951
21504
|
registerSchema({
|
|
19952
21505
|
command: "testimonials.list",
|
|
19953
21506
|
description: "List testimonials with optional filters.",
|
|
@@ -19977,7 +21530,7 @@ registerSchema({
|
|
|
19977
21530
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
19978
21531
|
}
|
|
19979
21532
|
});
|
|
19980
|
-
var listCommand6 =
|
|
21533
|
+
var listCommand6 = defineCommand146({
|
|
19981
21534
|
meta: {
|
|
19982
21535
|
name: "list",
|
|
19983
21536
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -20026,7 +21579,7 @@ var listCommand6 = defineCommand144({
|
|
|
20026
21579
|
});
|
|
20027
21580
|
|
|
20028
21581
|
// src/commands/testimonials/search.ts
|
|
20029
|
-
import { defineCommand as
|
|
21582
|
+
import { defineCommand as defineCommand147 } from "citty";
|
|
20030
21583
|
registerSchema({
|
|
20031
21584
|
command: "testimonials.search",
|
|
20032
21585
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -20057,7 +21610,7 @@ registerSchema({
|
|
|
20057
21610
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
20058
21611
|
}
|
|
20059
21612
|
});
|
|
20060
|
-
var searchCommand2 =
|
|
21613
|
+
var searchCommand2 = defineCommand147({
|
|
20061
21614
|
meta: {
|
|
20062
21615
|
name: "search",
|
|
20063
21616
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -20131,7 +21684,7 @@ var searchCommand2 = defineCommand145({
|
|
|
20131
21684
|
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
20132
21685
|
|
|
20133
21686
|
// src/commands/testimonials/index.ts
|
|
20134
|
-
var testimonialsCommand =
|
|
21687
|
+
var testimonialsCommand = defineCommand148({
|
|
20135
21688
|
meta: {
|
|
20136
21689
|
name: "testimonials",
|
|
20137
21690
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -20152,10 +21705,10 @@ Examples:
|
|
|
20152
21705
|
});
|
|
20153
21706
|
|
|
20154
21707
|
// src/commands/videos/index.ts
|
|
20155
|
-
import { defineCommand as
|
|
21708
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
20156
21709
|
|
|
20157
21710
|
// src/commands/videos/delete.ts
|
|
20158
|
-
import { defineCommand as
|
|
21711
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
20159
21712
|
registerSchema({
|
|
20160
21713
|
command: "videos.delete",
|
|
20161
21714
|
description: "Delete a video by ID",
|
|
@@ -20169,7 +21722,7 @@ registerSchema({
|
|
|
20169
21722
|
}
|
|
20170
21723
|
}
|
|
20171
21724
|
});
|
|
20172
|
-
var deleteCommand3 =
|
|
21725
|
+
var deleteCommand3 = defineCommand149({
|
|
20173
21726
|
meta: {
|
|
20174
21727
|
name: "delete",
|
|
20175
21728
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -20210,7 +21763,7 @@ var deleteCommand3 = defineCommand147({
|
|
|
20210
21763
|
});
|
|
20211
21764
|
|
|
20212
21765
|
// src/commands/videos/get.ts
|
|
20213
|
-
import { defineCommand as
|
|
21766
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
20214
21767
|
registerSchema({
|
|
20215
21768
|
command: "videos.get",
|
|
20216
21769
|
description: "Get a single video by ID",
|
|
@@ -20218,7 +21771,7 @@ registerSchema({
|
|
|
20218
21771
|
id: { type: "string", description: "Video ID", required: true }
|
|
20219
21772
|
}
|
|
20220
21773
|
});
|
|
20221
|
-
var getCommand5 =
|
|
21774
|
+
var getCommand5 = defineCommand150({
|
|
20222
21775
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
20223
21776
|
args: {
|
|
20224
21777
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -20255,7 +21808,7 @@ var getCommand5 = defineCommand148({
|
|
|
20255
21808
|
});
|
|
20256
21809
|
|
|
20257
21810
|
// src/commands/videos/search.ts
|
|
20258
|
-
import { defineCommand as
|
|
21811
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
20259
21812
|
registerSchema({
|
|
20260
21813
|
command: "videos.search",
|
|
20261
21814
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -20265,7 +21818,7 @@ registerSchema({
|
|
|
20265
21818
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
20266
21819
|
}
|
|
20267
21820
|
});
|
|
20268
|
-
var searchCommand3 =
|
|
21821
|
+
var searchCommand3 = defineCommand151({
|
|
20269
21822
|
meta: {
|
|
20270
21823
|
name: "search",
|
|
20271
21824
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -20317,7 +21870,7 @@ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
20317
21870
|
// src/commands/videos/upload.ts
|
|
20318
21871
|
import { readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
20319
21872
|
import { extname as extname3 } from "path";
|
|
20320
|
-
import { defineCommand as
|
|
21873
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
20321
21874
|
var MIME_MAP = {
|
|
20322
21875
|
".mp4": "video/mp4",
|
|
20323
21876
|
".mov": "video/quicktime",
|
|
@@ -20351,7 +21904,7 @@ function detectContentType(filePath) {
|
|
|
20351
21904
|
}
|
|
20352
21905
|
return mime;
|
|
20353
21906
|
}
|
|
20354
|
-
var uploadCommand2 =
|
|
21907
|
+
var uploadCommand2 = defineCommand152({
|
|
20355
21908
|
meta: {
|
|
20356
21909
|
name: "upload",
|
|
20357
21910
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -20405,7 +21958,7 @@ var uploadCommand2 = defineCommand150({
|
|
|
20405
21958
|
});
|
|
20406
21959
|
|
|
20407
21960
|
// src/commands/videos/index.ts
|
|
20408
|
-
var videosCommand =
|
|
21961
|
+
var videosCommand = defineCommand153({
|
|
20409
21962
|
meta: {
|
|
20410
21963
|
name: "videos",
|
|
20411
21964
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -20428,10 +21981,10 @@ Examples:
|
|
|
20428
21981
|
});
|
|
20429
21982
|
|
|
20430
21983
|
// src/commands/winning-ads/index.ts
|
|
20431
|
-
import { defineCommand as
|
|
21984
|
+
import { defineCommand as defineCommand156 } from "citty";
|
|
20432
21985
|
|
|
20433
21986
|
// src/commands/winning-ads/advertisers.ts
|
|
20434
|
-
import { defineCommand as
|
|
21987
|
+
import { defineCommand as defineCommand154 } from "citty";
|
|
20435
21988
|
registerSchema({
|
|
20436
21989
|
command: "winning-ads.advertisers",
|
|
20437
21990
|
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).",
|
|
@@ -20444,7 +21997,7 @@ registerSchema({
|
|
|
20444
21997
|
function identity(record) {
|
|
20445
21998
|
return record;
|
|
20446
21999
|
}
|
|
20447
|
-
var advertisersCommand2 =
|
|
22000
|
+
var advertisersCommand2 = defineCommand154({
|
|
20448
22001
|
meta: {
|
|
20449
22002
|
name: "advertisers",
|
|
20450
22003
|
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'
|
|
@@ -20495,7 +22048,7 @@ var advertisersCommand2 = defineCommand152({
|
|
|
20495
22048
|
});
|
|
20496
22049
|
|
|
20497
22050
|
// src/commands/winning-ads/search.ts
|
|
20498
|
-
import { defineCommand as
|
|
22051
|
+
import { defineCommand as defineCommand155 } from "citty";
|
|
20499
22052
|
registerSchema({
|
|
20500
22053
|
command: "winning-ads.search",
|
|
20501
22054
|
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.",
|
|
@@ -20603,7 +22156,7 @@ function buildSearchBody(args) {
|
|
|
20603
22156
|
}
|
|
20604
22157
|
return body;
|
|
20605
22158
|
}
|
|
20606
|
-
var searchCommand4 =
|
|
22159
|
+
var searchCommand4 = defineCommand155({
|
|
20607
22160
|
meta: {
|
|
20608
22161
|
name: "search",
|
|
20609
22162
|
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"
|
|
@@ -20715,7 +22268,7 @@ var searchCommand4 = defineCommand153({
|
|
|
20715
22268
|
});
|
|
20716
22269
|
|
|
20717
22270
|
// src/commands/winning-ads/index.ts
|
|
20718
|
-
var winningAdsCommand =
|
|
22271
|
+
var winningAdsCommand = defineCommand156({
|
|
20719
22272
|
meta: {
|
|
20720
22273
|
name: "winning-ads",
|
|
20721
22274
|
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.
|
|
@@ -20739,7 +22292,7 @@ Examples:
|
|
|
20739
22292
|
});
|
|
20740
22293
|
|
|
20741
22294
|
// src/version.ts
|
|
20742
|
-
import { readFileSync as
|
|
22295
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
20743
22296
|
function packageJsonUrl() {
|
|
20744
22297
|
return new URL("../package.json", import.meta.url);
|
|
20745
22298
|
}
|
|
@@ -20751,11 +22304,11 @@ function parsePackageVersion(raw) {
|
|
|
20751
22304
|
throw new Error("Invalid CLI package.json: missing version");
|
|
20752
22305
|
}
|
|
20753
22306
|
function getCliVersion() {
|
|
20754
|
-
return parsePackageVersion(
|
|
22307
|
+
return parsePackageVersion(readFileSync11(packageJsonUrl(), "utf8"));
|
|
20755
22308
|
}
|
|
20756
22309
|
|
|
20757
22310
|
// src/cli.ts
|
|
20758
|
-
var main =
|
|
22311
|
+
var main = defineCommand157({
|
|
20759
22312
|
meta: {
|
|
20760
22313
|
name: "baker",
|
|
20761
22314
|
version: getCliVersion(),
|
|
@@ -20770,7 +22323,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
20770
22323
|
subCommands: {
|
|
20771
22324
|
actions: actionsCommand,
|
|
20772
22325
|
"scheduled-actions": scheduledActionsCommand,
|
|
20773
|
-
ads:
|
|
22326
|
+
ads: adsCommand2,
|
|
20774
22327
|
ga4: ga4Command,
|
|
20775
22328
|
gsc: gscCommand,
|
|
20776
22329
|
research: researchCommand,
|