Alpine.js upgrade: 3.14.9 → 3.15.12
- You asked to verify safety before touching the dev system, given the panel's history with 3.15.x
- Built a real test harness (jsdom) since no browser was available in my sandbox — actually executed the real app.js against the real page structure, not just re-reading code
- Ran the identical test against both versions and diffed the results: byte-for-byte identical — zero new errors from the upgrade
- Self-hosted it afterward (was loading from unpkg.com — same CDN-dependency risk as the earlier Chart.js issue, except for the whole framework instead of one chart)
Console cleanup — three real, confirmed bugs
- CSP was silently blocking styles for months. script-src trusted unpkg.com/cdnjs.cloudflare.com, but style-src never did — meaning your Terminal (xterm) and code editor (CodeMirror) stylesheets have likely never loaded correctly. Self-hosted both (xterm + all 17 CodeMirror files: core, 12 language modes, 4 addons) rather than just patching the CSP to trust more origins.
- Tightened the CSP — removed unpkg.com from script-src entirely now that nothing external loads. One less trusted origin.
- Fixed two null-property console errors (wsInfo, selectedProvider) — the codebase already had the correct safe pattern in a few places; two spots were just missing it.
App Store — PHP row layout
- You caught the Settings button looking disconnected from PHP's other controls
- Confirmed first it was purely visual (button worked fine when clicked)
- Took three iterations to actually fix: widening the shared column broke every other row (empty gutter, since the table forces one width across all rows); the real fix was restructuring PHP's row into two explicit groups — Settings+Uninstall (same as every module) on one line, the version picker+Add on its own line below — plus narrowing the dropdown so that second line actually fits
Also fixed along the way
- Merged two duplicate Uninstall buttons for PHP into one (the old PHP-specific one was silently missing the loading spinner)
- Removed a dead, commented-out duplicate script block