@rolino/cli 0.7.0 → 0.7.1
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 +9 -0
- package/README.md +8 -4
- package/dist/bin.cjs +30 -34
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-PEJ2WA66.js → chunk-KSPZKKBG.js} +13 -17
- package/dist/chunk-KSPZKKBG.js.map +1 -0
- package/dist/index.cjs +30 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-PEJ2WA66.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.7.
|
|
53
|
+
version: "0.7.1",
|
|
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.7.
|
|
111
|
-
"@rolino/local-auth": "0.7.
|
|
112
|
-
"@rolino/sdk": "0.7.
|
|
110
|
+
"@rolino/contracts": "0.7.1",
|
|
111
|
+
"@rolino/local-auth": "0.7.1",
|
|
112
|
+
"@rolino/sdk": "0.7.1",
|
|
113
113
|
commander: "^15.0.0",
|
|
114
114
|
open: "^11.0.0"
|
|
115
115
|
},
|
|
@@ -122,24 +122,21 @@ var package_default = {
|
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
// src/cli.ts
|
|
125
|
-
var
|
|
125
|
+
var import_contracts2 = require("@rolino/contracts");
|
|
126
126
|
var import_sdk = require("@rolino/sdk");
|
|
127
127
|
|
|
128
128
|
// src/browser-login.ts
|
|
129
129
|
var import_node_crypto = require("crypto");
|
|
130
130
|
var import_node_http = require("http");
|
|
131
|
+
var import_contracts = require("@rolino/contracts");
|
|
131
132
|
var import_local_auth = require("@rolino/local-auth");
|
|
132
133
|
var import_open = __toESM(require("open"), 1);
|
|
133
134
|
var OAUTH_CALLBACK_PORT = 48391;
|
|
134
135
|
var OAUTH_CALLBACK_PATH = "/oauth/callback";
|
|
135
136
|
var OAUTH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
136
|
-
var
|
|
137
|
+
var AUTHORIZATION_REQUEST_SCOPES = [
|
|
137
138
|
"offline_access",
|
|
138
|
-
|
|
139
|
-
"projects:read",
|
|
140
|
-
"posts:read",
|
|
141
|
-
"integrations:read",
|
|
142
|
-
"calendar:read"
|
|
139
|
+
...import_contracts.AGENT_CAPABILITIES
|
|
143
140
|
];
|
|
144
141
|
function escapeHtml(value) {
|
|
145
142
|
return value.replace(/[&<>"']/g, (character) => ({
|
|
@@ -179,7 +176,7 @@ function createBrowserAuthorizationRequest(baseUrl) {
|
|
|
179
176
|
url.searchParams.set("response_type", "code");
|
|
180
177
|
url.searchParams.set("client_id", configuration.clientId);
|
|
181
178
|
url.searchParams.set("redirect_uri", redirectUri);
|
|
182
|
-
url.searchParams.set("scope",
|
|
179
|
+
url.searchParams.set("scope", AUTHORIZATION_REQUEST_SCOPES.join(" "));
|
|
183
180
|
url.searchParams.set("resource", configuration.resource);
|
|
184
181
|
url.searchParams.set("state", state);
|
|
185
182
|
url.searchParams.set("code_challenge", codeChallenge);
|
|
@@ -218,7 +215,7 @@ async function exchangeAuthorizationCode(options) {
|
|
|
218
215
|
accessTokenExpiresAt: new Date(Date.now() + expiresIn * 1e3).toISOString(),
|
|
219
216
|
refreshToken: payload.refresh_token,
|
|
220
217
|
refreshTokenExpiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
221
|
-
scopes: typeof payload.scope === "string" ? payload.scope.split(/\s+/).filter(Boolean) : [...
|
|
218
|
+
scopes: typeof payload.scope === "string" ? payload.scope.split(/\s+/).filter(Boolean) : [...AUTHORIZATION_REQUEST_SCOPES]
|
|
222
219
|
};
|
|
223
220
|
}
|
|
224
221
|
async function loginWithBrowser(options) {
|
|
@@ -685,13 +682,12 @@ function updateCodexConfig(source, server) {
|
|
|
685
682
|
const block = codexBlock(server, newline);
|
|
686
683
|
const begin = source.indexOf(CODEX_BEGIN);
|
|
687
684
|
const end = source.indexOf(CODEX_END);
|
|
688
|
-
if (begin === -1 !== (end === -1) || begin !== -1 && end < begin) {
|
|
689
|
-
throw new TypeError("Codex config contains an incomplete Rolino-managed block.");
|
|
690
|
-
}
|
|
691
685
|
let unmanagedSource = source;
|
|
692
|
-
if (begin !== -1) {
|
|
686
|
+
if (begin !== -1 && end !== -1 && end > begin) {
|
|
693
687
|
const after = end + CODEX_END.length;
|
|
694
688
|
unmanagedSource = `${source.slice(0, begin)}${source.slice(after)}`;
|
|
689
|
+
} else if (begin !== -1 || end !== -1) {
|
|
690
|
+
unmanagedSource = source.split(/\r?\n/).filter((line) => line.trim() !== CODEX_BEGIN && line.trim() !== CODEX_END).join(newline);
|
|
695
691
|
}
|
|
696
692
|
const withoutRolino = removeExistingCodexEntry(unmanagedSource, newline);
|
|
697
693
|
return `${withoutRolino ? `${withoutRolino}${newline}${newline}` : ""}${block}${newline}`;
|
|
@@ -897,40 +893,40 @@ function outputFormat(value) {
|
|
|
897
893
|
throw new import_commander.InvalidArgumentError("Output must be human, json, or jsonl.");
|
|
898
894
|
}
|
|
899
895
|
function postStatus(value) {
|
|
900
|
-
const parsed =
|
|
896
|
+
const parsed = import_contracts2.PostStatusSchema.safeParse(value.toUpperCase());
|
|
901
897
|
if (parsed.success) return parsed.data;
|
|
902
898
|
throw new import_commander.InvalidArgumentError(
|
|
903
|
-
`Status must be one of ${
|
|
899
|
+
`Status must be one of ${import_contracts2.PostStatusSchema.options.join(", ")}.`
|
|
904
900
|
);
|
|
905
901
|
}
|
|
906
902
|
function seoOpportunityKind(value) {
|
|
907
|
-
const parsed =
|
|
903
|
+
const parsed = import_contracts2.SeoOpportunityKindSchema.safeParse(value.toUpperCase());
|
|
908
904
|
if (parsed.success) return parsed.data;
|
|
909
|
-
throw new import_commander.InvalidArgumentError(`SEO kind must be one of ${
|
|
905
|
+
throw new import_commander.InvalidArgumentError(`SEO kind must be one of ${import_contracts2.SeoOpportunityKindSchema.options.join(", ")}.`);
|
|
910
906
|
}
|
|
911
907
|
function seoExpectedImpact(value) {
|
|
912
|
-
const parsed =
|
|
908
|
+
const parsed = import_contracts2.SeoExpectedImpactSchema.safeParse(value.toUpperCase());
|
|
913
909
|
if (parsed.success) return parsed.data;
|
|
914
910
|
throw new import_commander.InvalidArgumentError("SEO impact must be HIGH, MEDIUM, or LOW.");
|
|
915
911
|
}
|
|
916
912
|
function seoReportCompleteness(value) {
|
|
917
|
-
const parsed =
|
|
913
|
+
const parsed = import_contracts2.SeoReportCompletenessSchema.safeParse(value.toUpperCase());
|
|
918
914
|
if (parsed.success) return parsed.data;
|
|
919
915
|
throw new import_commander.InvalidArgumentError("Report status must be COMPLETE or PARTIAL.");
|
|
920
916
|
}
|
|
921
917
|
function projectType(value) {
|
|
922
|
-
const parsed =
|
|
918
|
+
const parsed = import_contracts2.ProjectTypeSchema.safeParse(value.toUpperCase());
|
|
923
919
|
if (parsed.success) return parsed.data;
|
|
924
920
|
throw new import_commander.InvalidArgumentError(
|
|
925
|
-
`Type must be one of ${
|
|
921
|
+
`Type must be one of ${import_contracts2.ProjectTypeSchema.options.join(", ")}.`
|
|
926
922
|
);
|
|
927
923
|
}
|
|
928
924
|
function publishingProvider(value) {
|
|
929
925
|
const normalized = value.toUpperCase();
|
|
930
|
-
const parsed =
|
|
926
|
+
const parsed = import_contracts2.PublishingProviderSchema.safeParse(normalized);
|
|
931
927
|
if (parsed.success) return parsed.data;
|
|
932
928
|
throw new import_commander.InvalidArgumentError(
|
|
933
|
-
`Platform must be one of ${
|
|
929
|
+
`Platform must be one of ${import_contracts2.PublishingProviderSchema.options.join(", ")}.`
|
|
934
930
|
);
|
|
935
931
|
}
|
|
936
932
|
function collectPublishingProvider(value, previous) {
|
|
@@ -941,10 +937,10 @@ function collectString(value, previous) {
|
|
|
941
937
|
}
|
|
942
938
|
function deliveryOptionsProvider(value) {
|
|
943
939
|
const normalized = value.toUpperCase();
|
|
944
|
-
const parsed =
|
|
940
|
+
const parsed = import_contracts2.ProviderDeliveryOptionsProviderSchema.safeParse(normalized);
|
|
945
941
|
if (parsed.success) return parsed.data;
|
|
946
942
|
throw new import_commander.InvalidArgumentError(
|
|
947
|
-
`Provider must be one of ${
|
|
943
|
+
`Provider must be one of ${import_contracts2.ProviderDeliveryOptionsProviderSchema.options.join(", ")}.`
|
|
948
944
|
);
|
|
949
945
|
}
|
|
950
946
|
function tiktokPostMode(value) {
|
|
@@ -982,7 +978,7 @@ function yesOrNo(value) {
|
|
|
982
978
|
function youtubeSettings(options) {
|
|
983
979
|
const hasYouTubeOptions = options.youtubeTitle !== void 0 || options.youtubeCategoryId !== void 0 || options.youtubePrivacy !== void 0 || options.youtubeMadeForKids !== void 0 || options.youtubeSyntheticMedia === true || options.youtubeNotifySubscribers === false || (options.youtubeTag?.length ?? 0) > 0;
|
|
984
980
|
if (!hasYouTubeOptions) return null;
|
|
985
|
-
return
|
|
981
|
+
return import_contracts2.YouTubePostSettingsSchema.parse({
|
|
986
982
|
title: options.youtubeTitle,
|
|
987
983
|
categoryId: options.youtubeCategoryId,
|
|
988
984
|
privacyStatus: options.youtubePrivacy,
|
|
@@ -1171,7 +1167,7 @@ function errorForOutput(error) {
|
|
|
1171
1167
|
function tiktokSettings(options) {
|
|
1172
1168
|
const hasTikTokOptions = options.tiktokMode !== void 0 || options.tiktokVisibility !== void 0 || options.tiktokComments !== void 0 || options.tiktokDuet !== void 0 || options.tiktokStitch !== void 0 || options.tiktokCommercialContent !== void 0 || options.tiktokPromotesOwnBrand !== void 0 || options.tiktokPromotesThirdParty !== void 0 || options.tiktokAiGenerated !== void 0 || options.tiktokCoverTimestampMs !== void 0 || options.tiktokSettingsReviewed === true;
|
|
1173
1169
|
if (!hasTikTokOptions) return void 0;
|
|
1174
|
-
return
|
|
1170
|
+
return import_contracts2.TikTokDraftSettingsSchema.parse({
|
|
1175
1171
|
postMode: options.tiktokMode,
|
|
1176
1172
|
privacyLevel: options.tiktokVisibility,
|
|
1177
1173
|
allowComment: options.tiktokComments,
|
|
@@ -1315,7 +1311,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1315
1311
|
global,
|
|
1316
1312
|
runtime,
|
|
1317
1313
|
async action(context, client) {
|
|
1318
|
-
const parsed =
|
|
1314
|
+
const parsed = import_contracts2.ProjectCreateInputSchema.safeParse({
|
|
1319
1315
|
name: local.name,
|
|
1320
1316
|
type: local.type,
|
|
1321
1317
|
websiteUrl: local.website,
|
|
@@ -2191,7 +2187,7 @@ This moves eligible editorial dates only. It does not schedule, publish, or unpu
|
|
|
2191
2187
|
blogArticles.command("update").argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--input <json-file>", "complete Blog draft JSON file").option("--yes", "confirm the draft save").action(async (articleId, local) => {
|
|
2192
2188
|
const global = program.opts();
|
|
2193
2189
|
commandExitCode = await execute({ command: "blog articles update", global, runtime, async action(context, client) {
|
|
2194
|
-
const draft =
|
|
2190
|
+
const draft = import_contracts2.AgentBlogDraftUpdateSchema.parse(JSON.parse(await (0, import_promises2.readFile)((0, import_node_path2.resolve)(runtime.cwd, local.input), "utf8")));
|
|
2195
2191
|
await requireWriteConsent({ yes: local.yes, global, runtime, preview: `Save a new immutable Blog draft revision?
|
|
2196
2192
|
Project: ${local.project}
|
|
2197
2193
|
Article: ${articleId}
|
|
@@ -2368,7 +2364,7 @@ Revision: ${local.revision}` });
|
|
|
2368
2364
|
backlinkProspects.command("list").requiredOption("--project <project-id>").option("--stage <stage>").action(async (local) => {
|
|
2369
2365
|
const global = program.opts();
|
|
2370
2366
|
commandExitCode = await execute({ command: "backlinks prospects list", global, runtime, async action(context, client) {
|
|
2371
|
-
const stage = local.stage ?
|
|
2367
|
+
const stage = local.stage ? import_contracts2.BacklinkProspectStageSchema.parse(local.stage.toUpperCase()) : void 0;
|
|
2372
2368
|
const data = await client.backlinks.prospects.list(local.project, { stage }, { requestId: context.requestId });
|
|
2373
2369
|
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2374
2370
|
} });
|