@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.
Files changed (2) hide show
  1. package/dist/cli.js +38 -20
  2. 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
- if (!AUTH_CODES.has(code)) return void 0;
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> Manual bid amount in account currency
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
- const statusNotice = getAdKitStatusNotice();
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",
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",