From d5db20c296b3c705722ad7a997b8089ddb11d334 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 13 Dec 2025 03:43:47 +0000 Subject: [PATCH] feat(cli): add cron status + warn when disabled --- docs/cron.md | 9 ++++++--- src/cli/cron-cli.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/docs/cron.md b/docs/cron.md index 3806d61bc..ee4f8bb6e 100644 --- a/docs/cron.md +++ b/docs/cron.md @@ -255,7 +255,7 @@ Add a `cron` command group (all commands should also support `--json` where sens - `--cron "" [--tz ""]` - target flags: - `--session main|isolated` - - `--wake now|next` + - `--wake now|next-heartbeat` - payload flags (choose one): - `--system-event ""` - `--message "" [--deliver] [--channel last|whatsapp|telegram] [--to ]` @@ -264,9 +264,10 @@ Add a `cron` command group (all commands should also support `--json` where sens - `clawdis cron rm ` - `clawdis cron enable ` / `clawdis cron disable ` - `clawdis cron run [--force]` (debug) +- `clawdis cron status` (scheduler enabled + next wake) Additionally: -- `clawdis wake --mode now|next --text ""` as a thin wrapper around `wake` for agents to call. +- `clawdis wake --mode now|next-heartbeat --text ""` as a thin wrapper around `wake` for agents to call. ## Examples @@ -317,7 +318,7 @@ clawdis cron add \ Enqueue a note for the main session but let the existing heartbeat cadence pick it up: ```bash -clawdis wake --mode next --text "Next heartbeat: check battery + upcoming meetings." +clawdis wake --mode next-heartbeat --text "Next heartbeat: check battery + upcoming meetings." ``` ## Logging & observability @@ -336,6 +337,8 @@ Suggested log events: - `cron: scheduler started` (jobCount, nextWakeAt) - `cron: job started` (jobId, scheduleKind, sessionTarget, wakeMode) - `cron: job finished` (status, durationMs, nextRunAtMs) +- When `cron.enabled` is false, the Gateway logs `cron: disabled` and jobs will not run automatically (the CLI warns on `cron add`/`cron edit`). +- Use `clawdis cron status` to confirm the scheduler is enabled and see the next wake time. ## Safety & security diff --git a/src/cli/cron-cli.ts b/src/cli/cron-cli.ts index adbb39b0f..189b9718b 100644 --- a/src/cli/cron-cli.ts +++ b/src/cli/cron-cli.ts @@ -1,8 +1,31 @@ import type { Command } from "commander"; import { danger } from "../globals.js"; import { defaultRuntime } from "../runtime.js"; +import type { GatewayRpcOpts } from "./gateway-rpc.js"; import { addGatewayClientOptions, callGatewayFromCli } from "./gateway-rpc.js"; +async function warnIfCronSchedulerDisabled(opts: GatewayRpcOpts) { + try { + const res = (await callGatewayFromCli("cron.status", opts, {})) as { + enabled?: boolean; + storePath?: string; + }; + if (res?.enabled === true) return; + const store = typeof res?.storePath === "string" ? res.storePath : ""; + defaultRuntime.error( + [ + "warning: cron scheduler is disabled in the Gateway; jobs are saved but will not run automatically.", + "Enable with `cron.enabled: true` in your clawdis config and restart the Gateway.", + store ? `store: ${store}` : "", + ] + .filter(Boolean) + .join("\n"), + ); + } catch { + // Ignore status failures (older gateway, offline, etc.) + } +} + function parseDurationMs(input: string): number | null { const raw = input.trim(); if (!raw) return null; @@ -70,6 +93,22 @@ export function registerCronCli(program: Command) { .command("cron") .description("Manage cron jobs (via Gateway)"); + addGatewayClientOptions( + cron + .command("status") + .description("Show cron scheduler status") + .option("--json", "Output JSON", false) + .action(async (opts) => { + try { + const res = await callGatewayFromCli("cron.status", opts, {}); + defaultRuntime.log(JSON.stringify(res, null, 2)); + } catch (err) { + defaultRuntime.error(danger(String(err))); + defaultRuntime.exit(1); + } + }), + ); + addGatewayClientOptions( cron .command("list") @@ -250,6 +289,7 @@ export function registerCronCli(program: Command) { const res = await callGatewayFromCli("cron.add", opts, params); defaultRuntime.log(JSON.stringify(res, null, 2)); + await warnIfCronSchedulerDisabled(opts); } catch (err) { defaultRuntime.error(danger(String(err))); defaultRuntime.exit(1); @@ -385,6 +425,7 @@ export function registerCronCli(program: Command) { patch, }); defaultRuntime.log(JSON.stringify(res, null, 2)); + await warnIfCronSchedulerDisabled(opts); } catch (err) { defaultRuntime.error(danger(String(err))); defaultRuntime.exit(1);