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.
Bug
On Linux/WSL,
lisa heartbeat install --every <N>prints a cron line viasecondsToCronApproxinsrc/heartbeat/install.ts. For several common values it produces either invalid cron (which fails silently when added to crontab) or uneven schedules:--every 5h0 */5 * * *--every 7h0 */7 * * *--every 90m*/90 * * * *--every 25h0 */25 * * *Reproduce (no install required):
macOS users are unaffected (launchd uses
StartIntervalin seconds).Fix
Snap to safe cron divisors:
1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 301, 2, 3, 4, 6, 8, 12; 24h becomes0 0 * * *(daily)0 0 */N * */ weeklyWhen 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
src/heartbeat/install.tssecondsToCronApprox(+ small change at the one Linux call site to surface the snap warning)lisa heartbeat installUX gains a one-line "(snapped to …)" notice when applicable.PR incoming.