NEXO 6.5.0 — Toggle any personal automation from one CLI call

Published 2026-04-19. Plan Consolidado fase F0.2.

What changes

v6.5.0 adds three CLI verbs that close the operator-side gap left by the previous release:

All three accept --json for machine consumers. Internally they go through two new helpers in src/script_registry.py: set_personal_script_enabled(name_or_path, enabled) and get_personal_script_status(name_or_path).

How the gate works

src/scripts/nexo-cron-wrapper.sh now reads personal_scripts.enabled on every tick, before executing the wrapped command. When the script is disabled the wrapper short-circuits to exit 0 with summary='[disabled]', leaves a one-line note in the run log ([disabled] $CRON_ID skipped — re-enable with: nexo scripts enable $CRON_ID), and finalises the cron_runs row exactly the way a real run would. The LaunchAgent stays loaded — no launchctl churn — so re-enabling is a single CLI call. The daily audit can tell apart "didn't run because off" from "ran with exit 0" because the summary explicitly says [disabled].

Sticky flag across sync

Up to v6.4.0, the upsert path on personal_scripts overwrote enabled = excluded.enabled on the ON CONFLICT DO UPDATE branch — meaning the next nexo scripts sync would silently flip a disabled script back on. v6.5.0 drops that overwrite: the operator-set flag is now sticky. Initial INSERT still defaults enabled=True; the change only affects existing rows. Four new tests in tests/test_personal_scripts_enabled.py cover the round-trip, the unknown-script error envelope, the read-only status shape, and the regression that broke before the upsert fix.

Companion client

The NEXO Desktop client — a closed-source companion app distributed separately from this open-source Brain — wires the same toggle into its Settings → Automatizaciones panel via the existing nexo scripts list --json --all + nexo scripts enable|disable --json contract. Operators who would rather click than type get exactly the same gate; operators who want a terminal keep the same Brain.