@adkit/cli 1.13.0 → 1.13.2

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 +101 -31
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1834,7 +1834,7 @@ var CAMPAIGN_CREATE_FLAGS = ["name", "status", "budget-daily", "campaign-type",
1834
1834
  var CAMPAIGN_UPDATE_FLAGS = ["name", "status", "budget-daily", "bid-strategy", "target-cpa", "target-roas", "search-partners", "display-network", "tracking-url-suffix", "countries"];
1835
1835
  var AD_GROUP_LIST_FLAGS = ["campaign", "status", "limit", "offset"];
1836
1836
  var AD_GROUP_FLAGS = ["campaign", "name", "status", "cpc-bid"];
1837
- var AD_LIST_FLAGS = ["ad-group", "status", "policy-status", "limit", "offset"];
1837
+ var AD_LIST_FLAGS = ["ad-group", "campaign", "status", "policy-status", "limit", "offset"];
1838
1838
  var AD_FLAGS2 = ["headline", "headline-1", "headline-2", "headline-3", "description", "description-1", "description-2", "callout", "sitelink", "final-url", "path", "ad-group", "status"];
1839
1839
  var KEYWORD_LIST_FLAGS = ["ad-group", "campaign", "status", "limit", "offset"];
1840
1840
  var KEYWORD_FLAGS = ["ad-group", "text", "match-type", "cpc-bid", "status"];
@@ -2484,8 +2484,9 @@ async function deleteAdGroup(client, args, flags) {
2484
2484
  }
2485
2485
  async function listGoogleAds(client, _args, flags) {
2486
2486
  validateFlags(flags, AD_LIST_FLAGS, "manage google ads list");
2487
- const adGroupId = typeof flags["ad-group"] === "string" ? flags["ad-group"] : void 0;
2488
- const qs = buildGoogleListQuery(flags, { adGroupId });
2487
+ const adGroupIds = typeof flags["ad-group"] === "string" ? flags["ad-group"] : void 0;
2488
+ const campaignIds = typeof flags.campaign === "string" ? flags.campaign : void 0;
2489
+ const qs = buildGoogleListQuery(flags, { adGroupIds, campaignIds });
2489
2490
  const path3 = `/manage/google/ads${qs}`;
2490
2491
  return client.get(path3);
2491
2492
  }
@@ -2782,17 +2783,25 @@ async function listGoogleKeywordResults(client, _args, flags) {
2782
2783
  }
2783
2784
  async function researchKeywords(client, _args, flags) {
2784
2785
  validateFlags(flags, KEYWORD_RESEARCH_FLAGS, "manage google research keywords");
2785
- const keywords = _args.join(",");
2786
- if (!keywords) throw new CliError("MISSING_ARGUMENT", "At least one seed keyword is required", 'Run: adkit manage google research keywords "saas ads" --account 1234567890');
2786
+ const keywords = _args.map((keyword) => keyword.trim());
2787
+ const hasBlankKeyword = keywords.some((keyword) => keyword.length === 0);
2788
+ if (keywords.length === 0) throw new CliError("MISSING_ARGUMENT", "At least one seed keyword is required", 'Run: adkit manage google research keywords "saas ads" --account 1234567890');
2789
+ if (hasBlankKeyword) throw new CliError("INVALID_VALUE", "Seed keywords must be non-empty", 'Run: adkit manage google research keywords "saas ads" --account 1234567890');
2787
2790
  const url = typeof flags.url === "string" ? flags.url : void 0;
2788
2791
  const location = typeof flags.location === "string" ? flags.location : void 0;
2789
2792
  const language = typeof flags.language === "string" ? flags.language : void 0;
2790
2793
  const limit = typeof flags.limit === "string" ? flags.limit : void 0;
2791
2794
  const minVolume = typeof flags["min-volume"] === "string" ? flags["min-volume"] : void 0;
2792
2795
  const accountId = typeof flags.account === "string" ? flags.account : void 0;
2793
- const qs = queryString({ accountId, keywords, url, location, language, limit, minVolume });
2794
- const path3 = `/manage/google/research/keywords${qs}`;
2795
- return client.get(path3);
2796
+ return client.post("/manage/google/research/keywords", {
2797
+ accountId,
2798
+ keywords,
2799
+ url,
2800
+ location,
2801
+ language,
2802
+ limit,
2803
+ minVolume
2804
+ });
2796
2805
  }
2797
2806
  async function researchTopics(client, args, flags) {
2798
2807
  validateFlags(flags, TARGETING_RESEARCH_FLAGS, "manage google research topics");
@@ -3493,6 +3502,12 @@ function buildLinkedInMediaUploadSource(flags) {
3493
3502
  return source;
3494
3503
  }
3495
3504
 
3505
+ // src/commands/microsoft.ts
3506
+ async function listMicrosoftAvailableAccounts(client, _args, flags) {
3507
+ validateFlags(flags, [], "manage microsoft accounts available");
3508
+ return client.get("/manage/microsoft/accounts/available");
3509
+ }
3510
+
3496
3511
  // src/commands/status.ts
3497
3512
  function isStatusResponse(value) {
3498
3513
  if (!value || typeof value !== "object") return false;
@@ -4144,7 +4159,10 @@ function wrapToLines(value, max) {
4144
4159
  if (word.length > max) {
4145
4160
  if (current) lines.push(current);
4146
4161
  current = "";
4147
- for (let i = 0; i < word.length; i += max) lines.push(word.slice(i, i + max));
4162
+ for (let i = 0; i < word.length; i += max) {
4163
+ const chunk = word.slice(i, i + max);
4164
+ lines.push(chunk);
4165
+ }
4148
4166
  continue;
4149
4167
  }
4150
4168
  const next = current ? current + " " + word : word;
@@ -4158,14 +4176,19 @@ function wrapToLines(value, max) {
4158
4176
  if (current) lines.push(current);
4159
4177
  return lines.length > 0 ? lines : [""];
4160
4178
  }
4161
- function formatSearchTermCost(cost) {
4162
- return `$${cost.toFixed(2)}`;
4179
+ function formatSearchTermMoney(value) {
4180
+ return `$${value.toFixed(2)}`;
4163
4181
  }
4164
4182
  function formatSearchTermConversions(conversions) {
4165
4183
  if (conversions === 0) return "0";
4166
4184
  const fixed = conversions.toFixed(2);
4167
4185
  return fixed.replace(/\.?0+$/, "");
4168
4186
  }
4187
+ function formatSearchTermRoas(roas) {
4188
+ if (roas === 0) return "0x";
4189
+ const fixed = roas.toFixed(2);
4190
+ return fixed.replace(/\.?0+$/, "") + "x";
4191
+ }
4169
4192
  function hasSearchTermStringFields(value) {
4170
4193
  if (value === null || typeof value !== "object") return false;
4171
4194
  if (!("searchTerm" in value) || typeof value.searchTerm !== "string") return false;
@@ -4176,7 +4199,11 @@ function hasSearchTermStringFields(value) {
4176
4199
  function hasSearchTermNumberFields(value) {
4177
4200
  if (value === null || typeof value !== "object") return false;
4178
4201
  if (!("impressions" in value) || typeof value.impressions !== "number") return false;
4202
+ if (!("clicks" in value) || typeof value.clicks !== "number") return false;
4179
4203
  if (!("cost" in value) || typeof value.cost !== "number") return false;
4204
+ if (!("conversions" in value) || typeof value.conversions !== "number") return false;
4205
+ if (!("conversionsValue" in value) || typeof value.conversionsValue !== "number") return false;
4206
+ if (!("roas" in value) || typeof value.roas !== "number") return false;
4180
4207
  return true;
4181
4208
  }
4182
4209
  function isGoogleSearchTermRecord(value) {
@@ -4199,8 +4226,10 @@ function toGoogleSearchTermDisplayRows(row) {
4199
4226
  MATCH: isFirst ? row.matchType : "",
4200
4227
  IMPR: isFirst ? row.impressions : "",
4201
4228
  CLICKS: isFirst ? row.clicks : "",
4202
- COST: isFirst ? formatSearchTermCost(row.cost) : "",
4203
- CONV: isFirst ? formatSearchTermConversions(row.conversions) : ""
4229
+ COST: isFirst ? formatSearchTermMoney(row.cost) : "",
4230
+ CONV: isFirst ? formatSearchTermConversions(row.conversions) : "",
4231
+ VALUE: isFirst ? formatSearchTermMoney(row.conversionsValue) : "",
4232
+ ROAS: isFirst ? formatSearchTermRoas(row.roas) : ""
4204
4233
  });
4205
4234
  }
4206
4235
  return result;
@@ -4456,7 +4485,7 @@ var FLAG = {
4456
4485
  budgetDaily: " --budget-daily <n> Daily budget in account currency",
4457
4486
  cta: " --cta <type> sign_up, learn_more, shop_now, download, get_offer, contact_us, subscribe, get_quote, book_now, apply_now"
4458
4487
  };
4459
- var RAW_PLATFORM_LABELS = { google: "Google", meta: "Meta", reddit: "Reddit", tiktok: "TikTok", x: "X", linkedin: "LinkedIn" };
4488
+ var RAW_PLATFORM_LABELS = { google: "Google", meta: "Meta", reddit: "Reddit", tiktok: "TikTok", x: "X", linkedin: "LinkedIn", microsoft: "Microsoft" };
4460
4489
  function rawPlatformCommandLine(platform2) {
4461
4490
  return `Raw ${RAW_PLATFORM_LABELS[platform2] ?? platform2} API calls use the shared command: adkit manage platform-api-requests --platform ${platform2} ...`;
4462
4491
  }
@@ -5268,7 +5297,8 @@ Flags (create/update):
5268
5297
  --status <s> enabled, paused, removed
5269
5298
 
5270
5299
  Flags (list):
5271
- --ad-group <id> Filter by Google ad group ID (platformId)
5300
+ --campaign <ids> Filter by Google campaign IDs (platformId, comma-separated)
5301
+ --ad-group <ids> Filter by Google ad group IDs (platformId, comma-separated)
5272
5302
  --status <s> Filter by ad status (default: enabled,paused; use all for every status)
5273
5303
  --policy-status <s> Filter by policy status: approved, limited, disapproved, problem, pending_review, under_appeal
5274
5304
  --limit <n> Max results
@@ -5287,6 +5317,7 @@ Notes:
5287
5317
  That means sibling ads in the same ad group may also use those assets. Use google assets if you need explicit scope control or richer sitelink payloads.
5288
5318
 
5289
5319
  Examples:
5320
+ adkit manage google ads list --account 1234567890 --campaign 987654321,987654322
5290
5321
  adkit manage google ads list --account 1234567890 --ad-group 555666777
5291
5322
  adkit manage google ads create --data '{"ads":[{"type":"responsive_display","adGroupId":"555666777","headlines":[{"text":"Display headline"}],"longHeadline":{"text":"A longer Display headline"},"descriptions":[{"text":"Display description"}],"businessName":"AdKit","finalUrls":["https://example.com"],"media":[{"role":"marketing_image","id":"customers/123/assets/111"},{"role":"square_marketing_image","id":"customers/123/assets/222"},{"role":"logo","id":"customers/123/assets/333"},{"role":"square_logo","id":"customers/123/assets/444"}]}]}' --account 1234567890
5292
5323
  adkit manage google ads create --ad-group 555666777 \\
@@ -5322,7 +5353,8 @@ ${FLAG.publish}
5322
5353
  ${FLAG.data}
5323
5354
 
5324
5355
  Flags (list):
5325
- --ad-group <id> Filter by Google ad group ID (platformId)
5356
+ --campaign <ids> Filter by Google campaign IDs (platformId, comma-separated)
5357
+ --ad-group <ids> Filter by Google ad group IDs (platformId, comma-separated)
5326
5358
  --status <s> Filter by ad status (default: enabled,paused; use all for every status)
5327
5359
  --policy-status <s> Filter by policy status: approved, limited, disapproved, problem, pending_review, under_appeal
5328
5360
  --limit <n> Max results
@@ -5343,6 +5375,7 @@ Notes:
5343
5375
  Path format: pass one string like "crm" or "crm/demo". AdKit normalizes extra slashes, and each segment must stay within Google's 15-character limit.
5344
5376
 
5345
5377
  Examples:
5378
+ adkit manage google ads list --account 1234567890 --campaign 987654321,987654322
5346
5379
  adkit manage google ads list --account 1234567890 --ad-group 555666777
5347
5380
  adkit manage google ads create --data '{"ads":[{"type":"responsive_display","adGroupId":"555666777","headlines":[{"text":"Display headline"}],"longHeadline":{"text":"A longer Display headline"},"descriptions":[{"text":"Display description"}],"businessName":"AdKit","finalUrls":["https://example.com"],"media":[{"role":"marketing_image","id":"customers/123/assets/111"},{"role":"square_marketing_image","id":"customers/123/assets/222"},{"role":"logo","id":"customers/123/assets/333"},{"role":"square_logo","id":"customers/123/assets/444"}]}]}' --account 1234567890
5348
5381
  adkit manage google ads create --ad-group 555666777 \\
@@ -5617,6 +5650,8 @@ Flags:
5617
5650
  --limit <n> Max results
5618
5651
  --raw Return raw Google API response
5619
5652
 
5653
+ Output includes conversion value and ROAS so tROAS accounts can be judged from the same rows.
5654
+
5620
5655
  Examples:
5621
5656
  adkit manage google results search-terms --account 1234567890
5622
5657
  adkit manage google results search-terms --account 1234567890 --campaign 456 --period 30d --sort clicks
@@ -5659,7 +5694,7 @@ Examples:
5659
5694
  adkit manage google results keywords --account 1234567890 --period 30d --fields all`;
5660
5695
  var GOOGLE_RESEARCH_HELP = `adkit manage google research \u2014 Google Ads research tools
5661
5696
 
5662
- keywords <query> Get keyword ideas from Google Keyword Planner
5697
+ keywords <keyword...> Get keyword ideas from Google Keyword Planner
5663
5698
  topics <query> Find Display topic IDs for targeting.content.topics
5664
5699
  interests <query> Find Display interest IDs for targeting.audience.interests
5665
5700
 
@@ -5681,6 +5716,7 @@ Examples:
5681
5716
  adkit manage google research interests software --account 1234567890
5682
5717
 
5683
5718
  Notes:
5719
+ Keyword research: pass each seed keyword as a separate argument. Do not comma-separate keywords.
5684
5720
  Topic search returns IDs for targeting.content.topics.include/exclude.
5685
5721
  Interest search returns IDs for targeting.audience.interests.include/exclude.
5686
5722
  Websites use direct URLs in targeting.content.websites.include/exclude. Custom audiences are Google user list IDs.`;
@@ -6150,9 +6186,9 @@ Examples:
6150
6186
 
6151
6187
  Flags:
6152
6188
  --data <json> Full request object (preferred for agents)
6153
- --platform <meta|google|tiktok|reddit|x|linkedin> Target platform (required)
6154
- --endpoint <path> Relative API path (required)
6155
- --payload <json> JSON body for POST/PUT/PATCH, query params for GET, omit for DELETE
6189
+ --platform <meta|google|tiktok|reddit|x|linkedin|microsoft> Target platform (required)
6190
+ --endpoint <path> Relative API path (required). Microsoft is the exception: pass the full https URL to a Bing Ads v13 host
6191
+ --payload <json> JSON body for POST/PUT/PATCH, query params for GET, omit for DELETE (exception: Microsoft DELETE takes a JSON body of ids)
6156
6192
  --method <GET|POST|PUT|PATCH|DELETE> HTTP method (default: POST)
6157
6193
  --request-description <text> What this request does (required)
6158
6194
  --account <id> Ad account ID (required)
@@ -6168,7 +6204,8 @@ Examples:
6168
6204
  adkit manage platform-api-requests --platform tiktok --endpoint "campaign/get/" --method GET --payload '{"advertiser_id":"123"}' --request-description "List TikTok campaigns" --account 123
6169
6205
  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
6170
6206
  adkit manage platform-api-requests --platform x --endpoint "accounts/18ce54d4x5t/campaigns" --method GET --request-description "List X campaigns" --account 18ce54d4x5t
6171
- adkit manage platform-api-requests --platform linkedin --endpoint "adCampaignGroups/(account:urn:li:sponsoredAccount:512345678)" --method GET --request-description "List LinkedIn campaign groups" --account 512345678`.trim(),
6207
+ adkit manage platform-api-requests --platform linkedin --endpoint "adCampaignGroups/(account:urn:li:sponsoredAccount:512345678)" --method GET --request-description "List LinkedIn campaign groups" --account 512345678
6208
+ adkit manage platform-api-requests --platform microsoft --endpoint "https://campaign.api.bingads.microsoft.com/CampaignManagement/v13/Campaigns/QueryByAccountId" --payload '{"AccountId":187276743,"CampaignType":"Search"}' --request-description "List Microsoft campaigns" --account 187276743 --publish`.trim(),
6172
6209
  manage: `adkit manage \u2014 Ad platform management
6173
6210
 
6174
6211
  Platforms:
@@ -6178,6 +6215,7 @@ Platforms:
6178
6215
  reddit Reddit Ads
6179
6216
  x X Ads raw API access
6180
6217
  linkedin LinkedIn Ads (campaigns, ad groups, ads, targeting, results)
6218
+ microsoft Microsoft Ads raw API access + account discovery
6181
6219
  drafts Manage drafts across platforms
6182
6220
  platform-api-requests Send raw API requests (escape hatch)
6183
6221
 
@@ -6270,6 +6308,21 @@ ${rawPlatformCommandLine("x")}
6270
6308
 
6271
6309
  Examples:
6272
6310
  adkit manage platform-api-requests --platform x --endpoint "accounts/18ce54d4x5t/campaigns" --method GET --request-description "List X campaigns" --account 18ce54d4x5t`.trim(),
6311
+ microsoft: `adkit manage microsoft \u2014 Microsoft Ads raw API access + account discovery
6312
+
6313
+ Microsoft (Bing) is currently exposed through Advanced Platform Access, plus account discovery.
6314
+ Endpoints are FULL https URLs to Bing Ads v13 hosts (campaign/reporting/bulk .api.bingads.microsoft.com) \u2014 not relative paths.
6315
+ Bing REST puts the operation in the HTTP verb; query reads are POST to .../Query* paths.
6316
+ Because query reads are POST, add --publish on read-only Query* calls \u2014 otherwise you get a draft instead of data.
6317
+
6318
+ ${rawPlatformCommandLine("microsoft")}
6319
+
6320
+ Commands:
6321
+ accounts available List Microsoft ad accounts discoverable from the connected workspace login
6322
+
6323
+ Examples:
6324
+ adkit manage microsoft accounts available
6325
+ adkit manage platform-api-requests --platform microsoft --endpoint "https://campaign.api.bingads.microsoft.com/CampaignManagement/v13/Campaigns/QueryByAccountId" --payload '{"AccountId":187276743,"CampaignType":"Search"}' --request-description "List Microsoft campaigns" --account 187276743 --publish`.trim(),
6273
6326
  linkedin: `adkit manage linkedin \u2014 LinkedIn Ads management
6274
6327
 
6275
6328
  Entity groups:
@@ -7202,13 +7255,14 @@ function readRawRequestData(flags) {
7202
7255
  const data = parseDataFlag(flags, `Run: adkit manage platform-api-requests --data '{"platform":"meta","endpoint":"act_123/campaigns","payload":{},"description":"Create campaign","accountId":"act_123"}'`);
7203
7256
  if (!data || typeof data !== "object" || Array.isArray(data)) throw new CliError("INVALID_VALUE", "--data must be a JSON object", "Include platform, endpoint, payload, description, and accountId");
7204
7257
  const input = data;
7258
+ const platform2 = readRawRequestPlatform(input.platform);
7205
7259
  const method = readRawRequestMethod(input.method);
7206
7260
  const publish = readRawRequestPublish({ data: input, flags });
7207
7261
  const description = readRawRequestDataDescription(input);
7208
- const payload = readRawRequestPayload({ method, payload: input.payload, source: "data" });
7262
+ const payload = readRawRequestPayload({ method, payload: input.payload, platform: platform2, source: "data" });
7209
7263
  return {
7210
7264
  body: {
7211
- platform: readRawRequestPlatform(input.platform),
7265
+ platform: platform2,
7212
7266
  endpoint: readRawRequestString({ value: input.endpoint, field: "endpoint", hint: "Include endpoint in --data" }),
7213
7267
  payload,
7214
7268
  method,
@@ -7219,13 +7273,14 @@ function readRawRequestData(flags) {
7219
7273
  };
7220
7274
  }
7221
7275
  function readRawRequestFlags(flags) {
7222
- const platform2 = requireFlag(flags, "platform", "Required: --platform meta, google, tiktok, reddit, x, or linkedin");
7276
+ const platformFlag = requireFlag(flags, "platform", "Required: --platform meta, google, tiktok, reddit, x, linkedin, or microsoft");
7277
+ const platform2 = readRawRequestPlatform(platformFlag);
7223
7278
  const method = readRawRequestMethod(flags.method);
7224
7279
  const rawPayload = readRawRequestFlagPayload(flags);
7225
- const payload = readRawRequestPayload({ method, payload: rawPayload, source: "flag" });
7280
+ const payload = readRawRequestPayload({ method, payload: rawPayload, platform: platform2, source: "flag" });
7226
7281
  return {
7227
7282
  body: {
7228
- platform: readRawRequestPlatform(platform2),
7283
+ platform: platform2,
7229
7284
  endpoint: requireFlag(flags, "endpoint", "Required: --endpoint <api-path>"),
7230
7285
  payload,
7231
7286
  method,
@@ -7254,8 +7309,8 @@ function readRawRequestString(input) {
7254
7309
  throw new CliError("MISSING_FLAG", `Missing required field: \`${input.field}\``, input.hint);
7255
7310
  }
7256
7311
  function readRawRequestPlatform(value) {
7257
- if (value === "meta" || value === "google" || value === "tiktok" || value === "reddit" || value === "x" || value === "linkedin") return value;
7258
- throw new CliError("INVALID_VALUE", `Invalid platform: ${String(value)}`, "Use meta, google, tiktok, reddit, x, or linkedin");
7312
+ if (value === "meta" || value === "google" || value === "tiktok" || value === "reddit" || value === "x" || value === "linkedin" || value === "microsoft") return value;
7313
+ throw new CliError("INVALID_VALUE", `Invalid platform: ${String(value)}`, "Use meta, google, tiktok, reddit, x, linkedin, or microsoft");
7259
7314
  }
7260
7315
  function readRawRequestMethod(value) {
7261
7316
  const method = typeof value === "string" ? value.toUpperCase() : "POST";
@@ -7280,7 +7335,7 @@ function readRawRequestPayload(input) {
7280
7335
  if (input.source === "data") throw new CliError("MISSING_FLAG", "POST/PUT/PATCH requests require payload in --data", 'Include "payload": {"key":"value"}');
7281
7336
  throw new CliError("MISSING_FLAG", "POST/PUT/PATCH requests require --payload", `Add --payload '{"key":"value"}'`);
7282
7337
  }
7283
- 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");
7338
+ if (input.method === "DELETE" && input.platform !== "microsoft" && input.payload !== void 0 && input.payload !== null) throw new CliError("INVALID_VALUE", "DELETE requests do not support payload", "Put identifiers in the endpoint path");
7284
7339
  return input.payload ?? null;
7285
7340
  }
7286
7341
  function showHelp(key, full = false) {
@@ -7426,7 +7481,7 @@ async function main() {
7426
7481
  return;
7427
7482
  }
7428
7483
  const platform2 = manageTarget;
7429
- if (platform2 !== "meta" && platform2 !== "google" && platform2 !== "tiktok" && platform2 !== "reddit" && platform2 !== "x" && platform2 !== "linkedin") throw new CliError("UNKNOWN_COMMAND", `Unknown platform: ${platform2}`, "Available: meta, google, tiktok, reddit, x, linkedin, drafts, platform-api-requests");
7484
+ if (platform2 !== "meta" && platform2 !== "google" && platform2 !== "tiktok" && platform2 !== "reddit" && platform2 !== "x" && platform2 !== "linkedin" && platform2 !== "microsoft") throw new CliError("UNKNOWN_COMMAND", `Unknown platform: ${platform2}`, "Available: meta, google, tiktok, reddit, x, linkedin, microsoft, drafts, platform-api-requests");
7430
7485
  const entity = args[2];
7431
7486
  const action = args[3];
7432
7487
  const restArgs = args.slice(4);
@@ -8164,8 +8219,23 @@ async function main() {
8164
8219
  default:
8165
8220
  throw new CliError("UNKNOWN_COMMAND", `Unknown entity: linkedin ${entity}`, "Available: accounts, media, campaigns, ad-groups, ads, targeting-search, results, platform-api-requests");
8166
8221
  }
8222
+ } else if (platform2 === "microsoft") {
8223
+ switch (entity) {
8224
+ case "accounts":
8225
+ switch (action) {
8226
+ case "available":
8227
+ data = await listMicrosoftAvailableAccounts(client, restArgs, flags);
8228
+ emptyHint = "No Microsoft ad accounts available from the connected workspace login.";
8229
+ break;
8230
+ default:
8231
+ throw new CliError("UNKNOWN_COMMAND", `Unknown action: microsoft accounts ${action}`, "Available: available.");
8232
+ }
8233
+ break;
8234
+ default:
8235
+ throw new CliError("UNKNOWN_COMMAND", `Unknown entity: microsoft ${entity}`, "Available: accounts, platform-api-requests");
8236
+ }
8167
8237
  } else if (platform2 === "x") throw new CliError("UNKNOWN_COMMAND", `Unknown entity: x ${entity}`, "Available: platform-api-requests");
8168
- else throw new CliError("UNKNOWN_COMMAND", "Unknown platform", "Available: meta, google, tiktok, reddit, x, linkedin, drafts, platform-api-requests");
8238
+ else throw new CliError("UNKNOWN_COMMAND", "Unknown platform", "Available: meta, google, tiktok, reddit, x, linkedin, microsoft, drafts, platform-api-requests");
8169
8239
  printResult(data, flags, emptyHint, detailEntity);
8170
8240
  return;
8171
8241
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adkit/cli",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
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",