@audienti/cli 0.1.17 → 0.1.18
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/README.md +5 -0
- package/package.json +1 -1
- package/src/api-client.js +40 -0
- package/src/cli.js +270 -6
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.18] - 2026-07-17
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add ContentOps CLI commands for inspecting programs, reviewing plan rows, approving/scheduling/publishing work items, and handling comment tasks.
|
|
12
|
+
- Add `audienti motions update <motn_id> --own-post-engagement <true|false>` to enable or disable owned-post engagement intake for inbound motions.
|
|
13
|
+
|
|
7
14
|
## [0.1.17] - 2026-07-17
|
|
8
15
|
|
|
9
16
|
### Added
|
package/README.md
CHANGED
|
@@ -63,8 +63,13 @@ audienti writer test-run <prsp_id>
|
|
|
63
63
|
audienti motions analytics <motn_id>
|
|
64
64
|
audienti motions run-discovery <motn_id>
|
|
65
65
|
audienti motions update <motn_id> --status paused
|
|
66
|
+
audienti motions update <motn_id> --own-post-engagement true
|
|
66
67
|
audienti motions activate <motn_id>
|
|
67
68
|
audienti motions delete <motn_id> --confirm yes
|
|
69
|
+
audienti content programs
|
|
70
|
+
audienti content plan <cprg_id>
|
|
71
|
+
audienti content approve <cpwi_id>
|
|
72
|
+
audienti content comments
|
|
68
73
|
audienti prospects show <prsp_id> --json
|
|
69
74
|
audienti prospects list --profiles
|
|
70
75
|
audienti prospects list --assigned-user unassigned
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -261,6 +261,46 @@ export class AudientiClient {
|
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
contentPrograms(accountId, query = {}) {
|
|
265
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "programs"], query));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
contentPlan(accountId, programId, query = {}) {
|
|
269
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "programs", programId, "plan"], query));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
contentWorkItem(accountId, workItemId) {
|
|
273
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "work_items", workItemId]));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
contentFeedback(accountId, workItemId, body) {
|
|
277
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "work_items", workItemId, "feedback"]), { method: "POST", body });
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
contentApprove(accountId, workItemId) {
|
|
281
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "work_items", workItemId, "approve"]), { method: "POST" });
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
contentSchedule(accountId, workItemId, body) {
|
|
285
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "work_items", workItemId, "schedule"]), { method: "POST", body });
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
contentPublish(accountId, workItemId, body) {
|
|
289
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "work_items", workItemId, "publish"]), { method: "POST", body });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
contentComments(accountId, query = {}) {
|
|
293
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "comment_tasks"], query));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
contentReply(accountId, commentTaskId, body) {
|
|
297
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "comment_tasks", commentTaskId, "send_reply"]), { method: "POST", body });
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
contentDismiss(accountId, commentTaskId) {
|
|
301
|
+
return this.requestJson(accountPath(accountId, ["content_ops", "comment_tasks", commentTaskId, "dismiss"]), { method: "POST" });
|
|
302
|
+
}
|
|
303
|
+
|
|
264
304
|
addMotionTag(accountId, motionId, body) {
|
|
265
305
|
return this.requestJson(accountPath(accountId, ["motions", motionId, "add_tag"]), {
|
|
266
306
|
method: "POST",
|
package/src/cli.js
CHANGED
|
@@ -55,7 +55,17 @@ const OFFERS_UPDATE_USAGE = "Usage: audienti offers update <offr_id> [--name <te
|
|
|
55
55
|
const OFFERS_DELETE_USAGE = "Usage: audienti offers delete <offr_id> --confirm <yes|true|Y|y> [--json] [--account <acct_id>]";
|
|
56
56
|
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>]";
|
|
57
57
|
const MOTIONS_ANALYTICS_USAGE = "Usage: audienti motions analytics <motn_id> [--window 30d] [--json] [--account <acct_id>]";
|
|
58
|
-
const MOTIONS_UPDATE_USAGE = "Usage: audienti motions update <motn_id> [--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--json] [--account <acct_id>]";
|
|
58
|
+
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>]";
|
|
59
|
+
const CONTENT_PROGRAMS_USAGE = "Usage: audienti content programs [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
60
|
+
const CONTENT_PLAN_USAGE = "Usage: audienti content plan <cprg_id> [--week <n>] [--due] [--json] [--account <acct_id>]";
|
|
61
|
+
const CONTENT_SHOW_USAGE = "Usage: audienti content show <cpwi_id> [--json] [--account <acct_id>]";
|
|
62
|
+
const CONTENT_FEEDBACK_USAGE = "Usage: audienti content feedback <cpwi_id> (--message <text> | --payload <file.json>) [--json] [--account <acct_id>]";
|
|
63
|
+
const CONTENT_APPROVE_USAGE = "Usage: audienti content approve <cpwi_id> [--json] [--account <acct_id>]";
|
|
64
|
+
const CONTENT_SCHEDULE_USAGE = "Usage: audienti content schedule <cpwi_id> --at <time> [--json] [--account <acct_id>]";
|
|
65
|
+
const CONTENT_PUBLISH_USAGE = "Usage: audienti content publish <cpwi_id> --url <permalink> [--json] [--account <acct_id>]";
|
|
66
|
+
const CONTENT_COMMENTS_USAGE = "Usage: audienti content comments [--unresolved] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
|
|
67
|
+
const CONTENT_REPLY_USAGE = "Usage: audienti content reply <cctk_id> [--body <text>] [--json] [--account <acct_id>]";
|
|
68
|
+
const CONTENT_DISMISS_USAGE = "Usage: audienti content dismiss <cctk_id> [--json] [--account <acct_id>]";
|
|
59
69
|
const MOTIONS_ADD_TAG_USAGE = "Usage: audienti motions add-tag <motn_id> <tag> [--json] [--account <acct_id>]";
|
|
60
70
|
const MOTIONS_REMOVE_TAG_USAGE = "Usage: audienti motions remove-tag <motn_id> <tag> [--json] [--account <acct_id>]";
|
|
61
71
|
const MOTIONS_DELETE_USAGE = "Usage: audienti motions delete <motn_id> --confirm <yes|true|Y|y> [--json] [--account <acct_id>]";
|
|
@@ -204,6 +214,16 @@ async function dispatch(argv, context) {
|
|
|
204
214
|
if (normalizedResource === "motions" && action === "clone") return motionsClone(rest, context, { accountOverride });
|
|
205
215
|
if (normalizedResource === "motions" && action === "move-prospects") return motionsMoveProspects(rest, context, { accountOverride });
|
|
206
216
|
if (normalizedResource === "motions" && action === "run-discovery") return motionsRunDiscovery(rest, context, { accountOverride });
|
|
217
|
+
if (normalizedResource === "content" && action === "programs") return contentPrograms(rest, context, { accountOverride });
|
|
218
|
+
if (normalizedResource === "content" && action === "plan") return contentPlan(rest, context, { accountOverride });
|
|
219
|
+
if (normalizedResource === "content" && action === "show") return contentShow(rest, context, { accountOverride });
|
|
220
|
+
if (normalizedResource === "content" && action === "feedback") return contentFeedback(rest, context, { accountOverride });
|
|
221
|
+
if (normalizedResource === "content" && action === "approve") return contentApprove(rest, context, { accountOverride });
|
|
222
|
+
if (normalizedResource === "content" && action === "schedule") return contentSchedule(rest, context, { accountOverride });
|
|
223
|
+
if (normalizedResource === "content" && action === "publish") return contentPublish(rest, context, { accountOverride });
|
|
224
|
+
if (normalizedResource === "content" && action === "comments") return contentComments(rest, context, { accountOverride });
|
|
225
|
+
if (normalizedResource === "content" && action === "reply") return contentReply(rest, context, { accountOverride });
|
|
226
|
+
if (normalizedResource === "content" && action === "dismiss") return contentDismiss(rest, context, { accountOverride });
|
|
207
227
|
if (normalizedResource === "prospects" && action === "list") return prospectsList(rest, context, { accountOverride });
|
|
208
228
|
if (normalizedResource === "prospects" && action === "check") return prospectsCheck(rest, context, { accountOverride });
|
|
209
229
|
if (normalizedResource === "prospects" && action === "show") return prospectsShow(rest, context, { accountOverride });
|
|
@@ -1360,9 +1380,10 @@ async function motionsUpdate(args, context, { accountOverride } = {}) {
|
|
|
1360
1380
|
const { values, positionals } = parseCommandArgs(args, {
|
|
1361
1381
|
...jsonOptions(),
|
|
1362
1382
|
status: { type: "string" },
|
|
1363
|
-
tags: { type: "string" }
|
|
1383
|
+
tags: { type: "string" },
|
|
1384
|
+
"own-post-engagement": { type: "string" }
|
|
1364
1385
|
});
|
|
1365
|
-
const hasUpdateField = values.status || values.tags !== undefined;
|
|
1386
|
+
const hasUpdateField = values.status || values.tags !== undefined || values["own-post-engagement"] !== undefined;
|
|
1366
1387
|
if (positionals.length !== 1 || !hasUpdateField) {
|
|
1367
1388
|
throw new CommandError(MOTIONS_UPDATE_USAGE);
|
|
1368
1389
|
}
|
|
@@ -1370,7 +1391,8 @@ async function motionsUpdate(args, context, { accountOverride } = {}) {
|
|
|
1370
1391
|
const normalizedStatus = normalizeMotionStatus(values.status);
|
|
1371
1392
|
const motionAttributes = compactObject({
|
|
1372
1393
|
status: normalizedStatus,
|
|
1373
|
-
play_tags: values.tags !== undefined ? tagList(values.tags) : undefined
|
|
1394
|
+
play_tags: values.tags !== undefined ? tagList(values.tags) : undefined,
|
|
1395
|
+
own_post_engagement: values["own-post-engagement"] !== undefined ? parseBooleanString(values["own-post-engagement"], "--own-post-engagement") : undefined
|
|
1374
1396
|
});
|
|
1375
1397
|
|
|
1376
1398
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
@@ -1411,6 +1433,149 @@ async function updateMotionStatus(motionId, status, context, { accountOverride,
|
|
|
1411
1433
|
renderMotion(motion, context);
|
|
1412
1434
|
}
|
|
1413
1435
|
|
|
1436
|
+
async function contentPrograms(args, context, { accountOverride } = {}) {
|
|
1437
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1438
|
+
...jsonOptions(),
|
|
1439
|
+
user: { type: "string" }
|
|
1440
|
+
});
|
|
1441
|
+
if (positionals.length > 0) throw new CommandError(CONTENT_PROGRAMS_USAGE);
|
|
1442
|
+
|
|
1443
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1444
|
+
const programs = await client.contentPrograms(accountId, compactObject({ user: values.user }));
|
|
1445
|
+
if (values.json) return writeJson(context.stdout, programs);
|
|
1446
|
+
|
|
1447
|
+
renderContentPrograms(programs, context);
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
async function contentPlan(args, context, { accountOverride } = {}) {
|
|
1451
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1452
|
+
...jsonOptions(),
|
|
1453
|
+
week: { type: "string" },
|
|
1454
|
+
due: { type: "boolean" }
|
|
1455
|
+
});
|
|
1456
|
+
if (positionals.length !== 1) throw new CommandError(CONTENT_PLAN_USAGE);
|
|
1457
|
+
|
|
1458
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1459
|
+
const payload = await client.contentPlan(accountId, positionals[0]);
|
|
1460
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
1461
|
+
|
|
1462
|
+
const week = values.week ? Number.parseInt(values.week, 10) : null;
|
|
1463
|
+
let rows = Array.isArray(payload?.rows) ? payload.rows : [];
|
|
1464
|
+
if (week) rows = rows.filter((row) => Number(row.week_number) === week);
|
|
1465
|
+
if (values.due) rows = rows.filter((row) => ["researching", "drafting", "needs_operator_review", "needs_operator_approval", "scheduled", "ready_to_post"].includes(row.stage));
|
|
1466
|
+
renderContentPlanRows(rows, context);
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
async function contentShow(args, context, { accountOverride } = {}) {
|
|
1470
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1471
|
+
if (positionals.length !== 1) throw new CommandError(CONTENT_SHOW_USAGE);
|
|
1472
|
+
|
|
1473
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1474
|
+
const item = await client.contentWorkItem(accountId, positionals[0]);
|
|
1475
|
+
if (values.json) return writeJson(context.stdout, item);
|
|
1476
|
+
|
|
1477
|
+
renderContentWorkItem(item, context);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
async function contentFeedback(args, context, { accountOverride } = {}) {
|
|
1481
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1482
|
+
...jsonOptions(),
|
|
1483
|
+
message: { type: "string" },
|
|
1484
|
+
payload: { type: "string" }
|
|
1485
|
+
});
|
|
1486
|
+
if (positionals.length !== 1 || (!values.message && !values.payload)) throw new CommandError(CONTENT_FEEDBACK_USAGE);
|
|
1487
|
+
|
|
1488
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1489
|
+
const payload = values.payload ? await readJsonPayload(values.payload) : { draft_feedback: values.message };
|
|
1490
|
+
const item = await client.contentFeedback(accountId, positionals[0], payload);
|
|
1491
|
+
if (values.json) return writeJson(context.stdout, item);
|
|
1492
|
+
|
|
1493
|
+
writeLine(context.stdout, `Queued feedback for ${display(item?.prefix_id)}.`);
|
|
1494
|
+
renderContentWorkItem(item, context);
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
async function contentApprove(args, context, { accountOverride } = {}) {
|
|
1498
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1499
|
+
if (positionals.length !== 1) throw new CommandError(CONTENT_APPROVE_USAGE);
|
|
1500
|
+
|
|
1501
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1502
|
+
const item = await client.contentApprove(accountId, positionals[0]);
|
|
1503
|
+
if (values.json) return writeJson(context.stdout, item);
|
|
1504
|
+
|
|
1505
|
+
writeLine(context.stdout, `Approved ${display(item?.prefix_id)}.`);
|
|
1506
|
+
renderContentWorkItem(item, context);
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
async function contentSchedule(args, context, { accountOverride } = {}) {
|
|
1510
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1511
|
+
...jsonOptions(),
|
|
1512
|
+
at: { type: "string" }
|
|
1513
|
+
});
|
|
1514
|
+
if (positionals.length !== 1 || !values.at) throw new CommandError(CONTENT_SCHEDULE_USAGE);
|
|
1515
|
+
|
|
1516
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1517
|
+
const item = await client.contentSchedule(accountId, positionals[0], { scheduled_at: values.at });
|
|
1518
|
+
if (values.json) return writeJson(context.stdout, item);
|
|
1519
|
+
|
|
1520
|
+
writeLine(context.stdout, `Scheduled ${display(item?.prefix_id)}.`);
|
|
1521
|
+
renderContentWorkItem(item, context);
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
async function contentPublish(args, context, { accountOverride } = {}) {
|
|
1525
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1526
|
+
...jsonOptions(),
|
|
1527
|
+
url: { type: "string" }
|
|
1528
|
+
});
|
|
1529
|
+
if (positionals.length !== 1 || !values.url) throw new CommandError(CONTENT_PUBLISH_USAGE);
|
|
1530
|
+
|
|
1531
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1532
|
+
const item = await client.contentPublish(accountId, positionals[0], { permalink: values.url });
|
|
1533
|
+
if (values.json) return writeJson(context.stdout, item);
|
|
1534
|
+
|
|
1535
|
+
writeLine(context.stdout, `Published ${display(item?.prefix_id)}.`);
|
|
1536
|
+
renderContentWorkItem(item, context);
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
async function contentComments(args, context, { accountOverride } = {}) {
|
|
1540
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1541
|
+
...jsonOptions(),
|
|
1542
|
+
unresolved: { type: "boolean" },
|
|
1543
|
+
user: { type: "string" }
|
|
1544
|
+
});
|
|
1545
|
+
if (positionals.length > 0) throw new CommandError(CONTENT_COMMENTS_USAGE);
|
|
1546
|
+
|
|
1547
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1548
|
+
const comments = await client.contentComments(accountId, compactObject({ unresolved: values.unresolved === false ? false : true, user: values.user }));
|
|
1549
|
+
if (values.json) return writeJson(context.stdout, comments);
|
|
1550
|
+
|
|
1551
|
+
renderContentComments(comments, context);
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
async function contentReply(args, context, { accountOverride } = {}) {
|
|
1555
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
1556
|
+
...jsonOptions(),
|
|
1557
|
+
body: { type: "string" }
|
|
1558
|
+
});
|
|
1559
|
+
if (positionals.length !== 1) throw new CommandError(CONTENT_REPLY_USAGE);
|
|
1560
|
+
|
|
1561
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1562
|
+
const comment = await client.contentReply(accountId, positionals[0], compactObject({ body: values.body }));
|
|
1563
|
+
if (values.json) return writeJson(context.stdout, comment);
|
|
1564
|
+
|
|
1565
|
+
writeLine(context.stdout, `Sent reply for ${display(comment?.prefix_id)}.`);
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
async function contentDismiss(args, context, { accountOverride } = {}) {
|
|
1569
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
1570
|
+
if (positionals.length !== 1) throw new CommandError(CONTENT_DISMISS_USAGE);
|
|
1571
|
+
|
|
1572
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
1573
|
+
const comment = await client.contentDismiss(accountId, positionals[0]);
|
|
1574
|
+
if (values.json) return writeJson(context.stdout, comment);
|
|
1575
|
+
|
|
1576
|
+
writeLine(context.stdout, `Dismissed ${display(comment?.prefix_id)}.`);
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1414
1579
|
function normalizeMotionStatus(status) {
|
|
1415
1580
|
if (status === undefined) return undefined;
|
|
1416
1581
|
|
|
@@ -1422,6 +1587,14 @@ function normalizeMotionStatus(status) {
|
|
|
1422
1587
|
return normalizedStatus;
|
|
1423
1588
|
}
|
|
1424
1589
|
|
|
1590
|
+
function parseBooleanString(value, flagName) {
|
|
1591
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
1592
|
+
if (["true", "1", "yes", "y"].includes(normalized)) return true;
|
|
1593
|
+
if (["false", "0", "no", "n"].includes(normalized)) return false;
|
|
1594
|
+
|
|
1595
|
+
throw new CommandError(`${flagName} must be true or false.`);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1425
1598
|
async function motionsTagMutation(action, args, context, { accountOverride } = {}) {
|
|
1426
1599
|
const usageText = action === "add" ? MOTIONS_ADD_TAG_USAGE : MOTIONS_REMOVE_TAG_USAGE;
|
|
1427
1600
|
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
@@ -3451,6 +3624,7 @@ function renderMotion(motion, context) {
|
|
|
3451
3624
|
if (motion?.offer?.name) writeLine(context.stdout, `Offer: ${motion.offer.name} (${display(motion.offer.prefix_id)})`);
|
|
3452
3625
|
if (motion?.icp?.name) writeLine(context.stdout, `ICP: ${motion.icp.name} (${display(motion.icp.prefix_id)})`);
|
|
3453
3626
|
if (motion?.list?.name) writeLine(context.stdout, `List: ${motion.list.name} (${display(motion.list.prefix_id)})`);
|
|
3627
|
+
writeLine(context.stdout, `Own-post engagement: ${motion?.own_post_engagement ? "enabled" : "disabled"}`);
|
|
3454
3628
|
if (Array.isArray(motion?.play_tags)) writeLine(context.stdout, `Tags: ${display(motion.play_tags.join(", "), "-")}`);
|
|
3455
3629
|
if (motion?.principal_account_user?.id) {
|
|
3456
3630
|
writeLine(
|
|
@@ -3460,6 +3634,59 @@ function renderMotion(motion, context) {
|
|
|
3460
3634
|
}
|
|
3461
3635
|
}
|
|
3462
3636
|
|
|
3637
|
+
function renderContentPrograms(programs, context) {
|
|
3638
|
+
if (!Array.isArray(programs) || programs.length === 0) return writeLine(context.stdout, "No ContentOps programs found.");
|
|
3639
|
+
|
|
3640
|
+
writeAlignedTable(context, ["PROGRAM ID", "OWNER", "STAGE", "BLOCKED", "CURRENT", "SCHEDULED", "STALE"], programs.map((program) => [
|
|
3641
|
+
display(program.prefix_id),
|
|
3642
|
+
display(program.owner?.name || program.owner?.email),
|
|
3643
|
+
display(program.stage),
|
|
3644
|
+
display(program.blocking_reason, "-"),
|
|
3645
|
+
display(program.current_piece?.prefix_id || program.current_piece?.piece_key, "-"),
|
|
3646
|
+
display(program.scheduled_piece?.prefix_id || program.scheduled_piece?.piece_key, "-"),
|
|
3647
|
+
program.plan_stale_motion_set ? "yes" : "no"
|
|
3648
|
+
]));
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
function renderContentPlanRows(rows, context) {
|
|
3652
|
+
if (!Array.isArray(rows) || rows.length === 0) return writeLine(context.stdout, "No ContentOps plan rows found.");
|
|
3653
|
+
|
|
3654
|
+
writeAlignedTable(context, ["DAY", "DATE", "MOTION", "STAGE", "STATUS", "TITLE"], rows.map((row) => [
|
|
3655
|
+
display(row.day_number),
|
|
3656
|
+
display(row.planned_publish_on, "-"),
|
|
3657
|
+
display(row.motion?.name || row.motion?.motion_prefix_id, "-"),
|
|
3658
|
+
display(row.stage, "-"),
|
|
3659
|
+
display(row.publish_status || row.workflow_phase, "-"),
|
|
3660
|
+
display(row.title)
|
|
3661
|
+
]));
|
|
3662
|
+
}
|
|
3663
|
+
|
|
3664
|
+
function renderContentWorkItem(item, context) {
|
|
3665
|
+
writeLine(context.stdout, `Content item: ${display(item?.title)} (${display(item?.prefix_id)})`);
|
|
3666
|
+
writeLine(context.stdout, `Stage: ${display(item?.stage)}`);
|
|
3667
|
+
writeLine(context.stdout, `Blocking: ${display(item?.blocking_reason, "-")}`);
|
|
3668
|
+
if (item?.motion?.name || item?.motion?.motion_prefix_id) writeLine(context.stdout, `Motion: ${display(item.motion.name || item.motion.motion_prefix_id)}`);
|
|
3669
|
+
if (item?.scheduled_at) writeLine(context.stdout, `Scheduled: ${item.scheduled_at}`);
|
|
3670
|
+
if (item?.permalink) writeLine(context.stdout, `Permalink: ${item.permalink}`);
|
|
3671
|
+
if (item?.finalized_content) {
|
|
3672
|
+
writeLine(context.stdout, "");
|
|
3673
|
+
writeLine(context.stdout, item.finalized_content);
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
|
|
3677
|
+
function renderContentComments(comments, context) {
|
|
3678
|
+
if (!Array.isArray(comments) || comments.length === 0) return writeLine(context.stdout, "No ContentOps comment tasks found.");
|
|
3679
|
+
|
|
3680
|
+
writeAlignedTable(context, ["TASK ID", "STATUS", "COMMENTER", "FIT", "OUTCOME", "COMMENT"], comments.map((comment) => [
|
|
3681
|
+
display(comment.prefix_id),
|
|
3682
|
+
display(comment.status),
|
|
3683
|
+
display(comment.commenter?.name),
|
|
3684
|
+
display(comment.fit_badge?.status || comment.fit_badge, "-"),
|
|
3685
|
+
display(comment.promotion_outcome, "-"),
|
|
3686
|
+
display(truncateCliText(comment.comment_body, 80))
|
|
3687
|
+
]));
|
|
3688
|
+
}
|
|
3689
|
+
|
|
3463
3690
|
function renderMotionStatus(status, context) {
|
|
3464
3691
|
writeLine(context.stdout, `Motion: ${display(status?.name)} (${display(status?.prefix_id)})`);
|
|
3465
3692
|
writeLine(context.stdout, `State: ${display(status?.state)}`);
|
|
@@ -4827,7 +5054,7 @@ const HELP_TOPICS = new Map([
|
|
|
4827
5054
|
" audienti motions run-discovery <motn_id>",
|
|
4828
5055
|
" audienti motions prospects <motn_id>",
|
|
4829
5056
|
" audienti motions create --payload <file.json>",
|
|
4830
|
-
" audienti motions update <motn_id> [--status <state>] [--tags <tag[,tag...]>]",
|
|
5057
|
+
" audienti motions update <motn_id> [--status <state>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>]",
|
|
4831
5058
|
" audienti motions add-tag <motn_id> <tag>",
|
|
4832
5059
|
" audienti motions remove-tag <motn_id> <tag>",
|
|
4833
5060
|
" audienti motions activate <motn_id>",
|
|
@@ -4837,6 +5064,15 @@ const HELP_TOPICS = new Map([
|
|
|
4837
5064
|
" audienti motions move-prospects <source_motn_id> --target <target_motn_id> <prsp_id> [prsp_id...]",
|
|
4838
5065
|
" Tip: `plays` is accepted anywhere `motions` is accepted.",
|
|
4839
5066
|
"",
|
|
5067
|
+
" ContentOps",
|
|
5068
|
+
" audienti content programs",
|
|
5069
|
+
" audienti content plan <cprg_id>",
|
|
5070
|
+
" audienti content show <cpwi_id>",
|
|
5071
|
+
" audienti content feedback <cpwi_id> --message <text>",
|
|
5072
|
+
" audienti content approve <cpwi_id>",
|
|
5073
|
+
" audienti content publish <cpwi_id> --url <permalink>",
|
|
5074
|
+
" audienti content comments",
|
|
5075
|
+
"",
|
|
4840
5076
|
" Prospects",
|
|
4841
5077
|
" audienti prospects list [filters]",
|
|
4842
5078
|
" audienti prospects check [filters]",
|
|
@@ -5907,7 +6143,7 @@ const HELP_TOPICS = new Map([
|
|
|
5907
6143
|
" audienti motions prospects <motn_id> [--json]",
|
|
5908
6144
|
" audienti motions add-prospects <motn_id> <prsp_id> [prsp_id...] [--json]",
|
|
5909
6145
|
" audienti motions create --payload <file.json> [--json]",
|
|
5910
|
-
" audienti motions update <motn_id> [--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--json]",
|
|
6146
|
+
" audienti motions update <motn_id> [--status <draft|preparing|active|paused|archived>] [--tags <tag[,tag...]>] [--own-post-engagement <true|false>] [--json]",
|
|
5911
6147
|
" audienti motions add-tag <motn_id> <tag> [--json]",
|
|
5912
6148
|
" audienti motions remove-tag <motn_id> <tag> [--json]",
|
|
5913
6149
|
" audienti motions activate <motn_id> [--json]",
|
|
@@ -5926,6 +6162,34 @@ const HELP_TOPICS = new Map([
|
|
|
5926
6162
|
" motn_id: motn_ prefix id"
|
|
5927
6163
|
].join("\n")],
|
|
5928
6164
|
|
|
6165
|
+
["content", [
|
|
6166
|
+
"Usage:",
|
|
6167
|
+
" audienti content programs [--user <account_user_id|email|name|me>] [--json]",
|
|
6168
|
+
" audienti content plan <cprg_id> [--week <n>] [--due] [--json]",
|
|
6169
|
+
" audienti content show <cpwi_id> [--json]",
|
|
6170
|
+
" audienti content feedback <cpwi_id> --message <text> [--json]",
|
|
6171
|
+
" audienti content approve <cpwi_id> [--json]",
|
|
6172
|
+
" audienti content schedule <cpwi_id> --at <time> [--json]",
|
|
6173
|
+
" audienti content publish <cpwi_id> --url <permalink> [--json]",
|
|
6174
|
+
" audienti content comments [--unresolved] [--user <account_user_id|email|name|me>] [--json]",
|
|
6175
|
+
" audienti content reply <cctk_id> [--body <text>] [--json]",
|
|
6176
|
+
" audienti content dismiss <cctk_id> [--json]",
|
|
6177
|
+
"",
|
|
6178
|
+
"API:",
|
|
6179
|
+
" GET/POST /api/v1/accounts/:account_id/content_ops/..."
|
|
6180
|
+
].join("\n")],
|
|
6181
|
+
|
|
6182
|
+
["content programs", [CONTENT_PROGRAMS_USAGE].join("\n")],
|
|
6183
|
+
["content plan", [CONTENT_PLAN_USAGE].join("\n")],
|
|
6184
|
+
["content show", [CONTENT_SHOW_USAGE].join("\n")],
|
|
6185
|
+
["content feedback", [CONTENT_FEEDBACK_USAGE].join("\n")],
|
|
6186
|
+
["content approve", [CONTENT_APPROVE_USAGE].join("\n")],
|
|
6187
|
+
["content schedule", [CONTENT_SCHEDULE_USAGE].join("\n")],
|
|
6188
|
+
["content publish", [CONTENT_PUBLISH_USAGE].join("\n")],
|
|
6189
|
+
["content comments", [CONTENT_COMMENTS_USAGE].join("\n")],
|
|
6190
|
+
["content reply", [CONTENT_REPLY_USAGE].join("\n")],
|
|
6191
|
+
["content dismiss", [CONTENT_DISMISS_USAGE].join("\n")],
|
|
6192
|
+
|
|
5929
6193
|
["motions list", [
|
|
5930
6194
|
"Usage:",
|
|
5931
6195
|
" audienti motions list [--tag <tag>] [--json] [--account <acct_id>]",
|