@audienti/cli 0.1.44 → 0.1.50

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 CHANGED
@@ -4,6 +4,55 @@ All notable changes to the Audienti CLI are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.50] - 2026-09-02
8
+
9
+ ### Added
10
+
11
+ - Add preview-first `audienti prospects move-account` with dual-account selection, optional destination assignment, motion and list mappings, manifest-bound apply, stable human-readable summaries, and unchanged final JSON output.
12
+
13
+ ## [0.1.49] - 2026-09-02
14
+
15
+ ### Added
16
+
17
+ - Expose configured user and social-cookie proxy geography, effective proxy source, and server-calculated LinkedIn quotas, warm-up ramp, outstanding-invitation inventory state, and current invitation capacity in `audienti setup play preflight` without exposing proxy or authentication secrets.
18
+
19
+ ## [0.1.48] - 2026-09-02
20
+
21
+ ### Added
22
+
23
+ - Add account-scoped `audienti users automation show` and preview-first `update` commands for principal-specific LinkedIn controls, category and aggregate visibility limits, warm-up ramping, unchanged JSON readback, and explicit `--apply` persistence.
24
+ - Add reversible `audienti icps archive` and `restore` commands, active/archived/all list filtering, lifecycle status in ICP analytics, and inspectable primary-motion and preserved-secondary-link effects.
25
+
26
+ ## [0.1.47] - 2026-09-02
27
+
28
+ ### Added
29
+
30
+ - Expose server-derived social-cookie active days, working hours, effective timezone, and current in-window status in `audienti setup play preflight`.
31
+
32
+ ### Changed
33
+
34
+ - Allow `audienti motions update <motn_id> --payload <file.json>` to replace an account-scoped motion principal and backing list, including `list_id: null` clearing.
35
+
36
+ ## [0.1.46] - 2026-09-02
37
+
38
+ ### Added
39
+
40
+ - Add `audienti analytics icps` and the account-scoped ICP analytics API for current source-ICP prospect mix, rolling seven-day contribution, per-ICP counts, creation timestamps and human-readable ages, and explicit unattributed semantics.
41
+
42
+ ### Changed
43
+
44
+ - Allow `audienti motions update <motn_id> --status closing` for motion wind-downs that stop discovery while admitted Operator work drains.
45
+
46
+ ## [0.1.45] - 2026-09-02
47
+
48
+ ### Added
49
+
50
+ - Add `audienti analytics motions` and the account-scoped motion analytics API for current prospect mix, rolling seven-day recorded-source contribution, per-motion counts, explicit attribution semantics, and unchanged machine-readable JSON output.
51
+
52
+ ### Changed
53
+
54
+ - Keep Operator and analytics API responses within shared product visibility while preserving true-user authorization for Operator queues.
55
+
7
56
  ## [0.1.44] - 2026-09-01
8
57
 
9
58
  ### Added
package/README.md CHANGED
@@ -4,7 +4,8 @@ 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
- configure list routing rules, and work supported operator flows.
7
+ configure list routing rules and account-user automation safety, and work
8
+ supported operator flows.
8
9
 
9
10
  ## Install
10
11
 
@@ -137,14 +138,18 @@ Common inspection commands:
137
138
  audienti update check
138
139
  audienti operator next --plan
139
140
  audienti writer test-run <prsp_id>
141
+ audienti analytics motions --json
142
+ audienti analytics icps --json
140
143
  audienti motions analytics <motn_id>
141
144
  audienti motions run-discovery <motn_id>
142
145
  audienti motions quick-start --url https://example.com --wait --confirm
143
146
  audienti motions abm-companies <motn_id> add --file abm-domains.txt
144
147
  audienti motions abm-companies <motn_id> list
148
+ audienti motions update <motn_id> --status closing
145
149
  audienti motions update <motn_id> --status paused
146
150
  audienti motions update <motn_id> --start-date 2026-09-01 --end-date 2026-09-30 --maximum-company-count 25
147
151
  audienti motions update <motn_id> --own-post-engagement true
152
+ audienti motions update <motn_id> --payload motion-principal-list.json
148
153
  audienti motions update <motn_id> --payload motion-signals.json
149
154
  audienti motions activate <motn_id>
150
155
  audienti motions delete <motn_id> --confirm yes
@@ -167,6 +172,9 @@ audienti company-rules list
167
172
  audienti lists routing-rules <list_id> list
168
173
  audienti lists routing-rules <list_id> apply
169
174
  audienti users activity --window 7d
175
+ audienti users automation show 136 --platform linkedin --json --account <acct_id>
176
+ audienti users automation update 136 --payload automation-controls.json --json --account <acct_id>
177
+ audienti users automation update 136 --payload automation-controls.json --apply --json --account <acct_id>
170
178
  audienti analytics prospects --window 24h
171
179
  audienti analytics dashboard --play-tag wine_campaign
172
180
  audienti analytics metrics --cohort-preset week-to-date
@@ -318,6 +326,112 @@ happened later, such as connection requests sent in a date range. Rebuild the
318
326
  list when the event definition or date window changes so the analytics question
319
327
  stays auditable.
320
328
 
329
+ `audienti setup play preflight` includes the selected sender's server-derived
330
+ working schedule under `social_cookie.automation`, including `active_days`,
331
+ normalized `working_hours`, effective `time_zone`, and current
332
+ `in_working_hours` state. The human-readable output reports the same timezone,
333
+ today's window, and whether provider execution is currently inside the window.
334
+ It also reports the configured user fallback location, the connected account's
335
+ configured and last-verified effective proxy geography, and the proxy source
336
+ without exposing proxy URLs, credentials, egress IPs, or browser session data.
337
+ For LinkedIn, `social_cookie.automation.pacing` includes effective weekly
338
+ quotas, daily targets, motion active days, the outstanding-invitation cap, ramp
339
+ configuration, current outstanding inventory, any inventory blocker, and current
340
+ invitation capacity calculated by the server. A `null` weekly quota means
341
+ unlimited.
342
+
343
+ Use `users automation` to inspect or change one account user's LinkedIn safety
344
+ policy without changing the saved account selection:
345
+
346
+ ```bash
347
+ audienti users automation show 136 --platform linkedin --json --account acct_example
348
+ audienti users automation update 136 --payload automation-controls.json --json --account acct_example
349
+ audienti users automation update 136 --payload automation-controls.json --apply --json --account acct_example
350
+ ```
351
+
352
+ `update` is preview-only unless `--apply` is present. The CLI always sends
353
+ `platform: "linkedin"` and an explicit `apply` boolean after the file fields,
354
+ so a payload file cannot silently opt into applying a change. The server scopes
355
+ the connected account through the selected account plus account user, preserves
356
+ omitted controls, returns the before and proposed/actual after states, and
357
+ records an audit event only for an applied update. `--json` prints the server
358
+ payload unchanged.
359
+
360
+ An `automation-controls.json` warm-up payload can use every automation gate,
361
+ independent action limits, an aggregate visibility limit, and a weekly ramp:
362
+
363
+ ```json
364
+ {
365
+ "automation_controls": {
366
+ "automatic_sending_enabled": false,
367
+ "visibility_operations_autopilot_enabled": true,
368
+ "post_comment_autopilot_enabled": false,
369
+ "connection_request_autopilot_enabled": false,
370
+ "inmail_autopilot_enabled": false,
371
+ "direct_message_autopilot_enabled": false,
372
+ "email_sending_autopilot_enabled": false,
373
+ "manual_action_handoff_enabled": false,
374
+ "risk_cooldown_enabled": true
375
+ },
376
+ "action_limits": {
377
+ "profile_view": { "hourly": 2, "daily": 4, "weekly": 20 },
378
+ "follow": { "hourly": 2, "daily": 3, "weekly": 15 },
379
+ "like": { "hourly": 1, "daily": 2, "weekly": 10 },
380
+ "invite": { "hourly": 1, "daily": 2, "weekly": 10 },
381
+ "message": { "hourly": 1, "daily": 2, "weekly": 10 },
382
+ "comment": { "hourly": 1, "daily": 1, "weekly": 5 },
383
+ "visibility": { "hourly": 3, "daily": 8, "weekly": 40 }
384
+ },
385
+ "visibility_ramp": {
386
+ "enabled": true,
387
+ "starting_daily_limit": 8,
388
+ "weekly_increment": 2
389
+ }
390
+ }
391
+ ```
392
+
393
+ `follow` covers follows and unfollows; `like` covers likes and unlikes;
394
+ `message` covers messages and InMail. `visibility` is the aggregate cap across
395
+ profile views, follows/unfollows, and likes/unlikes. The show/preview readback
396
+ includes configured, default, effective, used, and remaining hourly, daily,
397
+ and weekly values plus the currently binding limits.
398
+
399
+ Motion update payload mode can replace the selected principal and backing list:
400
+
401
+ ```json
402
+ {
403
+ "principal_account_user_id": 136,
404
+ "list_id": "list_abc123"
405
+ }
406
+ ```
407
+
408
+ The principal and list are resolved inside the selected account. Use
409
+ `"list_id": null` to clear the backing list.
410
+
411
+ To inspect the account's current prospect mix by motion type and compare it
412
+ with the rolling seven-day recorded-source contribution:
413
+
414
+ ```bash
415
+ audienti analytics motions
416
+ audienti analytics motions --json
417
+ ```
418
+
419
+ Current Unattributed counts mean no current motion association. Rolling
420
+ seven-day Unattributed counts mean no attributable recorded source motion; the
421
+ server falls back to the current motion only when recorded source data is
422
+ blank.
423
+
424
+ To inspect the account's current prospect mix by source ICP and compare it
425
+ with the rolling seven-day source contribution:
426
+
427
+ ```bash
428
+ audienti analytics icps
429
+ audienti analytics icps --json
430
+ ```
431
+
432
+ Unattributed means no attributable account source ICP. The server falls back
433
+ to the current motion ICP only when recorded ICP source data is blank.
434
+
321
435
  To see whether one motion is producing prospects by day, and where each
322
436
  produced-day cohort currently sits in the funnel:
323
437
 
@@ -362,12 +476,19 @@ To create or update an ICP from a rich JSON payload:
362
476
  ```bash
363
477
  audienti icps create --payload icp.json
364
478
  audienti icps update <icp_id> --payload icp-patch.json
479
+ audienti icps list --status all
480
+ audienti icps archive <icp_id>
481
+ audienti icps restore <icp_id>
365
482
  ```
366
483
 
367
484
  `icps update --payload` accepts the same human-readable facet keys as create.
368
485
  Supplied facet collections, such as `company_sizes_attributes`, replace that
369
486
  collection in place; omitted fields and collections remain unchanged. Invalid
370
487
  lookup values fail server-side without partially applying the patch.
488
+ Archive is reversible and is the normal cleanup action. It removes the ICP from
489
+ new selection, closes active primary motions so admitted work can drain,
490
+ archives inactive primary motions, and preserves secondary motion links.
491
+ Restoring the ICP does not reactivate motions.
371
492
 
372
493
  To audit one account user's outbound actions, optionally narrowed to one motion
373
494
  and one AccountProspect.created_at cohort:
@@ -446,6 +567,19 @@ audienti prospects assign <prsp_id> --assigned-user <account_user_id|me>
446
567
  audienti prospects assign <prsp_id> --assigned-user unassign
447
568
  ```
448
569
 
570
+ To preview moving a prospect and its account-scoped history into another
571
+ account where you are also an administrator:
572
+
573
+ ```bash
574
+ audienti prospects move-account <prsp_id> --account <source_acct_id> --target-account <target_acct_id>
575
+ audienti prospects move-account <prsp_id> --account <source_acct_id> --target-account <target_acct_id> --assigned-user me --target-motion <motn_id> --target-list <list_id> --apply
576
+ ```
577
+
578
+ The command is preview-only unless `--apply` is present. Apply always requests
579
+ a fresh preview first and submits the returned `manifest_digest`, so a move is
580
+ rejected when the underlying state changes. `--json` prints the preview or final
581
+ apply response unchanged.
582
+
449
583
  To make emergency prospect state changes without going through a motion:
450
584
 
451
585
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audienti/cli",
3
- "version": "0.1.44",
3
+ "version": "0.1.50",
4
4
  "description": "Agent-first command-line client for Audienti.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -70,9 +70,17 @@ Useful MCP tools:
70
70
  - `auth.me` confirms the token identity.
71
71
  - `accounts.list` shows accessible accounts.
72
72
  - `setup.play_preflight` returns connected-account readiness and setup or
73
- mapping URLs.
73
+ mapping URLs, including the selected sender's active days, working hours,
74
+ effective timezone, current in-window status, configured user fallback
75
+ location, effective proxy geography and source, and server-calculated
76
+ LinkedIn pacing and outstanding-invitation inventory authority under
77
+ `social_cookie.automation`. Treat `ready: true` as connection readiness, not
78
+ approval to start automation.
74
79
  - `offers.create`, `icps.create`, and `motions.create` set up the offer, ICP,
75
80
  and play.
81
+ - Use `audienti icps list --status all` to audit active and archived ICPs. Use
82
+ `audienti icps archive <icp_id>` for reversible cleanup and `restore` to make
83
+ the ICP selectable again; restore never reactivates motions.
76
84
  - Use `audienti motions abm-companies <motn_id> add --file <txt|json>` to attach
77
85
  a positive company filter list for isolated ABM discovery runs.
78
86
  - `analytics.stages` returns stage conversion cohorts and stage aging.
@@ -85,6 +93,9 @@ Useful MCP tools:
85
93
  payload or behavior is unclear.
86
94
  - Inspect the current resource before a create, update, attach, delete, or
87
95
  operator outcome writeback.
96
+ - For account-user automation, run `users automation show`, then preview the
97
+ exact payload without `--apply`. Apply only after explicit authorization and
98
+ verify the applied response/readback.
88
99
  - Treat the production API as the source of truth. Persist durable work in
89
100
  Audienti rather than leaving it only in agent prose.
90
101
  - Keep current gaps explicit. Do not imply that unsupported actions execute.
@@ -96,10 +107,15 @@ audienti help agent-workflows
96
107
  audienti prospects list --query "name or company" --wide --json
97
108
  audienti prospects list --assigned-user unassigned --json
98
109
  audienti prospects assign <prsp_id> --assigned-user me --json
110
+ audienti prospects move-account <prsp_id> --account <source_acct_id> --target-account <target_acct_id> --json
111
+ audienti prospects move-account <prsp_id> --account <source_acct_id> --target-account <target_acct_id> --assigned-user me --apply --json
99
112
  audienti prospects set-status <prsp_id> --status not_fit --json
100
113
  audienti prospects lock <prsp_id> --note "Emergency hold" --json
101
114
  audienti prospects unlock <prsp_id> --json
102
115
  audienti users activity me --window 7d --json
116
+ audienti users automation show <account_user_id|me> --platform linkedin --json --account <acct_id>
117
+ audienti users automation update <account_user_id|me> --payload automation-controls.json --json --account <acct_id>
118
+ audienti users automation update <account_user_id|me> --payload automation-controls.json --apply --json --account <acct_id>
103
119
  audienti prospects import-batch --file prospects.csv --motion <motn_id> --assigned-user me --json
104
120
  audienti lists create --name "Target list" --json
105
121
  audienti lists routing-rules <list_id> list --json
@@ -111,10 +127,13 @@ audienti motions abm-companies <motn_id> add --file abm-domains.txt --json
111
127
  audienti motions abm-companies <motn_id> list --json
112
128
  audienti motions update <motn_id> --status paused --json
113
129
  audienti motions update <motn_id> --start-date 2026-09-01 --end-date 2026-09-30 --maximum-company-count 25 --json
130
+ audienti motions update <motn_id> --payload motion-principal-list.json --json
114
131
  audienti motions activate <motn_id> --json
115
132
  audienti motions delete <motn_id> --confirm yes --json
116
133
  audienti operator next --json
117
134
  audienti operator next --plan
135
+ audienti analytics motions --json
136
+ audienti analytics icps --json
118
137
  audienti analytics prospects --window 24h --json
119
138
  audienti analytics stages --window 30d
120
139
  audienti analytics visibility --window 24h --user me --json
@@ -132,6 +151,83 @@ audienti writer test-run <prsp_id> --mode step --branch no-accept --step 3 --rep
132
151
  audienti writer test-run show <prsp_id> <rprt_id>
133
152
  ```
134
153
 
154
+ ## Prospect Account Moves
155
+
156
+ Use `audienti prospects move-account` only to transfer one prospect and its
157
+ account-scoped history, not to copy it. `--account` is the source account and
158
+ `--target-account` is the destination. The authenticated user must administer
159
+ both accounts.
160
+
161
+ Start with a preview and inspect `eligible`, `blockers`, `mappings`,
162
+ `dispositions`, and `expected_state`:
163
+
164
+ ```bash
165
+ audienti prospects move-account <prsp_id> \
166
+ --account <source_acct_id> \
167
+ --target-account <target_acct_id> \
168
+ --assigned-user <target_account_user_id|me> \
169
+ --target-motion <target_motn_id> \
170
+ --target-list <target_list_id> \
171
+ --json
172
+ ```
173
+
174
+ Omit mappings that were not explicitly chosen; never infer a target motion,
175
+ list, agent, or research mapping by name. Apply only after the preview is
176
+ eligible and the user authorizes the move:
177
+
178
+ ```bash
179
+ audienti prospects move-account <prsp_id> \
180
+ --account <source_acct_id> \
181
+ --target-account <target_acct_id> \
182
+ --assigned-user <target_account_user_id|me> \
183
+ --target-motion <target_motn_id> \
184
+ --target-list <target_list_id> \
185
+ --apply \
186
+ --json
187
+ ```
188
+
189
+ With `--apply`, the CLI performs a fresh preview and submits that response's
190
+ `manifest_digest`; it does not reuse an older preview. Treat a stale manifest,
191
+ any blocker, or any failed response as not applied, then inspect current source
192
+ and target state before retrying.
193
+
194
+ ## Account-User Automation Safety
195
+
196
+ `audienti users automation show <account_user_id|me>` resolves one connected
197
+ account through the selected account, account user, and LinkedIn platform. Use
198
+ per-command `--account` for administrative inspection without changing the
199
+ saved default. Fail closed on API ambiguity or missing access; do not substitute
200
+ another connected account.
201
+
202
+ Automation updates are preview-first:
203
+
204
+ ```bash
205
+ audienti users automation show 136 --platform linkedin --json --account acct_example
206
+ audienti users automation update 136 --payload automation-controls.json --json --account acct_example
207
+ audienti users automation update 136 --payload automation-controls.json --apply --json --account acct_example
208
+ audienti users automation show 136 --platform linkedin --json --account acct_example
209
+ ```
210
+
211
+ The payload object accepts `automation_controls`, `action_limits`, and
212
+ `visibility_ramp`. Action-limit keys are `profile_view`, `follow`, `like`,
213
+ `invite`, `message`, `comment`, and aggregate `visibility`; each action limit
214
+ may provide `hourly`, `daily`, and `weekly`. `follow` covers follow/unfollow,
215
+ `like` covers like/unlike, and `message` covers messages/InMail. A ramp accepts
216
+ `enabled`, `starting_daily_limit`, `weekly_increment`, and optional
217
+ `started_at`.
218
+
219
+ The CLI wraps the file as `{ automation: { ...payload, platform: "linkedin",
220
+ apply: false|true } }`; file values cannot override the command's platform or
221
+ apply decision. Omitted settings are preserved by the server. Use unchanged
222
+ JSON output to compare current, before, and after snapshots, including policy
223
+ source, schedule/timezone, configured/default/effective limits, used and
224
+ remaining capacity, binding limits, preview/applied state, and applied audit id.
225
+
226
+ For a new account, keep contact and writing controls disabled, enable risk
227
+ cooldown, and bound `visibility` to the authorized active-day warm-up level.
228
+ Never infer that `ready: true`, paused motions, or prepared queue work authorizes
229
+ provider execution.
230
+
135
231
  List routing-rule create and update commands accept the same normalized
136
232
  condition and action data as the list UI. Inspect the ordered rules first, use
137
233
  `audienti lists routing-rules help` for the payload contract, and treat `apply`
package/src/api-client.js CHANGED
@@ -51,6 +51,17 @@ export class AudientiClient {
51
51
  return this.requestJson(accountPath(accountId, ["users"]));
52
52
  }
53
53
 
54
+ userAutomation(accountId, userId, query = {}) {
55
+ return this.requestJson(accountPath(accountId, ["users", userId, "automation"], query));
56
+ }
57
+
58
+ updateUserAutomation(accountId, userId, body, query = {}) {
59
+ return this.requestJson(accountPath(accountId, ["users", userId, "automation"], query), {
60
+ method: "PATCH",
61
+ body
62
+ });
63
+ }
64
+
54
65
  socialCookies(accountId, query = {}) {
55
66
  return this.requestJson(accountPath(accountId, ["social_cookies"], query));
56
67
  }
@@ -87,8 +98,8 @@ export class AudientiClient {
87
98
  });
88
99
  }
89
100
 
90
- icps(accountId) {
91
- return this.requestJson(accountPath(accountId, ["icps"]));
101
+ icps(accountId, query = {}) {
102
+ return this.requestJson(accountPath(accountId, ["icps"], query));
92
103
  }
93
104
 
94
105
  icp(accountId, icpId) {
@@ -109,6 +120,20 @@ export class AudientiClient {
109
120
  });
110
121
  }
111
122
 
123
+ archiveIcp(accountId, icpId) {
124
+ return this.requestJson(accountPath(accountId, ["icps", icpId, "archive"]), {
125
+ method: "POST",
126
+ body: {}
127
+ });
128
+ }
129
+
130
+ restoreIcp(accountId, icpId) {
131
+ return this.requestJson(accountPath(accountId, ["icps", icpId, "restore"]), {
132
+ method: "POST",
133
+ body: {}
134
+ });
135
+ }
136
+
112
137
  addIcpTag(accountId, icpId, body) {
113
138
  return this.requestJson(accountPath(accountId, ["icps", icpId, "add_tag"]), {
114
139
  method: "POST",
@@ -467,6 +492,13 @@ export class AudientiClient {
467
492
  return this.requestJson(accountPath(accountId, ["prospects", prospectId]));
468
493
  }
469
494
 
495
+ moveProspectAccount(accountId, prospectId, body) {
496
+ return this.requestJson(accountPath(accountId, ["prospects", prospectId, "move_account"]), {
497
+ method: "POST",
498
+ body
499
+ });
500
+ }
501
+
470
502
  replanProspect(accountId, prospectId, body = {}) {
471
503
  return this.requestJson(accountPath(accountId, ["prospects", prospectId, "replan"]), {
472
504
  method: "POST",
@@ -663,6 +695,14 @@ export class AudientiClient {
663
695
  return this.requestJson(accountPath(accountId, ["analytics", "dashboard"], query));
664
696
  }
665
697
 
698
+ analyticsMotions(accountId) {
699
+ return this.requestJson(accountPath(accountId, ["analytics", "motions"]));
700
+ }
701
+
702
+ analyticsIcps(accountId) {
703
+ return this.requestJson(accountPath(accountId, ["analytics", "icps"]));
704
+ }
705
+
666
706
  analyticsMetrics(accountId, query = {}) {
667
707
  return this.requestJson(accountPath(accountId, ["analytics", "metrics"], query));
668
708
  }