@rolino/cli 0.5.0-beta.0 → 0.5.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 +41 -0
- package/README.md +63 -26
- package/dist/bin.cjs +105 -4
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-TFNGSKT3.js → chunk-MBZL2CK6.js} +106 -5
- package/dist/chunk-MBZL2CK6.js.map +1 -0
- package/dist/index.cjs +105 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-TFNGSKT3.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -285,7 +285,7 @@ import { Command, CommanderError, InvalidArgumentError } from "commander";
|
|
|
285
285
|
// package.json
|
|
286
286
|
var package_default = {
|
|
287
287
|
name: "@rolino/cli",
|
|
288
|
-
version: "0.5.0
|
|
288
|
+
version: "0.5.0",
|
|
289
289
|
description: "Agent-friendly command-line interface for Rolino",
|
|
290
290
|
type: "module",
|
|
291
291
|
license: "MIT",
|
|
@@ -342,9 +342,9 @@ var package_default = {
|
|
|
342
342
|
dev: "tsx src/bin.ts"
|
|
343
343
|
},
|
|
344
344
|
dependencies: {
|
|
345
|
-
"@rolino/contracts": "0.5.0
|
|
346
|
-
"@rolino/local-auth": "0.5.0
|
|
347
|
-
"@rolino/sdk": "0.5.0
|
|
345
|
+
"@rolino/contracts": "0.5.0",
|
|
346
|
+
"@rolino/local-auth": "0.5.0",
|
|
347
|
+
"@rolino/sdk": "0.5.0",
|
|
348
348
|
commander: "^15.0.0",
|
|
349
349
|
open: "^11.0.0"
|
|
350
350
|
},
|
|
@@ -1060,6 +1060,10 @@ async function requireWriteConsent(options) {
|
|
|
1060
1060
|
);
|
|
1061
1061
|
}
|
|
1062
1062
|
}
|
|
1063
|
+
function requireBlogExecutionConsent(options) {
|
|
1064
|
+
if (options.yes || resolveFormat(options.global, options.runtime) !== "human") return;
|
|
1065
|
+
throw new TypeError("This Blog execute command requires explicit consent. Review the confirmed operation and pass --yes.");
|
|
1066
|
+
}
|
|
1063
1067
|
function formatMcpSetupPreview(result) {
|
|
1064
1068
|
return [
|
|
1065
1069
|
`Client: ${result.client === "codex" ? "Codex" : "Claude Code"}`,
|
|
@@ -2120,6 +2124,103 @@ Article: ${articleId}` });
|
|
|
2120
2124
|
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2121
2125
|
} });
|
|
2122
2126
|
});
|
|
2127
|
+
const blogImages = blog.command("images").description("Create and review Blog images with blog:write; cannot approve or publish");
|
|
2128
|
+
blogImages.command("generate").description("Queue one exact-revision featured image with blog:write; cannot approve or publish").argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--revision <revision-id>", "exact Blog revision ID").option("--editorial-brief <text>", "bounded visual direction; provider controls stay on the server").option("--idempotency-key <key>", "stable retry key; defaults to request ID").action(async (articleId, local) => {
|
|
2129
|
+
const global = program.opts();
|
|
2130
|
+
commandExitCode = await execute({ command: "blog images generate", global, runtime, async action(context, client) {
|
|
2131
|
+
const data = await client.blog.articles.generateImage(local.project, articleId, { revisionId: local.revision, idempotencyKey: local.idempotencyKey ?? context.requestId, editorialBrief: local.editorialBrief }, { requestId: context.requestId });
|
|
2132
|
+
writeSuccess(context, data, `Blog image generation queued.
|
|
2133
|
+
Image: ${data.image.id}
|
|
2134
|
+
Job: ${data.job.id}`);
|
|
2135
|
+
} });
|
|
2136
|
+
});
|
|
2137
|
+
blogImages.command("upload").description("Upload one JPEG, PNG, or WebP for an exact Blog revision with blog:write; cannot approve or publish").argument("<article-id>").argument("<file-path>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--revision <revision-id>", "exact Blog revision ID").requiredOption("--alt-text <text>", "reviewable image alt text").action(async (articleId, filePath, local) => {
|
|
2138
|
+
const global = program.opts();
|
|
2139
|
+
commandExitCode = await execute({ command: "blog images upload", global, runtime, async action(context, client) {
|
|
2140
|
+
const absolutePath = resolve2(runtime.cwd, filePath);
|
|
2141
|
+
const details = await stat(absolutePath).catch(() => null);
|
|
2142
|
+
if (!details?.isFile()) throw new TypeError("The Blog image path must point to a readable file.");
|
|
2143
|
+
const contentTypes = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".webp": "image/webp" };
|
|
2144
|
+
const extension = extname(absolutePath).toLowerCase();
|
|
2145
|
+
const contentType = contentTypes[extension];
|
|
2146
|
+
if (!contentType) throw new TypeError("Use a JPEG, PNG, or WebP Blog image.");
|
|
2147
|
+
const body = await openAsBlob(absolutePath, { type: contentType });
|
|
2148
|
+
const data = await client.blog.articles.uploadImage(local.project, articleId, { revisionId: local.revision, fileName: basename(absolutePath), contentType, fileSize: details.size, altText: local.altText, body }, { requestId: context.requestId });
|
|
2149
|
+
writeSuccess(context, data, `Blog image uploaded for review.
|
|
2150
|
+
Image: ${data.id}
|
|
2151
|
+
State: ${data.state}`);
|
|
2152
|
+
} });
|
|
2153
|
+
});
|
|
2154
|
+
blogImages.command("review").description("Review one exact Blog image with blog:write; does not approve the article or publish").argument("<article-id>").argument("<image-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--decision <decision>", "APPROVED or REJECTED").requiredOption("--expected-version <version>", "current image version", positiveInteger).option("--alt-text <text>", "final image alt text; required by the server for approval").option("--idempotency-key <key>", "stable retry key; defaults to request ID").action(async (articleId, imageId, local) => {
|
|
2155
|
+
const decision = local.decision.toUpperCase();
|
|
2156
|
+
if (decision !== "APPROVED" && decision !== "REJECTED") throw new TypeError("--decision must be APPROVED or REJECTED.");
|
|
2157
|
+
const global = program.opts();
|
|
2158
|
+
commandExitCode = await execute({ command: "blog images review", global, runtime, async action(context, client) {
|
|
2159
|
+
const data = await client.blog.articles.reviewImage(local.project, articleId, imageId, { decision, expectedVersion: local.expectedVersion, altText: local.altText ?? "", idempotencyKey: local.idempotencyKey ?? context.requestId }, { requestId: context.requestId });
|
|
2160
|
+
writeSuccess(context, data, `Blog image review saved.
|
|
2161
|
+
Image: ${data.id}
|
|
2162
|
+
State: ${data.state}`);
|
|
2163
|
+
} });
|
|
2164
|
+
});
|
|
2165
|
+
const blogApprove = blog.command("approve").description("Approve one exact Blog bundle with blog:approve; cannot publish");
|
|
2166
|
+
blogApprove.command("preview").description("Preview one exact approval bundle with blog:approve; creates a confirmation but cannot publish").argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--revision <revision-id>", "exact Blog revision ID").action(async (articleId, local) => {
|
|
2167
|
+
const global = program.opts();
|
|
2168
|
+
commandExitCode = await execute({ command: "blog approve preview", global, runtime, async action(context, client) {
|
|
2169
|
+
const data = await client.blog.articles.previewApproval(local.project, articleId, { revisionId: local.revision }, { requestId: context.requestId });
|
|
2170
|
+
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2171
|
+
} });
|
|
2172
|
+
});
|
|
2173
|
+
blogApprove.command("execute").description("Approve the confirmed exact bundle with blog:approve; separate blog:publish access is still required").argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--revision <revision-id>", "same exact revision used for preview").requiredOption("--confirmation-token <token>", "short-lived token returned by preview").requiredOption("--idempotency-key <key>", "stable retry key").option("--yes", "confirm exact bundle approval").action(async (articleId, local) => {
|
|
2174
|
+
const global = program.opts();
|
|
2175
|
+
commandExitCode = await execute({ command: "blog approve execute", global, runtime, async action(context, client) {
|
|
2176
|
+
requireBlogExecutionConsent({ yes: local.yes, global, runtime });
|
|
2177
|
+
const data = await client.blog.articles.executeApproval(local.project, articleId, { revisionId: local.revision, confirmationToken: local.confirmationToken, idempotencyKey: local.idempotencyKey }, { requestId: context.requestId });
|
|
2178
|
+
writeSuccess(context, data, `Exact Blog bundle approved.
|
|
2179
|
+
Revision: ${data.revisionId}
|
|
2180
|
+
Publishing still requires blog:publish.`);
|
|
2181
|
+
} });
|
|
2182
|
+
});
|
|
2183
|
+
const blogSchedule = blog.command("schedule").description("Schedule exact approved Blog bundles with blog:publish; does not grant approval");
|
|
2184
|
+
const addScheduleOptions = (command, executeSchedule) => {
|
|
2185
|
+
command.argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--revision <revision-id>", "exact approved Blog revision ID").requiredOption("--at <iso>", "future ISO date-time with UTC offset").requiredOption("--timezone <iana>", "explicit IANA timezone").option("--destination <destination-id...>", "exact destination IDs; defaults to the current primary");
|
|
2186
|
+
if (executeSchedule) command.requiredOption("--confirmation-token <token>", "short-lived token returned by preview").requiredOption("--idempotency-key <key>", "stable retry key").option("--yes", "confirm future external publication");
|
|
2187
|
+
return command;
|
|
2188
|
+
};
|
|
2189
|
+
addScheduleOptions(blogSchedule.command("preview").description("Preview an exact future Blog schedule with blog:publish; does not publish now"), false).action(async (articleId, local) => {
|
|
2190
|
+
const global = program.opts();
|
|
2191
|
+
commandExitCode = await execute({ command: "blog schedule preview", global, runtime, async action(context, client) {
|
|
2192
|
+
const data = await client.blog.articles.previewSchedule(local.project, articleId, { revisionId: local.revision, scheduledAt: local.at, timezone: local.timezone, destinationIds: local.destination }, { requestId: context.requestId });
|
|
2193
|
+
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2194
|
+
} });
|
|
2195
|
+
});
|
|
2196
|
+
addScheduleOptions(blogSchedule.command("execute").description("Execute a confirmed future Blog schedule with blog:publish; causes future external publication"), true).action(async (articleId, local) => {
|
|
2197
|
+
const global = program.opts();
|
|
2198
|
+
commandExitCode = await execute({ command: "blog schedule execute", global, runtime, async action(context, client) {
|
|
2199
|
+
requireBlogExecutionConsent({ yes: local.yes, global, runtime });
|
|
2200
|
+
const data = await client.blog.articles.executeSchedule(local.project, articleId, { revisionId: local.revision, scheduledAt: local.at, timezone: local.timezone, destinationIds: local.destination, confirmationToken: local.confirmationToken, idempotencyKey: local.idempotencyKey }, { requestId: context.requestId });
|
|
2201
|
+
writeSuccess(context, data, `Blog article scheduled.
|
|
2202
|
+
Time: ${data.scheduledAt}
|
|
2203
|
+
Timezone: ${data.timezone}`);
|
|
2204
|
+
} });
|
|
2205
|
+
});
|
|
2206
|
+
const blogScheduleCancel = blogSchedule.command("cancel").description("Cancel one future Blog schedule with blog:publish; never unpublishes a live article");
|
|
2207
|
+
blogScheduleCancel.command("preview").description("Preview exact schedule cancellation with blog:publish; does not unpublish").argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").action(async (articleId, local) => {
|
|
2208
|
+
const global = program.opts();
|
|
2209
|
+
commandExitCode = await execute({ command: "blog schedule cancel preview", global, runtime, async action(context, client) {
|
|
2210
|
+
const data = await client.blog.articles.previewScheduleCancellation(local.project, articleId, { requestId: context.requestId });
|
|
2211
|
+
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2212
|
+
} });
|
|
2213
|
+
});
|
|
2214
|
+
blogScheduleCancel.command("execute").description("Cancel the confirmed future schedule with blog:publish; never unpublishes a live article").argument("<article-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--confirmation-token <token>", "short-lived token returned by preview").requiredOption("--idempotency-key <key>", "stable retry key").option("--yes", "confirm schedule cancellation").action(async (articleId, local) => {
|
|
2215
|
+
const global = program.opts();
|
|
2216
|
+
commandExitCode = await execute({ command: "blog schedule cancel execute", global, runtime, async action(context, client) {
|
|
2217
|
+
requireBlogExecutionConsent({ yes: local.yes, global, runtime });
|
|
2218
|
+
const data = await client.blog.articles.executeScheduleCancellation(local.project, articleId, { confirmationToken: local.confirmationToken, idempotencyKey: local.idempotencyKey }, { requestId: context.requestId });
|
|
2219
|
+
writeSuccess(context, data, `Future Blog schedule canceled.
|
|
2220
|
+
Article: ${data.articleId}
|
|
2221
|
+
A live article was not unpublished.`);
|
|
2222
|
+
} });
|
|
2223
|
+
});
|
|
2123
2224
|
blog.command("job").argument("<job-id>").requiredOption("--project <project-id>", "exact Rolino project ID").action(async (jobId, local) => {
|
|
2124
2225
|
const global = program.opts();
|
|
2125
2226
|
commandExitCode = await execute({ command: "blog job", global, runtime, async action(context, client) {
|
|
@@ -2311,4 +2412,4 @@ export {
|
|
|
2311
2412
|
ROLINO_CLI_VERSION,
|
|
2312
2413
|
runCli
|
|
2313
2414
|
};
|
|
2314
|
-
//# sourceMappingURL=chunk-
|
|
2415
|
+
//# sourceMappingURL=chunk-MBZL2CK6.js.map
|