@adkit/cli 1.13.32 → 1.13.34

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 (3) hide show
  1. package/README.md +8 -1
  2. package/dist/cli.js +140 -7
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -41,9 +41,14 @@ adkit projects current
41
41
 
42
42
  ### Ad Library
43
43
 
44
- Browse competitor ads and advertisers tracked by AdKit.
44
+ Browse the shared ad library or your project’s My Watchlist. `add` finds or creates an advertiser and saves it to that project; `track` and `untrack` change membership for an existing ID. Repeating either is safe. Untracking keeps the shared advertiser and other projects intact.
45
45
 
46
46
  ```bash
47
+ adkit library advertisers list --scope watchlist --project <project-id>
48
+ adkit library advertisers search "notion" --scope watchlist --project <project-id>
49
+ adkit library advertisers add --website notion.so --project <project-id>
50
+ adkit library advertisers track <id> --project <project-id>
51
+ adkit library advertisers untrack <id> --project <project-id>
47
52
  adkit library advertisers search "notion" --platform meta
48
53
  adkit library advertisers <id>
49
54
  adkit library advertisers similar --industry saas
@@ -51,6 +56,8 @@ adkit library ads list --advertiser <id>
51
56
  adkit library ads <id>
52
57
  ```
53
58
 
59
+ Omit `--scope` (or use `--scope library`) for the whole library. List/search default to newest first; use `--sort name` for alphabetical order. Use `--json` for automation.
60
+
54
61
  ### Studio
55
62
 
56
63
  Create and manage AI-generated ads.
package/dist/cli.js CHANGED
@@ -4727,7 +4727,7 @@ function readStringFlag2(flags, key) {
4727
4727
  const value = flags[key];
4728
4728
  return typeof value === "string" ? value : void 0;
4729
4729
  }
4730
- var ADVERTISER_FILTER_FLAGS = ["industry", "category", "platform", "sort", "limit", "page"];
4730
+ var ADVERTISER_FILTER_FLAGS = ["industry", "category", "platform", "sort", "limit", "page", "scope"];
4731
4731
  async function listAdvertisers(client, _args, flags) {
4732
4732
  validateFlags(flags, ADVERTISER_FILTER_FLAGS, "library advertisers list");
4733
4733
  const qs = buildAdvertiserQueryString(flags);
@@ -4769,14 +4769,31 @@ async function addAdvertiser(client, _args, flags) {
4769
4769
  linkedInLibraryUrl: linkedinLibrary
4770
4770
  });
4771
4771
  }
4772
+ async function trackAdvertiser(client, args, flags) {
4773
+ const path3 = getAdvertiserWatchlistPath(args, flags);
4774
+ return client.post(path3);
4775
+ }
4776
+ async function untrackAdvertiser(client, args, flags) {
4777
+ const path3 = getAdvertiserWatchlistPath(args, flags);
4778
+ return client.delete(path3);
4779
+ }
4780
+ function getAdvertiserWatchlistPath(args, flags) {
4781
+ validateFlags(flags, [], "library advertisers");
4782
+ if (args.length !== 1 || !args[0]) throw new CliError("MISSING_ARGUMENT", "Expected exactly one advertiser ID", "Run: adkit library advertisers track <id> or adkit library advertisers untrack <id>");
4783
+ if (flags.data !== void 0) throw new CliError("INVALID_VALUE", "Watchlist changes do not accept --data", "Pass the advertiser ID as a positional argument and select the project with --project");
4784
+ const id = encodeURIComponent(args[0]);
4785
+ return `/library/advertisers/${id}/watchlist`;
4786
+ }
4772
4787
  function buildAdvertiserQueryString(flags, query) {
4788
+ const scope = flags.scope;
4789
+ if (scope !== void 0 && scope !== "library" && scope !== "watchlist") throw new CliError("INVALID_VALUE", "--scope must be library or watchlist", "Use --scope watchlist for the selected project, or omit it to search the whole library");
4773
4790
  const industry = typeof flags.industry === "string" ? flags.industry : void 0;
4774
4791
  const category = typeof flags.category === "string" ? flags.category : void 0;
4775
4792
  const platform2 = typeof flags.platform === "string" ? flags.platform : void 0;
4776
- const sort = typeof flags.sort === "string" ? flags.sort : "name";
4793
+ const sort = typeof flags.sort === "string" ? flags.sort : void 0;
4777
4794
  const limit = typeof flags.limit === "string" ? flags.limit : void 0;
4778
4795
  const page = typeof flags.page === "string" ? flags.page : void 0;
4779
- return queryString3({ industry, category, platform: platform2, query, sort, limit, page });
4796
+ return queryString3({ industry, category, platform: platform2, query, sort, limit, page, scope });
4780
4797
  }
4781
4798
  async function listLibraryAds(client, _args, flags) {
4782
4799
  const platform2 = readStringFlag2(flags, "platform");
@@ -4801,6 +4818,56 @@ async function getLibraryAd(client, args, _flags) {
4801
4818
  if (!id) throw new CliError("MISSING_ARGUMENT", "Missing required argument: `<id>`", "Run: adkit library ads <ad-id>");
4802
4819
  return client.get(`/library/ads/${id}`);
4803
4820
  }
4821
+ var LIBRARY_BOARD_FIELDS = ["name", "description", "color"];
4822
+ async function createLibraryBoard(client, _args, flags) {
4823
+ validateFlags(flags, LIBRARY_BOARD_FIELDS, "library boards create");
4824
+ const name = requireFlag(flags, "name", "Run: adkit library boards create --name <name>");
4825
+ const body = { name };
4826
+ const description = readLibraryBoardTextFlag(flags, "description");
4827
+ const color = readLibraryBoardTextFlag(flags, "color");
4828
+ if (description !== void 0) body.description = description;
4829
+ if (color !== void 0) body.color = color;
4830
+ return client.post("/library/boards", body);
4831
+ }
4832
+ async function updateLibraryBoard(client, args, flags) {
4833
+ validateFlags(flags, [...LIBRARY_BOARD_FIELDS, "share-enabled"], "library boards update");
4834
+ const boardId = requireArg(args, 0, "board-id", "Run: adkit library boards update <board-id> --name <name>");
4835
+ const body = {};
4836
+ const name = readLibraryBoardTextFlag(flags, "name");
4837
+ const description = readLibraryBoardTextFlag(flags, "description");
4838
+ const color = readLibraryBoardTextFlag(flags, "color");
4839
+ const shareEnabled = readLibraryBoardShareEnabled(flags);
4840
+ if (name !== void 0) body.name = name;
4841
+ if (description !== void 0) body.description = description;
4842
+ if (color !== void 0) body.color = color;
4843
+ if (shareEnabled !== void 0) body.shareEnabled = shareEnabled;
4844
+ if (Object.keys(body).length === 0) throw new CliError("MISSING_FLAG", "Board update requires at least one field", "Use --name, --description, --color, or --share-enabled <true|false>");
4845
+ const encodedBoardId = encodeURIComponent(boardId);
4846
+ return client.patch(`/library/boards/${encodedBoardId}`, body);
4847
+ }
4848
+ async function addLibraryBoardAds(client, args, flags) {
4849
+ validateFlags(flags, [], "library boards add-ads");
4850
+ const boardId = requireArg(args, 0, "board-id", "Run: adkit library boards add-ads <board-id> <ad-id...>");
4851
+ const adIds = args.slice(1);
4852
+ if (adIds.length === 0) throw new CliError("MISSING_ARGUMENT", "Expected at least one ad ID after the board ID", "Run: adkit library boards add-ads <board-id> <ad-id...>");
4853
+ if (adIds.length > 20) throw new CliError("INVALID_VALUE", "A board add-ads command accepts at most 20 ad IDs", "Split the ads across multiple add-ads commands");
4854
+ const encodedBoardId = encodeURIComponent(boardId);
4855
+ return client.post(`/library/boards/${encodedBoardId}/ads`, { adIds });
4856
+ }
4857
+ function readLibraryBoardTextFlag(flags, key) {
4858
+ const value = flags[key];
4859
+ if (typeof value === "string") return value;
4860
+ if (!Array.isArray(value)) return void 0;
4861
+ if (value.length === 1) return value[0];
4862
+ throw new CliError("INVALID_VALUE", `--${key} can only be provided once for board commands`, `Use one --${key} value`);
4863
+ }
4864
+ function readLibraryBoardShareEnabled(flags) {
4865
+ const value = flags["share-enabled"];
4866
+ if (value === void 0) return void 0;
4867
+ if (value === true || value === "true") return true;
4868
+ if (value === "false") return false;
4869
+ throw new CliError("INVALID_VALUE", "--share-enabled must be true or false", "Use --share-enabled true or --share-enabled false");
4870
+ }
4804
4871
 
4805
4872
  // src/commands/studio.ts
4806
4873
  import { readFile as readFile2 } from "node:fs/promises";
@@ -8105,8 +8172,27 @@ Examples:
8105
8172
 
8106
8173
  advertisers Browse and inspect advertisers
8107
8174
  ads Browse and inspect ads
8175
+ boards Create, update, share, and fill inspiration boards
8108
8176
 
8109
8177
  Run \`adkit library <command> --help\` for details.`.trim(),
8178
+ "library boards": `adkit library boards \u2014 Manage inspiration boards
8179
+
8180
+ create Create a private board
8181
+ update <board-id> Update board details or sharing
8182
+ add-ads <board-id> <ad-id...> Add 1-20 library ads without duplicates
8183
+
8184
+ Flags (create/update):
8185
+ --name <text> Board name
8186
+ --description <text> Board description
8187
+ --color <value> Board color
8188
+ --share-enabled <true|false> Enable or disable the public link (update only)
8189
+ --project <id> Choose the project; otherwise use the active project
8190
+
8191
+ Examples:
8192
+ adkit library boards create --name "Offer-first banners"
8193
+ adkit library boards update 507f1f77bcf86cd799439011 --name "Client references"
8194
+ adkit library boards update 507f1f77bcf86cd799439011 --share-enabled true
8195
+ adkit library boards add-ads 507f1f77bcf86cd799439011 507f1f77bcf86cd799439012 507f1f77bcf86cd799439013`.trim(),
8110
8196
  studio: `adkit studio \u2014 Create and manage Studio ads
8111
8197
 
8112
8198
  ads Manage Studio ads
@@ -8208,10 +8294,22 @@ Examples:
8208
8294
  <id> View advertiser details
8209
8295
  similar Find similar to your project
8210
8296
  similar <id> Find similar to an advertiser
8211
- add Add a new advertiser
8297
+ add Find or add an advertiser and save it to My Watchlist
8298
+ track <id> Save an existing advertiser to My Watchlist
8299
+ untrack <id> Remove it from this project only
8300
+
8301
+ Watchlist:
8302
+ --scope <library|watchlist> List/search the whole library (default) or My Watchlist
8303
+ --project <id> Choose the project; otherwise use the active project
8304
+ Track/untrack return advertiserId and tracked. Repeating either is safe.
8305
+ Untrack keeps the advertiser and other projects intact.
8212
8306
 
8213
8307
  Examples:
8214
8308
  adkit library advertisers list
8309
+ adkit library advertisers list --scope watchlist --project <project-id>
8310
+ adkit library advertisers search nike --scope watchlist --project <project-id>
8311
+ adkit library advertisers track <advertiser-id> --project <project-id>
8312
+ adkit library advertisers untrack <advertiser-id> --project <project-id>
8215
8313
  adkit library advertisers search nike
8216
8314
  adkit library advertisers list --platform meta --industry SaaS
8217
8315
  adkit library advertisers similar
@@ -8360,13 +8458,15 @@ var HELP_FULL = {
8360
8458
  <id> View advertiser details
8361
8459
  similar Find similar to your project
8362
8460
  similar <id> Find similar to an advertiser
8363
- add Add a new advertiser
8461
+ add Find or add an advertiser and save it to My Watchlist
8462
+ track <id> Save an existing advertiser to My Watchlist
8463
+ untrack <id> Remove it from this project only
8364
8464
 
8365
8465
  Filters (list / search):
8366
8466
  --industry <string> Filter by industry (e.g. "SaaS", "E-commerce")
8367
8467
  --category <string> Filter by category (e.g. "Productivity Tools")
8368
8468
  --platform <meta|google|linkedin> Filter by ad platform
8369
- --sort <name|newest|spend> Sort order (default: name)
8469
+ --sort <name|newest|spend> Sort order (default: newest)
8370
8470
  --limit <n> Results per page (default: 20, max: 100)
8371
8471
  --page <n> Page number (default: 1)
8372
8472
 
@@ -8384,8 +8484,18 @@ Add flags:
8384
8484
  --google-library <url> Google Ads Transparency URL
8385
8485
  --linkedin-library <url> LinkedIn Ad Library URL
8386
8486
 
8487
+ Watchlist:
8488
+ --scope <library|watchlist> List/search the whole library (default) or My Watchlist
8489
+ --project <id> Choose the project; otherwise use the active project
8490
+ Track/untrack return advertiserId and tracked. Repeating either is safe.
8491
+ Untrack keeps the advertiser and other projects intact.
8492
+
8387
8493
  Examples:
8388
8494
  adkit library advertisers list
8495
+ adkit library advertisers list --scope watchlist --project <project-id>
8496
+ adkit library advertisers search nike --scope watchlist --project <project-id>
8497
+ adkit library advertisers track <advertiser-id> --project <project-id>
8498
+ adkit library advertisers untrack <advertiser-id> --project <project-id>
8389
8499
  adkit library advertisers search nike
8390
8500
  adkit library advertisers search "productivity tools" --platform meta
8391
8501
  adkit library advertisers list --industry SaaS --limit 10
@@ -8930,11 +9040,13 @@ function printAddAdvertiserResult(data) {
8930
9040
  const adv = dig(data, "advertiser");
8931
9041
  const isNew = dig(data, "isNew");
8932
9042
  const jobCreated = dig(data, "jobCreated");
9043
+ const tracked = dig(data, "tracked");
8933
9044
  const lines = [""];
8934
9045
  if (isNew) lines.push(` \u2713 Created advertiser: ${toStr2(dig(adv, "name"))}`);
8935
9046
  else lines.push(` Advertiser already exists: ${toStr2(dig(adv, "name"))}`);
8936
9047
  if (dig(adv, "website")) lines.push(` Website: ${toStr2(dig(adv, "website"))}`);
8937
9048
  if (dig(adv, "_id")) lines.push(` ID: ${toStr2(dig(adv, "_id"))}`);
9049
+ if (tracked === true) lines.push(" Saved to this project\u2019s watchlist.");
8938
9050
  if (jobCreated) lines.push("", " Scraping job queued \u2014 advertiser data will be populated shortly.");
8939
9051
  else if (!isNew && dig(adv, "hasDescription")) lines.push("", " Advertiser already has complete data.");
8940
9052
  const job = dig(data, "job");
@@ -10255,6 +10367,11 @@ async function main() {
10255
10367
  const data = await addAdvertiser(client, args.slice(3), flags);
10256
10368
  if (wantsJson(flags)) printResult(data, flags);
10257
10369
  else printAddAdvertiserResult(data);
10370
+ } else if (action === "track" || action === "untrack") {
10371
+ const changeWatchlist = action === "track" ? trackAdvertiser : untrackAdvertiser;
10372
+ const commandArgs = args.slice(3);
10373
+ const data = await changeWatchlist(client, commandArgs, flags);
10374
+ printResult(data, flags);
10258
10375
  } else if (action === "similar") {
10259
10376
  const advertiserId = args[3];
10260
10377
  if (advertiserId) flags.advertiserId = advertiserId;
@@ -10358,7 +10475,23 @@ ${pageInfo}`);
10358
10475
  }
10359
10476
  return;
10360
10477
  }
10361
- throw new CliError("UNKNOWN_COMMAND", `Unknown library command: ${libraryTarget}`, "Available: advertisers, ads");
10478
+ if (libraryTarget === "boards") {
10479
+ const action = args[2];
10480
+ if (flags.help || !action) {
10481
+ showHelp("library boards", flags.help === "full");
10482
+ return;
10483
+ }
10484
+ const client = requireClient(flags);
10485
+ const commandArgs = args.slice(3);
10486
+ let data;
10487
+ if (action === "create") data = await createLibraryBoard(client, commandArgs, flags);
10488
+ else if (action === "update") data = await updateLibraryBoard(client, commandArgs, flags);
10489
+ else if (action === "add-ads") data = await addLibraryBoardAds(client, commandArgs, flags);
10490
+ else throw new CliError("UNKNOWN_COMMAND", `Unknown library boards action: ${action}`, "Available: create, update, add-ads");
10491
+ printResult(data, flags);
10492
+ return;
10493
+ }
10494
+ throw new CliError("UNKNOWN_COMMAND", `Unknown library command: ${libraryTarget}`, "Available: advertisers, ads, boards");
10362
10495
  }
10363
10496
  if (args[0] === "studio") {
10364
10497
  const studioTarget = args[1];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adkit/cli",
3
- "version": "1.13.32",
3
+ "version": "1.13.34",
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",