Repository navigation
Releases: angeldeejay/magicmirror-module-sandbox
Releases · angeldeejay/magicmirror-module-sandbox
Release list
v3.0.0
- MM Version domain — new sidebar domain for nvm-style MagicMirror core version management. Displays the active core version, a list of locally cached installations, and available GitHub releases. Per-version actions: activate, re-download, and delete. A capability table surfaces runtime flags for the active version (Express version, default modules directory, config loading strategy, hook support, CORS proxy, and more).
- Topbar version badge —
MmVersionBadgecomponent in the topbar shows the active core version at a glance. Displays thebuiltInVersionnumber when using sandbox-bundled shims, or the installed version key when an mmvm version is active. Clicking the badge opens the MM Version domain. Updates in real time onmodule-sandbox:mm-version-changedevents. server/mm-version-manager.ts— server-side nvm-style version store under~/.mmvm/. Implements install, activate, delete, re-download, and capability-introspection operations. Exposes/api/mm-versions,POST /api/mm-versions/activate,POST /api/mm-versions/reset,POST /api/mm-versions/download,POST /api/mm-versions/redownload/:key, andDELETE /api/mm-versions/:keyroutes consumed by the MM Version domain.scripts/sync-mmcore-source.ts— new build step that downloads a pinned MagicMirror release from npm intommcore-source/using a version manifest. Skips the GitHub API call entirely when the manifest already records the current version, avoiding rate-limit failures in CI and offline environments. Falls back gracefully to the existing manifest when the API is unreachable.bin/sync-magicmirror-assets.tsmmcore-source fallback —copyReferencedAssetnow triesmmcore-source/node_modules/as a second fallback when a CSS../node_modules/reference is not found inpackageRoot/node_modules/. Fixes font-sync failures when MagicMirror is sourced frommmcore-source/rather than the devDependency.jsonc-parserintegration —client/vendor/jsonc-parser-bundle.tsbundlesjsonc-parseraswindow.jsoncParser(same esbuild pattern asjs-beautify). Replaces ~205 lines of hand-rolled comment-aware JSON parsing inmodule-config-editor.tswith a well-tested library implementation.- CJS dist fix for
mm-version-manager— replaced the barefileURLToPath(import.meta.url)call withtypeof __filename === "string" ? __filename : fileURLToPath(import.meta.url)so the module loads correctly from the CommonJS dist package. Previously the module crashed on startup in consumer installs withERR_INVALID_ARG_TYPE: The "path" argument must be of type string. Received undefined. - Domain order extended to seven —
mmversionis inserted betweenqualityandaboutin the canonical domain sequence acrossSidebar.tsx, the topbarDomainNavdropdown, the Eta sidebar template, and theCANONICAL_DOMAIN_ORDERconstant in the UI test suite. semveradded as a runtime dependency — used inMmVersionDomainfor release sorting and pre-release filtering.- Build pipeline extended —
build:00-sync-mmcore-sourceandbuild:02-sync-analyzersteps added torun-s build:*;client:shellandclient:runtimenow also bundlejsonc-parser-bundle.ts. - Documentation — added
docs/mmversion.mdoperator manual; updateddocs/README.mdto list seven sidebar domains and note the topbar version badge; updatedARCHITECTURE.mdto documentmm-version-manager.ts,MmVersionDomain,MmVersionBadge,jsonc-parser-bundle.ts, andsidebar-mmversion.eta; fixed script drift inAGENTS.md(build:00-sync-mm-assets→ correct three-step sequence). - Screenshots —
scripts/take-screenshots.tsnow capturesdocs/screenshots/mmversion.png;docs/mmversion.mdreferences the screenshot from thecoveragebranch. - Test coverage — 92%+ branch coverage maintained across the full unit suite (451 tests, 28 files). New test files:
mm-version-domain.test.tsx(32 tests),mm-version-domain-branches-a.test.tsx(11 tests),mm-version-domain-branches-b1.test.tsx(6 tests),mm-version-domain-branches-b2.test.tsx(4 tests),topbar-mm-badge.test.tsx(15 tests),sidebar-domain-nav.test.tsx(10 tests). UI journey coverage: 15 new journey IDs for the mmversion domain; 100% journeys/transitions/outcomes across the full UI suite (37 tests). tests/unit/server/routes.test.ts— extended with coverage for all six mm-versions API endpoints.tests/unit/bin/sync-magicmirror-assets.test.ts— updated to cover themmcore-source/node_modules/sibling fallback path.
What's Changed
- feat: MM Version domain, nvm-style version manager, and build hardeniong (v3.0.0) by @angeldeejay in #2
Full Changelog: v2.0.0...v3.0.0
v2.0.0
- Toolchain modernization — replaced
--experimental-strip-typeswith the stable--strip-typesflag across all scripts and npm run commands.eslint.config.mjsmigrated toeslint.config.ts;vite.config.mjsmigrated tovite.config.ts;bin/install-guard.jsmigrated tobin/install-guard.ts. All build scripts (build-client-assets,sync-module-analyzer,magicmirror-module-sandbox) now run undertsx. Added.prettierignore. - TypeScript configuration restructure — added
client/tsconfig.jsonand alignedclient/tsconfig.runtime.jsonfor the client build surface; addedtests/tsconfig.testfiles.jsonandtsconfig.config.jsonfor test and config roots. Removedtsconfig.client-runtime.json. Tightened path references intsconfig.jsonandtsconfig.node.json. - Sidebar toggle — clicking the active sidebar tab now closes the sidebar panel; clicking any tab while the sidebar is closed opens it. Toggle state is handled through
.harness-sidebar-tabevents without extra state management. - Domain navigation dropdown — the topbar now exposes a domain navigation dropdown that opens on click, closes on outside click or selection, and reflects the active domain label. Replaces the previous always-visible tab row for switching sidebar areas.
- CSS fix: sidebar panel scroll —
.harness-sidebarwas missingmin-height: 0, which caused the flex item to grow to full content height (overflowing its CSS grid row) and disabledoverflow-y: autoon.harness-sidebar-scroll. Fixed withmin-height: 0. - Fix:
SANDBOX_VERSIONpath resolution from installed package — theSANDBOX_VERSIONIIFE now detects when running from adist/server/context and resolves../../package.jsoninstead of../package.json, so the version string is correctly read in consumer installs. - Fix: e2e build environment isolation —
buildCurrentRepointests/e2e/helpers.tsnow stripsNODE_ENV,VITEST,VITEST_POOL_ID, andVITEST_WORKER_IDbefore spawning the build subprocess. This prevents@preact/preset-vite's CJS variant from loadingzimmerframeviarequire()(ESM-only package) under rolldownoptimizeDepswhen the test environment is active. jitidevDependency — addedjiti@^2.6.1to support ESLint 10+ loading TypeScript config files (eslint.config.ts).- Journey coverage expanded — added 6 new journey IDs (
ui-domain-nav-dropdown-opens,ui-domain-nav-dropdown-closes-on-outside-click,ui-domain-nav-trigger-reflects-active-domain,ui-domain-nav-dropdown-closes-on-selection,ui-sidebar-toggle-opens,ui-sidebar-toggle-closes). Total journey coverage catalog: 15 → 21 entries. - Test suite hardening — expanded
startup-scripts,shell-hydration-parity, andruntime-core-contractsunit tests; fixedpageClickbrowser command to useel.click()viaevaluateto bypass Playwright coordinate routing intercepted by a positioned footer element. - Dependabot configuration updated — bumped and regrouped update schedule entries.
Full Changelog: v1.3.0...v2.0.0
v1.3.0
- Upgraded MagicMirror dependency to v2.36.0 — formalized the pin from
^2.35.0to^2.36.0and propagated the version string across all sandbox surfaces (config/harness.config.ts,server/html.ts,client/runtime/module.ts, test fixtures and assertions). Full contract audit confirmed zero API breaks between v2.35 and v2.36:module.js,node_helper.js,logger.js,http_fetcher.js,server_functions.js, andvendor.jsall retain the same public API. - Config editor overhaul —
client/vendor/module-config-editor.tsreceived several changes across this release:- Three-editor architecture — rewritten from a single Ace instance to three stacked editors: a read-only prefix pane (the
let config = { … config: {envelope), a scrollable editable pane for inner config properties, and a read-only suffix pane. Line numbers are continuous across all three. The editable pane enforcesINNER_INDENT(6 spaces, depth 3) for display; stored values are always dedented to depth 0.Ctrl+A+Deleteclears only the editable pane. A custom Ace theme (ace-theme-harness.ts) adapts all token and chrome colors to the active--hns-*token set, making the editor theme-aware without JavaScript. header: falserenders as boolean —syncHeadernow detects the"false"string convention used by MagicMirror's attribute transport and emits a booleanfalsenode instead of the string"false".- JS comment support — the editable pane accepts
//and/* */comments without invalidating the config. Format strips comments viastripComments()before running js-beautify; comments are not preserved through a format round-trip by design. - Readonly pane hardening — a transparent
::afteroverlay blocks pointer events on prefix and suffix panes.tabIndex=-1on their internal Ace textareas eliminates the focus tooltip on keyboard navigation. - Inline error highlighting — on a parse failure the editable pane marks the error row with a gutter annotation and a subtle red line highlight, both cleared on the next valid keystroke. The validity indicator now shows only Config valid or Config invalid.
applyBeautifycursor preservation — after a format round-trip the editor attempts to restore cursor position and selection via a normalized left-context pattern match that survives whitespace changes and quoted-to-unquoted key transforms. Restoration is best-effort.
- Three-editor architecture — rewritten from a single Ace instance to three stacked editors: a read-only prefix pane (the
- Journey coverage: stale artifact fix — the reporter now detects which suites (
ui,integration) are present in the current run by inspectingtestModulespaths and passes them asexplicitSuitestobuildJourneyCoverageSummary. Previously, a run where all journey-tagged tests crashed before producing records would exit early without overwriting the summary JSON, leaving a stale 100% score in place for subsequent badge generation. - Documentation — added
docs/themes.md(theme switcher user manual); updateddocs/config.mdfor the validity badge and error highlighting; corrected panel order indocs/debug.md; removed non-existent content fromdocs/about.md; removed changelog-toned language fromdocs/runtime.md.
Full Changelog: v1.2.0...v1.3.0
v1.2.0
- Browser test suite optimizations — net result vs baseline: integration suite -41% wall-clock, -51% test time;
core-fidelityfile -63% per-file:- Switched
page.goto()waitUntilfrom"networkidle"to"domcontentloaded"— eliminates the idle-network wait that was the single largest per-navigation cost (-62% pergotoSandbox()call, -19% integration wall-clock). - Added server pool — each Vitest worker acquires a warm server on first use and holds it across all test sessions in that worker, skipping cold-start for every test after the first per file (-25% wall-clock, -24% ui wall-clock).
- Added
resetSandbox()browser command — firesPOST /__harness/restartwhich triggers Socket.IOharness:reload→ shell callscore.reloadStage()→ stage iframe reloads without a full page navigation. Per-call cost drops from ~280 ms (gotoSandbox) to ~99 ms (-65%). Applied to the eight repeat-reset tests incore-fidelity. - Added frame handle
WeakMapcache increate-browser-commands.ts— avoids repeatedpage.frame()lookups within a single test. - Switched
cleanupAllSandboxSessionRuntimesto parallel teardown viaPromise.allfor concurrent session cleanup. - Excluded
.runtime-cache/from the module file watcher — fixture stylesheet and state writes no longer trigger spuriousharness:reloadevents during tests. - Fixed
publishStageReadyrace instage-bridge.ts—request-stage-snapshothandler now passesBoolean(core.lifecycleState?.domCreated)instead of a bare truthy check, eliminating a class of intermittent flaky failures.
- Switched
- Child process management hardening — prevents orphan Node.js server processes from accumulating across test runs and on Ctrl+C:
- Replaced internal
(stream as any)._handle?.unref?.()/._handle?.ref?.()with the publicstream.unref()/stream.ref()API onchild.stdoutandchild.stderr(net.Socketinstances). The internal_handlepath was bypassing the public interface; the public path is stable, non-internal, and documented. - Added
stdout.destroy()andstderr.destroy()afterterminateChildProcessin the final pool teardown path — flushes the libuvuv_pipe_thandles so they release their event-loop ref immediately instead of waiting for the GC. - Registered
killAllPooledServers()onprocess.exit,SIGINT, andSIGTERMwith a__poolCleanupRegisteredguard to prevent double-registration when bothintegrationanduiprojects import the module in the same Vitest worker process. Previously Ctrl+C mid-run left pooled servers alive in the background.
- Replaced internal
- CI
actcompatibility — local pipeline runs viaactno longer fail on the coverage-publish step:- Added
!env.ACTto thePublish coverage artifacts branchstep condition. TheJamesIves/github-pages-deploy-actionrequiresrsyncand GitHub deploy tooling that are absent from localactDocker images; the guard skips the step cleanly when running underact. - Updated
ci:actscript to pass--rm— containers are removed automatically after each run without requiring a separate Docker cleanup command.
- Added
- Upgraded
ignorefrom^5.3.2to^7.0.5. Used inserver/watch.tsfor.gitignorepattern matching; API surface (ignore(),.add(),.ignores()) is unchanged across major versions. - Excluded
client/styles/fromnpm run format— all files in that directory are generated at build time and must not be reformatted. - Additional MagicMirror fidelity fixes identified by a second-pass divergence audit:
module.data.pathnow matches MM format —pathis nowmodules/${name}/(relative, trailing slash) matchingmain.js. Previously the sandbox used an absolute path with no trailing slash (/modules/${name}), causingthis.data.path + filenameconcatenation to produce malformed URLs.module.file()is now implemented as(this.data.path + filename).replace(/\/\//g, "/"), a verbatim port ofmodule.js.lockStringsprotocol fully implemented —hide(speed, cb, {lockString})now pushes the lock string ontothis.lockStrings;show(speed, cb, {lockString})removes it and skips the show call when locks remain, matchingmodule.js. Previouslythis.lockStringswas initialized but never read or written, so modules that hide via multiple independent actors (presence sensors, schedules, voice commands) would show prematurely on anyshow()call.loadTemplates()respects module overrides and pre-warms Nunjucks — the base implementation now carries atypeof instance.loadTemplates === "function"guard (likegetTemplateandgetTemplateData) so a module that defines its ownloadTemplates()is no longer silently overwritten. The default base implementation now pre-warms the Nunjucks template cache by rendering the file template with an empty data set beforestart()is called, matchingmodule.jsboot-phase behavior.MM.getModules()filter methods emit diagnostics on empty results —withClass(),exceptWithClass(), andexceptModule()now log aLog.warnwhen they return an empty collection, explaining that the sandbox is a single-module environment and that the module's intent is recorded but cannot be simulated. Previously these methods silently returned empty arrays, making it opaque that the sandbox does not support sibling-module coordination.
- D8 test suite no longer produces console noise — the VM context for the
installGlobals creates Logtest block now receives a silent no-op console soLog.*method invocations during the test do not write to stdout/stderr. - Browser runtime now matches MagicMirror core behavior exactly across all divergences identified by a full contract audit (
client/runtime/module.ts,lifecycle.ts,notifications.ts):getDom()always returnsPromise<HTMLElement>— the base implementation is now a verbatim port ofmodule.js:82-107. Previously the sandbox returned a synchronousHTMLElement(or a deferred wrapper) whengetDomwas called viathis._super(), masking bugs that surfaced only in real MagicMirror.hide()andshow()suspend/resume timing —suspend()andresume()now fire inside the animation callback after the transition completes, matchingmodule.js:367-413. Previously they fired before the animation began.module.hiddenasymmetry —MM.hideModulesetsmodule.hidden = trueimmediately before the animation (matchingmain.js:721);MM.showModulesetsmodule.hidden = falseonly after the animation completes (matchingmain.js:729-731).- Header rendered as
innerHTML—getHeader()return values are now inserted viainnerHTML, nottextContent, matchingmain.js:253. Modules that return HTML markup ingetHeader()now render correctly. getHeader()default simplified toreturn this.data.header— matchesmodule.js:115-116. The previous sandbox-specific false/empty-string handling diverged from core.Logobject now complete —Log.debug,Log.group,Log.groupCollapsed,Log.groupEnd,Log.time,Log.timeEnd,Log.timeStamp, andLog.setLogLevelare now exposed, matchinglogger.js. Previously calling any of these threwTypeError: Log.X is not a function.MM.getModules()filter methods — the returned array now carries.withClass(),.exceptWithClass(),.exceptModule(), and.enumerate()as non-enumerable properties, matchingmain.js:501-585. Previously the sandbox returned a plain array without these helpers.notificationReceived()receives the original payload — the sandbox previously passed a JSON clone of the payload. The original object reference is now forwarded, matchingmain.js:98-101. The clone is still used for the debug log entry only.- Template preloading layer removed —
loadTemplates()now resolves immediately. The deferred-wrapper and sync-preload machinery (createDeferredGetDomWrapper,preloadTemplateDependencyTree,seedTemplateLoaderCache,renderPreloadedTemplate,attachDeferredDomReady,hasPreloadedTemplate,readTemplateSource,extractTemplateDependencies,resolveTemplateDependencyPath,isGetDomSuperCall) has been deleted. The nunjucksWebLoaderhandles async template fetching as it does in core.
Full Changelog: v1.1.0...v1.2.0
v1.1.1
- Added
@fastify/rate-limitas a global plugin and applied per-routeconfig.rateLimiton the five static vendor asset routes (/moment.js,/animate.css,/croner.js,/moment-timezone.js,/font-awesome.css) to satisfy CodeQLjs/missing-rate-limiting(CWE-307/400/770) alerts. - Switched the harness UI font from
"Roboto"(inherited from MagicMirror) to Open Sans via@fontsource/open-sans. Latin and latin-ext subsets (weights 300/400/600/700, normal style) are now copied toclient/webfonts/at build time and served at/webfonts/. This makes the operator shell visually independent from the module under test. - Removed generated build artifacts (
client/webfonts/,client/styles/font-awesome.css,client/styles/magicmirror-fonts.css,client/styles/magicmirror-stage.css) from git tracking. These files are now gitignored and regenerated on every build, reducing repository binary bloat. - Trimmed the npm package
fileslist: onlybin/install-guard.jsis now shipped frombin/; the four TypeScript source files (magicmirror-module-sandbox.ts,preview.ts,sync-magicmirror-assets.ts,helpers/css-bundler.ts) that were previously included unnecessarily are excluded. - Added Dependabot configuration (
.github/dependabot.yml) with weekly npm and GitHub Actions update checks, grouped by ecosystem (fastify, testing, typescript, vite, magicmirror). - Added
npm audit --omit=dev --audit-level=highstep to bothci.ymlandpublish.ymlso high/critical vulnerabilities in production dependencies block CI and releases. Dev-only dependency chains are excluded to avoid false positives. - Added
SECURITY.mdwith a vulnerability reporting policy via GitHub Security Advisories. - Added
.github/CODEOWNERSto auto-assign@angeldeejayas reviewer on all pull requests including Dependabot updates.
Full Changelog: v1.1.0...v1.1.1
v1.1.0
- Added Quality sidebar domain with real-time module analysis against MagicMirror 3rd-party criteria. Findings are grouped by severity (errors, warnings, recommendations) with per-severity filter checkboxes and an on-demand Analyze module button. Results update automatically in watch mode. Backed by a new
VendorModuleAnalyzerinserver/module-analysis.ts, an always-on analysis watcher inserver/analysis-watcher.ts, and thequality-panel.tsbrowser runtime. - Introduced upstream vendor sync for the module analyzer. Four files (
module-analyzer.ts,dependency-usage.ts,missing-dependency-rule.ts,rule-registry.ts) are now auto-synced fromMagicMirrorOrg/MagicMirror-3rd-Party-Modulesat build time viasync:module-analyzer, gitignored from this repo, and regenerated on everynpm run build. - Applied no-patch shim fidelity:
logger.jsandnode_helper.jsfrom MagicMirror core are now copied verbatim during sync; sandbox behavior is injected only through appended postludes. The previous source-patch templates (core-logger-replacements.json,core-node-helper-replacements.json) and theSourceReplacementmachinery have been removed. - Bundled Express and undici directly from MagicMirror's own
node_modulesvia esbuild intoshims/generated/node_modules/express/andshims/generated/node_modules/undici/.node_helper.jscan nowrequire('express')andserver_functions.jscanrequire('undici')via standard Node module resolution without any source patches and without adding them as sandbox dependencies. Removedserve-staticandundicifrompackage.jsondependencies. - Split the file watcher into two independent watchers: a module watcher (always-on, stage-scoped reloads, restarts helper on non-style/non-translation changes, respects the mounted module's
.gitignore) and a sandbox watcher (active only under--watch, shell-scoped reloads, triggersrebuildClientAssetsandrebuildNodeCompatfor source changes, callsrestartHelperonly on config changes). - Added build pipeline contract tests (
tests/unit/shims/build-pipeline-contracts.test.ts) that verify each expected shim artifact exists after the build, validate the Express and undici bundles by shape (use/getmethods,express.static,fetch/requestexports), and confirm both bundles resolve correctly from themagicmirror-corecontext via the standard Node module walk. - Added shell hydration parity tests (
tests/unit/server/shell-hydration-parity.test.ts) and extended route and watcher unit coverage acrossroutes.test.tsandwatch.test.ts. - Added seven new UI domain navigation journeys to the journey coverage catalog covering the Quality domain and domain navigation ordering.
- Replaced
peaceiris/actions-gh-pageswithJamesIves/github-pages-deploy-action@v4in CI to resolve the Node 20 deprecation warning underFORCE_JAVASCRIPT_ACTIONS_TO_NODE24. - Introduced a CSS custom property token system (
--hns-*namespace, ~60 tokens) as the single source of truth for all sandbox shell colors. All hardcoded hex values in_shell.scss,_shared.scss,_runtime.scss,_debug.scss,_notifications.scss, and_quality.scssare replaced withvar(--hns-*)references. Existing--sandbox-*control variables are preserved and re-derived from--hns-*tokens so no downstream consumer API changes. - Shipped four built-in themes (Carbon Slate, Obsidian Amber, Violet Circuit, Phosphor Green) via a new
_themes.scsspartial. Themes are activated by[data-theme]on<html>— no JavaScript required for CSS updates. Carbon Slate is the default, applied server-side to prevent FOUC. - Added a theme switcher to the topbar: a brush icon button opens a Bootstrap-style dropdown listing all four themes with color-swatch previews, theme names, and a check mark on the active selection. The chosen theme persists across sessions via
localStorage. Dropdown closes on any outside click. - Added a loading/restart backdrop overlay (
harness-backdrop) shown during stage loads and sandbox restarts.core.showBackdrop(label)/core.hideBackdrop()are exposed on the shell microcore so other runtime scripts can trigger it. - Applied
Cache-Control: no-storeon all/__harness/static assets so watch-mode reloads always serve fresh builds without requiring a hard browser refresh. - Forced
runClientAssetsBuild()at sandbox startup in watch mode so the operator shell is always up to date when the server comes online. - Updated documentation: added
docs/quality.mdfor the new Quality domain, correctedARCHITECTURE.md(removed stale patch references, documented two-watcher split, added CSS token system and backdrop sections), updateddocs/README.mdto list six sidebar domains, and retook all screenshots at 1366×1024.
Full Changelog: v1.0.1...v1.1.0
v1.0.1
- Added MagicMirror-style browser-side Nunjucks template support through
getTemplate(),getTemplateData(), andnunjucksEnvironment(). - Synced the Nunjucks, Moment, Moment Timezone, and Croner browser vendor assets from the local
magicmirrordependency into the sandbox client build so published installs keep working without requiringmagicmirrorat runtime. - Added
_super()binding compatibility in the browser runtime so overridden module methods stay closer to MagicMirror behavior. - Replaced the old synchronous template-cache workaround with a runtime adapter for
getDom()+this._super()so overriding modules receive an immediate wrapper while deferred template content still resolves before the sandbox commits the render. - Removed the duplicate early stage-module script injection path so mounted modules no longer fail with
Module is not definedbefore the sandbox runtime boots. - Overrode MagicMirror's hidden-cursor default inside the sandbox shell styles so the operator UI remains usable in normal browsers.
- Aligned the server-rendered Config sidebar markup with the hydrated Preact shell so button ids, layout, and hydration stay consistent.
- Fixed mounted-module
sandbox.startupscripts on Windows so consumer npm scripts launch reliably without blocking sandbox startup when child process creation fails. - Added shell SSR parity unit coverage across the hydrated Eta/Preact topbar, sidebar domains, and footer, plus fallback branch coverage that keeps the unit coverage threshold green.
- Updated the fixture module to exercise
.njktemplate rendering plus the integratedgetDom()+_super()adapter path and keep integration coverage aligned with real third-party module patterns.
Full Changelog: v1.0.0...v1.0.1
v1.0.0
- Initial public release of the single-module MagicMirror sandbox package.
- Fastify host, Vite + Preact operator shell, and real
node_helper.jswiring. - Sandbox helper compatibility now syncs MagicMirror core
js/class.js,js/logger.js,js/node_helper.js,js/http_fetcher.js, andjs/server_functions.jsinto a compat root so bare and path-based helper requires stay closer to current core behavior inside the sandbox. - Backend-owned mounted-module config persistence with sandbox-managed editing tools.
- Sidebar domains for runtime controls, config editing, notifications, debug logs, and about metadata.
- Eta-based host templates and iframe-backed stage isolation so shell reloads stay separate from mounted-module reloads.
- TypeScript-maintained client/runtime sources with published compiled
dist/artifacts for package consumers. - MagicMirror asset synchronization, local preview flows, install guards, and packaged-install smoke coverage.
- Vitest-based unit, integration, UI, and e2e coverage, including headed maintainer inspection workflows.
- GitHub Actions CI now publishes a unified job summary for v8 + journey coverage, plus README badges from the coverage branch, and browser-backed journey coverage emits suite-specific badges for
uiandintegration. - Refreshed docs, screenshots, CI on Node 24, and GitHub Actions publish automation for npm with trusted publishing/provenance plus mirrored GitHub Packages releases.
Full Changelog: https://github.com/angeldeejay/magicmirror-module-sandbox/commits/v1.0.0