@audienti/cli 0.1.42 → 0.1.44
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 +6 -0
- package/README.md +44 -2
- package/package.json +1 -1
- package/src/api-client.js +4 -0
- package/src/cli.js +240 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.44] - 2026-09-01
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `audienti analytics metrics` for one-request account-scoped outbound operation cohorts, canonical operation and attempt counts, daily or weekly rows, six leaf outcome filters plus success/failure umbrellas, exact JSON output, and filters for account users, motions, tags, lists, offers, ICPs, Social Cookies, platforms, and actions.
|
|
12
|
+
|
|
7
13
|
## [0.1.42] - 2026-08-28
|
|
8
14
|
|
|
9
15
|
### Changed
|
package/README.md
CHANGED
|
@@ -169,6 +169,7 @@ audienti lists routing-rules <list_id> apply
|
|
|
169
169
|
audienti users activity --window 7d
|
|
170
170
|
audienti analytics prospects --window 24h
|
|
171
171
|
audienti analytics dashboard --play-tag wine_campaign
|
|
172
|
+
audienti analytics metrics --cohort-preset week-to-date
|
|
172
173
|
audienti analytics cohorts create-list --name "Blank note test" --start 2026-07-20 --end 2026-07-20 --note-mode blank
|
|
173
174
|
audienti analytics users --user me --window 30d
|
|
174
175
|
audienti analytics visibility --window 24h --user me
|
|
@@ -259,6 +260,46 @@ To compare recent weekly prospect cohorts by their current pipeline stages:
|
|
|
259
260
|
audienti analytics prospects cohort-analysis --weeks 4 --motion <motn_id>
|
|
260
261
|
```
|
|
261
262
|
|
|
263
|
+
To inspect the current outcomes of outbound operations created in a date range,
|
|
264
|
+
use the account-scoped metrics report:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
audienti analytics metrics --cohort-start 2026-08-24 --cohort-end 2026-08-30 --interval daily
|
|
268
|
+
audienti analytics metrics --cohort-start 2026-08-24 --cohort-end 2026-08-30 --interval weekly
|
|
269
|
+
audienti analytics metrics --cohort-preset week-to-date --user me --motion <motn_id> --play-tag <tag> --list <list_id> --offer <offr_id> --icp <icp_id> --social-cookie <scok_id> --platform linkedin --action messaging.message_sent --outcome succeeded_after_retry
|
|
270
|
+
audienti analytics metrics --cohort-preset week-to-date --json
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
This is an `events.created_at` root-operation cohort, and each operation is
|
|
274
|
+
classified by its current outcome across all of its attempts. It is distinct
|
|
275
|
+
from the `AccountProspect.created_at` entry cohorts used by dashboard, stages,
|
|
276
|
+
and prospect cohort analysis. The command
|
|
277
|
+
makes one authenticated request to the account Metrics API. Plain text formats
|
|
278
|
+
only the returned cohort ranges, Operations, First-try success, Recovered, Final
|
|
279
|
+
failures, In progress, Attempts, selected daily or weekly grid rows, action rows,
|
|
280
|
+
and account-wide Social Cookie rows. `--json` prints the API response deeply
|
|
281
|
+
unchanged; the CLI does not recalculate cohorts, outcomes, counts, or rates.
|
|
282
|
+
|
|
283
|
+
The six leaf outcomes are `first_attempt_success`, `succeeded_after_retry`,
|
|
284
|
+
`failed_without_retry`, `failed_after_retry`, `in_progress`, and `unresolved`.
|
|
285
|
+
The `success` and `failure` values are umbrella filters over their corresponding
|
|
286
|
+
two terminal leaf outcomes.
|
|
287
|
+
|
|
288
|
+
For example, the human output uses the server-provided values directly:
|
|
289
|
+
|
|
290
|
+
```text
|
|
291
|
+
Outbound metrics
|
|
292
|
+
Cohort: 2026-08-24 to 2026-08-30 (events.created_at)
|
|
293
|
+
Current: 2026-08-24T00:00:00-05:00 to 2026-08-31T00:00:00-05:00
|
|
294
|
+
Previous: 2026-08-17T00:00:00-05:00 to 2026-08-24T00:00:00-05:00
|
|
295
|
+
Operations: 1347
|
|
296
|
+
First-try success: 1275 (94.7%)
|
|
297
|
+
Recovered: 40 (3%)
|
|
298
|
+
Final failures: 16 (1.2%)
|
|
299
|
+
In progress: 16 (1.2%)
|
|
300
|
+
Attempts: 1400
|
|
301
|
+
```
|
|
302
|
+
|
|
262
303
|
To materialize a connection-request activity cohort as a reusable list selector,
|
|
263
304
|
then reuse it in analytics:
|
|
264
305
|
|
|
@@ -269,8 +310,9 @@ audienti analytics prospects --list <list_id> --window 30d
|
|
|
269
310
|
audienti analytics users --user me --list <list_id> --start 2026-07-01 --end 2026-07-31
|
|
270
311
|
```
|
|
271
312
|
|
|
272
|
-
|
|
273
|
-
|
|
313
|
+
For prospect, dashboard, and stages analytics, use `--cohort-start` and
|
|
314
|
+
`--cohort-end` when the cohort is based on when people entered Audienti, a
|
|
315
|
+
motion, or a receiving segment. Use `analytics cohorts
|
|
274
316
|
create-list` followed by `--list` when the cohort is based on an event that
|
|
275
317
|
happened later, such as connection requests sent in a date range. Rebuild the
|
|
276
318
|
list when the event definition or date window changes so the analytics question
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -663,6 +663,10 @@ export class AudientiClient {
|
|
|
663
663
|
return this.requestJson(accountPath(accountId, ["analytics", "dashboard"], query));
|
|
664
664
|
}
|
|
665
665
|
|
|
666
|
+
analyticsMetrics(accountId, query = {}) {
|
|
667
|
+
return this.requestJson(accountPath(accountId, ["analytics", "metrics"], query));
|
|
668
|
+
}
|
|
669
|
+
|
|
666
670
|
analyticsStages(accountId, query = {}) {
|
|
667
671
|
return this.requestJson(accountPath(accountId, ["analytics", "stages"], query));
|
|
668
672
|
}
|
package/src/cli.js
CHANGED
|
@@ -36,6 +36,16 @@ const DELETE_CONFIRMATION_VALUES = new Set(["yes", "true", "y"]);
|
|
|
36
36
|
const MOTION_STATUS_VALUES = new Set(["draft", "preparing", "active", "paused", "archived"]);
|
|
37
37
|
const PROSPECT_INACTIVE_REASON_VALUES = new Set(["nurture", "non_responsive", "not_fit", "bad_data_404"]);
|
|
38
38
|
const PROSPECT_STATUS_VALUES = new Set(["active", ...PROSPECT_INACTIVE_REASON_VALUES, "rejected"]);
|
|
39
|
+
const OUTBOUND_METRICS_OUTCOMES = new Set([
|
|
40
|
+
"success",
|
|
41
|
+
"failure",
|
|
42
|
+
"first_attempt_success",
|
|
43
|
+
"succeeded_after_retry",
|
|
44
|
+
"failed_without_retry",
|
|
45
|
+
"failed_after_retry",
|
|
46
|
+
"in_progress",
|
|
47
|
+
"unresolved"
|
|
48
|
+
]);
|
|
39
49
|
const PROSPECTS_ADD_NOTE_USAGE = "Usage: audienti prospects add-note <prsp_id> (--message <text> [--type <note|steer|voicemail_outreach|video_outreach>] [--engagement-type <key>] | --payload <file.json>) [--json] [--account <acct_id>]";
|
|
40
50
|
const PROSPECTS_ADD_STEER_USAGE = "Usage: audienti prospects add-steer <prsp_id> (--message <text> [--engagement-type <key>] | --payload <file.json>) [--json] [--account <acct_id>]";
|
|
41
51
|
const PROSPECTS_ADD_PROFILE_USAGE = "Usage: audienti prospects add-profile <prsp_id> --url <profile_url|email|phone> [--json] [--account <acct_id>]";
|
|
@@ -109,6 +119,7 @@ const ANALYTICS_PROSPECTS_USAGE = "Usage: audienti analytics prospects [--window
|
|
|
109
119
|
const ANALYTICS_PROSPECTS_COHORT_ANALYSIS_USAGE = "Usage: audienti analytics prospects cohort-analysis [--weeks <n>] [--window 24h] [--motion <motn_id>] [--list <list_id>] [--provenance <source>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
110
120
|
const ANALYTICS_USERS_USAGE = "Usage: audienti analytics users [--user <account_user_id|email|name|me>] [--window 30d | --start YYYY-MM-DD --end YYYY-MM-DD] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--motion <motn_id>] [--list <list_id>] [--provenance <source>] [--platform <linkedin|email|gmail>] [--json] [--account <acct_id>]";
|
|
111
121
|
const ANALYTICS_DASHBOARD_USAGE = "Usage: audienti analytics dashboard [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--play-tag <tag>] [--motion <motn_id>] [--list <list_id>] [--offer <offr_id>] [--icp <icp_id>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
122
|
+
const ANALYTICS_METRICS_USAGE = "Usage: audienti analytics metrics [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD | --cohort-preset week-to-date] [--interval <daily|weekly>] [--user <account_user_id|email|name|me>] [--motion <motn_id>] [--play-tag <tag>] [--list <list_id>] [--offer <offr_id>] [--icp <icp_id>] [--social-cookie <scok_id>] [--platform <platform>] [--action <action_key>] [--outcome <success|failure|first_attempt_success|succeeded_after_retry|failed_without_retry|failed_after_retry|in_progress|unresolved>] [--json] [--account <acct_id>]";
|
|
112
123
|
const ANALYTICS_STAGES_USAGE = "Usage: audienti analytics stages [--interval weekly|monthly] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--play-tag <tag>] [--motion <motn_id>] [--list <list_id>] [--offer <offr_id>] [--icp <icp_id>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
113
124
|
const ANALYTICS_COHORT_LIST_USAGE = "Usage: audienti analytics cohorts create-list --name <text> --start YYYY-MM-DD --end YYYY-MM-DD [--event connection_request_sent] [--user <account_user_id|email|name|me>] [--note-mode <any|with_note|blank>] [--motion <motn_id>] [--offer <offr_id>] [--icp <icp_id>] [--play-tag <tag>] [--json] [--account <acct_id>]";
|
|
114
125
|
const TOOLS_LIST_USAGE = "Usage: audienti tools list [--json]";
|
|
@@ -311,6 +322,7 @@ async function dispatch(argv, context) {
|
|
|
311
322
|
if (normalizedResource === "analytics" && ["visibility", "visops"].includes(action)) return analyticsVisibility(rest, context, { accountOverride });
|
|
312
323
|
if (normalizedResource === "analytics" && action === "content") return analyticsContent(rest, context, { accountOverride });
|
|
313
324
|
if (normalizedResource === "analytics" && ["dashboard", "campaign", "campaigns"].includes(action)) return analyticsDashboard(rest, context, { accountOverride });
|
|
325
|
+
if (normalizedResource === "analytics" && action === "metrics") return analyticsMetrics(rest, context, { accountOverride });
|
|
314
326
|
if (normalizedResource === "analytics" && action === "stages") return analyticsStages(rest, context, { accountOverride });
|
|
315
327
|
if (normalizedResource === "analytics" && ["cohorts", "cohort"].includes(action)) return analyticsCohorts(rest, context, { accountOverride });
|
|
316
328
|
|
|
@@ -325,13 +337,15 @@ function extractGlobalOptions(argv) {
|
|
|
325
337
|
const arg = argv[index];
|
|
326
338
|
|
|
327
339
|
if (arg === "--account") {
|
|
328
|
-
|
|
329
|
-
if (!
|
|
340
|
+
const rawAccountOverride = argv[index + 1];
|
|
341
|
+
if (!rawAccountOverride || rawAccountOverride.startsWith("--")) {
|
|
330
342
|
throw new CommandError("--account requires an account id.");
|
|
331
343
|
}
|
|
344
|
+
accountOverride = rawAccountOverride.trim();
|
|
345
|
+
if (!accountOverride) throw new CommandError("--account requires an account id.");
|
|
332
346
|
index += 1;
|
|
333
347
|
} else if (arg.startsWith("--account=")) {
|
|
334
|
-
accountOverride = arg.slice("--account=".length);
|
|
348
|
+
accountOverride = arg.slice("--account=".length).trim();
|
|
335
349
|
if (!accountOverride) throw new CommandError("--account requires an account id.");
|
|
336
350
|
} else {
|
|
337
351
|
args.push(arg);
|
|
@@ -3257,6 +3271,18 @@ async function analyticsDashboard(args, context, { accountOverride } = {}) {
|
|
|
3257
3271
|
renderAnalyticsDashboard(payload, context);
|
|
3258
3272
|
}
|
|
3259
3273
|
|
|
3274
|
+
async function analyticsMetrics(args, context, { accountOverride } = {}) {
|
|
3275
|
+
const { values, positionals } = parseCommandArgs(args, analyticsMetricsOptions());
|
|
3276
|
+
if (positionals.length > 0) throw new CommandError(ANALYTICS_METRICS_USAGE);
|
|
3277
|
+
validateAnalyticsMetricsValues(values);
|
|
3278
|
+
|
|
3279
|
+
const { client, accountId, config } = await requireAccountContext(context, { accountOverride });
|
|
3280
|
+
const payload = await client.analyticsMetrics(accountId, analyticsMetricsQuery(values, config, { accountOverride }));
|
|
3281
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
3282
|
+
|
|
3283
|
+
renderAnalyticsMetrics(payload, context);
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3260
3286
|
async function analyticsStages(args, context, { accountOverride } = {}) {
|
|
3261
3287
|
const { values, positionals } = parseCommandArgs(args, analyticsStagesOptions());
|
|
3262
3288
|
if (positionals.length > 0) throw new CommandError(ANALYTICS_STAGES_USAGE);
|
|
@@ -3549,6 +3575,26 @@ function analyticsStagesOptions() {
|
|
|
3549
3575
|
};
|
|
3550
3576
|
}
|
|
3551
3577
|
|
|
3578
|
+
function analyticsMetricsOptions() {
|
|
3579
|
+
return {
|
|
3580
|
+
...jsonOptions(),
|
|
3581
|
+
"cohort-start": { type: "string" },
|
|
3582
|
+
"cohort-end": { type: "string" },
|
|
3583
|
+
"cohort-preset": { type: "string" },
|
|
3584
|
+
interval: { type: "string" },
|
|
3585
|
+
user: { type: "string" },
|
|
3586
|
+
motion: { type: "string" },
|
|
3587
|
+
"play-tag": { type: "string" },
|
|
3588
|
+
list: { type: "string" },
|
|
3589
|
+
offer: { type: "string" },
|
|
3590
|
+
icp: { type: "string" },
|
|
3591
|
+
"social-cookie": { type: "string" },
|
|
3592
|
+
platform: { type: "string" },
|
|
3593
|
+
action: { type: "string" },
|
|
3594
|
+
outcome: { type: "string" }
|
|
3595
|
+
};
|
|
3596
|
+
}
|
|
3597
|
+
|
|
3552
3598
|
function analyticsCohortListOptions() {
|
|
3553
3599
|
return {
|
|
3554
3600
|
...jsonOptions(),
|
|
@@ -3614,6 +3660,59 @@ function analyticsStagesQuery(values, config = {}, { accountOverride } = {}) {
|
|
|
3614
3660
|
});
|
|
3615
3661
|
}
|
|
3616
3662
|
|
|
3663
|
+
function analyticsMetricsQuery(values, config = {}, { accountOverride } = {}) {
|
|
3664
|
+
return compactObject({
|
|
3665
|
+
cohort_start_date: values["cohort-start"],
|
|
3666
|
+
cohort_end_date: values["cohort-end"],
|
|
3667
|
+
cohort_preset: values["cohort-preset"] === "week-to-date" ? "week_to_date" : values["cohort-preset"],
|
|
3668
|
+
interval: values.interval,
|
|
3669
|
+
account_user_id: resolveAccountUserId(values.user, config, { accountOverride }),
|
|
3670
|
+
motion_id: values.motion,
|
|
3671
|
+
play_tag: values["play-tag"],
|
|
3672
|
+
list_id: values.list,
|
|
3673
|
+
offer_id: values.offer,
|
|
3674
|
+
icp_id: values.icp,
|
|
3675
|
+
social_cookie_id: values["social-cookie"],
|
|
3676
|
+
platform: values.platform,
|
|
3677
|
+
action_key: values.action,
|
|
3678
|
+
outcome: values.outcome
|
|
3679
|
+
});
|
|
3680
|
+
}
|
|
3681
|
+
|
|
3682
|
+
function validateAnalyticsMetricsValues(values) {
|
|
3683
|
+
for (const [key, value] of Object.entries(values)) {
|
|
3684
|
+
if (key !== "json" && typeof value === "string" && value.trim() === "") {
|
|
3685
|
+
throw new CommandError(`--${key} cannot be blank.`);
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
validateDatePair(values["cohort-start"], values["cohort-end"], "--cohort-start", "--cohort-end");
|
|
3690
|
+
validateIsoDate(values["cohort-start"], "--cohort-start");
|
|
3691
|
+
validateIsoDate(values["cohort-end"], "--cohort-end");
|
|
3692
|
+
|
|
3693
|
+
if (values["cohort-preset"] && (values["cohort-start"] || values["cohort-end"])) {
|
|
3694
|
+
throw new CommandError("--cohort-preset cannot be combined with --cohort-start or --cohort-end.");
|
|
3695
|
+
}
|
|
3696
|
+
if (values["cohort-preset"] && values["cohort-preset"] !== "week-to-date") {
|
|
3697
|
+
throw new CommandError("--cohort-preset must be week-to-date.");
|
|
3698
|
+
}
|
|
3699
|
+
if (values.interval && !["daily", "weekly"].includes(values.interval)) {
|
|
3700
|
+
throw new CommandError("--interval must be daily or weekly.");
|
|
3701
|
+
}
|
|
3702
|
+
if (values.outcome && !OUTBOUND_METRICS_OUTCOMES.has(values.outcome)) {
|
|
3703
|
+
throw new CommandError("--outcome must be one of success, failure, first_attempt_success, succeeded_after_retry, failed_without_retry, failed_after_retry, in_progress, unresolved.");
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
function validateIsoDate(value, flagName) {
|
|
3708
|
+
if (!value) return;
|
|
3709
|
+
|
|
3710
|
+
const match = String(value).match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
3711
|
+
const date = match ? new Date(`${value}T00:00:00Z`) : null;
|
|
3712
|
+
const valid = date && !Number.isNaN(date.getTime()) && date.toISOString().slice(0, 10) === value;
|
|
3713
|
+
if (!valid) throw new CommandError(`${flagName} must be a valid date in YYYY-MM-DD format.`);
|
|
3714
|
+
}
|
|
3715
|
+
|
|
3617
3716
|
function validateDatePair(start, end, startFlag, endFlag) {
|
|
3618
3717
|
if ((start && !end) || (!start && end)) {
|
|
3619
3718
|
throw new CommandError(`${startFlag} and ${endFlag} must be provided together.`);
|
|
@@ -5867,6 +5966,102 @@ function renderAnalyticsDashboard(payload, context) {
|
|
|
5867
5966
|
writeCountTable(context, "Current pipeline stages", payload?.pipeline_stage_counts, ["STAGE", "COUNT"], countRow);
|
|
5868
5967
|
}
|
|
5869
5968
|
|
|
5969
|
+
function renderAnalyticsMetrics(payload, context) {
|
|
5970
|
+
const cohort = payload?.cohort || {};
|
|
5971
|
+
const summary = payload?.summary || {};
|
|
5972
|
+
writeLine(context.stdout, "Outbound metrics");
|
|
5973
|
+
writeLine(context.stdout, `Cohort: ${display(cohort.start_date, "-")} to ${display(cohort.end_date, "-")} (${display(cohort.field, "-")})`);
|
|
5974
|
+
writeLine(context.stdout, `Current: ${metricsRangeLabel(cohort.start_at, cohort.end_at)}`);
|
|
5975
|
+
writeLine(context.stdout, `Previous: ${metricsRangeLabel(cohort.previous_start_at, cohort.previous_end_at)}`);
|
|
5976
|
+
writeLine(context.stdout, `Operations: ${display(summary.operation_count, "-")}`);
|
|
5977
|
+
writeLine(context.stdout, `First-try success: ${metricsCountRateLabel(summary, "first_attempt_success")}`);
|
|
5978
|
+
writeLine(context.stdout, `Recovered: ${metricsCountRateLabel(summary, "succeeded_after_retry")}`);
|
|
5979
|
+
writeLine(context.stdout, `Final failures: ${metricsCountRateLabel(summary, "ultimate_failure")}`);
|
|
5980
|
+
writeLine(context.stdout, `In progress: ${metricsCountRateLabel(summary, "in_progress")}`);
|
|
5981
|
+
writeLine(context.stdout, `Attempts: ${display(summary.attempt_count, "-")}`);
|
|
5982
|
+
|
|
5983
|
+
renderAnalyticsMetricsGrid(payload?.grid, context);
|
|
5984
|
+
renderAnalyticsMetricsActions(payload?.action_rows, context);
|
|
5985
|
+
if (payload?.scope?.social_cookie == null) renderAnalyticsMetricsCookies(payload?.social_cookie_rows, context);
|
|
5986
|
+
}
|
|
5987
|
+
|
|
5988
|
+
function metricsRangeLabel(startAt, endAt) {
|
|
5989
|
+
return startAt && endAt ? `${startAt} to ${endAt}` : "not available";
|
|
5990
|
+
}
|
|
5991
|
+
|
|
5992
|
+
function metricsCountRateLabel(summary, bucket) {
|
|
5993
|
+
return `${display(summary?.[`${bucket}_count`], "-")} (${percentageLabel(summary?.[`${bucket}_rate`])})`;
|
|
5994
|
+
}
|
|
5995
|
+
|
|
5996
|
+
function renderAnalyticsMetricsGrid(grid, context) {
|
|
5997
|
+
const rows = Array.isArray(grid?.rows) ? grid.rows : [];
|
|
5998
|
+
const intervalLabel = grid?.interval === "weekly" ? "Weekly" : "Daily";
|
|
5999
|
+
writeLine(context.stdout, "");
|
|
6000
|
+
writeLine(context.stdout, `${intervalLabel} rows`);
|
|
6001
|
+
if (rows.length === 0) return writeLine(context.stdout, "None");
|
|
6002
|
+
|
|
6003
|
+
writeAlignedTable(context, [
|
|
6004
|
+
grid?.row_heading?.toUpperCase() || "PERIOD",
|
|
6005
|
+
"OPERATIONS",
|
|
6006
|
+
"FIRST-TRY SUCCESS",
|
|
6007
|
+
"RECOVERED",
|
|
6008
|
+
"FINAL FAILURES",
|
|
6009
|
+
"IN PROGRESS",
|
|
6010
|
+
"ATTEMPTS"
|
|
6011
|
+
], rows.map((row) => [
|
|
6012
|
+
display(row?.label, "-"),
|
|
6013
|
+
display(row?.summary?.operation_count, "-"),
|
|
6014
|
+
metricsCountRateLabel(row?.summary, "first_attempt_success"),
|
|
6015
|
+
metricsCountRateLabel(row?.summary, "succeeded_after_retry"),
|
|
6016
|
+
metricsCountRateLabel(row?.summary, "ultimate_failure"),
|
|
6017
|
+
metricsCountRateLabel(row?.summary, "in_progress"),
|
|
6018
|
+
display(row?.summary?.attempt_count, "-")
|
|
6019
|
+
]), { numericColumns: [false, true, true, true, true, true, true] });
|
|
6020
|
+
}
|
|
6021
|
+
|
|
6022
|
+
function renderAnalyticsMetricsActions(rows, context) {
|
|
6023
|
+
const actions = Array.isArray(rows) ? rows : [];
|
|
6024
|
+
writeLine(context.stdout, "");
|
|
6025
|
+
writeLine(context.stdout, "Action breakdown");
|
|
6026
|
+
if (actions.length === 0) return writeLine(context.stdout, "None");
|
|
6027
|
+
|
|
6028
|
+
writeAnalyticsMetricsSummaryTable(context, ["ACTION", "KEY"], actions.map((row) => [
|
|
6029
|
+
display(row?.label, "-"),
|
|
6030
|
+
display(row?.key, "-")
|
|
6031
|
+
]), actions.map((row) => row?.summary));
|
|
6032
|
+
}
|
|
6033
|
+
|
|
6034
|
+
function renderAnalyticsMetricsCookies(rows, context) {
|
|
6035
|
+
const cookies = Array.isArray(rows) ? rows : [];
|
|
6036
|
+
writeLine(context.stdout, "");
|
|
6037
|
+
writeLine(context.stdout, "Social Cookie breakdown");
|
|
6038
|
+
if (cookies.length === 0) return writeLine(context.stdout, "None");
|
|
6039
|
+
|
|
6040
|
+
writeAnalyticsMetricsSummaryTable(context, ["SOCIAL COOKIE", "ID"], cookies.map((row) => [
|
|
6041
|
+
display(row?.label, "-"),
|
|
6042
|
+
display(row?.prefix_id, "-")
|
|
6043
|
+
]), cookies.map((row) => row?.summary));
|
|
6044
|
+
}
|
|
6045
|
+
|
|
6046
|
+
function writeAnalyticsMetricsSummaryTable(context, identityHeaders, identityRows, summaries) {
|
|
6047
|
+
const summaryHeaders = ["OPERATIONS", "FIRST-TRY SUCCESS", "RECOVERED", "FINAL FAILURES", "IN PROGRESS", "ATTEMPTS"];
|
|
6048
|
+
const rows = identityRows.map((identity, index) => {
|
|
6049
|
+
const summary = summaries[index];
|
|
6050
|
+
return [
|
|
6051
|
+
...identity,
|
|
6052
|
+
display(summary?.operation_count, "-"),
|
|
6053
|
+
metricsCountRateLabel(summary, "first_attempt_success"),
|
|
6054
|
+
metricsCountRateLabel(summary, "succeeded_after_retry"),
|
|
6055
|
+
metricsCountRateLabel(summary, "ultimate_failure"),
|
|
6056
|
+
metricsCountRateLabel(summary, "in_progress"),
|
|
6057
|
+
display(summary?.attempt_count, "-")
|
|
6058
|
+
];
|
|
6059
|
+
});
|
|
6060
|
+
writeAlignedTable(context, [...identityHeaders, ...summaryHeaders], rows, {
|
|
6061
|
+
numericColumns: [...identityHeaders.map(() => false), true, true, true, true, true, true]
|
|
6062
|
+
});
|
|
6063
|
+
}
|
|
6064
|
+
|
|
5870
6065
|
function renderAnalyticsStages(payload, context) {
|
|
5871
6066
|
const conversionGrid = payload?.conversion_grid || {};
|
|
5872
6067
|
writeLine(context.stdout, `Stage analytics (${display(payload?.cohort?.label, "selected cohort")})`);
|
|
@@ -6772,6 +6967,7 @@ const HELP_TOPICS = new Map([
|
|
|
6772
6967
|
" Analytics",
|
|
6773
6968
|
" audienti analytics prospects --window 24h",
|
|
6774
6969
|
" audienti analytics dashboard --play-tag <tag>",
|
|
6970
|
+
" audienti analytics metrics --cohort-preset week-to-date",
|
|
6775
6971
|
" audienti analytics stages --interval weekly",
|
|
6776
6972
|
" audienti analytics cohorts create-list --name \"Blank note test\" --start 2026-07-20 --end 2026-07-20 --note-mode blank",
|
|
6777
6973
|
" audienti analytics prospects cohort-analysis --weeks 4 --motion <motn_id>",
|
|
@@ -6794,6 +6990,7 @@ const HELP_TOPICS = new Map([
|
|
|
6794
6990
|
" Preview a campaign: audienti writer test-run <prsp_id>",
|
|
6795
6991
|
" Analyze one motion: audienti motions analytics <motn_id>",
|
|
6796
6992
|
" Count one campaign: audienti analytics dashboard --play-tag <tag>",
|
|
6993
|
+
" Inspect outcomes: audienti analytics metrics --cohort-preset week-to-date",
|
|
6797
6994
|
" Compare stage rates: audienti analytics stages --interval weekly",
|
|
6798
6995
|
" Audit your work: audienti analytics users --user me --window 30d",
|
|
6799
6996
|
" Review reminders: audienti tasks list",
|
|
@@ -9557,6 +9754,7 @@ const HELP_TOPICS = new Map([
|
|
|
9557
9754
|
"Usage:",
|
|
9558
9755
|
" audienti analytics prospects [--window 24h] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--motion <motn_id>] [--list <list_id>] [--user <account_user_id|email|name|me>] [--json]",
|
|
9559
9756
|
" audienti analytics dashboard [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--play-tag <tag>] [--motion <motn_id>] [--list <list_id>] [--json]",
|
|
9757
|
+
" audienti analytics metrics [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD | --cohort-preset week-to-date] [--interval <daily|weekly>] [--user <account_user_id|email|name|me>] [--motion <motn_id>] [--play-tag <tag>] [--list <list_id>] [--offer <offr_id>] [--icp <icp_id>] [--social-cookie <scok_id>] [--platform <platform>] [--action <action_key>] [--outcome <success|failure|first_attempt_success|succeeded_after_retry|failed_without_retry|failed_after_retry|in_progress|unresolved>] [--json]",
|
|
9560
9758
|
" audienti analytics stages [--interval weekly|monthly] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--play-tag <tag>] [--motion <motn_id>] [--list <list_id>] [--json]",
|
|
9561
9759
|
" audienti analytics cohorts create-list --name <text> --start YYYY-MM-DD --end YYYY-MM-DD [--note-mode <any|with_note|blank>] [--user <account_user_id|email|name|me>] [--json]",
|
|
9562
9760
|
" audienti analytics prospects cohort-analysis [--weeks <n>] [--window 24h] [--motion <motn_id>] [--list <list_id>] [--user <account_user_id|email|name|me>] [--json]",
|
|
@@ -9575,6 +9773,7 @@ const HELP_TOPICS = new Map([
|
|
|
9575
9773
|
" --list <list_id> Filter analytics to prospects in one list, including analytics cohort lists.",
|
|
9576
9774
|
" --play-tag <tag> For dashboard analytics, filter to motions/lists tagged with a campaign tag.",
|
|
9577
9775
|
" --interval <weekly|monthly> For stages analytics, select the conversion cohort grain.",
|
|
9776
|
+
" Metrics uses events.created_at root-operation cohorts and reports each operation's current outcome across its attempts; it is not an AccountProspect.created_at entry cohort.",
|
|
9578
9777
|
" --provenance <source> Optional lower-level AccountProspect.intake_source filter.",
|
|
9579
9778
|
" --platform <linkedin|email|gmail> For user analytics, filter events.platform. --channel is accepted as an alias.",
|
|
9580
9779
|
" cohort-analysis loops over recent weekly AccountProspect.created_at cohorts and compares their current stages.",
|
|
@@ -9614,6 +9813,43 @@ const HELP_TOPICS = new Map([
|
|
|
9614
9813
|
" GET /api/v1/accounts/:account_id/analytics/dashboard.json"
|
|
9615
9814
|
].join("\n")],
|
|
9616
9815
|
|
|
9816
|
+
["analytics metrics", [
|
|
9817
|
+
"Usage:",
|
|
9818
|
+
` ${ANALYTICS_METRICS_USAGE.slice("Usage: ".length)}`,
|
|
9819
|
+
"",
|
|
9820
|
+
"Status: implemented",
|
|
9821
|
+
"",
|
|
9822
|
+
"Purpose:",
|
|
9823
|
+
" Return account-scoped outbound operation outcomes with exactly one authenticated API request.",
|
|
9824
|
+
" The cohort is events.created_at: root operations created in the selected period, measured by their current outcomes.",
|
|
9825
|
+
" This differs from AccountProspect.created_at entry cohorts used by dashboard, stages, and prospect cohort analysis.",
|
|
9826
|
+
"",
|
|
9827
|
+
"Options:",
|
|
9828
|
+
" --cohort-start <YYYY-MM-DD> --cohort-end <YYYY-MM-DD> Select an explicit inclusive operation cohort.",
|
|
9829
|
+
" --cohort-preset <week-to-date> Select the server-defined week-to-date cohort; cannot be combined with explicit dates.",
|
|
9830
|
+
" --interval <daily|weekly> Request daily or weekly operation rows. The server default is daily.",
|
|
9831
|
+
" --user <account_user_id|email|name|me> Filter to one account user.",
|
|
9832
|
+
" --motion <motn_id> Filter operations to prospects in one motion/play.",
|
|
9833
|
+
" --play-tag <tag> Filter operations to prospects in motions/lists with the tag.",
|
|
9834
|
+
" --list <list_id> Filter operations to prospects in one list.",
|
|
9835
|
+
" --offer <offr_id> Filter operations to prospects for one offer.",
|
|
9836
|
+
" --icp <icp_id> Filter operations to prospects for one ICP.",
|
|
9837
|
+
" --social-cookie <scok_id> Filter to one account-accessible Social Cookie.",
|
|
9838
|
+
" --platform <platform> Filter by the normalized event platform.",
|
|
9839
|
+
" --action <action_key> Filter by the exact outbound action key.",
|
|
9840
|
+
" --outcome <success|failure|first_attempt_success|succeeded_after_retry|failed_without_retry|failed_after_retry|in_progress|unresolved>",
|
|
9841
|
+
" Umbrella filters: success, failure.",
|
|
9842
|
+
" Leaf outcomes: first_attempt_success, succeeded_after_retry, failed_without_retry, failed_after_retry, in_progress, unresolved.",
|
|
9843
|
+
" --json Print the API response deeply unchanged.",
|
|
9844
|
+
"",
|
|
9845
|
+
"Output:",
|
|
9846
|
+
" Plain text formats only API-returned operation counts/rates, selected grid rows, actions, and account-wide cookie rows.",
|
|
9847
|
+
" JSON is the canonical outbound_metrics response without client-side cohort, outcome, count, or rate calculations.",
|
|
9848
|
+
"",
|
|
9849
|
+
"API:",
|
|
9850
|
+
" GET /api/v1/accounts/:account_id/analytics/metrics.json"
|
|
9851
|
+
].join("\n")],
|
|
9852
|
+
|
|
9617
9853
|
["analytics stages", [
|
|
9618
9854
|
"Usage:",
|
|
9619
9855
|
` ${ANALYTICS_STAGES_USAGE.slice("Usage: ".length)}`,
|
|
@@ -9874,6 +10110,7 @@ const HELP_TOPICS = new Map([
|
|
|
9874
10110
|
" audienti users activity me --window 7d",
|
|
9875
10111
|
" audienti analytics prospects --window 24h",
|
|
9876
10112
|
" audienti analytics dashboard --play-tag wine_campaign",
|
|
10113
|
+
" audienti analytics metrics --cohort-preset week-to-date",
|
|
9877
10114
|
" audienti analytics stages --interval weekly --play-tag wine_campaign",
|
|
9878
10115
|
" audienti analytics cohorts create-list --name \"Connection requests 2026-07-20\" --start 2026-07-20 --end 2026-07-20",
|
|
9879
10116
|
" audienti analytics users --user me --window 30d",
|