@audienti/cli 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/api-client.js +14 -0
- package/src/cli.js +113 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.8] - 2026-07-14
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `audienti motions clone <motn_id> --name <text>` to clone a motion/play config through the API without copying people.
|
|
12
|
+
- Add `audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...]` to transfer prospects between motions/plays.
|
|
13
|
+
|
|
7
14
|
## [0.1.7] - 2026-07-12
|
|
8
15
|
|
|
9
16
|
### Fixed
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -130,6 +130,20 @@ export class AudientiClient {
|
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
cloneMotion(accountId, motionId, body) {
|
|
134
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "clone"]), {
|
|
135
|
+
method: "POST",
|
|
136
|
+
body
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
moveMotionProspects(accountId, motionId, body) {
|
|
141
|
+
return this.requestJson(accountPath(accountId, ["motions", motionId, "move_prospects"]), {
|
|
142
|
+
method: "POST",
|
|
143
|
+
body
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
133
147
|
motionStatus(accountId, motionId) {
|
|
134
148
|
return this.requestJson(accountPath(accountId, ["motions", motionId, "status"]));
|
|
135
149
|
}
|
package/src/cli.js
CHANGED
|
@@ -31,6 +31,8 @@ const PROSPECTS_ADD_PROFILE_USAGE = "Usage: audienti prospects add-profile <prsp
|
|
|
31
31
|
const PROSPECTS_REPORT_BAD_PROFILE_USAGE = "Usage: audienti prospects report-bad-profile <prsp_id> <prof_id|citation_id> [--json] [--account <acct_id>]";
|
|
32
32
|
const WRITER_TEST_RUN_USAGE = "Usage: audienti writer test-run <prsp_id> [--json] [--mode <report|plan|step>] [--branch <both|no-accept|accepted>] [--step <step_key|row_number>] [--no-cache] [--clear-cache] [--account <acct_id>]";
|
|
33
33
|
const MOTIONS_ANALYTICS_USAGE = "Usage: audienti motions analytics <motn_id> [--window 30d] [--json] [--account <acct_id>]";
|
|
34
|
+
const MOTIONS_CLONE_USAGE = "Usage: audienti motions clone <motn_id> --name <text> [--json] [--account <acct_id>]";
|
|
35
|
+
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>]";
|
|
34
36
|
const ANALYTICS_PROSPECTS_USAGE = "Usage: audienti analytics prospects [--window 24h] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--motion <motn_id>] [--provenance <source>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
35
37
|
const ANALYTICS_PROSPECTS_COHORT_ANALYSIS_USAGE = "Usage: audienti analytics prospects cohort-analysis [--weeks <n>] [--window 24h] [--motion <motn_id>] [--provenance <source>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
36
38
|
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>] [--provenance <source>] [--platform <linkedin|email|gmail>] [--json] [--account <acct_id>]";
|
|
@@ -135,6 +137,8 @@ async function dispatch(argv, context) {
|
|
|
135
137
|
if (normalizedResource === "motions" && action === "prospects") return motionsProspects(rest, context, { accountOverride });
|
|
136
138
|
if (normalizedResource === "motions" && action === "add-prospects") return motionsAddProspects(rest, context, { accountOverride });
|
|
137
139
|
if (normalizedResource === "motions" && action === "create") return motionsCreate(rest, context, { accountOverride });
|
|
140
|
+
if (normalizedResource === "motions" && action === "clone") return motionsClone(rest, context, { accountOverride });
|
|
141
|
+
if (normalizedResource === "motions" && action === "move-prospects") return motionsMoveProspects(rest, context, { accountOverride });
|
|
138
142
|
if (normalizedResource === "prospects" && action === "list") return prospectsList(rest, context, { accountOverride });
|
|
139
143
|
if (normalizedResource === "prospects" && action === "show") return prospectsShow(rest, context, { accountOverride });
|
|
140
144
|
if (normalizedResource === "prospects" && action === "timeline") return prospectsTimeline(rest, context, { accountOverride });
|
|
@@ -782,6 +786,52 @@ async function motionsCreate(args, context, { accountOverride } = {}) {
|
|
|
782
786
|
renderMotion(created, context);
|
|
783
787
|
}
|
|
784
788
|
|
|
789
|
+
async function motionsClone(args, context, { accountOverride } = {}) {
|
|
790
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
791
|
+
...jsonOptions(),
|
|
792
|
+
name: { type: "string" }
|
|
793
|
+
});
|
|
794
|
+
if (positionals.length !== 1 || !values.name) {
|
|
795
|
+
throw new CommandError(MOTIONS_CLONE_USAGE);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
799
|
+
const cloned = await client.cloneMotion(accountId, positionals[0], {
|
|
800
|
+
motion: {
|
|
801
|
+
name: values.name
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
if (values.json) return writeJson(context.stdout, cloned);
|
|
805
|
+
|
|
806
|
+
writeLine(context.stdout, `Cloned motion ${display(positionals[0])} as ${display(cloned?.name)} (${display(cloned?.prefix_id)}).`);
|
|
807
|
+
renderMotion(cloned, context);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
async function motionsMoveProspects(args, context, { accountOverride } = {}) {
|
|
811
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
812
|
+
...jsonOptions(),
|
|
813
|
+
target: { type: "string" }
|
|
814
|
+
});
|
|
815
|
+
if (positionals.length < 2 || !values.target) {
|
|
816
|
+
throw new CommandError(MOTIONS_MOVE_PROSPECTS_USAGE);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
const [sourceMotionId, ...prospectIds] = positionals;
|
|
820
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
821
|
+
const payload = await client.moveMotionProspects(accountId, sourceMotionId, {
|
|
822
|
+
target_motion_id: values.target,
|
|
823
|
+
prospect_ids: prospectIds
|
|
824
|
+
});
|
|
825
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
826
|
+
|
|
827
|
+
const moved = Number(payload?.moved || 0);
|
|
828
|
+
const failed = Array.isArray(payload?.failed) ? payload.failed.length : 0;
|
|
829
|
+
writeLine(context.stdout, `Moved ${moved} prospects from ${display(sourceMotionId)} to ${display(values.target)}.`);
|
|
830
|
+
if (failed > 0) {
|
|
831
|
+
writeLine(context.stdout, `${failed} prospects failed.`);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
785
835
|
async function prospectsList(args, context, { accountOverride } = {}) {
|
|
786
836
|
const { values, positionals } = parseCommandArgs(args, {
|
|
787
837
|
...jsonOptions(),
|
|
@@ -3270,6 +3320,8 @@ const HELP_TOPICS = new Map([
|
|
|
3270
3320
|
" audienti motions analytics <motn_id>",
|
|
3271
3321
|
" audienti motions prospects <motn_id>",
|
|
3272
3322
|
" audienti motions create --payload <file.json>",
|
|
3323
|
+
" audienti motions clone <motn_id> --name <text>",
|
|
3324
|
+
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...]",
|
|
3273
3325
|
" Tip: `plays` is accepted anywhere `motions` is accepted.",
|
|
3274
3326
|
"",
|
|
3275
3327
|
" Prospects",
|
|
@@ -3842,8 +3894,10 @@ const HELP_TOPICS = new Map([
|
|
|
3842
3894
|
" audienti motions prospects <motn_id> [--json]",
|
|
3843
3895
|
" audienti motions add-prospects <motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
3844
3896
|
" audienti motions create --payload <file.json> [--json]",
|
|
3897
|
+
" audienti motions clone <motn_id> --name <text> [--json]",
|
|
3898
|
+
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
3845
3899
|
"",
|
|
3846
|
-
"Status: read, create, status, and prospect attachment commands implemented",
|
|
3900
|
+
"Status: read, create, clone, status, and prospect attachment commands implemented",
|
|
3847
3901
|
"",
|
|
3848
3902
|
"CLI synonym:",
|
|
3849
3903
|
" `plays` is accepted anywhere `motions` is accepted",
|
|
@@ -4017,6 +4071,62 @@ const HELP_TOPICS = new Map([
|
|
|
4017
4071
|
" Use `audienti offers list`, `audienti icps list`, and `audienti users list` to resolve valid ids before calling this command."
|
|
4018
4072
|
].join("\n")],
|
|
4019
4073
|
|
|
4074
|
+
["motions clone", [
|
|
4075
|
+
"Usage:",
|
|
4076
|
+
` ${MOTIONS_CLONE_USAGE.slice("Usage: ".length)}`,
|
|
4077
|
+
"",
|
|
4078
|
+
"Status: implemented",
|
|
4079
|
+
"",
|
|
4080
|
+
"Purpose:",
|
|
4081
|
+
" Clone one motion or play's configuration under a new name without copying its people.",
|
|
4082
|
+
"",
|
|
4083
|
+
"Input shape:",
|
|
4084
|
+
" motn_id: motn_ prefix id",
|
|
4085
|
+
" name: new motion name",
|
|
4086
|
+
"",
|
|
4087
|
+
"Behavior:",
|
|
4088
|
+
" Copies the motion kind, offer, ICP, principal, premise, approach, targeting profile, suppression policy, secondary roles, and active signal rows.",
|
|
4089
|
+
" The clone starts as draft with a new empty backing list.",
|
|
4090
|
+
"",
|
|
4091
|
+
"API:",
|
|
4092
|
+
" POST /api/v1/accounts/:account_id/motions/:id/clone.json",
|
|
4093
|
+
"",
|
|
4094
|
+
"JSON body:",
|
|
4095
|
+
" {",
|
|
4096
|
+
" \"motion\": {",
|
|
4097
|
+
" \"name\": \"Wine Campaign Restaurant Operators\"",
|
|
4098
|
+
" }",
|
|
4099
|
+
" }"
|
|
4100
|
+
].join("\n")],
|
|
4101
|
+
|
|
4102
|
+
["motions move-prospects", [
|
|
4103
|
+
"Usage:",
|
|
4104
|
+
` ${MOTIONS_MOVE_PROSPECTS_USAGE.slice("Usage: ".length)}`,
|
|
4105
|
+
"",
|
|
4106
|
+
"Status: implemented",
|
|
4107
|
+
"",
|
|
4108
|
+
"Purpose:",
|
|
4109
|
+
" Move prospects out of one motion or play and into another motion or play.",
|
|
4110
|
+
"",
|
|
4111
|
+
"Input shape:",
|
|
4112
|
+
" source_motn_id: source motn_ prefix id",
|
|
4113
|
+
" target_motn_id: target motn_ prefix id",
|
|
4114
|
+
" prsp_id: one or more prospect prefix ids",
|
|
4115
|
+
"",
|
|
4116
|
+
"Behavior:",
|
|
4117
|
+
" Move removes each selected prospect from the source motion and source backing list, then adds it to the target motion and target backing list.",
|
|
4118
|
+
" Copy is intentionally not exposed until multi-motion membership exists.",
|
|
4119
|
+
"",
|
|
4120
|
+
"API:",
|
|
4121
|
+
" POST /api/v1/accounts/:account_id/motions/:id/move_prospects.json",
|
|
4122
|
+
"",
|
|
4123
|
+
"JSON body:",
|
|
4124
|
+
" {",
|
|
4125
|
+
" \"target_motion_id\": \"motn_target\",",
|
|
4126
|
+
" \"prospect_ids\": [\"prsp_one\", \"prsp_two\"]",
|
|
4127
|
+
" }"
|
|
4128
|
+
].join("\n")],
|
|
4129
|
+
|
|
4020
4130
|
["prospects", [
|
|
4021
4131
|
"Usage:",
|
|
4022
4132
|
" audienti prospects list [--json] [filters]",
|
|
@@ -4762,6 +4872,8 @@ const HELP_TOPICS = new Map([
|
|
|
4762
4872
|
"",
|
|
4763
4873
|
"2. Create a motion or play",
|
|
4764
4874
|
" audienti motions create --payload <file.json>",
|
|
4875
|
+
" audienti motions clone <motn_id> --name \"New subset motion\"",
|
|
4876
|
+
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...]",
|
|
4765
4877
|
" audienti motions status <motn_id>",
|
|
4766
4878
|
"",
|
|
4767
4879
|
"3. Add a new prospect from LinkedIn and poll enrichment",
|