v0.41.0

Latest release

3 November 2026

Installed addons move to site/addons/{creator}/{name}, and a kept page or region is shared as widely as what it read about the visitor allows, so per is gone.

Added

  • phlat addons:list lists every addon on disk, built-in, site-only and installed, with whether it is configured and the tag an installed one is pinned to.
  • phlat addons:install and addons:reset accept a full git URL as well as creator/name. The creator/name form resolves against the addons.source config key, which defaults to ssh://[email protected].
  • addons:install refuses an addon whose alias is already used by another addon, and the creators phlat and site.
  • edge in a view's cache setting ({"cache": {"ttl": 86400, "edge": true}}) lets a shared cache in front of the site hold the kept page. Signed-out visitors are sent public, max-age=0, s-maxage=N.
  • Options::chosen() says whether the visitor has chosen any declared option.
  • Cache::LEVELS lists the levels an entry is shared at: none, role and user.
  • deploy.php runs git submodule update --init --recursive after deploy:update_code, so installed addons arrive with a release.

Changed

  • An installed addon lives at site/addons/{creator}/{name}/, not addons/{creator}/{name}/ at the project root. Its id in addons.{id} config is unchanged. AddonManager resolves each id to one fixed location.
  • A kept page, {cache}, {fragment} and {component} entry is shared as widely as its render allows: everyone when it asked nothing about the visitor, each role when it asked role(), can() or isLoggedIn(), each user when it asked who they are. A signed-out visitor's user(), role() and isLoggedIn() now count as role reads.
  • Cache::setVaried() and Cache::setFor() take a $level from Cache::LEVELS in place of $per. Cache::getVaried() and Cache::getFor() take no per. App::unkeepable() is now App::cacheLevel() and returns the level, or null for a render that read the session.
  • The cache schema is bumped, so the fragment cache is emptied once on upgrade.
  • phlat cache:clear flushes the fragment cache first, so cache.flush:after fires before the files go.
  • addons:uninstall and addons:reset work when site/ sits inside a larger git repo.

Removed

  • per on {cache}, {fragment} and {component} and on a view's cache setting, and Cache::per() and PageView::per(). A leftover per throws.
  • addons/ at the project root, in .gitignore and in .gitattributes.