Download src/cli/cron-cli/register.cron-scratch.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 3.42 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cli/cron-cli/register.cron-scratch.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/cli/cron-cli/register.cron-scratch.ts
-
curl -L -o register.cron-scratch.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cli/cron-cli/register.cron-scratch.ts
3.42 kB
| import { parseStrictNonNegativeInteger } from "@openclaw/normalization-core/number-coercion"; | |
| // Cron scratch CLI: private per-job prompt context reads and compare-and-swap writes. | |
| import type { Command } from "commander"; | |
| import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js"; | |
| import { CronCliError } from "./cron-cli-error.js"; | |
| import { createCronOutputCommand } from "./output-mode.js"; | |
| import { handleCronCliError, printCronJson, requireCronJobId } from "./shared.js"; | |
| import { readCronScratchContent } from "./trigger-options.js"; | |
| type ScratchRecord = { content: string; revision: number; updatedAtMs: number }; | |
| type ScratchGetResult = { | |
| scratch: ScratchRecord | null; | |
| currentRevision: number; | |
| maxBytes: number; | |
| }; | |
| type ScratchSetResult = | |
| | { ok: true; scratch: ScratchRecord | null; currentRevision: number; maxBytes: number } | |
| | { ok: false; reason: "revision-conflict"; currentRevision: number }; | |
| function parseExpectedRevision(value: string | undefined): number | undefined { | |
| if (value === undefined) { | |
| return undefined; | |
| } | |
| const revision = parseStrictNonNegativeInteger(value); | |
| if (revision === undefined) { | |
| throw new CronCliError("--expected-revision must be a non-negative integer"); | |
| } | |
| return revision; | |
| } | |
| export function registerCronScratchCommand(cron: Command) { | |
| addGatewayClientOptions( | |
| createCronOutputCommand(cron, "scratch") | |
| .description("Read or replace an automation's private scratch") | |
| .argument("<id>", "Job id") | |
| .option("--set <text>", "Replace scratch with exact text") | |
| .option("--file <path>", "Replace scratch from a file, or - for stdin") | |
| .option("--unset", "Remove the scratch row", false) | |
| .option("--expected-revision <n>", "Require the current scratch revision") | |
| .action(async (idArg, opts) => { | |
| try { | |
| const id = requireCronJobId(idArg); | |
| const mutations = [ | |
| opts.set !== undefined, | |
| opts.file !== undefined, | |
| opts.unset === true, | |
| ].filter(Boolean).length; | |
| if (mutations > 1) { | |
| throw new CronCliError("choose only one of --set, --file, or --unset"); | |
| } | |
| const current = (await callGatewayFromCli("cron.scratch.get", opts, { | |
| id, | |
| })) as ScratchGetResult; | |
| if (mutations === 0) { | |
| if (opts.json) { | |
| printCronJson(current); | |
| } else if (current.scratch) { | |
| process.stdout.write(current.scratch.content); | |
| } | |
| return; | |
| } | |
| const explicitRevision = parseExpectedRevision(opts.expectedRevision); | |
| const expectedRevision = explicitRevision ?? current.currentRevision; | |
| const content = opts.unset | |
| ? null | |
| : opts.file !== undefined | |
| ? await readCronScratchContent(String(opts.file)) | |
| : String(opts.set ?? ""); | |
| const result = (await callGatewayFromCli("cron.scratch.set", opts, { | |
| id, | |
| content, | |
| expectedRevision, | |
| })) as ScratchSetResult; | |
| if (!result.ok) { | |
| throw new CronCliError( | |
| `cron scratch changed concurrently (current revision ${result.currentRevision})`, | |
| ); | |
| } | |
| printCronJson(result); | |
| } catch (error) { | |
| handleCronCliError(error); | |
| } | |
| }), | |
| ); | |
| } | |