@audienti/cli 0.1.75 → 0.1.76

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to the Audienti CLI are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.76] - 2026-09-27
8
+
9
+ ### Added
10
+
11
+ - Add `lists bulk-add-tag|merge|export`, `lists routing-rules <list> toggle`, `icps bulk-add-tag|clone|delete|prospects`, `offers regenerate-research|update-writeup|add-artifacts|remove-artifact`, `tasks update|bulk-update`, and `tools linkedin-strategy-review delete` so list, ICP, offer, task, and strategy review catalog actions are reachable from the CLI. `offers show` now lists attached artifacts.
12
+
7
13
  ## [0.1.75] - 2026-09-27
8
14
 
9
15
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audienti/cli",
3
- "version": "0.1.75",
3
+ "version": "0.1.76",
4
4
  "description": "Agent-first command-line client for Audienti.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/api-client.js CHANGED
@@ -113,6 +113,33 @@ export class AudientiClient {
113
113
  });
114
114
  }
115
115
 
116
+ regenerateOfferResearch(accountId, offerId, body = {}) {
117
+ return this.requestJson(accountPath(accountId, ["offers", offerId, "regenerate_research"]), {
118
+ method: "POST",
119
+ body
120
+ });
121
+ }
122
+
123
+ updateOfferWriteup(accountId, offerId, body) {
124
+ return this.requestJson(accountPath(accountId, ["offers", offerId, "writeup"]), {
125
+ method: "PATCH",
126
+ body
127
+ });
128
+ }
129
+
130
+ addOfferArtifacts(accountId, offerId, body) {
131
+ return this.requestJson(accountPath(accountId, ["offers", offerId, "artifacts"]), {
132
+ method: "POST",
133
+ body
134
+ });
135
+ }
136
+
137
+ removeOfferArtifact(accountId, offerId, artifactId) {
138
+ return this.requestJson(accountPath(accountId, ["offers", offerId, "artifacts", artifactId]), {
139
+ method: "DELETE"
140
+ });
141
+ }
142
+
116
143
  icps(accountId, query = {}) {
117
144
  return this.requestJson(accountPath(accountId, ["icps"], query));
118
145
  }
@@ -163,6 +190,30 @@ export class AudientiClient {
163
190
  });
164
191
  }
165
192
 
193
+ bulkAddIcpTag(accountId, body) {
194
+ return this.requestJson(accountPath(accountId, ["icps", "bulk_add_tag"]), {
195
+ method: "POST",
196
+ body
197
+ });
198
+ }
199
+
200
+ cloneIcp(accountId, icpId) {
201
+ return this.requestJson(accountPath(accountId, ["icps", icpId, "clone"]), {
202
+ method: "POST",
203
+ body: {}
204
+ });
205
+ }
206
+
207
+ deleteIcp(accountId, icpId) {
208
+ return this.requestJson(accountPath(accountId, ["icps", icpId]), {
209
+ method: "DELETE"
210
+ });
211
+ }
212
+
213
+ icpProspects(accountId, icpId, query = {}) {
214
+ return this.requestJson(accountPath(accountId, ["icps", icpId, "prospects"], query));
215
+ }
216
+
166
217
  companies(accountId, query = {}) {
167
218
  return this.requestJson(accountPath(accountId, ["companies"], query));
168
219
  }
@@ -360,6 +411,20 @@ export class AudientiClient {
360
411
  });
361
412
  }
362
413
 
414
+ updateTask(accountId, taskId, body) {
415
+ return this.requestJson(accountPath(accountId, ["tasks", taskId]), {
416
+ method: "PATCH",
417
+ body
418
+ });
419
+ }
420
+
421
+ bulkUpdateTasks(accountId, body) {
422
+ return this.requestJson(accountPath(accountId, ["tasks", "bulk_update"]), {
423
+ method: "PATCH",
424
+ body
425
+ });
426
+ }
427
+
363
428
  lists(accountId) {
364
429
  return this.requestJson(accountPath(accountId, ["lists"]));
365
430
  }
@@ -402,6 +467,24 @@ export class AudientiClient {
402
467
  });
403
468
  }
404
469
 
470
+ bulkAddListTag(accountId, body) {
471
+ return this.requestJson(accountPath(accountId, ["lists", "bulk_add_tag"]), {
472
+ method: "POST",
473
+ body
474
+ });
475
+ }
476
+
477
+ mergeLists(accountId, body) {
478
+ return this.requestJson(accountPath(accountId, ["lists", "merge_selected"]), {
479
+ method: "POST",
480
+ body
481
+ });
482
+ }
483
+
484
+ exportList(accountId, listId, query = {}) {
485
+ return this.requestJson(accountPath(accountId, ["lists", listId, "export"], query));
486
+ }
487
+
405
488
  listProspects(accountId, listId, query = {}) {
406
489
  return this.requestJson(accountPath(accountId, ["lists", listId, "prospects"], query));
407
490
  }
@@ -451,6 +534,12 @@ export class AudientiClient {
451
534
  });
452
535
  }
453
536
 
537
+ toggleListRoutingRule(accountId, listId, ruleId) {
538
+ return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules", ruleId, "toggle"]), {
539
+ method: "PATCH"
540
+ });
541
+ }
542
+
454
543
  applyListRoutingRules(accountId, listId) {
455
544
  return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules", "apply"]), {
456
545
  method: "POST",
@@ -777,6 +866,12 @@ export class AudientiClient {
777
866
  return this.requestJson(accountPath(accountId, ["tools", "linkedin-review", "reports", reportId]));
778
867
  }
779
868
 
869
+ deleteLinkedinStrategyReview(accountId, reportId) {
870
+ return this.requestJson(accountPath(accountId, ["tools", "linkedin-strategy-review", "reports", reportId]), {
871
+ method: "DELETE"
872
+ });
873
+ }
874
+
780
875
  humanizeText(accountId, body) {
781
876
  return this.requestJson(accountPath(accountId, ["tools", "humanize"]), {
782
877
  method: "POST",
package/src/cli.js CHANGED
@@ -207,6 +207,21 @@ const TOOLS_LINKEDIN_REVIEW_USAGE = "Usage: audienti tools linkedin-review --url
207
207
  const TOOLS_LINKEDIN_REVIEW_REPORTS_USAGE = "Usage: audienti tools linkedin-review reports [--limit <n>] [--json] [--account <acct_id>]";
208
208
  const TOOLS_LINKEDIN_REVIEW_SHOW_USAGE = "Usage: audienti tools linkedin-review show <rprt_id> [--json] [--account <acct_id>]";
209
209
  const TOOLS_LINKEDIN_REVIEW_STATUS_USAGE = "Usage: audienti tools linkedin-review status <rprt_id> [--json] [--account <acct_id>]";
210
+ const TOOLS_LINKEDIN_STRATEGY_REVIEW_DELETE_USAGE = "Usage: audienti tools linkedin-strategy-review delete <rprt_id> --confirm <yes|true|Y|y> [--json] [--account <acct_id>]";
211
+ const LISTS_BULK_ADD_TAG_USAGE = "Usage: audienti lists bulk-add-tag --tag <tag> <list_id> [list_id...] [--json] [--account <acct_id>]";
212
+ const LISTS_MERGE_USAGE = "Usage: audienti lists merge <list_id> <list_id> [--json] [--account <acct_id>]";
213
+ const LISTS_EXPORT_USAGE = "Usage: audienti lists export <list_id> [--output <file.csv>] [--inactive-reason <reason>] [--json] [--account <acct_id>]";
214
+ const LIST_ROUTING_RULES_TOGGLE_USAGE = "Usage: audienti lists routing-rules <list_id> toggle <rule_id> [--json] [--account <acct_id>]";
215
+ const ICPS_BULK_ADD_TAG_USAGE = "Usage: audienti icps bulk-add-tag --tag <tag> <icp_id> [icp_id...] [--json] [--account <acct_id>]";
216
+ const ICPS_CLONE_USAGE = "Usage: audienti icps clone <icp_id> [--json] [--account <acct_id>]";
217
+ const ICPS_DELETE_USAGE = "Usage: audienti icps delete <icp_id> --confirm <yes|true|Y|y> [--json] [--account <acct_id>]";
218
+ const ICPS_PROSPECTS_USAGE = "Usage: audienti icps prospects <icp_id> [--query <text>] [--limit <n>] [--offset <n> | --page <n>] [--profiles] [--json] [--account <acct_id>]";
219
+ const OFFERS_REGENERATE_RESEARCH_USAGE = "Usage: audienti offers regenerate-research <offr_id> [--guidance <text>] [--json] [--account <acct_id>]";
220
+ const OFFERS_UPDATE_WRITEUP_USAGE = "Usage: audienti offers update-writeup <offr_id> --description <text> [--json] [--account <acct_id>]";
221
+ const OFFERS_ADD_ARTIFACTS_USAGE = "Usage: audienti offers add-artifacts <offr_id> <file> [file...] [--json] [--account <acct_id>]";
222
+ const OFFERS_REMOVE_ARTIFACT_USAGE = "Usage: audienti offers remove-artifact <offr_id> <artifact_id> [--json] [--account <acct_id>]";
223
+ const TASKS_UPDATE_USAGE = "Usage: audienti tasks update <ptsk_id> [--title <text>] [--due <time>] [--notes <text>] [--prospect <prsp_id|\"\">] [--list <list_id|\"\">] [--assigned-user <id|me>] [--json] [--account <acct_id>]";
224
+ const TASKS_BULK_UPDATE_USAGE = "Usage: audienti tasks bulk-update --action <complete|reassign> [--assigned-user <id|me>] <ptsk_id> [ptsk_id...] [--json] [--account <acct_id>]";
210
225
  const SOCIAL_COOKIES_SYNC_MESSAGES_USAGE = "Usage: audienti social-cookies sync-messages <scok_id> [--folder <folder>] [--retry] [--json] [--account <acct_id>]";
211
226
  const COHORT_STAGE_ORDER = [
212
227
  "identified",
@@ -309,6 +324,10 @@ async function dispatch(argv, context) {
309
324
  if (normalizedResource === "offers" && action === "create") return offersCreate(rest, context, { accountOverride });
310
325
  if (normalizedResource === "offers" && action === "update") return offersUpdate(rest, context, { accountOverride });
311
326
  if (normalizedResource === "offers" && action === "delete") return offersDelete(rest, context, { accountOverride });
327
+ if (normalizedResource === "offers" && action === "regenerate-research") return offersRegenerateResearch(rest, context, { accountOverride });
328
+ if (normalizedResource === "offers" && action === "update-writeup") return offersUpdateWriteup(rest, context, { accountOverride });
329
+ if (normalizedResource === "offers" && action === "add-artifacts") return offersAddArtifacts(rest, context, { accountOverride });
330
+ if (normalizedResource === "offers" && action === "remove-artifact") return offersRemoveArtifact(rest, context, { accountOverride });
312
331
  if (normalizedResource === "icps" && action === "list") return icpsList(rest, context, { accountOverride });
313
332
  if (normalizedResource === "icps" && action === "show") return icpsShow(rest, context, { accountOverride });
314
333
  if (normalizedResource === "icps" && action === "analytics") return analyticsIcps(rest, context, { accountOverride });
@@ -318,6 +337,10 @@ async function dispatch(argv, context) {
318
337
  if (normalizedResource === "icps" && action === "restore") return icpsLifecycleMutation("restore", rest, context, { accountOverride });
319
338
  if (normalizedResource === "icps" && action === "add-tag") return icpsTagMutation("add", rest, context, { accountOverride });
320
339
  if (normalizedResource === "icps" && action === "remove-tag") return icpsTagMutation("remove", rest, context, { accountOverride });
340
+ if (normalizedResource === "icps" && action === "bulk-add-tag") return icpsBulkAddTag(rest, context, { accountOverride });
341
+ if (normalizedResource === "icps" && action === "clone") return icpsClone(rest, context, { accountOverride });
342
+ if (normalizedResource === "icps" && action === "delete") return icpsDelete(rest, context, { accountOverride });
343
+ if (normalizedResource === "icps" && action === "prospects") return icpsProspects(rest, context, { accountOverride });
321
344
  if (normalizedResource === "companies" && action === "search") return companiesSearch(rest, context, { accountOverride });
322
345
  if (normalizedResource === "dnc" && action === "list") return dncList(rest, context, { accountOverride });
323
346
  if (normalizedResource === "dnc" && action === "add") return dncAdd(rest, context, { accountOverride });
@@ -339,6 +362,8 @@ async function dispatch(argv, context) {
339
362
  if (normalizedResource === "tasks" && ["list", "manage"].includes(action)) return tasksList(rest, context, { accountOverride });
340
363
  if (normalizedResource === "tasks" && action === "add") return tasksAdd(rest, context, { accountOverride });
341
364
  if (normalizedResource === "tasks" && action === "complete") return tasksComplete(rest, context, { accountOverride });
365
+ if (normalizedResource === "tasks" && action === "update") return tasksUpdate(rest, context, { accountOverride });
366
+ if (normalizedResource === "tasks" && action === "bulk-update") return tasksBulkUpdate(rest, context, { accountOverride });
342
367
  if (normalizedResource === "lists" && action === "list") return listsList(rest, context, { accountOverride });
343
368
  if (normalizedResource === "lists" && action === "create") return listsCreate(rest, context, { accountOverride });
344
369
  if (normalizedResource === "lists" && action === "show") return listsShow(rest, context, { accountOverride });
@@ -346,6 +371,9 @@ async function dispatch(argv, context) {
346
371
  if (normalizedResource === "lists" && action === "add-tag") return listsTagMutation("add", rest, context, { accountOverride });
347
372
  if (normalizedResource === "lists" && action === "remove-tag") return listsTagMutation("remove", rest, context, { accountOverride });
348
373
  if (normalizedResource === "lists" && action === "delete") return listsDelete(rest, context, { accountOverride });
374
+ if (normalizedResource === "lists" && action === "bulk-add-tag") return listsBulkAddTag(rest, context, { accountOverride });
375
+ if (normalizedResource === "lists" && action === "merge") return listsMerge(rest, context, { accountOverride });
376
+ if (normalizedResource === "lists" && action === "export") return listsExport(rest, context, { accountOverride });
349
377
  if (normalizedResource === "lists" && action === "prospects") return listProspects(rest, context, { accountOverride });
350
378
  if (normalizedResource === "lists" && action === "add-prospects") return listsAddProspects(rest, context, { accountOverride });
351
379
  if (normalizedResource === "lists" && action === "remove-prospects") return listsRemoveProspects(rest, context, { accountOverride });
@@ -409,6 +437,7 @@ async function dispatch(argv, context) {
409
437
  if (normalizedResource === "tools" && action === "get") return toolsGet(rest, context, { accountOverride });
410
438
  if (normalizedResource === "tools" && action === "humanize") return toolsHumanize(rest, context, { accountOverride });
411
439
  if (normalizedResource === "tools" && action === "linkedin-review") return toolsLinkedinReview(rest, context, { accountOverride });
440
+ if (normalizedResource === "tools" && action === "linkedin-strategy-review") return toolsLinkedinStrategyReview(rest, context, { accountOverride });
412
441
  if (normalizedResource === "operator" && action === "failed-drafts") return operatorFailedDrafts(rest, context, { accountOverride });
413
442
  if (normalizedResource === "operator" && action === "queue") return operatorQueue(rest, context, { accountOverride });
414
443
  if (normalizedResource === "operator" && action === "next") return operatorNext(rest, context, { accountOverride });
@@ -1250,6 +1279,65 @@ async function offersDelete(args, context, { accountOverride } = {}) {
1250
1279
  writeLine(context.stdout, `Deleted offer ${display(payload?.name)} (${display(payload?.prefix_id)}).`);
1251
1280
  }
1252
1281
 
1282
+ async function offersRegenerateResearch(args, context, { accountOverride } = {}) {
1283
+ const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), guidance: { type: "string" } });
1284
+ if (positionals.length !== 1) throw new CommandError(OFFERS_REGENERATE_RESEARCH_USAGE);
1285
+
1286
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1287
+ const offer = await client.regenerateOfferResearch(accountId, positionals[0], compactObject({ guidance: values.guidance }));
1288
+ if (values.json) return writeJson(context.stdout, offer);
1289
+
1290
+ writeLine(context.stdout, `Queued a new research write-up for offer ${display(offer?.name)} (${display(offer?.prefix_id)}).`);
1291
+ }
1292
+
1293
+ async function offersUpdateWriteup(args, context, { accountOverride } = {}) {
1294
+ const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), description: { type: "string" } });
1295
+ if (positionals.length !== 1 || values.description === undefined) throw new CommandError(OFFERS_UPDATE_WRITEUP_USAGE);
1296
+
1297
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1298
+ const offer = await client.updateOfferWriteup(accountId, positionals[0], { offer: { description: values.description } });
1299
+ if (values.json) return writeJson(context.stdout, offer);
1300
+
1301
+ writeLine(context.stdout, `Updated the write-up for offer ${display(offer?.name)} (${display(offer?.prefix_id)}).`);
1302
+ }
1303
+
1304
+ async function offersAddArtifacts(args, context, { accountOverride } = {}) {
1305
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1306
+ if (positionals.length < 2) throw new CommandError(OFFERS_ADD_ARTIFACTS_USAGE);
1307
+
1308
+ const [offerId, ...paths] = positionals;
1309
+ const artifacts = [];
1310
+ for (const path of paths) {
1311
+ let data;
1312
+ try {
1313
+ data = await readFile(path);
1314
+ } catch (error) {
1315
+ throw new CommandError(`Cannot read ${path}: ${error.message}`);
1316
+ }
1317
+ artifacts.push({ filename: basename(path), data: data.toString("base64") });
1318
+ }
1319
+
1320
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1321
+ const payload = await client.addOfferArtifacts(accountId, offerId, { artifacts });
1322
+ if (values.json) return writeJson(context.stdout, payload);
1323
+
1324
+ const count = payload?.attached_count ?? artifacts.length;
1325
+ writeLine(context.stdout, `Attached ${count} ${count === 1 ? "artifact" : "artifacts"} to offer ${display(payload?.offer_id || offerId)}.`);
1326
+ renderOfferArtifacts(payload?.artifacts, context);
1327
+ }
1328
+
1329
+ async function offersRemoveArtifact(args, context, { accountOverride } = {}) {
1330
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1331
+ if (positionals.length !== 2) throw new CommandError(OFFERS_REMOVE_ARTIFACT_USAGE);
1332
+
1333
+ const [offerId, artifactId] = positionals;
1334
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1335
+ const payload = await client.removeOfferArtifact(accountId, offerId, artifactId);
1336
+ if (values.json) return writeJson(context.stdout, payload);
1337
+
1338
+ writeLine(context.stdout, `Removed artifact ${display(artifactId)} from offer ${display(payload?.offer_id || offerId)}.`);
1339
+ }
1340
+
1253
1341
  async function icpsList(args, context, { accountOverride } = {}) {
1254
1342
  const { values, positionals } = parseCommandArgs(args, {
1255
1343
  ...jsonOptions(),
@@ -1359,6 +1447,68 @@ async function icpsTagMutation(action, args, context, { accountOverride } = {})
1359
1447
  if (Array.isArray(icp?.tags)) writeLine(context.stdout, `Tags: ${display(icp.tags.join(", "), "-")}`);
1360
1448
  }
1361
1449
 
1450
+ async function icpsBulkAddTag(args, context, { accountOverride } = {}) {
1451
+ const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), tag: { type: "string" } });
1452
+ if (positionals.length === 0 || !String(values.tag || "").trim()) throw new CommandError(ICPS_BULK_ADD_TAG_USAGE);
1453
+
1454
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1455
+ const icps = await client.bulkAddIcpTag(accountId, { icp_ids: positionals, tag: values.tag });
1456
+ if (values.json) return writeJson(context.stdout, icps);
1457
+
1458
+ const count = Array.isArray(icps) ? icps.length : 0;
1459
+ writeLine(context.stdout, `Added tag ${display(values.tag)} to ${count} ${count === 1 ? "ICP" : "ICPs"}.`);
1460
+ }
1461
+
1462
+ async function icpsClone(args, context, { accountOverride } = {}) {
1463
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1464
+ if (positionals.length !== 1) throw new CommandError(ICPS_CLONE_USAGE);
1465
+
1466
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1467
+ const icp = await client.cloneIcp(accountId, positionals[0]);
1468
+ if (values.json) return writeJson(context.stdout, icp);
1469
+
1470
+ writeLine(context.stdout, `Cloned ICP as ${display(icp?.name)} (${display(icp?.prefix_id)}).`);
1471
+ }
1472
+
1473
+ async function icpsDelete(args, context, { accountOverride } = {}) {
1474
+ const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), confirm: { type: "string" } });
1475
+ const normalizedConfirm = String(values.confirm || "").trim().toLowerCase();
1476
+ if (positionals.length !== 1 || !DELETE_CONFIRMATION_VALUES.has(normalizedConfirm)) throw new CommandError(ICPS_DELETE_USAGE);
1477
+
1478
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1479
+ const payload = await client.deleteIcp(accountId, positionals[0]);
1480
+ if (values.json) return writeJson(context.stdout, payload);
1481
+
1482
+ writeLine(context.stdout, `Deleted ICP ${display(payload?.name)} (${display(payload?.prefix_id)}).`);
1483
+ }
1484
+
1485
+ async function icpsProspects(args, context, { accountOverride } = {}) {
1486
+ const { values, positionals } = parseCommandArgs(args, {
1487
+ ...jsonOptions(),
1488
+ query: { type: "string" },
1489
+ limit: { type: "string" },
1490
+ offset: { type: "string" },
1491
+ page: { type: "string" },
1492
+ profiles: { type: "boolean" }
1493
+ });
1494
+ if (positionals.length !== 1) throw new CommandError(ICPS_PROSPECTS_USAGE);
1495
+ if (values.page && values.offset) throw new CommandError("Choose one pagination mode: use either --page or --offset.");
1496
+
1497
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1498
+ const payload = await client.icpProspects(accountId, positionals[0], compactObject({
1499
+ query: values.query,
1500
+ limit: values.limit,
1501
+ offset: values.offset,
1502
+ page: values.page,
1503
+ include_profiles: values.profiles
1504
+ }));
1505
+ if (values.json) return writeJson(context.stdout, payload);
1506
+
1507
+ renderProspects(payload, context, { profiles: values.profiles });
1508
+ const meta = payload?.meta || {};
1509
+ writeLine(context.stdout, `Showing ${display(meta.returned_count, 0)} of ${display(meta.total_count, 0)} matched prospects.`);
1510
+ }
1511
+
1362
1512
  async function companiesSearch(args, context, { accountOverride } = {}) {
1363
1513
  const { values, positionals } = parseCommandArgs(args, {
1364
1514
  ...jsonOptions(),
@@ -1969,6 +2119,56 @@ async function tasksComplete(args, context, { accountOverride } = {}) {
1969
2119
  writeLine(context.stdout, `Completed task ${display(payload?.prefix_id || payload?.id || positionals[0])}.`);
1970
2120
  }
1971
2121
 
2122
+ async function tasksUpdate(args, context, { accountOverride } = {}) {
2123
+ const { values, positionals } = parseCommandArgs(args, taskAddOptions());
2124
+ const fields = {
2125
+ title: values.title,
2126
+ due_at: values.due,
2127
+ notes: values.notes,
2128
+ prospect_id: values.prospect,
2129
+ list_id: values.list,
2130
+ assignee_account_user_id: values["assigned-user"]
2131
+ };
2132
+ const sentFields = Object.entries(fields).filter(([, value]) => value !== undefined);
2133
+ if (positionals.length !== 1 || sentFields.length === 0) throw new CommandError(TASKS_UPDATE_USAGE);
2134
+ if (values.prospect && values.list) throw new CommandError("Use either --prospect or --list, not both.");
2135
+
2136
+ const { client, accountId, config } = await requireAccountContext(context, { accountOverride });
2137
+ const task = Object.fromEntries(sentFields);
2138
+ if (task.assignee_account_user_id !== undefined) {
2139
+ task.assignee_account_user_id = resolveAccountUserId(task.assignee_account_user_id, config, { accountOverride }) ?? "";
2140
+ }
2141
+ const payload = await client.updateTask(accountId, positionals[0], { task });
2142
+ if (values.json) return writeJson(context.stdout, payload);
2143
+
2144
+ writeLine(context.stdout, `Updated task ${display(payload?.prefix_id || payload?.id || positionals[0])}.`);
2145
+ writeLine(context.stdout, `Title: ${display(payload?.title)}`);
2146
+ writeLine(context.stdout, `Due: ${display(payload?.due_at, "-")} | Association: ${taskAssociationLabel(payload)}`);
2147
+ }
2148
+
2149
+ async function tasksBulkUpdate(args, context, { accountOverride } = {}) {
2150
+ const { values, positionals } = parseCommandArgs(args, {
2151
+ ...jsonOptions(),
2152
+ action: { type: "string" },
2153
+ "assigned-user": { type: "string" }
2154
+ });
2155
+ const bulkAction = String(values.action || "").trim();
2156
+ if (positionals.length === 0 || !["complete", "reassign"].includes(bulkAction)) throw new CommandError(TASKS_BULK_UPDATE_USAGE);
2157
+ if (bulkAction === "reassign" && !values["assigned-user"]) throw new CommandError("--assigned-user is required with --action reassign.");
2158
+
2159
+ const { client, accountId, config } = await requireAccountContext(context, { accountOverride });
2160
+ const payload = await client.bulkUpdateTasks(accountId, compactObject({
2161
+ task_ids: positionals,
2162
+ bulk_action: bulkAction,
2163
+ assignee_account_user_id: bulkAction === "reassign" ? resolveAccountUserId(values["assigned-user"], config, { accountOverride }) : undefined
2164
+ }));
2165
+ if (values.json) return writeJson(context.stdout, payload);
2166
+
2167
+ const count = payload?.count ?? 0;
2168
+ const noun = count === 1 ? "task" : "tasks";
2169
+ writeLine(context.stdout, bulkAction === "complete" ? `Completed ${count} ${noun}.` : `Queued reassignment of ${count} ${noun}.`);
2170
+ }
2171
+
1972
2172
  async function listsCreate(args, context, { accountOverride } = {}) {
1973
2173
  const { values, positionals } = parseCommandArgs(args, {
1974
2174
  ...jsonOptions(),
@@ -2086,6 +2286,52 @@ async function listsDelete(args, context, { accountOverride } = {}) {
2086
2286
  }
2087
2287
  }
2088
2288
 
2289
+ async function listsBulkAddTag(args, context, { accountOverride } = {}) {
2290
+ const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), tag: { type: "string" } });
2291
+ if (positionals.length === 0 || !String(values.tag || "").trim()) throw new CommandError(LISTS_BULK_ADD_TAG_USAGE);
2292
+
2293
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
2294
+ const lists = await client.bulkAddListTag(accountId, { list_ids: positionals, tag: values.tag });
2295
+ if (values.json) return writeJson(context.stdout, lists);
2296
+
2297
+ const count = Array.isArray(lists) ? lists.length : 0;
2298
+ writeLine(context.stdout, `Added tag ${display(values.tag)} to ${count} ${count === 1 ? "list" : "lists"}.`);
2299
+ }
2300
+
2301
+ async function listsMerge(args, context, { accountOverride } = {}) {
2302
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
2303
+ if (positionals.length !== 2) throw new CommandError(LISTS_MERGE_USAGE);
2304
+
2305
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
2306
+ const list = await client.mergeLists(accountId, { list_ids: positionals });
2307
+ if (values.json) return writeJson(context.stdout, list);
2308
+
2309
+ writeLine(context.stdout, `Merged into list ${display(list?.name)} (${display(list?.prefix_id)}); the newer list was deleted.`);
2310
+ writeLine(context.stdout, `Prospects: ${display(list?.prospect_count, 0)}`);
2311
+ }
2312
+
2313
+ async function listsExport(args, context, { accountOverride } = {}) {
2314
+ const { values, positionals } = parseCommandArgs(args, {
2315
+ ...jsonOptions(),
2316
+ output: { type: "string" },
2317
+ "inactive-reason": { type: "string" }
2318
+ });
2319
+ if (positionals.length !== 1) throw new CommandError(LISTS_EXPORT_USAGE);
2320
+
2321
+ const listId = positionals[0];
2322
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
2323
+ const csv = String(await client.exportList(accountId, listId, compactObject({ inactive_reason: values["inactive-reason"] })) ?? "");
2324
+
2325
+ if (values.output) {
2326
+ await writeFile(values.output, csv);
2327
+ if (values.json) return writeJson(context.stdout, { list_id: listId, output: values.output, bytes: Buffer.byteLength(csv) });
2328
+ return writeLine(context.stdout, `Wrote list ${display(listId)} CSV to ${values.output}.`);
2329
+ }
2330
+ if (values.json) return writeJson(context.stdout, { list_id: listId, csv });
2331
+
2332
+ context.stdout.write(csv);
2333
+ }
2334
+
2089
2335
  async function listProspects(args, context, { accountOverride } = {}) {
2090
2336
  const { values, positionals } = parseCommandArgs(args, {
2091
2337
  ...jsonOptions(),
@@ -2167,7 +2413,7 @@ async function listsRemoveProspects(args, context, { accountOverride } = {}) {
2167
2413
  async function listsRoutingRules(args, context, { accountOverride } = {}) {
2168
2414
  const [listId, subaction, ...rest] = args;
2169
2415
  if (!listId || !subaction) {
2170
- throw new CommandError("Usage: audienti lists routing-rules <list_id> <list|create|update|remove|move|apply> [args] [--json] [--account <acct_id>]");
2416
+ throw new CommandError("Usage: audienti lists routing-rules <list_id> <list|create|update|remove|move|toggle|apply> [args] [--json] [--account <acct_id>]");
2171
2417
  }
2172
2418
 
2173
2419
  if (subaction === "list") return listRoutingRulesList(listId, rest, context, { accountOverride });
@@ -2175,9 +2421,10 @@ async function listsRoutingRules(args, context, { accountOverride } = {}) {
2175
2421
  if (subaction === "update") return listRoutingRulesUpdate(listId, rest, context, { accountOverride });
2176
2422
  if (["remove", "delete"].includes(subaction)) return listRoutingRulesRemove(listId, rest, context, { accountOverride });
2177
2423
  if (subaction === "move") return listRoutingRulesMove(listId, rest, context, { accountOverride });
2424
+ if (subaction === "toggle") return listRoutingRulesToggle(listId, rest, context, { accountOverride });
2178
2425
  if (subaction === "apply") return listRoutingRulesApply(listId, rest, context, { accountOverride });
2179
2426
 
2180
- throw new CommandError("Usage: audienti lists routing-rules <list_id> <list|create|update|remove|move|apply> [args] [--json] [--account <acct_id>]");
2427
+ throw new CommandError("Usage: audienti lists routing-rules <list_id> <list|create|update|remove|move|toggle|apply> [args] [--json] [--account <acct_id>]");
2181
2428
  }
2182
2429
 
2183
2430
  async function listRoutingRulesList(listId, args, context, { accountOverride } = {}) {
@@ -2251,6 +2498,19 @@ async function listRoutingRulesMove(listId, args, context, { accountOverride } =
2251
2498
  renderListRoutingRules(payload, context);
2252
2499
  }
2253
2500
 
2501
+ async function listRoutingRulesToggle(listId, args, context, { accountOverride } = {}) {
2502
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
2503
+ if (positionals.length !== 1) throw new CommandError(LIST_ROUTING_RULES_TOGGLE_USAGE);
2504
+
2505
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
2506
+ const payload = await client.toggleListRoutingRule(accountId, listId, positionals[0]);
2507
+ if (values.json) return writeJson(context.stdout, payload);
2508
+
2509
+ const rule = payload?.routing_rule;
2510
+ const state = rule?.enabled ? "Enabled" : "Disabled";
2511
+ writeLine(context.stdout, `${state} routing rule ${display(rule?.name)} (${display(rule?.id || positionals[0])}) on list ${display(payload?.list_id || listId)}.`);
2512
+ }
2513
+
2254
2514
  async function listRoutingRulesApply(listId, args, context, { accountOverride } = {}) {
2255
2515
  const { values, positionals } = parseCommandArgs(args, jsonOptions());
2256
2516
  if (positionals.length > 0) throw new CommandError(LIST_ROUTING_RULES_APPLY_USAGE);
@@ -3803,6 +4063,23 @@ async function toolsLinkedinReviewStatus(args, context, { accountOverride } = {}
3803
4063
  renderLinkedinReviewStatus(payload, context);
3804
4064
  }
3805
4065
 
4066
+ async function toolsLinkedinStrategyReview(args, context, { accountOverride } = {}) {
4067
+ const [subaction, ...rest] = args;
4068
+ if (subaction !== "delete") throw new CommandError(TOOLS_LINKEDIN_STRATEGY_REVIEW_DELETE_USAGE);
4069
+
4070
+ const { values, positionals } = parseCommandArgs(rest, { ...jsonOptions(), confirm: { type: "string" } });
4071
+ const normalizedConfirm = String(values.confirm || "").trim().toLowerCase();
4072
+ if (positionals.length !== 1 || !DELETE_CONFIRMATION_VALUES.has(normalizedConfirm)) {
4073
+ throw new CommandError(TOOLS_LINKEDIN_STRATEGY_REVIEW_DELETE_USAGE);
4074
+ }
4075
+
4076
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
4077
+ const payload = await client.deleteLinkedinStrategyReview(accountId, positionals[0]);
4078
+ if (values.json) return writeJson(context.stdout, payload);
4079
+
4080
+ writeLine(context.stdout, `Deleted LinkedIn strategy review report ${display(payload?.id || positionals[0])}.`);
4081
+ }
4082
+
3806
4083
  async function operatorQueue(args, context, { accountOverride } = {}) {
3807
4084
  const { values, positionals } = parseCommandArgs(args, operatorFilterOptions(operatorPaginationOptions()));
3808
4085
  if (positionals.length > 0) throw new CommandError("Usage: audienti operator queue [--json] [filters] [--account <acct_id>]");
@@ -6128,6 +6405,16 @@ function renderOffer(offer, context) {
6128
6405
  writeLine(context.stdout, `Offer: ${display(offer?.name)} (${display(offer?.prefix_id)})`);
6129
6406
  if (offer?.description) writeLine(context.stdout, `Description: ${offer.description}`);
6130
6407
  if (offer?.url) writeLine(context.stdout, `URL: ${offer.url}`);
6408
+ if (Array.isArray(offer?.artifacts) && offer.artifacts.length > 0) renderOfferArtifacts(offer.artifacts, context);
6409
+ }
6410
+
6411
+ function renderOfferArtifacts(artifacts, context) {
6412
+ if (!Array.isArray(artifacts) || artifacts.length === 0) return writeLine(context.stdout, "No artifacts attached.");
6413
+
6414
+ writeLine(context.stdout, "ARTIFACT ID\tFILENAME\tTYPE\tBYTES");
6415
+ for (const artifact of artifacts) {
6416
+ writeLine(context.stdout, [display(artifact.id), display(artifact.filename), display(artifact.content_type, "-"), display(artifact.byte_size, 0)].join("\t"));
6417
+ }
6131
6418
  }
6132
6419
 
6133
6420
  function renderIcps(icps, context) {
@@ -8971,15 +9258,23 @@ const HELP_TOPICS = new Map([
8971
9258
  " audienti lists routing-rules <list_id> list",
8972
9259
  " audienti lists routing-rules <list_id> create --payload <file.json>",
8973
9260
  " audienti lists routing-rules <list_id> apply",
9261
+ " audienti lists bulk-add-tag --tag <tag> <list_id> [list_id...]",
9262
+ " audienti lists merge <list_id> <list_id>",
9263
+ " audienti lists export <list_id> [--output <file.csv>]",
8974
9264
  " audienti tags list",
8975
9265
  " audienti tags show <tag>",
8976
9266
  " audienti tasks list [--status open]",
8977
9267
  " audienti tasks add --title <text> --due <time>",
8978
9268
  " audienti tasks complete <ptsk_id>",
9269
+ " audienti tasks update <ptsk_id> [--title <text>]",
9270
+ " audienti tasks bulk-update --action <complete|reassign> <ptsk_id> [ptsk_id...]",
8979
9271
  " audienti offers list",
8980
9272
  " audienti offers show <offr_id>",
8981
9273
  " audienti offers update <offr_id> [--name <text>]",
8982
9274
  " audienti offers delete <offr_id> --confirm <yes|true|Y|y>",
9275
+ " audienti offers regenerate-research <offr_id> [--guidance <text>]",
9276
+ " audienti offers update-writeup <offr_id> --description <text>",
9277
+ " audienti offers add-artifacts <offr_id> <file> [file...]",
8983
9278
  " audienti icps list [--status <active|archived|all>] [--tag <tag>]",
8984
9279
  " audienti icps show <icp_id>",
8985
9280
  " audienti icps update <icp_id> [--tags <tag[,tag...]> | --payload <file.json>]",
@@ -8987,6 +9282,10 @@ const HELP_TOPICS = new Map([
8987
9282
  " audienti icps restore <icp_id>",
8988
9283
  " audienti icps add-tag <icp_id> <tag>",
8989
9284
  " audienti icps remove-tag <icp_id> <tag>",
9285
+ " audienti icps bulk-add-tag --tag <tag> <icp_id> [icp_id...]",
9286
+ " audienti icps clone <icp_id>",
9287
+ " audienti icps delete <icp_id> --confirm <yes|true|Y|y>",
9288
+ " audienti icps prospects <icp_id> [--query <text>]",
8990
9289
  " audienti companies search --query <text>",
8991
9290
  " audienti linkedin-lookups <kind> [--query <text>]",
8992
9291
  " audienti dnc list",
@@ -9528,6 +9827,10 @@ const HELP_TOPICS = new Map([
9528
9827
  " audienti offers create --name <text> [--json]",
9529
9828
  " audienti offers update <offr_id> [--name <text>] [--json]",
9530
9829
  " audienti offers delete <offr_id> --confirm <yes|true|Y|y> [--json]",
9830
+ " audienti offers regenerate-research <offr_id> [--guidance <text>] [--json]",
9831
+ " audienti offers update-writeup <offr_id> --description <text> [--json]",
9832
+ " audienti offers add-artifacts <offr_id> <file> [file...] [--json]",
9833
+ " audienti offers remove-artifact <offr_id> <artifact_id> [--json]",
9531
9834
  "",
9532
9835
  "Status: implemented",
9533
9836
  "",
@@ -9639,6 +9942,10 @@ const HELP_TOPICS = new Map([
9639
9942
  " audienti icps remove-tag <icp_id> <tag> [--json]",
9640
9943
  " audienti icps archive <icp_id> [--json]",
9641
9944
  " audienti icps restore <icp_id> [--json]",
9945
+ " audienti icps bulk-add-tag --tag <tag> <icp_id> [icp_id...] [--json]",
9946
+ " audienti icps clone <icp_id> [--json]",
9947
+ " audienti icps delete <icp_id> --confirm <yes|true|Y|y> [--json]",
9948
+ " audienti icps prospects <icp_id> [--query <text>] [--json]",
9642
9949
  "",
9643
9950
  "Status: implemented",
9644
9951
  "",
@@ -10337,6 +10644,8 @@ const HELP_TOPICS = new Map([
10337
10644
  ` ${TASKS_LIST_USAGE.slice("Usage: ".length)}`,
10338
10645
  ` ${TASKS_ADD_USAGE.slice("Usage: ".length)}`,
10339
10646
  ` ${TASKS_COMPLETE_USAGE.slice("Usage: ".length)}`,
10647
+ ` ${TASKS_UPDATE_USAGE.slice("Usage: ".length)}`,
10648
+ ` ${TASKS_BULK_UPDATE_USAGE.slice("Usage: ".length)}`,
10340
10649
  "",
10341
10650
  "Status: implemented",
10342
10651
  "",
@@ -10417,10 +10726,13 @@ const HELP_TOPICS = new Map([
10417
10726
  " audienti lists add-tag <list_id> <tag> [--json]",
10418
10727
  " audienti lists remove-tag <list_id> <tag> [--json]",
10419
10728
  " audienti lists delete <list_id> --confirm <yes|true|Y|y> [--json]",
10729
+ " audienti lists bulk-add-tag --tag <tag> <list_id> [list_id...] [--json]",
10730
+ " audienti lists merge <list_id> <list_id> [--json]",
10731
+ " audienti lists export <list_id> [--output <file.csv>] [--json]",
10420
10732
  " audienti lists prospects <list_id> [--json]",
10421
10733
  " audienti lists add-prospects <list_id> <prsp_id> [prsp_id...] [--json]",
10422
10734
  " audienti lists remove-prospects <list_id> <prsp_id> [prsp_id...] [--json]",
10423
- " audienti lists routing-rules <list_id> <list|create|update|remove|move|apply> [args] [--json]",
10735
+ " audienti lists routing-rules <list_id> <list|create|update|remove|move|toggle|apply> [args] [--json]",
10424
10736
  "",
10425
10737
  "Status: read, create, update, delete, membership, and routing-rule commands implemented",
10426
10738
  "",
@@ -10435,6 +10747,7 @@ const HELP_TOPICS = new Map([
10435
10747
  " audienti lists routing-rules <list_id> update <rule_id> --payload <file.json> [--json] [--account <acct_id>]",
10436
10748
  " audienti lists routing-rules <list_id> remove <rule_id> [--json] [--account <acct_id>]",
10437
10749
  " audienti lists routing-rules <list_id> move <rule_id> <up|down> [--json] [--account <acct_id>]",
10750
+ " audienti lists routing-rules <list_id> toggle <rule_id> [--json] [--account <acct_id>]",
10438
10751
  " audienti lists routing-rules <list_id> apply [--json] [--account <acct_id>]",
10439
10752
  "",
10440
10753
  "Status: implemented",
@@ -10576,6 +10889,259 @@ const HELP_TOPICS = new Map([
10576
10889
  " PATCH /api/v1/accounts/:account_id/lists/:id.json"
10577
10890
  ].join("\n")],
10578
10891
 
10892
+ ["lists bulk-add-tag", [
10893
+ "Usage:",
10894
+ ` ${LISTS_BULK_ADD_TAG_USAGE.slice("Usage: ".length)}`,
10895
+ "",
10896
+ "Status: implemented",
10897
+ "",
10898
+ "Purpose:",
10899
+ " Add one normalized tag to several lists at once. All lists change or none do.",
10900
+ "",
10901
+ "Input shape:",
10902
+ " list_id: list_ prefix id or integer id; every id must belong to the account",
10903
+ " tag: string",
10904
+ "",
10905
+ "API:",
10906
+ " POST /api/v1/accounts/:account_id/lists/bulk_add_tag.json"
10907
+ ].join("\n")],
10908
+
10909
+ ["lists merge", [
10910
+ "Usage:",
10911
+ ` ${LISTS_MERGE_USAGE.slice("Usage: ".length)}`,
10912
+ "",
10913
+ "Status: implemented",
10914
+ "",
10915
+ "Purpose:",
10916
+ " Merge two lists. The older list keeps its name and gains the newer list's tags, prospects, agents, and routing targets; the newer list is deleted.",
10917
+ " System and HubSpot-synced lists cannot be merged.",
10918
+ "",
10919
+ "Input shape:",
10920
+ " list_id: exactly two different list ids in the account",
10921
+ "",
10922
+ "API:",
10923
+ " POST /api/v1/accounts/:account_id/lists/merge_selected.json"
10924
+ ].join("\n")],
10925
+
10926
+ ["lists export", [
10927
+ "Usage:",
10928
+ ` ${LISTS_EXPORT_USAGE.slice("Usage: ".length)}`,
10929
+ "",
10930
+ "Status: implemented",
10931
+ "",
10932
+ "Purpose:",
10933
+ " Download the list's prospects as CSV with the same columns as the web export.",
10934
+ " Prints to stdout unless --output is given.",
10935
+ "",
10936
+ "Input shape:",
10937
+ " list_id: list_ prefix id",
10938
+ " inactive-reason: optional filter for the inactive system list",
10939
+ "",
10940
+ "API:",
10941
+ " GET /api/v1/accounts/:account_id/lists/:id/export.json (returns text/csv)"
10942
+ ].join("\n")],
10943
+
10944
+ ["lists routing-rules toggle", [
10945
+ "Usage:",
10946
+ ` ${LIST_ROUTING_RULES_TOGGLE_USAGE.slice("Usage: ".length)}`,
10947
+ "",
10948
+ "Status: implemented",
10949
+ "",
10950
+ "Purpose:",
10951
+ " Turn one routing rule on or off.",
10952
+ "",
10953
+ "Input shape:",
10954
+ " rule_id: routing rule id on the list",
10955
+ "",
10956
+ "API:",
10957
+ " PATCH /api/v1/accounts/:account_id/lists/:list_id/routing_rules/:id/toggle.json"
10958
+ ].join("\n")],
10959
+
10960
+ ["icps bulk-add-tag", [
10961
+ "Usage:",
10962
+ ` ${ICPS_BULK_ADD_TAG_USAGE.slice("Usage: ".length)}`,
10963
+ "",
10964
+ "Status: implemented",
10965
+ "",
10966
+ "Purpose:",
10967
+ " Add one normalized tag to several ICPs at once. All ICPs change or none do.",
10968
+ "",
10969
+ "Input shape:",
10970
+ " icp_id: icpp_ prefix id or integer id; every id must belong to the account",
10971
+ " tag: string",
10972
+ "",
10973
+ "API:",
10974
+ " POST /api/v1/accounts/:account_id/icps/bulk_add_tag.json"
10975
+ ].join("\n")],
10976
+
10977
+ ["icps clone", [
10978
+ "Usage:",
10979
+ ` ${ICPS_CLONE_USAGE.slice("Usage: ".length)}`,
10980
+ "",
10981
+ "Status: implemented",
10982
+ "",
10983
+ "Purpose:",
10984
+ " Copy an ICP and its audience rules under a new \"(Copy)\" name.",
10985
+ "",
10986
+ "Input shape:",
10987
+ " icp_id: icpp_ prefix id or integer id",
10988
+ "",
10989
+ "API:",
10990
+ " POST /api/v1/accounts/:account_id/icps/:id/clone.json"
10991
+ ].join("\n")],
10992
+
10993
+ ["icps delete", [
10994
+ "Usage:",
10995
+ ` ${ICPS_DELETE_USAGE.slice("Usage: ".length)}`,
10996
+ "",
10997
+ "Status: implemented",
10998
+ "",
10999
+ "Purpose:",
11000
+ " Delete an ICP. ICPs still used by motions or agents are refused; archive them instead.",
11001
+ "",
11002
+ "Input shape:",
11003
+ " icp_id: icpp_ prefix id or integer id",
11004
+ " confirm: one of yes, true, Y, y",
11005
+ "",
11006
+ "API:",
11007
+ " DELETE /api/v1/accounts/:account_id/icps/:id.json"
11008
+ ].join("\n")],
11009
+
11010
+ ["icps prospects", [
11011
+ "Usage:",
11012
+ ` ${ICPS_PROSPECTS_USAGE.slice("Usage: ".length)}`,
11013
+ "",
11014
+ "Status: implemented",
11015
+ "",
11016
+ "Purpose:",
11017
+ " List prospects matched to an ICP, newest first, optionally filtered by a text query.",
11018
+ "",
11019
+ "Input shape:",
11020
+ " icp_id: icpp_ prefix id or integer id",
11021
+ " limit: 1-100 (default 25)",
11022
+ "",
11023
+ "API:",
11024
+ " GET /api/v1/accounts/:account_id/icps/:id/prospects.json"
11025
+ ].join("\n")],
11026
+
11027
+ ["offers regenerate-research", [
11028
+ "Usage:",
11029
+ ` ${OFFERS_REGENERATE_RESEARCH_USAGE.slice("Usage: ".length)}`,
11030
+ "",
11031
+ "Status: implemented",
11032
+ "",
11033
+ "Purpose:",
11034
+ " Queue a new research write-up for an offer, optionally steered by guidance. Returns once queued.",
11035
+ "",
11036
+ "Input shape:",
11037
+ " offr_id: offr_ prefixed id or integer id",
11038
+ " guidance: optional text",
11039
+ "",
11040
+ "API:",
11041
+ " POST /api/v1/accounts/:account_id/offers/:id/regenerate_research.json"
11042
+ ].join("\n")],
11043
+
11044
+ ["offers update-writeup", [
11045
+ "Usage:",
11046
+ ` ${OFFERS_UPDATE_WRITEUP_USAGE.slice("Usage: ".length)}`,
11047
+ "",
11048
+ "Status: implemented",
11049
+ "",
11050
+ "Purpose:",
11051
+ " Replace an offer's write-up without queueing new research.",
11052
+ "",
11053
+ "Input shape:",
11054
+ " offr_id: offr_ prefixed id or integer id",
11055
+ " description: text",
11056
+ "",
11057
+ "API:",
11058
+ " PATCH /api/v1/accounts/:account_id/offers/:id/writeup.json"
11059
+ ].join("\n")],
11060
+
11061
+ ["offers add-artifacts", [
11062
+ "Usage:",
11063
+ ` ${OFFERS_ADD_ARTIFACTS_USAGE.slice("Usage: ".length)}`,
11064
+ "",
11065
+ "Status: implemented",
11066
+ "",
11067
+ "Purpose:",
11068
+ " Attach local files to an offer as artifacts. `audienti offers show` lists attached artifacts.",
11069
+ "",
11070
+ "Input shape:",
11071
+ " offr_id: offr_ prefixed id or integer id",
11072
+ " file: local file path; sent as base64",
11073
+ "",
11074
+ "API:",
11075
+ " POST /api/v1/accounts/:account_id/offers/:offer_id/artifacts.json"
11076
+ ].join("\n")],
11077
+
11078
+ ["offers remove-artifact", [
11079
+ "Usage:",
11080
+ ` ${OFFERS_REMOVE_ARTIFACT_USAGE.slice("Usage: ".length)}`,
11081
+ "",
11082
+ "Status: implemented",
11083
+ "",
11084
+ "Purpose:",
11085
+ " Remove one artifact from an offer.",
11086
+ "",
11087
+ "Input shape:",
11088
+ " artifact_id: id from `audienti offers show <offr_id>`",
11089
+ "",
11090
+ "API:",
11091
+ " DELETE /api/v1/accounts/:account_id/offers/:offer_id/artifacts/:id.json"
11092
+ ].join("\n")],
11093
+
11094
+ ["tasks update", [
11095
+ "Usage:",
11096
+ ` ${TASKS_UPDATE_USAGE.slice("Usage: ".length)}`,
11097
+ "",
11098
+ "Status: implemented",
11099
+ "",
11100
+ "Purpose:",
11101
+ " Edit any task in the account. Only the options you pass change; pass an empty --prospect or --list to clear it.",
11102
+ "",
11103
+ "Input shape:",
11104
+ " task_id: ptsk_ prefix id or numeric id",
11105
+ " assigned-user: account user id or me",
11106
+ "",
11107
+ "API:",
11108
+ " PATCH /api/v1/accounts/:account_id/tasks/:id.json"
11109
+ ].join("\n")],
11110
+
11111
+ ["tasks bulk-update", [
11112
+ "Usage:",
11113
+ ` ${TASKS_BULK_UPDATE_USAGE.slice("Usage: ".length)}`,
11114
+ "",
11115
+ "Status: implemented",
11116
+ "",
11117
+ "Purpose:",
11118
+ " Complete several tasks now, or queue their reassignment to one account user.",
11119
+ "",
11120
+ "Input shape:",
11121
+ " task_id: ptsk_ prefix ids; every id must belong to the account",
11122
+ " action: complete or reassign (reassign needs --assigned-user)",
11123
+ "",
11124
+ "API:",
11125
+ " PATCH /api/v1/accounts/:account_id/tasks/bulk_update.json"
11126
+ ].join("\n")],
11127
+
11128
+ ["tools linkedin-strategy-review delete", [
11129
+ "Usage:",
11130
+ ` ${TOOLS_LINKEDIN_STRATEGY_REVIEW_DELETE_USAGE.slice("Usage: ".length)}`,
11131
+ "",
11132
+ "Status: implemented",
11133
+ "",
11134
+ "Purpose:",
11135
+ " Delete one LinkedIn strategy review report.",
11136
+ "",
11137
+ "Input shape:",
11138
+ " rprt_id: rprt_ report id of a strategy review",
11139
+ " confirm: one of yes, true, Y, y",
11140
+ "",
11141
+ "API:",
11142
+ " DELETE /api/v1/accounts/:account_id/tools/linkedin-strategy-review/reports/:id.json"
11143
+ ].join("\n")],
11144
+
10579
11145
  ["lists add-tag", [
10580
11146
  "Usage:",
10581
11147
  ` ${LISTS_ADD_TAG_USAGE.slice("Usage: ".length)}`,
@@ -12037,6 +12603,7 @@ const HELP_TOPICS = new Map([
12037
12603
  " audienti tools linkedin-review reports [--limit <n>] [--json]",
12038
12604
  " audienti tools linkedin-review show <rprt_id> [--json]",
12039
12605
  " audienti tools linkedin-review status <rprt_id> [--json]",
12606
+ " audienti tools linkedin-strategy-review delete <rprt_id> --confirm <yes|true|Y|y> [--json]",
12040
12607
  "",
12041
12608
  "Status: implemented",
12042
12609
  "",
@@ -12047,7 +12614,8 @@ const HELP_TOPICS = new Map([
12047
12614
  " audienti tools linkedin-review Queue a LinkedIn personal profile authority review and ICP-fit positioning blueprint.",
12048
12615
  " audienti tools linkedin-review reports List recent LinkedIn Review reports for the active account.",
12049
12616
  " audienti tools linkedin-review show View the completed report content in the terminal.",
12050
- " audienti tools linkedin-review status Show the current report stage and run status."
12617
+ " audienti tools linkedin-review status Show the current report stage and run status.",
12618
+ " audienti tools linkedin-strategy-review delete Delete one LinkedIn strategy review report."
12051
12619
  ].join("\n")],
12052
12620
 
12053
12621
  ["tools list", [