v0.20.0
Enable clippy::match_same_arms and merge the two duplicate-body arms it flagged in cli::parse (issue #719): the bare None arm into the Background arm, and the redundant explicit -h/--help/help arm that the trailing wildcard already covered.
Added
-
Routine flags. A routine's agent runs unattended inside tmux with no
channel back to a human — until now. It (or a human, via MCP/HTTP) can
raise a flag against a routine: a free-texttype(e.g."bug","gap",
"edge_case","question") and free-textdescription, stored as
general(committed) orlocal(gitignored) under the routine's
flags/folder. New MCP toolscreate_flag,list_flags,resolve_flag
and matching/api/v1/routines/{id}/flagsREST endpoints. Open flags are
injected into the routine'sprompt.mdon the next run so the agent sees
what it flagged before, and the UI shows a flag-count badge with a
read-only flags page to review and resolve them. -
Structured JSON logging. Set
MOADIM_LOG_FORMAT=jsonto switchdaemon.log
(and foreground stdout) fromenv_logger's human-readable format to one JSON
object per line (ts,level,target,msg), so alaunchd/systemd-run
daemon can ship its log into an aggregator (Loki, ELK, Vector, CloudWatch)
without regex-scraping free-form text. Opt-in — the variable unset keeps the
current text format byte-for-byte, andRUST_LOGlevel filtering is unchanged
in both formats. (#416)
Changed
- Hardened the dashboard's Content-Security-Policy. Every response's CSP
previously carried onlyframe-ancestors 'none'(#406's anti-clickjacking
fix), leavingscript-src/style-src/default-srcunset and an injected
inline<script>or<base>tag entirely unblocked — a real gap given the
dashboard drives an unauthenticated loopback API with destructive controls
(create/trigger/delete routines,POST /shutdown). The CSP now sets
default-src 'self'and explicitscript-src,style-src,font-src,
img-src,connect-src,base-uri 'none',form-action 'none', and
object-src 'none'directives verified against the bundled Yew/WASM SPA and
Swagger UI, while keepingframe-ancestors 'none'. (#551)
Fixed
-
Default routines with empty
machineslist now self-repair. Default routines
seeded before machine-awareness was introduced could be left permanently dormant
(emptymachineslist, so no machine ever matched them). The daemon now detects
an empty machines list during the startup reconcile pass and seeds the current
machine, restoring the routine to an active state without any manual intervention.
(#723) -
The OpenAPI spec (
GET /api/v1'sinfo.version, the Swagger UI, and the
committedapis/openapi.json) no longer advertises a frozen0.1.0. The
hardcodedversionliteral was dropped from the#[openapi(info(...))]
attribute so utoipa derives it fromCARGO_PKG_VERSION, keeping the spec
version in lockstep with the crate.
Tests
- Added a
cli_testsregression guard (status_and_stop_json_share_a_common_key_set)
asserting that every object keystop --jsonemits also appears in
status --json, so the shared{running,pid,address}base contract between
the two--jsonshapes can't silently drift apart as fields are added to
one side but not the other.status --jsonmay carry additional
server-sourced fields (uptime_secs,version) thatstop --jsonomits;
seestatus_and_stop_json_share_the_same_shapefor the value-level guard on
the shared subset.