Skip to content

feat(cron): add computed status field to --json output#78701

Merged
vincentkoc merged 3 commits intoopenclaw:mainfrom
aweiker:feat/cron-json-status
May 7, 2026
Merged

feat(cron): add computed status field to --json output#78701
vincentkoc merged 3 commits intoopenclaw:mainfrom
aweiker:feat/cron-json-status

Conversation

@aweiker
Copy link
Copy Markdown
Contributor

@aweiker aweiker commented May 7, 2026

Summary

openclaw cron list --json and openclaw cron show <id> --json now include a top-level status field on each job object.

Problem

The human-readable cron list output shows a computed "Status" column (disabled/running/ok/error/idle), but --json output only includes the raw state object. External tooling (dashboards, ops gateways, scripts) must re-implement the status derivation logic:

if (!job.enabled) return "disabled";
if (state.runningAtMs) return "running";
return state.lastRunStatus ?? state.lastStatus ?? "idle";

Solution

Added enrichCronJsonWithStatus() in shared.ts that injects a computed status field into the JSON output for both cron list --json and cron show <id> --json.

Values: "disabled" | "running" | "ok" | "error" | "skipped" | "idle"

The status derivation preserves the deprecated lastStatus fallback for legacy jobs that may not have lastRunStatus set, matching the existing formatStatus behavior.

The raw state object is preserved unchanged for backward compatibility.

Changes

  • src/cli/cron-cli/shared.ts — new enrichCronJsonWithStatus() and computeStatus() helpers
  • src/cli/cron-cli/register.cron-add.ts — wrap cron list --json output
  • src/cli/cron-cli/register.cron-simple.ts — wrap cron show --json output
  • CHANGELOG.md — added entry under Unreleased

Real Behavior Proof

  • Behavior or issue addressed: cron list --json and cron show <id> --json were missing the computed status field that the human-readable table output shows. External tools had to re-implement status derivation logic.
  • Real environment tested: Local OpenClaw checkout at commit 17863c53 on branch feat/cron-json-status, built and run with node openclaw.mjs against a live gateway with active cron jobs.
  • Exact steps or command run after this patch:
cd /tmp/openclaw-source
git checkout feat/cron-json-status
node openclaw.mjs cron list --json | jq '.jobs[:3] | map({name, status})'
node openclaw.mjs cron show watch-openclaw-pr-78701 --json | jq '{name, status}'
  • Evidence after fix:

Terminal output from node openclaw.mjs cron list --json:

[
  {
    "name": "watch-openclaw-pr-78701",
    "status": "running"
  },
  {
    "name": "slack-ask-rodin",
    "status": "ok"
  },
  {
    "name": "gargoyle-dev-loop",
    "status": "ok"
  }
]

Terminal output from node openclaw.mjs cron show watch-openclaw-pr-78701 --json:

{
  "name": "watch-openclaw-pr-78701",
  "status": "running"
}
  • Observed result after fix: The status field is present on all job objects in both list and show JSON outputs. Values match the human-readable Status column: "running" for active jobs (derived from state.runningAtMs), "ok" for completed jobs, "disabled" for disabled jobs.
  • What was not tested: Edge case of a job with only the deprecated lastStatus field and no lastRunStatus. The fallback path is covered by code inspection but no legacy job was available in the test environment.

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 7, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 7, 2026

Codex review: needs maintainer review before merge.

Summary
The PR adds a computed top-level status field to cron list/show JSON output and records the user-facing CLI change in the changelog.

Reproducibility: yes. Source inspection on current main shows cron list --json and cron show --json print raw list/job objects, while printCronList and printCronShow compute a separate human status.

Real behavior proof
Sufficient (terminal): The PR body includes copied terminal output from a live gateway showing status present in both cron list --json and cron show <id> --json after the patch.

Next step before merge
No automated repair lane is needed because there are no blocking review findings; this is a normal maintainer-review merge decision.

Security
Cleared: Cleared: the diff only reshapes CLI cron JSON output and changelog text, with no dependency, workflow, secret, install, or package execution changes.

Review details

Best possible solution:

Land the additive CLI JSON enrichment after maintainer review, keeping raw state unchanged and adding focused coverage only if maintainers want stronger regression protection.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main shows cron list --json and cron show --json print raw list/job objects, while printCronList and printCronShow compute a separate human status.

Is this the best way to solve the issue?

Yes. Enriching only the CLI JSON output boundary is a narrow additive solution that preserves the existing raw state object and avoids changing the Gateway RPC contract.

What I checked:

  • Current main JSON paths: cron list --json prints the raw cron.list response and cron show --json prints the raw loaded job, so current main does not add a top-level computed status field. (src/cli/cron-cli/register.cron-add.ts:59, b680360fde68)
  • Human status derivation: The human list/show formatters compute status separately from enabled, state.runningAtMs, and persisted run status fields, which is the behavior this PR exposes to JSON callers. (src/cli/cron-cli/shared.ts:231, b680360fde68)
  • Cron state compatibility: Cron state defines preferred lastRunStatus and deprecated lastStatus, and current runtime writes both on completion, so the PR's fallback keeps compatibility with current and legacy jobs. (src/cron/types.ts:178, b680360fde68)
  • PR diff scope: The head diff only adds JSON enrichment for cron list/show, a shared helper, and a changelog entry; it does not touch dependencies, workflows, install scripts, packaging, or secret handling. (src/cli/cron-cli/shared.ts:29, 86c6907551e0)
  • Real behavior proof: The PR body includes terminal output from a live gateway showing status values returned by both cron list --json and cron show <id> --json after the patch. (86c6907551e0)
  • Feature history routing: Blame for the current cron CLI JSON paths and human status formatter points to the same cron CLI implementation commit by Vincent Koc; recent cron commits in this area also route through that author. (src/cli/cron-cli/shared.ts:231, 14336e332555)

Likely related people:

  • vincentkoc: Current-main blame for the cron CLI JSON print paths, status formatter, cron state fields, and completion status writes points to Vincent Koc, with recent cron history in the same area also under that author. (role: introduced behavior and recent cron maintainer; confidence: medium; commits: 14336e332555, 44ec3e411109, a622aee45a29; files: src/cli/cron-cli/shared.ts, src/cli/cron-cli/register.cron-add.ts, src/cli/cron-cli/register.cron-simple.ts)

Remaining risk / open question:

  • No focused regression test currently covers the new JSON status field; maintainers may want one before merge.

Codex review notes: model gpt-5.5, reasoning high; reviewed against b680360fde68.

@aweiker
Copy link
Copy Markdown
Contributor Author

aweiker commented May 7, 2026

Addressed the review feedback:

  1. Lint fixes (commit 17863c53): Added braces to single-statement if blocks and replaced spread-in-.map() with Object.assign to satisfy oxlint.

  2. Real behavior proof: Updated the PR body with actual CLI output captured from a local build of this branch (node openclaw.mjs cron list --json and cron show <id> --json). The status field is confirmed present on all job objects.

@clawsweeper re-review

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 7, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
forgedthought and others added 3 commits May 6, 2026 21:19
`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.
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.
@aweiker aweiker force-pushed the feat/cron-json-status branch from 3e6a6eb to 86c6907 Compare May 7, 2026 04:19
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@vincentkoc vincentkoc self-assigned this May 7, 2026
@vincentkoc vincentkoc merged commit 8974a78 into openclaw:main May 7, 2026
102 checks passed
steipete pushed a commit that referenced this pull request May 7, 2026
* 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>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* 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>
rogerdigital pushed a commit to rogerdigital/openclaw that referenced this pull request May 9, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants