@audienti/cli 0.1.2 → 0.1.4

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,19 @@ All notable changes to the Audienti CLI are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.4] - 2026-07-11
8
+
9
+ ### Added
10
+
11
+ - Add `audienti operator next --plan` for deterministic next-action plan output.
12
+ - Add `audienti analytics prospects`, `audienti analytics visibility`, and `audienti analytics content` for account-scoped operational analytics.
13
+
14
+ ## [0.1.3] - 2026-07-11
15
+
16
+ ### Changed
17
+
18
+ - Track the admin-only announcement creation API contract.
19
+
7
20
  ## [0.1.2] - 2026-07-10
8
21
 
9
22
  ### Added
package/README.md CHANGED
@@ -41,6 +41,15 @@ Use `--json` whenever another program or agent will consume the result. Inspect
41
41
  the target state before mutations, and use the command-specific help before
42
42
  creating, changing, or deleting data.
43
43
 
44
+ Common inspection commands:
45
+
46
+ ```bash
47
+ audienti operator next --plan
48
+ audienti analytics prospects --window 24h
49
+ audienti analytics visibility --window 24h --user me
50
+ audienti analytics content --window week
51
+ ```
52
+
44
53
  ## Compatibility
45
54
 
46
55
  The CLI talks to the versioned Audienti `/api/v1` contract at
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audienti/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Agent-first command-line client for Audienti.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "bin/",
11
11
  "src/",
12
+ "skills/",
12
13
  "README.md",
13
14
  "LICENSE",
14
15
  "CHANGELOG.md"
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: audienti
3
+ description: Use when the user wants to operate Audienti through the production CLI, including account selection, plays, prospect imports, lists, message previews, or supported operator outcomes.
4
+ ---
5
+
6
+ # Audienti CLI
7
+
8
+ Use the installed `audienti` command as the production contract. Do not build a
9
+ parallel wrapper or call undocumented API endpoints.
10
+
11
+ ## Setup
12
+
13
+ 1. Verify the command is installed:
14
+
15
+ ```bash
16
+ audienti --help
17
+ ```
18
+
19
+ 2. If it is unavailable, install the public package:
20
+
21
+ ```bash
22
+ npm install --global @audienti/cli
23
+ ```
24
+
25
+ 3. Authentication is explicit and per machine. Do not ask a user to paste a
26
+ production token into chat, a repository file, an issue, or a CI secret. Use
27
+ the existing `audienti auth token` flow only after the user supplies a token
28
+ through an approved secure channel.
29
+
30
+ 4. Start with discovery, not mutation:
31
+
32
+ ```bash
33
+ audienti auth status
34
+ audienti accounts list --json
35
+ audienti help agent-workflows
36
+ ```
37
+
38
+ ## Operating Rules
39
+
40
+ - Use `--json` whenever another agent or tool will consume the response.
41
+ - Use `audienti <resource> <action> help` before a mutation when the accepted
42
+ payload or behavior is unclear.
43
+ - Inspect the current resource before a create, update, attach, delete, or
44
+ operator outcome writeback.
45
+ - Treat the production API as the source of truth. Persist durable work in
46
+ Audienti rather than leaving it only in agent prose.
47
+ - Keep current gaps explicit. Do not imply that unsupported actions execute.
48
+
49
+ ## Common Entry Points
50
+
51
+ ```bash
52
+ audienti help agent-workflows
53
+ audienti prospects list --query "name or company" --wide --json
54
+ audienti lists create --name "Target list" --json
55
+ audienti operator next --json
56
+ audienti operator next --plan
57
+ audienti analytics prospects --window 24h --json
58
+ audienti analytics visibility --window 24h --user me --json
59
+ audienti analytics content --window week --json
60
+ ```
package/src/api-client.js CHANGED
@@ -215,6 +215,18 @@ export class AudientiClient {
215
215
  });
216
216
  }
217
217
 
218
+ analyticsProspects(accountId, query = {}) {
219
+ return this.requestJson(accountPath(accountId, ["analytics", "prospects"], query));
220
+ }
221
+
222
+ analyticsVisibility(accountId, query = {}) {
223
+ return this.requestJson(accountPath(accountId, ["analytics", "visibility"], query));
224
+ }
225
+
226
+ analyticsContent(accountId, query = {}) {
227
+ return this.requestJson(accountPath(accountId, ["analytics", "content"], query));
228
+ }
229
+
218
230
  async requestJson(path, { method = "GET", body } = {}) {
219
231
  const response = await this.fetchImpl(new URL(path, `${this.host}/`), {
220
232
  method,
package/src/cli.js CHANGED
@@ -122,6 +122,9 @@ async function dispatch(argv, context) {
122
122
  if (normalizedResource === "operator" && action === "queue") return operatorQueue(rest, context, { accountOverride });
123
123
  if (normalizedResource === "operator" && action === "next") return operatorNext(rest, context, { accountOverride });
124
124
  if (normalizedResource === "operator" && action === "outcome") return operatorOutcome(rest, context, { accountOverride });
125
+ if (normalizedResource === "analytics" && ["prospects", "prospect"].includes(action)) return analyticsProspects(rest, context, { accountOverride });
126
+ if (normalizedResource === "analytics" && ["visibility", "visops"].includes(action)) return analyticsVisibility(rest, context, { accountOverride });
127
+ if (normalizedResource === "analytics" && action === "content") return analyticsContent(rest, context, { accountOverride });
125
128
 
126
129
  throw new CommandError(usage(), { exitCode: resource ? 1 : 0 });
127
130
  }
@@ -1022,11 +1025,13 @@ async function operatorQueue(args, context, { accountOverride } = {}) {
1022
1025
 
1023
1026
  async function operatorNext(args, context, { accountOverride } = {}) {
1024
1027
  const { values, positionals } = parseCommandArgs(args, operatorOptions());
1025
- if (positionals.length > 0) throw new CommandError("Usage: audienti operator next [--json] [filters] [--account <acct_id>]");
1028
+ if (positionals.length > 0) throw new CommandError("Usage: audienti operator next [--json|--plan] [filters] [--account <acct_id>]");
1029
+ if (values.json && values.plan) throw new CommandError("Choose one output format: use either --json or --plan.");
1026
1030
 
1027
1031
  const { client, accountId } = await requireAccountContext(context, { accountOverride });
1028
1032
  const payload = await client.operatorNext(accountId, operatorQuery(values));
1029
1033
  if (values.json) return writeJson(context.stdout, payload);
1034
+ if (values.plan) return renderOperatorPlan(payload?.next_move, context);
1030
1035
 
1031
1036
  renderOperatorNext(payload?.next_move, context);
1032
1037
  }
@@ -1051,6 +1056,39 @@ async function operatorOutcome(args, context, { accountOverride } = {}) {
1051
1056
  renderOperatorOutcome(response, context);
1052
1057
  }
1053
1058
 
1059
+ async function analyticsProspects(args, context, { accountOverride } = {}) {
1060
+ const { values, positionals } = parseCommandArgs(args, analyticsOptions());
1061
+ if (positionals.length > 0) throw new CommandError("Usage: audienti analytics prospects [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]");
1062
+
1063
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1064
+ const payload = await client.analyticsProspects(accountId, analyticsQuery(values));
1065
+ if (values.json) return writeJson(context.stdout, payload);
1066
+
1067
+ renderAnalyticsProspects(payload, context);
1068
+ }
1069
+
1070
+ async function analyticsVisibility(args, context, { accountOverride } = {}) {
1071
+ const { values, positionals } = parseCommandArgs(args, analyticsOptions());
1072
+ if (positionals.length > 0) throw new CommandError("Usage: audienti analytics visibility [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]");
1073
+
1074
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1075
+ const payload = await client.analyticsVisibility(accountId, analyticsQuery(values));
1076
+ if (values.json) return writeJson(context.stdout, payload);
1077
+
1078
+ renderAnalyticsVisibility(payload, context);
1079
+ }
1080
+
1081
+ async function analyticsContent(args, context, { accountOverride } = {}) {
1082
+ const { values, positionals } = parseCommandArgs(args, analyticsOptions());
1083
+ if (positionals.length > 0) throw new CommandError("Usage: audienti analytics content [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]");
1084
+
1085
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
1086
+ const payload = await client.analyticsContent(accountId, analyticsQuery(values));
1087
+ if (values.json) return writeJson(context.stdout, payload);
1088
+
1089
+ renderAnalyticsContent(payload, context);
1090
+ }
1091
+
1054
1092
  function parseCommandArgs(args, options) {
1055
1093
  try {
1056
1094
  return parseArgs({
@@ -1109,6 +1147,7 @@ function jsonOptions() {
1109
1147
  function operatorOptions() {
1110
1148
  return {
1111
1149
  ...jsonOptions(),
1150
+ plan: { type: "boolean" },
1112
1151
  principal: { type: "string" },
1113
1152
  motion: { type: "string" },
1114
1153
  list: { type: "string" },
@@ -1129,6 +1168,21 @@ function operatorQuery(values) {
1129
1168
  });
1130
1169
  }
1131
1170
 
1171
+ function analyticsOptions() {
1172
+ return {
1173
+ ...jsonOptions(),
1174
+ window: { type: "string" },
1175
+ user: { type: "string" }
1176
+ };
1177
+ }
1178
+
1179
+ function analyticsQuery(values) {
1180
+ return compactObject({
1181
+ window: values.window,
1182
+ account_user_id: values.user
1183
+ });
1184
+ }
1185
+
1132
1186
  function compactObject(object) {
1133
1187
  return Object.fromEntries(
1134
1188
  Object.entries(object).filter(([, value]) => value !== undefined && value !== null && String(value).trim() !== "")
@@ -1761,6 +1815,60 @@ function renderOperatorNext(row, context) {
1761
1815
  writeLine(context.stdout, operatorRowLine(row));
1762
1816
  }
1763
1817
 
1818
+ function renderOperatorPlan(row, context) {
1819
+ if (!row) return writeLine(context.stdout, "No operator moves found.");
1820
+
1821
+ const nextAction = row.next_action || {};
1822
+ const cta = row.cta || {};
1823
+ const draft = row.operator_draft || {};
1824
+
1825
+ writeLine(context.stdout, "Static operator plan");
1826
+ writeLine(context.stdout, `Move: ${display(row.id)}`);
1827
+ writeLine(context.stdout, `Kind: ${display(row.opportunity_kind)}`);
1828
+ writeLine(context.stdout, `Prospect: ${entityLabel(row.prospect)}`);
1829
+ if (row.motion) writeLine(context.stdout, `Motion: ${entityLabel(row.motion)}`);
1830
+ if (row.pipeline_stage || row.plan_state || row.status_label) {
1831
+ writeLine(context.stdout, `State: ${compactText([row.pipeline_stage, row.plan_state, row.status_label]).join(", ")}`);
1832
+ }
1833
+ if (row.due_label) writeLine(context.stdout, `Due: ${row.due_label}`);
1834
+
1835
+ writeLine(context.stdout, "");
1836
+ writeLine(context.stdout, `Next action: ${display(nextActionLabel(row), "Unknown")} (${display(nextAction.type, "unknown")})`);
1837
+ if (nextAction.request_mode) writeLine(context.stdout, `Request mode: ${nextAction.request_mode}`);
1838
+ const timing = timingLabel(nextAction, row);
1839
+ if (timing) writeLine(context.stdout, `Timing: ${timing}`);
1840
+ const target = targetLabel(nextAction);
1841
+ if (target) writeLine(context.stdout, `Target: ${target}`);
1842
+
1843
+ if (Object.keys(cta).length > 0) {
1844
+ writeLine(context.stdout, "");
1845
+ writeLine(context.stdout, `CTA: ${ctaLabel(cta)}`);
1846
+ }
1847
+
1848
+ if (Object.keys(draft).length > 0) {
1849
+ writeLine(context.stdout, "");
1850
+ writeLine(context.stdout, `Draft: ${draftLabel(draft)}`);
1851
+ if (draft.writer_path) writeLine(context.stdout, `Writer: ${draft.writer_path}`);
1852
+ if (draft.subject) writeLine(context.stdout, `Subject: ${draft.subject}`);
1853
+ const body = draft.body || draft.text;
1854
+ if (body) {
1855
+ writeLine(context.stdout, "Body:");
1856
+ writeLine(context.stdout, body);
1857
+ }
1858
+ }
1859
+
1860
+ if (row.rationale) {
1861
+ writeLine(context.stdout, "");
1862
+ writeLine(context.stdout, "Rationale:");
1863
+ writeLine(context.stdout, row.rationale);
1864
+ }
1865
+ if (row.guidance) {
1866
+ writeLine(context.stdout, "");
1867
+ writeLine(context.stdout, "Guidance:");
1868
+ writeLine(context.stdout, row.guidance);
1869
+ }
1870
+ }
1871
+
1764
1872
  function renderOperatorOutcome(payload, context) {
1765
1873
  const outcome = payload?.operator_outcome || {};
1766
1874
  const rowId = payload?.row_id || outcome.row_id;
@@ -1774,6 +1882,84 @@ function renderOperatorOutcome(payload, context) {
1774
1882
  }
1775
1883
  }
1776
1884
 
1885
+ function renderAnalyticsProspects(payload, context) {
1886
+ writeLine(context.stdout, `Prospect analytics (${analyticsWindowLabel(payload)})`);
1887
+ writeAnalyticsScope(payload, context);
1888
+ writeLine(context.stdout, `Prospects added: ${display(payload?.prospects_added_count, 0)}`);
1889
+ writeAnalyticsActionSummary(payload?.actions, context, "Actions");
1890
+ writeCountTable(context, "Action breakdown", payload?.actions?.breakdown, ["ACTION", "COUNT", "AUTOMATED", "AUTO %"], actionBreakdownRow);
1891
+ writeCountTable(context, "Queue stages", payload?.queue_stages, ["STAGE", "COUNT"], countRow);
1892
+ }
1893
+
1894
+ function renderAnalyticsVisibility(payload, context) {
1895
+ writeLine(context.stdout, `Visibility analytics (${analyticsWindowLabel(payload)})`);
1896
+ writeAnalyticsScope(payload, context);
1897
+ writeLine(context.stdout, `Unique people engaged: ${display(payload?.unique_people_engaged_count, 0)}`);
1898
+ writeAnalyticsActionSummary(payload?.engagements, context, "Engagements");
1899
+ writeCountTable(context, "Engagement breakdown", payload?.engagements?.breakdown, ["ACTION", "COUNT", "AUTOMATED", "AUTO %"], actionBreakdownRow);
1900
+ }
1901
+
1902
+ function renderAnalyticsContent(payload, context) {
1903
+ writeLine(context.stdout, `Content analytics (${analyticsWindowLabel(payload)})`);
1904
+ writeAnalyticsScope(payload, context);
1905
+ writeLine(context.stdout, `Published posts: ${display(payload?.published_posts_count, 0)}`);
1906
+ writeCountTable(context, "Stages", payload?.stage_breakdown, ["STAGE", "COUNT"], countRow);
1907
+ writeCountTable(context, "Execution statuses", payload?.execution_status_breakdown, ["STATUS", "COUNT"], countRow);
1908
+ }
1909
+
1910
+ function writeAnalyticsScope(payload, context) {
1911
+ if (payload?.account_user) {
1912
+ writeLine(context.stdout, `User: ${entityLabel(payload.account_user)}`);
1913
+ } else {
1914
+ writeLine(context.stdout, "User: all account users");
1915
+ }
1916
+ }
1917
+
1918
+ function writeAnalyticsActionSummary(actions, context, label) {
1919
+ const total = display(actions?.total_count, 0);
1920
+ const automated = display(actions?.automated_count, 0);
1921
+ const percentage = percentageLabel(actions?.automated_percentage);
1922
+ writeLine(context.stdout, `${label}: ${total} (automated ${automated}, ${percentage})`);
1923
+ }
1924
+
1925
+ function writeCountTable(context, title, rows, headers, mapRow) {
1926
+ const list = Array.isArray(rows) ? rows : [];
1927
+ writeLine(context.stdout, "");
1928
+ writeLine(context.stdout, title);
1929
+ if (list.length === 0) return writeLine(context.stdout, "None");
1930
+
1931
+ writeLine(context.stdout, headers.join("\t"));
1932
+ for (const row of list) writeLine(context.stdout, mapRow(row).join("\t"));
1933
+ }
1934
+
1935
+ function actionBreakdownRow(row) {
1936
+ return [
1937
+ display(row?.label || row?.key),
1938
+ display(row?.count, 0),
1939
+ display(row?.automated_count, 0),
1940
+ percentageLabel(row?.automated_percentage)
1941
+ ];
1942
+ }
1943
+
1944
+ function countRow(row) {
1945
+ return [
1946
+ display(row?.label || row?.key),
1947
+ display(row?.count, 0)
1948
+ ];
1949
+ }
1950
+
1951
+ function analyticsWindowLabel(payload) {
1952
+ const window = payload?.window || {};
1953
+ const key = display(window.key, "24h");
1954
+ if (!window.started_at || !window.ended_at) return key;
1955
+
1956
+ return `${key}: ${window.started_at} to ${window.ended_at}`;
1957
+ }
1958
+
1959
+ function percentageLabel(value) {
1960
+ return value === undefined || value === null || value === "" ? "n/a" : `${value}%`;
1961
+ }
1962
+
1777
1963
  function operatorRowLine(row) {
1778
1964
  return [
1779
1965
  display(row?.id),
@@ -1788,6 +1974,53 @@ function nextActionLabel(source) {
1788
1974
  return source?.recommended_action_label || source?.next_action?.label || source?.cta?.label;
1789
1975
  }
1790
1976
 
1977
+ function entityLabel(entity) {
1978
+ if (!entity) return "";
1979
+
1980
+ const name = entity.display_name || entity.name || entity.prefix_id || entity.id;
1981
+ const id = entity.prefix_id || entity.id;
1982
+ return id && id !== name ? `${display(name)} (${display(id)})` : display(name);
1983
+ }
1984
+
1985
+ function timingLabel(nextAction, row) {
1986
+ const timing = nextAction.timing || {};
1987
+ const mode = timing.mode || row.timing_mode;
1988
+ const scheduledFor = timing.scheduled_for || row.scheduled_for;
1989
+ const parts = compactText([
1990
+ mode,
1991
+ scheduledFor ? `scheduled for ${scheduledFor}` : null
1992
+ ]);
1993
+
1994
+ return parts.join(", ");
1995
+ }
1996
+
1997
+ function targetLabel(nextAction) {
1998
+ const target = nextAction.target || {};
1999
+ return compactText([
2000
+ target.platform,
2001
+ target.profile_url,
2002
+ target.post_url,
2003
+ target.message_event_id ? `message ${target.message_event_id}` : null,
2004
+ target.post_id ? `post ${target.post_id}` : null
2005
+ ]).join(" | ");
2006
+ }
2007
+
2008
+ function ctaLabel(cta) {
2009
+ const action = compactText([cta.action || cta.type, cta.platform ? `on ${cta.platform}` : null]).join(" ");
2010
+ const disabled = cta.disabled ? "disabled" : "enabled";
2011
+ return `${display(cta.label, "Unnamed CTA")}${action ? ` (${action})` : ""}${cta.disabled === undefined ? "" : `, ${disabled}`}`;
2012
+ }
2013
+
2014
+ function draftLabel(draft) {
2015
+ const required = draft.required === true ? "required" : draft.required === false ? "not required" : null;
2016
+ const ready = draft.ready === true ? "ready" : draft.ready === false ? "not ready" : null;
2017
+ return compactText([draft.state, ready, required]).join(", ") || "unknown";
2018
+ }
2019
+
2020
+ function compactText(values) {
2021
+ return values.map((value) => String(value || "").trim()).filter(Boolean);
2022
+ }
2023
+
1791
2024
  function successCount(payload) {
1792
2025
  if (Array.isArray(payload?.added)) return payload.added.length;
1793
2026
  if (Array.isArray(payload?.removed)) return payload.removed.length;
@@ -2041,9 +2274,12 @@ const HELP_TOPICS = new Map([
2041
2274
  " audienti prospects import <linkedin_url> [--list <list_id>] [--motion <motn_id>] [--json]",
2042
2275
  " audienti prospects import-status <primp_id> [--json]",
2043
2276
  " audienti tools get <email|phone> --url <linkedin_url> [--json]",
2044
- " audienti operator next [--json]",
2277
+ " audienti operator next [--json|--plan]",
2045
2278
  " audienti operator queue [--json]",
2046
2279
  " audienti operator outcome <row_id> --payload <file.json> [--json]",
2280
+ " audienti analytics prospects [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
2281
+ " audienti analytics visibility [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
2282
+ " audienti analytics content [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
2047
2283
  "",
2048
2284
  "Planned submit-shape help topics:",
2049
2285
  " audienti prospects disposition help",
@@ -3109,7 +3345,7 @@ const HELP_TOPICS = new Map([
3109
3345
 
3110
3346
  ["operator", [
3111
3347
  "Usage:",
3112
- " audienti operator next [--json]",
3348
+ " audienti operator next [--json|--plan]",
3113
3349
  " audienti operator queue [--json]",
3114
3350
  " audienti operator outcome <row_id> --payload <file.json>",
3115
3351
  "",
@@ -3126,10 +3362,13 @@ const HELP_TOPICS = new Map([
3126
3362
 
3127
3363
  ["operator next", [
3128
3364
  "Usage:",
3129
- " audienti operator next [--json] [filters] [--account <acct_id>]",
3365
+ " audienti operator next [--json|--plan] [filters] [--account <acct_id>]",
3130
3366
  "",
3131
3367
  "Status: implemented",
3132
3368
  "",
3369
+ "Options:",
3370
+ " --plan Render a deterministic static plan from the existing next-action coach payload, CTA, and operator draft state",
3371
+ "",
3133
3372
  "Output shape:",
3134
3373
  " next_move.id: row id",
3135
3374
  " next_move.prospect.prefix_id: prsp_ | null",
@@ -3187,6 +3426,84 @@ const HELP_TOPICS = new Map([
3187
3426
  " POST /api/v1/accounts/:account_id/operator/outcome.json"
3188
3427
  ].join("\n")],
3189
3428
 
3429
+ ["analytics", [
3430
+ "Usage:",
3431
+ " audienti analytics prospects [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
3432
+ " audienti analytics visibility [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
3433
+ " audienti analytics visops [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
3434
+ " audienti analytics content [--window 24h] [--user <account_user_id|email|name|me>] [--json]",
3435
+ "",
3436
+ "Status: implemented",
3437
+ "",
3438
+ "Window:",
3439
+ " --window <24h|7d|1w|day|week>",
3440
+ " --user <account_user_id|email|name|me> Narrow analytics to one account user. Email/name partials are accepted when they match exactly one account user.",
3441
+ "",
3442
+ "Output:",
3443
+ " Account-scoped analytics for prospects, visibility engagement, and ContentOps publishing."
3444
+ ].join("\n")],
3445
+
3446
+ ["analytics prospects", [
3447
+ "Usage:",
3448
+ " audienti analytics prospects [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]",
3449
+ "",
3450
+ "Status: implemented",
3451
+ "",
3452
+ "Output shape:",
3453
+ " prospects_added_count: account prospects added in the window",
3454
+ " account_user: selected account user when --user is provided, otherwise null",
3455
+ " actions: outbound action totals, type breakdown, and automated percentage",
3456
+ " queue_stages[]: current account prospect stage counts",
3457
+ "",
3458
+ "API:",
3459
+ " GET /api/v1/accounts/:account_id/analytics/prospects.json"
3460
+ ].join("\n")],
3461
+
3462
+ ["analytics prospect", [
3463
+ "Usage:",
3464
+ " audienti analytics prospect [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]",
3465
+ "",
3466
+ "Alias for `audienti analytics prospects`."
3467
+ ].join("\n")],
3468
+
3469
+ ["analytics visibility", [
3470
+ "Usage:",
3471
+ " audienti analytics visibility [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]",
3472
+ "",
3473
+ "Status: implemented",
3474
+ "",
3475
+ "Output shape:",
3476
+ " unique_people_engaged_count: unique prospects or profiles touched by visibility actions in the window",
3477
+ " account_user: selected account user when --user is provided, otherwise null",
3478
+ " engagements: visibility action totals, type breakdown, and automated percentage",
3479
+ "",
3480
+ "API:",
3481
+ " GET /api/v1/accounts/:account_id/analytics/visibility.json"
3482
+ ].join("\n")],
3483
+
3484
+ ["analytics visops", [
3485
+ "Usage:",
3486
+ " audienti analytics visops [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]",
3487
+ "",
3488
+ "Alias for `audienti analytics visibility`."
3489
+ ].join("\n")],
3490
+
3491
+ ["analytics content", [
3492
+ "Usage:",
3493
+ " audienti analytics content [--window 24h] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]",
3494
+ "",
3495
+ "Status: implemented",
3496
+ "",
3497
+ "Output shape:",
3498
+ " account_user: selected account user when --user is provided, otherwise null",
3499
+ " published_posts_count: ContentOps work items published in the window",
3500
+ " stage_breakdown[]: current ContentOps work item stage counts",
3501
+ " execution_status_breakdown[]: current ContentOps execution status counts",
3502
+ "",
3503
+ "API:",
3504
+ " GET /api/v1/accounts/:account_id/analytics/content.json"
3505
+ ].join("\n")],
3506
+
3190
3507
  ["agent-workflows", [
3191
3508
  "Usage:",
3192
3509
  " audienti help agent-workflows",
@@ -3230,9 +3547,15 @@ const HELP_TOPICS = new Map([
3230
3547
  "",
3231
3548
  "6. Work the operator queue",
3232
3549
  " audienti operator next",
3550
+ " audienti operator next --plan",
3233
3551
  " audienti operator queue --json",
3234
3552
  " audienti operator outcome <row_id> --payload <file.json>",
3235
3553
  "",
3554
+ "7. Inspect account analytics",
3555
+ " audienti analytics prospects --window 24h",
3556
+ " audienti analytics visibility --window 24h --user me",
3557
+ " audienti analytics content --window week",
3558
+ "",
3236
3559
  "Good defaults:",
3237
3560
  " Use --json when another tool or agent will parse the result.",
3238
3561
  " Use --account <acct_id> to avoid mutating the saved account during one-off runs.",