@audienti/cli 0.1.73 → 0.1.75

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,10 +4,23 @@ All notable changes to the Audienti CLI are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.75] - 2026-09-27
8
+
9
+ ### Added
10
+
11
+ - Add `hubspot show|connect|disconnect|sync|retry` (`connect --token-stdin` keeps the token out of shell history), `hubspot list-syncs create|update|remove|sync`, `webhooks list|create|update|rotate|remove`, `reply-alerts show|update`, and `brand-profile show|update` so HubSpot, prospect webhook, reply alert, and brand profile settings are reachable from the CLI.
12
+
13
+ ## [0.1.74] - 2026-09-27
14
+
7
15
  ### Added
8
16
 
17
+ - Add `accounts show`, `company-rules show`, and `linkedin-lookups <kind>` so account details, single company rules, and LinkedIn targeting values are reachable from the CLI.
9
18
  - Add Motion-owned discovery signal tracking to `motions show` and the `motions signals` command, including attribution holds, source counts, and retained Agent provenance.
10
19
 
20
+ ### Fixed
21
+
22
+ - LinkedIn lookups accept API tokens and prefixed ICP ids, so CLI lookups no longer fail with an authentication error.
23
+
11
24
  ## [0.1.73] - 2026-09-26
12
25
 
13
26
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audienti/cli",
3
- "version": "0.1.73",
3
+ "version": "0.1.75",
4
4
  "description": "Agent-first command-line client for Audienti.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/api-client.js CHANGED
@@ -40,6 +40,14 @@ export class AudientiClient {
40
40
  return this.requestJson("/api/v1/accounts.json");
41
41
  }
42
42
 
43
+ account(accountId) {
44
+ return this.requestJson(accountPath(accountId, []));
45
+ }
46
+
47
+ linkedinLookup(kind, query = {}) {
48
+ return this.requestJson(apiPath(["linkedin_lookups", kind], query));
49
+ }
50
+
43
51
  mcp(message) {
44
52
  return this.requestJson("/mcp", {
45
53
  method: "POST",
@@ -187,6 +195,10 @@ export class AudientiClient {
187
195
  return this.requestJson(accountPath(accountId, ["company_rules"]));
188
196
  }
189
197
 
198
+ companyRule(accountId, ruleId) {
199
+ return this.requestJson(accountPath(accountId, ["company_rules", ruleId]));
200
+ }
201
+
190
202
  createCompanyRule(accountId, body) {
191
203
  return this.requestJson(accountPath(accountId, ["company_rules"]), {
192
204
  method: "POST",
@@ -219,6 +231,114 @@ export class AudientiClient {
219
231
  });
220
232
  }
221
233
 
234
+ hubspotIntegration(accountId, query = {}) {
235
+ return this.requestJson(accountPath(accountId, ["hubspot_integration"], query));
236
+ }
237
+
238
+ connectHubspot(accountId, body) {
239
+ return this.requestJson(accountPath(accountId, ["hubspot_integration"]), {
240
+ method: "POST",
241
+ body
242
+ });
243
+ }
244
+
245
+ disconnectHubspot(accountId) {
246
+ return this.requestJson(accountPath(accountId, ["hubspot_integration"]), {
247
+ method: "DELETE"
248
+ });
249
+ }
250
+
251
+ retryHubspotEvent(accountId, body) {
252
+ return this.requestJson(accountPath(accountId, ["hubspot_integration", "retry_event"]), {
253
+ method: "POST",
254
+ body
255
+ });
256
+ }
257
+
258
+ syncHubspot(accountId) {
259
+ return this.requestJson(accountPath(accountId, ["hubspot_integration", "sync_all"]), {
260
+ method: "POST"
261
+ });
262
+ }
263
+
264
+ createHubspotListSync(accountId, body) {
265
+ return this.requestJson(accountPath(accountId, ["hubspot_integration", "list_syncs"]), {
266
+ method: "POST",
267
+ body
268
+ });
269
+ }
270
+
271
+ updateHubspotListSync(accountId, listSyncId, body) {
272
+ return this.requestJson(accountPath(accountId, ["hubspot_integration", "list_syncs", listSyncId]), {
273
+ method: "PATCH",
274
+ body
275
+ });
276
+ }
277
+
278
+ deleteHubspotListSync(accountId, listSyncId) {
279
+ return this.requestJson(accountPath(accountId, ["hubspot_integration", "list_syncs", listSyncId]), {
280
+ method: "DELETE"
281
+ });
282
+ }
283
+
284
+ syncHubspotListSync(accountId, listSyncId) {
285
+ return this.requestJson(accountPath(accountId, ["hubspot_integration", "list_syncs", listSyncId, "sync_now"]), {
286
+ method: "POST"
287
+ });
288
+ }
289
+
290
+ prospectWebhookEndpoints(accountId) {
291
+ return this.requestJson(accountPath(accountId, ["prospect_webhook_endpoints"]));
292
+ }
293
+
294
+ createProspectWebhookEndpoint(accountId, body) {
295
+ return this.requestJson(accountPath(accountId, ["prospect_webhook_endpoints"]), {
296
+ method: "POST",
297
+ body
298
+ });
299
+ }
300
+
301
+ updateProspectWebhookEndpoint(accountId, endpointId, body) {
302
+ return this.requestJson(accountPath(accountId, ["prospect_webhook_endpoints", endpointId]), {
303
+ method: "PATCH",
304
+ body
305
+ });
306
+ }
307
+
308
+ rotateProspectWebhookEndpoint(accountId, endpointId) {
309
+ return this.requestJson(accountPath(accountId, ["prospect_webhook_endpoints", endpointId, "rotate"]), {
310
+ method: "POST"
311
+ });
312
+ }
313
+
314
+ deleteProspectWebhookEndpoint(accountId, endpointId) {
315
+ return this.requestJson(accountPath(accountId, ["prospect_webhook_endpoints", endpointId]), {
316
+ method: "DELETE"
317
+ });
318
+ }
319
+
320
+ brandProfile(accountId) {
321
+ return this.requestJson(accountPath(accountId, ["brand_profile"]));
322
+ }
323
+
324
+ updateBrandProfile(accountId, body) {
325
+ return this.requestJson(accountPath(accountId, ["brand_profile"]), {
326
+ method: "PATCH",
327
+ body
328
+ });
329
+ }
330
+
331
+ replyAlerts() {
332
+ return this.requestJson(apiPath(["me", "reply_alerts"]));
333
+ }
334
+
335
+ updateReplyAlerts(body) {
336
+ return this.requestJson(apiPath(["me", "reply_alerts"]), {
337
+ method: "PATCH",
338
+ body
339
+ });
340
+ }
341
+
222
342
  tags(accountId) {
223
343
  return this.requestJson(accountPath(accountId, ["tags"]));
224
344
  }
@@ -819,11 +939,13 @@ export class AudientiClient {
819
939
  }
820
940
 
821
941
  function accountPath(accountId, segments, query = {}) {
942
+ return apiPath(["accounts", accountId, ...segments], query);
943
+ }
944
+
945
+ function apiPath(segments, query = {}) {
822
946
  const encodedSegments = [
823
947
  "api",
824
948
  "v1",
825
- "accounts",
826
- accountId,
827
949
  ...segments
828
950
  ].map((segment) => encodeURIComponent(segment));
829
951
  const searchParams = new URLSearchParams();
package/src/cli.js CHANGED
@@ -112,6 +112,37 @@ const COMPANY_RULES_CREATE_USAGE = "Usage: audienti company-rules create (--link
112
112
  const COMPANY_RULES_UPDATE_USAGE = "Usage: audienti company-rules update <rule_id> [--linkedin-url <url>] [--domain <domain>] [--disposition <monitor|nurture|not_fit|reject>] [--name <text>] [--user <account_user_id|email|me|none>] [--note <text>] [--json] [--account <acct_id>]";
113
113
  const COMPANY_RULES_REMOVE_USAGE = "Usage: audienti company-rules remove <rule_id> [--json] [--account <acct_id>]";
114
114
  const COMPANY_RULES_APPLY_USAGE = "Usage: audienti company-rules apply (<rule_id>|--all) [--json] [--account <acct_id>]";
115
+ const COMPANY_RULES_SHOW_USAGE = "Usage: audienti company-rules show <rule_id> [--json] [--account <acct_id>]";
116
+ const HUBSPOT_SHOW_USAGE = "Usage: audienti hubspot show [--errors] [--limit <n>] [--json] [--account <acct_id>]";
117
+ const HUBSPOT_CONNECT_USAGE = "Usage: audienti hubspot connect (--token <private_app_token> | --token-stdin) [--json] [--account <acct_id>]";
118
+ const WEBHOOK_STATUS_VALUES = new Set(["enabled", "disabled"]);
119
+ const HUBSPOT_DISCONNECT_USAGE = "Usage: audienti hubspot disconnect [--json] [--account <acct_id>]";
120
+ const HUBSPOT_SYNC_USAGE = "Usage: audienti hubspot sync [--json] [--account <acct_id>]";
121
+ const HUBSPOT_RETRY_USAGE = "Usage: audienti hubspot retry <event_id> [--json] [--account <acct_id>]";
122
+ const HUBSPOT_LIST_SYNCS_CREATE_USAGE = "Usage: audienti hubspot list-syncs create --hubspot-list <hubspot_list_id> --signal <signal_id> --source-agent <agent_id> [--json] [--account <acct_id>]";
123
+ const HUBSPOT_LIST_SYNCS_UPDATE_USAGE = "Usage: audienti hubspot list-syncs update <list_sync_id> --signal <signal_id> --source-agent <agent_id> [--json] [--account <acct_id>]";
124
+ const HUBSPOT_LIST_SYNCS_REMOVE_USAGE = "Usage: audienti hubspot list-syncs remove <list_sync_id> [--json] [--account <acct_id>]";
125
+ const HUBSPOT_LIST_SYNCS_SYNC_USAGE = "Usage: audienti hubspot list-syncs sync <list_sync_id> [--json] [--account <acct_id>]";
126
+ const WEBHOOKS_LIST_USAGE = "Usage: audienti webhooks list [--json] [--account <acct_id>]";
127
+ const WEBHOOKS_CREATE_USAGE = "Usage: audienti webhooks create [--label <text>] [--signal <signal_id>] [--list <list_id>] [--json] [--account <acct_id>]";
128
+ const WEBHOOKS_UPDATE_USAGE = "Usage: audienti webhooks update <endpoint_id> [--label <text>] [--status <enabled|disabled>] [--signal <signal_id|none>] [--json] [--account <acct_id>]";
129
+ const WEBHOOKS_ROTATE_USAGE = "Usage: audienti webhooks rotate <endpoint_id> [--json] [--account <acct_id>]";
130
+ const WEBHOOKS_REMOVE_USAGE = "Usage: audienti webhooks remove <endpoint_id> [--json] [--account <acct_id>]";
131
+ const REPLY_ALERTS_SHOW_USAGE = "Usage: audienti reply-alerts show [--json]";
132
+ const REPLY_ALERTS_UPDATE_USAGE = "Usage: audienti reply-alerts update [--phone <number|none>] [--sms <true|false>] [--slack <true|false>] [--json]";
133
+ const BRAND_PROFILE_SHOW_USAGE = "Usage: audienti brand-profile show [--json] [--account <acct_id>]";
134
+ const BRAND_PROFILE_UPDATE_USAGE = "Usage: audienti brand-profile update [--voice <text>] [--style <text>] [--do-not-use <text>] [--json] [--account <acct_id>]";
135
+ const ACCOUNTS_SHOW_USAGE = "Usage: audienti accounts show [<acct_id>] [--json] [--account <acct_id>]";
136
+ const LINKEDIN_LOOKUPS_USAGE = "Usage: audienti linkedin-lookups <company-sizes|company-types|functions|industries|job-titles|locations|seniorities> [--query <text>] [--icp <icp_id>] [--json] [--account <acct_id>]";
137
+ const LINKEDIN_LOOKUP_KINDS = new Map([
138
+ ["company-sizes", { path: "company_sizes", query: "none", icp: true }],
139
+ ["company-types", { path: "company_types", query: "none", icp: true }],
140
+ ["functions", { path: "functions", query: "required", icp: true }],
141
+ ["industries", { path: "industries", query: "required", icp: false }],
142
+ ["job-titles", { path: "job_titles", query: "required", icp: true }],
143
+ ["locations", { path: "locations", query: "required", icp: true }],
144
+ ["seniorities", { path: "seniorities", query: "optional", icp: true }]
145
+ ]);
115
146
  const TASKS_LIST_USAGE = "Usage: audienti tasks list [--status <open|completed>] [--limit <n>] [--json] [--account <acct_id>]";
116
147
  const TASKS_ADD_USAGE = "Usage: audienti tasks add --title <text> --due <time> [--prospect <prsp_id>] [--list <list_id>] [--assigned-user <id|me>] [--notes <text>] [--json] [--account <acct_id>]";
117
148
  const TASKS_COMPLETE_USAGE = "Usage: audienti tasks complete <ptsk_id> [--json] [--account <acct_id>]";
@@ -265,6 +296,8 @@ async function dispatch(argv, context) {
265
296
  if (normalizedResource === "update" && action === "check") return updateCheck(rest, context);
266
297
  if (normalizedResource === "accounts" && action === "list") return accountsList(rest, context, { accountOverride });
267
298
  if (normalizedResource === "accounts" && action === "select") return accountsSelect(rest, context);
299
+ if (normalizedResource === "accounts" && action === "show") return accountsShow(rest, context, { accountOverride });
300
+ if (normalizedResource === "linkedin-lookups") return linkedinLookups(action, rest, context, { accountOverride });
268
301
  if (normalizedResource === "users" && action === "list") return usersList(rest, context, { accountOverride });
269
302
  if (normalizedResource === "users" && action === "select") return usersSelect(rest, context, { accountOverride });
270
303
  if (normalizedResource === "users" && action === "activity") return usersActivity(rest, context, { accountOverride });
@@ -291,10 +324,16 @@ async function dispatch(argv, context) {
291
324
  if (normalizedResource === "dnc" && action === "import") return dncImport(rest, context, { accountOverride });
292
325
  if (normalizedResource === "dnc" && ["remove", "delete"].includes(action)) return dncRemove(rest, context, { accountOverride });
293
326
  if (normalizedResource === "company-rules" && action === "list") return companyRulesList(rest, context, { accountOverride });
327
+ if (normalizedResource === "company-rules" && action === "show") return companyRulesShow(rest, context, { accountOverride });
294
328
  if (normalizedResource === "company-rules" && action === "create") return companyRulesCreate(rest, context, { accountOverride });
295
329
  if (normalizedResource === "company-rules" && action === "update") return companyRulesUpdate(rest, context, { accountOverride });
296
330
  if (normalizedResource === "company-rules" && ["remove", "delete"].includes(action)) return companyRulesRemove(rest, context, { accountOverride });
297
331
  if (normalizedResource === "company-rules" && action === "apply") return companyRulesApply(rest, context, { accountOverride });
332
+ if (normalizedResource === "hubspot" && action === "list-syncs") return hubspotListSyncs(rest[0], rest.slice(1), context, { accountOverride });
333
+ if (normalizedResource === "hubspot") return hubspotCommand(action, rest, context, { accountOverride });
334
+ if (normalizedResource === "webhooks") return webhooksCommand(action, rest, context, { accountOverride });
335
+ if (normalizedResource === "reply-alerts") return replyAlertsCommand(action, rest, context);
336
+ if (normalizedResource === "brand-profile") return brandProfileCommand(action, rest, context, { accountOverride });
298
337
  if (normalizedResource === "tags" && action === "list") return tagsList(rest, context, { accountOverride });
299
338
  if (normalizedResource === "tags" && action === "show") return tagsShow(rest, context, { accountOverride });
300
339
  if (normalizedResource === "tasks" && ["list", "manage"].includes(action)) return tasksList(rest, context, { accountOverride });
@@ -482,6 +521,11 @@ function normalizeResource(resource) {
482
521
  if (resource === "principals") return "users";
483
522
  if (resource === "writers") return "writer";
484
523
  if (resource === "company_rules" || resource === "company-rules") return "company-rules";
524
+ if (resource === "hubspot_integration" || resource === "hubspot-integration") return "hubspot";
525
+ if (resource === "prospect_webhook_endpoints" || resource === "prospect-webhook-endpoints") return "webhooks";
526
+ if (resource === "reply_alerts") return "reply-alerts";
527
+ if (resource === "brand_profile") return "brand-profile";
528
+ if (resource === "linkedin_lookups" || resource === "linkedin-lookups") return "linkedin-lookups";
485
529
  if (resource === "social_cookie" || resource === "social_cookies") return "social-cookies";
486
530
  return resource === "plays" ? "motions" : resource;
487
531
  }
@@ -802,6 +846,64 @@ async function accountsList(args, context, { accountOverride } = {}) {
802
846
  }
803
847
  }
804
848
 
849
+ async function accountsShow(args, context, { accountOverride } = {}) {
850
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
851
+ if (positionals.length > 1) throw new CommandError(ACCOUNTS_SHOW_USAGE);
852
+
853
+ const config = await requireAuthenticatedConfig(context);
854
+ const accountId = positionals[0] || accountOverride || config.accountId;
855
+ if (!accountId) {
856
+ throw new CommandError("No active account. Run `audienti accounts select <acct_id>`, pass `--account <acct_id>`, or give an account id.");
857
+ }
858
+
859
+ const account = await clientFromConfig(config, context).account(accountId);
860
+ if (values.json) return writeJson(context.stdout, account);
861
+
862
+ writeLine(context.stdout, `Account: ${display(account?.name)} (${display(account?.prefix_id || accountId)})`);
863
+ writeLine(context.stdout, `Personal: ${account?.personal ? "yes" : "no"}`);
864
+ writeLine(context.stdout, `Members: ${Array.isArray(account?.account_users) ? account.account_users.length : 0}`);
865
+ writeLine(context.stdout, `Created: ${display(account?.created_at, "-")}`);
866
+ }
867
+
868
+ async function linkedinLookups(kind, args, context, { accountOverride } = {}) {
869
+ const lookup = LINKEDIN_LOOKUP_KINDS.get(String(kind || "").replaceAll("_", "-"));
870
+ if (!lookup) throw new CommandError(LINKEDIN_LOOKUPS_USAGE);
871
+
872
+ const { values, positionals } = parseCommandArgs(args, {
873
+ ...jsonOptions(),
874
+ query: { type: "string" },
875
+ icp: { type: "string" }
876
+ });
877
+ const query = values.query?.trim();
878
+ const invalid = positionals.length > 0 ||
879
+ (lookup.query === "required" && !query) ||
880
+ (lookup.query === "none" && values.query !== undefined) ||
881
+ (!lookup.icp && values.icp !== undefined);
882
+ if (invalid) throw new CommandError(LINKEDIN_LOOKUPS_USAGE);
883
+
884
+ const config = await requireAuthenticatedConfig(context);
885
+ const params = { q: query };
886
+ if (values.icp) {
887
+ const accountId = accountOverride || config.accountId;
888
+ if (!accountId) {
889
+ throw new CommandError("No active account. Run `audienti accounts select <acct_id>` or pass `--account <acct_id>` to look up with --icp.");
890
+ }
891
+ params.icp_id = values.icp;
892
+ params.account_id = accountId;
893
+ }
894
+
895
+ const payload = await clientFromConfig(config, context).linkedinLookup(lookup.path, params);
896
+ if (values.json) return writeJson(context.stdout, payload);
897
+
898
+ const rows = Array.isArray(payload) ? payload : [];
899
+ if (rows.length === 0) return writeLine(context.stdout, "No results found.");
900
+
901
+ writeLine(context.stdout, "ID\tNAME\tSOURCE");
902
+ for (const row of rows) {
903
+ writeLine(context.stdout, [display(row.id, "-"), display(row.name), display(row.source, "-")].join("\t"));
904
+ }
905
+ }
906
+
805
907
  async function accountsSelect(args, context) {
806
908
  const { positionals } = parseCommandArgs(args, {});
807
909
  if (positionals.length !== 1) throw new CommandError("Usage: audienti accounts select <acct_id>");
@@ -1339,6 +1441,22 @@ async function companyRulesList(args, context, { accountOverride } = {}) {
1339
1441
  renderCompanyRules(payload, context);
1340
1442
  }
1341
1443
 
1444
+ async function companyRulesShow(args, context, { accountOverride } = {}) {
1445
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1446
+ if (positionals.length !== 1) throw new CommandError(COMPANY_RULES_SHOW_USAGE);
1447
+
1448
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1449
+ const payload = await client.companyRule(accountId, positionals[0]);
1450
+ if (values.json) return writeJson(context.stdout, payload);
1451
+
1452
+ const rule = payload?.company_rule;
1453
+ writeLine(context.stdout, `Company rule ${display(rule?.name || rule?.domain || rule?.linkedin_company_identifier)} (${display(rule?.prefix_id || rule?.id)})`);
1454
+ writeLine(context.stdout, `Disposition: ${display(rule?.disposition)} | Scope: ${companyRuleScopeLabel(rule)} | Active: ${rule?.active ? "yes" : "no"}`);
1455
+ writeLine(context.stdout, `LinkedIn: ${display(rule?.linkedin_company_url || rule?.linkedin_company_identifier, "-")}`);
1456
+ writeLine(context.stdout, `Domain: ${display(rule?.domain, "-")}`);
1457
+ if (rule?.note) writeLine(context.stdout, `Note: ${rule.note}`);
1458
+ }
1459
+
1342
1460
  async function companyRulesCreate(args, context, { accountOverride } = {}) {
1343
1461
  const { values, positionals } = parseCommandArgs(args, companyRuleOptions());
1344
1462
  if (positionals.length > 0 || (!values["linkedin-url"] && !values.domain) || !values.disposition) {
@@ -1401,6 +1519,377 @@ async function companyRulesApply(args, context, { accountOverride } = {}) {
1401
1519
  }
1402
1520
  }
1403
1521
 
1522
+ async function hubspotCommand(action, args, context, { accountOverride } = {}) {
1523
+ if (action === "show") return hubspotShow(args, context, { accountOverride });
1524
+ if (action === "connect") return hubspotConnect(args, context, { accountOverride });
1525
+ if (action === "disconnect") return hubspotDisconnect(args, context, { accountOverride });
1526
+ if (action === "sync") return hubspotSync(args, context, { accountOverride });
1527
+ if (action === "retry") return hubspotRetry(args, context, { accountOverride });
1528
+
1529
+ throw new CommandError(`Unknown hubspot command "${display(action, "")}". Run \`audienti hubspot --help\`.`);
1530
+ }
1531
+
1532
+ async function hubspotShow(args, context, { accountOverride } = {}) {
1533
+ const { values, positionals } = parseCommandArgs(args, {
1534
+ ...jsonOptions(),
1535
+ errors: { type: "boolean" },
1536
+ limit: { type: "string" }
1537
+ });
1538
+ if (positionals.length > 0) throw new CommandError(HUBSPOT_SHOW_USAGE);
1539
+ const limit = normalizeOptionalPositiveInteger(values.limit, "--limit");
1540
+
1541
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1542
+ const payload = await client.hubspotIntegration(accountId, {
1543
+ log_status: values.errors ? "error" : undefined,
1544
+ limit
1545
+ });
1546
+ if (values.json) return writeJson(context.stdout, payload);
1547
+
1548
+ const integration = payload?.hubspot_integration;
1549
+ if (!integration) {
1550
+ writeLine(context.stdout, "HubSpot: not connected.");
1551
+ return;
1552
+ }
1553
+
1554
+ writeLine(context.stdout, `HubSpot: ${display(integration.status)} | Auto sync: ${integration.auto_sync_enabled ? "on" : "off"}`);
1555
+ writeLine(context.stdout, `Portal: ${display(integration.external_account_name, "-")} (${display(integration.external_account_id, "-")})`);
1556
+ writeLine(context.stdout, `Last synced: ${display(integration.last_synced_at, "never")}`);
1557
+ if (integration.last_error_message) writeLine(context.stdout, `Last error: ${integration.last_error_message}`);
1558
+
1559
+ const listSyncs = payload?.list_syncs || [];
1560
+ writeLine(context.stdout, `List syncs: ${listSyncs.length}`);
1561
+ for (const listSync of listSyncs) {
1562
+ writeLine(context.stdout, ` ${display(listSync.id)} ${display(listSync.source_list_name || listSync.source_list_id)} ${display(listSync.display_status || listSync.status)} signal: ${display(listSync.custom_signal?.name, "-")}`);
1563
+ }
1564
+
1565
+ const events = payload?.recent_events || [];
1566
+ writeLine(context.stdout, `Recent events: ${events.length}`);
1567
+ for (const event of events) {
1568
+ const retry = event.retryable ? " (retryable)" : "";
1569
+ writeLine(context.stdout, ` ${display(event.id)} ${display(event.status)} ${display(event.event_type)} ${display(event.message, "")}${retry}`);
1570
+ }
1571
+ }
1572
+
1573
+ async function hubspotConnect(args, context, { accountOverride } = {}) {
1574
+ const { values, positionals } = parseCommandArgs(args, {
1575
+ ...jsonOptions(),
1576
+ token: { type: "string" },
1577
+ "token-stdin": { type: "boolean" }
1578
+ });
1579
+ const useStdin = Boolean(values["token-stdin"]);
1580
+ if (positionals.length > 0 || useStdin === (values.token !== undefined)) throw new CommandError(HUBSPOT_CONNECT_USAGE);
1581
+
1582
+ const token = (useStdin ? await readStdinText(context) : String(values.token)).trim();
1583
+ if (!token) throw new CommandError(HUBSPOT_CONNECT_USAGE);
1584
+
1585
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1586
+ const payload = await client.connectHubspot(accountId, { personal_access_token: token });
1587
+ if (values.json) return writeJson(context.stdout, payload);
1588
+
1589
+ const integration = payload?.hubspot_integration;
1590
+ writeLine(context.stdout, `Connected HubSpot portal ${display(integration?.external_account_name || integration?.external_account_id)}.`);
1591
+ if (payload?.warning) writeLine(context.stdout, `Warning: ${payload.warning}`);
1592
+ }
1593
+
1594
+ async function hubspotDisconnect(args, context, { accountOverride } = {}) {
1595
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1596
+ if (positionals.length > 0) throw new CommandError(HUBSPOT_DISCONNECT_USAGE);
1597
+
1598
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1599
+ const payload = await client.disconnectHubspot(accountId);
1600
+ if (values.json) return writeJson(context.stdout, payload);
1601
+
1602
+ writeLine(context.stdout, "Disconnected HubSpot.");
1603
+ }
1604
+
1605
+ async function hubspotSync(args, context, { accountOverride } = {}) {
1606
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1607
+ if (positionals.length > 0) throw new CommandError(HUBSPOT_SYNC_USAGE);
1608
+
1609
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1610
+ const payload = await client.syncHubspot(accountId);
1611
+ if (values.json) return writeJson(context.stdout, payload);
1612
+
1613
+ writeLine(context.stdout, display(payload?.message, "HubSpot sync all queued."));
1614
+ }
1615
+
1616
+ async function hubspotRetry(args, context, { accountOverride } = {}) {
1617
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1618
+ if (positionals.length !== 1) throw new CommandError(HUBSPOT_RETRY_USAGE);
1619
+
1620
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1621
+ const payload = await client.retryHubspotEvent(accountId, { event_id: positionals[0] });
1622
+ if (values.json) return writeJson(context.stdout, payload);
1623
+
1624
+ writeLine(context.stdout, display(payload?.message, "HubSpot retry queued."));
1625
+ }
1626
+
1627
+ async function hubspotListSyncs(action, args, context, { accountOverride } = {}) {
1628
+ const options = {
1629
+ ...jsonOptions(),
1630
+ "hubspot-list": { type: "string" },
1631
+ signal: { type: "string" },
1632
+ "source-agent": { type: "string" }
1633
+ };
1634
+
1635
+ if (action === "create") {
1636
+ const { values, positionals } = parseCommandArgs(args, options);
1637
+ if (positionals.length > 0 || !values["hubspot-list"] || !values.signal || !values["source-agent"]) {
1638
+ throw new CommandError(HUBSPOT_LIST_SYNCS_CREATE_USAGE);
1639
+ }
1640
+
1641
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1642
+ const payload = await client.createHubspotListSync(accountId, {
1643
+ source_list_id: values["hubspot-list"],
1644
+ custom_signal_id: values.signal,
1645
+ source_agent_id: values["source-agent"]
1646
+ });
1647
+ if (values.json) return writeJson(context.stdout, payload);
1648
+
1649
+ const listSync = payload?.list_sync;
1650
+ writeLine(context.stdout, `Created HubSpot list sync ${display(listSync?.id)} for ${display(listSync?.source_list_name || listSync?.source_list_id)}.`);
1651
+ return;
1652
+ }
1653
+
1654
+ if (action === "update") {
1655
+ const { values, positionals } = parseCommandArgs(args, options);
1656
+ if (positionals.length !== 1 || !values.signal || !values["source-agent"]) throw new CommandError(HUBSPOT_LIST_SYNCS_UPDATE_USAGE);
1657
+
1658
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1659
+ const payload = await client.updateHubspotListSync(accountId, positionals[0], {
1660
+ custom_signal_id: values.signal,
1661
+ source_agent_id: values["source-agent"]
1662
+ });
1663
+ if (values.json) return writeJson(context.stdout, payload);
1664
+
1665
+ writeLine(context.stdout, `Updated HubSpot list sync ${display(payload?.list_sync?.id || positionals[0])}. Updated prospects: ${display(payload?.updated_count, 0)}.`);
1666
+ return;
1667
+ }
1668
+
1669
+ if (action === "remove" || action === "delete") {
1670
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1671
+ if (positionals.length !== 1) throw new CommandError(HUBSPOT_LIST_SYNCS_REMOVE_USAGE);
1672
+
1673
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1674
+ const payload = await client.deleteHubspotListSync(accountId, positionals[0]);
1675
+ if (values.json) return writeJson(context.stdout, payload);
1676
+
1677
+ writeLine(context.stdout, `Removed HubSpot list sync ${display(payload?.id || positionals[0])}.`);
1678
+ return;
1679
+ }
1680
+
1681
+ if (action === "sync") {
1682
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1683
+ if (positionals.length !== 1) throw new CommandError(HUBSPOT_LIST_SYNCS_SYNC_USAGE);
1684
+
1685
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1686
+ const payload = await client.syncHubspotListSync(accountId, positionals[0]);
1687
+ if (values.json) return writeJson(context.stdout, payload);
1688
+
1689
+ writeLine(context.stdout, display(payload?.message, "HubSpot list sync queued."));
1690
+ return;
1691
+ }
1692
+
1693
+ throw new CommandError(`Unknown hubspot list-syncs command "${display(action, "")}". Run \`audienti hubspot list-syncs --help\`.`);
1694
+ }
1695
+
1696
+ async function webhooksCommand(action, args, context, { accountOverride } = {}) {
1697
+ const options = {
1698
+ ...jsonOptions(),
1699
+ label: { type: "string" },
1700
+ signal: { type: "string" },
1701
+ list: { type: "string" },
1702
+ status: { type: "string" }
1703
+ };
1704
+
1705
+ if (action === "list") {
1706
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1707
+ if (positionals.length > 0) throw new CommandError(WEBHOOKS_LIST_USAGE);
1708
+
1709
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1710
+ const payload = await client.prospectWebhookEndpoints(accountId);
1711
+ if (values.json) return writeJson(context.stdout, payload);
1712
+
1713
+ const endpoints = payload?.prospect_webhook_endpoints || [];
1714
+ if (endpoints.length === 0) {
1715
+ writeLine(context.stdout, "No prospect webhook endpoints.");
1716
+ return;
1717
+ }
1718
+ for (const endpoint of endpoints) {
1719
+ writeLine(context.stdout, `${display(endpoint.id)} ${display(endpoint.display_label || endpoint.label)} ${display(endpoint.status)} ${display(endpoint.url)}`);
1720
+ }
1721
+ return;
1722
+ }
1723
+
1724
+ if (action === "create") {
1725
+ const { values, positionals } = parseCommandArgs(args, options);
1726
+ if (positionals.length > 0 || values.status !== undefined) throw new CommandError(WEBHOOKS_CREATE_USAGE);
1727
+
1728
+ const body = {};
1729
+ if (values.label !== undefined) body.label = values.label;
1730
+ if (values.signal !== undefined) body.custom_signal_id = values.signal;
1731
+ if (values.list !== undefined) body.list_id = values.list;
1732
+
1733
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1734
+ const payload = await client.createProspectWebhookEndpoint(accountId, body);
1735
+ if (values.json) return writeJson(context.stdout, payload);
1736
+
1737
+ writeWebhookEndpoint("Created", payload?.prospect_webhook_endpoint, context);
1738
+ return;
1739
+ }
1740
+
1741
+ if (action === "update") {
1742
+ const { values, positionals } = parseCommandArgs(args, options);
1743
+ const body = {};
1744
+ if (values.label !== undefined) body.label = values.label;
1745
+ if (values.status !== undefined) {
1746
+ if (!WEBHOOK_STATUS_VALUES.has(values.status)) throw new CommandError("--status must be enabled or disabled.");
1747
+ body.status = values.status;
1748
+ }
1749
+ if (values.signal !== undefined) body.custom_signal_id = values.signal === "none" ? "" : values.signal;
1750
+ if (positionals.length !== 1 || values.list !== undefined || Object.keys(body).length === 0) {
1751
+ throw new CommandError(WEBHOOKS_UPDATE_USAGE);
1752
+ }
1753
+
1754
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1755
+ const payload = await client.updateProspectWebhookEndpoint(accountId, positionals[0], body);
1756
+ if (values.json) return writeJson(context.stdout, payload);
1757
+
1758
+ writeWebhookEndpoint("Updated", payload?.prospect_webhook_endpoint, context);
1759
+ return;
1760
+ }
1761
+
1762
+ if (action === "rotate") {
1763
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1764
+ if (positionals.length !== 1) throw new CommandError(WEBHOOKS_ROTATE_USAGE);
1765
+
1766
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1767
+ const payload = await client.rotateProspectWebhookEndpoint(accountId, positionals[0]);
1768
+ if (values.json) return writeJson(context.stdout, payload);
1769
+
1770
+ writeWebhookEndpoint("Rotated", payload?.prospect_webhook_endpoint, context);
1771
+ return;
1772
+ }
1773
+
1774
+ if (action === "remove" || action === "delete") {
1775
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1776
+ if (positionals.length !== 1) throw new CommandError(WEBHOOKS_REMOVE_USAGE);
1777
+
1778
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1779
+ const payload = await client.deleteProspectWebhookEndpoint(accountId, positionals[0]);
1780
+ if (values.json) return writeJson(context.stdout, payload);
1781
+
1782
+ writeLine(context.stdout, `Removed prospect webhook endpoint ${display(payload?.id || positionals[0])}.`);
1783
+ return;
1784
+ }
1785
+
1786
+ throw new CommandError(`Unknown webhooks command "${display(action, "")}". Run \`audienti webhooks --help\`.`);
1787
+ }
1788
+
1789
+ async function readStdinText(context) {
1790
+ const input = context.stdin;
1791
+ if (!input) return "";
1792
+
1793
+ let text = "";
1794
+ for await (const chunk of input) text += String(chunk);
1795
+ return text;
1796
+ }
1797
+
1798
+ function writeWebhookEndpoint(verb, endpoint, context) {
1799
+ writeLine(context.stdout, `${verb} prospect webhook endpoint ${display(endpoint?.display_label || endpoint?.label)} (${display(endpoint?.id)}).`);
1800
+ writeLine(context.stdout, `Status: ${display(endpoint?.status)} | Signal: ${display(endpoint?.custom_signal?.name, "-")} | List: ${display(endpoint?.list?.name, "-")}`);
1801
+ writeLine(context.stdout, `URL: ${display(endpoint?.url)}`);
1802
+ }
1803
+
1804
+ async function replyAlertsCommand(action, args, context) {
1805
+ if (action === "show") {
1806
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1807
+ if (positionals.length > 0) throw new CommandError(REPLY_ALERTS_SHOW_USAGE);
1808
+
1809
+ const config = await requireAuthenticatedConfig(context);
1810
+ const client = clientFromConfig(config, context);
1811
+ const payload = await client.replyAlerts();
1812
+ if (values.json) return writeJson(context.stdout, payload);
1813
+
1814
+ writeReplyAlerts(payload?.reply_alerts, context);
1815
+ return;
1816
+ }
1817
+
1818
+ if (action === "update") {
1819
+ const { values, positionals } = parseCommandArgs(args, {
1820
+ ...jsonOptions(),
1821
+ phone: { type: "string" },
1822
+ sms: { type: "string" },
1823
+ slack: { type: "string" }
1824
+ });
1825
+ const body = {};
1826
+ if (values.phone !== undefined) body.phone_number = values.phone === "none" ? "" : values.phone;
1827
+ if (values.sms !== undefined) body.sms_enabled = parseBooleanString(values.sms, "--sms");
1828
+ if (values.slack !== undefined) body.slack_enabled = parseBooleanString(values.slack, "--slack");
1829
+ if (positionals.length > 0 || Object.keys(body).length === 0) throw new CommandError(REPLY_ALERTS_UPDATE_USAGE);
1830
+
1831
+ const config = await requireAuthenticatedConfig(context);
1832
+ const client = clientFromConfig(config, context);
1833
+ const payload = await client.updateReplyAlerts(body);
1834
+ if (values.json) return writeJson(context.stdout, payload);
1835
+
1836
+ writeLine(context.stdout, "Updated reply alerts.");
1837
+ writeReplyAlerts(payload?.reply_alerts, context);
1838
+ return;
1839
+ }
1840
+
1841
+ throw new CommandError(`Unknown reply-alerts command "${display(action, "")}". Run \`audienti reply-alerts --help\`.`);
1842
+ }
1843
+
1844
+ function writeReplyAlerts(alerts, context) {
1845
+ writeLine(context.stdout, `SMS: ${alerts?.sms_enabled ? "on" : "off"} | Phone: ${display(alerts?.phone_number, "-")} | Active: ${alerts?.sms_active ? "yes" : "no"}`);
1846
+ writeLine(context.stdout, `Slack: ${alerts?.slack_enabled ? "on" : "off"} | Connected: ${alerts?.slack_connected ? "yes" : "no"} | Channel: ${display(alerts?.slack_channel, "-")}`);
1847
+ }
1848
+
1849
+ async function brandProfileCommand(action, args, context, { accountOverride } = {}) {
1850
+ if (action === "show") {
1851
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
1852
+ if (positionals.length > 0) throw new CommandError(BRAND_PROFILE_SHOW_USAGE);
1853
+
1854
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1855
+ const payload = await client.brandProfile(accountId);
1856
+ if (values.json) return writeJson(context.stdout, payload);
1857
+
1858
+ writeBrandProfile(payload?.brand_profile, context);
1859
+ return;
1860
+ }
1861
+
1862
+ if (action === "update") {
1863
+ const { values, positionals } = parseCommandArgs(args, {
1864
+ ...jsonOptions(),
1865
+ voice: { type: "string" },
1866
+ style: { type: "string" },
1867
+ "do-not-use": { type: "string" }
1868
+ });
1869
+ const body = {};
1870
+ if (values.voice !== undefined) body.voice = values.voice;
1871
+ if (values.style !== undefined) body.style = values.style;
1872
+ if (values["do-not-use"] !== undefined) body.do_not_use = values["do-not-use"];
1873
+ if (positionals.length > 0 || Object.keys(body).length === 0) throw new CommandError(BRAND_PROFILE_UPDATE_USAGE);
1874
+
1875
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1876
+ const payload = await client.updateBrandProfile(accountId, body);
1877
+ if (values.json) return writeJson(context.stdout, payload);
1878
+
1879
+ writeLine(context.stdout, "Updated brand profile.");
1880
+ writeBrandProfile(payload?.brand_profile, context);
1881
+ return;
1882
+ }
1883
+
1884
+ throw new CommandError(`Unknown brand-profile command "${display(action, "")}". Run \`audienti brand-profile --help\`.`);
1885
+ }
1886
+
1887
+ function writeBrandProfile(profile, context) {
1888
+ writeLine(context.stdout, `Voice: ${display(profile?.voice, "-")}`);
1889
+ writeLine(context.stdout, `Style: ${display(profile?.style, "-")}`);
1890
+ writeLine(context.stdout, `Do not use: ${display(profile?.do_not_use, "-")}`);
1891
+ }
1892
+
1404
1893
  async function tagsList(args, context, { accountOverride } = {}) {
1405
1894
  const { values, positionals } = parseCommandArgs(args, jsonOptions());
1406
1895
  if (positionals.length > 0) throw new CommandError("Usage: audienti tags list [--json] [--account <acct_id>]");
@@ -8411,6 +8900,7 @@ const HELP_TOPICS = new Map([
8411
8900
  " Setup & identity",
8412
8901
  " audienti auth status",
8413
8902
  " audienti config list",
8903
+ " audienti accounts show [acct_id]",
8414
8904
  " audienti update check",
8415
8905
  " audienti setup play preflight",
8416
8906
  " audienti users list",
@@ -8498,10 +8988,16 @@ const HELP_TOPICS = new Map([
8498
8988
  " audienti icps add-tag <icp_id> <tag>",
8499
8989
  " audienti icps remove-tag <icp_id> <tag>",
8500
8990
  " audienti companies search --query <text>",
8991
+ " audienti linkedin-lookups <kind> [--query <text>]",
8501
8992
  " audienti dnc list",
8502
8993
  " audienti dnc add <email|citation_id|profile_url>",
8503
8994
  " audienti company-rules list",
8995
+ " audienti company-rules show <rule_id>",
8504
8996
  " audienti company-rules create (--linkedin-url <url> | --domain <domain>) --disposition <state>",
8997
+ " audienti hubspot show",
8998
+ " audienti webhooks list",
8999
+ " audienti brand-profile show",
9000
+ " audienti reply-alerts show",
8505
9001
  "",
8506
9002
  " Writer",
8507
9003
  " audienti writer test-run <prsp_id>",
@@ -8725,6 +9221,7 @@ const HELP_TOPICS = new Map([
8725
9221
  ["accounts", [
8726
9222
  "Usage:",
8727
9223
  " audienti accounts list [--json]",
9224
+ " audienti accounts show [<acct_id>] [--json]",
8728
9225
  " audienti accounts select <acct_id>",
8729
9226
  "",
8730
9227
  "Status: implemented",
@@ -8783,6 +9280,51 @@ const HELP_TOPICS = new Map([
8783
9280
  " audienti accounts list --json"
8784
9281
  ].join("\n")],
8785
9282
 
9283
+ ["accounts show", [
9284
+ "Usage:",
9285
+ ` ${ACCOUNTS_SHOW_USAGE.slice("Usage: ".length)}`,
9286
+ "",
9287
+ "Status: implemented",
9288
+ "",
9289
+ "API:",
9290
+ " GET /api/v1/accounts/:id.json",
9291
+ "",
9292
+ "Input shape:",
9293
+ " acct_id: string Account prefix id; defaults to --account or the selected account",
9294
+ "",
9295
+ "Output shape:",
9296
+ " id, prefix_id, name, personal, owner_id, account_users[], created_at, updated_at"
9297
+ ].join("\n")],
9298
+
9299
+ ["linkedin-lookups", [
9300
+ "Usage:",
9301
+ ` ${LINKEDIN_LOOKUPS_USAGE.slice("Usage: ".length)}`,
9302
+ "",
9303
+ "Status: implemented",
9304
+ "",
9305
+ "Purpose:",
9306
+ " Look up LinkedIn targeting values (the ids used in ICP filters).",
9307
+ "",
9308
+ "Kinds:",
9309
+ " job-titles, functions, locations --query required",
9310
+ " industries --query required; --icp not supported",
9311
+ " seniorities --query optional filter",
9312
+ " company-sizes, company-types no --query; returns the full list",
9313
+ "",
9314
+ "ICP option:",
9315
+ " --icp <icp_id> uses values saved on that ICP of the active account (or --account).",
9316
+ " For company-sizes, company-types and seniorities it also saves the list onto that ICP.",
9317
+ "",
9318
+ "API:",
9319
+ " GET /api/v1/linkedin_lookups/<kind>.json?q=<text>&icp_id=<icp_id>",
9320
+ "",
9321
+ "Output shape:",
9322
+ " [{ id, name, source? }]",
9323
+ "",
9324
+ "Example:",
9325
+ " audienti linkedin-lookups job-titles --query \"head of sales\" --json"
9326
+ ].join("\n")],
9327
+
8786
9328
  ["accounts select", [
8787
9329
  "Usage:",
8788
9330
  " audienti accounts select <acct_id>",
@@ -9410,9 +9952,245 @@ const HELP_TOPICS = new Map([
9410
9952
  " DELETE /api/v1/accounts/:account_id/dnc/:id.json"
9411
9953
  ].join("\n")],
9412
9954
 
9955
+ ["hubspot", [
9956
+ "Usage:",
9957
+ ` ${HUBSPOT_SHOW_USAGE.slice("Usage: ".length)}`,
9958
+ ` ${HUBSPOT_CONNECT_USAGE.slice("Usage: ".length)}`,
9959
+ ` ${HUBSPOT_DISCONNECT_USAGE.slice("Usage: ".length)}`,
9960
+ ` ${HUBSPOT_SYNC_USAGE.slice("Usage: ".length)}`,
9961
+ ` ${HUBSPOT_RETRY_USAGE.slice("Usage: ".length)}`,
9962
+ ` ${HUBSPOT_LIST_SYNCS_CREATE_USAGE.slice("Usage: ".length)}`,
9963
+ ` ${HUBSPOT_LIST_SYNCS_UPDATE_USAGE.slice("Usage: ".length)}`,
9964
+ ` ${HUBSPOT_LIST_SYNCS_REMOVE_USAGE.slice("Usage: ".length)}`,
9965
+ ` ${HUBSPOT_LIST_SYNCS_SYNC_USAGE.slice("Usage: ".length)}`,
9966
+ "",
9967
+ "Status: implemented",
9968
+ "",
9969
+ "Purpose:",
9970
+ " Connect HubSpot, queue syncs, retry failed sync events, and manage HubSpot list syncs. The token is never returned.",
9971
+ "",
9972
+ "API:",
9973
+ " GET /api/v1/accounts/:account_id/hubspot_integration.json",
9974
+ " POST /api/v1/accounts/:account_id/hubspot_integration.json",
9975
+ " DELETE /api/v1/accounts/:account_id/hubspot_integration.json",
9976
+ " POST /api/v1/accounts/:account_id/hubspot_integration/sync_all.json",
9977
+ " POST /api/v1/accounts/:account_id/hubspot_integration/retry_event.json"
9978
+ ].join("\n")],
9979
+
9980
+ ["hubspot show", [
9981
+ "Usage:",
9982
+ ` ${HUBSPOT_SHOW_USAGE.slice("Usage: ".length)}`,
9983
+ "",
9984
+ "Status: implemented",
9985
+ "",
9986
+ "API:",
9987
+ " GET /api/v1/accounts/:account_id/hubspot_integration.json"
9988
+ ].join("\n")],
9989
+
9990
+ ["hubspot connect", [
9991
+ "Usage:",
9992
+ ` ${HUBSPOT_CONNECT_USAGE.slice("Usage: ".length)}`,
9993
+ "",
9994
+ "Status: implemented",
9995
+ "",
9996
+ "Notes:",
9997
+ " --token-stdin reads the token from stdin, keeping it out of shell history and the process list.",
9998
+ "",
9999
+ "API:",
10000
+ " POST /api/v1/accounts/:account_id/hubspot_integration.json"
10001
+ ].join("\n")],
10002
+
10003
+ ["hubspot disconnect", [
10004
+ "Usage:",
10005
+ ` ${HUBSPOT_DISCONNECT_USAGE.slice("Usage: ".length)}`,
10006
+ "",
10007
+ "Status: implemented",
10008
+ "",
10009
+ "API:",
10010
+ " DELETE /api/v1/accounts/:account_id/hubspot_integration.json"
10011
+ ].join("\n")],
10012
+
10013
+ ["hubspot sync", [
10014
+ "Usage:",
10015
+ ` ${HUBSPOT_SYNC_USAGE.slice("Usage: ".length)}`,
10016
+ "",
10017
+ "Status: implemented",
10018
+ "",
10019
+ "API:",
10020
+ " POST /api/v1/accounts/:account_id/hubspot_integration/sync_all.json"
10021
+ ].join("\n")],
10022
+
10023
+ ["hubspot retry", [
10024
+ "Usage:",
10025
+ ` ${HUBSPOT_RETRY_USAGE.slice("Usage: ".length)}`,
10026
+ "",
10027
+ "Status: implemented",
10028
+ "",
10029
+ "API:",
10030
+ " POST /api/v1/accounts/:account_id/hubspot_integration/retry_event.json"
10031
+ ].join("\n")],
10032
+
10033
+ ["hubspot list-syncs", [
10034
+ "Usage:",
10035
+ ` ${HUBSPOT_LIST_SYNCS_CREATE_USAGE.slice("Usage: ".length)}`,
10036
+ ` ${HUBSPOT_LIST_SYNCS_UPDATE_USAGE.slice("Usage: ".length)}`,
10037
+ ` ${HUBSPOT_LIST_SYNCS_REMOVE_USAGE.slice("Usage: ".length)}`,
10038
+ ` ${HUBSPOT_LIST_SYNCS_SYNC_USAGE.slice("Usage: ".length)}`,
10039
+ "",
10040
+ "Status: implemented",
10041
+ "",
10042
+ "API:",
10043
+ " POST /api/v1/accounts/:account_id/hubspot_integration/list_syncs.json",
10044
+ " PATCH /api/v1/accounts/:account_id/hubspot_integration/list_syncs/:id.json",
10045
+ " DELETE /api/v1/accounts/:account_id/hubspot_integration/list_syncs/:id.json",
10046
+ " POST /api/v1/accounts/:account_id/hubspot_integration/list_syncs/:id/sync_now.json"
10047
+ ].join("\n")],
10048
+
10049
+ ["webhooks", [
10050
+ "Usage:",
10051
+ ` ${WEBHOOKS_LIST_USAGE.slice("Usage: ".length)}`,
10052
+ ` ${WEBHOOKS_CREATE_USAGE.slice("Usage: ".length)}`,
10053
+ ` ${WEBHOOKS_UPDATE_USAGE.slice("Usage: ".length)}`,
10054
+ ` ${WEBHOOKS_ROTATE_USAGE.slice("Usage: ".length)}`,
10055
+ ` ${WEBHOOKS_REMOVE_USAGE.slice("Usage: ".length)}`,
10056
+ "",
10057
+ "Status: implemented",
10058
+ "",
10059
+ "Purpose:",
10060
+ " Manage prospect intake webhook endpoints. Create and rotate return the endpoint URL.",
10061
+ "",
10062
+ "API:",
10063
+ " GET /api/v1/accounts/:account_id/prospect_webhook_endpoints.json",
10064
+ " POST /api/v1/accounts/:account_id/prospect_webhook_endpoints.json",
10065
+ " PATCH /api/v1/accounts/:account_id/prospect_webhook_endpoints/:id.json",
10066
+ " POST /api/v1/accounts/:account_id/prospect_webhook_endpoints/:id/rotate.json",
10067
+ " DELETE /api/v1/accounts/:account_id/prospect_webhook_endpoints/:id.json"
10068
+ ].join("\n")],
10069
+
10070
+ ["webhooks list", [
10071
+ "Usage:",
10072
+ ` ${WEBHOOKS_LIST_USAGE.slice("Usage: ".length)}`,
10073
+ "",
10074
+ "Status: implemented",
10075
+ "",
10076
+ "API:",
10077
+ " GET /api/v1/accounts/:account_id/prospect_webhook_endpoints.json"
10078
+ ].join("\n")],
10079
+
10080
+ ["webhooks create", [
10081
+ "Usage:",
10082
+ ` ${WEBHOOKS_CREATE_USAGE.slice("Usage: ".length)}`,
10083
+ "",
10084
+ "Status: implemented",
10085
+ "",
10086
+ "API:",
10087
+ " POST /api/v1/accounts/:account_id/prospect_webhook_endpoints.json"
10088
+ ].join("\n")],
10089
+
10090
+ ["webhooks update", [
10091
+ "Usage:",
10092
+ ` ${WEBHOOKS_UPDATE_USAGE.slice("Usage: ".length)}`,
10093
+ "",
10094
+ "Status: implemented",
10095
+ "",
10096
+ "API:",
10097
+ " PATCH /api/v1/accounts/:account_id/prospect_webhook_endpoints/:id.json"
10098
+ ].join("\n")],
10099
+
10100
+ ["webhooks rotate", [
10101
+ "Usage:",
10102
+ ` ${WEBHOOKS_ROTATE_USAGE.slice("Usage: ".length)}`,
10103
+ "",
10104
+ "Status: implemented",
10105
+ "",
10106
+ "API:",
10107
+ " POST /api/v1/accounts/:account_id/prospect_webhook_endpoints/:id/rotate.json"
10108
+ ].join("\n")],
10109
+
10110
+ ["webhooks remove", [
10111
+ "Usage:",
10112
+ ` ${WEBHOOKS_REMOVE_USAGE.slice("Usage: ".length)}`,
10113
+ "",
10114
+ "Status: implemented",
10115
+ "",
10116
+ "API:",
10117
+ " DELETE /api/v1/accounts/:account_id/prospect_webhook_endpoints/:id.json"
10118
+ ].join("\n")],
10119
+
10120
+ ["reply-alerts", [
10121
+ "Usage:",
10122
+ ` ${REPLY_ALERTS_SHOW_USAGE.slice("Usage: ".length)}`,
10123
+ ` ${REPLY_ALERTS_UPDATE_USAGE.slice("Usage: ".length)}`,
10124
+ "",
10125
+ "Status: implemented",
10126
+ "",
10127
+ "Purpose:",
10128
+ " Show or change your own SMS and Slack reply alerts. Connect Slack in the web app.",
10129
+ "",
10130
+ "API:",
10131
+ " GET /api/v1/me/reply_alerts.json",
10132
+ " PATCH /api/v1/me/reply_alerts.json"
10133
+ ].join("\n")],
10134
+
10135
+ ["reply-alerts show", [
10136
+ "Usage:",
10137
+ ` ${REPLY_ALERTS_SHOW_USAGE.slice("Usage: ".length)}`,
10138
+ "",
10139
+ "Status: implemented",
10140
+ "",
10141
+ "API:",
10142
+ " GET /api/v1/me/reply_alerts.json"
10143
+ ].join("\n")],
10144
+
10145
+ ["reply-alerts update", [
10146
+ "Usage:",
10147
+ ` ${REPLY_ALERTS_UPDATE_USAGE.slice("Usage: ".length)}`,
10148
+ "",
10149
+ "Status: implemented",
10150
+ "",
10151
+ "API:",
10152
+ " PATCH /api/v1/me/reply_alerts.json"
10153
+ ].join("\n")],
10154
+
10155
+ ["brand-profile", [
10156
+ "Usage:",
10157
+ ` ${BRAND_PROFILE_SHOW_USAGE.slice("Usage: ".length)}`,
10158
+ ` ${BRAND_PROFILE_UPDATE_USAGE.slice("Usage: ".length)}`,
10159
+ "",
10160
+ "Status: implemented",
10161
+ "",
10162
+ "Purpose:",
10163
+ " Show or change the account brand voice, style, and banned phrases. Account admins only.",
10164
+ "",
10165
+ "API:",
10166
+ " GET /api/v1/accounts/:account_id/brand_profile.json",
10167
+ " PATCH /api/v1/accounts/:account_id/brand_profile.json"
10168
+ ].join("\n")],
10169
+
10170
+ ["brand-profile show", [
10171
+ "Usage:",
10172
+ ` ${BRAND_PROFILE_SHOW_USAGE.slice("Usage: ".length)}`,
10173
+ "",
10174
+ "Status: implemented",
10175
+ "",
10176
+ "API:",
10177
+ " GET /api/v1/accounts/:account_id/brand_profile.json"
10178
+ ].join("\n")],
10179
+
10180
+ ["brand-profile update", [
10181
+ "Usage:",
10182
+ ` ${BRAND_PROFILE_UPDATE_USAGE.slice("Usage: ".length)}`,
10183
+ "",
10184
+ "Status: implemented",
10185
+ "",
10186
+ "API:",
10187
+ " PATCH /api/v1/accounts/:account_id/brand_profile.json"
10188
+ ].join("\n")],
10189
+
9413
10190
  ["company-rules", [
9414
10191
  "Usage:",
9415
10192
  " audienti company-rules list [--json]",
10193
+ ` ${COMPANY_RULES_SHOW_USAGE.slice("Usage: ".length)}`,
9416
10194
  ` ${COMPANY_RULES_CREATE_USAGE.slice("Usage: ".length)}`,
9417
10195
  ` ${COMPANY_RULES_UPDATE_USAGE.slice("Usage: ".length)}`,
9418
10196
  ` ${COMPANY_RULES_REMOVE_USAGE.slice("Usage: ".length)}`,
@@ -9434,6 +10212,16 @@ const HELP_TOPICS = new Map([
9434
10212
  " GET /api/v1/accounts/:account_id/company_rules.json"
9435
10213
  ].join("\n")],
9436
10214
 
10215
+ ["company-rules show", [
10216
+ "Usage:",
10217
+ ` ${COMPANY_RULES_SHOW_USAGE.slice("Usage: ".length)}`,
10218
+ "",
10219
+ "Status: implemented",
10220
+ "",
10221
+ "API:",
10222
+ " GET /api/v1/accounts/:account_id/company_rules/:id.json"
10223
+ ].join("\n")],
10224
+
9437
10225
  ["company-rules create", [
9438
10226
  "Usage:",
9439
10227
  ` ${COMPANY_RULES_CREATE_USAGE.slice("Usage: ".length)}`,