@audienti/cli 0.1.27 → 0.1.28
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 +7 -0
- package/package.json +1 -1
- package/src/api-client.js +14 -0
- package/src/cli.js +142 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.28] - 2026-07-23
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `audienti prospects reenrich` for dry-running or queueing one forced LinkedIn person profile re-enrichment.
|
|
12
|
+
- Add `audienti prospects refresh-queue` for dry-running or applying account-scoped next-action and operator draft cache repair for one prospect.
|
|
13
|
+
|
|
7
14
|
## [0.1.27] - 2026-07-22
|
|
8
15
|
|
|
9
16
|
### Added
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -373,6 +373,20 @@ export class AudientiClient {
|
|
|
373
373
|
});
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
+
reenrichProspect(accountId, prospectId, body = {}) {
|
|
377
|
+
return this.requestJson(accountPath(accountId, ["prospects", prospectId, "reenrich"]), {
|
|
378
|
+
method: "POST",
|
|
379
|
+
body
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
refreshProspectQueue(accountId, prospectId, body = {}) {
|
|
384
|
+
return this.requestJson(accountPath(accountId, ["prospects", prospectId, "refresh_queue"]), {
|
|
385
|
+
method: "POST",
|
|
386
|
+
body
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
376
390
|
assignProspects(accountId, body) {
|
|
377
391
|
return this.requestJson(accountPath(accountId, ["prospects", "assign"]), {
|
|
378
392
|
method: "POST",
|
package/src/cli.js
CHANGED
|
@@ -39,6 +39,8 @@ const PROSPECTS_REPORT_BAD_PROFILE_USAGE = "Usage: audienti prospects report-bad
|
|
|
39
39
|
const PROSPECTS_ASSIGN_USAGE = "Usage: audienti prospects assign <prsp_id> [prsp_id...] --assigned-user <id|me|unassign> [--json] [--account <acct_id>]";
|
|
40
40
|
const PROSPECTS_SET_STATUS_USAGE = "Usage: audienti prospects set-status <prsp_id> --status <active|nurture|non_responsive|not_fit|bad_data_404|rejected> [--json] [--account <acct_id>]";
|
|
41
41
|
const PROSPECTS_REPLAN_USAGE = "Usage: audienti prospects replan <prsp_id> [--apply] [--json] [--account <acct_id>]";
|
|
42
|
+
const PROSPECTS_REENRICH_USAGE = "Usage: audienti prospects reenrich <prsp_id> [--profile <prof_id|citation_id>] [--apply] [--json] [--account <acct_id>]";
|
|
43
|
+
const PROSPECTS_REFRESH_QUEUE_USAGE = "Usage: audienti prospects refresh-queue <prsp_id> [--apply] [--json] [--account <acct_id>]";
|
|
42
44
|
const PROSPECTS_REJECT_USAGE = "Usage: audienti prospects reject <prsp_id> [--json] [--account <acct_id>]";
|
|
43
45
|
const PROSPECTS_NURTURE_USAGE = "Usage: audienti prospects nurture <prsp_id> [--reason <nurture|non_responsive|not_fit|bad_data_404>] [--json] [--account <acct_id>]";
|
|
44
46
|
const PROSPECTS_RESTORE_USAGE = "Usage: audienti prospects restore <prsp_id> [--json] [--account <acct_id>]";
|
|
@@ -247,6 +249,8 @@ async function dispatch(argv, context) {
|
|
|
247
249
|
if (normalizedResource === "prospects" && action === "assign") return prospectsAssign(rest, context, { accountOverride });
|
|
248
250
|
if (normalizedResource === "prospects" && action === "set-status") return prospectsSetStatus(rest, context, { accountOverride });
|
|
249
251
|
if (normalizedResource === "prospects" && action === "replan") return prospectsReplan(rest, context, { accountOverride });
|
|
252
|
+
if (normalizedResource === "prospects" && action === "reenrich") return prospectsReenrich(rest, context, { accountOverride });
|
|
253
|
+
if (normalizedResource === "prospects" && action === "refresh-queue") return prospectsRefreshQueue(rest, context, { accountOverride });
|
|
250
254
|
if (normalizedResource === "prospects" && action === "reject") return prospectsDisposition("reject", rest, context, { accountOverride });
|
|
251
255
|
if (normalizedResource === "prospects" && action === "nurture") return prospectsDisposition("nurture", rest, context, { accountOverride });
|
|
252
256
|
if (normalizedResource === "prospects" && action === "restore") return prospectsDisposition("restore", rest, context, { accountOverride });
|
|
@@ -1861,6 +1865,40 @@ async function prospectsReplan(args, context, { accountOverride } = {}) {
|
|
|
1861
1865
|
renderProspectReplan(payload, context);
|
|
1862
1866
|
}
|
|
1863
1867
|
|
|
1868
|
+
async function prospectsReenrich(args, context, { accountOverride } = {}) {
|
|
1869
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1870
|
+
...jsonOptions(),
|
|
1871
|
+
apply: { type: "boolean" },
|
|
1872
|
+
profile: { type: "string" }
|
|
1873
|
+
});
|
|
1874
|
+
if (positionals.length !== 1) throw new CommandError(PROSPECTS_REENRICH_USAGE);
|
|
1875
|
+
|
|
1876
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1877
|
+
const payload = await client.reenrichProspect(accountId, positionals[0], compactObject({
|
|
1878
|
+
apply: values.apply,
|
|
1879
|
+
profile_id: values.profile
|
|
1880
|
+
}));
|
|
1881
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1882
|
+
|
|
1883
|
+
renderProspectReenrich(payload, context);
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
async function prospectsRefreshQueue(args, context, { accountOverride } = {}) {
|
|
1887
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1888
|
+
...jsonOptions(),
|
|
1889
|
+
apply: { type: "boolean" }
|
|
1890
|
+
});
|
|
1891
|
+
if (positionals.length !== 1) throw new CommandError(PROSPECTS_REFRESH_QUEUE_USAGE);
|
|
1892
|
+
|
|
1893
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1894
|
+
const payload = await client.refreshProspectQueue(accountId, positionals[0], compactObject({
|
|
1895
|
+
apply: values.apply
|
|
1896
|
+
}));
|
|
1897
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1898
|
+
|
|
1899
|
+
renderProspectRefreshQueue(payload, context);
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1864
1902
|
async function prospectsDisposition(action, args, context, { accountOverride } = {}) {
|
|
1865
1903
|
const usageText = {
|
|
1866
1904
|
reject: PROSPECTS_REJECT_USAGE,
|
|
@@ -3998,6 +4036,61 @@ function renderProspectReplan(payload, context) {
|
|
|
3998
4036
|
if (payload?.status === "coach_error") writeLine(context.stdout, "The plan was not persisted. Fix the coach error and rerun with --apply.");
|
|
3999
4037
|
}
|
|
4000
4038
|
|
|
4039
|
+
function renderProspectReenrich(payload, context) {
|
|
4040
|
+
const prospect = payload?.prospect || {};
|
|
4041
|
+
const profile = payload?.profile || {};
|
|
4042
|
+
const completeness = payload?.completeness || {};
|
|
4043
|
+
const enrichment = payload?.enrichment || {};
|
|
4044
|
+
const status = payload?.status === "queued" ? "queued" : (payload?.status === "not_queued" ? "not queued" : "dry run");
|
|
4045
|
+
|
|
4046
|
+
writeLine(context.stdout, `Re-enrich ${status} for ${display(prospect.display_name || prospect.name)} (${display(prospect.prefix_id)}).`);
|
|
4047
|
+
writeLine(context.stdout, `Profile: ${display(profile.prefix_id)} ${display(profile.identifier)} ${display(profile.url)}`);
|
|
4048
|
+
writeLine(context.stdout, `Profile status: ${display(profile.status)}`);
|
|
4049
|
+
writeLine(context.stdout, `Thin profile signals: ${completeness.thin_profile_signals ? "yes" : "no"}`);
|
|
4050
|
+
writeLine(context.stdout, `Experience entries: ${sumObjectValues(completeness.experience_counts)}`);
|
|
4051
|
+
writeLine(context.stdout, `Substantive bio length: ${display(completeness.substantive_bio_length, 0)}`);
|
|
4052
|
+
if (profile.invalid_reason) writeLine(context.stdout, `Invalid reason: ${profile.invalid_reason}`);
|
|
4053
|
+
if (enrichment.retry_counter_reset) writeLine(context.stdout, "A stale enrichment retry counter will be cleared.");
|
|
4054
|
+
if (enrichment.next_enrichment_at) writeLine(context.stdout, `Next enrichment at: ${enrichment.next_enrichment_at}`);
|
|
4055
|
+
if (payload?.status === "dry_run") writeLine(context.stdout, "Run again with --apply to queue full enrichment.");
|
|
4056
|
+
if (payload?.status === "not_queued") writeLine(context.stdout, "The profile was not queued, usually because an active enrichment is already running.");
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
function renderProspectRefreshQueue(payload, context) {
|
|
4060
|
+
const prospect = payload?.prospect || {};
|
|
4061
|
+
const draftCache = payload?.draft_cache || {};
|
|
4062
|
+
const coachCache = payload?.coach_cache || {};
|
|
4063
|
+
const refresh = payload?.queue_refresh || {};
|
|
4064
|
+
const status = payload?.status === "applied" ? "applied" : "dry run";
|
|
4065
|
+
|
|
4066
|
+
writeLine(context.stdout, `Refresh queue ${status} for ${display(prospect.display_name || prospect.name)} (${display(prospect.prefix_id)}).`);
|
|
4067
|
+
writeLine(context.stdout, `Coach cache: ${coachCache.present ? "present" : "empty"}`);
|
|
4068
|
+
if (coachCache.evaluated_at) writeLine(context.stdout, `Coach evaluated at: ${coachCache.evaluated_at}`);
|
|
4069
|
+
writeLine(context.stdout, `Draft cache rows: ${display(draftCache.count, 0)}`);
|
|
4070
|
+
writeLine(context.stdout, `Draft statuses: ${formatObjectCounts(draftCache.by_status)}`);
|
|
4071
|
+
writeLine(context.stdout, `Action types: ${Array.isArray(draftCache.action_types) && draftCache.action_types.length > 0 ? draftCache.action_types.join(", ") : "none"}`);
|
|
4072
|
+
if (payload?.applied) {
|
|
4073
|
+
writeLine(context.stdout, `Deleted draft rows: ${display(draftCache.deleted_count, 0)}`);
|
|
4074
|
+
writeLine(context.stdout, `Draft prewarm queued: ${display(refresh?.draft_prewarm?.enqueued_rows, 0)}`);
|
|
4075
|
+
} else {
|
|
4076
|
+
writeLine(context.stdout, "Run again with --apply to clear coach/draft cache and rebuild the queue row.");
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
|
|
4080
|
+
function sumObjectValues(value) {
|
|
4081
|
+
if (!value || typeof value !== "object") return 0;
|
|
4082
|
+
|
|
4083
|
+
return Object.values(value).reduce((sum, item) => sum + Number(item || 0), 0);
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
function formatObjectCounts(value) {
|
|
4087
|
+
if (!value || typeof value !== "object" || Object.keys(value).length === 0) return "none";
|
|
4088
|
+
|
|
4089
|
+
return Object.entries(value)
|
|
4090
|
+
.map(([key, count]) => `${key}:${count}`)
|
|
4091
|
+
.join(", ");
|
|
4092
|
+
}
|
|
4093
|
+
|
|
4001
4094
|
function replanStatusLabel(payload) {
|
|
4002
4095
|
if (payload?.status === "dry_run") return "dry run";
|
|
4003
4096
|
if (payload?.status === "coach_error") return "coach error";
|
|
@@ -5575,6 +5668,8 @@ const HELP_TOPICS = new Map([
|
|
|
5575
5668
|
" audienti prospects assign <prsp_id> --assigned-user <id|me|unassign>",
|
|
5576
5669
|
" audienti prospects set-status <prsp_id> --status <active|nurture|non_responsive|not_fit|bad_data_404|rejected>",
|
|
5577
5670
|
" audienti prospects replan <prsp_id> [--apply]",
|
|
5671
|
+
" audienti prospects reenrich <prsp_id> [--apply]",
|
|
5672
|
+
" audienti prospects refresh-queue <prsp_id> [--apply]",
|
|
5578
5673
|
" audienti prospects lock <prsp_id> [--note <text>]",
|
|
5579
5674
|
" audienti prospects reject <prsp_id>",
|
|
5580
5675
|
" audienti prospects nurture <prsp_id> [--reason <reason>]",
|
|
@@ -7080,6 +7175,8 @@ const HELP_TOPICS = new Map([
|
|
|
7080
7175
|
" audienti prospects assign <prsp_id> [prsp_id...] --assigned-user <id|me|unassign> [--json]",
|
|
7081
7176
|
" audienti prospects set-status <prsp_id> --status <active|nurture|non_responsive|not_fit|bad_data_404|rejected> [--json]",
|
|
7082
7177
|
" audienti prospects replan <prsp_id> [--apply] [--json]",
|
|
7178
|
+
" audienti prospects reenrich <prsp_id> [--profile <prof_id|citation_id>] [--apply] [--json]",
|
|
7179
|
+
" audienti prospects refresh-queue <prsp_id> [--apply] [--json]",
|
|
7083
7180
|
" audienti prospects reject <prsp_id> [--json]",
|
|
7084
7181
|
" audienti prospects nurture <prsp_id> [--reason <reason>] [--json]",
|
|
7085
7182
|
" audienti prospects restore <prsp_id> [--json]",
|
|
@@ -7283,6 +7380,51 @@ const HELP_TOPICS = new Map([
|
|
|
7283
7380
|
" }"
|
|
7284
7381
|
].join("\n")],
|
|
7285
7382
|
|
|
7383
|
+
["prospects reenrich", [
|
|
7384
|
+
"Usage:",
|
|
7385
|
+
` ${PROSPECTS_REENRICH_USAGE.slice("Usage: ".length)}`,
|
|
7386
|
+
"",
|
|
7387
|
+
"Status: implemented",
|
|
7388
|
+
"",
|
|
7389
|
+
"Purpose:",
|
|
7390
|
+
" Force a full LinkedIn person profile enrichment for one prospect from the CLI.",
|
|
7391
|
+
"",
|
|
7392
|
+
"Behavior:",
|
|
7393
|
+
" Defaults to a dry-run showing the selected profile, completeness signals, and whether a stale retry counter would be cleared.",
|
|
7394
|
+
" Pass --apply to queue ProfileEnrichJob with a maintenance origin and schedule expansion after enrichment.",
|
|
7395
|
+
"",
|
|
7396
|
+
"API:",
|
|
7397
|
+
" POST /api/v1/accounts/:account_id/prospects/:id/reenrich.json",
|
|
7398
|
+
"",
|
|
7399
|
+
"JSON body:",
|
|
7400
|
+
" {",
|
|
7401
|
+
" \"apply\": true,",
|
|
7402
|
+
" \"profile_id\": \"prof_abc123\"",
|
|
7403
|
+
" }"
|
|
7404
|
+
].join("\n")],
|
|
7405
|
+
|
|
7406
|
+
["prospects refresh-queue", [
|
|
7407
|
+
"Usage:",
|
|
7408
|
+
` ${PROSPECTS_REFRESH_QUEUE_USAGE.slice("Usage: ".length)}`,
|
|
7409
|
+
"",
|
|
7410
|
+
"Status: implemented",
|
|
7411
|
+
"",
|
|
7412
|
+
"Purpose:",
|
|
7413
|
+
" Clear stale next-action coach and operator draft cache for one account prospect, then rebuild the queue row.",
|
|
7414
|
+
"",
|
|
7415
|
+
"Behavior:",
|
|
7416
|
+
" Defaults to a dry-run showing coach-cache and draft-cache state.",
|
|
7417
|
+
" Pass --apply to delete this prospect's account-scoped ProspectDraft rows, clear AccountProspect coach cache, and force the queue refresher.",
|
|
7418
|
+
"",
|
|
7419
|
+
"API:",
|
|
7420
|
+
" POST /api/v1/accounts/:account_id/prospects/:id/refresh_queue.json",
|
|
7421
|
+
"",
|
|
7422
|
+
"JSON body:",
|
|
7423
|
+
" {",
|
|
7424
|
+
" \"apply\": true",
|
|
7425
|
+
" }"
|
|
7426
|
+
].join("\n")],
|
|
7427
|
+
|
|
7286
7428
|
["prospects reject", [
|
|
7287
7429
|
"Usage:",
|
|
7288
7430
|
` ${PROSPECTS_REJECT_USAGE.slice("Usage: ".length)}`,
|