You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Removed
Removed the cron-job feature. Moadim scheduled two kinds of things —
"cron jobs" (a schedule + a handler script) and "routines" (a schedule + an
AI-agent prompt). The project's focus is AI-agent routines, so the cron-job
half — the CronJob/CronStore model, the /api/v1/cron-jobs* REST routes,
the *_cron_job MCP tools, the moadim cron-jobs CLI subcommand, the ~/.config/moadim/jobs/ and ~/.config/moadim/handlers/ directories, and
the job-specific crontab block — has been removed. Routines are unaffected
and keep their own crontab block, REST routes, MCP tools, and CLI
subcommand. (#842)
Changed
list_routines omits routine prompts by default. The prompt is the
largest field on a routine and is rarely needed when scanning a listing, so it
bloated GET /routines responses and burned MCP context tokens on every call.
The prompt key is now absent from list entries unless the caller opts in with include_prompts=true (a new boolean on the list_routines MCP tool and the GET /routines query string). get_routine / GET /routines/{id} are
unaffected and always return the prompt; routine.toml persistence is
unchanged. (#824)
Documentation
Added CODE_OF_CONDUCT.md. The repo had a CONTRIBUTING.md and SECURITY.md but no documented standard of conduct or enforcement contact,
leaving GitHub's community-standards profile incomplete. Added a Contributor
Covenant v2.1 code of conduct with a real reporting contact, and linked it
from CONTRIBUTING.md. (#423)
The README's Bind address section now warns that the REST API and MCP
endpoint are unauthenticated, so MOADIM_BIND_ADDR should stay on a loopback
address: binding to a routable interface (a LAN IP or 0.0.0.0) exposes
unauthenticated routine create/trigger — effectively remote code execution — to
the network. Recommends an authenticating reverse proxy / firewall for remote
access instead. (#253)
Fixed
The daemon never killed hung routine tmux sessions when launched via
launchd/systemd. Those managers start moadim --interactive with a
minimal PATH (e.g. macOS launchd's /usr/bin:/bin:/usr/sbin:/sbin) that
hides a Homebrew- or npm-installed tmux. The daemon's own cleanup/watchdog
sweep shelled out to tmux directly (no login shell), so every
liveness/kill probe silently failed and read as "session already dead" —
a hung run's workbench got TTL-reaped while its real tmux session and agent
process kept running, untracked, forever. resolve_tmux_bin now also
searches common install locations (Homebrew, /usr/local/bin, ~/.local/bin) when tmux isn't on PATH, and the generated launchd
plist now sets a real PATH via EnvironmentVariables.
cargo build was broken on main. Two independent PRs (#804 and #805)
each added a unused_async = "deny" entry under [lints.clippy] in Cargo.toml, and both merged cleanly since git's line-based merge doesn't
understand TOML semantics. The resulting duplicate key made every cargo
invocation fail immediately with error: duplicate key before compiling a
single crate. Removed the duplicate entry so the workspace builds again.
docs/moadim.1's .TH header reported a stale moadim 0.16.0 even though Cargo.toml had moved on to 0.18.0 — the hand-maintained man page has no
build-time link to the crate version, so a release could silently ship a man
page reporting the previous version. Corrected the version token and added
a regression test (cli::cli_tests::man_page_version_matches_cargo_pkg_version)
that fails when the two drift again. (#556)
Locked the --json machine-readable contract with a regression test
(cli::cli_tests::status_stop_cleanup_json_share_the_same_address) asserting status --json, stop --json, and cleanup --json all surface the same address value, so the three shapes can't silently drift apart again. (#245)
Removed two dead AppError::NotFound arms in svc_update (routines/service.rs):
the function already checks the routine's existence once, up front, while
holding the store's lock continuously for the rest of the call, so the two
later re-fetches could never actually miss. The two tests written to cover
those unreachable arms were accidental duplicates of the same first-check
path; merged them into one svc_update_not_found_when_id_missing test that
covers both request shapes against the real, single NotFound path.
Added
Machine name in health output.GET /health and the MCP health tool now
report the daemon's resolved machine identity (from MOADIM_MACHINE, machine.local.toml, or hostname — same as GET /machine) in a new machine
field, so clients can tell which machine answered without a second request. (#778)
Changed
Enabled the clippy::wildcard_imports lint. It flags use some::module::*;
glob imports, which obscure where a name comes from at the call site, can
silently change behavior when the globbed module gains a new item, and
defeat "go to definition" tooling. Zero existing violations, so this only
guards against the pattern creeping in going forward. No behavior change.
Enabled the clippy::unused_async lint. It flags async fns (and async
closures/blocks) that never .await anything internally, which needlessly
propagate async-ness up the call stack and pull in a Future state machine
for work that's actually synchronous. Zero existing violations, so this only
guards against the pattern creeping in going forward. No behavior change.
(#803)
Gzip-compressed HTTP responses. The Axum router now negotiates Accept-Encoding and gzip-compresses response bodies via a tower-http CompressionLayer, cutting the ~1.1 MB SPA payload (and the OpenAPI JSON
under /docs) several-fold on every load/refresh for clients that
advertise gzip support. A no-op for clients that don't. (#399)
Bumped tower-http from 0.6.11 to 0.7.0. No source changes needed —
the only feature used (compression-gzip's CompressionLayer) is
API-compatible across the bump.
Declared rust-version = "1.88" (MSRV) in the root Cargo.toml and ui/Cargo.toml, matching the floor already required transitively by darling 0.23, so cargo install moadim on an older stable toolchain now
fails with Cargo's clean MSRV message instead of an opaque compile error. (#326)
The local pre-push hook now runs cargo clippy --workspace instead of a
bare cargo clippy. In this non-virtual workspace (the root Cargo.toml
declares both a [package] and [workspace]), the bare form only checks
the root moadim package, so the ui member crate was never type-checked
or linted by the hook.
.github/workflows/lint.yml's clippy job now runs cargo clippy --workspace --all-targets -- -D warnings too, closing the matching gap in
CI: previously the bare cargo clippy --all-targets only checked the root moadim package, so ui/Cargo.toml's [lints.clippy] all = "deny"
posture was never enforced on PRs and a dashboard lint regression could
merge to main fully green, only surfacing via the local hook (if a
contributor had it installed) or at release time.
build_app_with_shutdown cloned store and routines into app_state,
then cloned them again from the original bindings for the MCP service
closure — clippy::redundant_clone flags the second pair as dead clones
since the originals are never read afterward. Reordered to clone once
(for the MCP closure) before moving the originals into app_state,
dropping two unnecessary Arc clone+drop pairs per router build. No
behavior change.
Fixed
Fixed the ui crate, which had silently stopped compiling: three test
fixtures (command_palette_tests.rs, routines_tests.rs, schedule_heatmap_tests.rs) were missing the tags field added to Routine by #505, and cron_jobs::unassigned_count / routines::unassigned_routines_count were dead code left over from before #771 made the "Unassigned" machine facet a permanent filter option. None of
this was caught because ui was outside the pre-push clippy gate and CI's
equivalent gate had the same blind spot (now closed, see --workspace
fix above).