14 July 2026¶
Brand assets & theme-aware tooling. Official brand assets plus theme-aware log viewer, dashboard landing and new project: commands.
2 changes:
- Official brand assets: docs logo, scaffolded favicons
- Theme-aware log viewer, dashboard landing &
project:commands
Official brand assets: docs logo, scaffolded favicons¶
The framework now ships its logo and a complete favicon set from a single source of truth
under brand/, consumed by both the documentation site and the project scaffolder.
Added¶
brand/— canonical brand assets. A new top-level directory is the single source of truth for framework artwork:brand/logos/(wordmark lockups, light/dark variants),brand/favicons/(the full generated favicon + PWA-icon set withmanifest.jsonandbrowserconfig.xml), andbrand/favicon-source/(regeneration masters). Seebrand/README.mdfor the naming convention.- Documentation site branding. The MkDocs site now carries the Pramnos logo and favicon
(
theme.logo/theme.favicon). The assets are synced frombrand/intodocs/assets/automatically before every build — by thedockerdocsscript locally and by the GitHub Pages workflow in CI — so there is only ever one copy to maintain. The generateddocs/assets/logo.png/favicon.pngare git-ignored. - Scaffolded favicons.
php pramnos initnow scaffolds a complete favicon set into every new project viaInit::scaffoldFavicons(). Layout:favicon.ico,manifest.jsonandbrowserconfig.xmlat the web root; all sized app icons underwww/assets/favicons/. The manifest is stamped with the app name and the manifest/tile icon paths are rewritten from the generator's root-relative form to the subdir, so they resolve under any base path. The matching<link>/<meta>tags are injected into the theme header for all three UI systems (plain-css, bootstrap, tailwind). - Header logo placeholder. The scaffolded theme header now shows a logo image instead of
the app name as plain text.
Init::scaffoldLogo()copies both ink variants (www/assets/img/logo.pngandlogo-inverse.png) into the project, and each theme references the variant that reads on its default navbar background (light-ink/inverse on bootstrap's dark bar, dark-ink on the white plain-css / tailwind bars). The app name is preserved as the image'salttext. Replace the files to rebrand.
Theme-aware log viewer, dashboard landing & project: commands¶
The framework log viewer now renders correctly under every scaffold theme, /Logs opens on
an analytics dashboard, Chart.js is a mandatory bundled library, and a new family of
project: commands reconfigures an existing project without re-running init.
Fixed¶
- Log viewer is now theme-aware.
LogControllerno longer emits hard-coded Bootstrap markup. Every action gathers data and renders through per-theme view files underscaffolding/themes/{tailwind,bootstrap,plain-css}/views/logs/, so the log pages match the active UI theme instead of only looking right under Bootstrap. - Self-contained log-viewer chrome.
Pramnos\Html\Logs\LogViewerView(the file selector, pagination, search, export dropdown, and date-range modal around the log iframe) ships its own scoped CSS and vanilla JavaScript — no Bootstrap CSS, jQuery, or FontAwesome, and no CDN stylesheet. TheLogViewerlog-content iframe likewise drops its FontAwesome CDN link in favour of self-contained unicode glyphs, so nothing external is requested. - CSP:
Rawdocuments nonce their inline scripts. The log-viewer iframe is served as aRawdocument, which previously did not receive the automatic CSP-nonce injection thatHtmldocuments get — so its inline scripts were blocked under ascript-src 'self' 'nonce-…'policy (e.g. when switching log files).Raw::render()now injects the request nonce into inline<script>/<style>tags. - Analytics: structured JSON entries are parsed correctly.
LogManager::getLogAnalytics()did not trim the trailing newline before its JSON check, so every structured entry was misread as plain text — the level was lost (error rate read 0% even for all-error logs) and the timestamp fell back to now (wrong "last activity"). Now consistent withgetLogFileStats().
Added¶
- Dashboard is the
/Logslanding./Logsnow opens the analytics dashboard; the raw log viewer moved to/Logs/viewer. The toolbar links the full flow (Dashboard, Log Files, Statistics, Search, Filter, Export, Rotate, Archive, Clear) and appears on every log page. - Large-file guard for the dashboard.
getLogAnalytics()scans only the tail (~25 MB / 500k lines) of very large logs and flags the result as truncated, so the dashboard never hangs on a multi-GB file. The dashboard shows a notice when analysis was truncated. - Chart.js is a mandatory library. The dashboard renders charts from the locally-bundled
Chart.js v4 asset (
assets/vendor/chartjs/…, CSP-safe). Mandatory libraries are declared with"mandatory": trueinscaffolding/assets.json— the single source of truth read by the newPramnos\Application\LibraryManagerand consumed by bothinitand theproject:commands. project:reconfigure— enable framework features (recorded inapp/app.php), install libraries, and report current configuration. Interactive on a TTY; scriptable via--enable-feature=,--add-library=,--status. Delegates library work toproject:install.project:install [libraries…]— install front-end vendor libraries into an existing project (e.g. Chart.js after it became mandatory): downloads assets intowww/assets/vendor/and registers them insrc/Application.php. With no arguments it tops up the mandatory + already-registered set.project:publish-views— publish bundled view templates intosrc/Views/(renamed fromscaffold:views).project:git-webhook— generatewww/webhook.php(renamed fromcreate:webhook).cache:clear— flush the application cache (all categories, or one with--category=).- More CLI commands.
route:list(list registered routes),queue:failed/queue:retry(inspect & re-queue failed tasks),db:wipe/db:fresh(drop / drop + migrate,--force-guarded),user:create(create a user/admin),key:generate(generate/rotate the app key in.env),tinker(interactive REPL — uses PsySH when installed; added to new apps'require-dev), and generatorscreate:command,create:task,create:provider,create:policy,create:test. - Feature → libraries linkage.
FeatureRegistryfeature definitions accept alibrarieskey; enabling a feature throughproject:reconfigureinstalls the libraries it declares. - Scheduled-task definitions.
initnow scaffoldsapp/schedule.phpas the official place to declare scheduled tasks (via theSchedulerAPI);schedule:run/schedule:listload it through the newScheduler::loadDefinitions(). Tasks are code-defined (not stored in a database) and run by a once-a-minuteschedule:runcron. - Scheduled-task logging.
schedule:runnow records each task's outcome (ran + duration, skipped-overlap, or failed + error) to theschedulelog channel, so there's a durable record even though cron discards the command's stdout.ScheduledTask::run()returns a bool (ran vs skipped) to drive it.
Changed¶
- Console command taxonomy tidied. Project-reconfiguration commands are grouped under
project:;migratelogs→logs:convert. Only genuine entry-point commands (init,serve) remain top-level.
Documentation¶
- The Console Commands Guide documents the full command
taxonomy and the
project:commands.