All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.0.2] - 2026-11-11

  • DOM-level JS tests for loader.js and panel.js wiring and postMessage origin gate (ADR 06)
  • EXPLAIN tests on Postgres, a Postgres service in CI (ADR 08)
  • allowed_origins: for proxies and tunnels that rewrite the Host header (ADR 04)
  • PhoenixDevToolbar.Report: read API over captured sessions for IEx and agents (ADR 13)
  • Shipped usage-rules.md and the phoenix-dev-toolbar-report agent skill (ADR 13)
  • Standalone panel URL: <path>/panel?path=... or the newest page, standalone mode (ADR 14)
  • Documented data-pdt-* row attributes with raw values, for browser-driving agents (ADR 14)
  • MCP endpoint at <path>/mcp, this machine only, read-only Report tools, mcp: false (ADR 15)
  • MCP clients: option: own LAN addresses count as local, IP/CIDR allowlist, :any (ADR 15)
  • MCP client setup for Claude Code, Codex, Cursor and VS Code in README and usage rules (ADR 15)
  • Panel sid check anchored with \A...\z (ADR 14)
  • Standalone panel ?path= and newest page limited to MCP's clients rule (ADR 14)
  • One "this machine" rule: actions: and Eval clients: take :local (ADR 10, ADR 12)
  • Eval default clients: widened to :local, own LAN address included (ADR 12)
  • Agent setup guide; README usage_rules config made skills-only, block rewrite warned (ADR 13)
  • MCP refusals name the peer and the option; clearer "No captured page" errors (ADR 15)

[0.0.1] - 2026-11-10

First public release. A dev-only toolbar for Phoenix LiveView apps: a summary bar and panel overlaid on the page you are working on, installed with one plug in the endpoint. Tabs: Request, Ecto (queries, N+1 detection, EXPLAIN, JSON export), LiveView (lifecycle timings, assigns, events, component tree), Process and System (any process, supervision trees, opt-in actions). Opt-in Cluster and Eval plugins. Plugin API with a guide. Off outside MIX_ENV=dev.

  • Project conventions: AGENTS.md, ADRs, roadmap, mix precommit, CI matrix (ADR 00, ADR 06)
  • PhoenixDevToolbar.enabled?/0 runtime guard (ADR 01)
  • Bounded ETS event store: caps, flood guard, TTL sweep, LiveView DOWN cleanup (ADR 03)
  • Payload truncation and key redaction helpers (ADR 03)
  • Telemetry collector: plugin fan-out, crash quarantine, $callers attribution (ADR 02)
  • LiveView session tracking: dead render link, reconnect, live navigation, nested (ADR 02)
  • Registry based live notifications for panel subscribers (ADR 03)
  • Built-in Request and Ecto collectors, default plugins (ADR 02)
  • PhoenixDevToolbar.Plug: page tracking, loader injection, asset serving (ADR 04)
  • Live panel served by the plug, no router changes: summary, Ecto and Request tabs (ADR 01, ADR 04)
  • Loader (shadow DOM iframe, collapse state), panel JS and CSS, esbuild bundles (ADR 04)
  • mix dev harness: SQLite demo app with N+1, events, Task.async and dead pages (ADR 06)
  • Prod compile check of a fixture host app installing the toolbar (ADR 01)
  • Panel keeps following a tab after older sessions expire; no missed or out of order events (ADR 04)
  • Bounded exception banners and plug options; panel asset URLs from the plug path (ADR 03, ADR 04)
  • Toolbar disables itself, with a warning, in releases unless explicitly enabled (ADR 01)
  • Panel UX: hide to a corner pill, HTTP/live query tags, timings, dropped badge, ARIA tabs (ADR 04)
  • CI tests the minimum stack with LiveView 1.1 (ADR 06)
  • Panel loads the host's own Phoenix and LiveView JS clients: no version skew (ADR 04)
  • LiveView collector: callback and render timings, bounded assigns diff, push_event names (ADR 02)
  • Bounded, budgeted redaction preview for assigns and LiveView params (ADR 03)
  • LiveView tab: lifecycle profiler, callbacks badge and server event log (ADR 07)
  • Assigns inspector: redacted snapshot through LiveView Debug, throttled refresh (ADR 07)
  • Component tree, polled only while the panel is open and visible (ADR 07)
  • Client event log: LiveView window events forwarded by the loader (ADR 04, ADR 07)
  • JS unit tests for the loader helpers: mix test.js, in precommit and CI (ADR 06)
  • mix dev pages: Components and Assigns (ADR 06)
  • Trimmed events badge in the summary bar; client event validation module (ADR 03, ADR 07)
  • Public plugin behaviour, use macro, plugin options and config validation (ADR 05)
  • Per plugin event caps and a per session ceiling, limits documented in the README (ADR 03)
  • max_events now caps each plugin per session, not the session (ADR 03)
  • Plugin panel shell: LiveComponent tabs, per plugin badges and trimmed notes (ADR 05)
  • LiveView tab on the public panel API; PanelLive is generic glue (ADR 05, ADR 07)
  • Plugin errors shown in their tab with Re-enable; panel side boundary for plugin code (ADR 05)
  • Plugin guide in ExDoc, Oban example plugin, harness pages for jobs and plugin errors (ADR 05, ADR 06)
  • Plugin boundary covers all of render/1; event plugin ids stamped by the collector (ADR 05)
  • Panel seen seqs bounded per session; Config checks id and name; update/2 rejected (ADR 03, ADR 05)
  • Ecto badge DOM id is pdt-badge-ecto-queries (ADR 05)
  • Summary bar: badges that do not fit are counted in a "+N" chip that opens the panel (ADR 04)
  • Callback spans: Context.span and Event.span, the LiveView callback an event ran in (ADR 02)
  • N+1 detector: Ecto badge, groups and row tags, n_plus_one: plugin option (ADR 08)
  • EXPLAIN capture: raw params of SELECTs kept in the event, bounded, never rendered (ADR 03, ADR 08)
  • EXPLAIN button in the Ecto tab: rolled back, single SELECT, page scoped; SQLite test repo (ADR 08)
  • N+1 groups merged by SQL and origin, Clear button, advice; EXPLAIN focus, names, Hide (ADR 08)
  • Process tab: vital signs, sparklines, links and monitors, nested LiveViews; in :defaults (ADR 09)
  • Process tab: GC now button, rate limited; /memory harness page (ADR 06, ADR 09)
  • Panel reload breaker: stops after 3 refused loads in 10 s, with a notice and Retry (ADR 04)
  • Panel socket at <path>/live: no host CSRF token or session needed; fixes the reload loop (ADR 04)
  • the plug's :live_socket_path option is gone (ADR 04)
  • Panel socket review fixes: decoded join check, stale on unknown panels, host socket options (ADR 04)
  • Panel: disconnected state, shorter cannot connect notice, inert tabs; Process tab wording (ADR 04, ADR 09)
  • Docs: per-run disable recipe through DEV_TOOLBAR=0 (ADR 01)
  • limits: overrides validated at boot; panel frame-ancestors and nosniff headers (ADR 03, ADR 04)
  • Public repo: renamed to phoenix_dev_toolbar, GitHub install, CI badge, SECURITY.md
  • Stricter lint: Credo opt-in checks, Dialyzer unmatched returns; shared test page helpers (ADR 06)
  • Ecto tab JSON export: short or full with EXPLAIN, download or copy (ADR 08)
  • Ecto export fix: a Copy built before the LiveView joined is dropped; request path fallback (ADR 08)
  • Toolbar reserves its page space so the page scrolls above it; draggable panel height (ADR 04)
  • Toolbar docks: bottom, top, left, right; dock picker, sideways collapsed strip (ADR 04)
  • Dock picker menu no longer clipped on side docks (ADR 04)
  • Page space opt out: reserve_space config and a dock menu toggle (ADR 04)
  • Ecto Copy never hangs: busy and crash answers, disabled during EXPLAIN (ADR 08)
  • Ecto Download checks root is one of the page's sids (ADR 08)
  • Process addressing, protected set, actions: loopback policy (ADR 10)
  • Panel.navigate/3: switch to another tab with params (ADR 10)
  • System tab, now in :defaults: any process by pid or name, crumbs, ancestors, state (ADR 11)
  • Process tab: every process is a link to the System tab (ADR 09)
  • Process actions: kill (with reason), suspend 10 s with auto resume, watch, message peek (ADR 10)
  • Redaction walks tuples, so queued messages and results are redacted too (ADR 10)
  • System tab trees: a supervisor's children, the application list with top supervisors (ADR 11)
  • System tab top: the 50 processes with the most memory, reductions or queue (ADR 11)
  • System tab message trace: one process, 100 messages or 10 s, OTP 27 sessions (ADR 11)
  • Cluster plugin (opt-in): connected nodes with round trip, processes, memory (ADR 12)
  • Eval plugin (opt-in): read queries, code with allow: :eval, loopback by default (ADR 12)
  • panel refuses host names that could be rebound; list yours in allowed_hosts (ADR 04)
  • unset enabled means on only in Mix :dev; prod under Mix is off (ADR 01)
  • panel socket requires a same-origin Origin, whatever the host check_origin (ADR 04)
  • access-control-* headers stripped from panel and export responses (ADR 04)
  • actions: defaults to false; :loopback opts in; Eval refused only on explicit false (ADR 10, ADR 12)
  • Ecto params through the budgeted preview, 2 KB cap; redact/2 node budget (ADR 02, ADR 03)
  • Response hook catches throws and exits; injection drops a preset content-length (ADR 04)
  • Collector failure path tests; hot path wording matches the code (ADR 02)
  • redact: adds to the defaults instead of replacing them (ADR 03)
  • Ecto repos default to the apps' :ecto_repos, one warning when none (ADR 02, ADR 05)
  • Integer list params shown as lists, not charlists; redact: entries validated (ADR 03)
  • Public moduledocs for the built-in plugins, ADR links, Setup and plugin groups in the docs (ADR 05)
  • Experimental markers on the plugin API; Truncate.changes/2 and snapshot/1 are internal (ADR 05)
  • Truncate.redact/2 cuts what it does not walk instead of returning it; scalar structs redacted (ADR 03)