Skip to content

heartbeat: secondsToCronApprox emits invalid or uneven cron lines on Linux/WSL #1

@oratis

Description

@oratis

Bug

On Linux/WSL, lisa heartbeat install --every <N> prints a cron line via secondsToCronApprox in src/heartbeat/install.ts. For several common values it produces either invalid cron (which fails silently when added to crontab) or uneven schedules:

Input Current output Problem
--every 5h 0 */5 * * * Runs at 00 05 10 15 20, then resets at midnight — gap is only 4h
--every 7h 0 */7 * * * Runs at 00 07 14 21, then resets — gap of 3h
--every 90m */90 * * * * Invalid — cron minute field is 0-59
--every 25h 0 */25 * * * Invalid — cron hour field is 0-23

Reproduce (no install required):

node -e 'function s2c(sec){if(sec>=3600&&sec%3600===0){const h=sec/3600;return h===1?"0 * * * *":"0 */"+h+" * * *"}if(sec>=60&&sec%60===0){const m=sec/60;return m===1?"* * * * *":"*/"+m+" * * * *"}return "*/"+Math.max(1,Math.round(sec/60))+" * * * *"} console.log(s2c(5400))'
# → */90 * * * *   ← invalid

macOS users are unaffected (launchd uses StartInterval in seconds).

Fix

Snap to safe cron divisors:

  • Minutes (<1h) → valid divisors of 60: 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30
  • Hours (1h ≤ N ≤ 24h) → valid divisors of 24: 1, 2, 3, 4, 6, 8, 12; 24h becomes 0 0 * * * (daily)
  • Days (>24h) → daily / 0 0 */N * * / weekly

When the requested interval doesn't match a safe divisor, snap to the nearest one and surface that to the caller so the installer can warn the user.

Scope

  • One file: src/heartbeat/install.ts
  • One pure function: secondsToCronApprox (+ small change at the one Linux call site to surface the snap warning)
  • No new deps, no public API change. The lisa heartbeat install UX gains a one-line "(snapped to …)" notice when applicable.

PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions