@audienti/cli 0.1.34 → 0.1.36
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 +17 -0
- package/README.md +37 -1
- package/package.json +1 -1
- package/skills/audienti/SKILL.md +15 -1
- package/src/api-client.js +55 -0
- package/src/cli.js +378 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.36] - 2026-08-22
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `audienti lists routing-rules` commands to inspect, create, update, remove, reorder, and apply the same account-scoped list routing rules available in the UI.
|
|
12
|
+
|
|
13
|
+
## [0.1.35] - 2026-08-18
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Add `audienti motions abm-companies` commands for listing, adding, and removing motion-scoped positive company filters through the account API.
|
|
18
|
+
- Surface ICP `seniority_match_mode`, motion inbound channels, LOPA profile rows, signal rows, and ABM company filters in CLI/API readbacks.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Reject `posting_language` on non-hiring signal rows instead of accepting a field that cannot persist outside company-scope hiring signals.
|
|
23
|
+
|
|
7
24
|
## [0.1.34] - 2026-08-17
|
|
8
25
|
|
|
9
26
|
### Added
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Audienti CLI is the agent-first command-line client for the Audienti production
|
|
|
4
4
|
API and the local bridge for Audienti's app-hosted MCP endpoint. It lets local
|
|
5
5
|
coding agents and operators inspect accounts,
|
|
6
6
|
create and manage plays, import prospects, build lists, manage task reminders,
|
|
7
|
-
and work supported operator flows.
|
|
7
|
+
configure list routing rules, and work supported operator flows.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -140,6 +140,8 @@ 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
|
|
145
147
|
audienti motions update <motn_id> --payload motion-signals.json
|
|
@@ -161,6 +163,8 @@ audienti tasks add --title "Review Cristina" --due 2026-07-24T11:00 --prospect <
|
|
|
161
163
|
audienti tasks complete <ptsk_id>
|
|
162
164
|
audienti dnc list
|
|
163
165
|
audienti company-rules list
|
|
166
|
+
audienti lists routing-rules <list_id> list
|
|
167
|
+
audienti lists routing-rules <list_id> apply
|
|
164
168
|
audienti users activity --window 7d
|
|
165
169
|
audienti analytics prospects --window 24h
|
|
166
170
|
audienti analytics dashboard --play-tag wine_campaign
|
|
@@ -199,6 +203,38 @@ audienti tasks add --title "Review target account" --due 2026-07-24T11:00 --list
|
|
|
199
203
|
audienti tasks complete <ptsk_id>
|
|
200
204
|
```
|
|
201
205
|
|
|
206
|
+
To manage the same ordered rules shown in a list's Routing Rules UI, use a JSON
|
|
207
|
+
payload for create and update operations:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
audienti lists routing-rules <list_id> list
|
|
211
|
+
audienti lists routing-rules <list_id> create --payload routing-rule.json
|
|
212
|
+
audienti lists routing-rules <list_id> update <rule_id> --payload routing-rule.json
|
|
213
|
+
audienti lists routing-rules <list_id> move <rule_id> up
|
|
214
|
+
audienti lists routing-rules <list_id> remove <rule_id>
|
|
215
|
+
audienti lists routing-rules <list_id> apply
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"name": "VP prospects to Alice",
|
|
221
|
+
"enabled": true,
|
|
222
|
+
"action_kind": "assign_user",
|
|
223
|
+
"target_account_user_id": "alice@example.com",
|
|
224
|
+
"conditions": {
|
|
225
|
+
"seniorities": [
|
|
226
|
+
{"id": "5", "name": "Vice President", "negative": false}
|
|
227
|
+
],
|
|
228
|
+
"seniority_match_mode": "at_least"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Use `action_kind: "route_to_list"` with `target_list_id` to route to another
|
|
234
|
+
working list. `apply` queues the existing list-routing background job, just like
|
|
235
|
+
the UI; it reports that work was enqueued, not that every prospect has finished
|
|
236
|
+
routing. Run `audienti lists routing-rules help` for the full condition contract.
|
|
237
|
+
|
|
202
238
|
To inspect activity for prospects that entered the account during a specific
|
|
203
239
|
cohort while keeping a separate activity window:
|
|
204
240
|
|
package/package.json
CHANGED
package/skills/audienti/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: audienti
|
|
3
|
-
description: Use when the user wants to operate Audienti through the production CLI or app-hosted MCP endpoint, including account selection, plays, prospect imports, lists, message previews, analytics, or supported operator outcomes.
|
|
3
|
+
description: Use when the user wants to operate Audienti through the production CLI or app-hosted MCP endpoint, including account selection, plays, prospect imports, lists and routing rules, message previews, analytics, or supported operator outcomes.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Audienti CLI and MCP
|
|
@@ -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
|
|
|
@@ -100,7 +102,13 @@ audienti prospects unlock <prsp_id> --json
|
|
|
100
102
|
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
|
|
105
|
+
audienti lists routing-rules <list_id> list --json
|
|
106
|
+
audienti lists routing-rules <list_id> create --payload routing-rule.json --json
|
|
107
|
+
audienti lists routing-rules <list_id> move <rule_id> up --json
|
|
108
|
+
audienti lists routing-rules <list_id> apply --json
|
|
103
109
|
audienti motions quick-start --url https://example.com --wait --confirm --json
|
|
110
|
+
audienti motions abm-companies <motn_id> add --file abm-domains.txt --json
|
|
111
|
+
audienti motions abm-companies <motn_id> list --json
|
|
104
112
|
audienti motions update <motn_id> --status paused --json
|
|
105
113
|
audienti motions activate <motn_id> --json
|
|
106
114
|
audienti motions delete <motn_id> --confirm yes --json
|
|
@@ -121,6 +129,12 @@ audienti writer test-run <prsp_id> --mode step --branch no-accept --step 3 --rep
|
|
|
121
129
|
audienti writer test-run show <prsp_id> <rprt_id>
|
|
122
130
|
```
|
|
123
131
|
|
|
132
|
+
List routing-rule create and update commands accept the same normalized
|
|
133
|
+
condition and action data as the list UI. Inspect the ordered rules first, use
|
|
134
|
+
`audienti lists routing-rules help` for the payload contract, and treat `apply`
|
|
135
|
+
as an asynchronous relaunch: it queues the existing routing job and does not
|
|
136
|
+
mean every list member has finished routing.
|
|
137
|
+
|
|
124
138
|
`audienti writer test-run <prsp_id>` starts a report-backed writing session and
|
|
125
139
|
builds the campaign timeline without drafting every message. The printed
|
|
126
140
|
`Report: rprt_...` id is the session handle. Pass `--report <rprt_id>` when
|
package/src/api-client.js
CHANGED
|
@@ -268,6 +268,44 @@ export class AudientiClient {
|
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
listRoutingRules(accountId, listId) {
|
|
272
|
+
return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules"]));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
createListRoutingRule(accountId, listId, body) {
|
|
276
|
+
return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules"]), {
|
|
277
|
+
method: "POST",
|
|
278
|
+
body
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
updateListRoutingRule(accountId, listId, ruleId, body) {
|
|
283
|
+
return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules", ruleId]), {
|
|
284
|
+
method: "PATCH",
|
|
285
|
+
body
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
removeListRoutingRule(accountId, listId, ruleId) {
|
|
290
|
+
return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules", ruleId]), {
|
|
291
|
+
method: "DELETE"
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
moveListRoutingRule(accountId, listId, ruleId, body) {
|
|
296
|
+
return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules", ruleId, "move"]), {
|
|
297
|
+
method: "PATCH",
|
|
298
|
+
body
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
applyListRoutingRules(accountId, listId) {
|
|
303
|
+
return this.requestJson(accountPath(accountId, ["lists", listId, "routing_rules", "apply"]), {
|
|
304
|
+
method: "POST",
|
|
305
|
+
body: {}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
271
309
|
motions(accountId) {
|
|
272
310
|
return this.requestJson(accountPath(accountId, ["motions"]));
|
|
273
311
|
}
|
|
@@ -290,6 +328,23 @@ export class AudientiClient {
|
|
|
290
328
|
});
|
|
291
329
|
}
|
|
292
330
|
|
|
331
|
+
motionAbmCompanies(accountId, motionId) {
|
|
332
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "abm_companies"]));
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
addMotionAbmCompanies(accountId, motionId, body) {
|
|
336
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "abm_companies"]), {
|
|
337
|
+
method: "POST",
|
|
338
|
+
body
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
removeMotionAbmCompany(accountId, motionId, rowId) {
|
|
343
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "abm_companies", rowId]), {
|
|
344
|
+
method: "DELETE"
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
293
348
|
contentPrograms(accountId, query = {}) {
|
|
294
349
|
return this.requestJson(accountPath(accountId, ["content_ops", "programs"], query));
|
|
295
350
|
}
|
package/src/cli.js
CHANGED
|
@@ -90,12 +90,21 @@ 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
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>]";
|
|
98
101
|
const LISTS_REMOVE_TAG_USAGE = "Usage: audienti lists remove-tag <list_id> <tag> [--json] [--account <acct_id>]";
|
|
102
|
+
const LIST_ROUTING_RULES_LIST_USAGE = "Usage: audienti lists routing-rules <list_id> list [--json] [--account <acct_id>]";
|
|
103
|
+
const LIST_ROUTING_RULES_CREATE_USAGE = "Usage: audienti lists routing-rules <list_id> create --payload <file.json> [--json] [--account <acct_id>]";
|
|
104
|
+
const LIST_ROUTING_RULES_UPDATE_USAGE = "Usage: audienti lists routing-rules <list_id> update <rule_id> --payload <file.json> [--json] [--account <acct_id>]";
|
|
105
|
+
const LIST_ROUTING_RULES_REMOVE_USAGE = "Usage: audienti lists routing-rules <list_id> remove <rule_id> [--json] [--account <acct_id>]";
|
|
106
|
+
const LIST_ROUTING_RULES_MOVE_USAGE = "Usage: audienti lists routing-rules <list_id> move <rule_id> <up|down> [--json] [--account <acct_id>]";
|
|
107
|
+
const LIST_ROUTING_RULES_APPLY_USAGE = "Usage: audienti lists routing-rules <list_id> apply [--json] [--account <acct_id>]";
|
|
99
108
|
const ANALYTICS_PROSPECTS_USAGE = "Usage: audienti analytics prospects [--window 24h] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--motion <motn_id>] [--list <list_id>] [--provenance <source>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
100
109
|
const ANALYTICS_PROSPECTS_COHORT_ANALYSIS_USAGE = "Usage: audienti analytics prospects cohort-analysis [--weeks <n>] [--window 24h] [--motion <motn_id>] [--list <list_id>] [--provenance <source>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
101
110
|
const ANALYTICS_USERS_USAGE = "Usage: audienti analytics users [--user <account_user_id|email|name|me>] [--window 30d | --start YYYY-MM-DD --end YYYY-MM-DD] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--motion <motn_id>] [--list <list_id>] [--provenance <source>] [--platform <linkedin|email|gmail>] [--json] [--account <acct_id>]";
|
|
@@ -234,9 +243,11 @@ async function dispatch(argv, context) {
|
|
|
234
243
|
if (normalizedResource === "lists" && action === "prospects") return listProspects(rest, context, { accountOverride });
|
|
235
244
|
if (normalizedResource === "lists" && action === "add-prospects") return listsAddProspects(rest, context, { accountOverride });
|
|
236
245
|
if (normalizedResource === "lists" && action === "remove-prospects") return listsRemoveProspects(rest, context, { accountOverride });
|
|
246
|
+
if (normalizedResource === "lists" && ["routing-rules", "rules"].includes(action)) return listsRoutingRules(rest, context, { accountOverride });
|
|
237
247
|
if (normalizedResource === "motions" && action === "list") return motionsList(rest, context, { accountOverride });
|
|
238
248
|
if (normalizedResource === "motions" && action === "show") return motionsShow(rest, context, { accountOverride });
|
|
239
249
|
if (normalizedResource === "motions" && action === "status") return motionsStatus(rest, context, { accountOverride });
|
|
250
|
+
if (normalizedResource === "motions" && ["abm-companies", "company-filters"].includes(action)) return motionsAbmCompanies(rest, context, { accountOverride });
|
|
240
251
|
if (normalizedResource === "motions" && action === "analytics") return motionsAnalytics(rest, context, { accountOverride });
|
|
241
252
|
if (normalizedResource === "motions" && action === "prospects") return motionsProspects(rest, context, { accountOverride });
|
|
242
253
|
if (normalizedResource === "motions" && action === "add-prospects") return motionsAddProspects(rest, context, { accountOverride });
|
|
@@ -1487,6 +1498,104 @@ async function listsRemoveProspects(args, context, { accountOverride } = {}) {
|
|
|
1487
1498
|
return rejected ? 1 : 0;
|
|
1488
1499
|
}
|
|
1489
1500
|
|
|
1501
|
+
async function listsRoutingRules(args, context, { accountOverride } = {}) {
|
|
1502
|
+
const [listId, subaction, ...rest] = args;
|
|
1503
|
+
if (!listId || !subaction) {
|
|
1504
|
+
throw new CommandError("Usage: audienti lists routing-rules <list_id> <list|create|update|remove|move|apply> [args] [--json] [--account <acct_id>]");
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
if (subaction === "list") return listRoutingRulesList(listId, rest, context, { accountOverride });
|
|
1508
|
+
if (subaction === "create") return listRoutingRulesCreate(listId, rest, context, { accountOverride });
|
|
1509
|
+
if (subaction === "update") return listRoutingRulesUpdate(listId, rest, context, { accountOverride });
|
|
1510
|
+
if (["remove", "delete"].includes(subaction)) return listRoutingRulesRemove(listId, rest, context, { accountOverride });
|
|
1511
|
+
if (subaction === "move") return listRoutingRulesMove(listId, rest, context, { accountOverride });
|
|
1512
|
+
if (subaction === "apply") return listRoutingRulesApply(listId, rest, context, { accountOverride });
|
|
1513
|
+
|
|
1514
|
+
throw new CommandError("Usage: audienti lists routing-rules <list_id> <list|create|update|remove|move|apply> [args] [--json] [--account <acct_id>]");
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
async function listRoutingRulesList(listId, args, context, { accountOverride } = {}) {
|
|
1518
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1519
|
+
if (positionals.length > 0) throw new CommandError(LIST_ROUTING_RULES_LIST_USAGE);
|
|
1520
|
+
|
|
1521
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1522
|
+
const payload = await client.listRoutingRules(accountId, listId);
|
|
1523
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1524
|
+
|
|
1525
|
+
renderListRoutingRules(payload, context);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
async function listRoutingRulesCreate(listId, args, context, { accountOverride } = {}) {
|
|
1529
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1530
|
+
...jsonOptions(),
|
|
1531
|
+
payload: {type: "string"}
|
|
1532
|
+
});
|
|
1533
|
+
if (positionals.length > 0 || !values.payload) throw new CommandError(LIST_ROUTING_RULES_CREATE_USAGE);
|
|
1534
|
+
|
|
1535
|
+
const ruleInput = await readJsonPayload(values.payload);
|
|
1536
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1537
|
+
const payload = await client.createListRoutingRule(accountId, listId, {routing_rule: ruleInput});
|
|
1538
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1539
|
+
|
|
1540
|
+
const rule = payload?.routing_rule;
|
|
1541
|
+
writeLine(context.stdout, `Created routing rule ${display(rule?.name)} (${display(rule?.id)}) on list ${display(payload?.list_id || listId)}.`);
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
async function listRoutingRulesUpdate(listId, args, context, { accountOverride } = {}) {
|
|
1545
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1546
|
+
...jsonOptions(),
|
|
1547
|
+
payload: {type: "string"}
|
|
1548
|
+
});
|
|
1549
|
+
if (positionals.length !== 1 || !values.payload) throw new CommandError(LIST_ROUTING_RULES_UPDATE_USAGE);
|
|
1550
|
+
|
|
1551
|
+
const ruleInput = await readJsonPayload(values.payload);
|
|
1552
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1553
|
+
const payload = await client.updateListRoutingRule(accountId, listId, positionals[0], {routing_rule: ruleInput});
|
|
1554
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1555
|
+
|
|
1556
|
+
const rule = payload?.routing_rule;
|
|
1557
|
+
writeLine(context.stdout, `Updated routing rule ${display(rule?.name)} (${display(rule?.id)}) on list ${display(payload?.list_id || listId)}.`);
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
async function listRoutingRulesRemove(listId, args, context, { accountOverride } = {}) {
|
|
1561
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1562
|
+
if (positionals.length !== 1) throw new CommandError(LIST_ROUTING_RULES_REMOVE_USAGE);
|
|
1563
|
+
|
|
1564
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1565
|
+
const payload = await client.removeListRoutingRule(accountId, listId, positionals[0]);
|
|
1566
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1567
|
+
|
|
1568
|
+
const rule = payload?.routing_rule;
|
|
1569
|
+
writeLine(context.stdout, `Removed routing rule ${display(rule?.name)} (${display(rule?.id || positionals[0])}) from list ${display(listId)}.`);
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
async function listRoutingRulesMove(listId, args, context, { accountOverride } = {}) {
|
|
1573
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1574
|
+
const [ruleId, direction] = positionals;
|
|
1575
|
+
if (positionals.length !== 2 || !["up", "down"].includes(direction)) {
|
|
1576
|
+
throw new CommandError(LIST_ROUTING_RULES_MOVE_USAGE);
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1580
|
+
const payload = await client.moveListRoutingRule(accountId, listId, ruleId, {direction});
|
|
1581
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1582
|
+
|
|
1583
|
+
const verb = payload?.moved ? "Moved" : "Could not move";
|
|
1584
|
+
writeLine(context.stdout, `${verb} routing rule ${display(ruleId)} ${direction} on list ${display(payload?.list_id || listId)}.`);
|
|
1585
|
+
renderListRoutingRules(payload, context);
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
async function listRoutingRulesApply(listId, args, context, { accountOverride } = {}) {
|
|
1589
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1590
|
+
if (positionals.length > 0) throw new CommandError(LIST_ROUTING_RULES_APPLY_USAGE);
|
|
1591
|
+
|
|
1592
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1593
|
+
const payload = await client.applyListRoutingRules(accountId, listId);
|
|
1594
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1595
|
+
|
|
1596
|
+
writeLine(context.stdout, `Routing rules will be applied in the background to list ${display(payload?.list_id || listId)}.`);
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1490
1599
|
async function motionsList(args, context, { accountOverride } = {}) {
|
|
1491
1600
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1492
1601
|
...jsonOptions(),
|
|
@@ -1687,12 +1796,68 @@ async function motionsCreate(args, context, { accountOverride } = {}) {
|
|
|
1687
1796
|
|
|
1688
1797
|
function normalizeMotionCreatePayload(payload) {
|
|
1689
1798
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return payload;
|
|
1799
|
+
validateMotionSignalRows(payload);
|
|
1690
1800
|
if (String(payload.kind || "").trim().toLowerCase() !== "inbound") return payload;
|
|
1691
1801
|
if (Object.prototype.hasOwnProperty.call(payload, "inbound_channels")) return payload;
|
|
1692
1802
|
|
|
1693
1803
|
return { ...payload, inbound_channels: ["linkedin"] };
|
|
1694
1804
|
}
|
|
1695
1805
|
|
|
1806
|
+
async function motionsAbmCompanies(args, context, { accountOverride } = {}) {
|
|
1807
|
+
const [motionId, subaction, ...rest] = args;
|
|
1808
|
+
if (!motionId || !subaction) throw new CommandError("Usage: audienti motions abm-companies <motn_id> <list|add|remove> [args] [--json] [--account <acct_id>]");
|
|
1809
|
+
|
|
1810
|
+
if (subaction === "list") return motionsAbmCompaniesList(motionId, rest, context, { accountOverride });
|
|
1811
|
+
if (subaction === "add") return motionsAbmCompaniesAdd(motionId, rest, context, { accountOverride });
|
|
1812
|
+
if (["remove", "delete"].includes(subaction)) return motionsAbmCompaniesRemove(motionId, rest, context, { accountOverride });
|
|
1813
|
+
|
|
1814
|
+
throw new CommandError("Usage: audienti motions abm-companies <motn_id> <list|add|remove> [args] [--json] [--account <acct_id>]");
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
async function motionsAbmCompaniesList(motionId, args, context, { accountOverride } = {}) {
|
|
1818
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1819
|
+
if (positionals.length > 0) throw new CommandError(MOTIONS_ABM_COMPANIES_LIST_USAGE);
|
|
1820
|
+
|
|
1821
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1822
|
+
const payload = await client.motionAbmCompanies(accountId, motionId);
|
|
1823
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1824
|
+
|
|
1825
|
+
renderMotionAbmCompanies(payload, context);
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
async function motionsAbmCompaniesAdd(motionId, args, context, { accountOverride } = {}) {
|
|
1829
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1830
|
+
...jsonOptions(),
|
|
1831
|
+
file: { type: "string" }
|
|
1832
|
+
});
|
|
1833
|
+
if ((positionals.length === 0 && !values.file) || (positionals.length > 0 && values.file)) {
|
|
1834
|
+
throw new CommandError(MOTIONS_ABM_COMPANIES_ADD_USAGE);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
const entries = values.file ? await motionAbmCompanyEntriesFromFile(values.file) : positionals;
|
|
1838
|
+
if (entries.length === 0) throw new CommandError(MOTIONS_ABM_COMPANIES_ADD_USAGE);
|
|
1839
|
+
|
|
1840
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1841
|
+
const payload = await client.addMotionAbmCompanies(accountId, motionId, { abm_companies: entries });
|
|
1842
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1843
|
+
|
|
1844
|
+
writeLine(context.stdout, `Company filters: ${Array.isArray(payload?.abm_companies) ? payload.abm_companies.length : 0}`);
|
|
1845
|
+
renderMotionAbmCompanies(payload, context);
|
|
1846
|
+
renderMotionAbmCompanyErrors(payload, context);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
async function motionsAbmCompaniesRemove(motionId, args, context, { accountOverride } = {}) {
|
|
1850
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1851
|
+
if (positionals.length !== 1) throw new CommandError(MOTIONS_ABM_COMPANIES_REMOVE_USAGE);
|
|
1852
|
+
|
|
1853
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1854
|
+
const payload = await client.removeMotionAbmCompany(accountId, motionId, positionals[0]);
|
|
1855
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1856
|
+
|
|
1857
|
+
writeLine(context.stdout, `Removed company filter ${display(positionals[0])} from motion ${display(payload?.motion_id || motionId)}.`);
|
|
1858
|
+
renderMotionAbmCompanies(payload, context);
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1696
1861
|
async function motionsDelete(args, context, { accountOverride } = {}) {
|
|
1697
1862
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1698
1863
|
...jsonOptions(),
|
|
@@ -1737,7 +1902,9 @@ async function motionUpdatePayload(values) {
|
|
|
1737
1902
|
throw new CommandError("Choose one motion input mode: either --payload <file.json> or the simple --status/--tags/--own-post-engagement flags.");
|
|
1738
1903
|
}
|
|
1739
1904
|
|
|
1740
|
-
|
|
1905
|
+
const payload = await readJsonPayload(values.payload);
|
|
1906
|
+
validateMotionSignalRows(payload);
|
|
1907
|
+
return payload;
|
|
1741
1908
|
}
|
|
1742
1909
|
|
|
1743
1910
|
return compactObject({
|
|
@@ -1751,6 +1918,41 @@ function motionSimpleFieldsPresent(values) {
|
|
|
1751
1918
|
return Boolean(values.status) || values.tags !== undefined || values["own-post-engagement"] !== undefined;
|
|
1752
1919
|
}
|
|
1753
1920
|
|
|
1921
|
+
function validateMotionSignalRows(payload) {
|
|
1922
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return;
|
|
1923
|
+
|
|
1924
|
+
for (const row of Array.isArray(payload.signal_rows) ? payload.signal_rows : []) {
|
|
1925
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) continue;
|
|
1926
|
+
if (!String(row.posting_language || "").trim()) continue;
|
|
1927
|
+
|
|
1928
|
+
const scope = String(row.scope || "company").trim().toLowerCase();
|
|
1929
|
+
const category = String(row.company_signal_category || "").trim().toLowerCase();
|
|
1930
|
+
if (scope === "company" && category === "hiring") continue;
|
|
1931
|
+
|
|
1932
|
+
throw new CommandError("posting_language is only supported on company-scope hiring signal rows.");
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
async function motionAbmCompanyEntriesFromFile(path) {
|
|
1937
|
+
const contents = await readFile(path, "utf8");
|
|
1938
|
+
const trimmed = contents.trim();
|
|
1939
|
+
if (!trimmed) return [];
|
|
1940
|
+
|
|
1941
|
+
try {
|
|
1942
|
+
const parsed = JSON.parse(trimmed);
|
|
1943
|
+
if (Array.isArray(parsed)) return parsed;
|
|
1944
|
+
if (parsed && typeof parsed === "object") {
|
|
1945
|
+
return Array.isArray(parsed.abm_companies) ? parsed.abm_companies :
|
|
1946
|
+
(Array.isArray(parsed.company_filters) ? parsed.company_filters :
|
|
1947
|
+
(Array.isArray(parsed.items) ? parsed.items : []));
|
|
1948
|
+
}
|
|
1949
|
+
} catch {
|
|
1950
|
+
// Plain text files use one company domain or LinkedIn company URL per line.
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
return trimmed.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1754
1956
|
async function motionsStatusShortcut(action, args, context, { accountOverride } = {}) {
|
|
1755
1957
|
const usage = `Usage: audienti motions ${action} <motn_id> [--json] [--account <acct_id>]`;
|
|
1756
1958
|
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
@@ -4035,6 +4237,30 @@ function renderList(list, context) {
|
|
|
4035
4237
|
if (list?.description) writeLine(context.stdout, `Description: ${list.description}`);
|
|
4036
4238
|
}
|
|
4037
4239
|
|
|
4240
|
+
function renderListRoutingRules(payload, context) {
|
|
4241
|
+
const rules = Array.isArray(payload?.routing_rules) ? payload.routing_rules : [];
|
|
4242
|
+
if (rules.length === 0) return writeLine(context.stdout, "No routing rules found.");
|
|
4243
|
+
|
|
4244
|
+
writeLine(context.stdout, "RULE ID\tPOSITION\tENABLED\tACTION\tTARGET\tNAME");
|
|
4245
|
+
for (const rule of rules) {
|
|
4246
|
+
writeLine(context.stdout, [
|
|
4247
|
+
display(rule.id),
|
|
4248
|
+
display(rule.position),
|
|
4249
|
+
rule.enabled ? "yes" : "no",
|
|
4250
|
+
display(rule.action_kind),
|
|
4251
|
+
routingRuleTargetLabel(rule),
|
|
4252
|
+
display(rule.name)
|
|
4253
|
+
].join("\t"));
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4257
|
+
function routingRuleTargetLabel(rule) {
|
|
4258
|
+
return rule?.target_account_user?.name ||
|
|
4259
|
+
rule?.target_account_user?.email ||
|
|
4260
|
+
rule?.target_list?.name ||
|
|
4261
|
+
"-";
|
|
4262
|
+
}
|
|
4263
|
+
|
|
4038
4264
|
function renderTags(tags, context) {
|
|
4039
4265
|
if (!Array.isArray(tags) || tags.length === 0) return writeLine(context.stdout, "No tags found.");
|
|
4040
4266
|
|
|
@@ -4228,7 +4454,7 @@ function renderOffer(offer, context) {
|
|
|
4228
4454
|
function renderIcps(icps, context) {
|
|
4229
4455
|
if (!Array.isArray(icps) || icps.length === 0) return writeLine(context.stdout, "No ICPs found.");
|
|
4230
4456
|
|
|
4231
|
-
writeLine(context.stdout, "ICP ID\tNAME\tTAGS\tDISCOVERY KEYWORD\tAGENT");
|
|
4457
|
+
writeLine(context.stdout, "ICP ID\tNAME\tTAGS\tDISCOVERY KEYWORD\tSENIORITY MODE\tAGENT");
|
|
4232
4458
|
for (const icp of icps) {
|
|
4233
4459
|
writeLine(
|
|
4234
4460
|
context.stdout,
|
|
@@ -4237,6 +4463,7 @@ function renderIcps(icps, context) {
|
|
|
4237
4463
|
display(icp.name),
|
|
4238
4464
|
display(Array.isArray(icp.tags) && icp.tags.length > 0 ? icp.tags.join(",") : "-"),
|
|
4239
4465
|
display(icp.discovery_keyword),
|
|
4466
|
+
display(icp.seniority_match_mode),
|
|
4240
4467
|
display(icp.agent?.name)
|
|
4241
4468
|
].join("\t")
|
|
4242
4469
|
);
|
|
@@ -4248,6 +4475,7 @@ function renderIcp(icp, context) {
|
|
|
4248
4475
|
if (Array.isArray(icp?.tags)) writeLine(context.stdout, `Tags: ${display(icp.tags.join(", "), "-")}`);
|
|
4249
4476
|
if (icp?.notes) writeLine(context.stdout, `Notes: ${icp.notes}`);
|
|
4250
4477
|
if (icp?.discovery_keyword) writeLine(context.stdout, `Discovery keyword: ${icp.discovery_keyword}`);
|
|
4478
|
+
if (icp?.seniority_match_mode) writeLine(context.stdout, `Seniority match mode: ${icp.seniority_match_mode}`);
|
|
4251
4479
|
if (icp?.agent?.name) writeLine(context.stdout, `Agent: ${icp.agent.name}`);
|
|
4252
4480
|
}
|
|
4253
4481
|
|
|
@@ -4365,6 +4593,10 @@ function renderMotion(motion, context) {
|
|
|
4365
4593
|
if (motion?.icp?.name) writeLine(context.stdout, `ICP: ${motion.icp.name} (${display(motion.icp.prefix_id)})`);
|
|
4366
4594
|
if (motion?.list?.name) writeLine(context.stdout, `List: ${motion.list.name} (${display(motion.list.prefix_id)})`);
|
|
4367
4595
|
writeLine(context.stdout, `Own-post engagement: ${motion?.own_post_engagement ? "enabled" : "disabled"}`);
|
|
4596
|
+
if (Array.isArray(motion?.inbound_channels)) writeLine(context.stdout, `Inbound channels: ${display(motion.inbound_channels.join(", "), "-")}`);
|
|
4597
|
+
renderMotionLopaProfiles(motion?.lopa_profiles, context);
|
|
4598
|
+
renderMotionSignalRows(motion?.signal_rows, context);
|
|
4599
|
+
renderMotionAbmCompanies(motion, context, { showEmpty: false });
|
|
4368
4600
|
if (Array.isArray(motion?.play_tags)) writeLine(context.stdout, `Tags: ${display(motion.play_tags.join(", "), "-")}`);
|
|
4369
4601
|
if (motion?.principal_account_user?.id) {
|
|
4370
4602
|
writeLine(
|
|
@@ -4374,6 +4606,55 @@ function renderMotion(motion, context) {
|
|
|
4374
4606
|
}
|
|
4375
4607
|
}
|
|
4376
4608
|
|
|
4609
|
+
function renderMotionLopaProfiles(rows, context) {
|
|
4610
|
+
if (!Array.isArray(rows) || rows.length === 0) return;
|
|
4611
|
+
|
|
4612
|
+
writeLine(context.stdout, "LOPA profiles:");
|
|
4613
|
+
for (const row of rows) {
|
|
4614
|
+
writeLine(context.stdout, `- ${display(row.url)} (${display(row.source_type, "other")})`);
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
|
|
4618
|
+
function renderMotionSignalRows(rows, context) {
|
|
4619
|
+
if (!Array.isArray(rows) || rows.length === 0) return;
|
|
4620
|
+
|
|
4621
|
+
writeLine(context.stdout, "Signal rows:");
|
|
4622
|
+
for (const row of rows) {
|
|
4623
|
+
const filters = [
|
|
4624
|
+
row.company_signal_category ? `category=${row.company_signal_category}` : null,
|
|
4625
|
+
row.role_terms ? `roles=${singleLine(row.role_terms)}` : null,
|
|
4626
|
+
row.posting_language ? `posting_language=${singleLine(row.posting_language)}` : null,
|
|
4627
|
+
row.topics ? `topics=${singleLine(row.topics)}` : null
|
|
4628
|
+
].filter(Boolean).join("; ");
|
|
4629
|
+
writeLine(context.stdout, `- ${display(row.scope)}: ${display(row.question)}${filters ? ` [${filters}]` : ""}`);
|
|
4630
|
+
}
|
|
4631
|
+
}
|
|
4632
|
+
|
|
4633
|
+
function renderMotionAbmCompanies(payload, context, { showEmpty = true } = {}) {
|
|
4634
|
+
const rows = Array.isArray(payload?.abm_companies) ? payload.abm_companies : [];
|
|
4635
|
+
if (rows.length === 0) {
|
|
4636
|
+
if (showEmpty) writeLine(context.stdout, "No company filters found.");
|
|
4637
|
+
return;
|
|
4638
|
+
}
|
|
4639
|
+
|
|
4640
|
+
writeAlignedTable(context, ["ROW ID", "KIND", "VALUE", "STATUS"], rows.map((row) => [
|
|
4641
|
+
display(row.id),
|
|
4642
|
+
display(row.kind),
|
|
4643
|
+
display(row.normalized_value || row.raw_value),
|
|
4644
|
+
display(row.status)
|
|
4645
|
+
]));
|
|
4646
|
+
}
|
|
4647
|
+
|
|
4648
|
+
function renderMotionAbmCompanyErrors(payload, context) {
|
|
4649
|
+
const errors = Array.isArray(payload?.errors) ? payload.errors : [];
|
|
4650
|
+
if (errors.length === 0) return;
|
|
4651
|
+
|
|
4652
|
+
writeLine(context.stdout, "Errors:");
|
|
4653
|
+
for (const error of errors) {
|
|
4654
|
+
writeLine(context.stdout, `- ${display(error.input)}: ${display(error.error)}`);
|
|
4655
|
+
}
|
|
4656
|
+
}
|
|
4657
|
+
|
|
4377
4658
|
function renderContentPrograms(programs, context) {
|
|
4378
4659
|
if (!Array.isArray(programs) || programs.length === 0) return writeLine(context.stdout, "No ContentOps programs found.");
|
|
4379
4660
|
|
|
@@ -5992,6 +6273,10 @@ function display(value, fallback = "") {
|
|
|
5992
6273
|
return value === undefined || value === null || value === "" ? fallback : value;
|
|
5993
6274
|
}
|
|
5994
6275
|
|
|
6276
|
+
function singleLine(value) {
|
|
6277
|
+
return String(value || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(", ");
|
|
6278
|
+
}
|
|
6279
|
+
|
|
5995
6280
|
function prospectsToCsv(prospects) {
|
|
5996
6281
|
const profileIdentifiers = profileIdentifiersForPayload({ meta: {} }, prospects);
|
|
5997
6282
|
const headers = [
|
|
@@ -6288,6 +6573,8 @@ const HELP_TOPICS = new Map([
|
|
|
6288
6573
|
" audienti motions run-discovery <motn_id>",
|
|
6289
6574
|
" audienti motions quick-start --url <company_url> --confirm --wait",
|
|
6290
6575
|
" audienti motions prospects <motn_id>",
|
|
6576
|
+
" audienti motions abm-companies <motn_id> list",
|
|
6577
|
+
" audienti motions abm-companies <motn_id> add <domain_or_linkedin_url>...",
|
|
6291
6578
|
" audienti motions create --payload <file.json>",
|
|
6292
6579
|
" audienti motions update <motn_id> [--status <state>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>]",
|
|
6293
6580
|
" audienti motions update <motn_id> --payload <file.json>",
|
|
@@ -6334,6 +6621,9 @@ const HELP_TOPICS = new Map([
|
|
|
6334
6621
|
" audienti lists prospects <list_id>",
|
|
6335
6622
|
" audienti lists add-tag <list_id> <tag>",
|
|
6336
6623
|
" audienti lists remove-tag <list_id> <tag>",
|
|
6624
|
+
" audienti lists routing-rules <list_id> list",
|
|
6625
|
+
" audienti lists routing-rules <list_id> create --payload <file.json>",
|
|
6626
|
+
" audienti lists routing-rules <list_id> apply",
|
|
6337
6627
|
" audienti tags list",
|
|
6338
6628
|
" audienti tags show <tag>",
|
|
6339
6629
|
" audienti tasks list [--status open]",
|
|
@@ -7314,13 +7604,63 @@ const HELP_TOPICS = new Map([
|
|
|
7314
7604
|
" audienti lists prospects <list_id> [--json]",
|
|
7315
7605
|
" audienti lists add-prospects <list_id> <prsp_id> [prsp_id...] [--json]",
|
|
7316
7606
|
" audienti lists remove-prospects <list_id> <prsp_id> [prsp_id...] [--json]",
|
|
7607
|
+
" audienti lists routing-rules <list_id> <list|create|update|remove|move|apply> [args] [--json]",
|
|
7317
7608
|
"",
|
|
7318
|
-
"Status: read, create, update, delete, and
|
|
7609
|
+
"Status: read, create, update, delete, membership, and routing-rule commands implemented",
|
|
7319
7610
|
"",
|
|
7320
7611
|
"ID shape:",
|
|
7321
7612
|
" list_id: list_ prefix id"
|
|
7322
7613
|
].join("\n")],
|
|
7323
7614
|
|
|
7615
|
+
["lists routing-rules", [
|
|
7616
|
+
"Usage:",
|
|
7617
|
+
" audienti lists routing-rules <list_id> list [--json] [--account <acct_id>]",
|
|
7618
|
+
" audienti lists routing-rules <list_id> create --payload <file.json> [--json] [--account <acct_id>]",
|
|
7619
|
+
" audienti lists routing-rules <list_id> update <rule_id> --payload <file.json> [--json] [--account <acct_id>]",
|
|
7620
|
+
" audienti lists routing-rules <list_id> remove <rule_id> [--json] [--account <acct_id>]",
|
|
7621
|
+
" audienti lists routing-rules <list_id> move <rule_id> <up|down> [--json] [--account <acct_id>]",
|
|
7622
|
+
" audienti lists routing-rules <list_id> apply [--json] [--account <acct_id>]",
|
|
7623
|
+
"",
|
|
7624
|
+
"Status: implemented",
|
|
7625
|
+
"",
|
|
7626
|
+
"Purpose:",
|
|
7627
|
+
" Configure, inspect, reorder, and relaunch the same routing rules available in the list UI.",
|
|
7628
|
+
" Apply only queues the existing background job; it does not wait for routing to finish.",
|
|
7629
|
+
"",
|
|
7630
|
+
"Payload shape:",
|
|
7631
|
+
" name: string",
|
|
7632
|
+
" enabled: boolean | optional",
|
|
7633
|
+
" position: non-negative integer | optional",
|
|
7634
|
+
" action_kind: assign_user | route_to_list",
|
|
7635
|
+
" target_account_user_id: account-user id, email, or me | required for assign_user",
|
|
7636
|
+
" target_list_id: list_ prefix id or numeric id | required for route_to_list",
|
|
7637
|
+
" conditions: object | optional",
|
|
7638
|
+
"",
|
|
7639
|
+
"Condition keys:",
|
|
7640
|
+
" locations, company_locations, seniorities, job_titles, bio_texts,",
|
|
7641
|
+
" company_sizes, company_types, company_keywords, seniority_match_mode, industry_groups",
|
|
7642
|
+
"",
|
|
7643
|
+
"Example payload file:",
|
|
7644
|
+
" {",
|
|
7645
|
+
" \"name\": \"VP prospects to Alice\",",
|
|
7646
|
+
" \"enabled\": true,",
|
|
7647
|
+
" \"action_kind\": \"assign_user\",",
|
|
7648
|
+
" \"target_account_user_id\": \"alice@example.com\",",
|
|
7649
|
+
" \"conditions\": {",
|
|
7650
|
+
" \"seniorities\": [{\"id\": \"5\", \"name\": \"Vice President\", \"negative\": false}],",
|
|
7651
|
+
" \"seniority_match_mode\": \"at_least\"",
|
|
7652
|
+
" }",
|
|
7653
|
+
" }",
|
|
7654
|
+
"",
|
|
7655
|
+
"API:",
|
|
7656
|
+
" GET /api/v1/accounts/:account_id/lists/:list_id/routing_rules.json",
|
|
7657
|
+
" POST /api/v1/accounts/:account_id/lists/:list_id/routing_rules.json",
|
|
7658
|
+
" PATCH /api/v1/accounts/:account_id/lists/:list_id/routing_rules/:id.json",
|
|
7659
|
+
" DELETE /api/v1/accounts/:account_id/lists/:list_id/routing_rules/:id.json",
|
|
7660
|
+
" PATCH /api/v1/accounts/:account_id/lists/:list_id/routing_rules/:id/move.json",
|
|
7661
|
+
" POST /api/v1/accounts/:account_id/lists/:list_id/routing_rules/apply.json"
|
|
7662
|
+
].join("\n")],
|
|
7663
|
+
|
|
7324
7664
|
["lists list", [
|
|
7325
7665
|
"Usage:",
|
|
7326
7666
|
" audienti lists list [--tag <tag>] [--json] [--account <acct_id>]",
|
|
@@ -7555,6 +7895,9 @@ const HELP_TOPICS = new Map([
|
|
|
7555
7895
|
" audienti motions analytics <motn_id> [--window 30d] [--json]",
|
|
7556
7896
|
" audienti motions prospects <motn_id> [--json]",
|
|
7557
7897
|
" audienti motions add-prospects <motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
7898
|
+
" audienti motions abm-companies <motn_id> list [--json]",
|
|
7899
|
+
" audienti motions abm-companies <motn_id> add (<domain_or_linkedin_url>... | --file <txt|json>) [--json]",
|
|
7900
|
+
" audienti motions abm-companies <motn_id> remove <row_id> [--json]",
|
|
7558
7901
|
" audienti motions create --payload <file.json> [--json]",
|
|
7559
7902
|
" audienti motions update <motn_id> ([--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] | --payload <file.json>) [--json]",
|
|
7560
7903
|
" audienti motions add-tag <motn_id> <tag> [--json]",
|
|
@@ -7637,10 +7980,38 @@ const HELP_TOPICS = new Map([
|
|
|
7637
7980
|
"Input shape:",
|
|
7638
7981
|
" motn_id: motn_ prefix id",
|
|
7639
7982
|
"",
|
|
7983
|
+
"Output shape:",
|
|
7984
|
+
" inbound_channels: enabled inbound collectors for inbound motions",
|
|
7985
|
+
" lopa_profiles[]: tracked LinkedIn profile rows for LOPA motions",
|
|
7986
|
+
" signal_rows[]: outbound signal configuration rows",
|
|
7987
|
+
" abm_companies[]: motion-scoped positive company filter rows",
|
|
7988
|
+
"",
|
|
7640
7989
|
"API:",
|
|
7641
7990
|
" GET /api/v1/accounts/:account_id/motions/:id.json"
|
|
7642
7991
|
].join("\n")],
|
|
7643
7992
|
|
|
7993
|
+
["motions abm-companies", [
|
|
7994
|
+
"Usage:",
|
|
7995
|
+
` ${MOTIONS_ABM_COMPANIES_LIST_USAGE.slice("Usage: ".length)}`,
|
|
7996
|
+
` ${MOTIONS_ABM_COMPANIES_ADD_USAGE.slice("Usage: ".length)}`,
|
|
7997
|
+
` ${MOTIONS_ABM_COMPANIES_REMOVE_USAGE.slice("Usage: ".length)}`,
|
|
7998
|
+
"",
|
|
7999
|
+
"Status: implemented",
|
|
8000
|
+
"",
|
|
8001
|
+
"Purpose:",
|
|
8002
|
+
" Manage a motion-scoped positive company filter list for isolated ABM discovery runs.",
|
|
8003
|
+
"",
|
|
8004
|
+
"Input shape:",
|
|
8005
|
+
" motn_id: motn_ prefix id",
|
|
8006
|
+
" domain_or_linkedin_url: company domain or LinkedIn company page URL",
|
|
8007
|
+
" file: plain text one entry per line, or JSON array / { abm_companies: [...] }",
|
|
8008
|
+
"",
|
|
8009
|
+
"API:",
|
|
8010
|
+
" GET /api/v1/accounts/:account_id/motions/:motion_id/abm_companies.json",
|
|
8011
|
+
" POST /api/v1/accounts/:account_id/motions/:motion_id/abm_companies.json",
|
|
8012
|
+
" DELETE /api/v1/accounts/:account_id/motions/:motion_id/abm_companies/:row_id.json"
|
|
8013
|
+
].join("\n")],
|
|
8014
|
+
|
|
7644
8015
|
["motions status", [
|
|
7645
8016
|
"Usage:",
|
|
7646
8017
|
" audienti motions status <motn_id> [--json] [--account <acct_id>]",
|
|
@@ -7806,7 +8177,7 @@ const HELP_TOPICS = new Map([
|
|
|
7806
8177
|
" icp_id: icpp_ prefix id | optional",
|
|
7807
8178
|
" list_id: list_ prefix id | optional",
|
|
7808
8179
|
" play_tags: [string] | optional",
|
|
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",
|
|
8180
|
+
" 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",
|
|
7810
8181
|
" signal_questions: newline-delimited company::, person::, or both:: legacy question text | optional for outbound motions",
|
|
7811
8182
|
" inbound_channels: [linkedin | reddit] | optional; defaults to [linkedin] for inbound motions",
|
|
7812
8183
|
" lopa_profiles: [{ url: string, source_type: creator | competitor | partner | customer | other }] | optional",
|
|
@@ -7825,6 +8196,7 @@ const HELP_TOPICS = new Map([
|
|
|
7825
8196
|
"",
|
|
7826
8197
|
"Behavior:",
|
|
7827
8198
|
" The API calls Motions::Setup and the managed graph provisioner. If principal_account_user_id is omitted, the authenticated account user is used.",
|
|
8199
|
+
" posting_language is only supported on company-scope hiring signal rows; use topics for person discussion evidence.",
|
|
7828
8200
|
" Use `audienti offers list`, `audienti icps list`, and `audienti users list` to resolve valid ids before calling this command."
|
|
7829
8201
|
].join("\n")],
|
|
7830
8202
|
|
|
@@ -7874,6 +8246,7 @@ const HELP_TOPICS = new Map([
|
|
|
7874
8246
|
"Behavior:",
|
|
7875
8247
|
" Choose either --payload or simple flags. Updates only the provided fields. Sending --tags replaces the motion's full tag set.",
|
|
7876
8248
|
" Payload mode supports outbound signal_rows or legacy signal_questions; supplied rows replace the motion's active ready signals.",
|
|
8249
|
+
" posting_language is only supported on company-scope hiring signal rows; use topics for person discussion evidence.",
|
|
7877
8250
|
"",
|
|
7878
8251
|
"API:",
|
|
7879
8252
|
" PATCH /api/v1/accounts/:account_id/motions/:id.json",
|
|
@@ -9298,6 +9671,7 @@ const HELP_TOPICS = new Map([
|
|
|
9298
9671
|
"2. Create a motion or play",
|
|
9299
9672
|
" audienti setup play preflight --principal <account_user_id|me> --platform linkedin",
|
|
9300
9673
|
" audienti motions create --payload <file.json>",
|
|
9674
|
+
" audienti motions abm-companies <motn_id> add --file abm-domains.txt",
|
|
9301
9675
|
" audienti motions clone <motn_id> --name \"New subset motion\"",
|
|
9302
9676
|
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...]",
|
|
9303
9677
|
" audienti motions activate <motn_id>",
|