Skip to content

Releases: angeldeejay/magicmirror-module-sandbox

v3.0.0

Choose a tag to compare

@angeldeejay angeldeejay released this 11 May 00:17
df80a49
  • 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 — MmVersionBadge component in the topbar shows the active core version at a glance. Displays the builtInVersion number 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 on module-sandbox:mm-version-changed events.
  • 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, and DELETE /api/mm-versions/:key routes consumed by the MM Version domain.
  • scripts/sync-mmcore-source.ts — new build step that downloads a pinned MagicMirror release from npm into mmcore-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.ts mmcore-source fallback — copyReferencedAsset now tries mmcore-source/node_modules/ as a second fallback when a CSS ../node_modules/ reference is not found in packageRoot/node_modules/. Fixes font-sync failures when MagicMirror is sourced from mmcore-source/ rather than the devDependency.
  • jsonc-parser integration — client/vendor/jsonc-parser-bundle.ts bundles jsonc-parser as window.jsoncParser (same esbuild pattern as js-beautify). Replaces ~205 lines of hand-rolled comment-aware JSON parsing in module-config-editor.ts with a well-tested library implementation.
  • CJS dist fix for mm-version-manager — replaced the bare fileURLToPath(import.meta.url) call with typeof __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 with ERR_INVALID_ARG_TYPE: The "path" argument must be of type string. Received undefined.
  • Domain order extended to seven — mmversion is inserted between quality and about in the canonical domain sequence across Sidebar.tsx, the topbar DomainNav dropdown, the Eta sidebar template, and the CANONICAL_DOMAIN_ORDER constant in the UI test suite.
  • semver added as a runtime dependency — used in MmVersionDomain for release sorting and pre-release filtering.
  • Build pipeline extended — build:00-sync-mmcore-source and build:02-sync-analyzer steps added to run-s build:*; client:shell and client:runtime now also bundle jsonc-parser-bundle.ts.
  • Documentation — added docs/mmversion.md operator manual; updated docs/README.md to list seven sidebar domains and note the topbar version badge; updated ARCHITECTURE.md to document mm-version-manager.ts, MmVersionDomain, MmVersionBadge, jsonc-parser-bundle.ts, and sidebar-mmversion.eta; fixed script drift in AGENTS.md (build:00-sync-mm-assets → correct three-step sequence).
  • Screenshots — scripts/take-screenshots.ts now captures docs/screenshots/mmversion.png; docs/mmversion.md references the screenshot from the coverage branch.
  • 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 the mmcore-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

Choose a tag to compare

@angeldeejay angeldeejay released this 05 May 22:17
34cfa7f
  • Toolchain modernization — replaced --experimental-strip-types with the stable --strip-types flag across all scripts and npm run commands. eslint.config.mjs migrated to eslint.config.ts; vite.config.mjs migrated to vite.config.ts; bin/install-guard.js migrated to bin/install-guard.ts. All build scripts (build-client-assets, sync-module-analyzer, magicmirror-module-sandbox) now run under tsx. Added .prettierignore.
  • TypeScript configuration restructure — added client/tsconfig.json and aligned client/tsconfig.runtime.json for the client build surface; added tests/tsconfig.testfiles.json and tsconfig.config.json for test and config roots. Removed tsconfig.client-runtime.json. Tightened path references in tsconfig.json and tsconfig.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-tab events 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-sidebar was missing min-height: 0, which caused the flex item to grow to full content height (overflowing its CSS grid row) and disabled overflow-y: auto on .harness-sidebar-scroll. Fixed with min-height: 0.
  • Fix: SANDBOX_VERSION path resolution from installed package — the SANDBOX_VERSION IIFE now detects when running from a dist/server/ context and resolves ../../package.json instead of ../package.json, so the version string is correctly read in consumer installs.
  • Fix: e2e build environment isolation — buildCurrentRepo in tests/e2e/helpers.ts now strips NODE_ENV, VITEST, VITEST_POOL_ID, and VITEST_WORKER_ID before spawning the build subprocess. This prevents @preact/preset-vite's CJS variant from loading zimmerframe via require() (ESM-only package) under rolldown optimizeDeps when the test environment is active.
  • jiti devDependency — added jiti@^2.6.1 to 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, and runtime-core-contracts unit tests; fixed pageClick browser command to use el.click() via evaluate to 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

Choose a tag to compare

@angeldeejay angeldeejay released this 04 May 03:35
  • Upgraded MagicMirror dependency to v2.36.0 — formalized the pin from ^2.35.0 to ^2.36.0 and 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, and vendor.js all retain the same public API.
  • Config editor overhaul — client/vendor/module-config-editor.ts received 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 enforces INNER_INDENT (6 spaces, depth 3) for display; stored values are always dedented to depth 0. Ctrl+A + Delete clears 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: false renders as boolean — syncHeader now detects the "false" string convention used by MagicMirror's attribute transport and emits a boolean false node instead of the string "false".
    • JS comment support — the editable pane accepts // and /* */ comments without invalidating the config. Format strips comments via stripComments() before running js-beautify; comments are not preserved through a format round-trip by design.
    • Readonly pane hardening — a transparent ::after overlay blocks pointer events on prefix and suffix panes. tabIndex=-1 on 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.
    • applyBeautify cursor 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.
  • Journey coverage: stale artifact fix — the reporter now detects which suites (ui, integration) are present in the current run by inspecting testModules paths and passes them as explicitSuites to buildJourneyCoverageSummary. 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); updated docs/config.md for the validity badge and error highlighting; corrected panel order in docs/debug.md; removed non-existent content from docs/about.md; removed changelog-toned language from docs/runtime.md.

Full Changelog: v1.2.0...v1.3.0

v1.2.0

Choose a tag to compare

@angeldeejay angeldeejay released this 03 May 00:59
  • Browser test suite optimizations — net result vs baseline: integration suite -41% wall-clock, -51% test time; core-fidelity file -63% per-file:
    • Switched page.goto() waitUntil from "networkidle" to "domcontentloaded" — eliminates the idle-network wait that was the single largest per-navigation cost (-62% per gotoSandbox() 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 — fires POST /__harness/restart which triggers Socket.IO harness:reload → shell calls core.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 in core-fidelity.
    • Added frame handle WeakMap cache in create-browser-commands.ts — avoids repeated page.frame() lookups within a single test.
    • Switched cleanupAllSandboxSessionRuntimes to parallel teardown via Promise.all for concurrent session cleanup.
    • Excluded .runtime-cache/ from the module file watcher — fixture stylesheet and state writes no longer trigger spurious harness:reload events during tests.
    • Fixed publishStageReady race in stage-bridge.ts — request-stage-snapshot handler now passes Boolean(core.lifecycleState?.domCreated) instead of a bare truthy check, eliminating a class of intermittent flaky failures.
  • 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 public stream.unref() / stream.ref() API on child.stdout and child.stderr (net.Socket instances). The internal _handle path was bypassing the public interface; the public path is stable, non-internal, and documented.
    • Added stdout.destroy() and stderr.destroy() after terminateChildProcess in the final pool teardown path — flushes the libuv uv_pipe_t handles so they release their event-loop ref immediately instead of waiting for the GC.
    • Registered killAllPooledServers() on process.exit, SIGINT, and SIGTERM with a __poolCleanupRegistered guard to prevent double-registration when both integration and ui projects import the module in the same Vitest worker process. Previously Ctrl+C mid-run left pooled servers alive in the background.
  • CI act compatibility — local pipeline runs via act no longer fail on the coverage-publish step:
    • Added !env.ACT to the Publish coverage artifacts branch step condition. The JamesIves/github-pages-deploy-action requires rsync and GitHub deploy tooling that are absent from local act Docker images; the guard skips the step cleanly when running under act.
    • Updated ci:act script to pass --rm — containers are removed automatically after each run without requiring a separate Docker cleanup command.
  • Upgraded ignore from ^5.3.2 to ^7.0.5. Used in server/watch.ts for .gitignore pattern matching; API surface (ignore(), .add(), .ignores()) is unchanged across major versions.
  • Excluded client/styles/ from npm 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.path now matches MM format — path is now modules/${name}/ (relative, trailing slash) matching main.js. Previously the sandbox used an absolute path with no trailing slash (/modules/${name}), causing this.data.path + filename concatenation to produce malformed URLs. module.file() is now implemented as (this.data.path + filename).replace(/\/\//g, "/"), a verbatim port of module.js.
    • lockStrings protocol fully implemented — hide(speed, cb, {lockString}) now pushes the lock string onto this.lockStrings; show(speed, cb, {lockString}) removes it and skips the show call when locks remain, matching module.js. Previously this.lockStrings was initialized but never read or written, so modules that hide via multiple independent actors (presence sensors, schedules, voice commands) would show prematurely on any show() call.
    • loadTemplates() respects module overrides and pre-warms Nunjucks — the base implementation now carries a typeof instance.loadTemplates === "function" guard (like getTemplate and getTemplateData) so a module that defines its own loadTemplates() 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 before start() is called, matching module.js boot-phase behavior.
    • MM.getModules() filter methods emit diagnostics on empty results — withClass(), exceptWithClass(), and exceptModule() now log a Log.warn when 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 Log test block now receives a silent no-op console so Log.* 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 returns Promise<HTMLElement> — the base implementation is now a verbatim port of module.js:82-107. Previously the sandbox returned a synchronous HTMLElement (or a deferred wrapper) when getDom was called via this._super(), masking bugs that surfaced only in real MagicMirror.
    • hide() and show() suspend/resume timing — suspend() and resume() now fire inside the animation callback after the transition completes, matching module.js:367-413. Previously they fired before the animation began.
    • module.hidden asymmetry — MM.hideModule sets module.hidden = true immediately before the animation (matching main.js:721); MM.showModule sets module.hidden = false only after the animation completes (matching main.js:729-731).
    • Header rendered as innerHTML — getHeader() return values are now inserted via innerHTML, not textContent, matching main.js:253. Modules that return HTML markup in getHeader() now render correctly.
    • getHeader() default simplified to return this.data.header — matches module.js:115-116. The previous sandbox-specific false/empty-string handling diverged from core.
    • Log object now complete — Log.debug, Log.group, Log.groupCollapsed, Log.groupEnd, Log.time, Log.timeEnd, Log.timeStamp, and Log.setLogLevel are now exposed, matching logger.js. Previously calling any of these threw TypeError: Log.X is not a function.
    • MM.getModules() filter methods — the returned array now carries .withClass(), .exceptWithClass(), .exceptModule(), and .enumerate() as non-enumerable properties, matching main.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, matching main.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 nunjucks WebLoader handles async template fetching as it does in core.

Full Changelog: v1.1.0...v1.2.0

v1.1.1

Choose a tag to compare

@angeldeejay angeldeejay released this 02 May 04:28
  • Added @fastify/rate-limit as a global plugin and applied per-route config.rateLimit on the five static vendor asset routes (/moment.js, /animate.css, /croner.js, /moment-timezone.js, /font-awesome.css) to satisfy CodeQL js/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 to client/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 files list: only bin/install-guard.js is now shipped from bin/; 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=high step to both ci.yml and publish.yml so high/critical vulnerabilities in production dependencies block CI and releases. Dev-only dependency chains are excluded to avoid false positives.
  • Added SECURITY.md with a vulnerability reporting policy via GitHub Security Advisories.
  • Added .github/CODEOWNERS to auto-assign @angeldeejay as reviewer on all pull requests including Dependabot updates.

Full Changelog: v1.1.0...v1.1.1

v1.1.0

Choose a tag to compare

@angeldeejay angeldeejay released this 02 May 01:56
  • 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 VendorModuleAnalyzer in server/module-analysis.ts, an always-on analysis watcher in server/analysis-watcher.ts, and the quality-panel.ts browser 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 from MagicMirrorOrg/MagicMirror-3rd-Party-Modules at build time via sync:module-analyzer, gitignored from this repo, and regenerated on every npm run build.
  • Applied no-patch shim fidelity: logger.js and node_helper.js from 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 the SourceReplacement machinery have been removed.
  • Bundled Express and undici directly from MagicMirror's own node_modules via esbuild into shims/generated/node_modules/express/ and shims/generated/node_modules/undici/. node_helper.js can now require('express') and server_functions.js can require('undici') via standard Node module resolution without any source patches and without adding them as sandbox dependencies. Removed serve-static and undici from package.json dependencies.
  • 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, triggers rebuildClientAssets and rebuildNodeCompat for source changes, calls restartHelper only 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/get methods, express.static, fetch/request exports), and confirm both bundles resolve correctly from the magicmirror-core context 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 across routes.test.ts and watch.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-pages with JamesIves/github-pages-deploy-action@v4 in CI to resolve the Node 20 deprecation warning under FORCE_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.scss are replaced with var(--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.scss partial. 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-store on 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.md for the new Quality domain, corrected ARCHITECTURE.md (removed stale patch references, documented two-watcher split, added CSS token system and backdrop sections), updated docs/README.md to list six sidebar domains, and retook all screenshots at 1366×1024.

Full Changelog: v1.0.1...v1.1.0

v1.0.1

Choose a tag to compare

@angeldeejay angeldeejay released this 29 Apr 03:23
  • Added MagicMirror-style browser-side Nunjucks template support through getTemplate(), getTemplateData(), and nunjucksEnvironment().
  • Synced the Nunjucks, Moment, Moment Timezone, and Croner browser vendor assets from the local magicmirror dependency into the sandbox client build so published installs keep working without requiring magicmirror at 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 defined before 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.startup scripts 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 .njk template rendering plus the integrated getDom() + _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

Choose a tag to compare

@angeldeejay angeldeejay released this 27 Apr 23:52
  • Initial public release of the single-module MagicMirror sandbox package.
  • Fastify host, Vite + Preact operator shell, and real node_helper.js wiring.
  • Sandbox helper compatibility now syncs MagicMirror core js/class.js, js/logger.js, js/node_helper.js, js/http_fetcher.js, and js/server_functions.js into 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 ui and integration.
  • 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