@adkit/cli 1.12.24 → 1.12.25

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 +91 -60
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -80,6 +80,7 @@ var CliError = class extends Error {
80
80
  suggestion;
81
81
  instructions;
82
82
  actionUrl;
83
+ notice;
83
84
  constructor(code, message, suggestion) {
84
85
  super(message);
85
86
  this.code = code;
@@ -90,16 +91,17 @@ var CliError = class extends Error {
90
91
  // src/client.ts
91
92
  var noticePrinted = false;
92
93
  function printServerNotice(response) {
93
- if (noticePrinted) return;
94
94
  const encoded = response.headers.get("x-adkit-notice");
95
- if (!encoded) return;
96
- noticePrinted = true;
95
+ if (!encoded) return void 0;
97
96
  const text = decodeURIComponent(encoded);
97
+ if (noticePrinted) return text;
98
+ noticePrinted = true;
98
99
  const dim = "\x1B[2m";
99
100
  const yellow = "\x1B[33m";
100
101
  const reset = "\x1B[0m";
101
102
  process.stderr.write(`${yellow}${dim}[AdKit notice] ${text}${reset}
102
103
  `);
104
+ return text;
103
105
  }
104
106
  function isErrorResponse(value) {
105
107
  return value != null && typeof value === "object";
@@ -204,7 +206,7 @@ var AdkitClient = class {
204
206
  const detail = code ?? (err instanceof Error ? err.message : String(err));
205
207
  throw new CliError("NETWORK_ERROR", `Cannot reach ${target} (${detail})`, "Verify your network connection");
206
208
  }
207
- printServerNotice(response);
209
+ const serverNotice = printServerNotice(response);
208
210
  if (response.status === 204) return void 0;
209
211
  if (!response.ok) {
210
212
  let serverMessage = "";
@@ -229,27 +231,40 @@ var AdkitClient = class {
229
231
  const fallbackMsg = response.status >= 500 ? `Server error (HTTP ${String(response.status)})` : `Request failed (HTTP ${String(response.status)})`;
230
232
  const errorMsg = appendErrorDetail(dataMessage || serverMessage || fallbackMsg, batchSummary);
231
233
  const suggestion2 = buildMetaDsaSuggestion(structured.code) ?? buildRetrySuggestion(retryable, retryAfterSeconds) ?? buildAuthSuggestion(structured.code);
232
- const error = new CliError(structured.code, errorMsg, suggestion2);
233
- error.instructions = structured.instructions;
234
- error.actionUrl = structured.actionUrl;
235
- throw error;
234
+ const error2 = new CliError(structured.code, errorMsg, suggestion2);
235
+ error2.instructions = structured.instructions;
236
+ error2.actionUrl = structured.actionUrl;
237
+ error2.notice = serverNotice;
238
+ throw error2;
239
+ }
240
+ if (response.status === 401) {
241
+ const error2 = new CliError("INVALID_API_KEY", `Invalid or expired API key${serverMessage ? ` \u2014 ${serverMessage}` : ""}`, "Run: adkit setup");
242
+ error2.notice = serverNotice;
243
+ throw error2;
236
244
  }
237
- if (response.status === 401) throw new CliError("INVALID_API_KEY", `Invalid or expired API key${serverMessage ? ` \u2014 ${serverMessage}` : ""}`, "Run: adkit setup");
238
245
  if (response.status === 429) {
239
246
  const waitMsg = buildRetrySuggestion(true, retryAfterSeconds) ?? "Wait a moment before retrying";
240
- throw new CliError("RATE_LIMITED", appendErrorDetail(serverMessage || "Rate limit exceeded", batchSummary), waitMsg);
247
+ const error2 = new CliError("RATE_LIMITED", appendErrorDetail(serverMessage || "Rate limit exceeded", batchSummary), waitMsg);
248
+ error2.notice = serverNotice;
249
+ throw error2;
241
250
  }
242
251
  if (response.status === 404) {
243
252
  const fallback = `Not found: ${method} ${path3} \u2014 the resource may have been deleted or the ID is wrong`;
244
- throw new CliError("NOT_FOUND", appendErrorDetail(serverMessage || fallback, batchSummary), "Check the resource ID");
253
+ const error2 = new CliError("NOT_FOUND", appendErrorDetail(serverMessage || fallback, batchSummary), "Check the resource ID");
254
+ error2.notice = serverNotice;
255
+ throw error2;
245
256
  }
246
257
  if (response.status >= 500) {
247
258
  const errorMsg = appendErrorDetail(dataMessage || serverMessage || `Server error (HTTP ${String(response.status)})`, batchSummary);
248
259
  const suggestion2 = buildRetrySuggestion(retryable, retryAfterSeconds);
249
- throw new CliError("SERVER_ERROR", errorMsg, suggestion2);
260
+ const error2 = new CliError("SERVER_ERROR", errorMsg, suggestion2);
261
+ error2.notice = serverNotice;
262
+ throw error2;
250
263
  }
251
264
  const suggestion = buildRetrySuggestion(retryable, retryAfterSeconds);
252
- throw new CliError("SERVER_ERROR", appendErrorDetail(serverMessage || `Request failed (HTTP ${String(response.status)})`, batchSummary), suggestion);
265
+ const error = new CliError("SERVER_ERROR", appendErrorDetail(serverMessage || `Request failed (HTTP ${String(response.status)})`, batchSummary), suggestion);
266
+ error.notice = serverNotice;
267
+ throw error;
253
268
  }
254
269
  return response.json();
255
270
  }
@@ -3529,8 +3544,8 @@ async function requestMultipart(client, pathName, formData) {
3529
3544
  try {
3530
3545
  const json = await response.json();
3531
3546
  if (isErrorResponse2(json)) {
3532
- serverMessage = json.statusMessage ?? json.message ?? "";
3533
3547
  dataMessage = json.data?.message ?? "";
3548
+ serverMessage = dataMessage || json.message || json.statusMessage || "";
3534
3549
  retryable = json.data?.retryable;
3535
3550
  retryAfterSeconds = json.data?.retryAfterSeconds ?? void 0;
3536
3551
  }
@@ -3885,11 +3900,23 @@ function toGoogleSearchTermDisplayRows(row) {
3885
3900
  import { createRequire } from "node:module";
3886
3901
 
3887
3902
  // src/update-check.ts
3888
- import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
3903
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
3889
3904
  import { join as join2 } from "node:path";
3890
3905
  var CACHE_PATH = join2(CONFIG_DIR, "update-check.json");
3891
3906
  var FETCH_TIMEOUT_MS = 3e3;
3892
3907
  var REGISTRY_URL = "https://registry.npmjs.org/@adkit/cli/latest";
3908
+ function readCache() {
3909
+ try {
3910
+ const raw = readFileSync4(CACHE_PATH, "utf-8");
3911
+ const parsed = JSON.parse(raw);
3912
+ if (!parsed || typeof parsed !== "object") return void 0;
3913
+ const cache = parsed;
3914
+ if (typeof cache.lastCheck !== "number" || typeof cache.latestVersion !== "string") return void 0;
3915
+ return { lastCheck: cache.lastCheck, latestVersion: cache.latestVersion };
3916
+ } catch {
3917
+ return void 0;
3918
+ }
3919
+ }
3893
3920
  function writeCache(data) {
3894
3921
  try {
3895
3922
  const cacheJson = JSON.stringify(data);
@@ -3939,7 +3966,8 @@ function isNewer(latest, current) {
3939
3966
  return false;
3940
3967
  }
3941
3968
  function startUpdateCheck(currentVersion) {
3942
- const pending = fetch(REGISTRY_URL, {
3969
+ const cached = readCache();
3970
+ void fetch(REGISTRY_URL, {
3943
3971
  signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
3944
3972
  }).then(async (res) => {
3945
3973
  if (!res.ok) return null;
@@ -3955,12 +3983,11 @@ function startUpdateCheck(currentVersion) {
3955
3983
  return null;
3956
3984
  }).catch(() => null);
3957
3985
  return () => {
3958
- void pending.then((latest) => {
3959
- if (latest && isNewer(latest, currentVersion)) {
3960
- const updateNotice = formatUpdateNotice(currentVersion, latest);
3961
- process.stderr.write(updateNotice);
3962
- }
3963
- });
3986
+ const latest = cached?.latestVersion;
3987
+ if (latest && isNewer(latest, currentVersion)) {
3988
+ const updateNotice = formatUpdateNotice(currentVersion, latest);
3989
+ process.stderr.write(updateNotice);
3990
+ }
3964
3991
  };
3965
3992
  }
3966
3993
 
@@ -6783,7 +6810,8 @@ async function selfUpdate(currentVersion) {
6783
6810
  else console.log(`Updated: ${currentVersion} \u2192 ${newVersion}`);
6784
6811
  } catch {
6785
6812
  console.error("Update failed. Try manually: npm install -g @adkit/cli@latest");
6786
- process.exit(1);
6813
+ process.exitCode = 1;
6814
+ return;
6787
6815
  }
6788
6816
  }
6789
6817
  async function main() {
@@ -6835,18 +6863,18 @@ async function main() {
6835
6863
  const manageTarget = args[1];
6836
6864
  if (flags.help && !manageTarget) {
6837
6865
  showHelp("manage", flags.help === "full");
6838
- process.exit(0);
6866
+ return;
6839
6867
  }
6840
6868
  if (!manageTarget) {
6841
6869
  showHelp("manage", flags.help === "full");
6842
- process.exit(0);
6870
+ return;
6843
6871
  }
6844
6872
  if (manageTarget === "drafts") {
6845
6873
  const action2 = args[2];
6846
6874
  const restArgs2 = args.slice(3);
6847
6875
  if (flags.help) {
6848
6876
  showHelp("drafts", flags.help === "full");
6849
- process.exit(0);
6877
+ return;
6850
6878
  }
6851
6879
  const client2 = requireClient(flags);
6852
6880
  let data2;
@@ -6878,7 +6906,7 @@ async function main() {
6878
6906
  if (manageTarget === "platform-api-requests") {
6879
6907
  if (flags.help) {
6880
6908
  showHelp("platform-api-requests", flags.help === "full");
6881
- process.exit(0);
6909
+ return;
6882
6910
  }
6883
6911
  const client2 = requireClient(flags);
6884
6912
  const data2 = await sendRawRequest(client2, flags);
@@ -6892,13 +6920,13 @@ async function main() {
6892
6920
  const restArgs = args.slice(4);
6893
6921
  if (flags.help) {
6894
6922
  const helpCandidates = [action ? `${platform2} ${entity} ${action}` : void 0, entity ? `${platform2} ${entity}` : void 0, platform2];
6895
- for (const helpKey of helpCandidates) if (helpKey && showHelp(helpKey, flags.help === "full")) process.exit(0);
6923
+ for (const helpKey of helpCandidates) if (helpKey && showHelp(helpKey, flags.help === "full")) return;
6896
6924
  printHelp(USAGE);
6897
- process.exit(0);
6925
+ return;
6898
6926
  }
6899
6927
  if (!entity) {
6900
6928
  showHelp(platform2, flags.help === "full");
6901
- process.exit(0);
6929
+ return;
6902
6930
  }
6903
6931
  const client = requireClient(flags);
6904
6932
  let data;
@@ -6940,7 +6968,7 @@ async function main() {
6940
6968
  case "campaigns": {
6941
6969
  if (!action) {
6942
6970
  showHelp("meta campaigns", flags.help === "full");
6943
- process.exit(0);
6971
+ return;
6944
6972
  }
6945
6973
  switch (action) {
6946
6974
  case "list":
@@ -6967,7 +6995,7 @@ async function main() {
6967
6995
  case "adsets": {
6968
6996
  if (!action) {
6969
6997
  showHelp("meta adsets", flags.help === "full");
6970
- process.exit(0);
6998
+ return;
6971
6999
  }
6972
7000
  switch (action) {
6973
7001
  case "list":
@@ -6994,7 +7022,7 @@ async function main() {
6994
7022
  case "ads": {
6995
7023
  if (!action) {
6996
7024
  showHelp("meta ads", flags.help === "full");
6997
- process.exit(0);
7025
+ return;
6998
7026
  }
6999
7027
  switch (action) {
7000
7028
  case "list":
@@ -7029,7 +7057,7 @@ async function main() {
7029
7057
  case "lead-forms": {
7030
7058
  if (!action) {
7031
7059
  showHelp("meta lead-forms", flags.help === "full");
7032
- process.exit(0);
7060
+ return;
7033
7061
  }
7034
7062
  switch (action) {
7035
7063
  case "list":
@@ -7115,7 +7143,7 @@ async function main() {
7115
7143
  case "assets": {
7116
7144
  if (!action) {
7117
7145
  showHelp("google assets", flags.help === "full");
7118
- process.exit(0);
7146
+ return;
7119
7147
  }
7120
7148
  switch (action) {
7121
7149
  case "list":
@@ -7143,7 +7171,7 @@ async function main() {
7143
7171
  case "media": {
7144
7172
  if (!action || flags.help) {
7145
7173
  showHelp("google media", flags.help === "full");
7146
- process.exit(0);
7174
+ return;
7147
7175
  }
7148
7176
  switch (action) {
7149
7177
  case "upload":
@@ -7157,7 +7185,7 @@ async function main() {
7157
7185
  case "campaigns": {
7158
7186
  if (!action) {
7159
7187
  showHelp("google campaigns", flags.help === "full");
7160
- process.exit(0);
7188
+ return;
7161
7189
  }
7162
7190
  switch (action) {
7163
7191
  case "list":
@@ -7182,7 +7210,7 @@ async function main() {
7182
7210
  case "ad-groups": {
7183
7211
  if (!action) {
7184
7212
  showHelp("google ad-groups", flags.help === "full");
7185
- process.exit(0);
7213
+ return;
7186
7214
  }
7187
7215
  switch (action) {
7188
7216
  case "list":
@@ -7207,7 +7235,7 @@ async function main() {
7207
7235
  case "ads": {
7208
7236
  if (!action) {
7209
7237
  showHelp("google ads", flags.help === "full");
7210
- process.exit(0);
7238
+ return;
7211
7239
  }
7212
7240
  switch (action) {
7213
7241
  case "list":
@@ -7234,7 +7262,7 @@ async function main() {
7234
7262
  case "keywords": {
7235
7263
  if (!action) {
7236
7264
  showHelp("google keywords", flags.help === "full");
7237
- process.exit(0);
7265
+ return;
7238
7266
  }
7239
7267
  switch (action) {
7240
7268
  case "list":
@@ -7254,7 +7282,7 @@ async function main() {
7254
7282
  const negativesAction = restArgs[0];
7255
7283
  if (!negativesAction || flags.help) {
7256
7284
  showHelp("google keywords negatives", flags.help === "full");
7257
- process.exit(0);
7285
+ return;
7258
7286
  }
7259
7287
  switch (negativesAction) {
7260
7288
  case "list":
@@ -7276,7 +7304,7 @@ async function main() {
7276
7304
  const negativeListsAction = restArgs[0];
7277
7305
  if (!negativeListsAction || flags.help) {
7278
7306
  showHelp("google keywords negative-lists", flags.help === "full");
7279
- process.exit(0);
7307
+ return;
7280
7308
  }
7281
7309
  const negativeListArgs = restArgs.slice(1);
7282
7310
  switch (negativeListsAction) {
@@ -7330,7 +7358,7 @@ async function main() {
7330
7358
  case "conversions": {
7331
7359
  if (!action || flags.help) {
7332
7360
  showHelp("google conversions", flags.help === "full");
7333
- process.exit(0);
7361
+ return;
7334
7362
  }
7335
7363
  switch (action) {
7336
7364
  case "upload":
@@ -7396,7 +7424,7 @@ async function main() {
7396
7424
  case "media": {
7397
7425
  if (!action || flags.help) {
7398
7426
  showHelp("tiktok media", flags.help === "full");
7399
- process.exit(0);
7427
+ return;
7400
7428
  }
7401
7429
  switch (action) {
7402
7430
  case "list":
@@ -7414,7 +7442,7 @@ async function main() {
7414
7442
  case "campaigns": {
7415
7443
  if (!action) {
7416
7444
  showHelp("tiktok campaigns", flags.help === "full");
7417
- process.exit(0);
7445
+ return;
7418
7446
  }
7419
7447
  switch (action) {
7420
7448
  case "list":
@@ -7436,7 +7464,7 @@ async function main() {
7436
7464
  case "ad-groups": {
7437
7465
  if (!action) {
7438
7466
  showHelp("tiktok ad-groups", flags.help === "full");
7439
- process.exit(0);
7467
+ return;
7440
7468
  }
7441
7469
  switch (action) {
7442
7470
  case "list":
@@ -7458,7 +7486,7 @@ async function main() {
7458
7486
  case "ads": {
7459
7487
  if (!action) {
7460
7488
  showHelp("tiktok ads", flags.help === "full");
7461
- process.exit(0);
7489
+ return;
7462
7490
  }
7463
7491
  switch (action) {
7464
7492
  case "list":
@@ -7522,17 +7550,17 @@ async function main() {
7522
7550
  const libraryTarget = args[1];
7523
7551
  if (flags.help && !libraryTarget) {
7524
7552
  showHelp("library", flags.help === "full");
7525
- process.exit(0);
7553
+ return;
7526
7554
  }
7527
7555
  if (!libraryTarget) {
7528
7556
  showHelp("library", flags.help === "full");
7529
- process.exit(0);
7557
+ return;
7530
7558
  }
7531
7559
  if (libraryTarget === "advertisers") {
7532
7560
  const action = args[2];
7533
7561
  if (flags.help || !action) {
7534
7562
  showHelp("library advertisers", flags.help === "full");
7535
- process.exit(0);
7563
+ return;
7536
7564
  }
7537
7565
  const client = requireClient(flags);
7538
7566
  if (action === "add") {
@@ -7553,7 +7581,8 @@ async function main() {
7553
7581
  const query = args.slice(3).join(" ");
7554
7582
  if (!query) {
7555
7583
  console.error("Usage: adkit library advertisers search <query>");
7556
- process.exit(1);
7584
+ process.exitCode = 1;
7585
+ return;
7557
7586
  }
7558
7587
  flags.search = query;
7559
7588
  const data = await listAdvertisers(client, [], flags);
@@ -7610,7 +7639,7 @@ ${pageInfo}`);
7610
7639
  const action = args[2];
7611
7640
  if (flags.help) {
7612
7641
  showHelp("library ads", flags.help === "full");
7613
- process.exit(0);
7642
+ return;
7614
7643
  }
7615
7644
  const client = requireClient(flags);
7616
7645
  if (action && action !== "list") {
@@ -7621,7 +7650,7 @@ ${pageInfo}`);
7621
7650
  const hasFilters = ["platform", "status", "format", "min-days", "max-days", "language", "min-score", "min-spend", "query", "search", "advertiser", "ids", "sort"].some((f) => typeof flags[f] === "string");
7622
7651
  if (!action && !hasFilters) {
7623
7652
  showHelp("library ads", flags.help === "full");
7624
- process.exit(0);
7653
+ return;
7625
7654
  }
7626
7655
  const data = await listLibraryAds(client, args.slice(3), flags);
7627
7656
  if (wantsJson(flags)) printResult(data, flags, "No ads found. Try adjusting your filters.");
@@ -7654,11 +7683,11 @@ ${pageInfo}`);
7654
7683
  const studioTarget = args[1];
7655
7684
  if (flags.help && !studioTarget) {
7656
7685
  showHelp("studio", flags.help === "full");
7657
- process.exit(0);
7686
+ return;
7658
7687
  }
7659
7688
  if (!studioTarget) {
7660
7689
  showHelp("studio", flags.help === "full");
7661
- process.exit(0);
7690
+ return;
7662
7691
  }
7663
7692
  let data;
7664
7693
  let emptyHint;
@@ -7668,7 +7697,7 @@ ${pageInfo}`);
7668
7697
  const restArgs = args.slice(3);
7669
7698
  if (flags.help) {
7670
7699
  showHelp("studio ads", flags.help === "full");
7671
- process.exit(0);
7700
+ return;
7672
7701
  }
7673
7702
  const client = requireClient(flags);
7674
7703
  switch (action) {
@@ -7699,7 +7728,7 @@ ${pageInfo}`);
7699
7728
  const restArgs = args.slice(3);
7700
7729
  if (flags.help) {
7701
7730
  showHelp("studio media", flags.help === "full");
7702
- process.exit(0);
7731
+ return;
7703
7732
  }
7704
7733
  const client = requireClient(flags);
7705
7734
  switch (action) {
@@ -7731,7 +7760,7 @@ ${pageInfo}`);
7731
7760
  case "share":
7732
7761
  if (flags.help) {
7733
7762
  showHelp("studio share", flags.help === "full");
7734
- process.exit(0);
7763
+ return;
7735
7764
  }
7736
7765
  data = await shareAd(requireClient(flags), args.slice(2), flags);
7737
7766
  break;
@@ -7745,7 +7774,7 @@ ${pageInfo}`);
7745
7774
  const action = args[1];
7746
7775
  if (flags.help) {
7747
7776
  showHelp("projects", flags.help === "full");
7748
- process.exit(0);
7777
+ return;
7749
7778
  }
7750
7779
  const client = requireClient(flags, { projectOptional: true });
7751
7780
  switch (action) {
@@ -7808,6 +7837,7 @@ ${pageInfo}`);
7808
7837
  ...err.instructions && { instructions: err.instructions },
7809
7838
  ...err.actionUrl && { actionUrl: err.actionUrl },
7810
7839
  ...err.suggestion && { suggestion: err.suggestion },
7840
+ ...err.notice && { notice: err.notice },
7811
7841
  ...shouldNudgeFeedback && { hint: "If this error is unexpected, report it using: adkit feedback" }
7812
7842
  });
7813
7843
  console.error(errorPayload);
@@ -7835,7 +7865,8 @@ ${pageInfo}`);
7835
7865
  INVALID_API_KEY: 4,
7836
7866
  NOT_AUTHENTICATED: 4
7837
7867
  };
7838
- process.exit(err instanceof CliError ? EXIT_CODES[err.code] ?? 1 : 1);
7868
+ process.exitCode = err instanceof CliError ? EXIT_CODES[err.code] ?? 1 : 1;
7869
+ return;
7839
7870
  } finally {
7840
7871
  if (args[0] !== "update") printUpdateNotice();
7841
7872
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adkit/cli",
3
- "version": "1.12.24",
3
+ "version": "1.12.25",
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",