@audienti/cli 0.1.32 → 0.1.34
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 +18 -0
- package/README.md +32 -0
- package/package.json +1 -1
- package/skills/audienti/SKILL.md +1 -0
- package/src/api-client.js +18 -0
- package/src/cli.js +244 -33
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.34] - 2026-08-17
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `audienti icps update <icp_id> --payload <file.json>` for rich ICP facet patches using the same payload shape as ICP creation.
|
|
12
|
+
- Surface executable motion configuration validity in `audienti motions status`, including missing outbound signals and missing LOPA tracked profile URLs.
|
|
13
|
+
- Add outbound motion signal configuration to `audienti motions create --payload` and `audienti motions update <motn_id> --payload <file.json>`, including scoped company/person/both signal rows.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Default omitted inbound motion channels to LinkedIn-only when motions are created through the CLI/API contract; Reddit remains explicit opt-in.
|
|
18
|
+
|
|
19
|
+
## [0.1.33] - 2026-08-13
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Add `audienti motions quick-start --url <company_url>` for URL-generated quick-start drafts, with optional `--wait --confirm` motion setup and discovery launch.
|
|
24
|
+
|
|
7
25
|
## [0.1.32] - 2026-08-11
|
|
8
26
|
|
|
9
27
|
### Added
|
package/README.md
CHANGED
|
@@ -139,8 +139,10 @@ audienti operator next --plan
|
|
|
139
139
|
audienti writer test-run <prsp_id>
|
|
140
140
|
audienti motions analytics <motn_id>
|
|
141
141
|
audienti motions run-discovery <motn_id>
|
|
142
|
+
audienti motions quick-start --url https://example.com --wait --confirm
|
|
142
143
|
audienti motions update <motn_id> --status paused
|
|
143
144
|
audienti motions update <motn_id> --own-post-engagement true
|
|
145
|
+
audienti motions update <motn_id> --payload motion-signals.json
|
|
144
146
|
audienti motions activate <motn_id>
|
|
145
147
|
audienti motions delete <motn_id> --confirm yes
|
|
146
148
|
audienti content programs
|
|
@@ -248,6 +250,36 @@ used by the operator surface:
|
|
|
248
250
|
audienti motions run-discovery <motn_id>
|
|
249
251
|
```
|
|
250
252
|
|
|
253
|
+
To check whether a motion has executable configuration before preparing,
|
|
254
|
+
activating, or running discovery:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
audienti motions status <motn_id>
|
|
258
|
+
audienti motions status <motn_id> --json
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The JSON response includes `executable_configuration.valid` plus a reason when
|
|
262
|
+
the config is incomplete, such as missing outbound signals or missing LOPA
|
|
263
|
+
tracked profile URLs.
|
|
264
|
+
|
|
265
|
+
To create and launch a quick-start motion from a company URL:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
audienti motions quick-start --url https://example.com --wait --confirm
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
To create or update an ICP from a rich JSON payload:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
audienti icps create --payload icp.json
|
|
275
|
+
audienti icps update <icp_id> --payload icp-patch.json
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
`icps update --payload` accepts the same human-readable facet keys as create.
|
|
279
|
+
Supplied facet collections, such as `company_sizes_attributes`, replace that
|
|
280
|
+
collection in place; omitted fields and collections remain unchanged. Invalid
|
|
281
|
+
lookup values fail server-side without partially applying the patch.
|
|
282
|
+
|
|
251
283
|
To audit one account user's outbound actions, optionally narrowed to one motion
|
|
252
284
|
and one AccountProspect.created_at cohort:
|
|
253
285
|
|
package/package.json
CHANGED
package/skills/audienti/SKILL.md
CHANGED
|
@@ -100,6 +100,7 @@ audienti prospects unlock <prsp_id> --json
|
|
|
100
100
|
audienti users activity me --window 7d --json
|
|
101
101
|
audienti prospects import-batch --file prospects.csv --motion <motn_id> --assigned-user me --json
|
|
102
102
|
audienti lists create --name "Target list" --json
|
|
103
|
+
audienti motions quick-start --url https://example.com --wait --confirm --json
|
|
103
104
|
audienti motions update <motn_id> --status paused --json
|
|
104
105
|
audienti motions activate <motn_id> --json
|
|
105
106
|
audienti motions delete <motn_id> --confirm yes --json
|
package/src/api-client.js
CHANGED
|
@@ -375,6 +375,24 @@ export class AudientiClient {
|
|
|
375
375
|
});
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
createQuickStart(accountId, body) {
|
|
379
|
+
return this.requestJson(accountPath(accountId, ["quick_start"]), {
|
|
380
|
+
method: "POST",
|
|
381
|
+
body
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
quickStart(accountId, draftId) {
|
|
386
|
+
return this.requestJson(accountPath(accountId, ["quick_start", draftId]));
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
confirmQuickStart(accountId, draftId, body = {}) {
|
|
390
|
+
return this.requestJson(accountPath(accountId, ["quick_start", draftId, "confirm"]), {
|
|
391
|
+
method: "POST",
|
|
392
|
+
body
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
378
396
|
motionProspects(accountId, motionId, query = {}) {
|
|
379
397
|
return this.requestJson(accountPath(accountId, ["motions", motionId, "prospects"], query));
|
|
380
398
|
}
|
package/src/cli.js
CHANGED
|
@@ -72,7 +72,7 @@ const OFFERS_DELETE_USAGE = "Usage: audienti offers delete <offr_id> --confirm <
|
|
|
72
72
|
const WRITER_TEST_RUN_USAGE = "Usage: audienti writer test-run <prsp_id> [--json] [--mode <plan|report|step>] [--branch <both|no-accept|accepted>] [--step <step_key|row_number>] [--report <rprt_id>] [--no-wait] [--timeout-seconds <n>] [--poll-interval-seconds <n>] [--account <acct_id>]";
|
|
73
73
|
const WRITER_TEST_RUN_SHOW_USAGE = "Usage: audienti writer test-run show <prsp_id> <rprt_id> [--json] [--account <acct_id>]";
|
|
74
74
|
const MOTIONS_ANALYTICS_USAGE = "Usage: audienti motions analytics <motn_id> [--window 30d] [--json] [--account <acct_id>]";
|
|
75
|
-
const MOTIONS_UPDATE_USAGE = "Usage: audienti motions update <motn_id> [--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] [--json] [--account <acct_id>]";
|
|
75
|
+
const MOTIONS_UPDATE_USAGE = "Usage: audienti motions update <motn_id> ([--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] | --payload <file.json>) [--json] [--account <acct_id>]";
|
|
76
76
|
const CONTENT_PROGRAMS_USAGE = "Usage: audienti content programs [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
77
77
|
const CONTENT_PLAN_USAGE = "Usage: audienti content plan <cprg_id> [--week <n>] [--due] [--json] [--account <acct_id>]";
|
|
78
78
|
const CONTENT_SHOW_USAGE = "Usage: audienti content show <cpwi_id> [--json] [--account <acct_id>]";
|
|
@@ -89,8 +89,9 @@ const MOTIONS_DELETE_USAGE = "Usage: audienti motions delete <motn_id> --confirm
|
|
|
89
89
|
const MOTIONS_CLONE_USAGE = "Usage: audienti motions clone <motn_id> --name <text> [--json] [--account <acct_id>]";
|
|
90
90
|
const MOTIONS_MOVE_PROSPECTS_USAGE = "Usage: audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...] [--json] [--account <acct_id>]";
|
|
91
91
|
const MOTIONS_RUN_DISCOVERY_USAGE = "Usage: audienti motions run-discovery <motn_id> [--target-count <n>] [--json] [--account <acct_id>]";
|
|
92
|
+
const MOTIONS_QUICK_START_USAGE = "Usage: audienti motions quick-start --url <company_url> [--principal <account_user_id|me>] [--feedback <text>] [--offer-type <type>] [--force] [--confirm] [--wait] [--timeout-seconds <n>] [--poll-interval-seconds <n>] [--json] [--account <acct_id>]";
|
|
92
93
|
const ICPS_SHOW_USAGE = "Usage: audienti icps show <icp_id> [--json] [--account <acct_id>]";
|
|
93
|
-
const ICPS_UPDATE_USAGE = "Usage: audienti icps update <icp_id> [--name <text>] [--notes <text>] [--discovery-keyword <text>] [--tags <tag[,tag...]>] [--json] [--account <acct_id>]";
|
|
94
|
+
const ICPS_UPDATE_USAGE = "Usage: audienti icps update <icp_id> ([--name <text>] [--notes <text>] [--discovery-keyword <text>] [--tags <tag[,tag...]>] | --payload <file.json>) [--json] [--account <acct_id>]";
|
|
94
95
|
const ICPS_ADD_TAG_USAGE = "Usage: audienti icps add-tag <icp_id> <tag> [--json] [--account <acct_id>]";
|
|
95
96
|
const ICPS_REMOVE_TAG_USAGE = "Usage: audienti icps remove-tag <icp_id> <tag> [--json] [--account <acct_id>]";
|
|
96
97
|
const LISTS_ADD_TAG_USAGE = "Usage: audienti lists add-tag <list_id> <tag> [--json] [--account <acct_id>]";
|
|
@@ -248,6 +249,7 @@ async function dispatch(argv, context) {
|
|
|
248
249
|
if (normalizedResource === "motions" && action === "clone") return motionsClone(rest, context, { accountOverride });
|
|
249
250
|
if (normalizedResource === "motions" && action === "move-prospects") return motionsMoveProspects(rest, context, { accountOverride });
|
|
250
251
|
if (normalizedResource === "motions" && action === "run-discovery") return motionsRunDiscovery(rest, context, { accountOverride });
|
|
252
|
+
if (normalizedResource === "motions" && action === "quick-start") return motionsQuickStart(rest, context, { accountOverride });
|
|
251
253
|
if (normalizedResource === "content" && action === "programs") return contentPrograms(rest, context, { accountOverride });
|
|
252
254
|
if (normalizedResource === "content" && action === "plan") return contentPlan(rest, context, { accountOverride });
|
|
253
255
|
if (normalizedResource === "content" && action === "show") return contentShow(rest, context, { accountOverride });
|
|
@@ -1028,25 +1030,19 @@ async function icpsCreate(args, context, { accountOverride } = {}) {
|
|
|
1028
1030
|
async function icpsUpdate(args, context, { accountOverride } = {}) {
|
|
1029
1031
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1030
1032
|
...jsonOptions(),
|
|
1033
|
+
payload: { type: "string" },
|
|
1031
1034
|
name: { type: "string" },
|
|
1032
1035
|
notes: { type: "string" },
|
|
1033
1036
|
tags: { type: "string" },
|
|
1034
1037
|
"discovery-keyword": { type: "string" }
|
|
1035
1038
|
});
|
|
1036
|
-
const hasUpdateField = values.
|
|
1039
|
+
const hasUpdateField = values.payload || icpSimpleFieldsPresent(values);
|
|
1037
1040
|
if (positionals.length !== 1 || !hasUpdateField) {
|
|
1038
1041
|
throw new CommandError(ICPS_UPDATE_USAGE);
|
|
1039
1042
|
}
|
|
1040
1043
|
|
|
1041
1044
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1042
|
-
const icp = await client.updateIcp(accountId, positionals[0], {
|
|
1043
|
-
icp: compactObject({
|
|
1044
|
-
name: values.name,
|
|
1045
|
-
notes: values.notes,
|
|
1046
|
-
discovery_keyword: values["discovery-keyword"],
|
|
1047
|
-
tags: values.tags !== undefined ? tagList(values.tags) : undefined
|
|
1048
|
-
})
|
|
1049
|
-
});
|
|
1045
|
+
const icp = await client.updateIcp(accountId, positionals[0], { icp: await icpUpdatePayload(values) });
|
|
1050
1046
|
if (values.json) return writeJson(context.stdout, icp);
|
|
1051
1047
|
|
|
1052
1048
|
writeLine(context.stdout, `Updated ICP ${display(icp?.name)} (${display(icp?.prefix_id)}).`);
|
|
@@ -1543,6 +1539,55 @@ async function motionsRunDiscovery(args, context, { accountOverride } = {}) {
|
|
|
1543
1539
|
renderMotionDiscoveryRun(payload, context);
|
|
1544
1540
|
}
|
|
1545
1541
|
|
|
1542
|
+
async function motionsQuickStart(args, context, { accountOverride } = {}) {
|
|
1543
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1544
|
+
...jsonOptions(),
|
|
1545
|
+
url: { type: "string" },
|
|
1546
|
+
principal: { type: "string" },
|
|
1547
|
+
feedback: { type: "string" },
|
|
1548
|
+
"offer-type": { type: "string" },
|
|
1549
|
+
force: { type: "boolean" },
|
|
1550
|
+
confirm: { type: "boolean" },
|
|
1551
|
+
wait: { type: "boolean" },
|
|
1552
|
+
"timeout-seconds": { type: "string" },
|
|
1553
|
+
"poll-interval-seconds": { type: "string" }
|
|
1554
|
+
});
|
|
1555
|
+
if (positionals.length > 0 || !values.url) throw new CommandError(MOTIONS_QUICK_START_USAGE);
|
|
1556
|
+
|
|
1557
|
+
const timeoutSeconds = normalizeOptionalPositiveInteger(values["timeout-seconds"], "--timeout-seconds") || DEFAULT_LOOKUP_TIMEOUT_SECONDS;
|
|
1558
|
+
const pollIntervalSeconds = normalizeOptionalPositiveInteger(values["poll-interval-seconds"], "--poll-interval-seconds") || DEFAULT_LOOKUP_POLL_INTERVAL_SECONDS;
|
|
1559
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1560
|
+
const requestBody = {
|
|
1561
|
+
quick_start: compactObject({
|
|
1562
|
+
company_url: values.url,
|
|
1563
|
+
principal_account_user_id: values.principal,
|
|
1564
|
+
feedback: values.feedback,
|
|
1565
|
+
offer_type: values["offer-type"],
|
|
1566
|
+
force: values.force || undefined
|
|
1567
|
+
})
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
let draft = await client.createQuickStart(accountId, requestBody);
|
|
1571
|
+
if (values.wait && !quickStartReady(draft)) {
|
|
1572
|
+
draft = await waitForQuickStartDraft(client, accountId, draft, context, { timeoutSeconds, pollIntervalSeconds });
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
if (values.confirm) {
|
|
1576
|
+
if (!quickStartReady(draft)) {
|
|
1577
|
+
throw new CommandError(`Quick-start draft ${display(draft?.id)} is ${display(draft?.status)}. Re-run with --wait or confirm after it is ready.`);
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
const payload = await client.confirmQuickStart(accountId, draft.id, {});
|
|
1581
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1582
|
+
|
|
1583
|
+
renderQuickStartConfirmation(payload, context);
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
if (values.json) return writeJson(context.stdout, draft);
|
|
1588
|
+
renderQuickStartDraft(draft, context);
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1546
1591
|
async function motionsAnalytics(args, context, { accountOverride } = {}) {
|
|
1547
1592
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1548
1593
|
...jsonOptions(),
|
|
@@ -1632,7 +1677,7 @@ async function motionsCreate(args, context, { accountOverride } = {}) {
|
|
|
1632
1677
|
}
|
|
1633
1678
|
|
|
1634
1679
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1635
|
-
const payload = await readJsonPayload(values.payload);
|
|
1680
|
+
const payload = normalizeMotionCreatePayload(await readJsonPayload(values.payload));
|
|
1636
1681
|
const created = await client.createMotion(accountId, { motion: payload });
|
|
1637
1682
|
if (values.json) return writeJson(context.stdout, created);
|
|
1638
1683
|
|
|
@@ -1640,6 +1685,14 @@ async function motionsCreate(args, context, { accountOverride } = {}) {
|
|
|
1640
1685
|
renderMotion(created, context);
|
|
1641
1686
|
}
|
|
1642
1687
|
|
|
1688
|
+
function normalizeMotionCreatePayload(payload) {
|
|
1689
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return payload;
|
|
1690
|
+
if (String(payload.kind || "").trim().toLowerCase() !== "inbound") return payload;
|
|
1691
|
+
if (Object.prototype.hasOwnProperty.call(payload, "inbound_channels")) return payload;
|
|
1692
|
+
|
|
1693
|
+
return { ...payload, inbound_channels: ["linkedin"] };
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1643
1696
|
async function motionsDelete(args, context, { accountOverride } = {}) {
|
|
1644
1697
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1645
1698
|
...jsonOptions(),
|
|
@@ -1660,30 +1713,44 @@ async function motionsDelete(args, context, { accountOverride } = {}) {
|
|
|
1660
1713
|
async function motionsUpdate(args, context, { accountOverride } = {}) {
|
|
1661
1714
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1662
1715
|
...jsonOptions(),
|
|
1716
|
+
payload: { type: "string" },
|
|
1663
1717
|
status: { type: "string" },
|
|
1664
1718
|
tags: { type: "string" },
|
|
1665
1719
|
"own-post-engagement": { type: "string" }
|
|
1666
1720
|
});
|
|
1667
|
-
const hasUpdateField = values.
|
|
1721
|
+
const hasUpdateField = values.payload || motionSimpleFieldsPresent(values);
|
|
1668
1722
|
if (positionals.length !== 1 || !hasUpdateField) {
|
|
1669
1723
|
throw new CommandError(MOTIONS_UPDATE_USAGE);
|
|
1670
1724
|
}
|
|
1671
1725
|
|
|
1672
|
-
const normalizedStatus = normalizeMotionStatus(values.status);
|
|
1673
|
-
const motionAttributes = compactObject({
|
|
1674
|
-
status: normalizedStatus,
|
|
1675
|
-
play_tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
1676
|
-
own_post_engagement: values["own-post-engagement"] !== undefined ? parseBooleanString(values["own-post-engagement"], "--own-post-engagement") : undefined
|
|
1677
|
-
});
|
|
1678
|
-
|
|
1679
1726
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1680
|
-
const motion = await client.updateMotion(accountId, positionals[0], { motion:
|
|
1727
|
+
const motion = await client.updateMotion(accountId, positionals[0], { motion: await motionUpdatePayload(values) });
|
|
1681
1728
|
if (values.json) return writeJson(context.stdout, motion);
|
|
1682
1729
|
|
|
1683
1730
|
writeLine(context.stdout, `Updated motion ${display(motion?.name)} (${display(motion?.prefix_id)}).`);
|
|
1684
1731
|
renderMotion(motion, context);
|
|
1685
1732
|
}
|
|
1686
1733
|
|
|
1734
|
+
async function motionUpdatePayload(values) {
|
|
1735
|
+
if (values.payload) {
|
|
1736
|
+
if (motionSimpleFieldsPresent(values)) {
|
|
1737
|
+
throw new CommandError("Choose one motion input mode: either --payload <file.json> or the simple --status/--tags/--own-post-engagement flags.");
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
return readJsonPayload(values.payload);
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
return compactObject({
|
|
1744
|
+
status: normalizeMotionStatus(values.status),
|
|
1745
|
+
play_tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
1746
|
+
own_post_engagement: values["own-post-engagement"] !== undefined ? parseBooleanString(values["own-post-engagement"], "--own-post-engagement") : undefined
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
function motionSimpleFieldsPresent(values) {
|
|
1751
|
+
return Boolean(values.status) || values.tags !== undefined || values["own-post-engagement"] !== undefined;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1687
1754
|
async function motionsStatusShortcut(action, args, context, { accountOverride } = {}) {
|
|
1688
1755
|
const usage = `Usage: audienti motions ${action} <motn_id> [--json] [--account <acct_id>]`;
|
|
1689
1756
|
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
@@ -3524,7 +3591,7 @@ function filterRecordsByTag(records, value, field) {
|
|
|
3524
3591
|
|
|
3525
3592
|
async function icpCreatePayload(values) {
|
|
3526
3593
|
if (values.payload) {
|
|
3527
|
-
if (values
|
|
3594
|
+
if (icpSimpleFieldsPresent(values)) {
|
|
3528
3595
|
throw new CommandError("Choose one ICP input mode: either --payload <file.json> or the simple --name/--notes/--discovery-keyword/tags flags.");
|
|
3529
3596
|
}
|
|
3530
3597
|
|
|
@@ -3543,6 +3610,27 @@ async function icpCreatePayload(values) {
|
|
|
3543
3610
|
});
|
|
3544
3611
|
}
|
|
3545
3612
|
|
|
3613
|
+
async function icpUpdatePayload(values) {
|
|
3614
|
+
if (values.payload) {
|
|
3615
|
+
if (icpSimpleFieldsPresent(values)) {
|
|
3616
|
+
throw new CommandError("Choose one ICP input mode: either --payload <file.json> or the simple --name/--notes/--discovery-keyword/tags flags.");
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
return readJsonPayload(values.payload);
|
|
3620
|
+
}
|
|
3621
|
+
|
|
3622
|
+
return compactObject({
|
|
3623
|
+
name: values.name,
|
|
3624
|
+
notes: values.notes,
|
|
3625
|
+
tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
3626
|
+
discovery_keyword: values["discovery-keyword"]
|
|
3627
|
+
});
|
|
3628
|
+
}
|
|
3629
|
+
|
|
3630
|
+
function icpSimpleFieldsPresent(values) {
|
|
3631
|
+
return Boolean(values.name) || values.notes !== undefined || values.tags !== undefined || values["discovery-keyword"] !== undefined;
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3546
3634
|
async function prospectNotePayload(values, { forcedType, usageText } = {}) {
|
|
3547
3635
|
const engagementKey = values["engagement-type"] || values["engagement-key"];
|
|
3548
3636
|
|
|
@@ -4272,6 +4360,7 @@ function renderMotion(motion, context) {
|
|
|
4272
4360
|
writeLine(context.stdout, `Motion: ${display(motion?.name)} (${display(motion?.prefix_id)})`);
|
|
4273
4361
|
writeLine(context.stdout, `Status: ${display(motion?.status)}`);
|
|
4274
4362
|
writeLine(context.stdout, `Kind: ${display(motion?.kind)}`);
|
|
4363
|
+
renderExecutableConfiguration(motion?.executable_configuration, context);
|
|
4275
4364
|
if (motion?.offer?.name) writeLine(context.stdout, `Offer: ${motion.offer.name} (${display(motion.offer.prefix_id)})`);
|
|
4276
4365
|
if (motion?.icp?.name) writeLine(context.stdout, `ICP: ${motion.icp.name} (${display(motion.icp.prefix_id)})`);
|
|
4277
4366
|
if (motion?.list?.name) writeLine(context.stdout, `List: ${motion.list.name} (${display(motion.list.prefix_id)})`);
|
|
@@ -4342,10 +4431,23 @@ function renderMotionStatus(status, context) {
|
|
|
4342
4431
|
writeLine(context.stdout, `Motion: ${display(status?.name)} (${display(status?.prefix_id)})`);
|
|
4343
4432
|
writeLine(context.stdout, `State: ${display(status?.state)}`);
|
|
4344
4433
|
writeLine(context.stdout, `Reason: ${display(status?.reason_label || status?.reason_key)}`);
|
|
4434
|
+
renderExecutableConfiguration(status?.executable_configuration, context);
|
|
4345
4435
|
if (status?.description) writeLine(context.stdout, status.description);
|
|
4346
4436
|
if (status?.action?.label) writeLine(context.stdout, `Action: ${status.action.label}`);
|
|
4347
4437
|
}
|
|
4348
4438
|
|
|
4439
|
+
function renderExecutableConfiguration(config, context) {
|
|
4440
|
+
if (!config || typeof config !== "object") return;
|
|
4441
|
+
|
|
4442
|
+
writeLine(context.stdout, `Valid config: ${config.valid ? "yes" : "no"}`);
|
|
4443
|
+
if (!config.valid && (config.reason_label || config.reason_key)) {
|
|
4444
|
+
writeLine(context.stdout, `Config reason: ${display(config.reason_label || config.reason_key)}`);
|
|
4445
|
+
}
|
|
4446
|
+
if (!config.valid && config.description) {
|
|
4447
|
+
writeLine(context.stdout, `Config detail: ${config.description}`);
|
|
4448
|
+
}
|
|
4449
|
+
}
|
|
4450
|
+
|
|
4349
4451
|
function renderProspects(payload, context, { wide = false, profiles = false } = {}) {
|
|
4350
4452
|
const prospects = Array.isArray(payload?.prospects) ? payload.prospects : [];
|
|
4351
4453
|
if (prospects.length === 0) return writeLine(context.stdout, "No prospects found.");
|
|
@@ -5324,6 +5426,45 @@ function renderMotionDiscoveryRun(payload, context) {
|
|
|
5324
5426
|
writeLine(context.stdout, `Target count: ${display(payload?.target_count)}`);
|
|
5325
5427
|
}
|
|
5326
5428
|
|
|
5429
|
+
function renderQuickStartDraft(draft, context) {
|
|
5430
|
+
writeLine(context.stdout, `Quick-start draft ${display(draft?.id)} is ${display(draft?.status)}.`);
|
|
5431
|
+
writeLine(context.stdout, `URL: ${display(draft?.normalized_url)}`);
|
|
5432
|
+
if (draft?.principal_account_user) writeLine(context.stdout, `Principal: ${accountUserLabel(draft.principal_account_user)}`);
|
|
5433
|
+
if (draft?.expires_at) writeLine(context.stdout, `Expires: ${draft.expires_at}`);
|
|
5434
|
+
if (draft?.error) writeLine(context.stdout, `Error: ${draft.error}`);
|
|
5435
|
+
if (quickStartReady(draft)) writeLine(context.stdout, `Confirm: audienti motions quick-start --url ${draft.normalized_url} --confirm`);
|
|
5436
|
+
}
|
|
5437
|
+
|
|
5438
|
+
function renderQuickStartConfirmation(payload, context) {
|
|
5439
|
+
const motion = payload?.motion || {};
|
|
5440
|
+
writeLine(context.stdout, `Quick-start motion ${display(entityLabel(motion) || motion.prefix_id)} ${payload?.reused ? "reused" : "created"}.`);
|
|
5441
|
+
writeLine(context.stdout, `Motion status: ${display(motion.status)}`);
|
|
5442
|
+
writeLine(context.stdout, `Reservation: ${display(payload?.reservation?.status)} / ${display(payload?.reservation?.launch_status)}`);
|
|
5443
|
+
if (payload?.reservation?.launch_reason) writeLine(context.stdout, `Launch reason: ${payload.reservation.launch_reason}`);
|
|
5444
|
+
}
|
|
5445
|
+
|
|
5446
|
+
function quickStartReady(draft) {
|
|
5447
|
+
return draft?.ready === true || draft?.status === "ready";
|
|
5448
|
+
}
|
|
5449
|
+
|
|
5450
|
+
function quickStartTerminal(draft) {
|
|
5451
|
+
return quickStartReady(draft) || draft?.status === "failed";
|
|
5452
|
+
}
|
|
5453
|
+
|
|
5454
|
+
async function waitForQuickStartDraft(client, accountId, initialDraft, context, { timeoutSeconds, pollIntervalSeconds }) {
|
|
5455
|
+
let draft = initialDraft;
|
|
5456
|
+
const deadline = context.now().getTime() + timeoutSeconds * 1000;
|
|
5457
|
+
|
|
5458
|
+
while (!quickStartTerminal(draft)) {
|
|
5459
|
+
if (context.now().getTime() >= deadline) return draft;
|
|
5460
|
+
|
|
5461
|
+
await context.sleep(pollIntervalSeconds * 1000);
|
|
5462
|
+
draft = await client.quickStart(accountId, draft.id);
|
|
5463
|
+
}
|
|
5464
|
+
|
|
5465
|
+
return draft;
|
|
5466
|
+
}
|
|
5467
|
+
|
|
5327
5468
|
function renderAnalyticsDashboard(payload, context) {
|
|
5328
5469
|
writeLine(context.stdout, `Dashboard analytics (${display(payload?.cohort?.label, "selected cohort")})`);
|
|
5329
5470
|
if (payload?.cohort) {
|
|
@@ -6145,9 +6286,11 @@ const HELP_TOPICS = new Map([
|
|
|
6145
6286
|
" audienti motions show <motn_id>",
|
|
6146
6287
|
" audienti motions analytics <motn_id>",
|
|
6147
6288
|
" audienti motions run-discovery <motn_id>",
|
|
6289
|
+
" audienti motions quick-start --url <company_url> --confirm --wait",
|
|
6148
6290
|
" audienti motions prospects <motn_id>",
|
|
6149
6291
|
" audienti motions create --payload <file.json>",
|
|
6150
6292
|
" audienti motions update <motn_id> [--status <state>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>]",
|
|
6293
|
+
" audienti motions update <motn_id> --payload <file.json>",
|
|
6151
6294
|
" audienti motions add-tag <motn_id> <tag>",
|
|
6152
6295
|
" audienti motions remove-tag <motn_id> <tag>",
|
|
6153
6296
|
" audienti motions activate <motn_id>",
|
|
@@ -6202,7 +6345,7 @@ const HELP_TOPICS = new Map([
|
|
|
6202
6345
|
" audienti offers delete <offr_id> --confirm <yes|true|Y|y>",
|
|
6203
6346
|
" audienti icps list [--tag <tag>]",
|
|
6204
6347
|
" audienti icps show <icp_id>",
|
|
6205
|
-
" audienti icps update <icp_id> [--tags <tag[,tag...]>]",
|
|
6348
|
+
" audienti icps update <icp_id> [--tags <tag[,tag...]> | --payload <file.json>]",
|
|
6206
6349
|
" audienti icps add-tag <icp_id> <tag>",
|
|
6207
6350
|
" audienti icps remove-tag <icp_id> <tag>",
|
|
6208
6351
|
" audienti companies search --query <text>",
|
|
@@ -6679,7 +6822,7 @@ const HELP_TOPICS = new Map([
|
|
|
6679
6822
|
" audienti icps list [--tag <tag>] [--json]",
|
|
6680
6823
|
" audienti icps show <icp_id> [--json]",
|
|
6681
6824
|
" audienti icps create (--name <text> | --payload <file.json>) [--json]",
|
|
6682
|
-
" audienti icps update <icp_id> [--tags <tag[,tag...]>] [--json]",
|
|
6825
|
+
" audienti icps update <icp_id> ([--tags <tag[,tag...]>] | --payload <file.json>) [--json]",
|
|
6683
6826
|
" audienti icps add-tag <icp_id> <tag> [--json]",
|
|
6684
6827
|
" audienti icps remove-tag <icp_id> <tag> [--json]",
|
|
6685
6828
|
"",
|
|
@@ -6772,12 +6915,12 @@ const HELP_TOPICS = new Map([
|
|
|
6772
6915
|
|
|
6773
6916
|
["icps update", [
|
|
6774
6917
|
"Usage:",
|
|
6775
|
-
"
|
|
6918
|
+
` ${ICPS_UPDATE_USAGE.slice("Usage: ".length)}`,
|
|
6776
6919
|
"",
|
|
6777
6920
|
"Status: implemented",
|
|
6778
6921
|
"",
|
|
6779
6922
|
"Purpose:",
|
|
6780
|
-
" Update simple ICP fields
|
|
6923
|
+
" Update simple ICP fields, replace the ICP's full tag set, or apply a rich ICP payload patch.",
|
|
6781
6924
|
"",
|
|
6782
6925
|
"Input shape:",
|
|
6783
6926
|
" icp_id: icpp_ prefixed id or integer id",
|
|
@@ -6785,15 +6928,30 @@ const HELP_TOPICS = new Map([
|
|
|
6785
6928
|
" notes: string | optional",
|
|
6786
6929
|
" discovery_keyword: string | optional",
|
|
6787
6930
|
" tags: comma-separated tag list | optional",
|
|
6931
|
+
" payload: file.json | optional full or partial ICP object using the account API create shape",
|
|
6932
|
+
"",
|
|
6933
|
+
"Behavior:",
|
|
6934
|
+
" Choose either --payload or simple flags. Supplied facet collections replace that collection in place; omitted fields and facet collections remain unchanged.",
|
|
6935
|
+
" Human-readable lookup-backed facet names are resolved by the account API. Invalid lookup values fail with 422 and no partial mutation.",
|
|
6788
6936
|
"",
|
|
6789
6937
|
"API:",
|
|
6790
6938
|
" PATCH /api/v1/accounts/:account_id/icps/:id.json",
|
|
6791
6939
|
"",
|
|
6792
|
-
"JSON body:",
|
|
6940
|
+
"Simple JSON body:",
|
|
6793
6941
|
" {",
|
|
6794
6942
|
" \"icp\": {",
|
|
6795
6943
|
" \"tags\": [\"enterprise\", \"renewal\"]",
|
|
6796
6944
|
" }",
|
|
6945
|
+
" }",
|
|
6946
|
+
"",
|
|
6947
|
+
"Payload file example:",
|
|
6948
|
+
" {",
|
|
6949
|
+
" \"company_sizes_attributes\": [",
|
|
6950
|
+
" {\"name\": \"1001-5000 employees\"}",
|
|
6951
|
+
" ],",
|
|
6952
|
+
" \"seniorities_attributes\": [",
|
|
6953
|
+
" {\"name\": \"CXO\"}",
|
|
6954
|
+
" ]",
|
|
6797
6955
|
" }"
|
|
6798
6956
|
].join("\n")],
|
|
6799
6957
|
|
|
@@ -7393,11 +7551,12 @@ const HELP_TOPICS = new Map([
|
|
|
7393
7551
|
" audienti motions show <motn_id> [--json]",
|
|
7394
7552
|
" audienti motions status <motn_id> [--json]",
|
|
7395
7553
|
" audienti motions run-discovery <motn_id> [--target-count <n>] [--json]",
|
|
7554
|
+
" audienti motions quick-start --url <company_url> [--confirm] [--wait] [--json]",
|
|
7396
7555
|
" audienti motions analytics <motn_id> [--window 30d] [--json]",
|
|
7397
7556
|
" audienti motions prospects <motn_id> [--json]",
|
|
7398
7557
|
" audienti motions add-prospects <motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
7399
7558
|
" audienti motions create --payload <file.json> [--json]",
|
|
7400
|
-
" audienti motions update <motn_id> [--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] [--json]",
|
|
7559
|
+
" audienti motions update <motn_id> ([--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] | --payload <file.json>) [--json]",
|
|
7401
7560
|
" audienti motions add-tag <motn_id> <tag> [--json]",
|
|
7402
7561
|
" audienti motions remove-tag <motn_id> <tag> [--json]",
|
|
7403
7562
|
" audienti motions activate <motn_id> [--json]",
|
|
@@ -7407,7 +7566,7 @@ const HELP_TOPICS = new Map([
|
|
|
7407
7566
|
" audienti motions clone <motn_id> --name <text> [--json]",
|
|
7408
7567
|
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
7409
7568
|
"",
|
|
7410
|
-
"Status: read, create, status update, delete, clone, status, discovery launch, and prospect attachment commands implemented",
|
|
7569
|
+
"Status: read, create, quick-start, status update, delete, clone, status, discovery launch, and prospect attachment commands implemented",
|
|
7411
7570
|
"",
|
|
7412
7571
|
"CLI synonym:",
|
|
7413
7572
|
" `plays` is accepted anywhere `motions` is accepted",
|
|
@@ -7495,6 +7654,7 @@ const HELP_TOPICS = new Map([
|
|
|
7495
7654
|
" state: healthy_idle | broken",
|
|
7496
7655
|
" reason_key: string",
|
|
7497
7656
|
" reason_label: string",
|
|
7657
|
+
" executable_configuration: { valid: boolean, reason_key: string | null, reason_label: string | null, description: string | null }",
|
|
7498
7658
|
" description: string",
|
|
7499
7659
|
" action: { key: string, label: string } | null",
|
|
7500
7660
|
" stats: { target_count, deficit, projected_connectable, capacity, daily_target }",
|
|
@@ -7545,6 +7705,36 @@ const HELP_TOPICS = new Map([
|
|
|
7545
7705
|
" POST /api/v1/accounts/:account_id/motions/:id/run_discovery.json"
|
|
7546
7706
|
].join("\n")],
|
|
7547
7707
|
|
|
7708
|
+
["motions quick-start", [
|
|
7709
|
+
"Usage:",
|
|
7710
|
+
` ${MOTIONS_QUICK_START_USAGE.slice("Usage: ".length)}`,
|
|
7711
|
+
"",
|
|
7712
|
+
"Status: implemented",
|
|
7713
|
+
"",
|
|
7714
|
+
"Purpose:",
|
|
7715
|
+
" Draft a quick-start motion from a company URL, then optionally confirm it into a launched quick-start motion.",
|
|
7716
|
+
"",
|
|
7717
|
+
"Options:",
|
|
7718
|
+
" --url <company_url> Public HTTP(S) URL used by the quick-start drafter.",
|
|
7719
|
+
" --principal <user> Account user id or me. Defaults to the authenticated token user.",
|
|
7720
|
+
" --feedback <text> Optional operator guidance for the draft.",
|
|
7721
|
+
" --offer-type <type> Optional supported offer type hint.",
|
|
7722
|
+
" --force Request a fresh draft when inputs should replace an existing ready draft.",
|
|
7723
|
+
" --confirm Confirm the ready draft into motion setup and discovery launch.",
|
|
7724
|
+
" --wait Poll until the generated draft is ready before returning or confirming.",
|
|
7725
|
+
" --timeout-seconds <n> Maximum wait time. Defaults to 60.",
|
|
7726
|
+
" --poll-interval-seconds <n> Poll cadence. Defaults to 2.",
|
|
7727
|
+
"",
|
|
7728
|
+
"Pipeline:",
|
|
7729
|
+
" POST creates or reuses a QuickStartDraft and enqueues GenerateQuickStartDraftJob when needed.",
|
|
7730
|
+
" POST confirm calls QuickStartOrchestrator, creating ICP, offer, signals, motion, reservation, and discovery launch.",
|
|
7731
|
+
"",
|
|
7732
|
+
"API:",
|
|
7733
|
+
" POST /api/v1/accounts/:account_id/quick_start.json",
|
|
7734
|
+
" GET /api/v1/accounts/:account_id/quick_start/:draft_id.json",
|
|
7735
|
+
" POST /api/v1/accounts/:account_id/quick_start/:draft_id/confirm.json"
|
|
7736
|
+
].join("\n")],
|
|
7737
|
+
|
|
7548
7738
|
["motions prospects", [
|
|
7549
7739
|
"Usage:",
|
|
7550
7740
|
" audienti motions prospects <motn_id> [--json] [--account <acct_id>]",
|
|
@@ -7616,7 +7806,9 @@ const HELP_TOPICS = new Map([
|
|
|
7616
7806
|
" icp_id: icpp_ prefix id | optional",
|
|
7617
7807
|
" list_id: list_ prefix id | optional",
|
|
7618
7808
|
" play_tags: [string] | optional",
|
|
7619
|
-
"
|
|
7809
|
+
" signal_rows: [{ scope: company | person | both, question: string, company_signal_category: string | optional, role_terms: string | optional, posting_language: string | optional, topics: string | optional }] | optional for outbound motions",
|
|
7810
|
+
" signal_questions: newline-delimited company::, person::, or both:: legacy question text | optional for outbound motions",
|
|
7811
|
+
" inbound_channels: [linkedin | reddit] | optional; defaults to [linkedin] for inbound motions",
|
|
7620
7812
|
" lopa_profiles: [{ url: string, source_type: creator | competitor | partner | customer | other }] | optional",
|
|
7621
7813
|
"",
|
|
7622
7814
|
"JSON example:",
|
|
@@ -7671,25 +7863,44 @@ const HELP_TOPICS = new Map([
|
|
|
7671
7863
|
"Status: implemented",
|
|
7672
7864
|
"",
|
|
7673
7865
|
"Purpose:",
|
|
7674
|
-
" Change one motion or play's lifecycle status
|
|
7866
|
+
" Change one motion or play's lifecycle status, replace its tag set, or patch rich motion configuration.",
|
|
7675
7867
|
"",
|
|
7676
7868
|
"Input shape:",
|
|
7677
7869
|
" motn_id: motn_ prefix id",
|
|
7678
7870
|
" status: draft | preparing | active | paused | archived | optional",
|
|
7679
7871
|
" tags: comma-separated tag list | optional",
|
|
7872
|
+
" payload: file.json | optional full or partial motion object using the account API shape",
|
|
7680
7873
|
"",
|
|
7681
7874
|
"Behavior:",
|
|
7682
|
-
" Updates only the provided fields. Sending --tags replaces the motion's full tag set.",
|
|
7875
|
+
" Choose either --payload or simple flags. Updates only the provided fields. Sending --tags replaces the motion's full tag set.",
|
|
7876
|
+
" Payload mode supports outbound signal_rows or legacy signal_questions; supplied rows replace the motion's active ready signals.",
|
|
7683
7877
|
"",
|
|
7684
7878
|
"API:",
|
|
7685
7879
|
" PATCH /api/v1/accounts/:account_id/motions/:id.json",
|
|
7686
7880
|
"",
|
|
7687
|
-
"JSON body:",
|
|
7881
|
+
"Simple JSON body:",
|
|
7688
7882
|
" {",
|
|
7689
7883
|
" \"motion\": {",
|
|
7690
7884
|
" \"status\": \"paused\",",
|
|
7691
7885
|
" \"play_tags\": [\"sarit\", \"pj\"]",
|
|
7692
7886
|
" }",
|
|
7887
|
+
" }",
|
|
7888
|
+
"",
|
|
7889
|
+
"Payload file example:",
|
|
7890
|
+
" {",
|
|
7891
|
+
" \"signal_rows\": [",
|
|
7892
|
+
" {",
|
|
7893
|
+
" \"scope\": \"company\",",
|
|
7894
|
+
" \"question\": \"Is the company hiring revenue operations leaders?\",",
|
|
7895
|
+
" \"company_signal_category\": \"hiring\",",
|
|
7896
|
+
" \"role_terms\": \"Revenue Operations\"",
|
|
7897
|
+
" },",
|
|
7898
|
+
" {",
|
|
7899
|
+
" \"scope\": \"person\",",
|
|
7900
|
+
" \"question\": \"Is the person talking about pipeline quality?\",",
|
|
7901
|
+
" \"topics\": \"pipeline quality\"",
|
|
7902
|
+
" }",
|
|
7903
|
+
" ]",
|
|
7693
7904
|
" }"
|
|
7694
7905
|
].join("\n")],
|
|
7695
7906
|
|