@adkit/cli 1.12.21 → 1.12.23

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 +148 -26
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1833,9 +1833,11 @@ var SEARCH_TERMS_FLAGS = ["campaign", "ad-group", "keyword", "keyword-match-type
1833
1833
  var PLACEMENT_REPORT_FLAGS = ["campaign", "ad-group", "period", "from", "to", "sort", "limit", "raw"];
1834
1834
  var GOOGLE_RESULTS_FLAGS = ["campaign", "ad-group", "period", "from", "to", "sort", "limit", "status", "breakdown", "fields", "conversion-actions", "raw"];
1835
1835
  var GOOGLE_KEYWORD_RESULTS_FLAGS = ["campaign", "ad-group", "period", "from", "to", "sort", "limit", "status", "fields", "raw"];
1836
+ var CONVERSION_UPLOAD_FLAGS = ["conversion", "gclid", "gbraid", "wbraid", "occurred-at", "value", "currency", "order-id", "conversion-environment", "validate-only", "job-id"];
1836
1837
  var CHANGE_HISTORY_FLAGS = ["account", "period", "from", "to", "limit", "resource", "campaign", "ad-group"];
1837
1838
  var KEYWORD_RESEARCH_FLAGS = ["url", "location", "language", "limit", "min-volume"];
1838
1839
  var TARGETING_RESEARCH_FLAGS = ["limit"];
1840
+ var NUMBER_FLAG_PATTERN = /^(?:\d+|\d+\.\d+|\.\d+)(?:e[+-]?\d+)?$/iu;
1839
1841
  function generateCampaignName2() {
1840
1842
  return `campaign ${getDateStamp()}`;
1841
1843
  }
@@ -1961,6 +1963,51 @@ function buildGoogleMediaUploadSource(flags) {
1961
1963
  if (name) source.name = name;
1962
1964
  return source;
1963
1965
  }
1966
+ function buildGoogleClickConversionUploadInput(flags) {
1967
+ const conversionId = requireSingleFlagValue(flags, "conversion", {
1968
+ missingHint: 'Run: adkit manage google conversions upload --conversion 123 --gclid <gclid> --occurred-at "2026-06-24 13:45:00+00:00" --value 120 --currency USD --validate-only'
1969
+ });
1970
+ const occurredAt = requireSingleFlagValue(flags, "occurred-at", {
1971
+ missingHint: 'Google offline uploads require a timestamp with timezone, e.g. "2026-06-24 13:45:00+00:00"'
1972
+ });
1973
+ const value = readNumberFlag(flags, "value", "Google offline uploads require --value <number>");
1974
+ const currency = requireSingleFlagValue(flags, "currency", {
1975
+ missingHint: "Google offline uploads require --currency <ISO code>, e.g. USD"
1976
+ });
1977
+ const conversion = {
1978
+ conversionId,
1979
+ occurredAt,
1980
+ value,
1981
+ currency
1982
+ };
1983
+ const gclid = readSingleFlagValue(flags, "gclid", "Use one --gclid value");
1984
+ const gbraid = readSingleFlagValue(flags, "gbraid", "Use one --gbraid value");
1985
+ const wbraid = readSingleFlagValue(flags, "wbraid", "Use one --wbraid value");
1986
+ const orderId = readSingleFlagValue(flags, "order-id", "Use one --order-id value");
1987
+ const conversionEnvironment = readSingleFlagValue(flags, "conversion-environment", "Use one --conversion-environment value");
1988
+ if (gclid) conversion.gclid = gclid;
1989
+ if (gbraid) conversion.gbraid = gbraid;
1990
+ if (wbraid) conversion.wbraid = wbraid;
1991
+ if (orderId) conversion.orderId = orderId;
1992
+ if (conversionEnvironment) conversion.conversionEnvironment = conversionEnvironment;
1993
+ return conversion;
1994
+ }
1995
+ function readNumberFlag(flags, key, hint) {
1996
+ const rawValue = requireSingleFlagValue(flags, key, { missingHint: hint });
1997
+ const trimmedValue = rawValue.trim();
1998
+ const value = NUMBER_FLAG_PATTERN.test(trimmedValue) ? Number(trimmedValue) : Number.NaN;
1999
+ if (!Number.isFinite(value) || value < 0) throw new CliError("INVALID_VALUE", `Invalid number for --${key}: ${rawValue}`, hint);
2000
+ return value;
2001
+ }
2002
+ function applyGoogleClickConversionUploadOptions(body, flags) {
2003
+ if (flags["validate-only"] === true) body.validateOnly = true;
2004
+ const rawJobId = readSingleFlagValue(flags, "job-id", "Use one --job-id value");
2005
+ if (!rawJobId) return;
2006
+ const trimmedJobId = rawJobId.trim();
2007
+ const jobId = /^\d+$/u.test(trimmedJobId) ? Number(trimmedJobId) : Number.NaN;
2008
+ if (!Number.isInteger(jobId) || jobId >= 2147483648) throw new CliError("INVALID_VALUE", `Invalid integer for --job-id: ${rawJobId}`, "Use a non-negative integer below 2147483648");
2009
+ body.jobId = jobId;
2010
+ }
1964
2011
  function resolveAssetScope(flags) {
1965
2012
  const scopeType = typeof flags.scope === "string" ? flags.scope : void 0;
1966
2013
  if (scopeType !== "account" && scopeType !== "campaign" && scopeType !== "ad-group") throw new CliError("MISSING_FLAG", "Missing required flag: `--scope`", "Use --scope account|campaign|ad-group");
@@ -2301,6 +2348,24 @@ async function uploadMedia2(client, _args, flags) {
2301
2348
  const path3 = `/manage/google/media${query}`;
2302
2349
  return client.post(path3, body);
2303
2350
  }
2351
+ async function uploadGoogleConversions(client, _args, flags) {
2352
+ validateFlags(flags, CONVERSION_UPLOAD_FLAGS, "manage google conversions upload");
2353
+ if (flags.publish === true) throw new CliError("INVALID_VALUE", "`--publish` is not used for conversion uploads", "Use --validate-only for a dry run; omit it to upload directly.");
2354
+ if (typeof flags.data === "string") {
2355
+ const rawBody = parseDataFlag(flags, 'Use { "conversions": [...] } for Google conversion upload');
2356
+ const accountId2 = resolveGoogleAccountId(rawBody, flags);
2357
+ const body2 = removeQueryOnlyBodyKeys(rawBody, ["accountId"]);
2358
+ const query2 = queryString({ accountId: accountId2 });
2359
+ const path4 = `/manage/google/conversions/upload${query2}`;
2360
+ return client.post(path4, body2);
2361
+ }
2362
+ const body = { conversions: [buildGoogleClickConversionUploadInput(flags)] };
2363
+ applyGoogleClickConversionUploadOptions(body, flags);
2364
+ const accountId = typeof flags.account === "string" ? flags.account : void 0;
2365
+ const query = queryString({ accountId });
2366
+ const path3 = `/manage/google/conversions/upload${query}`;
2367
+ return client.post(path3, body);
2368
+ }
2304
2369
  async function listGoogleCampaigns(client, _args, flags) {
2305
2370
  validateFlags(flags, CAMPAIGN_LIST_FLAGS, "manage google campaigns list");
2306
2371
  const qs = buildGoogleListQuery(flags);
@@ -2843,7 +2908,7 @@ function readTikTokPlatformOverridesFlag(flags) {
2843
2908
  function isCliTikTokPlatformOverrides(value) {
2844
2909
  return !!value && typeof value === "object" && !Array.isArray(value);
2845
2910
  }
2846
- function readNumberFlag(flags, key) {
2911
+ function readNumberFlag2(flags, key) {
2847
2912
  const value = flags[key];
2848
2913
  if (value === void 0) return void 0;
2849
2914
  if (typeof value !== "string") throw new CliError("INVALID_VALUE", `Use one --${key} value`, `Run: adkit manage tiktok --help`);
@@ -2852,8 +2917,8 @@ function readNumberFlag(flags, key) {
2852
2917
  return parsed;
2853
2918
  }
2854
2919
  function buildTikTokBudget(flags) {
2855
- const daily = readNumberFlag(flags, "budget-daily");
2856
- const lifetime = readNumberFlag(flags, "budget-lifetime");
2920
+ const daily = readNumberFlag2(flags, "budget-daily");
2921
+ const lifetime = readNumberFlag2(flags, "budget-lifetime");
2857
2922
  if (daily === void 0 && lifetime === void 0) return void 0;
2858
2923
  if (daily !== void 0 && lifetime !== void 0) throw new CliError("INVALID_VALUE", "Use either --budget-daily or --budget-lifetime", "TikTok accepts one budget mode per campaign/ad group");
2859
2924
  return daily !== void 0 ? { daily } : { lifetime };
@@ -2898,7 +2963,7 @@ function buildTikTokAdGroupPayload(flags, mode) {
2898
2963
  if (typeof flags["start-date"] === "string") payload.startDate = flags["start-date"];
2899
2964
  if (typeof flags["end-date"] === "string") payload.endDate = flags["end-date"];
2900
2965
  if (typeof flags.pacing === "string") payload.pacing = flags.pacing;
2901
- const bidAmount = readNumberFlag(flags, "bid-amount");
2966
+ const bidAmount = readNumberFlag2(flags, "bid-amount");
2902
2967
  if (bidAmount !== void 0) payload.bidAmount = bidAmount;
2903
2968
  if (typeof flags["event-type"] === "string") {
2904
2969
  payload.conversion = {
@@ -4052,7 +4117,7 @@ var FLAG = {
4052
4117
  budgetDaily: " --budget-daily <n> Daily budget in account currency",
4053
4118
  cta: " --cta <type> sign_up, learn_more, shop_now, download, get_offer, contact_us, subscribe, get_quote, book_now, apply_now"
4054
4119
  };
4055
- var RAW_PLATFORM_LABELS = { google: "Google", meta: "Meta", reddit: "Reddit", tiktok: "TikTok" };
4120
+ var RAW_PLATFORM_LABELS = { google: "Google", meta: "Meta", reddit: "Reddit", tiktok: "TikTok", x: "X" };
4056
4121
  function rawPlatformCommandLine(platform2) {
4057
4122
  return `Raw ${RAW_PLATFORM_LABELS[platform2] ?? platform2} API calls use the shared command: adkit manage platform-api-requests --platform ${platform2} ...`;
4058
4123
  }
@@ -5302,6 +5367,33 @@ Notes:
5302
5367
  Upload returns assets[].id and assets[].resourceName. Use either value in Display ad media[].id.
5303
5368
  Display media roles: marketing_image, square_marketing_image, logo, square_logo.
5304
5369
  Videos are not supported in Google Display v1; upload images only.`;
5370
+ var GOOGLE_CONVERSIONS_HELP = `adkit manage google conversions \u2014 Google Ads conversion tracking
5371
+
5372
+ upload Upload offline click conversion events
5373
+
5374
+ Flags (upload):
5375
+ --conversion <id> Google conversion ID (platformId), must be type upload_clicks
5376
+ --gclid <id> Google click ID
5377
+ --gbraid <id> GBRAID click parameter
5378
+ --wbraid <id> WBRAID click parameter
5379
+ --occurred-at <ts> Conversion timestamp with timezone, e.g. "2026-06-24 13:45:00+00:00"
5380
+ --value <n> Conversion value
5381
+ --currency <code> ISO currency code, e.g. USD
5382
+ --order-id <id> Optional order ID for dedupe/adjustments
5383
+ --conversion-environment <web|app>
5384
+ --validate-only Validate without importing conversions
5385
+ --job-id <n> Optional Google diagnostics job id
5386
+ --account <id> Optional if one Google Ads account is connected
5387
+ --data <json> Batch body: {"conversions":[...],"validateOnly":true}
5388
+
5389
+ Examples:
5390
+ adkit manage google conversions upload --conversion 123 --gclid EAIaIQob... --occurred-at "2026-06-24 13:45:00+00:00" --value 120 --currency USD --validate-only
5391
+ adkit manage google conversions upload --data '{"conversions":[{"conversionId":"123","gclid":"EAIaIQob...","occurredAt":"2026-06-24 13:45:00+00:00","value":120,"currency":"USD"}],"validateOnly":true}' --account 1234567890
5392
+
5393
+ Notes:
5394
+ Upload sends events directly to Google; it is not a draft flow.
5395
+ Use --validate-only before a real upload when testing a new CRM/backend export.
5396
+ Real uploads require publish access.`;
5305
5397
  var META_RESEARCH_HELP = `adkit manage meta research \u2014 Meta Ads research tools
5306
5398
 
5307
5399
  interests <query> Search targeting interests (returns IDs for ad set targeting)
@@ -5362,6 +5454,7 @@ Examples:
5362
5454
  "google change-history": GOOGLE_CHANGE_HISTORY_HELP,
5363
5455
  "google research": GOOGLE_RESEARCH_HELP,
5364
5456
  "google media": GOOGLE_MEDIA_HELP,
5457
+ "google conversions": GOOGLE_CONVERSIONS_HELP,
5365
5458
  "tiktok accounts": `adkit manage tiktok accounts \u2014 TikTok Ads accounts
5366
5459
 
5367
5460
  list List connected TikTok advertisers
@@ -5536,20 +5629,20 @@ Examples:
5536
5629
  "platform-api-requests": `adkit manage platform-api-requests \u2014 Send raw API requests to ad platforms
5537
5630
 
5538
5631
  Bypasses normalized AdKit entity validation, but still runs account and safety checks.
5539
- GET requests execute immediately. POST/PATCH/DELETE create drafts by default; add --publish to execute mutating requests immediately.
5540
- Must be enabled in project settings first.
5632
+ GET requests execute immediately. POST/PUT/PATCH/DELETE create drafts by default; add --publish to execute mutating requests immediately.
5633
+ Must be enabled in Agent Permissions first.
5541
5634
  Use this for unsupported native platform resources/workflows. Use platformOverrides instead when you only need raw fields on a supported normalized resource.
5542
5635
  Use the selected platform's official endpoint paths, field names, enum values, and resource shapes. Do not translate normalized AdKit field names into raw API payloads by guessing.
5543
5636
 
5544
5637
  Flags:
5545
5638
  --data <json> Full request object (preferred for agents)
5546
- --platform <meta|google|tiktok|reddit> Target platform (required)
5639
+ --platform <meta|google|tiktok|reddit|x> Target platform (required)
5547
5640
  --endpoint <path> Relative API path (required)
5548
- --payload <json> JSON body for POST/PATCH, query params for GET, omit for DELETE
5549
- --method <GET|POST|PATCH|DELETE> HTTP method (default: POST)
5641
+ --payload <json> JSON body for POST/PUT/PATCH, query params for GET, omit for DELETE
5642
+ --method <GET|POST|PUT|PATCH|DELETE> HTTP method (default: POST)
5550
5643
  --request-description <text> What this request does (required)
5551
5644
  --account <id> Ad account ID (required)
5552
- --publish Execute POST/PATCH/DELETE immediately instead of creating a draft
5645
+ --publish Execute POST/PUT/PATCH/DELETE immediately instead of creating a draft
5553
5646
 
5554
5647
  --data fields:
5555
5648
  platform, endpoint, payload, description, accountId, method, publish
@@ -5559,7 +5652,8 @@ Examples:
5559
5652
  adkit manage platform-api-requests --platform meta --endpoint "act_123/campaigns" --payload '{"name":"Test","objective":"OUTCOME_TRAFFIC","status":"PAUSED","special_ad_categories":[]}' --request-description "Create campaign" --account act_123 --publish
5560
5653
  adkit manage platform-api-requests --platform google --endpoint "customers/123/googleAds:mutate" --payload '{"mutateOperations":[...]}' --request-description "Pause ad" --account 123
5561
5654
  adkit manage platform-api-requests --platform tiktok --endpoint "campaign/get/" --method GET --payload '{"advertiser_id":"123"}' --request-description "List TikTok campaigns" --account 123
5562
- adkit manage platform-api-requests --platform reddit --endpoint "ad_accounts/a2_example/campaigns" --payload '{"name":"Test","objective":"TRAFFIC","configured_status":"PAUSED"}' --request-description "Create paused Reddit campaign" --account a2_example`.trim(),
5655
+ adkit manage platform-api-requests --platform reddit --endpoint "ad_accounts/a2_example/campaigns" --payload '{"name":"Test","objective":"TRAFFIC","configured_status":"PAUSED"}' --request-description "Create paused Reddit campaign" --account a2_example
5656
+ adkit manage platform-api-requests --platform x --endpoint "accounts/18ce54d4x5t/campaigns" --method GET --request-description "List X campaigns" --account 18ce54d4x5t`.trim(),
5563
5657
  manage: `adkit manage \u2014 Ad platform management
5564
5658
 
5565
5659
  Platforms:
@@ -5567,6 +5661,7 @@ Platforms:
5567
5661
  google Google Ads
5568
5662
  tiktok TikTok Ads
5569
5663
  reddit Reddit Ads
5664
+ x X Ads raw API access
5570
5665
  drafts Manage drafts across platforms
5571
5666
  platform-api-requests Send raw API requests (escape hatch)
5572
5667
 
@@ -5604,6 +5699,7 @@ Entity groups:
5604
5699
  ads Manage responsive search and Display ads
5605
5700
  keywords Manage keywords and negatives \u2014 config only, not metrics
5606
5701
  keywords negative-lists Shared negative keyword lists (create, attach to campaigns)
5702
+ conversions Manage conversion tracking and upload offline conversions
5607
5703
  results Performance metrics (campaigns, ad-groups, ads, keywords, search-terms)
5608
5704
  change-history Recent Google Ads account changes from the last 30 days
5609
5705
  research Keyword Planner plus Display topic/interest IDs
@@ -5615,7 +5711,8 @@ ${FLAG.account}
5615
5711
  ${FLAG.publish}
5616
5712
  ${FLAG.data}
5617
5713
 
5618
- Mutations are draft-first by default. Use --publish to publish immediately.
5714
+ Config mutations are draft-first by default. Use --publish to publish immediately.
5715
+ Conversion uploads send events directly; use --validate-only for a dry run.
5619
5716
  ${rawPlatformCommandLine("google")}
5620
5717
  Display path: research topics/interests, upload images with google media, create campaigns --campaign-type display, create ad-groups with targeting, then create ads with type:"responsive_display".
5621
5718
  Google Display Ads is in beta \u2014 some first-class normalized Display features may not be available yet.
@@ -5648,6 +5745,15 @@ General flags:
5648
5745
  ${FLAG.account}
5649
5746
 
5650
5747
  Run adkit manage reddit accounts --help for account setup.`.trim(),
5748
+ x: `adkit manage x \u2014 X Ads raw API access
5749
+
5750
+ X is currently exposed through Advanced Platform Access only.
5751
+ Use platform-api-requests with official X Ads API endpoint paths.
5752
+
5753
+ ${rawPlatformCommandLine("x")}
5754
+
5755
+ Examples:
5756
+ adkit manage platform-api-requests --platform x --endpoint "accounts/18ce54d4x5t/campaigns" --method GET --request-description "List X campaigns" --account 18ce54d4x5t`.trim(),
5651
5757
  drafts: `adkit manage drafts \u2014 Manage drafts
5652
5758
 
5653
5759
  list List all drafts
@@ -5901,6 +6007,7 @@ var HELP_FULL = {
5901
6007
  "google change-history": GOOGLE_CHANGE_HISTORY_HELP,
5902
6008
  "google research": GOOGLE_RESEARCH_HELP,
5903
6009
  "google media": GOOGLE_MEDIA_HELP,
6010
+ "google conversions": GOOGLE_CONVERSIONS_HELP,
5904
6011
  "meta research": META_RESEARCH_HELP,
5905
6012
  "studio generate": STUDIO_GENERATE_HELP_FULL,
5906
6013
  "library advertisers": `adkit library advertisers \u2014 Browse, inspect, and discover advertisers
@@ -6573,7 +6680,7 @@ function readRawRequestData(flags) {
6573
6680
  };
6574
6681
  }
6575
6682
  function readRawRequestFlags(flags) {
6576
- const platform2 = requireFlag(flags, "platform", "Required: --platform meta, google, tiktok, or reddit");
6683
+ const platform2 = requireFlag(flags, "platform", "Required: --platform meta, google, tiktok, reddit, or x");
6577
6684
  const method = readRawRequestMethod(flags.method);
6578
6685
  const rawPayload = readRawRequestFlagPayload(flags);
6579
6686
  const payload = readRawRequestPayload({ method, payload: rawPayload, source: "flag" });
@@ -6608,12 +6715,12 @@ function readRawRequestString(input) {
6608
6715
  throw new CliError("MISSING_FLAG", `Missing required field: \`${input.field}\``, input.hint);
6609
6716
  }
6610
6717
  function readRawRequestPlatform(value) {
6611
- if (value === "meta" || value === "google" || value === "tiktok" || value === "reddit") return value;
6612
- throw new CliError("INVALID_VALUE", `Invalid platform: ${String(value)}`, "Use meta, google, tiktok, or reddit");
6718
+ if (value === "meta" || value === "google" || value === "tiktok" || value === "reddit" || value === "x") return value;
6719
+ throw new CliError("INVALID_VALUE", `Invalid platform: ${String(value)}`, "Use meta, google, tiktok, reddit, or x");
6613
6720
  }
6614
6721
  function readRawRequestMethod(value) {
6615
6722
  const method = typeof value === "string" ? value.toUpperCase() : "POST";
6616
- if (method !== "GET" && method !== "POST" && method !== "PATCH" && method !== "DELETE") throw new CliError("INVALID_VALUE", `Invalid method: ${method}`, "Use GET, POST, PATCH, or DELETE");
6723
+ if (method !== "GET" && method !== "POST" && method !== "PUT" && method !== "PATCH" && method !== "DELETE") throw new CliError("INVALID_VALUE", `Invalid method: ${method}`, "Use GET, POST, PUT, PATCH, or DELETE");
6617
6724
  return method;
6618
6725
  }
6619
6726
  function readRawRequestPublish(input) {
@@ -6631,8 +6738,8 @@ function readRawRequestFlagPayload(flags) {
6631
6738
  }
6632
6739
  function readRawRequestPayload(input) {
6633
6740
  if (input.method !== "GET" && input.method !== "DELETE" && (input.payload === void 0 || input.payload === null)) {
6634
- if (input.source === "data") throw new CliError("MISSING_FLAG", "POST/PATCH requests require payload in --data", 'Include "payload": {"key":"value"}');
6635
- throw new CliError("MISSING_FLAG", "POST/PATCH requests require --payload", `Add --payload '{"key":"value"}'`);
6741
+ if (input.source === "data") throw new CliError("MISSING_FLAG", "POST/PUT/PATCH requests require payload in --data", 'Include "payload": {"key":"value"}');
6742
+ throw new CliError("MISSING_FLAG", "POST/PUT/PATCH requests require --payload", `Add --payload '{"key":"value"}'`);
6636
6743
  }
6637
6744
  if (input.method === "DELETE" && input.payload !== void 0 && input.payload !== null) throw new CliError("INVALID_VALUE", "DELETE requests do not support payload", "Put identifiers in the endpoint path");
6638
6745
  return input.payload ?? null;
@@ -6779,7 +6886,7 @@ async function main() {
6779
6886
  return;
6780
6887
  }
6781
6888
  const platform2 = manageTarget;
6782
- if (platform2 !== "meta" && platform2 !== "google" && platform2 !== "tiktok" && platform2 !== "reddit") throw new CliError("UNKNOWN_COMMAND", `Unknown platform: ${platform2}`, "Available: meta, google, tiktok, reddit, drafts, platform-api-requests");
6889
+ if (platform2 !== "meta" && platform2 !== "google" && platform2 !== "tiktok" && platform2 !== "reddit" && platform2 !== "x") throw new CliError("UNKNOWN_COMMAND", `Unknown platform: ${platform2}`, "Available: meta, google, tiktok, reddit, x, drafts, platform-api-requests");
6783
6890
  const entity = args[2];
6784
6891
  const action = args[3];
6785
6892
  const restArgs = args.slice(4);
@@ -6817,7 +6924,7 @@ async function main() {
6817
6924
  case "list":
6818
6925
  case void 0:
6819
6926
  data = await listAccounts(client, restArgs, flags);
6820
- emptyHint = "No Meta ad accounts connected. Run `adkit setup manage` or connect via https://app.adkit.so/settings/integrations";
6927
+ emptyHint = "No Meta ad accounts connected. Run `adkit setup manage` or connect a workspace login via https://app.adkit.so/dashboard/settings/workspace-integrations";
6821
6928
  break;
6822
6929
  case "connect":
6823
6930
  data = await connectAccount(client, restArgs, flags);
@@ -6988,7 +7095,7 @@ async function main() {
6988
7095
  case "list":
6989
7096
  case void 0:
6990
7097
  data = await listAccounts2(client, restArgs, flags);
6991
- emptyHint = "No Google Ads accounts connected. Run `adkit setup manage` or connect via https://app.adkit.so/settings/integrations";
7098
+ emptyHint = "No Google Ads accounts connected. Run `adkit setup manage` or connect a workspace login via https://app.adkit.so/dashboard/settings/workspace-integrations";
6992
7099
  break;
6993
7100
  case "available":
6994
7101
  data = await listAvailable(client, restArgs, flags);
@@ -7220,6 +7327,20 @@ async function main() {
7220
7327
  else data = await listGoogleResults(client, restArgs, flags);
7221
7328
  break;
7222
7329
  }
7330
+ case "conversions": {
7331
+ if (!action || flags.help) {
7332
+ showHelp("google conversions", flags.help === "full");
7333
+ process.exit(0);
7334
+ }
7335
+ switch (action) {
7336
+ case "upload":
7337
+ data = await uploadGoogleConversions(client, restArgs, flags);
7338
+ break;
7339
+ default:
7340
+ throw new CliError("UNKNOWN_COMMAND", `Unknown action: google conversions ${action}`, "Available: upload");
7341
+ }
7342
+ break;
7343
+ }
7223
7344
  case "change-history": {
7224
7345
  if (action && action !== "list") throw new CliError("UNKNOWN_COMMAND", `Unknown action: google change-history ${action}`, "Available: list");
7225
7346
  data = await listGoogleChangeHistory(client, restArgs, flags);
@@ -7246,7 +7367,7 @@ async function main() {
7246
7367
  break;
7247
7368
  }
7248
7369
  default:
7249
- throw new CliError("UNKNOWN_COMMAND", `Unknown entity: google ${entity}`, "Available: accounts, assets, media, campaigns, ad-groups, ads, keywords, results, change-history, research");
7370
+ throw new CliError("UNKNOWN_COMMAND", `Unknown entity: google ${entity}`, "Available: accounts, assets, media, campaigns, ad-groups, ads, keywords, conversions, results, change-history, research");
7250
7371
  }
7251
7372
  } else if (platform2 === "tiktok") {
7252
7373
  switch (entity) {
@@ -7255,7 +7376,7 @@ async function main() {
7255
7376
  case "list":
7256
7377
  case void 0:
7257
7378
  data = await listTikTokAccounts(client, restArgs, flags);
7258
- emptyHint = "No TikTok Ads accounts connected. Run `adkit setup manage` or connect via https://app.adkit.so/settings/integrations";
7379
+ emptyHint = "No TikTok Ads accounts connected. Run `adkit setup manage` or connect a workspace login via https://app.adkit.so/dashboard/settings/workspace-integrations";
7259
7380
  break;
7260
7381
  case "available":
7261
7382
  data = await listTikTokAvailableAccounts(client, restArgs, flags);
@@ -7372,7 +7493,7 @@ async function main() {
7372
7493
  case "list":
7373
7494
  case void 0:
7374
7495
  data = await listRedditAccounts(client, restArgs, flags);
7375
- emptyHint = "No Reddit Ads accounts connected. Run `adkit setup manage` or connect via https://app.adkit.so/settings/integrations";
7496
+ emptyHint = "No Reddit Ads accounts connected. Run `adkit setup manage` or connect a workspace login via https://app.adkit.so/dashboard/settings/workspace-integrations";
7376
7497
  break;
7377
7498
  case "available":
7378
7499
  data = await listRedditAvailableAccounts(client, restArgs, flags);
@@ -7392,7 +7513,8 @@ async function main() {
7392
7513
  default:
7393
7514
  throw new CliError("UNKNOWN_COMMAND", `Unknown entity: reddit ${entity}`, "Available: accounts, platform-api-requests");
7394
7515
  }
7395
- } else throw new CliError("UNKNOWN_COMMAND", "Unknown platform", "Available: meta, google, tiktok, reddit, drafts, platform-api-requests");
7516
+ } else if (platform2 === "x") throw new CliError("UNKNOWN_COMMAND", `Unknown entity: x ${entity}`, "Available: platform-api-requests");
7517
+ else throw new CliError("UNKNOWN_COMMAND", "Unknown platform", "Available: meta, google, tiktok, reddit, x, drafts, platform-api-requests");
7396
7518
  printResult(data, flags, emptyHint, detailEntity);
7397
7519
  return;
7398
7520
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adkit/cli",
3
- "version": "1.12.21",
3
+ "version": "1.12.23",
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",