Skip to content

Releases: Mfrostbutter/ageniusdesk-ce

v0.5.0 — Silent-failure detection + workflow promotion

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 14 Aug 00:44
c4673bf

n8n tells you the run succeeded. The run did not succeed.

That is the failure class this release is built around: a node errored under Continue-On-Fail, or quietly stopped producing data, and the execution still lands in the green pile with nothing to alert on. v0.5 catches those, catches the node that never ran at all, and adds a way to move a workflow between environments without guessing at credentials.

Silent failures surfaced across the Overview

Added

  • Silent-failure detection (green but broken runs). On OpenTelemetry ingest, AgeniusDesk reads output shape rather than status. It unions the three places n8n records a demoted error and classifies each node's output volume against that node's own recent history, so a steady producer that had input and dropped to zero (or far below its normal band) is flagged, while cold-start nodes and habitually-empty pollers stay quiet. Drop cascades are suppressed to the origin node, so one root cause is one alert instead of fifteen. Detected failures land in the same errors pipeline as everything else under their own Silent failure class: a dedicated Overview card, tiles on Insights and the Observe strip, a SILENT badge with jump-to-trace in the Errors feed, and a distinct amber block on the Execution Timeline. Tunable per instance with AGD_HEALTH_*.

    Requires the instance to be exporting OpenTelemetry to AgeniusDesk. Instances AgeniusDesk provisions are auto-wired; for one you connected by URL, enable n8n's native OTel export.

  • Dead-man's switch: the node that should have run but didn't. The output-shape detectors cannot see a node that produced no span, because there is nothing to read. On a completed green run this diffs the workflow's declared nodes against the spans that actually landed, and flags one that had input available but never ran and that historically runs in nearly every execution. Graph-aware, so a node legitimately skipped downstream of an empty node is treated as a cascade victim rather than a dead node.

  • Workflow promotion across instances (dev to staging to prod). The open-source answer to n8n Enterprise environments. A preflight reports every credential each workflow binds, whether the target ships that type, and duplicate-name collisions, before anything is written. Credential auto-provision reuses a credential already mirrored onto the target or creates one from the Secrets store, running through the same SSRF, instance-scope, and URL-repoint guardrails as the manual mirror route. Ambiguity is surfaced, never guessed, and provisioning is idempotent by reuse rather than delete-and-recreate, so an already-promoted workflow never has its credential id pulled out from under it. Because n8n binds a node credential by both id and name, activation is refused when a mapped credential has no name on the target rather than importing something that fails on its first run.

Security

  • The assistant asks before it acts. It reads content you do not control (n8n error and execution payloads, RAG hits, MCP output), so a prompt injection buried in any of it could previously steer a state-changing tool call during an ordinary chat turn. Those calls no longer execute mid-turn: they return as a proposal on an approval card, operator-gated, CSRF-checked, single-use, and expiring. The gate lives in a shared dispatch path so it covers both the OpenAI-compatible and Anthropic tool loops, and the card renders on all six chat surfaces. MCP tools are classified per server from the server's own readOnlyHint annotations, and a tool that cannot be classified fails closed. AGD_ASSISTANT_AUTORUN=true restores unattended execution for a headless install.

  • Public API keys gain expiry, scoping, and a rate limit. A key can now carry an expiry, be scoped to an IP, instance, or workflow, and is subject to a per-key token bucket. Every field is optional and absent means unrestricted, so keys you already issued keep working.

  • One self-signed n8n no longer disables certificate checking for the whole fleet. TLS verification moved from a global switch to a per-instance tls_verify.

  • The unauthenticated ingest paths are rate limited and bounded. Per-IP limits on the webhook and OTLP receivers, prune-before-insert so the span row cap is a real ceiling under sustained load, and span-attribute size bounds.

Plus a defense-in-depth batch: a central audit sink, promoted secrets no longer copied into os.environ, same-origin CORS default, constant-time MCP ping compare, deploy-time Docker HostConfig re-check, and separated password/TOTP lockout counters.

Fixed

  • Traces are attributed to the instance that produced them. n8n's OTel export carries no attribute naming the AgeniusDesk instance it was configured under, only an opaque hash, and the old matcher never resolved it, so every trace fell back to whichever instance you were viewing. In a multi-instance fleet that mis-attributed executions and error rates, and broke cost and health enrichment outright: enrichment fetched run-data from the active instance, which does not hold a foreign instance's execution, so it read empty and wrote $0 cost / no health. Resolution is now two-tier, a deterministic resource attribute on provisioned instances plus a one-time learn step for external ones, and an exporter that cannot yet be placed parks in a stable bucket instead of landing on the active instance.

  • Cost and silent-failure enrichment fetch run-data from the trace's owning instance, so a non-active instance's spend and health are no longer silently empty.

  • Aggregate Spend counts every run, not just traces you opened. Cost enrichment ran lazily on trace open while health enrichment already ran on ingest, so a full day of runs could show $0.0000 Spend while any individual waterfall showed real dollars. Pricing now happens as runs land.

  • Community module views no longer load with dead JavaScript. The sandboxed iframe made a view's own module.js a cross-origin fetch, and the static route sent no Access-Control-Allow-Origin, so the browser blocked the script silently and the view came up with no behavior and no error.

  • Assistant provider keys resolve however you named your secrets, rather than only the convention name.

Upgrade notes

The assistant now gates state-changing tool calls by default (AGD_ASSISTANT_AUTORUN=true restores the old behavior). AGD_TLS_VERIFY is superseded by the per-instance tls_verify field. New per-IP and per-key rate limits apply to the ingest and public API paths; defaults sit well above normal single-fleet traffic.

Full detail in the CHANGELOG. Silent-failure detection is written up in docs/architecture/silent-failure-detection.md; promotion has a new guide at docs/guide/promote.md.

v0.4.4 — Scheduled backups + offsite storage

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 06 Jul 15:14

Scheduled backups land, and they picked up an offsite bonus on the way.

Scheduled backups with offsite destination

Added

  • Scheduled workflow backups. A dependency-free interval scheduler snapshots every connected instance's workflows to disk on a schedule, pruning to a configurable retention. Configure it on the Export / Backup view (interval, snapshots to keep, active-only) or over operator-gated /api/backups endpoints. The schedule is read live from config.json, so toggling it takes effect with no restart, and it fans out across the whole fleet regardless of which instance is active. A failing instance is isolated: the others still snapshot. Off by default.

  • Offsite backup destination (S3-compatible). Scheduled backups can also push each snapshot to S3-compatible object storage (AWS S3, Cloudflare R2, Backblaze B2, Wasabi, self-hosted MinIO) so a backup survives loss of the host or its Docker volume. Opt-in via a new s3 dependency extra, with a Test connection probe. The local snapshot is always written first and an upload failure is recorded per instance without losing it. Credentials come only from the encrypted secret store as $VAR refs. Options: mirror the keep-N retention offsite, and Fernet-encrypt each object before upload. LAN MinIO allowed; the cloud metadata address is refused. Push-only in v1.

    Cloudflare R2's free plan (10 GB, no egress fees) holds years of fleet backups at no cost. Backblaze B2's 10 GB free tier is a comparable zero-cost offsite target.

Changed

  • Local models show token usage instead of "price unknown" in the cost waterfall. Ollama and other always-local AI nodes are classified by n8n.node.type and render token counts with a plain "local" tag rather than a meaningless dollar figure. An operator price override still wins if one is set.

Full detail in the CHANGELOG. Backups guide: docs/guide/import-export.md.

v0.4.3 — Python Code node support for deployed n8n

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 05 Jul 17:59

Added

  • Python Code nodes work out of the box in deployed n8n. The built-in n8n template now deploys as a two-container bundle: n8n running task runners in external mode plus an n8nio/runners sidecar that ships the JavaScript and Python runners. The stock n8nio/n8n image has no Python 3, so Python Code nodes previously failed; moving execution into the sidecar fixes that and also isolates JS execution. The Python standard library is open by default (import json, datetime, re, hashlib, …). A new n8n version field tags both images together so their versions always match. Verified end to end.
  • ContainerSpec.init: bundle members can declare a one-shot init container to seed a config file into a fresh volume.

Changed

  • Existing template-deployed n8n instances become a two-container bundle on their next redeploy or recreate. Workflows, credentials, and the data volume are preserved (the encryption key is reused). No action required.

Full changelog: https://github.com/Mfrostbutter/ageniusdesk-ce/blob/main/CHANGELOG.md

0.4.2 — security release

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 02 Jul 21:27

Security release: upgrade recommended.

Fixes four high-severity findings from the 2026-07-01 full security review (all reachable by the read-only viewer role or by an operator escalating to host root), plus the medium/low batch.

Security

  • Agent Fleet in-process code execution is now admin-only (/api/agent-fleetrequire_role("admin")).
  • MCP server management SSRF closed (/api/mcp operator-gated; every fetch through assert_safe_probe_url).
  • Docker community-template JSON injection closed (substitution only on parsed string leaves).
  • DOM XSS in the markdown renderers closed (escape-before-transform; DOMPurify on Agent Fleet).
  • Medium/Low batch resolved (inspect redaction, host-scoped secret binding, credential-mirror SSRF guard, constant-time API-key compare, TOTP replay window, encrypted template_state, and more).

Added

  • Name and port your services in the setup wizard, with live port-conflict warnings (new GET /api/containers/ports-in-use).
  • Show/hide toggle on password fields (owner setup, sign in, reset).
  • Configurable error-reporting window on the Overview (24h / 7d / 30d / 90d / All, default 30d).

Full detail in CHANGELOG.md.

AgeniusDesk CE v0.4.1

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 30 Jun 10:14

Patch release: n8n-only by default.

The Agent Fleet view and Code Lab's Agent Builder mode now appear only when the optional agent extra (AGD_EXTRAS="...,langgraph") is installed, so a default install reads as a pure n8n control plane. AGD_AGENTS_ENABLED overrides the auto-detect: false hides the agent surface even with the extra present, true forces it on. The gate is UI-only (nav + Code Lab mode); it changes no dependencies, and GET /api/status now carries agents_enabled for the frontend.

This makes the v0.4.0 "n8n-first" positioning true of a tagged release. The v0.4.0 agent layer it sits on (LangGraph + PydanticAI fleet, live graph, run waterfall, human-in-the-loop, n8n-mcp + skills) is unchanged.

Full notes: CHANGELOG

AgeniusDesk CE v0.4.0

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 29 Jun 01:15

Added

  • Agent Fleet — a managed fleet of LangGraph + PydanticAI agents (built-in). A new core module + sidebar view that operates agents the way AgeniusDesk operates n8n: a catalog (built-ins: ops-triage ReAct, fix-proposer human-in-the-loop, health-reporter parallel fan-out), run with a live graph and a normalized run waterfall streamed over the WebSocket, approve/resume for human-in-the-loop, and LangSmith tracing with per-call token/cost. Both LangGraph and PydanticAI agents run (PydanticAI via its own adapter); the waterfall renders the same for either, so monitoring is framework-agnostic, and LangGraph additionally shows the node graph. The LangGraph/PydanticAI stack is an opt-in dependency extra so the default image stays lean: build with --build-arg AGD_EXTRAS="assistant,langgraph" (or pip install '.[langgraph]'); without it the module loads but a run reports the missing extra. See docs/specs/2026-06-28-agent-fleet-langgraph-spec.md.
  • Delete agents from the fleet. Each operator-authored (vault) agent card has a Delete button that removes its agents/<id>/ folder after a confirm; the catalog refreshes with no restart. Built-in example agents are protected (no button, rejected server-side) and deletion is blocked during a live run. Cards now also show a framework chip (LangGraph / PydanticAI) and a "built-in" tag.
  • Build your own agents in Code Lab. Code Lab gains an Agent Builder mode (LangGraph | PydanticAI toggle, ReAct / human-in-the-loop / parallel fan-out / blank starters, Python, and agent-aware AI assist in the sidebar). Register to Agent Fleet saves the agent into your vault under agents/<id>/ (a pure graph.py factory + an agent.json manifest, with a tools picker, model, and human-in-the-loop toggle); the fleet discovers it live with no restart and runs it alongside the built-ins. Agents are vault files you own, so you can edit, export, or delete them. The catalog merges built-ins + your vault agents; vault discovery reads only the manifests, so it stays boot-safe without the langgraph extra.
  • Built-in n8n-mcp (node intelligence), auto-installed. When Docker is available, AgeniusDesk now starts the n8n-mcp server in its own container on first boot and registers it as an MCP server automatically, so Code Lab and the assistant get real n8n node knowledge, search, and workflow validation out of the box. It runs in docs-only mode by default (no n8n credentials needed); a one-click Upgrade wires it to the active instance for workflow create/update/manage tools. Surfaced as an n8n Intelligence card in Settings → MCP Servers (status, Enable, Wire-to-active-instance, Remove). Best-effort and non-fatal: where Docker isn't reachable it's a one-click Enable instead (POST /api/mcp/n8n-mcp/enable), and a post-start probe gates registration so a dead endpoint is never registered. The dashboard reaches the container over a published host port via the host gateway (the same path the n8n proxy uses). Opt out with AGD_N8N_MCP_AUTO=false; tune with AGD_N8N_MCP_PORT / AGD_N8N_MCP_URL / AGD_N8N_MCP_IMAGE.
  • n8n skill library in the Harness. The harness now ships a curated library of focused n8n skills under skills/, seeded into your vault on first run. Each skill is a SKILL.md entry point plus reference docs covering one area (workflow patterns, node configuration, expressions, JavaScript/Python Code nodes, error handling, validation, AI agents, binary/data, sub-workflows, the n8n-mcp tools, multi-instance, and self-hosting), with a router note (skills/README.md) the in-app assistant reads first to load the right guidance on demand. Pair it with the n8n-mcp MCP server and Code Lab to build workflows correctly the first time. Seeded once and never overwritten, so your edits stick; opt out with AGD_SEED_SKILLS=false. Vendored from czlonkowski/n8n-skills (MIT), with the license and notices kept alongside the files. The seed AGENTS.md now points agents at the library, and the default Code Lab instructions route to it (and to the n8n-mcp tools) out of the box: consult the matching skill via the workspace tools, then validate with n8n-mcp before returning a workflow.

Fixed

  • "CSRF check failed" on mutations after running two dashboards on localhost. Cookies are not isolated by port, so a second AgeniusDesk on another localhost port (or its login screen) clears the shared, readable agd_csrf cookie for the whole domain. The httponly session survives, so the dashboard stays logged in but every mutation (e.g. switching n8n instances) 403s. The double-submit token is now self-healing: a valid session with a missing agd_csrf cookie gets it re-minted on the next GET /api/auth/status or /api/auth/me (the token is a pure double-submit value, not bound to the session, so re-issuing is safe), and the API client retries a CSRF check failed mutation once after re-fetching /status, so it recovers with no reload. Tip for local multi-instance dev: use 127.0.0.1 for one and localhost for the other to keep their cookie jars separate.
  • Workflow import no longer 400s on a full n8n export. n8n's public create API is strict (additionalProperties: false), so importing a complete export failed with request/body must NOT have additional properties whenever it carried a field the importer's denylist missed (e.g. isArchived on newer n8n). The importer now builds the create payload from an allowlist (name, nodes, connections, settings), and filters the nested settings object to n8n's allowed keys too (the same strict rule applies there, e.g. timeSavedPerExecution is rejected), so any extra or future export field is dropped and the import succeeds.
  • Deploying a container on a taken host port now warns clearly. Standing up n8n (or any container) on a port already in use (e.g. an n8n already on 5678) failed with a cryptic Docker bind error. The deploy now pre-checks the requested host port against running containers and fails fast naming the conflicting container, and translates the bind error so a host-process collision is reported plainly instead. The Quick Start also documents changing the dashboard's own port when 3000 is taken.
  • Harness seed docs stay current on existing installs. The root README.md and AGENTS.md are seeded only on first run, so improvements (the new skills/ library, the n8n-mcp pointer) never reached vaults created earlier. They are now refreshed to the current seed on boot only when still pristine — an unedited README (content matches a known prior seed) or an unedited constitution (AGENTS.md still at version 1 with a known prior body). Any operator edit — via the editor (version bumped) or directly in Obsidian (body changed) — is detected by hash and never overwritten.
  • The dashboard can no longer destroy or stop its own container. Container management can act on any container via the mounted Docker socket, which meant the dashboard's own container could be destroyed/stopped/recreated from inside the app — taking AgeniusDesk down. It now detects the self-container and refuses destroy, stop, restart, pause, and recreate on it (403, "manage it from Docker Desktop / the host"); the container list flags it (is_self) and the UI shows a "this dashboard" marker instead of destructive controls. Harmless actions (logs, inspect, start) and all other containers are unaffected.

v0.3.0

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 28 Jun 11:55

Added

  • More AI providers for the assistant and workflow creation. Beyond OpenRouter / OpenAI / Anthropic / Ollama, the assistant now natively supports Perplexity, Groq, DeepSeek, Mistral, xAI (Grok), and Together AI, plus a Custom (OpenAI-compatible) provider: set a base URL in Models and point it at any OpenAI-compatible endpoint (Azure OpenAI, LiteLLM, vLLM, LocalAI, Fireworks, ...). They route through the shared OpenAI-compatible chat path with live model listing where the provider exposes a /models endpoint; Perplexity is offered tools-free since it rejects an unknown tools field. Each area (Code Lab / Error Triage / Assistant) still picks its own provider and model, and keys resolve from the Secrets store by convention ($PERPLEXITY_KEY, $GROQ_KEY, $DEEPSEEK_KEY, $MISTRAL_KEY, $XAI_KEY, $TOGETHER_KEY, $CUSTOM_LLM_KEY).

  • VPS deployment guide. A step-by-step walkthrough for hosting AgeniusDesk as a public web app on your own domain (DigitalOcean, Hostinger, or any Ubuntu VPS): provision, point DNS, run in Docker bound to localhost, and front it with Caddy for automatic HTTPS, plus a public-deployment hardening checklist. Ships docker-compose.prod.example.yml (Caddy reverse-proxy overlay) and Caddyfile.example so the all-Docker path is copy-paste. See docs/DEPLOY.md.

  • Community-module frontend isolation (sandboxed iframe). A community module's frontend view no longer runs in the app page. It loads in an <iframe sandbox="allow-scripts ..."> without allow-same-origin, so the module's code runs in an opaque origin and cannot read or change the host DOM, window, cookies, or storage: a buggy or hostile module can break itself but not the AgeniusDesk UI. The module reaches the host only through a postMessage bridge that reimplements window.AgeniusDesk (fetch, notify, navigate, openInHarness); the host verifies the message source and restricts fetch to same-origin /api/ paths (adding auth and CSRF host-side). The host also pushes the active theme's CSS variables into the frame and auto-resizes it to content height. Module code that already uses AgeniusDesk.* keeps working unchanged.

  • Community-module backend isolation (out-of-process, opt-in). A community module's backend can now run OUTSIDE the app process, selected in Settings > Modules (or the AGD_MODULE_ISOLATION env var, which overrides the setting). Two tiers:

    • Subprocess runs each module in a sandboxed child process: host backend imports are blocked, the env is scrubbed to an allowlist, and the host reaches it through a reverse proxy with a per-spawn secret.
    • Container runs each module in its own hardened Docker container (read-only rootfs, all Linux capabilities dropped, no-new-privileges, no Docker socket, pid/memory/cpu limits; modules that declare no network join an internal network with zero internet). This is the real OS boundary.

    Either way, privileged actions go through a loopback capability bridge, never direct host access: vault read/write scoped to the module's declared paths (checked against the symlink-resolved location), and a tool-free assistant.complete that runs the LLM host-side so the provider key never reaches the module. The default stays in-process, so existing installs are unchanged. The reference YouTube Research module is dual-mode: the same code runs in-process or isolated.

  • Fleet Health view. A dedicated view aggregating workflow health across every connected n8n instance: per-instance active/total workflows, error rate over recent executions, and the unhealthy workflows, plus a combined roll-up. Live parallel fan-out; a degraded or unreachable instance is shown, not fatal. The "one client becomes ten" pane.

  • Auto-install the error handler on connect. Adding an n8n instance now best-effort installs + activates the Global Error Handler workflow into it (idempotent), so its errors flow to AgeniusDesk from the moment it's connected. It posts to a container-reachable dashboard URL (AGD_PUBLIC_HOST, else a configured host alias). n8n's public API cannot set the instance-wide Error Workflow, so the connect result surfaces that one remaining manual step.

Fixed

  • Stored XSS in the shared error item (pre-release). The error renderer shared across Overview, Errors, and Fleet Health escaped an error's workflow_id / execution_id too weakly for the onclick / href contexts it writes them into. Since those fields arrive on the login-exempt error webhook, a crafted value could break out of the attribute and run script in the operator's dashboard. The component now escapes the attribute/JS delimiters (matching the source renderer) and percent-encodes ids in URLs; a node-driven regression test renders a hostile error and asserts no breakout.
  • Role floor on error operations. Error-store endpoints that reach into n8n (purge executions, install/activate the error handler) or clear stored errors now require the operator role, matching every other n8n-mutating route; reads and the machine webhook stay open.
  • Error handler vs. webhook token. The auto-installed Global Error Handler now sends the x-agd-webhook-token header (from $env.AGD_WEBHOOK_TOKEN), so error delivery keeps working when the dashboard requires a webhook token instead of silently dropping every error.

Next

  • Container tier hardening: drop the module worker to a non-root uid, and a per-host egress proxy that enforces the manifest's declared network.hosts (today a network-declaring module reaches any host).

v0.2.0

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 27 Jun 15:37

AgeniusDesk CE v0.2.0 adds full execution observability, the community-module install pipeline with its first module, and the authentication/onboarding layer.

Highlights

  • OpenTelemetry observability: embedded OTLP/HTTP receiver (point n8n's native exporter at AgeniusDesk, no external collector required), an Observe trace waterfall, a metrics strip (executions, error rate, p50/p95, throughput), and LLM cost folded into the trace layer (per-trace and per-call spend).
  • Community-module pipeline: install third-party modules from a GitHub repo through a two-phase inspect/scan/consent flow, with monorepo discovery, a per-install audit trail, and one-click restart.
  • YouTube Research module (the first community module): paste a link and get a structured breakdown auto-filed into your notes vault under research/<topic>/. Distributed from ageniusdesk-community-modules.
  • Authentication and accounts: owner login, optional TOTP two-factor, password reset, role-based access control, and CSRF protection.
  • Onboarding: a derived-state Setup Journey and per-view coachmarks.

See the CHANGELOG for the full list.

A note on community-module security

Community modules currently run with full access: a module's backend runs in-process (full data and credential access) and its frontend runs inside the app page. The inspect/scan/consent flow is a heuristic static review and informed consent, not a sandbox. Real isolation (a frontend iframe sandbox plus an out-of-process backend) is the headline of v0.3. Install community modules only from sources you trust.