v0.32.0
EvoNexus v0.32.0 — Plugin System v1
A big one. Plugins are here — a full extensibility layer with 15 capabilities, a pre-install security scanner, per-capability toggles, update diff previews, and a reference plugin (pm-essentials) shipping exemplars of every surface. Alongside it: a security-hardening pass (PRD #37) and a batch of community-reported fixes across integrations, networking, and Docker.
What's New
Plugin System v1 (#41)
Plugins are git-installable bundles that contribute agents, skills, commands, rules, routines, heartbeats, widgets, MCP servers, custom UI pages, and seed data — all declared in a single plugin.yaml manifest.
Core runtime
- Pydantic-validated manifests with 15 typed capabilities
git:///https://tarball / uploaded ZIP install with SHA-256 integrity check- Semver-aware SQL migration runner with rollback (sqlparse-backed)
- Atomic directory ops with rollback on failure
- Claude Code hooks dispatcher (PreToolUse / PostToolUse / Stop / SubagentStop) with per-plugin SQLite circuit breaker
- Crash-recovery on boot for orphaned installs via
.install-state.json - Plugin-contributed rows tagged with
source_pluginacross tickets, projects, goals, missions, goal_tasks, and triggers — uninstall cleans them surgically without touching user data
REST API + dashboard UI
GET/POST/PATCH/DELETE /api/plugins(full CRUD)GET /api/plugins/marketplace(curated registry)POST /api/plugins/upload(ZIP / tar.gz, 20 MB cap, zip-slip guard)GET /api/plugins/<slug>/update/preview(diff before applying)- New
/pluginspage with marketplace grid, install wizard (source → security scan → config → confirm), plugin detail with widgets, capabilities toggles, MCP banner, and Update with diff preview - New
/mcp-serverssystem page aggregating~/.claude.jsonentries grouped by plugin / native
CLI
evo-nexus plugin init— scaffold from templateevo-nexus plugin install <source>/list/uninstall <slug>/update <slug>- Starter template under
cli/templates/plugin-skeleton/
Plugin capabilities that close v1
- Wave 1.1 — Per-capability toggles: ON/OFF per capability without uninstalling. Disable cascades to
.claude/{agents,skills,commands}/plugin-{slug}-*(rename to.disabled), routines skipped by scheduler, hooks and heartbeats skipped by dispatchers. - Wave 1.2 — Update diff preview: read-only preview with added / removed / modified capabilities per type, SQL migration SHA conflict detection, breaking-changes flag, 5-minute cache.
- Wave 2.0 — Icons + agent avatars:
agent_meta_seed.pyships metadata for 38 native agents served viaGET /api/agent-meta; plugin agents contribute custom icons with img fallback. - Wave 2.1 — Custom UI pages: plugins can contribute React pages mounted at
/plugins-ui/:slug/*, sidebar groups, and writable SQLite resources (column allowlist + jsonschema validation).window.EvoNexusSDK injected post-login. - Wave 2.2r — Plugin integrations: declare env-var-based integrations with optional HTTP health checks running as in-process heartbeats (zero Claude CLI overhead).
- Wave 2.3 — Plugin MCP servers: plugins declare MCP servers with command whitelist and shell-metachar block; 6-layer atomic write to
~/.claude.jsonwith flock, timestamped backups (retention 10), drift detection. - Wave 2.5 — Pre-install security scan: hybrid regex + LLM scanner, 13 pattern categories, 57-domain whitelist, anti-hallucination guard, 7-day cache, APPROVE / WARN / BLOCK adaptive button with admin BLOCK override.
Plugin management skills — plugin-install, plugin-list, plugin-uninstall, plugin-update, plugin-marketplace, plugin-health, plugin-security-scan expose plugin operations to every agent.
Security hardening (PRD #37)
/api/health/deepnow requires admin session — previously leaked filesystem paths, provider identity, secret-key source and error details to unauthenticated callers./api/healthis now a minimal public liveness probe (status only).- Plugin install sources restricted —
resolve_sourcerejects local filesystem paths,file://,ssh://, and non-HTTPS schemes with a clearValueError. Onlygithub:,https://tarballs, or uploaded ZIP / tar.gz are accepted. - Plugin triggers ship disabled by default — regardless of YAML value unless explicitly
"true", so a malicious plugin can't auto-fire hooks on install. - Frontend route splitting — top-level bundles are code-split; main chunk drops substantially on first load.
Community fixes
- #49 — Integration status verifies all declared env keys.
list_integrationspreviously checked a single key per entry, so Evolution API / Evolution Go / Evo CRM appeared configured with only the token or only the URL. Schema nowkeys: list[str]; configured means every declared key is non-empty. Bling fixed to use real OAuth2 vars (BLING_CLIENT_ID/BLING_CLIENT_SECRET, runmake bling-auth). Omie now requires bothOMIE_APP_KEYandOMIE_APP_SECRET. - #18 — Safer
start-services.shcleanup.pkill -f 'python.*app.py'was killing unrelated Python processes on multi-project hosts. Replaced with explicit pinned match on venv interpreter + absolute script path; TCP 8080 (orEVONEXUS_PORT) freed directly viafuser/lsof— falls back tolsof -ti tcp:$PORT | killwhenfuseris absent (BSD-ish / macOS). - #35 — Terminal detects RFC1918 + CGNAT hostnames as local. Previously only
localhost/127.0.0.1were "local"; bare-metal installs fell back to/terminalon the same origin which didn't exist. Now covers RFC1918, RFC6598 CGNAT (100.64.0.0/10, common on Brazilian VPS), link-local, IPv6 loopback. NewVITE_TERMINAL_URLexplicit override. - #45 —
docker-compose.proxy.ymlfor reverse-proxy hosts. Sibling compose file that usesexpose:instead ofports:so Coolify / Dokploy / Traefik / Caddy own external traffic while containers stay reachable by name inside the Docker network. Volumes identical tohub.ymlfor no-loss migration. - #46 — Supabase / Neon / Railway pooler docs. New
docs/knowledge-database.mdwith provider cheat-sheet (port 5432 vs 6543, Supabase IPv6-only edge case, error reference table). Inline hint added under the Knowledge connections wizard input. - #26 — History cleanup dry-run script.
scripts/clean-history.sh— safe-by-default helper that clones the remote as--mirrorand previews removal of ~283 MB of orphaned PNG avatar blobs viagit filter-repo. Verifies develop/main HEAD trees are byte-identical and all tags preserved before the maintainer force-pushes.CONTRIBUTING.mdgains the partial-clone recipe so new contributors download ~10 MB instead of ~290 MB in the interim.
Other changes
- Telegram notifications moved from skills to routines.
run_skill(notify_telegram=True)appends a one-shot send instruction at the end of the prompt — guarantees exactly one send per execution. - Merged routines listing.
/api/routinesnow merges declared routines with execution metrics, so newly installed plugin routines and unrun core routines show up with zeroed metrics. - Brain Repo sync no longer blocks HTTP requests. New
brain_repo/job_runner.pybackground executor serialises sync / milestone / bootstrap ops; endpoints enqueue and return immediately;/backupsand/brain-repopoll state and expose Cancel. EVONEXUS_DEV=1— toggles Flask auto-reloader for backend development.
Migration notes
- If you set
BLING_ACCESS_TOKENmanually, runmake bling-authto obtain the OAuth credentials — the legacy env var is no longer recognized. - Tooling scraping
/api/health/deepfor internals must now authenticate as admin.
Full Changelog: v0.31.0...v0.32.0