@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 +13 -0
- package/README.md +9 -0
- package/package.json +2 -1
- package/skills/audienti/SKILL.md +60 -0
- package/src/api-client.js +12 -0
- package/src/cli.js +327 -4
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.
|
|
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.",
|