@audienti/cli 0.1.60 → 0.1.61

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,16 @@ All notable changes to the Audienti CLI are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.61] - 2026-09-08
8
+
9
+ ### Added
10
+
11
+ - Add owner-scoped `network-ops queue`, `accept`, and `decline` commands for pending inbound LinkedIn connection requests, with `reject` as a decline alias and explicit queued-versus-provider-confirmed output.
12
+
13
+ ### Fixed
14
+
15
+ - Preserve exact invitation-to-message binding in Network Ops output instead of assigning unrelated neighboring payload text.
16
+
7
17
  ## [0.1.60] - 2026-09-08
8
18
 
9
19
  ### Changed
package/README.md CHANGED
@@ -218,7 +218,8 @@ audienti operator next --plan
218
218
  audienti operator next --done --note "Connection request sent."
219
219
  ```
220
220
 
221
- `operator queue`, `operator failed-drafts`, and `inbox-ops queue` print a
221
+ `operator queue`, `operator failed-drafts`, `network-ops queue`, and
222
+ `inbox-ops queue` print a
222
223
  continuation command when more rows remain. Read-only `operator next` (including
223
224
  `--plan`) also prints one when its page has no focal move but more rows remain;
224
225
  when a move is present, inspect or act on it and rerun `operator next`.
@@ -229,6 +230,21 @@ with an offset. If the scan limit is reached, narrow the filters; an incomplete
229
230
  scan does not mean the queue is empty. JSON output preserves the API response.
230
231
  Pagination flags are not accepted when recording outcomes or requeueing drafts.
231
232
 
233
+ Network Ops has its own owner-scoped CLI surface for pending inbound LinkedIn
234
+ connection requests. It shows the exact invitation-bound message when one was
235
+ captured and queues the same canonical provider actions as the product UI:
236
+
237
+ ```bash
238
+ audienti network-ops queue [--page <n>] [--offset <n>|--cursor <token>]
239
+ audienti network-ops accept <row_id>
240
+ audienti network-ops decline <row_id>
241
+ ```
242
+
243
+ `reject` is accepted as an alias for `decline`. An accepted API response means
244
+ the provider action was queued; it is not confirmation that LinkedIn completed
245
+ the action. The same queue can be read with
246
+ `audienti operator queue --opportunity-kind network`.
247
+
232
248
  Inbox Ops has its own owner-scoped CLI surface. Queue rows expose the stable row
233
249
  id used by the row-based rule command. Rules can also be set or removed directly
234
250
  by sender or domain; the server normalizes and validates every supplied key:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audienti/cli",
3
- "version": "0.1.60",
3
+ "version": "0.1.61",
4
4
  "description": "Agent-first command-line client for Audienti.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: audienti
3
- description: Use when the user wants to operate Audienti through the production CLI or app-hosted MCP endpoint, including account selection, plays, prospect imports, lists and routing rules, message previews, analytics, or supported operator outcomes.
3
+ description: Use when the user wants to operate Audienti through the production CLI or app-hosted MCP endpoint, including account selection, plays, prospect imports, lists and routing rules, message previews, analytics, Inbox Ops, Network Ops, or supported operator outcomes.
4
4
  ---
5
5
 
6
6
  # Audienti CLI and MCP
@@ -136,6 +136,9 @@ audienti motions activate <motn_id> --json
136
136
  audienti motions delete <motn_id> --confirm yes --json
137
137
  audienti operator next --json
138
138
  audienti operator next --plan
139
+ audienti network-ops queue --json
140
+ audienti network-ops accept <row_id> --account <acct_id> --json
141
+ audienti network-ops decline <row_id> --account <acct_id> --json
139
142
  audienti inbox-ops queue --json
140
143
  audienti inbox-ops filters --json
141
144
  audienti inbox-ops rule <row_id> --scope <sender|domain> --disposition <allow|filter> --json
package/src/api-client.js CHANGED
@@ -657,6 +657,12 @@ export class AudientiClient {
657
657
  return this.requestJson(accountPath(accountId, ["operator"], query));
658
658
  }
659
659
 
660
+ networkOpsAction(accountId, rowId, action) {
661
+ return this.requestJson(accountPath(accountId, ["network_ops", rowId, action]), {
662
+ method: "POST"
663
+ });
664
+ }
665
+
660
666
  inboxOpsFilters(accountId) {
661
667
  return this.requestJson(accountPath(accountId, ["inbox_ops", "filters"]));
662
668
  }
package/src/cli.js CHANGED
@@ -66,6 +66,9 @@ const PROSPECTS_IMPORT_BATCH_USAGE = "Usage: audienti prospects import-batch --f
66
66
  const OPERATOR_FAILED_DRAFTS_USAGE = "Usage: audienti operator failed-drafts [--json] [filters] [--account <acct_id>]";
67
67
  const OPERATOR_FAILED_DRAFTS_REQUEUE_USAGE = "Usage: audienti operator failed-drafts requeue (--all | <row_id> [row_id...]) [--limit <n>] [--json] [filters] [--account <acct_id>]";
68
68
  const INBOX_OPS_QUEUE_USAGE = "Usage: audienti inbox-ops queue [--page <n>] [--offset <n>|--cursor <token>] [--json] [--account <acct_id>]";
69
+ const NETWORK_OPS_QUEUE_USAGE = "Usage: audienti network-ops queue [--page <n>] [--offset <n>|--cursor <token>] [--json] [--account <acct_id>]";
70
+ const NETWORK_OPS_ACCEPT_USAGE = "Usage: audienti network-ops accept <row_id> [--json] [--account <acct_id>]";
71
+ const NETWORK_OPS_DECLINE_USAGE = "Usage: audienti network-ops decline <row_id> [--json] [--account <acct_id>]";
69
72
  const OPERATOR_PAGINATION_HELP = [
70
73
  "Read pagination:",
71
74
  " --page <n> Positive page number",
@@ -80,6 +83,7 @@ const INBOX_OPS_RULE_USAGE = "Usage: audienti inbox-ops rule <row_id> --scope <s
80
83
  const INBOX_OPS_RULE_SET_USAGE = "Usage: audienti inbox-ops rule set --scope <sender|domain> --key <email|domain> --disposition <allow|filter> [--json] [--account <acct_id>]";
81
84
  const INBOX_OPS_RULE_REMOVE_USAGE = "Usage: audienti inbox-ops rule remove --scope <sender|domain> --key <email|domain> [--json] [--account <acct_id>]";
82
85
  const INBOX_OPS_ROW_ID_PATTERN = /^inbox_ops_message_[1-9]\d*$/;
86
+ const NETWORK_OPS_ROW_ID_PATTERN = /^network_ops_event_[1-9]\d*$/;
83
87
  const DNC_ADD_USAGE = "Usage: audienti dnc add <email|citation_id|profile_url> [--json] [--account <acct_id>]";
84
88
  const DNC_IMPORT_USAGE = "Usage: audienti dnc import --file <txt|csv> [--json] [--account <acct_id>]";
85
89
  const DNC_REMOVE_USAGE = "Usage: audienti dnc remove <dnc_entry_id> [--json] [--account <acct_id>]";
@@ -346,6 +350,10 @@ async function dispatch(argv, context) {
346
350
  if (normalizedResource === "operator" && action === "next") return operatorNext(rest, context, { accountOverride });
347
351
  if (normalizedResource === "operator" && action === "outcome") return operatorOutcome(rest, context, { accountOverride });
348
352
  if (normalizedResource === "operator" && action === "answer") return operatorAnswer(rest, context, { accountOverride });
353
+ if (normalizedResource === "network-ops" && action === "queue") return networkOpsQueue(rest, context, { accountOverride });
354
+ if (normalizedResource === "network-ops" && ["accept", "decline", "reject"].includes(action)) {
355
+ return networkOpsAction(action, rest, context, { accountOverride });
356
+ }
349
357
  if (normalizedResource === "inbox-ops" && action === "queue") return inboxOpsQueue(rest, context, { accountOverride });
350
358
  if (normalizedResource === "inbox-ops" && action === "filters") return inboxOpsFilters(rest, context, { accountOverride });
351
359
  if (normalizedResource === "inbox-ops" && action === "rule") return inboxOpsRule(rest, context, { accountOverride });
@@ -3275,6 +3283,39 @@ async function inboxOpsQueue(args, context, { accountOverride } = {}) {
3275
3283
  renderOperatorRead(payload, context, { command: "inbox-ops queue", accountId, query }, () => renderInboxOpsQueue(payload, context));
3276
3284
  }
3277
3285
 
3286
+ async function networkOpsQueue(args, context, { accountOverride } = {}) {
3287
+ const { values, positionals } = parseCommandArgs(args, {
3288
+ ...jsonOptions(),
3289
+ ...operatorPaginationOptions()
3290
+ });
3291
+ if (positionals.length > 0) throw new CommandError(NETWORK_OPS_QUEUE_USAGE);
3292
+
3293
+ const query = { opportunity_kind: "network", ...operatorPaginationQuery(values) };
3294
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
3295
+ const payload = await client.operatorQueue(accountId, query);
3296
+ if (values.json) return writeJson(context.stdout, payload);
3297
+
3298
+ renderOperatorRead(payload, context, { command: "network-ops queue", accountId, query }, () => renderNetworkOpsQueue(payload, context, { accountId }));
3299
+ }
3300
+
3301
+ async function networkOpsAction(action, args, context, { accountOverride } = {}) {
3302
+ const { values, positionals } = parseCommandArgs(args, jsonOptions());
3303
+ const canonicalAction = action === "reject" ? "decline" : action;
3304
+ const usage = canonicalAction === "accept" ? NETWORK_OPS_ACCEPT_USAGE : NETWORK_OPS_DECLINE_USAGE;
3305
+ if (positionals.length !== 1) throw new CommandError(usage);
3306
+
3307
+ const rowId = positionals[0];
3308
+ if (!NETWORK_OPS_ROW_ID_PATTERN.test(rowId)) {
3309
+ throw new CommandError("<row_id> must match network_ops_event_<positive integer>.");
3310
+ }
3311
+
3312
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
3313
+ const payload = await client.networkOpsAction(accountId, rowId, canonicalAction);
3314
+ if (values.json) return writeJson(context.stdout, payload);
3315
+
3316
+ renderNetworkOpsAction(payload, context);
3317
+ }
3318
+
3278
3319
  async function inboxOpsFilters(args, context, { accountOverride } = {}) {
3279
3320
  const { values, positionals } = parseCommandArgs(args, jsonOptions());
3280
3321
  if (positionals.length > 0) throw new CommandError(INBOX_OPS_FILTERS_USAGE);
@@ -6405,7 +6446,7 @@ function operatorContinuationCommand(payload, { command, accountId, query, plan
6405
6446
  }
6406
6447
 
6407
6448
  function operatorContinuationFilters(command, query, resolvedFilters = {}) {
6408
- if (command === "inbox-ops queue") return [];
6449
+ if (["inbox-ops queue", "network-ops queue"].includes(command)) return [];
6409
6450
 
6410
6451
  const filters = { ...resolvedFilters, ...query };
6411
6452
  const flags = {
@@ -6448,6 +6489,37 @@ function renderInboxOpsQueue(payload, context) {
6448
6489
  ]));
6449
6490
  }
6450
6491
 
6492
+ function renderNetworkOpsQueue(payload, context, { accountId }) {
6493
+ const decisionQueue = Array.isArray(payload?.decision_queue) ? payload.decision_queue : [];
6494
+ const rows = decisionQueue.length > 0 ? decisionQueue : [payload?.next_move].filter(Boolean);
6495
+ if (rows.length === 0) return writeLine(context.stdout, "No Network Ops rows found.");
6496
+
6497
+ writeAlignedTable(context, ["ROW ID", "PERSON", "MESSAGE", "STATE"], rows.map((row) => [
6498
+ display(row?.id),
6499
+ operatorSubjectLabel(row),
6500
+ row?.network_ops?.note || "-",
6501
+ display(row?.network_ops?.state)
6502
+ ]));
6503
+
6504
+ for (const row of rows) {
6505
+ const accountOption = ` --account ${operatorCommandArgument(accountId)}`;
6506
+ writeLine(context.stdout, "");
6507
+ writeLine(context.stdout, `Accept: audienti network-ops accept ${row.id}${accountOption}`);
6508
+ writeLine(context.stdout, `Decline: audienti network-ops decline ${row.id}${accountOption}`);
6509
+ }
6510
+ }
6511
+
6512
+ function renderNetworkOpsAction(payload, context) {
6513
+ const actionKey = String(payload?.action?.key || "");
6514
+ const label = actionKey.endsWith("_decline") ? "Decline" : "Acceptance";
6515
+ const person = payload?.request?.display_name || payload?.request?.id || payload?.row_id;
6516
+ writeLine(context.stdout, `${label} queued for ${display(person)} (${display(payload?.row_id)}).`);
6517
+ if (payload?.action?.prefix_id) {
6518
+ writeLine(context.stdout, `Action: ${payload.action.prefix_id} (${display(payload.action.state)})`);
6519
+ }
6520
+ writeLine(context.stdout, "Queued means provider execution was requested; it is not confirmation that LinkedIn completed the action.");
6521
+ }
6522
+
6451
6523
  function renderInboxOpsFilters(payload, context) {
6452
6524
  const owner = payload?.owner || {};
6453
6525
  const filters = payload?.email_filters || {};
@@ -7903,6 +7975,11 @@ const HELP_TOPICS = new Map([
7903
7975
  " audienti inbox-ops queue",
7904
7976
  " audienti inbox-ops filters",
7905
7977
  " audienti inbox-ops rule <row_id> --scope <sender|domain> --disposition <allow|filter>",
7978
+ "",
7979
+ " Network Ops",
7980
+ " audienti network-ops queue",
7981
+ " audienti network-ops accept <row_id>",
7982
+ " audienti network-ops decline <row_id>",
7906
7983
  "",
7907
7984
  " Analytics",
7908
7985
  " audienti analytics motions",
@@ -10806,6 +10883,66 @@ const HELP_TOPICS = new Map([
10806
10883
  " key: PATCH|DELETE /api/v1/accounts/:account_id/inbox_ops/rules.json"
10807
10884
  ].join("\n")],
10808
10885
 
10886
+ ["network-ops", [
10887
+ "Usage:",
10888
+ ` ${NETWORK_OPS_QUEUE_USAGE.slice("Usage: ".length)}`,
10889
+ ` ${NETWORK_OPS_ACCEPT_USAGE.slice("Usage: ".length)}`,
10890
+ ` ${NETWORK_OPS_DECLINE_USAGE.slice("Usage: ".length)}`,
10891
+ " audienti network-ops reject <row_id> [--json] [--account <acct_id>]",
10892
+ "",
10893
+ "Status: implemented",
10894
+ "",
10895
+ "Purpose:",
10896
+ " Inspect the authenticated owner's private inbound LinkedIn connection requests and queue accept or decline provider actions.",
10897
+ " `reject` is accepted as an alias for `decline`.",
10898
+ "",
10899
+ "Safety:",
10900
+ " Rows always resolve through the current owner-private Network Ops scope. Arbitrary event ids and another user's requests fail closed.",
10901
+ " A successful response means the provider action was queued, not that LinkedIn has confirmed it.",
10902
+ "",
10903
+ "API:",
10904
+ " queue: GET /api/v1/accounts/:account_id/operator.json?opportunity_kind=network",
10905
+ " action: POST /api/v1/accounts/:account_id/network_ops/:row_id/:accept_or_decline.json"
10906
+ ].join("\n")],
10907
+
10908
+ ["network-ops queue", [
10909
+ NETWORK_OPS_QUEUE_USAGE,
10910
+ "",
10911
+ "Status: implemented",
10912
+ "",
10913
+ ...OPERATOR_PAGINATION_HELP,
10914
+ "Purpose:",
10915
+ " List one page of the authenticated owner's pending inbound LinkedIn connection requests, including the exact invitation-bound message when available.",
10916
+ " The general equivalent is `audienti operator queue --opportunity-kind network`.",
10917
+ "",
10918
+ "API:",
10919
+ " GET /api/v1/accounts/:account_id/operator.json?opportunity_kind=network"
10920
+ ].join("\n")],
10921
+
10922
+ ["network-ops accept", [
10923
+ NETWORK_OPS_ACCEPT_USAGE,
10924
+ "",
10925
+ "Status: implemented",
10926
+ "",
10927
+ "Purpose:",
10928
+ " Queue the canonical LinkedIn accept action for one authorized pending Network Ops row.",
10929
+ "",
10930
+ "API:",
10931
+ " POST /api/v1/accounts/:account_id/network_ops/:row_id/accept.json"
10932
+ ].join("\n")],
10933
+
10934
+ ["network-ops decline", [
10935
+ NETWORK_OPS_DECLINE_USAGE,
10936
+ "",
10937
+ "Status: implemented",
10938
+ "",
10939
+ "Purpose:",
10940
+ " Queue the canonical LinkedIn decline action for one authorized pending Network Ops row. `reject` is an alias.",
10941
+ "",
10942
+ "API:",
10943
+ " POST /api/v1/accounts/:account_id/network_ops/:row_id/decline.json"
10944
+ ].join("\n")],
10945
+
10809
10946
  ["operator", [
10810
10947
  "Usage:",
10811
10948
  " audienti operator next [--json|--plan|--done|--skip|--fail|--return]",
@@ -10822,7 +10959,7 @@ const HELP_TOPICS = new Map([
10822
10959
  " --motion <motn_id>",
10823
10960
  " --list <list_id>",
10824
10961
  " --stage <stage>",
10825
- " --opportunity-kind prospect|visibility|inbox",
10962
+ " --opportunity-kind prospect|visibility|inbox|network|content",
10826
10963
  " --writing-status ready|drafting|draft_failed"
10827
10964
  ].join("\n")],
10828
10965
 
@@ -11357,6 +11494,9 @@ const HELP_TOPICS = new Map([
11357
11494
  " audienti operator failed-drafts",
11358
11495
  " audienti operator failed-drafts requeue <row_id>",
11359
11496
  " audienti operator outcome <row_id> --payload <file.json>",
11497
+ " audienti network-ops queue",
11498
+ " audienti network-ops accept <row_id>",
11499
+ " audienti network-ops decline <row_id>",
11360
11500
  " audienti inbox-ops queue",
11361
11501
  " audienti inbox-ops filters",
11362
11502
  " audienti inbox-ops rule <row_id> --scope sender --disposition filter",