@adkit/cli 1.12.3 → 1.12.8
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/dist/cli.js +38 -20
- package/package.json +4 -1
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// ../shared/dist/utils/service-status.js
|
|
4
|
-
var ADKIT_STATUS_NOTICE = null;
|
|
5
|
-
function getAdKitStatusNotice() {
|
|
6
|
-
const statusNotice = ADKIT_STATUS_NOTICE?.trim();
|
|
7
|
-
return statusNotice ? `Active AdKit status notice: ${statusNotice}` : void 0;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
3
|
// src/config.ts
|
|
11
4
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
12
5
|
import { join } from "node:path";
|
|
@@ -72,6 +65,15 @@ function readLegacyProjectApiKey(config, selectedProject) {
|
|
|
72
65
|
return config.projects?.[selectedProject]?.apiKey ?? null;
|
|
73
66
|
}
|
|
74
67
|
|
|
68
|
+
// ../shared/dist/errors.js
|
|
69
|
+
function describeRetryDelay(retryAfterSeconds) {
|
|
70
|
+
if (!retryAfterSeconds || retryAfterSeconds <= 300)
|
|
71
|
+
return "in a few minutes";
|
|
72
|
+
if (retryAfterSeconds <= 3600)
|
|
73
|
+
return "within the hour";
|
|
74
|
+
return "in a few hours";
|
|
75
|
+
}
|
|
76
|
+
|
|
75
77
|
// src/errors.ts
|
|
76
78
|
var CliError = class extends Error {
|
|
77
79
|
code;
|
|
@@ -86,6 +88,19 @@ var CliError = class extends Error {
|
|
|
86
88
|
};
|
|
87
89
|
|
|
88
90
|
// src/client.ts
|
|
91
|
+
var noticePrinted = false;
|
|
92
|
+
function printServerNotice(response) {
|
|
93
|
+
if (noticePrinted) return;
|
|
94
|
+
const encoded = response.headers.get("x-adkit-notice");
|
|
95
|
+
if (!encoded) return;
|
|
96
|
+
noticePrinted = true;
|
|
97
|
+
const text = decodeURIComponent(encoded);
|
|
98
|
+
const dim = "\x1B[2m";
|
|
99
|
+
const yellow = "\x1B[33m";
|
|
100
|
+
const reset = "\x1B[0m";
|
|
101
|
+
process.stderr.write(`${yellow}${dim}[AdKit notice] ${text}${reset}
|
|
102
|
+
`);
|
|
103
|
+
}
|
|
89
104
|
function isErrorResponse(value) {
|
|
90
105
|
return value != null && typeof value === "object";
|
|
91
106
|
}
|
|
@@ -135,12 +150,14 @@ function appendErrorDetail(message, detail) {
|
|
|
135
150
|
}
|
|
136
151
|
function buildRetrySuggestion(retryable, retryAfterSeconds) {
|
|
137
152
|
if (retryable !== true) return void 0;
|
|
138
|
-
if (typeof retryAfterSeconds === "number") return `Wait ${String(retryAfterSeconds)} seconds before retrying`;
|
|
153
|
+
if (typeof retryAfterSeconds === "number" && retryAfterSeconds <= 300) return `Wait ${String(retryAfterSeconds)} seconds before retrying`;
|
|
154
|
+
if (typeof retryAfterSeconds === "number") return `Try again ${describeRetryDelay(retryAfterSeconds)}`;
|
|
139
155
|
return "Retry in a few seconds";
|
|
140
156
|
}
|
|
141
|
-
var AUTH_CODES = /* @__PURE__ */ new Set(["not_connected", "token_expired", "refresh_token_expired"]);
|
|
157
|
+
var AUTH_CODES = /* @__PURE__ */ new Set(["invalid_grant", "auth_error", "auth_expired", "not_connected", "token_expired", "refresh_token_expired"]);
|
|
142
158
|
function buildAuthSuggestion(code) {
|
|
143
|
-
|
|
159
|
+
const normalizedCode = code.toLowerCase();
|
|
160
|
+
if (!AUTH_CODES.has(normalizedCode)) return void 0;
|
|
144
161
|
return "Run: adkit setup manage";
|
|
145
162
|
}
|
|
146
163
|
var AdkitClient = class {
|
|
@@ -178,6 +195,7 @@ var AdkitClient = class {
|
|
|
178
195
|
const detail = code ?? (err instanceof Error ? err.message : String(err));
|
|
179
196
|
throw new CliError("NETWORK_ERROR", `Cannot reach ${target} (${detail})`, "Verify your network connection");
|
|
180
197
|
}
|
|
198
|
+
printServerNotice(response);
|
|
181
199
|
if (response.status === 204) return void 0;
|
|
182
200
|
if (!response.ok) {
|
|
183
201
|
let serverMessage = "";
|
|
@@ -2656,7 +2674,7 @@ var PLATFORM_OVERRIDE_FLAG = "platform-overrides";
|
|
|
2656
2674
|
var CAMPAIGN_CREATE_FLAGS = ["name", "objective", "status", "budget-daily", "budget-lifetime", PLATFORM_OVERRIDE_FLAG];
|
|
2657
2675
|
var CAMPAIGN_UPDATE_FLAGS = ["name", "status", "budget-daily", "budget-lifetime", PLATFORM_OVERRIDE_FLAG];
|
|
2658
2676
|
var AD_GROUP_LIST_FLAGS2 = ["campaign-ids", "fields", "limit", "offset"];
|
|
2659
|
-
var AD_GROUP_CREATE_FLAGS = ["campaign", "name", "status", "budget-daily", "budget-lifetime", "billing-event", "optimization", "schedule-start-time", "schedule-end-time", "schedule-type", "pacing", "bid-amount", "event-type", "pixel", "placement", PLATFORM_OVERRIDE_FLAG];
|
|
2677
|
+
var AD_GROUP_CREATE_FLAGS = ["campaign", "name", "status", "budget-daily", "budget-lifetime", "billing-event", "bid-strategy", "optimization", "schedule-start-time", "schedule-end-time", "schedule-type", "pacing", "bid-amount", "event-type", "pixel", "placement", PLATFORM_OVERRIDE_FLAG];
|
|
2660
2678
|
var AD_GROUP_UPDATE_FLAGS = ["name", "status", "budget-daily", "budget-lifetime", "billing-event", "optimization", "schedule-start-time", "schedule-end-time", "schedule-type", "pacing", "bid-amount", "event-type", "pixel", PLATFORM_OVERRIDE_FLAG];
|
|
2661
2679
|
var AD_LIST_FLAGS2 = ["ad-group-ids", "campaign-ids", "fields", "limit", "offset"];
|
|
2662
2680
|
var AD_CREATE_FLAGS = ["ad-group", "name", "status", "media-id", "ad-text", "url", "cta", "display-name", "identity-id", "identity-type", "tracking-pixel", PLATFORM_OVERRIDE_FLAG];
|
|
@@ -2809,6 +2827,7 @@ function buildTikTokAdGroupPayload(flags, mode) {
|
|
|
2809
2827
|
if (budget) payload.budget = budget;
|
|
2810
2828
|
if (typeof flags.status === "string") payload.status = flags.status;
|
|
2811
2829
|
if (typeof flags["billing-event"] === "string") payload.billingEvent = flags["billing-event"];
|
|
2830
|
+
if (mode === "create" && typeof flags["bid-strategy"] === "string") payload.bidStrategy = flags["bid-strategy"];
|
|
2812
2831
|
if (typeof flags.optimization === "string") payload.optimization = flags.optimization;
|
|
2813
2832
|
if (typeof flags["schedule-end-time"] === "string") payload.scheduleEndTime = flags["schedule-end-time"];
|
|
2814
2833
|
if (typeof flags["schedule-type"] === "string") payload.scheduleType = flags["schedule-type"];
|
|
@@ -4551,7 +4570,7 @@ var GOOGLE_CAMPAIGN_HELP = `adkit manage google campaigns \u2014 Google Ads camp
|
|
|
4551
4570
|
create Create a campaign
|
|
4552
4571
|
update <id> Update a campaign
|
|
4553
4572
|
delete <id> Delete a campaign
|
|
4554
|
-
<id> View campaign details
|
|
4573
|
+
<id> View campaign details (PMAX includes assetGroups)
|
|
4555
4574
|
|
|
4556
4575
|
Flags (create):
|
|
4557
4576
|
--name <name> Campaign name (required)
|
|
@@ -4577,6 +4596,7 @@ Note:
|
|
|
4577
4596
|
Advanced geo examples: adkit manage google campaigns --help full
|
|
4578
4597
|
Display creation starts here: campaigns create --campaign-type display, then create Display ad groups and responsive_display ads.
|
|
4579
4598
|
Performance Max: campaignType "performance_max" with asset groups \u2014 build it with --data. See --help full.
|
|
4599
|
+
View a Performance Max campaign by ID to read back its assetGroups from Google.
|
|
4580
4600
|
For spend/clicks/conversions: adkit manage google results
|
|
4581
4601
|
|
|
4582
4602
|
Examples:
|
|
@@ -4593,7 +4613,7 @@ var GOOGLE_CAMPAIGN_HELP_FULL = `adkit manage google campaigns \u2014 Google Ads
|
|
|
4593
4613
|
create Create a campaign
|
|
4594
4614
|
update <id> Update a campaign
|
|
4595
4615
|
delete <id> Delete a campaign
|
|
4596
|
-
<id> View campaign details
|
|
4616
|
+
<id> View campaign details (PMAX includes assetGroups)
|
|
4597
4617
|
|
|
4598
4618
|
Flags (create):
|
|
4599
4619
|
--name <name> Campaign name (required)
|
|
@@ -4627,6 +4647,7 @@ Notes:
|
|
|
4627
4647
|
Google excludes support location geo target constants, not proximity radius exclusions.
|
|
4628
4648
|
Display campaign creation uses campaignType:"display" or --campaign-type display. Videos are not supported for Display media in v1.
|
|
4629
4649
|
Performance Max: campaignType "performance_max" with exactly one assetGroups[] entry. Text assets inline ({role,text}); image assets are uploaded via google media first, then referenced by id/resourceName. Needs an enabled conversion action (publish is blocked without one). Non-retail only. Build it with --data.
|
|
4650
|
+
View a Performance Max campaign by ID to read back assetGroups from Google. There is no separate google asset-groups command.
|
|
4630
4651
|
For spend/clicks/conversions: adkit manage google results
|
|
4631
4652
|
|
|
4632
4653
|
Examples:
|
|
@@ -5268,15 +5289,16 @@ ${FLAG.data}
|
|
|
5268
5289
|
--schedule-start-time <value> Required for create, e.g. "2026-05-15 12:00:00"
|
|
5269
5290
|
--schedule-end-time <value> Optional end time
|
|
5270
5291
|
--billing-event <s> cpc, cpm, ocpm
|
|
5292
|
+
--bid-strategy <s> bid_type_no_bid, bid_type_custom, bid_type_max_conversion
|
|
5271
5293
|
--optimization <s> click, convert, lead_generation, video_view, reach
|
|
5272
|
-
--bid-amount <n>
|
|
5294
|
+
--bid-amount <n> Custom bid in account currency; conversion/OCPM maps to cost per conversion
|
|
5273
5295
|
--event-type <s> purchase, add_to_cart, view_content, complete_registration, lead, submit_form
|
|
5274
5296
|
--pixel <id> Pixel ID; falls back to account default pixel when conversion is used
|
|
5275
5297
|
--placement <ids> Override TikTok placement IDs (publish default: PLACEMENT_TIKTOK)
|
|
5276
5298
|
|
|
5277
5299
|
Examples:
|
|
5278
5300
|
adkit manage tiktok ad-groups create --campaign 1770 --name "US Broad" --budget-daily 50 --schedule-start-time "2026-05-15 12:00:00" --billing-event cpc --optimization click
|
|
5279
|
-
adkit manage tiktok ad-groups create --data '{"adGroups":[{"campaignId":"1770","name":"Purchase","budget":{"daily":50},"scheduleStartTime":"2026-05-15 12:00:00","conversion":{"eventType":"purchase"},"targeting":{"geoLocations":{"include":[{"type":"country","country":"US"}]}}}]}'`.trim(),
|
|
5301
|
+
adkit manage tiktok ad-groups create --data '{"adGroups":[{"campaignId":"1770","name":"Purchase","budget":{"daily":50},"scheduleStartTime":"2026-05-15 12:00:00","bidAmount":80,"conversion":{"eventType":"purchase"},"targeting":{"geoLocations":{"include":[{"type":"country","country":"US"}]}}}]}'`.trim(),
|
|
5280
5302
|
"tiktok ads": `adkit manage tiktok ads \u2014 TikTok video ads
|
|
5281
5303
|
|
|
5282
5304
|
list List ads
|
|
@@ -6440,11 +6462,7 @@ function showHelp(key, full = false) {
|
|
|
6440
6462
|
return false;
|
|
6441
6463
|
}
|
|
6442
6464
|
function printHelp(text) {
|
|
6443
|
-
|
|
6444
|
-
const helpText = statusNotice ? `${statusNotice}
|
|
6445
|
-
|
|
6446
|
-
${text}` : text;
|
|
6447
|
-
console.log(helpText);
|
|
6465
|
+
console.log(text);
|
|
6448
6466
|
}
|
|
6449
6467
|
async function selfUpdate(currentVersion) {
|
|
6450
6468
|
const { execSync } = await import("node:child_process");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adkit/cli",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.8",
|
|
4
4
|
"description": "The Ads CLI for AI agents — manage Meta & Google ad campaigns, browse the ad library, and generate creatives from your terminal.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ads cli",
|
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
"build": "esbuild src/cli.ts --bundle --format=esm --platform=node --target=node18 --outfile=dist/cli.js --banner:js='#!/usr/bin/env node'",
|
|
35
35
|
"release": "cd ../shared && npm run build && cd ../cli && npm version patch && npm run build && npm publish --access public"
|
|
36
36
|
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"open": "^10.2.0"
|
|
39
|
+
},
|
|
37
40
|
"devDependencies": {
|
|
38
41
|
"@adkit/shared": "*",
|
|
39
42
|
"@types/node": "^20.10.0",
|