mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-18 13:31:40 +00:00
* feat(cron): add headless code-mode driver and trigger-script evaluator Part A of cron event triggers: runCodeModeScriptHeadless runs a script to completion (exec/settle/resume, no snapshots, no session), plus the cron-facing evaluator with per-job tool catalog cache, semaphore, 16KB state cap, and closed failure taxonomy. * fix(cron): correct trigger-script bootstrap flags and cache narrowing * feat(cron): add event triggers (polled condition-watcher scripts) Part B: trigger field on cron jobs gated by cron.triggers.enabled; timer evaluates the script each due tick, quiet ticks leave no run history, fired runs append the script message to the payload; once semantics, min-interval floor, SQLite columns, RPC/CLI/agent-tool surfaces, and docs. * fix(cron): propagate triggerEval through startup catch-up outcomes * fix(cron): honor cron staggering on quiet trigger ticks; fix trigger test types * fix(cron): reject with Error reason in trigger-script abort test * fix(cron): regenerate protocol/docs/snapshot artifacts and break madge cycle for trigger types CI fixes for #101195: trigger evaluator result types move to the cron types leaf (madge cycle), cron tool schema inventory gains trigger, Swift protocol bindings + docs map + Linux prompt snapshots regenerated. * fix(cron): drop underscore-dangle names in trigger code sync assert * fix(cron): adopt registerHeadlessToolSearchCatalog after tool-search symbol localization Upstream #101831 made registerToolSearchCatalog module-private; fold the headless ref-only catalog registration into one public seam.
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
// Client-side trigger script loading for cron create/edit commands.
|
|
import fs from "node:fs/promises";
|
|
|
|
const MAX_CRON_TRIGGER_SCRIPT_BYTES = 65_536;
|
|
|
|
async function readStdin(stream: NodeJS.ReadableStream): Promise<string> {
|
|
const chunks: Buffer[] = [];
|
|
let total = 0;
|
|
for await (const chunk of stream) {
|
|
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
total += buffer.byteLength;
|
|
if (total > MAX_CRON_TRIGGER_SCRIPT_BYTES) {
|
|
throw new Error("Trigger script exceeds 65536 bytes");
|
|
}
|
|
chunks.push(buffer);
|
|
}
|
|
return Buffer.concat(chunks, total).toString("utf8");
|
|
}
|
|
|
|
/** Reads a trigger script locally before sending the cron RPC. */
|
|
export async function readCronTriggerScript(
|
|
source: string,
|
|
deps?: {
|
|
readFile?: (path: string) => Promise<string>;
|
|
stdin?: NodeJS.ReadableStream;
|
|
},
|
|
): Promise<string> {
|
|
const raw =
|
|
source === "-"
|
|
? await readStdin(deps?.stdin ?? process.stdin)
|
|
: await (deps?.readFile ?? ((path) => fs.readFile(path, "utf8")))(source);
|
|
if (Buffer.byteLength(raw, "utf8") > MAX_CRON_TRIGGER_SCRIPT_BYTES) {
|
|
throw new Error("Trigger script exceeds 65536 bytes");
|
|
}
|
|
const script = raw.trim();
|
|
if (!script) {
|
|
throw new Error("Trigger script must not be empty");
|
|
}
|
|
return script;
|
|
}
|