* feat(cron): add computed status field to --json output
`openclaw cron list --json` and `openclaw cron show <id> --json` now
include a top-level `status` field on each job object, computed from
enabled + state.runningAtMs + state.lastRunStatus.
Values: "disabled" | "running" | "ok" | "error" | "skipped" | "idle"
This matches the human-readable status column already shown by
`cron list` and `cron show` (without --json), making it easier for
external tooling (dashboards, ops gateways) to determine job state
without re-implementing the derivation logic.
The raw state object is preserved unchanged for backward compatibility.
* fix: preserve lastStatus fallback + add changelog entry
Address ClawSweeper review findings:
- P2: Fall back to deprecated state.lastStatus when lastRunStatus is
absent, matching the existing formatStatus behavior for legacy jobs.
- P3: Add CHANGELOG.md entry under Unreleased for this user-facing
CLI feature.
* fix: address lint errors - add braces and avoid spread-in-map
---------
Co-authored-by: Rodin <rodin@forgedthought.ai>
Co-authored-by: claw <claw@weiker.me>
Summary:
- This PR adds optional `agentId` filtering to `cron.list`, auto-fills it for agent tool calls, exposes `openclaw cron list --agent`, updates generated protocol clients, docs, changelog, tests, and prompt fixtures.
- Reproducibility: yes. The motivating behavior is source-reproducible on current main because cron tool, CLI, ... e list paths do not accept or apply `agentId`; the PR diff adds that path with focused regression coverage.
Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: chore: regenerate protocol schema after adding agentId to CronListParams
- Included post-review commit in the final squash: feat(cron): add agentId filtering to cron list
Validation:
- ClawSweeper review passed for head 35b692bc97.
- Required merge gates passed before the squash merge.
Prepared head SHA: 35b692bc97
Review: https://github.com/openclaw/openclaw/pull/77602#issuecomment-4375631700
Co-authored-by: zhanggttry <zhanggttry@163.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
* fix(cron): warn when --agent is not specified on cron add
Warn users when creating a cron job without specifying the --agent flag,
so they know the job will run with the default agent (main).
Fixes#42196
* fix(cron): warn when cron add omits --agent
* fix(cron): name default agent in warning
---------
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Several `openclaw <parent>` commands (channels, plugins, approvals, devices,
cron, mcp) were exiting with code 1 when invoked bare, while printing the
same help-style content that `<parent> --help` produces (which exits 0).
This broke `&&` chains and surfaced a misleading
`ELIFECYCLE Command failed with exit code 1.` line under pnpm.
Add a small `applyParentDefaultHelpAction(cmd)` helper in
`src/cli/program/parent-default-help.ts` that attaches a default action
which prints the parent's own help and sets `process.exitCode = 0`. The
helper is a no-op when the parent already has its own action (e.g.
`agents` defaulting to `agents list`), so existing intentional defaults
are preserved.
Apply it to the six core parents listed in #73077.
Add toolsAllow field to cron agent-turn payloads, enabling users to
restrict which tool schemas are sent to the model for a given cron job.
When --tools is set:
- Only listed tools are included in the provider request
- promptMode is forced to 'minimal' (strips skills catalog, reply tags,
heartbeat, messaging, docs, memory, model aliases, silent replies)
- Dramatically reduces input tokens for small local models (~16K to ~800)
CLI surface:
- openclaw cron add --tools exec,read,write
- openclaw cron edit <id> --tools exec
- openclaw cron edit <id> --clear-tools (remove allow-list)
Closes#58435
Co-authored-by: andyk-ms <andyk-ms@users.noreply.github.com>
Previously, `--at` with an offset-less ISO datetime (e.g. `2026-03-23T23:00:00`)
was always interpreted as UTC, even when `--tz` was provided. This caused one-shot
jobs to fire at the wrong time.
Changes:
- `parseAt()` now accepts an optional `tz` parameter
- When `--tz` is provided with `--at`, offset-less datetimes are interpreted in
that IANA timezone using Intl.DateTimeFormat
- Datetimes with explicit offsets (e.g. `+01:00`, `Z`) are unaffected
- Removed the guard in cron-edit that blocked `--tz` with `--at`
- Updated `--at` help text to mention `--tz` support
- Added 2 tests verifying timezone resolution and offset preservation
feat(cron): support persistent session targets for cron jobs (#9765)
Add support for `sessionTarget: "current"` and `session:<id>` so cron jobs can
bind to the creating session or a persistent named session instead of only
`main` or ephemeral `isolated` sessions.
Also:
- preserve custom session targets across reloads and restarts
- update gateway validation and normalization for the new target forms
- add cron coverage for current/custom session targets and fallback behavior
- fix merged CI regressions in Discord and diffs tests
- add a changelog entry for the new cron session behavior
Co-authored-by: kkhomej33-netizen <kkhomej33-netizen@users.noreply.github.com>
Co-authored-by: ImLukeF <92253590+ImLukeF@users.noreply.github.com>
* feat(cron): add failure destination support with webhook mode and bestEffort handling
Extends PR #24789 failure alerts with features from PR #29145:
- Add webhook delivery mode for failure alerts (mode: 'webhook')
- Add accountId support for multi-account channel configurations
- Add bestEffort handling to skip alerts when job has bestEffort=true
- Add separate failureDestination config (global + per-job in delivery)
- Add duplicate prevention (prevents sending to same as primary delivery)
- Add CLI flags: --failure-alert-mode, --failure-alert-account-id
- Add UI fields for new options in web cron editor
* fix(cron): merge failureAlert mode/accountId and preserve failureDestination on updates
- Fix mergeCronFailureAlert to merge mode and accountId fields
- Fix mergeCronDelivery to preserve failureDestination on updates
- Fix isSameDeliveryTarget to use 'announce' as default instead of 'none'
to properly detect duplicates when delivery.mode is undefined
* fix(cron): validate webhook mode requires URL in resolveFailureDestination
When mode is 'webhook' but no 'to' URL is provided, return null
instead of creating an invalid plan that silently fails later.
* fix(cron): fail closed on webhook mode without URL and make failureDestination fields clearable
- sendCronFailureAlert: fail closed when mode is webhook but URL is missing
- mergeCronDelivery: use per-key presence checks so callers can clear
nested failureDestination fields via cron.update
Note: protocol:check shows missing internalEvents in Swift models - this is
a pre-existing issue unrelated to these changes (upstream sync needed).
* fix(cron): use separate schema for failureDestination and fix type cast
- Create CronFailureDestinationSchema excluding after/cooldownMs fields
- Fix type cast in sendFailureNotificationAnnounce to use CronMessageChannel
* fix(cron): merge global failureDestination with partial job overrides
When job has partial failureDestination config, fall back to global
config for unset fields instead of treating it as a full override.
* fix(cron): avoid forcing announce mode and clear inherited to on mode change
- UI: only include mode in patch if explicitly set to non-default
- delivery.ts: clear inherited 'to' when job overrides mode, since URL
semantics differ between announce and webhook modes
* fix(cron): preserve explicit to on mode override and always include mode in UI patches
- delivery.ts: preserve job-level explicit 'to' when overriding mode
- UI: always include mode in failureAlert patch so users can switch between announce/webhook
* fix(cron): allow clearing accountId and treat undefined global mode as announce
- UI: always include accountId in patch so users can clear it
- delivery.ts: treat undefined global mode as announce when comparing for clearing inherited 'to'
* Cron: harden failure destination routing and add regression coverage
* Cron: resolve failure destination review feedback
* Cron: drop unrelated timeout assertions from conflict resolution
* Cron: format cron CLI regression test
* Cron: align gateway cron test mock types
---------
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(cron): use longer default timeout for cron run --expect-final
* test(cron-cli): stabilize cron run timeout assertions with explicit run exits
---------
Co-authored-by: Kelly Baker <kelly@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* feat(cron): add --account flag for multi-account delivery routing
Add support for explicit delivery account routing in cron jobs across CLI, normalization, delivery planning, and isolated delivery target resolution.
Highlights:
- Add --account <id> to cron add and cron edit
- Add optional delivery.accountId to cron types and delivery plan
- Normalize and trim delivery.accountId in cron create/update normalization
- Prefer explicit accountId over session lastAccountId and bindings fallback
- Thread accountId through isolated cron run delivery resolution
- Preserve cron edit --best-effort-deliver/--no-best-effort-deliver behavior by keeping implicit announce mode
- Expand tests for account passthrough/merge/precedence and CLI account flows
* cron: resolve rebase duplicate accountId fields
---------
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Expose the existing CronJob.sessionKey field through the CLI so users
can target cron jobs at specific named sessions without needing an
external shell script + system crontab workaround.
The backend already fully supports sessionKey on cron jobs - this
change wires it to the CLI surface with --session-key on cron add,
and --session-key / --clear-session-key on cron edit.
Closes#27158
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>