Skip to content

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 21 Jun 16:11
f02fa1a

Added

  • Multi-machine targeting. Routines and cron jobs now carry a machines list,
    so one shared ~/.config/moadim config repo can drive different routines/jobs on
    different machines (e.g. a laptop, a work box, a server). Each daemon resolves its
    own machine identity — MOADIM_MACHINE env, else the name in the gitignored
    ~/.config/moadim/machine.local.toml, else the system hostname — and its crontab
    sync schedules only the entries naming that machine. A new moadim machine
    command (show / set <name> / list) inspects and sets the identity. The
    machines field is settable via REST, the MCP create_*/update_* tools, and
    the --machines '["work","server"]' CLI flag.
    Note: an empty machines list runs nowhere — an entry is dormant until
    assigned, so routines/jobs created before this change stop scheduling until you
    assign them (the daemon logs each unassigned entry once at sync time). The
    built-in default routine self-assigns to the machine that first seeds it.
  • moadim status --json now folds the running server's GET /health details into
    its object as uptime_secs and version, so a single call answers liveness
    and age/version instead of forcing a second curl /health. Both fields are
    null when no server answers or its /health body cannot be parsed; exit codes
    and the human-readable status output are unchanged (#284).

Changed

  • Enabled the clippy::map_unwrap_or lint and fixed the violations, replacing
    map(...).unwrap_or(...) / map(...).unwrap_or_else(...) chains with the more
    direct map_or / map_or_else. No behavior change. (#524)
  • Enabled the clippy::semicolon_if_nothing_returned lint and fixed the existing
    violations so statements that return () end with a trailing semicolon. No
    behavior change.
  • Enabled the clippy::manual_let_else lint and rewrote the match guards
    whose only non-binding arm diverged (return/continue) as
    let ... else { ... }, keeping the happy path unindented. No behavior change.

Fixed

  • 6-field cron schedules (sec min hour dom month dow, accepted by croner)
    are now projected to a valid 5-field OS crontab line instead of being written
    verbatim. Previously only 7-field expressions had their leading seconds
    stripped, so a valid 6-field schedule reached the crontab unchanged — where
    vixie-cron/cronie either rejects the line (silently dropping every managed
    job) or misreads seconds as minutes (shifting the schedule). normalize_schedule
    and to_os_schedule now handle the 6-field form the same way as 7-field.
  • The iCal feed (GET /routines.ics) no longer silently stops short of its
    advertised 30-day horizon for high-frequency routines. The per-routine
    MAX_EVENTS_PER_ROUTINE = 100 cap still bounds feed size, but when a routine
    fires more often than the cap allows within the horizon, a trailing
    truncation-marker VEVENT (UID …-truncated@moadim) is now appended at the
    first omitted fire time, so calendar subscribers can see the projection was
    capped and where it stops instead of the routine appearing to just end after a
    few days (#251).
  • Added a MOADIM_TMUX_BIN test seam to the cleanup sweep's tmux side-effects so tests never probe or kill sessions on the real tmux server; in test builds it falls back to a non-existent path. Mirrors the MOADIM_CRONTAB_BIN guard. (#215)
  • Routine iCal feed events are now TRANSP:TRANSPARENT instead of the default
    OPAQUE, so subscribing to the .ics feed no longer marks the operator BUSY at
    every scheduled fire time. A fire is a momentary trigger, not reserved time. (#461)
  • Routine update now rejects a ttl_secs / max_runtime_secs that exceeds the
    cron-derived ceiling for the effective schedule (the new schedule if supplied,
    otherwise the routine's current one). The check runs before any mutation, so a
    rejected update leaves the in-memory store untouched. (#468)
  • launchctl_bin() no longer falls back to the real launchctl in test builds.
    A #[cfg(test)] structural guard resolves the default to a nonexistent path
    (/nonexistent/moadim-test-launchctl-guard) so a macOS test that forgets to
    wire up the MOADIM_LAUNCHCTL_BIN shim cannot mutate the developer's live
    launchd session; the eventual spawn fails harmlessly. Mirrors the crontab_bin()
    guard from #211 (#213).
  • The OpenAPI servers URL is now host-relative (/api/v1) instead of a
    hardcoded http://127.0.0.1:5784/api/v1. Swagger UI's "Try it out" now targets
    the origin the docs were served from, so it follows a custom MOADIM_BIND_ADDR
    port or a reverse proxy instead of failing against an address the daemon may not
    be bound to. (#385)