@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @rolino/cli
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4f9e790: Add the optional `blog:manage` capability and synchronized agent-first Blog
|
|
8
|
+
setup, import, cadence planning, plan review, article creation, confirmed
|
|
9
|
+
connection provisioning, and safe verification operations.
|
|
10
|
+
- 1edd1e7: Add published Blog Studio delivery contracts and the server-only Next.js 16 Blog Studio package.
|
|
11
|
+
- 74a13ea: Expose immediate versus scheduled delivery and destination lifecycle stages,
|
|
12
|
+
preserve YouTube visibility for immediate publishing, and clarify remote
|
|
13
|
+
schedule confirmation across public clients.
|
|
14
|
+
- 4af607d: Add independent exact-bundle Blog approval, reviewed image upload and generation,
|
|
15
|
+
confirmed publication scheduling and cancellation, and the complete authorized
|
|
16
|
+
agent workflow without widening existing credentials.
|
|
17
|
+
- 4a893dd: Add provider-neutral Blog publishing destinations, safe delivery inspection,
|
|
18
|
+
and exact destination binding across public agent interfaces.
|
|
19
|
+
- 843a1db: Add the exact optional `seo:read` capability and bounded read-only SEO
|
|
20
|
+
opportunity and weekly-report parity across public agent contracts, clients,
|
|
21
|
+
CLI commands, and closed-world MCP tools. SEO reads now use the version 3 task
|
|
22
|
+
contract with the exact Ready, Research, or Rejected decision, selected format,
|
|
23
|
+
complete deliverables, bounded evidence, safe URLs, limitations, and no-publish
|
|
24
|
+
rules. Public output uses readable topic names and separate topic-relevance and
|
|
25
|
+
action-readiness confidence. Research tasks compare all supported formats and
|
|
26
|
+
must validate or reject the finding before a separate draft action is allowed.
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [4f9e790]
|
|
31
|
+
- Updated dependencies [1edd1e7]
|
|
32
|
+
- Updated dependencies [74a13ea]
|
|
33
|
+
- Updated dependencies [4af607d]
|
|
34
|
+
- Updated dependencies [4a893dd]
|
|
35
|
+
- Updated dependencies [843a1db]
|
|
36
|
+
- @rolino/contracts@0.5.0
|
|
37
|
+
- @rolino/sdk@0.5.0
|
|
38
|
+
- @rolino/local-auth@0.5.0
|
|
39
|
+
|
|
3
40
|
## 0.5.0-beta.0
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
|
@@ -37,6 +74,10 @@
|
|
|
37
74
|
|
|
38
75
|
### Minor Changes
|
|
39
76
|
|
|
77
|
+
- Add Blog image generation, exact local-file upload, image review, confirmed
|
|
78
|
+
exact-bundle approval, future scheduling, and schedule cancellation commands
|
|
79
|
+
with deterministic agent output, stable idempotency, safe errors, and
|
|
80
|
+
independent `blog:write`, `blog:approve`, and `blog:publish` boundaries.
|
|
40
81
|
- Add Blog destination discovery, delivery inspection, and exact destination selection for publication commands.
|
|
41
82
|
|
|
42
83
|
## 0.4.0
|
package/README.md
CHANGED
|
@@ -53,12 +53,21 @@ rolino integrations delivery-options --project PROJECT_ID --provider TIKTOK|LINK
|
|
|
53
53
|
rolino calendar list --project PROJECT_ID [--from ISO_DATE --to ISO_DATE] [--limit 50] [--cursor CURSOR]
|
|
54
54
|
rolino seo opportunities list --project PROJECT_ID [--limit 20] [--cursor CURSOR] [--kind KIND] [--impact HIGH|MEDIUM|LOW]
|
|
55
55
|
rolino seo opportunities show OPPORTUNITY_ID --project PROJECT_ID
|
|
56
|
-
rolino seo reports list --project PROJECT_ID [--limit 10] [--cursor CURSOR] [--status COMPLETE|PARTIAL]
|
|
57
|
-
rolino seo reports show REPORT_ID --project PROJECT_ID
|
|
58
|
-
rolino blog destinations providers --project PROJECT_ID
|
|
59
|
-
rolino blog destinations list --project PROJECT_ID
|
|
60
|
-
rolino blog destinations deliveries --project PROJECT_ID [--article ARTICLE_ID]
|
|
61
|
-
rolino
|
|
56
|
+
rolino seo reports list --project PROJECT_ID [--limit 10] [--cursor CURSOR] [--status COMPLETE|PARTIAL]
|
|
57
|
+
rolino seo reports show REPORT_ID --project PROJECT_ID
|
|
58
|
+
rolino blog destinations providers --project PROJECT_ID
|
|
59
|
+
rolino blog destinations list --project PROJECT_ID
|
|
60
|
+
rolino blog destinations deliveries --project PROJECT_ID [--article ARTICLE_ID]
|
|
61
|
+
rolino blog images generate ARTICLE_ID --project PROJECT_ID --revision REVISION_ID
|
|
62
|
+
rolino blog images upload ARTICLE_ID FILE --project PROJECT_ID --revision REVISION_ID --alt-text TEXT
|
|
63
|
+
rolino blog images review ARTICLE_ID IMAGE_ID --project PROJECT_ID --decision APPROVED|REJECTED --expected-version VERSION [--alt-text TEXT]
|
|
64
|
+
rolino blog approve preview ARTICLE_ID --project PROJECT_ID --revision REVISION_ID
|
|
65
|
+
rolino blog approve execute ARTICLE_ID --project PROJECT_ID --revision REVISION_ID --confirmation-token TOKEN --idempotency-key KEY --yes
|
|
66
|
+
rolino blog schedule preview ARTICLE_ID --project PROJECT_ID --revision REVISION_ID --at ISO --timezone IANA [--destination ID...]
|
|
67
|
+
rolino blog schedule execute ARTICLE_ID --project PROJECT_ID --revision REVISION_ID --at ISO --timezone IANA --confirmation-token TOKEN --idempotency-key KEY --yes
|
|
68
|
+
rolino blog schedule cancel preview ARTICLE_ID --project PROJECT_ID
|
|
69
|
+
rolino blog schedule cancel execute ARTICLE_ID --project PROJECT_ID --confirmation-token TOKEN --idempotency-key KEY --yes
|
|
70
|
+
rolino doctor
|
|
62
71
|
```
|
|
63
72
|
|
|
64
73
|
Interactive login opens the configured Rolino instance in a browser, obtains
|
|
@@ -262,26 +271,54 @@ gain it automatically. Start every setup with:
|
|
|
262
271
|
rolino --agent blog setup status --project PROJECT_ID
|
|
263
272
|
```
|
|
264
273
|
|
|
265
|
-
The `blog site`, `blog plan`, `blog article`, `blog connection`, and
|
|
266
|
-
`blog destinations` command groups mirror the versioned API. Use these safe
|
|
267
|
-
publishing reads before setup or publication:
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
rolino --agent blog destinations providers --project PROJECT_ID
|
|
271
|
-
rolino --agent blog destinations list --project PROJECT_ID
|
|
272
|
-
rolino --agent blog destinations deliveries --project PROJECT_ID
|
|
273
|
-
rolino --agent blog destinations deliveries --project PROJECT_ID --article ARTICLE_ID
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
The provider catalog requires `blog:manage`. It returns only providers enabled
|
|
277
|
-
for the workspace, safe capabilities, and official documentation. Destination
|
|
278
|
-
and delivery-attempt reads require `blog:read`. They omit draft content,
|
|
279
|
-
prompts, evidence, secrets, and raw provider responses. A returned remote URL
|
|
280
|
-
is not proof that a queued or failed delivery is live.
|
|
281
|
-
|
|
282
|
-
Mutations require a stable idempotency key.
|
|
283
|
-
Connection provisioning also requires preview, explicit confirmation, and
|
|
284
|
-
execute. A first successful execute can return a delivery token or webhook
|
|
274
|
+
The `blog site`, `blog plan`, `blog article`, `blog connection`, and
|
|
275
|
+
`blog destinations` command groups mirror the versioned API. Use these safe
|
|
276
|
+
publishing reads before setup or publication:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
rolino --agent blog destinations providers --project PROJECT_ID
|
|
280
|
+
rolino --agent blog destinations list --project PROJECT_ID
|
|
281
|
+
rolino --agent blog destinations deliveries --project PROJECT_ID
|
|
282
|
+
rolino --agent blog destinations deliveries --project PROJECT_ID --article ARTICLE_ID
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The provider catalog requires `blog:manage`. It returns only providers enabled
|
|
286
|
+
for the workspace, safe capabilities, and official documentation. Destination
|
|
287
|
+
and delivery-attempt reads require `blog:read`. They omit draft content,
|
|
288
|
+
prompts, evidence, secrets, and raw provider responses. A returned remote URL
|
|
289
|
+
is not proof that a queued or failed delivery is live.
|
|
290
|
+
|
|
291
|
+
Mutations require a stable idempotency key.
|
|
292
|
+
Connection provisioning also requires preview, explicit confirmation, and
|
|
293
|
+
execute. A first successful execute can return a delivery token or webhook
|
|
285
294
|
secret once; save it only in server-side environment configuration. Replays
|
|
286
295
|
do not reveal it again. Blog publication remains the separate approved exact
|
|
287
296
|
revision preview/execute workflow.
|
|
297
|
+
|
|
298
|
+
Blog image commands require `blog:write`; they cannot approve an article or
|
|
299
|
+
publish it. Image upload reads only the path in the command, accepts JPEG, PNG,
|
|
300
|
+
or WebP, and keeps its signed upload URL and storage key private. Approving an
|
|
301
|
+
exact revision and image bundle requires the independent `blog:approve`
|
|
302
|
+
capability and cannot publish. Scheduling, rescheduling, or canceling a future
|
|
303
|
+
publication requires the independent `blog:publish` capability and does not
|
|
304
|
+
grant approval.
|
|
305
|
+
|
|
306
|
+
Approval, schedule, and cancellation execution bind the short-lived token from
|
|
307
|
+
the matching preview and a stable idempotency key. Human output requires
|
|
308
|
+
`--yes`. JSON mode does not prompt, but it still requires the confirmation
|
|
309
|
+
token and idempotency key. A safe replay uses the same exact input and key.
|
|
310
|
+
|
|
311
|
+
Use this order for complete Blog work:
|
|
312
|
+
|
|
313
|
+
1. Read setup status and current article or plan state.
|
|
314
|
+
2. Ask for any missing website, cadence, destination, and access level.
|
|
315
|
+
3. Import and plan through durable jobs, then poll instead of retrying blindly.
|
|
316
|
+
4. Present evidence before accepting a plan item unless the user already authorized that exact bounded action.
|
|
317
|
+
5. Create or update one immutable revision with catalog-backed links.
|
|
318
|
+
6. Generate or upload one approved image, review it, and verify alt text.
|
|
319
|
+
7. Without `blog:approve`, stop and ask the user to approve in Rolino.
|
|
320
|
+
8. With `blog:approve`, preview and execute the unchanged exact bundle with confirmation and a stable idempotency key.
|
|
321
|
+
9. Without `blog:publish`, stop after approval.
|
|
322
|
+
10. With `blog:publish`, preview and execute unchanged immediate publication or scheduling with a stable idempotency key.
|
|
323
|
+
11. Poll delivery attempts and verify the live remote URL; queued is not published.
|
|
324
|
+
12. After any content or image change, restart from approval preview.
|
package/dist/bin.cjs
CHANGED
|
@@ -34,7 +34,7 @@ var import_commander = require("commander");
|
|
|
34
34
|
// package.json
|
|
35
35
|
var package_default = {
|
|
36
36
|
name: "@rolino/cli",
|
|
37
|
-
version: "0.5.0
|
|
37
|
+
version: "0.5.0",
|
|
38
38
|
description: "Agent-friendly command-line interface for Rolino",
|
|
39
39
|
type: "module",
|
|
40
40
|
license: "MIT",
|
|
@@ -91,9 +91,9 @@ var package_default = {
|
|
|
91
91
|
dev: "tsx src/bin.ts"
|
|
92
92
|
},
|
|
93
93
|
dependencies: {
|
|
94
|
-
"@rolino/contracts": "0.5.0
|
|
95
|
-
"@rolino/local-auth": "0.5.0
|
|
96
|
-
"@rolino/sdk": "0.5.0
|
|
94
|
+
"@rolino/contracts": "0.5.0",
|
|
95
|
+
"@rolino/local-auth": "0.5.0",
|
|
96
|
+
"@rolino/sdk": "0.5.0",
|
|
97
97
|
commander: "^15.0.0",
|
|
98
98
|
open: "^11.0.0"
|
|
99
99
|
},
|
|
@@ -1053,6 +1053,10 @@ async function requireWriteConsent(options) {
|
|
|
1053
1053
|
);
|
|
1054
1054
|
}
|
|
1055
1055
|
}
|
|
1056
|
+
function requireBlogExecutionConsent(options) {
|
|
1057
|
+
if (options.yes || resolveFormat(options.global, options.runtime) !== "human") return;
|
|
1058
|
+
throw new TypeError("This Blog execute command requires explicit consent. Review the confirmed operation and pass --yes.");
|
|
1059
|
+
}
|
|
1056
1060
|
function formatMcpSetupPreview(result) {
|
|
1057
1061
|
return [
|
|
1058
1062
|
`Client: ${result.client === "codex" ? "Codex" : "Claude Code"}`,
|
|
@@ -2113,6 +2117,103 @@ Article: ${articleId}` });
|
|
|
2113
2117
|
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2114
2118
|
} });
|
|
2115
2119
|
});
|
|
2120
|
+
const blogImages = blog.command("images").description("Create and review Blog images with blog:write; cannot approve or publish");
|
|
2121
|
+
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) => {
|
|
2122
|
+
const global = program.opts();
|
|
2123
|
+
commandExitCode = await execute({ command: "blog images generate", global, runtime, async action(context, client) {
|
|
2124
|
+
const data = await client.blog.articles.generateImage(local.project, articleId, { revisionId: local.revision, idempotencyKey: local.idempotencyKey ?? context.requestId, editorialBrief: local.editorialBrief }, { requestId: context.requestId });
|
|
2125
|
+
writeSuccess(context, data, `Blog image generation queued.
|
|
2126
|
+
Image: ${data.image.id}
|
|
2127
|
+
Job: ${data.job.id}`);
|
|
2128
|
+
} });
|
|
2129
|
+
});
|
|
2130
|
+
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) => {
|
|
2131
|
+
const global = program.opts();
|
|
2132
|
+
commandExitCode = await execute({ command: "blog images upload", global, runtime, async action(context, client) {
|
|
2133
|
+
const absolutePath = (0, import_node_path2.resolve)(runtime.cwd, filePath);
|
|
2134
|
+
const details = await (0, import_promises2.stat)(absolutePath).catch(() => null);
|
|
2135
|
+
if (!details?.isFile()) throw new TypeError("The Blog image path must point to a readable file.");
|
|
2136
|
+
const contentTypes = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".webp": "image/webp" };
|
|
2137
|
+
const extension = (0, import_node_path2.extname)(absolutePath).toLowerCase();
|
|
2138
|
+
const contentType = contentTypes[extension];
|
|
2139
|
+
if (!contentType) throw new TypeError("Use a JPEG, PNG, or WebP Blog image.");
|
|
2140
|
+
const body = await (0, import_node_fs2.openAsBlob)(absolutePath, { type: contentType });
|
|
2141
|
+
const data = await client.blog.articles.uploadImage(local.project, articleId, { revisionId: local.revision, fileName: (0, import_node_path2.basename)(absolutePath), contentType, fileSize: details.size, altText: local.altText, body }, { requestId: context.requestId });
|
|
2142
|
+
writeSuccess(context, data, `Blog image uploaded for review.
|
|
2143
|
+
Image: ${data.id}
|
|
2144
|
+
State: ${data.state}`);
|
|
2145
|
+
} });
|
|
2146
|
+
});
|
|
2147
|
+
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) => {
|
|
2148
|
+
const decision = local.decision.toUpperCase();
|
|
2149
|
+
if (decision !== "APPROVED" && decision !== "REJECTED") throw new TypeError("--decision must be APPROVED or REJECTED.");
|
|
2150
|
+
const global = program.opts();
|
|
2151
|
+
commandExitCode = await execute({ command: "blog images review", global, runtime, async action(context, client) {
|
|
2152
|
+
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 });
|
|
2153
|
+
writeSuccess(context, data, `Blog image review saved.
|
|
2154
|
+
Image: ${data.id}
|
|
2155
|
+
State: ${data.state}`);
|
|
2156
|
+
} });
|
|
2157
|
+
});
|
|
2158
|
+
const blogApprove = blog.command("approve").description("Approve one exact Blog bundle with blog:approve; cannot publish");
|
|
2159
|
+
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) => {
|
|
2160
|
+
const global = program.opts();
|
|
2161
|
+
commandExitCode = await execute({ command: "blog approve preview", global, runtime, async action(context, client) {
|
|
2162
|
+
const data = await client.blog.articles.previewApproval(local.project, articleId, { revisionId: local.revision }, { requestId: context.requestId });
|
|
2163
|
+
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2164
|
+
} });
|
|
2165
|
+
});
|
|
2166
|
+
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) => {
|
|
2167
|
+
const global = program.opts();
|
|
2168
|
+
commandExitCode = await execute({ command: "blog approve execute", global, runtime, async action(context, client) {
|
|
2169
|
+
requireBlogExecutionConsent({ yes: local.yes, global, runtime });
|
|
2170
|
+
const data = await client.blog.articles.executeApproval(local.project, articleId, { revisionId: local.revision, confirmationToken: local.confirmationToken, idempotencyKey: local.idempotencyKey }, { requestId: context.requestId });
|
|
2171
|
+
writeSuccess(context, data, `Exact Blog bundle approved.
|
|
2172
|
+
Revision: ${data.revisionId}
|
|
2173
|
+
Publishing still requires blog:publish.`);
|
|
2174
|
+
} });
|
|
2175
|
+
});
|
|
2176
|
+
const blogSchedule = blog.command("schedule").description("Schedule exact approved Blog bundles with blog:publish; does not grant approval");
|
|
2177
|
+
const addScheduleOptions = (command, executeSchedule) => {
|
|
2178
|
+
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");
|
|
2179
|
+
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");
|
|
2180
|
+
return command;
|
|
2181
|
+
};
|
|
2182
|
+
addScheduleOptions(blogSchedule.command("preview").description("Preview an exact future Blog schedule with blog:publish; does not publish now"), false).action(async (articleId, local) => {
|
|
2183
|
+
const global = program.opts();
|
|
2184
|
+
commandExitCode = await execute({ command: "blog schedule preview", global, runtime, async action(context, client) {
|
|
2185
|
+
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 });
|
|
2186
|
+
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2187
|
+
} });
|
|
2188
|
+
});
|
|
2189
|
+
addScheduleOptions(blogSchedule.command("execute").description("Execute a confirmed future Blog schedule with blog:publish; causes future external publication"), true).action(async (articleId, local) => {
|
|
2190
|
+
const global = program.opts();
|
|
2191
|
+
commandExitCode = await execute({ command: "blog schedule execute", global, runtime, async action(context, client) {
|
|
2192
|
+
requireBlogExecutionConsent({ yes: local.yes, global, runtime });
|
|
2193
|
+
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 });
|
|
2194
|
+
writeSuccess(context, data, `Blog article scheduled.
|
|
2195
|
+
Time: ${data.scheduledAt}
|
|
2196
|
+
Timezone: ${data.timezone}`);
|
|
2197
|
+
} });
|
|
2198
|
+
});
|
|
2199
|
+
const blogScheduleCancel = blogSchedule.command("cancel").description("Cancel one future Blog schedule with blog:publish; never unpublishes a live article");
|
|
2200
|
+
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) => {
|
|
2201
|
+
const global = program.opts();
|
|
2202
|
+
commandExitCode = await execute({ command: "blog schedule cancel preview", global, runtime, async action(context, client) {
|
|
2203
|
+
const data = await client.blog.articles.previewScheduleCancellation(local.project, articleId, { requestId: context.requestId });
|
|
2204
|
+
writeSuccess(context, data, JSON.stringify(data, null, 2));
|
|
2205
|
+
} });
|
|
2206
|
+
});
|
|
2207
|
+
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) => {
|
|
2208
|
+
const global = program.opts();
|
|
2209
|
+
commandExitCode = await execute({ command: "blog schedule cancel execute", global, runtime, async action(context, client) {
|
|
2210
|
+
requireBlogExecutionConsent({ yes: local.yes, global, runtime });
|
|
2211
|
+
const data = await client.blog.articles.executeScheduleCancellation(local.project, articleId, { confirmationToken: local.confirmationToken, idempotencyKey: local.idempotencyKey }, { requestId: context.requestId });
|
|
2212
|
+
writeSuccess(context, data, `Future Blog schedule canceled.
|
|
2213
|
+
Article: ${data.articleId}
|
|
2214
|
+
A live article was not unpublished.`);
|
|
2215
|
+
} });
|
|
2216
|
+
});
|
|
2116
2217
|
blog.command("job").argument("<job-id>").requiredOption("--project <project-id>", "exact Rolino project ID").action(async (jobId, local) => {
|
|
2117
2218
|
const global = program.opts();
|
|
2118
2219
|
commandExitCode = await execute({ command: "blog job", global, runtime, async action(context, client) {
|