@audienti/cli 0.1.33 → 0.1.35
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 +23 -0
- package/README.md +27 -0
- package/package.json +1 -1
- package/skills/audienti/SKILL.md +4 -0
- package/src/api-client.js +17 -0
- package/src/cli.js +314 -33
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,29 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.35] - 2026-08-18
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `audienti motions abm-companies` commands for listing, adding, and removing motion-scoped positive company filters through the account API.
|
|
12
|
+
- Surface ICP `seniority_match_mode`, motion inbound channels, LOPA profile rows, signal rows, and ABM company filters in CLI/API readbacks.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Reject `posting_language` on non-hiring signal rows instead of accepting a field that cannot persist outside company-scope hiring signals.
|
|
17
|
+
|
|
18
|
+
## [0.1.34] - 2026-08-17
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Add `audienti icps update <icp_id> --payload <file.json>` for rich ICP facet patches using the same payload shape as ICP creation.
|
|
23
|
+
- Surface executable motion configuration validity in `audienti motions status`, including missing outbound signals and missing LOPA tracked profile URLs.
|
|
24
|
+
- 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.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Default omitted inbound motion channels to LinkedIn-only when motions are created through the CLI/API contract; Reddit remains explicit opt-in.
|
|
29
|
+
|
|
7
30
|
## [0.1.33] - 2026-08-13
|
|
8
31
|
|
|
9
32
|
### Added
|
package/README.md
CHANGED
|
@@ -140,8 +140,11 @@ audienti writer test-run <prsp_id>
|
|
|
140
140
|
audienti motions analytics <motn_id>
|
|
141
141
|
audienti motions run-discovery <motn_id>
|
|
142
142
|
audienti motions quick-start --url https://example.com --wait --confirm
|
|
143
|
+
audienti motions abm-companies <motn_id> add --file abm-domains.txt
|
|
144
|
+
audienti motions abm-companies <motn_id> list
|
|
143
145
|
audienti motions update <motn_id> --status paused
|
|
144
146
|
audienti motions update <motn_id> --own-post-engagement true
|
|
147
|
+
audienti motions update <motn_id> --payload motion-signals.json
|
|
145
148
|
audienti motions activate <motn_id>
|
|
146
149
|
audienti motions delete <motn_id> --confirm yes
|
|
147
150
|
audienti content programs
|
|
@@ -249,12 +252,36 @@ used by the operator surface:
|
|
|
249
252
|
audienti motions run-discovery <motn_id>
|
|
250
253
|
```
|
|
251
254
|
|
|
255
|
+
To check whether a motion has executable configuration before preparing,
|
|
256
|
+
activating, or running discovery:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
audienti motions status <motn_id>
|
|
260
|
+
audienti motions status <motn_id> --json
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The JSON response includes `executable_configuration.valid` plus a reason when
|
|
264
|
+
the config is incomplete, such as missing outbound signals or missing LOPA
|
|
265
|
+
tracked profile URLs.
|
|
266
|
+
|
|
252
267
|
To create and launch a quick-start motion from a company URL:
|
|
253
268
|
|
|
254
269
|
```bash
|
|
255
270
|
audienti motions quick-start --url https://example.com --wait --confirm
|
|
256
271
|
```
|
|
257
272
|
|
|
273
|
+
To create or update an ICP from a rich JSON payload:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
audienti icps create --payload icp.json
|
|
277
|
+
audienti icps update <icp_id> --payload icp-patch.json
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
`icps update --payload` accepts the same human-readable facet keys as create.
|
|
281
|
+
Supplied facet collections, such as `company_sizes_attributes`, replace that
|
|
282
|
+
collection in place; omitted fields and collections remain unchanged. Invalid
|
|
283
|
+
lookup values fail server-side without partially applying the patch.
|
|
284
|
+
|
|
258
285
|
To audit one account user's outbound actions, optionally narrowed to one motion
|
|
259
286
|
and one AccountProspect.created_at cohort:
|
|
260
287
|
|
package/package.json
CHANGED
package/skills/audienti/SKILL.md
CHANGED
|
@@ -73,6 +73,8 @@ Useful MCP tools:
|
|
|
73
73
|
mapping URLs.
|
|
74
74
|
- `offers.create`, `icps.create`, and `motions.create` set up the offer, ICP,
|
|
75
75
|
and play.
|
|
76
|
+
- Use `audienti motions abm-companies <motn_id> add --file <txt|json>` to attach
|
|
77
|
+
a positive company filter list for isolated ABM discovery runs.
|
|
76
78
|
- `analytics.stages` returns stage conversion cohorts and stage aging.
|
|
77
79
|
- `analytics.cohort_lists.create` materializes event cohorts as reusable lists.
|
|
78
80
|
|
|
@@ -101,6 +103,8 @@ audienti users activity me --window 7d --json
|
|
|
101
103
|
audienti prospects import-batch --file prospects.csv --motion <motn_id> --assigned-user me --json
|
|
102
104
|
audienti lists create --name "Target list" --json
|
|
103
105
|
audienti motions quick-start --url https://example.com --wait --confirm --json
|
|
106
|
+
audienti motions abm-companies <motn_id> add --file abm-domains.txt --json
|
|
107
|
+
audienti motions abm-companies <motn_id> list --json
|
|
104
108
|
audienti motions update <motn_id> --status paused --json
|
|
105
109
|
audienti motions activate <motn_id> --json
|
|
106
110
|
audienti motions delete <motn_id> --confirm yes --json
|
package/src/api-client.js
CHANGED
|
@@ -290,6 +290,23 @@ export class AudientiClient {
|
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
motionAbmCompanies(accountId, motionId) {
|
|
294
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "abm_companies"]));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
addMotionAbmCompanies(accountId, motionId, body) {
|
|
298
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "abm_companies"]), {
|
|
299
|
+
method: "POST",
|
|
300
|
+
body
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
removeMotionAbmCompany(accountId, motionId, rowId) {
|
|
305
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "abm_companies", rowId]), {
|
|
306
|
+
method: "DELETE"
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
293
310
|
contentPrograms(accountId, query = {}) {
|
|
294
311
|
return this.requestJson(accountPath(accountId, ["content_ops", "programs"], query));
|
|
295
312
|
}
|
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>]";
|
|
@@ -90,8 +90,11 @@ const MOTIONS_CLONE_USAGE = "Usage: audienti motions clone <motn_id> --name <tex
|
|
|
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
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>]";
|
|
93
|
+
const MOTIONS_ABM_COMPANIES_LIST_USAGE = "Usage: audienti motions abm-companies <motn_id> list [--json] [--account <acct_id>]";
|
|
94
|
+
const MOTIONS_ABM_COMPANIES_ADD_USAGE = "Usage: audienti motions abm-companies <motn_id> add (<domain_or_linkedin_url>... | --file <txt|json>) [--json] [--account <acct_id>]";
|
|
95
|
+
const MOTIONS_ABM_COMPANIES_REMOVE_USAGE = "Usage: audienti motions abm-companies <motn_id> remove <row_id> [--json] [--account <acct_id>]";
|
|
93
96
|
const ICPS_SHOW_USAGE = "Usage: audienti icps show <icp_id> [--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...]>] [--json] [--account <acct_id>]";
|
|
97
|
+
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>]";
|
|
95
98
|
const ICPS_ADD_TAG_USAGE = "Usage: audienti icps add-tag <icp_id> <tag> [--json] [--account <acct_id>]";
|
|
96
99
|
const ICPS_REMOVE_TAG_USAGE = "Usage: audienti icps remove-tag <icp_id> <tag> [--json] [--account <acct_id>]";
|
|
97
100
|
const LISTS_ADD_TAG_USAGE = "Usage: audienti lists add-tag <list_id> <tag> [--json] [--account <acct_id>]";
|
|
@@ -237,6 +240,7 @@ async function dispatch(argv, context) {
|
|
|
237
240
|
if (normalizedResource === "motions" && action === "list") return motionsList(rest, context, { accountOverride });
|
|
238
241
|
if (normalizedResource === "motions" && action === "show") return motionsShow(rest, context, { accountOverride });
|
|
239
242
|
if (normalizedResource === "motions" && action === "status") return motionsStatus(rest, context, { accountOverride });
|
|
243
|
+
if (normalizedResource === "motions" && ["abm-companies", "company-filters"].includes(action)) return motionsAbmCompanies(rest, context, { accountOverride });
|
|
240
244
|
if (normalizedResource === "motions" && action === "analytics") return motionsAnalytics(rest, context, { accountOverride });
|
|
241
245
|
if (normalizedResource === "motions" && action === "prospects") return motionsProspects(rest, context, { accountOverride });
|
|
242
246
|
if (normalizedResource === "motions" && action === "add-prospects") return motionsAddProspects(rest, context, { accountOverride });
|
|
@@ -1030,25 +1034,19 @@ async function icpsCreate(args, context, { accountOverride } = {}) {
|
|
|
1030
1034
|
async function icpsUpdate(args, context, { accountOverride } = {}) {
|
|
1031
1035
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1032
1036
|
...jsonOptions(),
|
|
1037
|
+
payload: { type: "string" },
|
|
1033
1038
|
name: { type: "string" },
|
|
1034
1039
|
notes: { type: "string" },
|
|
1035
1040
|
tags: { type: "string" },
|
|
1036
1041
|
"discovery-keyword": { type: "string" }
|
|
1037
1042
|
});
|
|
1038
|
-
const hasUpdateField = values.
|
|
1043
|
+
const hasUpdateField = values.payload || icpSimpleFieldsPresent(values);
|
|
1039
1044
|
if (positionals.length !== 1 || !hasUpdateField) {
|
|
1040
1045
|
throw new CommandError(ICPS_UPDATE_USAGE);
|
|
1041
1046
|
}
|
|
1042
1047
|
|
|
1043
1048
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1044
|
-
const icp = await client.updateIcp(accountId, positionals[0], {
|
|
1045
|
-
icp: compactObject({
|
|
1046
|
-
name: values.name,
|
|
1047
|
-
notes: values.notes,
|
|
1048
|
-
discovery_keyword: values["discovery-keyword"],
|
|
1049
|
-
tags: values.tags !== undefined ? tagList(values.tags) : undefined
|
|
1050
|
-
})
|
|
1051
|
-
});
|
|
1049
|
+
const icp = await client.updateIcp(accountId, positionals[0], { icp: await icpUpdatePayload(values) });
|
|
1052
1050
|
if (values.json) return writeJson(context.stdout, icp);
|
|
1053
1051
|
|
|
1054
1052
|
writeLine(context.stdout, `Updated ICP ${display(icp?.name)} (${display(icp?.prefix_id)}).`);
|
|
@@ -1683,7 +1681,7 @@ async function motionsCreate(args, context, { accountOverride } = {}) {
|
|
|
1683
1681
|
}
|
|
1684
1682
|
|
|
1685
1683
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1686
|
-
const payload = await readJsonPayload(values.payload);
|
|
1684
|
+
const payload = normalizeMotionCreatePayload(await readJsonPayload(values.payload));
|
|
1687
1685
|
const created = await client.createMotion(accountId, { motion: payload });
|
|
1688
1686
|
if (values.json) return writeJson(context.stdout, created);
|
|
1689
1687
|
|
|
@@ -1691,6 +1689,70 @@ async function motionsCreate(args, context, { accountOverride } = {}) {
|
|
|
1691
1689
|
renderMotion(created, context);
|
|
1692
1690
|
}
|
|
1693
1691
|
|
|
1692
|
+
function normalizeMotionCreatePayload(payload) {
|
|
1693
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return payload;
|
|
1694
|
+
validateMotionSignalRows(payload);
|
|
1695
|
+
if (String(payload.kind || "").trim().toLowerCase() !== "inbound") return payload;
|
|
1696
|
+
if (Object.prototype.hasOwnProperty.call(payload, "inbound_channels")) return payload;
|
|
1697
|
+
|
|
1698
|
+
return { ...payload, inbound_channels: ["linkedin"] };
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
async function motionsAbmCompanies(args, context, { accountOverride } = {}) {
|
|
1702
|
+
const [motionId, subaction, ...rest] = args;
|
|
1703
|
+
if (!motionId || !subaction) throw new CommandError("Usage: audienti motions abm-companies <motn_id> <list|add|remove> [args] [--json] [--account <acct_id>]");
|
|
1704
|
+
|
|
1705
|
+
if (subaction === "list") return motionsAbmCompaniesList(motionId, rest, context, { accountOverride });
|
|
1706
|
+
if (subaction === "add") return motionsAbmCompaniesAdd(motionId, rest, context, { accountOverride });
|
|
1707
|
+
if (["remove", "delete"].includes(subaction)) return motionsAbmCompaniesRemove(motionId, rest, context, { accountOverride });
|
|
1708
|
+
|
|
1709
|
+
throw new CommandError("Usage: audienti motions abm-companies <motn_id> <list|add|remove> [args] [--json] [--account <acct_id>]");
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
async function motionsAbmCompaniesList(motionId, args, context, { accountOverride } = {}) {
|
|
1713
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1714
|
+
if (positionals.length > 0) throw new CommandError(MOTIONS_ABM_COMPANIES_LIST_USAGE);
|
|
1715
|
+
|
|
1716
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1717
|
+
const payload = await client.motionAbmCompanies(accountId, motionId);
|
|
1718
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1719
|
+
|
|
1720
|
+
renderMotionAbmCompanies(payload, context);
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
async function motionsAbmCompaniesAdd(motionId, args, context, { accountOverride } = {}) {
|
|
1724
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1725
|
+
...jsonOptions(),
|
|
1726
|
+
file: { type: "string" }
|
|
1727
|
+
});
|
|
1728
|
+
if ((positionals.length === 0 && !values.file) || (positionals.length > 0 && values.file)) {
|
|
1729
|
+
throw new CommandError(MOTIONS_ABM_COMPANIES_ADD_USAGE);
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
const entries = values.file ? await motionAbmCompanyEntriesFromFile(values.file) : positionals;
|
|
1733
|
+
if (entries.length === 0) throw new CommandError(MOTIONS_ABM_COMPANIES_ADD_USAGE);
|
|
1734
|
+
|
|
1735
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1736
|
+
const payload = await client.addMotionAbmCompanies(accountId, motionId, { abm_companies: entries });
|
|
1737
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1738
|
+
|
|
1739
|
+
writeLine(context.stdout, `Company filters: ${Array.isArray(payload?.abm_companies) ? payload.abm_companies.length : 0}`);
|
|
1740
|
+
renderMotionAbmCompanies(payload, context);
|
|
1741
|
+
renderMotionAbmCompanyErrors(payload, context);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
async function motionsAbmCompaniesRemove(motionId, args, context, { accountOverride } = {}) {
|
|
1745
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1746
|
+
if (positionals.length !== 1) throw new CommandError(MOTIONS_ABM_COMPANIES_REMOVE_USAGE);
|
|
1747
|
+
|
|
1748
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1749
|
+
const payload = await client.removeMotionAbmCompany(accountId, motionId, positionals[0]);
|
|
1750
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1751
|
+
|
|
1752
|
+
writeLine(context.stdout, `Removed company filter ${display(positionals[0])} from motion ${display(payload?.motion_id || motionId)}.`);
|
|
1753
|
+
renderMotionAbmCompanies(payload, context);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1694
1756
|
async function motionsDelete(args, context, { accountOverride } = {}) {
|
|
1695
1757
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1696
1758
|
...jsonOptions(),
|
|
@@ -1711,30 +1773,81 @@ async function motionsDelete(args, context, { accountOverride } = {}) {
|
|
|
1711
1773
|
async function motionsUpdate(args, context, { accountOverride } = {}) {
|
|
1712
1774
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1713
1775
|
...jsonOptions(),
|
|
1776
|
+
payload: { type: "string" },
|
|
1714
1777
|
status: { type: "string" },
|
|
1715
1778
|
tags: { type: "string" },
|
|
1716
1779
|
"own-post-engagement": { type: "string" }
|
|
1717
1780
|
});
|
|
1718
|
-
const hasUpdateField = values.
|
|
1781
|
+
const hasUpdateField = values.payload || motionSimpleFieldsPresent(values);
|
|
1719
1782
|
if (positionals.length !== 1 || !hasUpdateField) {
|
|
1720
1783
|
throw new CommandError(MOTIONS_UPDATE_USAGE);
|
|
1721
1784
|
}
|
|
1722
1785
|
|
|
1723
|
-
const normalizedStatus = normalizeMotionStatus(values.status);
|
|
1724
|
-
const motionAttributes = compactObject({
|
|
1725
|
-
status: normalizedStatus,
|
|
1726
|
-
play_tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
1727
|
-
own_post_engagement: values["own-post-engagement"] !== undefined ? parseBooleanString(values["own-post-engagement"], "--own-post-engagement") : undefined
|
|
1728
|
-
});
|
|
1729
|
-
|
|
1730
1786
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1731
|
-
const motion = await client.updateMotion(accountId, positionals[0], { motion:
|
|
1787
|
+
const motion = await client.updateMotion(accountId, positionals[0], { motion: await motionUpdatePayload(values) });
|
|
1732
1788
|
if (values.json) return writeJson(context.stdout, motion);
|
|
1733
1789
|
|
|
1734
1790
|
writeLine(context.stdout, `Updated motion ${display(motion?.name)} (${display(motion?.prefix_id)}).`);
|
|
1735
1791
|
renderMotion(motion, context);
|
|
1736
1792
|
}
|
|
1737
1793
|
|
|
1794
|
+
async function motionUpdatePayload(values) {
|
|
1795
|
+
if (values.payload) {
|
|
1796
|
+
if (motionSimpleFieldsPresent(values)) {
|
|
1797
|
+
throw new CommandError("Choose one motion input mode: either --payload <file.json> or the simple --status/--tags/--own-post-engagement flags.");
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
const payload = await readJsonPayload(values.payload);
|
|
1801
|
+
validateMotionSignalRows(payload);
|
|
1802
|
+
return payload;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
return compactObject({
|
|
1806
|
+
status: normalizeMotionStatus(values.status),
|
|
1807
|
+
play_tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
1808
|
+
own_post_engagement: values["own-post-engagement"] !== undefined ? parseBooleanString(values["own-post-engagement"], "--own-post-engagement") : undefined
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
function motionSimpleFieldsPresent(values) {
|
|
1813
|
+
return Boolean(values.status) || values.tags !== undefined || values["own-post-engagement"] !== undefined;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
function validateMotionSignalRows(payload) {
|
|
1817
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return;
|
|
1818
|
+
|
|
1819
|
+
for (const row of Array.isArray(payload.signal_rows) ? payload.signal_rows : []) {
|
|
1820
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) continue;
|
|
1821
|
+
if (!String(row.posting_language || "").trim()) continue;
|
|
1822
|
+
|
|
1823
|
+
const scope = String(row.scope || "company").trim().toLowerCase();
|
|
1824
|
+
const category = String(row.company_signal_category || "").trim().toLowerCase();
|
|
1825
|
+
if (scope === "company" && category === "hiring") continue;
|
|
1826
|
+
|
|
1827
|
+
throw new CommandError("posting_language is only supported on company-scope hiring signal rows.");
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
async function motionAbmCompanyEntriesFromFile(path) {
|
|
1832
|
+
const contents = await readFile(path, "utf8");
|
|
1833
|
+
const trimmed = contents.trim();
|
|
1834
|
+
if (!trimmed) return [];
|
|
1835
|
+
|
|
1836
|
+
try {
|
|
1837
|
+
const parsed = JSON.parse(trimmed);
|
|
1838
|
+
if (Array.isArray(parsed)) return parsed;
|
|
1839
|
+
if (parsed && typeof parsed === "object") {
|
|
1840
|
+
return Array.isArray(parsed.abm_companies) ? parsed.abm_companies :
|
|
1841
|
+
(Array.isArray(parsed.company_filters) ? parsed.company_filters :
|
|
1842
|
+
(Array.isArray(parsed.items) ? parsed.items : []));
|
|
1843
|
+
}
|
|
1844
|
+
} catch {
|
|
1845
|
+
// Plain text files use one company domain or LinkedIn company URL per line.
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
return trimmed.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1738
1851
|
async function motionsStatusShortcut(action, args, context, { accountOverride } = {}) {
|
|
1739
1852
|
const usage = `Usage: audienti motions ${action} <motn_id> [--json] [--account <acct_id>]`;
|
|
1740
1853
|
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
@@ -3575,7 +3688,7 @@ function filterRecordsByTag(records, value, field) {
|
|
|
3575
3688
|
|
|
3576
3689
|
async function icpCreatePayload(values) {
|
|
3577
3690
|
if (values.payload) {
|
|
3578
|
-
if (values
|
|
3691
|
+
if (icpSimpleFieldsPresent(values)) {
|
|
3579
3692
|
throw new CommandError("Choose one ICP input mode: either --payload <file.json> or the simple --name/--notes/--discovery-keyword/tags flags.");
|
|
3580
3693
|
}
|
|
3581
3694
|
|
|
@@ -3594,6 +3707,27 @@ async function icpCreatePayload(values) {
|
|
|
3594
3707
|
});
|
|
3595
3708
|
}
|
|
3596
3709
|
|
|
3710
|
+
async function icpUpdatePayload(values) {
|
|
3711
|
+
if (values.payload) {
|
|
3712
|
+
if (icpSimpleFieldsPresent(values)) {
|
|
3713
|
+
throw new CommandError("Choose one ICP input mode: either --payload <file.json> or the simple --name/--notes/--discovery-keyword/tags flags.");
|
|
3714
|
+
}
|
|
3715
|
+
|
|
3716
|
+
return readJsonPayload(values.payload);
|
|
3717
|
+
}
|
|
3718
|
+
|
|
3719
|
+
return compactObject({
|
|
3720
|
+
name: values.name,
|
|
3721
|
+
notes: values.notes,
|
|
3722
|
+
tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
3723
|
+
discovery_keyword: values["discovery-keyword"]
|
|
3724
|
+
});
|
|
3725
|
+
}
|
|
3726
|
+
|
|
3727
|
+
function icpSimpleFieldsPresent(values) {
|
|
3728
|
+
return Boolean(values.name) || values.notes !== undefined || values.tags !== undefined || values["discovery-keyword"] !== undefined;
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3597
3731
|
async function prospectNotePayload(values, { forcedType, usageText } = {}) {
|
|
3598
3732
|
const engagementKey = values["engagement-type"] || values["engagement-key"];
|
|
3599
3733
|
|
|
@@ -4191,7 +4325,7 @@ function renderOffer(offer, context) {
|
|
|
4191
4325
|
function renderIcps(icps, context) {
|
|
4192
4326
|
if (!Array.isArray(icps) || icps.length === 0) return writeLine(context.stdout, "No ICPs found.");
|
|
4193
4327
|
|
|
4194
|
-
writeLine(context.stdout, "ICP ID\tNAME\tTAGS\tDISCOVERY KEYWORD\tAGENT");
|
|
4328
|
+
writeLine(context.stdout, "ICP ID\tNAME\tTAGS\tDISCOVERY KEYWORD\tSENIORITY MODE\tAGENT");
|
|
4195
4329
|
for (const icp of icps) {
|
|
4196
4330
|
writeLine(
|
|
4197
4331
|
context.stdout,
|
|
@@ -4200,6 +4334,7 @@ function renderIcps(icps, context) {
|
|
|
4200
4334
|
display(icp.name),
|
|
4201
4335
|
display(Array.isArray(icp.tags) && icp.tags.length > 0 ? icp.tags.join(",") : "-"),
|
|
4202
4336
|
display(icp.discovery_keyword),
|
|
4337
|
+
display(icp.seniority_match_mode),
|
|
4203
4338
|
display(icp.agent?.name)
|
|
4204
4339
|
].join("\t")
|
|
4205
4340
|
);
|
|
@@ -4211,6 +4346,7 @@ function renderIcp(icp, context) {
|
|
|
4211
4346
|
if (Array.isArray(icp?.tags)) writeLine(context.stdout, `Tags: ${display(icp.tags.join(", "), "-")}`);
|
|
4212
4347
|
if (icp?.notes) writeLine(context.stdout, `Notes: ${icp.notes}`);
|
|
4213
4348
|
if (icp?.discovery_keyword) writeLine(context.stdout, `Discovery keyword: ${icp.discovery_keyword}`);
|
|
4349
|
+
if (icp?.seniority_match_mode) writeLine(context.stdout, `Seniority match mode: ${icp.seniority_match_mode}`);
|
|
4214
4350
|
if (icp?.agent?.name) writeLine(context.stdout, `Agent: ${icp.agent.name}`);
|
|
4215
4351
|
}
|
|
4216
4352
|
|
|
@@ -4323,10 +4459,15 @@ function renderMotion(motion, context) {
|
|
|
4323
4459
|
writeLine(context.stdout, `Motion: ${display(motion?.name)} (${display(motion?.prefix_id)})`);
|
|
4324
4460
|
writeLine(context.stdout, `Status: ${display(motion?.status)}`);
|
|
4325
4461
|
writeLine(context.stdout, `Kind: ${display(motion?.kind)}`);
|
|
4462
|
+
renderExecutableConfiguration(motion?.executable_configuration, context);
|
|
4326
4463
|
if (motion?.offer?.name) writeLine(context.stdout, `Offer: ${motion.offer.name} (${display(motion.offer.prefix_id)})`);
|
|
4327
4464
|
if (motion?.icp?.name) writeLine(context.stdout, `ICP: ${motion.icp.name} (${display(motion.icp.prefix_id)})`);
|
|
4328
4465
|
if (motion?.list?.name) writeLine(context.stdout, `List: ${motion.list.name} (${display(motion.list.prefix_id)})`);
|
|
4329
4466
|
writeLine(context.stdout, `Own-post engagement: ${motion?.own_post_engagement ? "enabled" : "disabled"}`);
|
|
4467
|
+
if (Array.isArray(motion?.inbound_channels)) writeLine(context.stdout, `Inbound channels: ${display(motion.inbound_channels.join(", "), "-")}`);
|
|
4468
|
+
renderMotionLopaProfiles(motion?.lopa_profiles, context);
|
|
4469
|
+
renderMotionSignalRows(motion?.signal_rows, context);
|
|
4470
|
+
renderMotionAbmCompanies(motion, context, { showEmpty: false });
|
|
4330
4471
|
if (Array.isArray(motion?.play_tags)) writeLine(context.stdout, `Tags: ${display(motion.play_tags.join(", "), "-")}`);
|
|
4331
4472
|
if (motion?.principal_account_user?.id) {
|
|
4332
4473
|
writeLine(
|
|
@@ -4336,6 +4477,55 @@ function renderMotion(motion, context) {
|
|
|
4336
4477
|
}
|
|
4337
4478
|
}
|
|
4338
4479
|
|
|
4480
|
+
function renderMotionLopaProfiles(rows, context) {
|
|
4481
|
+
if (!Array.isArray(rows) || rows.length === 0) return;
|
|
4482
|
+
|
|
4483
|
+
writeLine(context.stdout, "LOPA profiles:");
|
|
4484
|
+
for (const row of rows) {
|
|
4485
|
+
writeLine(context.stdout, `- ${display(row.url)} (${display(row.source_type, "other")})`);
|
|
4486
|
+
}
|
|
4487
|
+
}
|
|
4488
|
+
|
|
4489
|
+
function renderMotionSignalRows(rows, context) {
|
|
4490
|
+
if (!Array.isArray(rows) || rows.length === 0) return;
|
|
4491
|
+
|
|
4492
|
+
writeLine(context.stdout, "Signal rows:");
|
|
4493
|
+
for (const row of rows) {
|
|
4494
|
+
const filters = [
|
|
4495
|
+
row.company_signal_category ? `category=${row.company_signal_category}` : null,
|
|
4496
|
+
row.role_terms ? `roles=${singleLine(row.role_terms)}` : null,
|
|
4497
|
+
row.posting_language ? `posting_language=${singleLine(row.posting_language)}` : null,
|
|
4498
|
+
row.topics ? `topics=${singleLine(row.topics)}` : null
|
|
4499
|
+
].filter(Boolean).join("; ");
|
|
4500
|
+
writeLine(context.stdout, `- ${display(row.scope)}: ${display(row.question)}${filters ? ` [${filters}]` : ""}`);
|
|
4501
|
+
}
|
|
4502
|
+
}
|
|
4503
|
+
|
|
4504
|
+
function renderMotionAbmCompanies(payload, context, { showEmpty = true } = {}) {
|
|
4505
|
+
const rows = Array.isArray(payload?.abm_companies) ? payload.abm_companies : [];
|
|
4506
|
+
if (rows.length === 0) {
|
|
4507
|
+
if (showEmpty) writeLine(context.stdout, "No company filters found.");
|
|
4508
|
+
return;
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
writeAlignedTable(context, ["ROW ID", "KIND", "VALUE", "STATUS"], rows.map((row) => [
|
|
4512
|
+
display(row.id),
|
|
4513
|
+
display(row.kind),
|
|
4514
|
+
display(row.normalized_value || row.raw_value),
|
|
4515
|
+
display(row.status)
|
|
4516
|
+
]));
|
|
4517
|
+
}
|
|
4518
|
+
|
|
4519
|
+
function renderMotionAbmCompanyErrors(payload, context) {
|
|
4520
|
+
const errors = Array.isArray(payload?.errors) ? payload.errors : [];
|
|
4521
|
+
if (errors.length === 0) return;
|
|
4522
|
+
|
|
4523
|
+
writeLine(context.stdout, "Errors:");
|
|
4524
|
+
for (const error of errors) {
|
|
4525
|
+
writeLine(context.stdout, `- ${display(error.input)}: ${display(error.error)}`);
|
|
4526
|
+
}
|
|
4527
|
+
}
|
|
4528
|
+
|
|
4339
4529
|
function renderContentPrograms(programs, context) {
|
|
4340
4530
|
if (!Array.isArray(programs) || programs.length === 0) return writeLine(context.stdout, "No ContentOps programs found.");
|
|
4341
4531
|
|
|
@@ -4393,10 +4583,23 @@ function renderMotionStatus(status, context) {
|
|
|
4393
4583
|
writeLine(context.stdout, `Motion: ${display(status?.name)} (${display(status?.prefix_id)})`);
|
|
4394
4584
|
writeLine(context.stdout, `State: ${display(status?.state)}`);
|
|
4395
4585
|
writeLine(context.stdout, `Reason: ${display(status?.reason_label || status?.reason_key)}`);
|
|
4586
|
+
renderExecutableConfiguration(status?.executable_configuration, context);
|
|
4396
4587
|
if (status?.description) writeLine(context.stdout, status.description);
|
|
4397
4588
|
if (status?.action?.label) writeLine(context.stdout, `Action: ${status.action.label}`);
|
|
4398
4589
|
}
|
|
4399
4590
|
|
|
4591
|
+
function renderExecutableConfiguration(config, context) {
|
|
4592
|
+
if (!config || typeof config !== "object") return;
|
|
4593
|
+
|
|
4594
|
+
writeLine(context.stdout, `Valid config: ${config.valid ? "yes" : "no"}`);
|
|
4595
|
+
if (!config.valid && (config.reason_label || config.reason_key)) {
|
|
4596
|
+
writeLine(context.stdout, `Config reason: ${display(config.reason_label || config.reason_key)}`);
|
|
4597
|
+
}
|
|
4598
|
+
if (!config.valid && config.description) {
|
|
4599
|
+
writeLine(context.stdout, `Config detail: ${config.description}`);
|
|
4600
|
+
}
|
|
4601
|
+
}
|
|
4602
|
+
|
|
4400
4603
|
function renderProspects(payload, context, { wide = false, profiles = false } = {}) {
|
|
4401
4604
|
const prospects = Array.isArray(payload?.prospects) ? payload.prospects : [];
|
|
4402
4605
|
if (prospects.length === 0) return writeLine(context.stdout, "No prospects found.");
|
|
@@ -5941,6 +6144,10 @@ function display(value, fallback = "") {
|
|
|
5941
6144
|
return value === undefined || value === null || value === "" ? fallback : value;
|
|
5942
6145
|
}
|
|
5943
6146
|
|
|
6147
|
+
function singleLine(value) {
|
|
6148
|
+
return String(value || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(", ");
|
|
6149
|
+
}
|
|
6150
|
+
|
|
5944
6151
|
function prospectsToCsv(prospects) {
|
|
5945
6152
|
const profileIdentifiers = profileIdentifiersForPayload({ meta: {} }, prospects);
|
|
5946
6153
|
const headers = [
|
|
@@ -6237,8 +6444,11 @@ const HELP_TOPICS = new Map([
|
|
|
6237
6444
|
" audienti motions run-discovery <motn_id>",
|
|
6238
6445
|
" audienti motions quick-start --url <company_url> --confirm --wait",
|
|
6239
6446
|
" audienti motions prospects <motn_id>",
|
|
6447
|
+
" audienti motions abm-companies <motn_id> list",
|
|
6448
|
+
" audienti motions abm-companies <motn_id> add <domain_or_linkedin_url>...",
|
|
6240
6449
|
" audienti motions create --payload <file.json>",
|
|
6241
6450
|
" audienti motions update <motn_id> [--status <state>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>]",
|
|
6451
|
+
" audienti motions update <motn_id> --payload <file.json>",
|
|
6242
6452
|
" audienti motions add-tag <motn_id> <tag>",
|
|
6243
6453
|
" audienti motions remove-tag <motn_id> <tag>",
|
|
6244
6454
|
" audienti motions activate <motn_id>",
|
|
@@ -6293,7 +6503,7 @@ const HELP_TOPICS = new Map([
|
|
|
6293
6503
|
" audienti offers delete <offr_id> --confirm <yes|true|Y|y>",
|
|
6294
6504
|
" audienti icps list [--tag <tag>]",
|
|
6295
6505
|
" audienti icps show <icp_id>",
|
|
6296
|
-
" audienti icps update <icp_id> [--tags <tag[,tag...]>]",
|
|
6506
|
+
" audienti icps update <icp_id> [--tags <tag[,tag...]> | --payload <file.json>]",
|
|
6297
6507
|
" audienti icps add-tag <icp_id> <tag>",
|
|
6298
6508
|
" audienti icps remove-tag <icp_id> <tag>",
|
|
6299
6509
|
" audienti companies search --query <text>",
|
|
@@ -6770,7 +6980,7 @@ const HELP_TOPICS = new Map([
|
|
|
6770
6980
|
" audienti icps list [--tag <tag>] [--json]",
|
|
6771
6981
|
" audienti icps show <icp_id> [--json]",
|
|
6772
6982
|
" audienti icps create (--name <text> | --payload <file.json>) [--json]",
|
|
6773
|
-
" audienti icps update <icp_id> [--tags <tag[,tag...]>] [--json]",
|
|
6983
|
+
" audienti icps update <icp_id> ([--tags <tag[,tag...]>] | --payload <file.json>) [--json]",
|
|
6774
6984
|
" audienti icps add-tag <icp_id> <tag> [--json]",
|
|
6775
6985
|
" audienti icps remove-tag <icp_id> <tag> [--json]",
|
|
6776
6986
|
"",
|
|
@@ -6863,12 +7073,12 @@ const HELP_TOPICS = new Map([
|
|
|
6863
7073
|
|
|
6864
7074
|
["icps update", [
|
|
6865
7075
|
"Usage:",
|
|
6866
|
-
"
|
|
7076
|
+
` ${ICPS_UPDATE_USAGE.slice("Usage: ".length)}`,
|
|
6867
7077
|
"",
|
|
6868
7078
|
"Status: implemented",
|
|
6869
7079
|
"",
|
|
6870
7080
|
"Purpose:",
|
|
6871
|
-
" Update simple ICP fields
|
|
7081
|
+
" Update simple ICP fields, replace the ICP's full tag set, or apply a rich ICP payload patch.",
|
|
6872
7082
|
"",
|
|
6873
7083
|
"Input shape:",
|
|
6874
7084
|
" icp_id: icpp_ prefixed id or integer id",
|
|
@@ -6876,15 +7086,30 @@ const HELP_TOPICS = new Map([
|
|
|
6876
7086
|
" notes: string | optional",
|
|
6877
7087
|
" discovery_keyword: string | optional",
|
|
6878
7088
|
" tags: comma-separated tag list | optional",
|
|
7089
|
+
" payload: file.json | optional full or partial ICP object using the account API create shape",
|
|
7090
|
+
"",
|
|
7091
|
+
"Behavior:",
|
|
7092
|
+
" Choose either --payload or simple flags. Supplied facet collections replace that collection in place; omitted fields and facet collections remain unchanged.",
|
|
7093
|
+
" Human-readable lookup-backed facet names are resolved by the account API. Invalid lookup values fail with 422 and no partial mutation.",
|
|
6879
7094
|
"",
|
|
6880
7095
|
"API:",
|
|
6881
7096
|
" PATCH /api/v1/accounts/:account_id/icps/:id.json",
|
|
6882
7097
|
"",
|
|
6883
|
-
"JSON body:",
|
|
7098
|
+
"Simple JSON body:",
|
|
6884
7099
|
" {",
|
|
6885
7100
|
" \"icp\": {",
|
|
6886
7101
|
" \"tags\": [\"enterprise\", \"renewal\"]",
|
|
6887
7102
|
" }",
|
|
7103
|
+
" }",
|
|
7104
|
+
"",
|
|
7105
|
+
"Payload file example:",
|
|
7106
|
+
" {",
|
|
7107
|
+
" \"company_sizes_attributes\": [",
|
|
7108
|
+
" {\"name\": \"1001-5000 employees\"}",
|
|
7109
|
+
" ],",
|
|
7110
|
+
" \"seniorities_attributes\": [",
|
|
7111
|
+
" {\"name\": \"CXO\"}",
|
|
7112
|
+
" ]",
|
|
6888
7113
|
" }"
|
|
6889
7114
|
].join("\n")],
|
|
6890
7115
|
|
|
@@ -7488,8 +7713,11 @@ const HELP_TOPICS = new Map([
|
|
|
7488
7713
|
" audienti motions analytics <motn_id> [--window 30d] [--json]",
|
|
7489
7714
|
" audienti motions prospects <motn_id> [--json]",
|
|
7490
7715
|
" audienti motions add-prospects <motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
7716
|
+
" audienti motions abm-companies <motn_id> list [--json]",
|
|
7717
|
+
" audienti motions abm-companies <motn_id> add (<domain_or_linkedin_url>... | --file <txt|json>) [--json]",
|
|
7718
|
+
" audienti motions abm-companies <motn_id> remove <row_id> [--json]",
|
|
7491
7719
|
" audienti motions create --payload <file.json> [--json]",
|
|
7492
|
-
" audienti motions update <motn_id> [--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] [--json]",
|
|
7720
|
+
" audienti motions update <motn_id> ([--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] | --payload <file.json>) [--json]",
|
|
7493
7721
|
" audienti motions add-tag <motn_id> <tag> [--json]",
|
|
7494
7722
|
" audienti motions remove-tag <motn_id> <tag> [--json]",
|
|
7495
7723
|
" audienti motions activate <motn_id> [--json]",
|
|
@@ -7570,10 +7798,38 @@ const HELP_TOPICS = new Map([
|
|
|
7570
7798
|
"Input shape:",
|
|
7571
7799
|
" motn_id: motn_ prefix id",
|
|
7572
7800
|
"",
|
|
7801
|
+
"Output shape:",
|
|
7802
|
+
" inbound_channels: enabled inbound collectors for inbound motions",
|
|
7803
|
+
" lopa_profiles[]: tracked LinkedIn profile rows for LOPA motions",
|
|
7804
|
+
" signal_rows[]: outbound signal configuration rows",
|
|
7805
|
+
" abm_companies[]: motion-scoped positive company filter rows",
|
|
7806
|
+
"",
|
|
7573
7807
|
"API:",
|
|
7574
7808
|
" GET /api/v1/accounts/:account_id/motions/:id.json"
|
|
7575
7809
|
].join("\n")],
|
|
7576
7810
|
|
|
7811
|
+
["motions abm-companies", [
|
|
7812
|
+
"Usage:",
|
|
7813
|
+
` ${MOTIONS_ABM_COMPANIES_LIST_USAGE.slice("Usage: ".length)}`,
|
|
7814
|
+
` ${MOTIONS_ABM_COMPANIES_ADD_USAGE.slice("Usage: ".length)}`,
|
|
7815
|
+
` ${MOTIONS_ABM_COMPANIES_REMOVE_USAGE.slice("Usage: ".length)}`,
|
|
7816
|
+
"",
|
|
7817
|
+
"Status: implemented",
|
|
7818
|
+
"",
|
|
7819
|
+
"Purpose:",
|
|
7820
|
+
" Manage a motion-scoped positive company filter list for isolated ABM discovery runs.",
|
|
7821
|
+
"",
|
|
7822
|
+
"Input shape:",
|
|
7823
|
+
" motn_id: motn_ prefix id",
|
|
7824
|
+
" domain_or_linkedin_url: company domain or LinkedIn company page URL",
|
|
7825
|
+
" file: plain text one entry per line, or JSON array / { abm_companies: [...] }",
|
|
7826
|
+
"",
|
|
7827
|
+
"API:",
|
|
7828
|
+
" GET /api/v1/accounts/:account_id/motions/:motion_id/abm_companies.json",
|
|
7829
|
+
" POST /api/v1/accounts/:account_id/motions/:motion_id/abm_companies.json",
|
|
7830
|
+
" DELETE /api/v1/accounts/:account_id/motions/:motion_id/abm_companies/:row_id.json"
|
|
7831
|
+
].join("\n")],
|
|
7832
|
+
|
|
7577
7833
|
["motions status", [
|
|
7578
7834
|
"Usage:",
|
|
7579
7835
|
" audienti motions status <motn_id> [--json] [--account <acct_id>]",
|
|
@@ -7587,6 +7843,7 @@ const HELP_TOPICS = new Map([
|
|
|
7587
7843
|
" state: healthy_idle | broken",
|
|
7588
7844
|
" reason_key: string",
|
|
7589
7845
|
" reason_label: string",
|
|
7846
|
+
" executable_configuration: { valid: boolean, reason_key: string | null, reason_label: string | null, description: string | null }",
|
|
7590
7847
|
" description: string",
|
|
7591
7848
|
" action: { key: string, label: string } | null",
|
|
7592
7849
|
" stats: { target_count, deficit, projected_connectable, capacity, daily_target }",
|
|
@@ -7738,7 +7995,9 @@ const HELP_TOPICS = new Map([
|
|
|
7738
7995
|
" icp_id: icpp_ prefix id | optional",
|
|
7739
7996
|
" list_id: list_ prefix id | optional",
|
|
7740
7997
|
" play_tags: [string] | optional",
|
|
7741
|
-
"
|
|
7998
|
+
" signal_rows: [{ scope: company | person | both, question: string, company_signal_category: string | optional, role_terms: string | optional, posting_language: hiring-only string | optional, topics: string | optional }] | optional for outbound motions",
|
|
7999
|
+
" signal_questions: newline-delimited company::, person::, or both:: legacy question text | optional for outbound motions",
|
|
8000
|
+
" inbound_channels: [linkedin | reddit] | optional; defaults to [linkedin] for inbound motions",
|
|
7742
8001
|
" lopa_profiles: [{ url: string, source_type: creator | competitor | partner | customer | other }] | optional",
|
|
7743
8002
|
"",
|
|
7744
8003
|
"JSON example:",
|
|
@@ -7755,6 +8014,7 @@ const HELP_TOPICS = new Map([
|
|
|
7755
8014
|
"",
|
|
7756
8015
|
"Behavior:",
|
|
7757
8016
|
" The API calls Motions::Setup and the managed graph provisioner. If principal_account_user_id is omitted, the authenticated account user is used.",
|
|
8017
|
+
" posting_language is only supported on company-scope hiring signal rows; use topics for person discussion evidence.",
|
|
7758
8018
|
" Use `audienti offers list`, `audienti icps list`, and `audienti users list` to resolve valid ids before calling this command."
|
|
7759
8019
|
].join("\n")],
|
|
7760
8020
|
|
|
@@ -7793,25 +8053,45 @@ const HELP_TOPICS = new Map([
|
|
|
7793
8053
|
"Status: implemented",
|
|
7794
8054
|
"",
|
|
7795
8055
|
"Purpose:",
|
|
7796
|
-
" Change one motion or play's lifecycle status
|
|
8056
|
+
" Change one motion or play's lifecycle status, replace its tag set, or patch rich motion configuration.",
|
|
7797
8057
|
"",
|
|
7798
8058
|
"Input shape:",
|
|
7799
8059
|
" motn_id: motn_ prefix id",
|
|
7800
8060
|
" status: draft | preparing | active | paused | archived | optional",
|
|
7801
8061
|
" tags: comma-separated tag list | optional",
|
|
8062
|
+
" payload: file.json | optional full or partial motion object using the account API shape",
|
|
7802
8063
|
"",
|
|
7803
8064
|
"Behavior:",
|
|
7804
|
-
" Updates only the provided fields. Sending --tags replaces the motion's full tag set.",
|
|
8065
|
+
" Choose either --payload or simple flags. Updates only the provided fields. Sending --tags replaces the motion's full tag set.",
|
|
8066
|
+
" Payload mode supports outbound signal_rows or legacy signal_questions; supplied rows replace the motion's active ready signals.",
|
|
8067
|
+
" posting_language is only supported on company-scope hiring signal rows; use topics for person discussion evidence.",
|
|
7805
8068
|
"",
|
|
7806
8069
|
"API:",
|
|
7807
8070
|
" PATCH /api/v1/accounts/:account_id/motions/:id.json",
|
|
7808
8071
|
"",
|
|
7809
|
-
"JSON body:",
|
|
8072
|
+
"Simple JSON body:",
|
|
7810
8073
|
" {",
|
|
7811
8074
|
" \"motion\": {",
|
|
7812
8075
|
" \"status\": \"paused\",",
|
|
7813
8076
|
" \"play_tags\": [\"sarit\", \"pj\"]",
|
|
7814
8077
|
" }",
|
|
8078
|
+
" }",
|
|
8079
|
+
"",
|
|
8080
|
+
"Payload file example:",
|
|
8081
|
+
" {",
|
|
8082
|
+
" \"signal_rows\": [",
|
|
8083
|
+
" {",
|
|
8084
|
+
" \"scope\": \"company\",",
|
|
8085
|
+
" \"question\": \"Is the company hiring revenue operations leaders?\",",
|
|
8086
|
+
" \"company_signal_category\": \"hiring\",",
|
|
8087
|
+
" \"role_terms\": \"Revenue Operations\"",
|
|
8088
|
+
" },",
|
|
8089
|
+
" {",
|
|
8090
|
+
" \"scope\": \"person\",",
|
|
8091
|
+
" \"question\": \"Is the person talking about pipeline quality?\",",
|
|
8092
|
+
" \"topics\": \"pipeline quality\"",
|
|
8093
|
+
" }",
|
|
8094
|
+
" ]",
|
|
7815
8095
|
" }"
|
|
7816
8096
|
].join("\n")],
|
|
7817
8097
|
|
|
@@ -9209,6 +9489,7 @@ const HELP_TOPICS = new Map([
|
|
|
9209
9489
|
"2. Create a motion or play",
|
|
9210
9490
|
" audienti setup play preflight --principal <account_user_id|me> --platform linkedin",
|
|
9211
9491
|
" audienti motions create --payload <file.json>",
|
|
9492
|
+
" audienti motions abm-companies <motn_id> add --file abm-domains.txt",
|
|
9212
9493
|
" audienti motions clone <motn_id> --name \"New subset motion\"",
|
|
9213
9494
|
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...]",
|
|
9214
9495
|
" audienti motions activate <motn_id>",
|