Version history of dash-mui-scheduler, rendered from CHANGELOG.md.

Changelog

Version history of dash-mui-scheduler. The timeline on this page is rendered from CHANGELOG.md, reproduced below.


All notable changes to dash-mui-scheduler — the Plotly Dash wrapper for the MUI X Scheduler (EventCalendar, EventCalendarPremium, EventTimeline) and its Radial chart components (RadialLineChart, RadialBarChart) — are documented here. The format is based on Keep a Changelog.

The petri-dish evolution game this component grew up alongside now lives in its

own project (2plot.xyz); its 0.4.x–0.5.x history moved with it.

[Unreleased]

Documentation site and repository plumbing only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0.

Added

running, and where this site's traffic record lives.** Two questions that could previously only be answered by asking the people who deployed it: which release of the AI-readability package a running site actually resolved, and whether its record of visits and reads is on storage that survives a deploy or on a disk that is wiped every time. Both are now readable from the outside, and the storage answer is measured rather than taken from the deployment's own description of itself.

page and listed in the sidebar under Legal. The privacy page describes what this site actually records — it is written from the code that does the recording, and a test fails the build if the two ever disagree. Both pages are served identically to people and to AI assistants: a site cannot have two versions of its own privacy policy.

them to anyone.** Two changes, both about the same thing. The address a visitor arrives with is used to tell one reader from another and is then discarded — what is kept is a scrambled, keyed fingerprint that cannot be turned back into an address. And the third-party lookup service this site used to ask "where is this address?" is gone entirely, not switched off: location now comes only from what the site's own CDN already reports, which is a country, and a city where the network operator has enabled it. Visitor and session counts are unaffected, including for days recorded before the change.

Fixed

of counting it as a read.** Pages this site deliberately keeps out of the AI-readable corpus — the two owner-only pages — are refused when a crawler asks for them, and that refusal is the only evidence the exclusion works. It now appears as its own labelled row rather than being added to the served totals or dropped from the table.

which AI crawler read which document was capped at twenty thousand rows, the same cap as the visit table — but a single crawler can pull thousands of documents in minutes, so a busy day silently deleted rows recording exactly the event the table exists to record, and the deletion looked like the crawler never having come. Read rows are now kept for the full retention window and nothing else. Visit numbers are unchanged.

spelling.** If the hub restricted one of this site's pages using a different capitalisation than the site expected, the site did not recognise it and kept the page's machine-readable copy open. No page is restricted today, so nothing was exposed; the check is now spelling-insensitive.

Every vendor's category — training crawler, search engine, traditional bot — was blank on the board and in the daily summary this site reports, because the documentation engine only started attaching it in a newer release than this site pins. The category now comes from that engine's own registry when it is not supplied, so it is right today rather than after the next upgrade.

mouse hover, so the one place this site lists its sibling sites could not be reached by anyone navigating with a keyboard — focus it, press Enter, nothing happened. Hovering still works exactly as before.

from the surrounding prose by colour alone, which is invisible to a reader with low colour vision and to anyone reading in high-contrast mode. Links in the navigation and footer are unchanged.

controls were 34 pixels square, below the 44-pixel minimum recommended for touch. Desktop spacing is untouched.

served with no cache instruction at all, so every visitor re-fetched them on every page load and the CDN in front of the site stored nothing. They now last an hour, with a day of grace while a new copy is fetched in the background. Pages themselves are deliberately not cached.

lightweight "are you alive?" request — the default for most monitoring services, and the one this site's own deploy check uses — was answered with "method not allowed" on the health endpoint rather than a status. Full requests always worked, which is why nobody noticed.

site can be served describe their responses differently, and the stricter one silently discarded any field it had not been told about in advance — so the new version field existed everywhere except on the lane this site actually runs. It now keeps whatever the health check reports, including fields added later.

[2026-09-01] — the read table drops internal traffic, and props a machine can read

Documentation site and repository plumbing only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0. Shipped as 2cfc003 and live on the same day.

Fixed

as if they were AI crawlers.** The hourly health check, the post-deploy test battery and continuous integration all identify themselves as internal machinery, and visitor counts have always ignored them — but the newer record of which documents get read did not, so the busiest "reader" of these docs was this site checking on itself.

engines, not just in a browser.** The prop tables on each component page were drawn by JavaScript after the page loaded, so anything that reads the page as text — an AI assistant asking what EventCalendar accepts, a search crawler indexing the docs — saw the prose and not one of the 33 props. All three server-rendered versions of every page now carry the full table.

It checked the not-found page and nothing else, so the two owner-only pages were never tested on the live site — they were correctly hidden, but by luck rather than by check.

stray "v" in front of a date, entries whose headings use a long dash are dated again, and bold text wrapped around code renders as bold instead of showing its asterisks.

Added

reference last actually changed, rather than being left to guess.

instead of looking like any other page until you click one.

Timezones" now reads simply "Localization" in the sidebar while keeping its full name everywhere else.

[2026-08-30] — a sidebar you can find things in, and a record of who reads the docs

Documentation site and repository plumbing only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0. Shipped as 4e8c00c and deployed the same day.

Added

Changelog · Scheduler · Radial Charts · API · Resources, in that order, and the order comes from each documentation page's own front matter rather than a list kept somewhere else — a new page appears where it says it belongs.

to AI readers.

installed dash_mui_scheduler package itself, so it cannot fall behind the components actually shipped — EventCalendar, EventCalendarPremium, EventTimeline, RadialLineChart and RadialBarChart, with each prop's type, default and description.

2plot sites — one place, from the network's own registry.

Every time the machine-readable corpus is served — /llms.txt, a page's own llms.txt, the sitemap — the site keeps a row saying who asked, what they got, how big it was, and whether the request came from an address the vendor publishes. A new operator page at /admin/traffic shows it back: vendor by day, vendor by document type, and the paths each one pulled, next to the visitor numbers for the same day.

breakdown**, sent only on days that actually had machine reads. Nothing that was already reported changed shape.

Changed

the dash-improve-my-llms vendor registry — the same registry that decides what robots.txt says — instead of a hand-kept list of user-agent strings. What the site SAYS about a crawler and what it COUNTS can no longer disagree.

true ones.** Human visits DROP and bot visits RISE, because clients that send no user agent at all, and library clients like httpx or Go-http-client, were being counted as people. Anthropic's ClaudeBot was also filed as a search crawler when it is a training crawler. Expect a visible step in the day-over-day chart; it is the number becoming correct.

Components and the MUI X Scheduler this library wraps. The Dash community forum link is gone, and the 2plot links moved to the new Other Apps menu and footer so nothing is listed twice.

Render builds a release branch that continuous integration writes after it goes green, so pushing to main proposes a deploy rather than performing one. A red build can no longer reach the live site while its own checks are still running.

Fixed

pointed at the author's profile page, so the one link a reader clicks to find the source took them somewhere they had to search from. The profile link now lives in the footer, where it belongs.

block inside a bulleted list or a quote widened the whole document instead of scrolling inside its own box.

first tapped the button, and that could leave it empty.

leaving an empty column down the right-hand side.

They were shown to everyone and then correctly refused; now they are shown only to the owner.

"copy" button and the icon links all carry proper labels. (One remaining audit finding sits in the MUI calendar itself and is upstream.)

The page served to crawlers and social-media scrapers was given a preview image by the site on top of the one the documentation engine already emitted, leaving the scraper to pick one. Each tag is now added only if it is missing.

checking the browser's page.** It was being classified as a crawler and therefore inspecting the wrong document — reporting a missing app manifest on a site that has one. The fix was adopted across the other 2plot sites, which all had it.

[2026-08-27] — the same icons for everyone, and a battery that waits

Documentation site and repository plumbing only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0. Shipped as 0e00207 and deployed the same day.

Fixed

offered are the same set again.** Google was shown six sizes up to 512×512; a browser loading the same page was shown three, topping out at 180×180. Both heads now declare the identical set, so the icon a tab, a bookmark or a search result picks comes from one answer rather than two.

Its network calls now verify certificates through the same bundle the rest of the tooling uses; without it, every request failed in the TLS handshake and the report said the site was down when it was up. (Continuous integration never saw this — only laptops.)

Changed

now waits for the host to answer before asserting anything about it, and retries a dropped connection or a momentary 5xx instead of recording a check that never ran. One unreachable host is reported once, not forty times.

crawler-versus-browser identity comparison — the check that caught the icon defect above — runs against the app in the test suite, so this class of drift is caught locally instead of by a red deployment.

[2026-08-26] — the kit every site shares, and one Python everywhere

Documentation site and repository plumbing only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0. Shipped as b3ecf3f and deployed the same day.

Added

who clones it — or points an AI coding assistant at it — inherits the same project guide, the same three workflow skills, and the same sandbox settings the rest of the network runs, instead of nothing. A companion DIVERGENCES.md records, with reasons, the five places this repo deliberately differs from the template it was forked from, so a future sync cannot quietly "fix" a decision that was made on purpose.

health probe at all, so the platform running it could only see "the process is alive", never "the site is answering" — and CI now fails the build if that probe is missing or broken, rather than trusting an external check that proves something else.

below, an operator can tell from the outside whether the running image is the one this repo declares — a mismatch that was previously invisible.

Changed

on its own; the test matrix, the release lane and the deploy verifier were left behind on 3.12, so the version this site was tested and released on was not the version it shipped. They now all say 3.14, the supported window follows the image rather than sitting still, and a test holds every place the interpreter is written down to a single answer.

minimums encode compatibility and security facts that a bump erases while adding nothing — the installer already picks the newest release above them. Security advisories are unaffected; they arrive on their own channel.

typed.** The docs pages already worked this way; the home document was the one served surface that would have published whatever number someone last wrote by hand.

Fixed

have.** It promised one to every visitor who hit a gated page — the network's credibility spent at its highest-intent moment.

When the deploy step is skipped, the verification job now stands down instead of certifying whichever release happened to still be live.

holds it there: the variant it replaced fails only on operators' own machines, where it reads as a broken sign-in wiring rather than a TLS problem.

[2026-08-23] — one headline per page, and a health probe that answers

Documentation site only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0. Shipped as d0f4068 and deployed the same evening.

Fixed

no-JavaScript block in the page shell opened with its own <h1>, and crawlers — which run no JavaScript — parse that block, so alongside each page's real heading they read a second, site-wide one competing with it. The block now starts a level down, and a new sweep checks every published page for exactly one headline rather than trusting the shell.

quotes the docs' own syntax.** Inlining an example file is triggered by a directive; a directive shown inside a fenced code block — teaching the syntax rather than using it — used to be inlined anyway, which closed the fence early and turned the rest of the sample into headings. Fenced examples are now left as the documentation they are. No page in this repo had one yet; the fix lands before the first one does.

satellite answered and — where the guardrail package supports it — whether geo-blocking is configured, how many countries are on the list (a count, never the list itself), and which country the request resolved to. Two things had to change for those answers to be true rather than merely present: the probe used to be computed once when the app started, so anything configured afterwards would have been reported wrong forever, and the country a request resolves to has to be read from that request — which the FastAPI build this site runs in production cannot do unless the route hands its own headers along.

Changed

the fix for the duplicate headline the prerendered copy used to inject, a deduplicated /llms.txt link in the page footer, hardening against a page that merely mentions the prerender marker silently losing its prerender, and the llms.txt v2 discovery relations — rel="alternate" / rel="describedby" plus matching Link headers — that give an agent a machine-readable route from any page to that page's prose.

repo now runs a weekly check, and it proposes version upgrades only for the Dash/Plotly stack, grouped into a single review. The other floors in requirements.txt record minimum-compatibility facts (a CVE, a rendering guarantee) that a mechanical raise would erase, so they are left alone. Security updates arrive through their own channel and are unaffected.

dependency floor deliberately rebuilds the whole image, so the most important deploy is also the slowest one; the wait is now sized for it, and a deploy that nothing actually triggered says so loudly instead of in passing.

[2026-08-22] — the interactive sign-in gate, shipped dark

Documentation site only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0. Merged as PR #8 and deployed the same evening; the Clerk 1.0.2 section below shipped earlier the same day and this supersedes it.

Added

behind a Clerk sign-in card, and none of them is: every tier ships public, so the site reads exactly as it did. What changed is that gating became a setting rather than a project — PAGE_DEFAULT_TIER=auth closes the interactive site, setting it back opens it, and neither touches a line of code. Pages can also declare their own tier in frontmatter.

individual pages live, without a deploy. It fails closed: with the auth layer unavailable, nobody gets in rather than everybody.

documents and each page's own /<page>/llms.txt are governed by a second, independent axis — so gating the site for people never silently closes the window agents read through. A new /api/agent-key turns a signed-in browser session into a key that a copied llms.txt link carries with it, because the assistant you paste that link into has no cookie.

date its content actually last changed, taken from this repository's own history, and that date is published verbatim. The home page declares none: it is a standing index, and any single date would be a guess.

Changed

On 1.0.2 signing out never told the server: the browser cleared its own session while the server kept honouring the identity cookie it had already issued, for up to seven days. Anyone who signed out on a shared machine stayed signed in as far as this site was concerned. 1.0.5 revokes properly, fixes the sign-in return trip (you now land back on the page you started on, signed in, instead of on a stale card), and — specific to this service's FastAPI backend — makes the authentication endpoints answerable at all: before it, every one of them rejected every request.

this site's own artwork and now includes the sizes that were missing, so browsers, phone home screens and search results all resolve a real icon instead of falling back to a generic globe.

under the header, with its own search field — previously phones had no way to jump to a page by name, only a long scroll, and the menu could not be closed with the button that opened it.

needs: the SEO layer to the release that makes page text visible to non-JavaScript readers, and the component library to the release where the navigation panel renders as a panel.

Fixed

post-deploy verification ran against whichever build happened to be answering — in practice the one being replaced. It now waits for the release it just shipped and verifies that.

the optional integration needed a newer Dash than the one running, on a version that was already new enough. It was wired to the wrong entry point and could never have worked; it is now wired correctly and silent unless enabled.

were removed — four of them, including two that had already caused visible layout bugs on sister sites. They would have broken silently, or started restyling something else entirely, on any future upgrade.

[2026-08-22] — Clerk auth hook 1.0.2

Shipped to the documentation site only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0.

Changed

flip-on: the avatar menu no longer paints signed-out over a valid session (it lost a race against Dash mounting the menu), and 1.0.1's widened clerk-backend-api cap lets pip resolve cryptography>=50.0.0, clearing four published advisories (GHSA-537c-gmf6-5ccf, PYSEC-2026-3552/3553/3554) from the installed environment.

[2026-08-18] — network instrumentation deploy

Shipped to the documentation site only; the dash_mui_scheduler package is unchanged — PyPI still carries 1.0.0.

Changed

boilerplate 1.3.x trio). The ledger is now buffered, cross-process locked, pruned by a retention window, and written atomically — a busy hour no longer rewrites the whole file on every hit, and two workers can no longer silently overwrite each other's counts. The hourly rollup this site reports to 2plot.ai is computed by the same shared code every satellite runs, so the network's numbers are finally measured with one rule. The Gen-0 reporter (lib/traffic_report.py) is retired.

attaches a persistent 1 GB disk and keeps the visitor ledger on it, so a mid-day deploy stops resetting the numbers the hub charts.

state a package version as {{VERSION:<distribution>}} and the site substitutes the installed version at load — a hardcoded number that drifts from the shipped package can no longer appear on any page or llms.txt surface. (No page had one; the mechanism now guards all of them.)

Added

their frontmatter (public | auth | admin | hidden), and the two corpus documents (/llms-small.txt, /llms-full.txt) take theirs from LLMS_SMALL_TIER / LLMS_FULL_TIER. Everything is and stays public — nothing enforces yet; this records the knobs the network's 402 experiment will read.

file: what turns on when each variable is set, and what the app does without it.

Fixed

the crawler-document fixes (the page <title> carrying the site name, per-page social images reaching crawlers, /favicon.ico answered with a redirect instead of the app shell).

[1.0.0] - 2026-08-03

The component API has been stable since the first release and the docs site is now on the network standard, so this graduates the package out of 0.x. Nothing in the component itself changed — existing code keeps working untouched.

Fixed

declared.** Every component imports typing_extensions, which the package had been getting for free because current versions of Dash happen to install it. Anyone resolving to an older Dash could install this package successfully and then have it fail on import. It is now declared outright.

Added

upload from a laptop. Pushing a v* tag now runs the whole test matrix against that exact commit, builds the package, proves the built result is a working component library, publishes it, and opens a GitHub release whose notes are lifted from this file. No PyPI token is stored anywhere — PyPI verifies a short-lived identity token that GitHub mints for this repository alone, so there is no long-lived secret to leak or rotate. RELEASING.md documents the flow.

before it can upload if the tag disagrees with the version the package declares, if the tagged commit never landed on main, or if this changelog has no section for the version being cut. The packaging is checked as well: both the wheel and the source archive must carry the built component bundle — a package that installs cleanly and then renders nothing is otherwise indistinguishable from a good one — and that check reads a clean install of the built artifact rather than the source tree sitting beside it.

[0.1.1] - 2026-08-01

Shipped to the documentation site; superseded on PyPI by 1.0.0, which carries these changes.

Added

2plot.ai, 2plot.dev and the other satellite documentation sites:

secretless test suite on both the Flask and FastAPI builds, lints the code and the workflows themselves, builds the real production image, checks the shipped dependency versions inside it, boots it, and runs the same smoke battery that later checks the live site. Merging to main deploys and then verifies the live domain — waiting for sustained health before calling the deploy good.

dash-mui-scheduler — MUI X scheduling for Dash — identically in the browser tab, in search results, in shared-link previews, in the machine-readable /llms.txt index, in its app manifest and atop the README, and a test pins each surface so none of them can silently drift.

unfurl with a purpose-drawn 1200×630 card served from the network CDN (so a sleeping free-tier container never blanks a preview) instead of an upscaled favicon.

documentation's llms.txt viewer once NETWORK_BULLETIN_URL is set on the service, so network-wide news reaches this site's readers without a deploy.

batteries, this site's calls to the hub — now identifies itself and is dropped from visitor analytics before it is ever written down — however the marker is capitalised — and every outbound call this site makes carries the same marker for the far side. The site reports to the hub under its one short id, muischeduler, everywhere.

hourly health sweep and gating deploys.

documentation sites and the hub, so an agent landing here can discover the rest of the network.

radial charts now sits near the top of the Quickstart page and on the documentation home page, so a reader landing on the docs can watch it without going to GitHub first. The README header carries a clickable thumbnail linking to the same walkthrough. Both embeds use YouTube's no-cookie player, so nothing is set until you press play.

engines as what it is: an MIT-licensed Python source library with a repository, a PyPI download page, a version number read straight from the package, and the walkthrough video attached.

the whole 2plot network. Once an hour it sends a signed daily rollup — page hits split human/bot, unique visitors, sessions, median session length, top pages and visitor countries — so the network dashboard shows how the documentation is actually being read. Reporting only happens when the shared network secret is configured; without it the site behaves exactly as before and makes no outbound calls.

Changed

that pointed at the retired pip-install-python.com domain — in the README, the sidebar, the site's structured data and the cross-host directory — now points at 2plot.dev, and the README opens with the 2plot banner.

installs from PyPI at ≥ 2.3.4 instead of a vendored 2.0.0 snapshot; the gunicorn web server is floored at ≥ 23 (clearing two request-smuggling CVEs its old pin was stuck on); and the optional Clerk auth package moves to 0.9.1, the release that fixes the account chip on satellite domains.

Everything the site publishes about itself — search-engine addresses, shared-link previews, the sitemap, the machine-readable pages — now points there, and the README and the PyPI listing send readers to the docs rather than back to the repository. The old onrender.com address keeps working and forwards to the new one, so existing links and bookmarks survive the move and search engines are told where the pages went.

Fixed

favicon size, the app-install icons and the iOS home-screen icon are drawn fresh from the vector logo instead of the blurry upscale they were before.

Pointing TRAFFIC_ANALYTICS_FILE at a persistent-disk path before the disk existed crashed every worker at boot, so the deploy never went live and the old build kept serving. The tracker now creates the directory when it can, and when the path is truly unwritable it disables itself with a clear log line — the site serves either way, and a test pins both behaviours.

exist.** The page template still carried the URL it was built with (dash-mui-scheduler.onrender.com) rather than the address the docs actually live at, and it claimed that one address for all 17 pages at once — the fastest way for a site to fall out of the index entirely. Every page now declares its own correct address, kept in step as you navigate, and every link the site publishes about itself is built from a single setting.

its own copy of the title, description and social tags, which overrode the per-page ones — so a search result or shared link for, say, Recurrence showed the site blurb instead of the page's. The per-page text now wins everywhere, including for search-engine and link-preview crawlers, and shared links unfurl with the project logo and the right page's title.

proxy.** Behind Render/Cloudflare every request looked like it came from the same address, which collapsed all visitors into one and mislabelled where readers came from; the site now reads the forwarded client address and the edge country header. Visitor geography also no longer costs a lookup on the request path.

20,000 hits) so a long-running deployment doesn't slow every page view down.

[0.1.0] - 2026-07-16

First public release — the component library on PyPI (pip install dash-mui-scheduler) and its documentation site, split out of the 2plot.ai monolith.

Added

EventCalendarPremium, EventTimeline, RadialLineChart and RadialBarChart — with recurrence, drag & resize, inline editing, resources, preferences, localization/timezones, and MUI X Premium features via a licenseKey prop.

lists every application and tool in the network: 2plot.xyz (the game), 2plot.ai (the hub), 2plot.media (videography), PiratesBargain (commerce), and ai-agent.buzz (the infinite AI canvas).

(component picker, the events/lastAction data boundary, prop cheat sheets, radial chart patterns, gotchas). Ships inside the PyPI source distribution alongside the README.

Event Calendar, Playground, Events, Resources, Views, Navigation, Responsive, Drag & Resize, Editing, Preferences, Recurrence, Event Timeline, Localization & Timezones) and 3 radial chart pages, each with an LLM-friendly /llms.txt mirror, sitemap, and social cards.

the FastAPI build ships /healthz, /api/backend, /api/pages, and Swagger UI.

Clerk environment variables later flips on 2plot-network sign-in with no code change.

Changed

links, and a fuller tour (overview, quick start, data boundary, Premium licensing, recurrence and radial chart samples, selected prop reference).

in git.

Fixed

printing it) made the bundle fetch a code-split chunk the package never registered with Dash, so the request came back a 500 and the export died. The chunk is now registered and served on demand.

from the departed evolution game overwrote the "dash-mui-scheduler" brand text in the header on every page load.

MUI_X_LICENSE_KEY, but the environment only provided MUI_PRO_API_KEY — so every Premium demo (recurrence, timeline, radial charts) rendered the "Missing license key" watermark. .env now aliases the key and the Render blueprint supplies MUI_X_LICENSE_KEY directly.

2plot artwork; it now uses the dash-mui-scheduler logo, and the console is clean on every docs page.

dash-mui-scheduler.onrender.com while the service name resolves to dash-mui-scheduler-docs.onrender.com; sitemap/llms/social links would have pointed at a dead host.

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: