@rolino/cli 0.2.0 → 0.4.0
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 +28 -0
- package/README.md +80 -61
- package/dist/bin.cjs +30 -14
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-2B34YBKX.js → chunk-VQOMONSS.js} +32 -15
- package/dist/chunk-VQOMONSS.js.map +1 -0
- package/dist/index.cjs +30 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-2B34YBKX.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -50,7 +50,7 @@ var import_commander = require("commander");
|
|
|
50
50
|
// package.json
|
|
51
51
|
var package_default = {
|
|
52
52
|
name: "@rolino/cli",
|
|
53
|
-
version: "0.
|
|
53
|
+
version: "0.4.0",
|
|
54
54
|
description: "Agent-friendly command-line interface for Rolino",
|
|
55
55
|
type: "module",
|
|
56
56
|
license: "MIT",
|
|
@@ -107,9 +107,9 @@ var package_default = {
|
|
|
107
107
|
dev: "tsx src/bin.ts"
|
|
108
108
|
},
|
|
109
109
|
dependencies: {
|
|
110
|
-
"@rolino/contracts": "0.
|
|
111
|
-
"@rolino/local-auth": "0.
|
|
112
|
-
"@rolino/sdk": "0.
|
|
110
|
+
"@rolino/contracts": "0.4.0",
|
|
111
|
+
"@rolino/local-auth": "0.4.0",
|
|
112
|
+
"@rolino/sdk": "0.4.0",
|
|
113
113
|
commander: "^15.0.0",
|
|
114
114
|
open: "^11.0.0"
|
|
115
115
|
},
|
|
@@ -525,6 +525,15 @@ function formatProviderDeliveryOptions(options) {
|
|
|
525
525
|
`Interactions: comments ${options.interactions.comment.available ? "available" : "disabled"}, duet ${options.interactions.duet.available ? "available" : "disabled"}, stitch ${options.interactions.stitch.available ? "available" : "disabled"}`,
|
|
526
526
|
`Maximum video duration: ${options.maxVideoDurationMs === null ? "unknown" : `${options.maxVideoDurationMs} ms`}`
|
|
527
527
|
].join("\n");
|
|
528
|
+
case "LINKEDIN":
|
|
529
|
+
return [
|
|
530
|
+
`LinkedIn delivery options for ${options.account.displayName ?? "connected member"}`,
|
|
531
|
+
`Checked: ${options.checkedAt}`,
|
|
532
|
+
`Health: ${options.health.status} (${options.health.code}) ${options.health.message}`,
|
|
533
|
+
`Post types: ${options.supportedPostTypes.join(", ")}`,
|
|
534
|
+
`Images: up to ${options.image.maxItems}; ${options.image.mimeTypes.join(", ")}; under ${options.image.maxPixelsExclusive.toLocaleString()} pixels`,
|
|
535
|
+
`Video: one ${options.video.mimeTypes.join(", ")}; ${options.video.minDurationMs / 1e3}s to ${options.video.maxDurationMs / 6e4}m; ${options.video.minBytes.toLocaleString()} to ${options.video.maxBytes.toLocaleString()} bytes`
|
|
536
|
+
].join("\n");
|
|
528
537
|
}
|
|
529
538
|
}
|
|
530
539
|
function formatPostReadiness(readiness) {
|
|
@@ -873,6 +882,14 @@ function collectPublishingProvider(value, previous) {
|
|
|
873
882
|
function collectString(value, previous) {
|
|
874
883
|
return [...previous ?? [], value];
|
|
875
884
|
}
|
|
885
|
+
function deliveryOptionsProvider(value) {
|
|
886
|
+
const normalized = value.toUpperCase();
|
|
887
|
+
const parsed = import_contracts2.ProviderDeliveryOptionsProviderSchema.safeParse(normalized);
|
|
888
|
+
if (parsed.success) return parsed.data;
|
|
889
|
+
throw new import_commander.InvalidArgumentError(
|
|
890
|
+
`Provider must be one of ${import_contracts2.ProviderDeliveryOptionsProviderSchema.options.join(", ")}.`
|
|
891
|
+
);
|
|
892
|
+
}
|
|
876
893
|
function tiktokPostMode(value) {
|
|
877
894
|
const normalized = value.trim().toLowerCase();
|
|
878
895
|
if (normalized === "direct" || normalized === "direct_post") {
|
|
@@ -1505,7 +1522,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1505
1522
|
});
|
|
1506
1523
|
});
|
|
1507
1524
|
const posts = program.command("posts").description("Read and prepare posts in a Rolino project");
|
|
1508
|
-
posts.command("create").description("Create a draft post without scheduling or publishing it").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--caption <text>", "draft caption; use an empty string for media-only drafts").option("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, or
|
|
1525
|
+
posts.command("create").description("Create a draft post without scheduling or publishing it").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--caption <text>", "draft caption; use an empty string for media-only drafts").option("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, BLUESKY, or LINKEDIN; repeat as needed", collectPublishingProvider, []).option("--media <asset-id>", "existing project media asset ID; repeat for multiple", collectString, []).option("--instagram-caption <text>", "Instagram-specific caption override").option("--tiktok-caption <text>", "TikTok-specific caption override").option("--tiktok-mode <mode>", "direct publishing or inbox draft delivery", tiktokPostMode).option("--tiktok-visibility <value>", "exact visibility returned by integrations delivery-options").option("--tiktok-comments <yes|no>", "allow TikTok comments", yesOrNo).option("--tiktok-duet <yes|no>", "allow TikTok duets", yesOrNo).option("--tiktok-stitch <yes|no>", "allow TikTok stitches", yesOrNo).option("--tiktok-commercial-content <yes|no>", "declare commercial TikTok content", yesOrNo).option("--tiktok-promotes-own-brand <yes|no>", "declare own-brand promotion", yesOrNo).option("--tiktok-promotes-third-party <yes|no>", "declare third-party promotion", yesOrNo).option("--tiktok-ai-generated <yes|no>", "declare AI-generated TikTok content", yesOrNo).option("--tiktok-cover-timestamp-ms <number>", "video cover timestamp in milliseconds", nonnegativeInteger).option("--tiktok-settings-reviewed", "confirm the TikTok account choices were reviewed; separate from --yes").option("--youtube-caption <text>", "YouTube description override; otherwise the shared caption is used").option("--bluesky-caption <text>", "Bluesky-specific caption override; limited to 300 graphemes").option("--linkedin-caption <text>", "LinkedIn-specific caption override; limited to 3,000 characters").option("--youtube-title <text>", "required YouTube video title").option("--youtube-category-id <id>", "required numeric YouTube video category ID").option("--youtube-privacy <status>", "required PUBLIC, UNLISTED, or PRIVATE visibility", youtubePrivacy).option("--youtube-made-for-kids <yes|no>", "required explicit YouTube audience declaration", yesOrNo).option("--youtube-synthetic-media", "declare realistic altered or synthetic media to YouTube").option("--no-youtube-notify-subscribers", "disable eligible YouTube subscriber notifications").option("--youtube-tag <tag>", "YouTube tag; repeat as needed", collectString, []).option("--idempotency-key <key>", "stable retry key; defaults to the request ID").option("--yes", "confirm creation without an interactive prompt").action(async (local) => {
|
|
1509
1526
|
const global = program.opts();
|
|
1510
1527
|
commandExitCode = await execute({
|
|
1511
1528
|
command: "posts create",
|
|
@@ -1531,7 +1548,8 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1531
1548
|
...local.instagramCaption === void 0 ? {} : { INSTAGRAM: local.instagramCaption },
|
|
1532
1549
|
...local.tiktokCaption === void 0 ? {} : { TIKTOK: local.tiktokCaption },
|
|
1533
1550
|
...local.youtubeCaption === void 0 ? {} : { YOUTUBE: local.youtubeCaption },
|
|
1534
|
-
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption }
|
|
1551
|
+
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption },
|
|
1552
|
+
...local.linkedinCaption === void 0 ? {} : { LINKEDIN: local.linkedinCaption }
|
|
1535
1553
|
},
|
|
1536
1554
|
tiktokSettings: tiktokSettings(local) ?? null,
|
|
1537
1555
|
youtubeSettings: youtubeSettings(local)
|
|
@@ -1549,7 +1567,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1549
1567
|
}
|
|
1550
1568
|
});
|
|
1551
1569
|
});
|
|
1552
|
-
posts.command("update").description("Update selected draft fields using optimistic concurrency").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).option("--caption <text>", "replacement draft caption; omitted fields are preserved").option("--platform <provider>", "replacement destinations; repeat as needed", collectPublishingProvider).option("--clear-platforms", "remove every draft destination").option("--media <asset-id>", "replacement media asset ID; repeat for multiple", collectString).option("--clear-media", "remove every media asset from the draft").option("--instagram-caption <text>", "Instagram-specific caption override").option("--tiktok-caption <text>", "TikTok-specific caption override").option("--tiktok-mode <mode>", "direct publishing or inbox draft delivery", tiktokPostMode).option("--tiktok-visibility <value>", "exact visibility returned by integrations delivery-options").option("--tiktok-comments <yes|no>", "allow TikTok comments", yesOrNo).option("--tiktok-duet <yes|no>", "allow TikTok duets", yesOrNo).option("--tiktok-stitch <yes|no>", "allow TikTok stitches", yesOrNo).option("--tiktok-commercial-content <yes|no>", "declare commercial TikTok content", yesOrNo).option("--tiktok-promotes-own-brand <yes|no>", "declare own-brand promotion", yesOrNo).option("--tiktok-promotes-third-party <yes|no>", "declare third-party promotion", yesOrNo).option("--tiktok-ai-generated <yes|no>", "declare AI-generated TikTok content", yesOrNo).option("--tiktok-cover-timestamp-ms <number>", "video cover timestamp in milliseconds", nonnegativeInteger).option("--tiktok-settings-reviewed", "confirm the TikTok account choices were reviewed; separate from --yes").option("--youtube-caption <text>", "YouTube description override; otherwise the shared caption is used").option("--bluesky-caption <text>", "Bluesky-specific caption override; limited to 300 graphemes").option("--youtube-title <text>", "required YouTube video title").option("--youtube-category-id <id>", "required numeric YouTube video category ID").option("--youtube-privacy <status>", "required PUBLIC, UNLISTED, or PRIVATE visibility", youtubePrivacy).option("--youtube-made-for-kids <yes|no>", "required explicit YouTube audience declaration", yesOrNo).option("--youtube-synthetic-media", "declare realistic altered or synthetic media to YouTube").option("--no-youtube-notify-subscribers", "disable eligible YouTube subscriber notifications").option("--youtube-tag <tag>", "replacement YouTube tag; repeat as needed", collectString).option("--idempotency-key <key>", "stable retry key; defaults to the request ID").option("--yes", "confirm the update without an interactive prompt").action(async (postId, local) => {
|
|
1570
|
+
posts.command("update").description("Update selected draft fields using optimistic concurrency").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).option("--caption <text>", "replacement draft caption; omitted fields are preserved").option("--platform <provider>", "replacement destinations; repeat as needed", collectPublishingProvider).option("--clear-platforms", "remove every draft destination").option("--media <asset-id>", "replacement media asset ID; repeat for multiple", collectString).option("--clear-media", "remove every media asset from the draft").option("--instagram-caption <text>", "Instagram-specific caption override").option("--tiktok-caption <text>", "TikTok-specific caption override").option("--tiktok-mode <mode>", "direct publishing or inbox draft delivery", tiktokPostMode).option("--tiktok-visibility <value>", "exact visibility returned by integrations delivery-options").option("--tiktok-comments <yes|no>", "allow TikTok comments", yesOrNo).option("--tiktok-duet <yes|no>", "allow TikTok duets", yesOrNo).option("--tiktok-stitch <yes|no>", "allow TikTok stitches", yesOrNo).option("--tiktok-commercial-content <yes|no>", "declare commercial TikTok content", yesOrNo).option("--tiktok-promotes-own-brand <yes|no>", "declare own-brand promotion", yesOrNo).option("--tiktok-promotes-third-party <yes|no>", "declare third-party promotion", yesOrNo).option("--tiktok-ai-generated <yes|no>", "declare AI-generated TikTok content", yesOrNo).option("--tiktok-cover-timestamp-ms <number>", "video cover timestamp in milliseconds", nonnegativeInteger).option("--tiktok-settings-reviewed", "confirm the TikTok account choices were reviewed; separate from --yes").option("--youtube-caption <text>", "YouTube description override; otherwise the shared caption is used").option("--bluesky-caption <text>", "Bluesky-specific caption override; limited to 300 graphemes").option("--linkedin-caption <text>", "LinkedIn-specific caption override; limited to 3,000 characters").option("--youtube-title <text>", "required YouTube video title").option("--youtube-category-id <id>", "required numeric YouTube video category ID").option("--youtube-privacy <status>", "required PUBLIC, UNLISTED, or PRIVATE visibility", youtubePrivacy).option("--youtube-made-for-kids <yes|no>", "required explicit YouTube audience declaration", yesOrNo).option("--youtube-synthetic-media", "declare realistic altered or synthetic media to YouTube").option("--no-youtube-notify-subscribers", "disable eligible YouTube subscriber notifications").option("--youtube-tag <tag>", "replacement YouTube tag; repeat as needed", collectString).option("--idempotency-key <key>", "stable retry key; defaults to the request ID").option("--yes", "confirm the update without an interactive prompt").action(async (postId, local) => {
|
|
1553
1571
|
const global = program.opts();
|
|
1554
1572
|
commandExitCode = await execute({
|
|
1555
1573
|
command: "posts update",
|
|
@@ -1577,7 +1595,8 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1577
1595
|
...local.instagramCaption === void 0 ? {} : { INSTAGRAM: local.instagramCaption },
|
|
1578
1596
|
...local.tiktokCaption === void 0 ? {} : { TIKTOK: local.tiktokCaption },
|
|
1579
1597
|
...local.youtubeCaption === void 0 ? {} : { YOUTUBE: local.youtubeCaption },
|
|
1580
|
-
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption }
|
|
1598
|
+
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption },
|
|
1599
|
+
...local.linkedinCaption === void 0 ? {} : { LINKEDIN: local.linkedinCaption }
|
|
1581
1600
|
};
|
|
1582
1601
|
const resolvedTikTokSettings = tiktokSettings(local);
|
|
1583
1602
|
const resolvedYouTubeSettings = youtubeSettings(local);
|
|
@@ -1725,7 +1744,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1725
1744
|
});
|
|
1726
1745
|
});
|
|
1727
1746
|
const publish = posts.command("publish").description("Preview and queue server-confirmed immediate publishing");
|
|
1728
|
-
publish.command("preview").description("Validate exact destinations and issue a five-minute confirmation").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).requiredOption("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, or
|
|
1747
|
+
publish.command("preview").description("Validate exact destinations and issue a five-minute confirmation").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).requiredOption("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, BLUESKY, or LINKEDIN; repeat as needed", collectPublishingProvider).action(async (postId, local) => {
|
|
1729
1748
|
const global = program.opts();
|
|
1730
1749
|
commandExitCode = await execute({
|
|
1731
1750
|
command: "posts publish preview",
|
|
@@ -1808,16 +1827,13 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1808
1827
|
}
|
|
1809
1828
|
});
|
|
1810
1829
|
});
|
|
1811
|
-
integrations.command("delivery-options").description("Refresh secret-safe creator delivery choices for one provider").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--provider <provider>", "publishing provider;
|
|
1830
|
+
integrations.command("delivery-options").description("Refresh secret-safe creator delivery choices for one provider").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--provider <provider>", "publishing provider; TIKTOK or LINKEDIN", deliveryOptionsProvider).action(async (local) => {
|
|
1812
1831
|
const global = program.opts();
|
|
1813
1832
|
commandExitCode = await execute({
|
|
1814
1833
|
command: "integrations delivery-options",
|
|
1815
1834
|
global,
|
|
1816
1835
|
runtime,
|
|
1817
1836
|
async action(context, client) {
|
|
1818
|
-
if (local.provider !== "TIKTOK") {
|
|
1819
|
-
throw new TypeError("Delivery options are currently available for TIKTOK.");
|
|
1820
|
-
}
|
|
1821
1837
|
const options = await client.integrations.deliveryOptions(
|
|
1822
1838
|
local.project,
|
|
1823
1839
|
local.provider,
|
|
@@ -1827,7 +1843,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1827
1843
|
context,
|
|
1828
1844
|
options,
|
|
1829
1845
|
formatProviderDeliveryOptions(options),
|
|
1830
|
-
[`rolino posts create --project ${local.project} --caption <text> --platform
|
|
1846
|
+
[`rolino posts create --project ${local.project} --caption <text> --platform ${local.provider} --agent --yes`]
|
|
1831
1847
|
);
|
|
1832
1848
|
}
|
|
1833
1849
|
});
|