From 1d0c59e60f5f2b8870845290fb89d56efea0d0c3 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Fri, 12 Jun 2026 21:30:41 +0200 Subject: [PATCH 1/3] fix!: install module via Composer path repository instead of app/code bind-mount --- .ddev/commands/web/install-magento | 36 ++++++----- .ddev/commands/web/install-module-deps | 75 ---------------------- .ddev/config.yaml | 13 ++-- .ddev/docker-compose.mageforge-source.yaml | 12 +++- docs/development.md | 37 +++++++---- 5 files changed, 56 insertions(+), 117 deletions(-) delete mode 100755 .ddev/commands/web/install-module-deps diff --git a/.ddev/commands/web/install-magento b/.ddev/commands/web/install-magento index b3c69092..2ead7166 100755 --- a/.ddev/commands/web/install-magento +++ b/.ddev/commands/web/install-magento @@ -12,14 +12,13 @@ cd /var/www/html || exit 1 # global config MAGENTO_FOLDER="magento" -# Guard: verify the MageForge bind-mount is active. -# The Docker bind-mount (../src → .../MageForge) is a kernel-level mount established -# when the containers start. If magento/ was deleted while DDEV was running, the mount -# becomes orphaned: its inode is gone, and recreating the directory produces a new inode -# not covered by the old mount. The module source would then be invisible to Magento. -# The only fix is a container restart, which re-establishes the mount on the new inode. -if [[ ! -f "${MAGENTO_FOLDER}/app/code/OpenForgeProject/MageForge/registration.php" ]]; then - echo "ERROR: The MageForge bind-mount is not active." +# Guard: verify the module source mount is active. +# The mount (repo root → magento/mageforge-source, read-only) is established when the +# containers start. If magento/ was deleted while DDEV was running, the mount can become +# orphaned: its inode is gone, and a recreated directory is not covered by the old mount. +# A container restart re-establishes the mount on the new inode. +if [[ ! -f "${MAGENTO_FOLDER}/mageforge-source/composer.json" ]]; then + echo "ERROR: The MageForge source mount is not active." echo "" echo "This happens when magento/ was deleted while DDEV was still running." echo "" @@ -72,17 +71,22 @@ composer config repositories.hyva-themes/magento2-theme-fallback git https://git composer config repositories.hyva-themes/magento2-order-cancellation-webapi git https://github.com/hyva-themes/magento2-order-cancellation-webapi.git composer config repositories.hyva-themes/magento2-email-module git https://github.com/hyva-themes/magento2-email-module.git -# Remove *.sample extension -find . -name "*.sample" -type f -exec sh -c 'mv "$1" "${1%.sample}"' _ {} \; +# Remove *.sample extension (skip the read-only module source mount) +find . -path ./mageforge-source -prune -o -name "*.sample" -type f -exec sh -c 'mv "$1" "${1%.sample}"' _ {} \; rm -f package-lock.json # remove basic package-lock.json to avoid conflicts # create missing local-themes.js file for grunt tasks echo 'module.exports = {};' >dev/tools/grunt/configs/local-themes.js -# Require Hyvä theme and install MageForge module deps before setup:install so that -# both are included in the initial schema-upgrade pass (avoiding a redundant second pass). -composer require 'hyva-themes/magento2-default-theme' -/var/www/html/.ddev/commands/web/install-module-deps +# Register the module source mount as a Composer path repository. Composer symlinks +# vendor/openforgeproject/mageforge → ../../mageforge-source, which resolves within the +# Magento root (satisfying Magento's path validator), and resolves the module's +# third-party dependencies (e.g. laravel/prompts) like any regular package. +composer config repositories.mageforge '{"type": "path", "url": "mageforge-source", "options": {"symlink": true}}' + +# Require Hyvä theme and MageForge before setup:install so that both are included +# in the initial schema-upgrade pass (avoiding a redundant second pass). +composer require 'hyva-themes/magento2-default-theme' 'openforgeproject/mageforge:@dev' # install magento bin/magento setup:install \ @@ -108,9 +112,7 @@ bin/magento deploy:mode:set developer # disable 2FA bin/magento module:disable Magento_TwoFactorAuth Magento_AdminAdobeImsTwoFactorAuth -# Enable MageForge: the module is bind-mounted under app/code/ and therefore not registered -# via Composer autoload. bin/magento module:enable discovers it through the component registrar -# (registration.php), writes the entry to app/etc/config.php, and exits non-zero on any error. +# Enable MageForge (Composer-installed modules are disabled until enabled in app/etc/config.php) bin/magento module:enable OpenForgeProject_MageForge # install sample data diff --git a/.ddev/commands/web/install-module-deps b/.ddev/commands/web/install-module-deps deleted file mode 100755 index a180bd7f..00000000 --- a/.ddev/commands/web/install-module-deps +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env bash - -## Description: Install MageForge module dependencies into the Magento vendor directory -## Usage: install-module-deps -## Example: ddev install-module-deps - -# The module source is bind-mounted (not Composer-installed), so its third-party -# dependencies are not resolved automatically. Read them from the module's composer.json -# and install the non-Magento/non-PHP ones into the Magento vendor. - -MAGENTO_DIR="/var/www/html/magento" -MODULE_COMPOSER_JSON="/var/www/html/composer.json" - -# Skip if Magento is not yet installed (e.g. on initial ddev start before install-magento) -if [[ ! -f "${MAGENTO_DIR}/vendor/autoload.php" ]]; then - exit 0 -fi - -cd "${MAGENTO_DIR}" || exit 1 - -php -r " - \$manifest = json_decode(file_get_contents('${MODULE_COMPOSER_JSON}'), true); - if (\$manifest === null) { - fwrite(STDERR, 'ERROR: Could not parse module composer.json at ${MODULE_COMPOSER_JSON}' . PHP_EOL); - exit(1); - } - \$deps = []; - foreach (\$manifest['require'] ?? [] as \$package => \$constraint) { - // Skip php, magento/*, and Composer platform packages (ext-*, lib-*, composer-*-api). - // Platform packages have no vendor/ directory and would cause repeated failed installs. - if (\$package === 'php' - || str_starts_with(\$package, 'magento/') - || str_starts_with(\$package, 'ext-') - || str_starts_with(\$package, 'lib-') - || \$package === 'composer-runtime-api' - || \$package === 'composer-plugin-api') { - continue; - } - \$deps[\$package] = \$constraint; - } - \$missingConstraints = []; - \$missingNames = []; - // Read Magento's composer.json once to compare declared constraints. - \$magentoManifest = is_file('composer.json') - ? json_decode(file_get_contents('composer.json'), true) - : null; - foreach (\$deps as \$package => \$constraint) { - \$vendorDir = 'vendor/' . \$package; - \$needsInstall = !is_dir(\$vendorDir); - if (!\$needsInstall) { - // Check whether Magento's composer.json already declares the exact required - // constraint. This detects constraint bumps in the module (e.g. ^0.3 → ^0.4) - // and triggers a re-install when the constraint changes. - \$declaredConstraint = \$magentoManifest['require'][\$package] - ?? \$magentoManifest['require-dev'][\$package] - ?? null; - if (\$declaredConstraint !== \$constraint) { - \$needsInstall = true; - } - } - if (\$needsInstall) { - \$missingConstraints[] = escapeshellarg(\"\$package:\$constraint\"); - \$missingNames[] = escapeshellarg(\$package); - } - } - if (\$missingConstraints) { - echo 'Installing MageForge module dependencies: ' . implode(', ', \$missingNames) . PHP_EOL; - // Add constraints without resolving first, then update only the new packages. - // This prevents Composer from touching unrelated Magento core dependencies. - passthru('composer require --no-interaction --no-update ' . implode(' ', \$missingConstraints), \$exitCode); - if (\$exitCode !== 0) { exit(\$exitCode); } - passthru('composer update --no-interaction --with-dependencies ' . implode(' ', \$missingNames), \$exitCode); - exit(\$exitCode); - } -" diff --git a/.ddev/config.yaml b/.ddev/config.yaml index 5c0c22bc..a25e9f99 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -11,17 +11,12 @@ database: version: "10.6" hooks: pre-start: - # Pre-create the MageForge bind-mount target directory on the host. - # Docker creates missing mount-target paths as root; by creating them here - # (as the host user) they get the correct ownership for the DDEV web container. - # MageForge/ is the actual bind-mount target (../src → .../MageForge), so we - # must create it explicitly – creating only the parent is not enough. - - exec-host: mkdir -p magento/app/code/OpenForgeProject/MageForge + # Pre-create the mageforge-source mount target on the host. Docker creates + # missing mount-target paths as root; creating it here (as the host user) + # gives it the correct ownership for the DDEV web container. + - exec-host: mkdir -p magento/mageforge-source post-start: - exec-host: ddev npx skills experimental_install - # Install MageForge module dependencies (e.g. laravel/prompts) that are not - # resolved automatically because the module is bind-mounted, not Composer-installed. - - exec: /var/www/html/.ddev/commands/web/install-module-deps use_dns_when_possible: true composer_root: magento composer_version: "2" diff --git a/.ddev/docker-compose.mageforge-source.yaml b/.ddev/docker-compose.mageforge-source.yaml index f01ddc72..32f4b154 100644 --- a/.ddev/docker-compose.mageforge-source.yaml +++ b/.ddev/docker-compose.mageforge-source.yaml @@ -1,6 +1,12 @@ services: web: volumes: - # Bind-mount the module source directly into app/code/ so realpath() returns - # a path within the Magento root, bypassing Magento's filesystem path validator. - - ../src:/var/www/html/magento/app/code/OpenForgeProject/MageForge:cached + # Mount the module repository read-only inside the Magento root. The Composer + # path-repository symlink (vendor/openforgeproject/mageforge → ../../mageforge-source) + # then resolves to a path within the Magento root, satisfying Magento's path + # validator. Read-only also protects the module source from an accidental + # `rm -rf magento` inside the container: deletion stops at the mount. + - ..:/var/www/html/magento/mageforge-source:ro,cached + # The repository contains magento/ itself; shadow it with an anonymous volume + # so the mount does not recurse (mageforge-source/magento/mageforge-source/…). + - /var/www/html/magento/mageforge-source/magento diff --git a/docs/development.md b/docs/development.md index c6502ecb..e87ce289 100644 --- a/docs/development.md +++ b/docs/development.md @@ -43,7 +43,7 @@ Welcome to the MageForge development repository. This guide covers everything yo > > - All module development happens in `/src/` — this is where you write code. > - Testing happens in `/magento/` — a full Magento 2 installation wired up for local use. -> - `/src/` is **bind-mounted by Docker** into `/magento/app/code/OpenForgeProject/MageForge/`. Changes are visible instantly; no Composer step needed. The mount is established on `ddev start` / `ddev restart`. +> - The repository is **mounted read-only by Docker** into `/magento/mageforge-source/` and installed into Magento as a regular Composer package (path repository with symlink). Changes in `/src/` are visible instantly; no Composer step needed. The mount is established on `ddev start` / `ddev restart`. > - `/magento/` is never included in a release. It exists solely for local development. --- @@ -83,12 +83,12 @@ Basic familiarity with Magento 2 module development is assumed. This script will: - Install a fresh Magento 2 instance inside `/magento/` - - Install third-party module dependencies via `ddev install-module-deps` + - Install MageForge via Composer (path repository pointing at the mounted module source) - Install Magento sample data - Enable the MageForge module (`bin/magento module:enable`) - Set developer mode and disable 2FA - > **Note:** `ddev start` must run before this command to establish the Docker bind-mount. + > **Note:** `ddev start` must run before this command to establish the Docker mount. 4. **Verify the installation:** @@ -100,15 +100,26 @@ You now have a fully functional local development environment. --- -## How the Bind-Mount Works +## How the Module Is Installed -`/src/` is bind-mounted by Docker (`.ddev/docker-compose.mageforge-source.yaml`) into the Magento app/code directory: +The repository root is bind-mounted **read-only** by Docker (`.ddev/docker-compose.mageforge-source.yaml`) into the Magento root: ``` -../src → magento/app/code/OpenForgeProject/MageForge/ +.. → magento/mageforge-source/ (read-only) ``` -A bind-mount is used instead of a Composer symlink because Magento's path validator rejects paths that resolve outside the Magento root. +`ddev install-magento` registers this directory as a Composer **path repository** and installs the module with `composer require openforgeproject/mageforge:@dev`. Composer creates a symlink: + +``` +magento/vendor/openforgeproject/mageforge → ../../mageforge-source +``` + +Why this construction? + +- **Magento's path validator** rejects paths that resolve (via `realpath()`) outside the Magento root. A plain Composer symlink to the repository root would fail; the mount point lives *inside* the Magento root, so validation passes. +- **Read-only protects the source**: an accidental `rm -rf magento` inside the container stops at the mount instead of deleting the repository through it. +- **Real Composer install**: third-party dependencies of the module (e.g. `laravel/prompts`) are resolved by Composer like for any end-user installation — no extra sync scripts needed. +- An anonymous volume shadows `mageforge-source/magento/` so the mount does not recurse into itself. **The mount is (re-)established every time the containers start.** Always run `ddev start` or `ddev restart` when: @@ -116,10 +127,10 @@ A bind-mount is used instead of a Composer symlink because Magento's path valida - pulling config changes from the repository - `/magento/` was deleted while DDEV was running (see [Common Issues](#common-issues)) -**Third-party dependencies** (e.g. `laravel/prompts`) are not resolved automatically for bind-mounted modules. A `post-start` hook runs `ddev install-module-deps` on every start to keep them in sync. You can also trigger it manually: +**Changed module dependencies** (`composer.json` in the repository root) are picked up with: ```bash -ddev install-module-deps +ddev composer update openforgeproject/mageforge ``` --- @@ -233,25 +244,25 @@ ddev poweroff ddev start ``` -**MageForge bind-mount not active / `registration.php` not found:** +**MageForge source mount not active / `mageforge-source` empty:** This happens when `/magento/` was deleted while DDEV was still running. Docker holds the old inode; the new directory is not covered by the mount. ```bash -ddev restart # Re-establishes the bind-mount on the new inode +ddev restart # Re-establishes the mount on the new inode ddev install-magento # Re-installs Magento with the mount now active ``` **Module dependencies missing after updating `composer.json`:** ```bash -ddev install-module-deps # Installs / updates third-party deps declared in src/composer.json +ddev composer update openforgeproject/mageforge # Re-resolves the module's dependencies ``` **Need to reinstall Magento from scratch:** ```bash -ddev restart # Ensure the bind-mount is fresh first +ddev restart # Ensure the source mount is fresh first ddev install-magento # Handles cleanup automatically ``` From 7a1e4f6df0db5efd4812010baefc393c22568087 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Fri, 12 Jun 2026 22:17:35 +0200 Subject: [PATCH 2/3] feat: update qa tools --- .ddev/commands/web/install-magento | 7 +- .ddev/commands/web/mago | 24 +- .ddev/commands/web/phpcbf | 45 +- .ddev/commands/web/phpcs | 48 +- .ddev/commands/web/phpstan | 37 +- .editorconfig | 24 + .gitattributes | 2 + .github/ISSUE_TEMPLATE/bug_report.md | 17 +- .github/ISSUE_TEMPLATE/feature_request.md | 5 +- .github/assets/cli-chooser.png | Bin 23694 -> 12381 bytes .github/copilot-instructions.md | 6 +- .github/labeler.yml | 28 +- .github/workflows/functional-tests.yml | 2 +- .github/workflows/label.yml | 10 +- .github/workflows/lint.yml | 54 + .github/workflows/magento-compatibility.yml | 12 +- .github/workflows/phpcs.yml | 16 +- .gitignore | 4 + .trunk/configs/.markdownlint.yaml | 4 + .trunk/trunk.yaml | 5 + CHANGELOG.md | 317 +++-- CONTRIBUTING.md | 10 +- README.md | 32 +- composer.json | 24 + docs/commands_reference.md | 38 +- docs/custom_theme_builders.md | 5 +- docs/development.md | 82 +- mago.toml | 30 +- phpcs.xml.dist | 14 + src/Block/Inspector.php | 7 +- src/Console/Command/AbstractCommand.php | 4 +- src/Console/Command/Dev/InspectorCommand.php | 2 +- src/Console/Command/System/CheckCommand.php | 13 +- src/Console/Command/Theme/BuildCommand.php | 9 +- src/Console/Command/Theme/CleanCommand.php | 11 +- src/Console/Command/Theme/TokensCommand.php | 11 +- src/Console/Command/Theme/WatchCommand.php | 7 +- src/Model/Config/Source/ToolbarPosition.php | 6 +- .../Decorator/InspectorHints.php | 20 +- .../Decorator/InspectorHintsFactory.php | 1 + .../TemplateEngine/Plugin/InspectorHints.php | 2 +- src/Model/ThemeList.php | 1 + src/Model/ThemePath.php | 4 +- src/Service/Hyva/ModuleScanner.php | 3 +- .../Inspector/Cache/BlockCacheCollector.php | 2 +- src/Service/SymlinkCleaner.php | 2 +- .../ThemeBuilder/HyvaThemes/Builder.php | 5 +- .../ThemeBuilder/TailwindCSS/Builder.php | 5 +- src/view/adminhtml/web/css/styles.css | 10 +- .../adminhtml/web/images/MageForgeLogo.png | Bin 869 -> 496 bytes src/view/frontend/templates/inspector.phtml | 71 +- .../frontend/web/css/audits/tab-order.css | 76 +- src/view/frontend/web/css/inspector.css | 856 +++++++------- src/view/frontend/web/css/toolbar.css | 1021 +++++++++-------- src/view/frontend/web/js/inspector.js | 476 ++++---- .../web/js/inspector/accessibility.js | 565 +++++---- src/view/frontend/web/js/inspector/dom.js | 196 ++-- .../frontend/web/js/inspector/draggable.js | 380 +++--- .../frontend/web/js/inspector/performance.js | 880 ++++++++------ src/view/frontend/web/js/inspector/picker.js | 480 ++++---- src/view/frontend/web/js/inspector/tabs.js | 388 ++++--- src/view/frontend/web/js/inspector/ui.js | 787 ++++++------- src/view/frontend/web/js/inspector/vitals.js | 495 ++++---- src/view/frontend/web/js/toolbar.js | 106 +- src/view/frontend/web/js/toolbar/audits.js | 371 +++--- .../js/toolbar/audits/buttons-without-type.js | 57 +- .../web/js/toolbar/audits/duplicate-ids.js | 91 +- .../js/toolbar/audits/empty-interactive.js | 102 +- .../web/js/toolbar/audits/highlight.js | 184 +-- .../js/toolbar/audits/images-without-alt.js | 109 +- .../audits/images-without-dimensions.js | 52 +- .../audits/images-without-lazy-load.js | 58 +- .../frontend/web/js/toolbar/audits/index.js | 54 +- .../js/toolbar/audits/inputs-without-label.js | 79 +- .../js/toolbar/audits/low-contrast-text.js | 206 ++-- .../web/js/toolbar/audits/multiple-h1.js | 58 +- .../js/toolbar/audits/small-touch-targets.js | 90 +- .../web/js/toolbar/audits/tab-order.js | 369 +++--- .../js/toolbar/audits/unsafe-blank-target.js | 57 +- src/view/frontend/web/js/toolbar/ui.js | 1009 ++++++++-------- 80 files changed, 5753 insertions(+), 4997 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/lint.yml create mode 100644 phpcs.xml.dist diff --git a/.ddev/commands/web/install-magento b/.ddev/commands/web/install-magento index 2ead7166..473f48fc 100755 --- a/.ddev/commands/web/install-magento +++ b/.ddev/commands/web/install-magento @@ -45,11 +45,10 @@ composer create-project \ magento-temp # Create Magento Folder if not exist -if [[ ! -d "${MAGENTO_FOLDER}" ]]; then +if [[ ! -d ${MAGENTO_FOLDER} ]]; then mkdir -p "${MAGENTO_FOLDER}" fi - # copy everything from magento-temp into magento folder cp -a magento-temp/. "${MAGENTO_FOLDER}/" @@ -127,9 +126,9 @@ bin/magento setup:upgrade HYVA_THEME_ID=$(mysql --host=db --user=db --password=db db \ --skip-column-names --silent \ --execute="SELECT theme_id FROM theme WHERE theme_path = 'Hyva/default' LIMIT 1" 2>/dev/null) || HYVA_THEME_ID="" -if [[ -n "$HYVA_THEME_ID" ]]; then +if [[ -n ${HYVA_THEME_ID} ]]; then echo "Setting Hyvä Default (ID: ${HYVA_THEME_ID}) as storefront theme..." - bin/magento config:set design/theme/theme_id "$HYVA_THEME_ID" + bin/magento config:set design/theme/theme_id "${HYVA_THEME_ID}" bin/magento cache:clean config else echo "WARNING: Hyvä Default theme not found in database, skipping theme activation." diff --git a/.ddev/commands/web/mago b/.ddev/commands/web/mago index 96a5acbe..5db35919 100755 --- a/.ddev/commands/web/mago +++ b/.ddev/commands/web/mago @@ -1,19 +1,19 @@ #!/usr/bin/env bash -## Description: Run Mago (PHP analysis, formatting, and linting) +set -euo pipefail + +## Description: Run Mago (PHP linter and formatter) ## Usage: mago [options] -## Example: "ddev mago" +## Example: ddev mago lint +## Example: ddev mago fmt +## Example: ddev mago fmt --dry-run -set -e +cd /var/www/html -# Require Mago to be installed (avoid executing remote install scripts automatically) -if ! command -v mago >/dev/null 2>&1; then - echo "mago is not installed. Please install it first: https://carthage.software/mago" - exit 1 +# Mago is a require-dev dependency of the module itself. +if [[ ! -x vendor/bin/mago ]]; then + echo "mago not found. Installing module dev dependencies..." + composer install --no-interaction fi -# Change to module root where mago.toml is found -cd /var/www/html - -# Run Mago with provided arguments -mago "$@" +vendor/bin/mago "$@" diff --git a/.ddev/commands/web/phpcbf b/.ddev/commands/web/phpcbf index 9a6899be..0a5265df 100755 --- a/.ddev/commands/web/phpcbf +++ b/.ddev/commands/web/phpcbf @@ -1,42 +1,19 @@ #!/usr/bin/env bash -## Description: Run phpcbf (auto-fix coding standard issues) -## Usage: phpcbf [path] +set -euo pipefail + +## Description: Run PHP Code Beautifier (auto-fix Magento2 standard violations) +## Usage: phpcbf [path] [flags] ## Example: ddev phpcbf ## Example: ddev phpcbf src/Service/StaticContentCleaner.php -## Example: ddev phpcbf vendor/openforgeproject/mageforge/src/Block - -cd /var/www/html/magento || exit 1 - -PHPCBF_BIN="vendor-bin/coding-standard/vendor/bin/phpcbf" -PHPCBF_FALLBACK="vendor-bin/coding-standard/vendor/squizlabs/php_codesniffer/bin/phpcbf" - -if [[ ! -x "${PHPCBF_BIN}" ]]; then - PHPCBF_BIN="${PHPCBF_FALLBACK}" -fi - -if [[ ! -x "${PHPCBF_BIN}" ]]; then - echo "phpcbf not found. Installing coding-standard toolchain..." - composer bin coding-standard install || exit 1 - PHPCBF_BIN="${PHPCBF_FALLBACK}" -fi - -if [[ ! -x "${PHPCBF_BIN}" ]]; then - echo "phpcbf binary still missing. Expected ${PHPCBF_FALLBACK}." - exit 1 -fi -# Set target path - default to vendor/openforgeproject/mageforge/src if not provided -TARGET_PATH="vendor/openforgeproject/mageforge/src" -if [[ $# -gt 0 ]] && [[ ! "$1" =~ ^- ]]; then - TARGET_PATH="$1" - shift # Remove the first argument +cd /var/www/html - # If path doesn't exist from magento dir, try from workspace root - if [[ ! -e "${TARGET_PATH}" ]] && [[ -e "../${TARGET_PATH}" ]]; then - TARGET_PATH="../${TARGET_PATH}" - fi +# The coding standard is a require-dev dependency of the module itself. +if [[ ! -x vendor/bin/phpcbf ]]; then + echo "phpcbf not found. Installing module dev dependencies..." + composer install --no-interaction fi -# Run PHPCBF with optional additional flags -"${PHPCBF_BIN}" -p -s --standard=Magento2 "$@" "${TARGET_PATH}" +# The ruleset (phpcs.xml.dist) defines the standard and default file list. +vendor/bin/phpcbf -p "$@" diff --git a/.ddev/commands/web/phpcs b/.ddev/commands/web/phpcs index f2b80066..f5c50b5f 100755 --- a/.ddev/commands/web/phpcs +++ b/.ddev/commands/web/phpcs @@ -1,45 +1,19 @@ #!/usr/bin/env bash -## Description: Run phpcs -## Usage: phpcs [path] +set -euo pipefail + +## Description: Run PHP CodeSniffer (Magento2 standard) on the module source +## Usage: phpcs [path] [flags] ## Example: ddev phpcs ## Example: ddev phpcs src/Service/StaticContentCleaner.php -## Example: ddev phpcs vendor/openforgeproject/mageforge/src/Block - -cd /var/www/html/magento || exit 1 - -PHPCS_BIN="vendor-bin/coding-standard/vendor/bin/phpcs" -PHPCS_FALLBACK="vendor-bin/coding-standard/vendor/squizlabs/php_codesniffer/bin/phpcs" - -if [[ ! -x "${PHPCS_BIN}" ]]; then - PHPCS_BIN="${PHPCS_FALLBACK}" -fi - -if [[ ! -x "${PHPCS_BIN}" ]]; then - echo "phpcs not found. Installing coding-standard toolchain..." - composer bin coding-standard install || exit 1 - PHPCS_BIN="${PHPCS_FALLBACK}" -fi - -if [[ ! -x "${PHPCS_BIN}" ]]; then - echo "phpcs binary still missing. Expected ${PHPCS_FALLBACK}." - exit 1 -fi -# Set target path - default to vendor/openforgeproject/mageforge/src if not provided -TARGET_PATH="vendor/openforgeproject/mageforge/src" -if [[ $# -gt 0 ]] && [[ ! "$1" =~ ^- ]]; then - TARGET_PATH="$1" - shift # Remove the first argument +cd /var/www/html - # If path starts with 'src/', convert to vendor path - if [[ "${TARGET_PATH}" =~ ^src/ ]]; then - TARGET_PATH="vendor/openforgeproject/mageforge/${TARGET_PATH}" - # If path doesn't exist from magento dir, try from workspace root - elif [[ ! -e "${TARGET_PATH}" ]] && [[ -e "../${TARGET_PATH}" ]]; then - TARGET_PATH="../${TARGET_PATH}" - fi +# The coding standard is a require-dev dependency of the module itself. +if [[ ! -x vendor/bin/phpcs ]]; then + echo "phpcs not found. Installing module dev dependencies..." + composer install --no-interaction fi -# Run PHPCS with optional additional flags -"${PHPCS_BIN}" -p -s --standard=Magento2 "$@" "${TARGET_PATH}" +# The ruleset (phpcs.xml.dist) defines the standard and default file list. +vendor/bin/phpcs -p -s "$@" diff --git a/.ddev/commands/web/phpstan b/.ddev/commands/web/phpstan index 889bd54d..de70ef59 100755 --- a/.ddev/commands/web/phpstan +++ b/.ddev/commands/web/phpstan @@ -11,45 +11,40 @@ cd /var/www/html/magento || exit 1 # Check if PHPStan is installed if [[ ! -f vendor/bin/phpstan ]]; then - echo "PHPStan not found. Installing PHPStan with Magento extension..." + echo "PHPStan not found. Installing PHPStan with Magento extension..." - # Allow PHPStan extension installer - composer config --no-plugins allow-plugins.phpstan/extension-installer true + # Allow PHPStan extension installer + composer config --no-plugins allow-plugins.phpstan/extension-installer true - # Install PHPStan and Magento extension - composer require --dev --no-update bitexpert/phpstan-magento phpstan/phpstan:^2.0 phpstan/extension-installer + # Install PHPStan and Magento extension + composer require --dev --no-update bitexpert/phpstan-magento phpstan/phpstan:^2.0 phpstan/extension-installer - # Update dependencies (limit scope to PHPStan packages) - composer update bitexpert/phpstan-magento phpstan/phpstan phpstan/extension-installer --with-dependencies + # Update dependencies (limit scope to PHPStan packages) + composer update bitexpert/phpstan-magento phpstan/phpstan phpstan/extension-installer --with-dependencies - echo "PHPStan installation complete." + echo "PHPStan installation complete." fi -# Set target path - prefer app/code mount over vendor copy if not provided or if it's a flag -if [[ -d "app/code/OpenForgeProject" ]]; then - DEFAULT_TARGET_PATH="app/code/OpenForgeProject" -else - DEFAULT_TARGET_PATH="vendor/openforgeproject/mageforge/src" -fi -TARGET_PATH="${DEFAULT_TARGET_PATH}" -if [[ $# -gt 0 ]] && [[ ! "$1" =~ ^- ]]; then +# Default target: the module source, symlinked into vendor via the Composer path repository +TARGET_PATH="vendor/openforgeproject/mageforge/src" +if [[ $# -gt 0 ]] && [[ ! $1 =~ ^- ]]; then TARGET_PATH="$1" shift # Remove the first argument # If path doesn't exist from magento dir, try from workspace root - if [[ ! -e "${TARGET_PATH}" ]] && [[ -e "../${TARGET_PATH}" ]]; then + if [[ ! -e ${TARGET_PATH} ]] && [[ -e "../${TARGET_PATH}" ]]; then TARGET_PATH="../${TARGET_PATH}" fi fi # Determine config file location if [[ -f "vendor/openforgeproject/mageforge/phpstan.neon" ]]; then - PHPSTAN_CONFIG="vendor/openforgeproject/mageforge/phpstan.neon" + PHPSTAN_CONFIG="vendor/openforgeproject/mageforge/phpstan.neon" elif [[ -f "../phpstan.neon" ]]; then - PHPSTAN_CONFIG="../phpstan.neon" + PHPSTAN_CONFIG="../phpstan.neon" else - echo "PHPStan config not found at vendor/openforgeproject/mageforge/phpstan.neon or ../phpstan.neon" - exit 1 + echo "PHPStan config not found at vendor/openforgeproject/mageforge/phpstan.neon or ../phpstan.neon" + exit 1 fi # Run PHPStan with the same configuration as CI pipeline diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..cc2ba22b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +# EditorConfig: https://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +# Match Prettier's output (2-space indent) for everything it formats +[*.{js,mjs,css,json,yml,yaml,md}] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab + +# DDEV command scripts are formatted by shfmt with tabs +[.ddev/commands/**] +indent_style = tab diff --git a/.gitattributes b/.gitattributes index ca0c2489..0589acd0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,6 +6,8 @@ /docs/ export-ignore /phpstan.neon export-ignore /mago.toml export-ignore +/phpcs.xml.dist export-ignore +/.editorconfig export-ignore /CONTRIBUTING.md export-ignore /context7.json export-ignore /release-please-config.json export-ignore diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0934522b..b7f850c8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,10 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: 'Bug Report: ' +title: "Bug Report: " labels: bug -assignees: '' - +assignees: "" --- **Describe the bug** @@ -12,6 +11,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. ... @@ -22,11 +22,12 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Environment (please complete the following information):** - - MageForge Version - - Magento Version - - Hyva Version - - OS: [e.g. MacOS, Linux, ... ] - - Terminal Name [e.G. Iterm, Powershell, ... ] + +- MageForge Version +- Magento Version +- Hyva Version +- OS: [e.g. MacOS, Linux, ... ] +- Terminal Name [e.G. Iterm, Powershell, ... ] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 1ebc1e90..5e437c39 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,10 +1,9 @@ --- name: Feature request about: Suggest an idea for this project -title: 'Feature-Request: ' +title: "Feature-Request: " labels: feature-request -assignees: '' - +assignees: "" --- **Magento 2 Version** diff --git a/.github/assets/cli-chooser.png b/.github/assets/cli-chooser.png index 8593bbe405b92aa4eca07e6f6b37caed57fa0822..ddf2abbd84bff3423b1baeffb2785579d7007101 100644 GIT binary patch literal 12381 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≀TB6XcXLf>t~!bFy#+(dk$8 z``#Fj*pbs{s>D^C?!*-otgoN4NhQ_}oLp*4ZYuj7I5U5Te&`%|_)P@z1#>uNDyo86 z>A%W4+W#t53rMEuqFLngRzryQPD>`Ty2~LDSN&5wKa$nA0JF^_^ot34JYa_sVBPEt z@jFLG6aAO>O078)$(L5@sA=FUYX1L`kxjg~k*zDgs9->OkXwAIofL=@FPL=S)ZAG_ zs=5OQnneJmMTE%fj48=>+N0Be6S9P%fR6DNl}Jn9`A37a51cn*yK+mJ%%FUq!;Y*n zfOFAf=VP-EcdY@s1x4gzRtwPzNgq0!x6V_yy`J>oF5!;9T4Lc+P7K-aTw2I3!?>fe z1I}N0M4P!tKekvw0{gDW{C^LYR5FZaz5Ds8r@64J<@NWiU}w`iP`XB?jn6>B9929E^aT&ir%tH(@l>Ak$T!(Uy7d9-#D5<)My7EiqGUU|(JuL2IUm&pNAH3f@H45@xh^mdT2sT{M z4wd8x3ZN)nbJ17`3))&F=^yfevST)mtaRPJa#k0I zw)bvxB>bLNKW6v>sqH-m+5gLzWFh1KQx2H1eR>gGG-b{c+Wo`o0g?yoLLNq|XC7M& zUmh`t&Y!DKTCCw7Rbm*HWv0Jcd5E((zg&+~Z*f066qVjxZSZu0q z+7X4wlj9;`7aqMQU5|Sb9ex*^*pt-DCkvtgWY5x7A;QHT4=JikR zK2}XiNtA!i;DHA~WvpiYbp~8eOSx#HK%~5SGhUzh%FZnk`bs61AI_{|m}kMQGPQ{Z tQb{4RMNu`1^qQuW_EG-7khXwy-l0E<(W@j!{m%zbd8@AQUCuo8{{a0s?xz3% literal 23694 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 z z4+++*x1k9#?w^Tjt&8}rt&0W%u?aHy?`Xx2cO+{pt~g2hit`d;`jtv&%XeBzuWYcO zmKGZZC|eQ|%CcI<<5Y-D&CDtqerj2mT4wpni(;iscl6G`^ws=SOC(`$VS~UvZGZZw*&H`!Rk`Orsz7oUpiZ|CS}MQ=5@X!xad3 z2NTg1FRyBXr9#)UsJxrW=Omn;k6cN;!Q$1{MSTSPfb(}`s-^w`d-_e~fX-_NwYtfB zx0P-E?F#(1y%`VMOnSK89>Kf7#Ei@<1EDV>a>mB6Zd7XAGqo2p8t&Xv|T zjif{TpO5 zcz-4c6s)=uM3SIwOFu_&eZ+SSEfse7`$>e>8pz-D6L>}!WeXB#Nh#G)|9jcZ#~0=8 zm$pqBQ{de#`vWFBUhX_YitP9Qd&Ji~`ez1z&?>)Cqt!Sf5C8W!h%%G0&$EbboGytp z5EMHV>&oF0%l`IH35Gy8?N=|j8VyhES2F-Os-t^b^82S?TydCUPTq= zlme6R-^oHj+kJ*&$g}f#>@{O%B@58K9TrzWi`S(0eCqV4GZ>)Lw4cu?4nJJNm71NF z9F~-1nughb^(Tv;@58rUnjzu!w9^&i#@ma2)}~Rz zYAnRtM_0qEB7R(K?XSk=QRvzD1eu~5G{*(Hpq3jqhlLa{4kaa}3zfne?%#=N76hd$ z>d~U|B{Y$JR1^TPsn9bB$vFd0#Nbmj?YO^xE(*oJBp>D7qT= zu#)%VvrP8(P%$xo2=-f`;^6E6LxX1WexiE%7ljKS5>G8Jiy2^y%IOK_igV1*eRFyD zMfi)Hmli?1MpFm=cht9U5pwhb`K&3`{$RL+xc?KvN$-rt0ny#~Vq;<{y_ptfW~XKL z`eU0g%U5f@97RHq+CBQeNNvdQH&RnkR8%Ze6|^}!L&ZcL`uJ|y{;U(r^xPWnF3L8D?K1w=^gJWRDDYQ z3)ErA;`TB80#iT-1O#}Xs5R{H;K*j%TzpW1kB*KGYR6|z3JTG5jBbNYVXYqR9bTNH z?Zp!r2T=_{Ute`E-17AU3LclR3V9cFqXl30^|ZWQJS#|+B$=IETofb1SGl(DO+jlHj;6z&*s1?ieAx)K( zz}>N$RZ&%sxcC%FE>nIVcW+e4H&lVeg$0Q>*GCFFd3gmBB`gQU-<;$K*{ZXe$9GtwdEoXhK3Yqj z^+XT`J9`)#X)DhM4GxjElFxE8w}tyoy;NNT#BXP2(09TvIWxfYpJ~|j%QO-@W6kpl z@=J4#-giC1gTYf>5QKrp;I45@=A&A6m}7KOgj-r_m(D*uHC3c+IFd>p=)uU8=HPGG zD4Nt&P`((4X<=OCi#ZKd3G;7~_=-ic)(lMkKBE3kL94tZZ!Z6gnVDONc9=FUX8(g_ zZyUW9WyZ*R(weaQ@B@Lb-$?}5kGGF);J32fD`O0(mqJS{f~}ZU^?Xa$a4>h3u%N>X zhROnM%LUD($BLY2(X;$CP(sN%oYuB4-7o4 z3HxIDN%}owN}<@#V;}he@u96?z0KA_+p<)0Y%B|F?H>&sTVSa3L+)9d0%SMSnjTV8 zfVWbd%N6!P)$v&+F>yqL0^VfFpo`jFr^^1hf2f~sP@wXLTIxPdZ?LVEN0-f??Dt|7 zwt93oAYf~H2>EY{(a)db64^fyxPV`1k zKCc3hBc?}29JgeLh6nBN)f#?$G)(7m&adubprM2A2jJ`;C{2@|k&sA}bxN2Ed^O9o z524;XVChk#{M>X`ay{!)U}V_HTquaY!2LdwZECi-D(3Ux@{p|~-{@jpo70wo0e5z( z|7XE2XQEk7tHS@m#LTej_4q(6Td7e@f>p}0oE(oxCFVh8zqD=#%jG)Xl2T9~(Nij33elm9_$s4;A3y;T5dxO$pFedaIN;YNsY*&<@Mhi!|*P z78k{9S(M~G<*L)d!M9DG)~onU;0P`bDfV#v2?a3PX!1+DFZ@_agpq^h@m06u*t21KQ79j>&27DW&VfQ?FtaWsL1U^M)Jf7yO-Z!zc> zDlT78c0?Fe#AwL%wdxJHTIp};IfB_GTE2}RKE9J>I`dfnxFT~V+;*{jfG-^ifvU;M zQ^%}b%X&KRoCX$C7F7FI7t`yHftpfUJhgCea1Z$%4!w`^OE!)OVW>CImT2@6a>#B^3E&r#CdpXy~2rHR~qU$60!f zI1wW%f{YyKhGH?}J?-slF08$pM>VQGhXHa8+3%M)(jdU^-wmQw6N(z4)tl+{;PO!s zU{NJ10~q=xUH7{gW_>(cz%RT|e82wdwD@JVu!rT3k_ud59_8^mX6_RvyJ%jrn3|sc zF1TS~|8%%#G7~cS_ZHw^TOfjT$${4g=lS9!1b_QgDA=VRFf{#woSZi4a?r~^C~S`Y zPF%uI%`ni*j28`7()nzE;V1+skp}!x*CFSfKuDEkL>|@rlsy$y7g4`eJZ_~lWmyxUYtnE^D;jHG3!K_xxBcLxw`NSs#X)N4g z{bHAE#00quDW-SLC+=o53+YAKfdn35(9piSKe7?YsC*uON7cFuas@0lgG^Q1vJe8W z|9&YJ7*kxFEt_5ofjHB=^Fg8M9;2DT71GN3kK5${!mCUB$@T4PavHYymqb%L^vXp- zSwXV@Gky}nP=Z&n<7d|9gIB5PZtouTG3Vw#@~Pa8y+ka{;C@ckx)X~Wga2C~yvVGV zT}5B&<&bY#p6sSwHWd1@Oe>j8?>k&B(R)b^DwXGCWoeg`6=kI@sT-XsU*)Z|9ME}+ zJOV>Dz&iJzre~+ealD+Pr82qqXvnEea3NB!US?iR&3jWTt4&6FIRPCce}Dh+$fu)c zCrY;yUqson2?Nxwj5!GITDU)6yj)SUVjnD9{uZpq>@;>U`UFX`3!nXaLMfvH1Elf! z0PW6ql>U*DY&JT+IBmAT(Vwh7I<+@cP6 zn3h>(DQP-Kj3i{(QtB=JNMnm+oX=gFSpXPGC1N8MgCPX?-Nx)w7-V>XR!)dVtJid` zXXoN0wr!`evHGG5h zyy~(+KuO0Sd$fPJn>AHqKOGr1L{m7ImYCl4_#>Cz6D+Ne?txos@(!^Oo|}1fb+ymp z`Exn}9$r_UF9q{dL7gCRCnf9HIt2mdE*q=3*R!wJ$JAkAppuq!WYY-W-6m*!RAmic zA3fu61(7euvHhmmhzGA=`I=9nt4nZdVd67fu$cYz@jWFkYli3Jg^|2V^+TTZ*#z?4 zAx3*=Cs!1tSQLf(ySjfyUT(Z^6MMCn_r15j zgWNv$@(E}m`1!X?vG$s5&B@2Up*?eh_u`==xVt446L-5e$q-?H0MSo1r zcTK8VZJ8?<<$3M()JS!|mP;VVkT(jUemLEY-QVv$BJ!1V?`~CztFNN$r{xbOOd2Ue zt=zA5;lDEZtm}j9%G1ho`ThIj2rrhBP?*OF==rl`Ud+MGpp{o7tL5@GYM$Y(SbC(# z-31_w_xeC9%6g1!h>Y>Kc;fTlZiUo|0 zG7wjym8#3ZD#U5X>&i#q@!9$vmdRMG>m3bvGARP9)Y0zY-zi!^NWj8`Z8B2%e1hWw zJrON07u}PqV7N}kMgFSAoKxg(@i>160ra_SLneNsL%Oa2+QZBIHt{tDC8M|{G zZS`ix2_gdVICOpq8{km1o4HmBl{ML%<#U3SQwjWAAj6POxe$x(%g@gGD1RByqRnQ2 zxQMOwkELeZTgulE8(P58jt5EN>$zCBvj+~%*GcM-a4M{ccw+wV^#JMSV9mfAlhV>Ix>( z-Ao_NUmtVDwP$(LrC-zd9p8<4aLc!;!U-hH*zY~4M64ecMqZp&IkScv60Dy&u;HA2 zlh&onyc=(Cj<+|TnVoGqJUQNXoX^-7{@_N-Gk?04wSb3?er$WwMex{wymr!h)imgN z9WD^j%(8I$%~#+D1y1!tCkL-04Lf_c@^an*WV&UO4k{L5$|Wal(bbi2n_oRiEtveN z`d@Lpy;tET)?6U2v7-|pe^NO1JkvtGRp#n)K%v(q0m_xwhImigv(xI9(4C~IhHX+) zs4Nm6Yn!lBZ1TP1{ahYdGCS!CE0$*_+`FGw+$xBp-ie;gYU)0EwhDTJzJu9d++M=j z%TButa;CjbxZr+Q1=`IGl&PxZz>}V#^U`t~XUovUxT1@e$JuVM__j~FyVr5!bJt}) z$RoY&wouC^!;r;D2MHZ}zf23%u&UKc@Y^)-p&=U1+0l3SV|3CRUI}8FnEedrCHkHs zHs%*EzM3j4hRRaXGZY?^QRb02+Aa>)b0RK(kIh&rH?;rZzGKn6gczMCno{CW>r^D? zP?qb)bZ#ecMB#E|BWX^2HdB^PAR5iglywk!zx!cml^~`~l&>@!|7k z`;qnRh_Dc%er0XuWc4jeUz!g+EAB^#^0J=EKU+rKO(ddJhZ}2)RT!d!wHGWGT&gvD z{!>=@JF4A=WVGv)0-Y0FA3>gCg45I0%Qd7&kRlG`>~nY;J>ktZOz9&f87rV&?472i z%xXI~@+vkgqyM>-t1Hgkoy+^U`J83-IJ`Q^bIl{_@^Ftbdhk8kvsP~EN%AQ{3m(i!aR%!E}ShI719gezY*2NBfpe-aVCRB>D-9@nMSd6Ty^F5)LTF>7`R(R(_5d1wjGe)T_aqFM z0iO4)o&yfdm7oFV&c{u5^~kxv9r^B}%S{OCrXlna^hnFC(U$#a(Z0pnbX(V)rV$4x z9@7R0$Y8ToEoeUR;D=w&+@2GM^hglqO!ng|M!VM1$@{_AQt8}M^Bj#-1SYPE=qzk3 zG8KP&*ka!X}2PsylNaLl&X{Ev%NMCJ^V<2)rRQAOc z&YO<>(?rSi*tx%Jrx3VPQc%ez^KjWm{EL;tC4TDxP`aBNCd&y&mroh>(`tSNYO7#t zPhmq&#CLs7?=4arD+nI$BNa^ZPuwS?>8BpkZr@={dNv%-Z4H?loj=QfhO zXYJ3C=eE30N?yld$#_aXx*}e^3Y|MxSd)0MrP;0I$#}p=#~ZwVU{+LaAQ9CxYv#BJ z7-_t9ArZXUnD+mj%e|*z%4T#R-s^4GN6Q~85``dtMwV&D`(=mMEpF|k1*gkwtJcS! zhfJAD2fa5EJKx9A&dNsWuux8L78AHjS(GZq(D0AhdWWzFC2BnPe0FGFHML-QLVRfl z2m8}~4OW~7indoIKMN<>(%$`U#%6I|z)o;9isMrcip0+Ag&_`P3dYp(p@|3CV%RG6BliNU?P@`LfgUnVkR8Kt zD8u4s;yX8qTkoZR9-lsN*uiCxuz1EPi9zw( zv=8+aCkkRo2~NdFK@rr^VSQWg-yAnGoGD#5?!lTmyp_~$rEj__j@RdtM*yW(+ySDZIgs9s)83kftuQc>D$=uPAdCgIvqSMV=XO^s6g4BofU(Qb!l=>goc-`TO~mtRGC9 zu}#b~kr!{ACk3?}MKs439i5!yMn!#4t#gkrS+uNgW^T3Ep+&{V&%P3yr$GNU5owI> znNJ>B`bZSA$xdcJd?#5l@;zJNEgV9&%e>1HMl-TA@DmM97__qJn^&)jFMJv#=5|Xl z50{K`m)-C2N)U?8jIE;%B6C^X@gVOr9$!MGC%e;hMX1H@G}Abmh}QTT>p0Pj`7IDB z1DW+B8MMkkzlhdOibJY$Qbdt7QQ*s;+gq|@#_{UDJ_?U{^1OOI7$|##OFmfk^o2{@7{%^``Aw} zH~`o+TY+MQQtU!o5M##tMT$vTL^l(a?vw`qYSn=hdMXD^)4-hE+#a`x(EJmRRcZg{ zjUJ6kQ(6Q45xch&POGkh@wA$%Il7{warhUQf>fPA7z;BqCcLG3rS#aC6hP@r*$yvl zx=a)q8QJ6?B_X9ae!GC|%I`Qg)p1E;!0u{L_rS1FD7X|mMt+}-|zG{1`Nav(vU=UyWQwTxwFfTiMR!i~s z?|OGyWKTgR3{(ew5x5Edp$4{Ux?72ZbHoEon<9L};So9)HJ9%b&&$hcN0JX5xDT{o zOs#(?H`Do(&x=ZmD~XI^2HZosgW|wI@D``;P1BMjOf3X37rTfoA6(Qe_hf(2ZEfW- zHF+Nl3kNTI|C5jDx=RJ~e{NH$4ySy^1C2}2YmlM>@NmKz8yi0-VH+JF<^ap4N1q5n zl{N}MF7JKp1!r|=vn-h}kslnRcz$-F(2~%l;8C%!Dg9(_ZY{~f@@eb@cmK-%N$CD_ z*XQYM1O$sus!B?Q=fc8YzQ_iu4HQh(yeDl5*MaM`gCs;m_+qMML3lr%4}C4BOm=+s zD*wqbhM666T1WF%_bKMG=Z?K+-N`fCWRZ_r$_=8D?#Lf0P(uFoq(}`a=e@=eib)%4 zGD&NE2c#rqfXvMB>x_X)%M4@vn(r?HMVXFM2V9|C95c+$$SVtl)zpDGFwS3+jX;%^ zhw?Kop?j}IHYdgPS{bv&hZ65~xC#D~)T<$qy8YWSX?(l%V9T<9DUNK2V8$e4j;{z`W`iHforJtJheptI=LcMx*t;P^ans~ANcBPJ)g6Jen$8d2i#*4@r`kMWt3xMlrAjT8HZHVy%$4T1FBMYQ89o-!p#hv_qIFy#c`Y2Y) zh7={FCKvHRr`VTls!x&RC|qVlSdzbf@*!wL@$YGnyEFsv4zHQe7RNMY61=)c+;)+*A}q9UrP+YU+j z2x7wekq4SSn6blG;v#ih+tAz*S~NWA6WY<^`!hK^hEN*lUKOX4;|3?%?lFpJN)rns z$?MY6>f!Tlo)uR_hOyfQ0xT!->X!;)mJgij#a)Yvc8%lJ)pZ(faNa^(tT2l4$&_?vLK z8AjSInf6!3#|?upr)S1wc4BJy0(n}HfihYgb{zjD_~%XCsf@O2QyK|)9T5Eg z((p9I5Z^EsV3nF``$qQmhfHI}7dlWUx5Gx#N&N6Q76Il87N3X)fA!z`I?MhK4E?$@ zn!b%WpkFm_{yz*q$01V6Umpe3*LiXX!+$@NPOI5wAN=#>Uxg9^qLRHyT|`C5E9?MS zI9Q|=f1w)$*=7FA#pCa~LJTe7WR6v2#A44^1)3=)m;j*WynxYaF zAtNF2{;25!e_*6P*^Y>Zr}Z-P`7ZBHUaOVy;E|F>^)pWWl8}jsN%cw{9~&%UG2bfQ zCH(IwR4_n8Orr8m-vX!x2Ge=kx30J-*yuA^E#`$4;-8O}_-3hziLV-up%(~9p#(xi zUi^t(2P5>G>k}NM*=R%rDgkVKB!=UpWW4otR#o|$r1SF~IdgSx2vrP})8oOLs}JN{ z;8HJ9Znr^k)3u}ICJJ$FYTg~%le52@5=&%kGfyg~PiXBpV6(~=@+5UOR>lNhUXJ-+ z813F5iMa0{-{Y?tzN8>yRb**5TozVsv2Rp8IW#Y<*Yq0BS2J7)kBls&g}C$F-HE_g zj+4Q9A{zS*39N*op!{b4w%>55gGH2(ghUA31ZuYew6>dFKce<+i2E5EiEu$&-rshI zazh5UXhcWZ58Qv|M#{?D*DM?x2vF>pFSW!YBO{xPHd}EGCTlRLWp)p*G#yC2eg8fW z!o!jJ5$Ea}4==z=37Bs3zBxNv(|!{gH6{~+>wz{gcA6!gI8=j!gCTOwd-Lhlt5>p4 z(ro_z^Tr2P=_MK2**b}L75?zB6K3ml*^z(L7p@z z9wVBK@!bMJU#jJ!db@io?+|TmzeTFMyw1mwp9FKxw(T$*>aBhD6F93)HQ^~3By20)yL+tW{7iclqO&Y8o{2(~+!jtWOL<4Q z0Dr)ORhva3vMBw2tz$pW5kc?)t2vR_9bMPyIVFweXHd%}_q2NJJ`G*x^%0u} z`I|jo3kzD;>B|WT51nj;kGQDD!FfOrrpXG_%Q#YPzu1j?(+uXcsgHM-bwiAKvA&*1Th~Z1^@Q z)AKj*f!#O9PRNUYYl0lvhpv@Dw_^_($p)9u)_8^Zc)5zf$zY!4WqW&ObouQHW5^xR zVp6Psdvhw_!WBziiaQ+7NzdiBq*D!^R^;NYsXMifF=JB=3sja!exy%`-V1^_0TLam zj|S8-gxt4(M!>B@EJ;hH&4zWpx*M_W9>bUDc>mc2&7iOCsEAUB3tH@vuN#Ys=C73a|gBn2ES?K^7TWTL%%bx0gsP zQTrf9Fe$XyQ(Cl{aN%*Cf2|Zl(7^<9C~R_|#n&V!C5fIrm=u*>>~XrfxjE;| zKo1OS@qZWizE7)6tpwVd4R~EtuLoHIF_*95wF+T7uDSf4esfJ7EJE793}6&0wzd#N zA9-(lQZO(6R?mjZOXmfIMu>eMT9|J%_HB8@%7-fVdc|{4MbgWQPotQs@Nmf;ASET+ zDQ}n~Qbl2DWoGB9kWL;}aR~<7rYEEJtw_SLe6w4QN89=-?m-mtQU$iaNWbVQm?EKH zDyF35@+Vv(S#xt!tp#}`f!x+m9mEjU`4Q;_K&a5B`MhbSH^B9+ zf#!>c6IGPFU;c+Sk@lvnp4We15(L=Nd^JX@=Z2xP(lXsizFLtWQ-Dm&N>RuPD>v$s zqlWoAp*dk&twrb0QLqzxDanp`CGLkPqKkop#I3j!(B>ndMB&oX|^`$+;2lax!eE~uH>%wM~15TWsG zwo`nyCqi(K`s%b^d#(i>deZKZ{l}IR?!R>MR$(gAPNpv$6<1(N;e>*w_53 zn|m9#cGaCmbvS1`_c{SzgoN13RqDUz8-u5*1~s#Hft7*b^V>=-`jq9WtuunsxXqeg zV1r-z<@84Ajp02f*?ynU{bQ>a3fPVFzS_>#_*;^<(>Ip84Ys`1S_+SK0KIOu2MoA)pe$sN+3Hz!X^tttnL5S>Cn z4N`a~zk0Z(ANBV1$e!<7C)<%LKE!nV2wJAUXF*Bl^t$?0X;viU!#N-QyxHplZp8cU z-(0yJA$dl+efg>M%1|l;z=kkbGLX!K_q0Z+QC=e^W-u5TEZ|4DC@N}@a9hFBBNU7oRH`T_bK!tcZ32!@xr-|^fWAn)f|3xxG{D`R z+hW<132|B>@_vhSbhCF@tvKg_5s`;W_uzbclpO1Ba%N#k;{N)0Jar^Lcjf=|#x|q!|T7Ab|`` zK%^4_1OkK-Qh@I;?>Fzv-}B>K&$ag{&tCUh&s84Y933!t>cst&q_84m{oZ}`4gtin(fz$rKWgQFEss6AZ2B`_75W^zrbj)g)k~?}A z-YWQ!I=oK!Hng_E3*?2QAn2&3wyjM}l!aRPkg_i!hJtMh?w{tgGhEGjC)7GMfW0Ru z-~)SxIGUVU2KBCO_^CKGF#YB_;NL$kT=Mksc~!IKJr9v*DKAS)+_Kj45a|Ba6J_gw zn4=8@zn70ZabIq$ccvJjgc?gn6=-vuy_C@e#_uT&|}WUnq>hH%a4Mnp;*^sj~$i56IKz31&74EfXrM@vGO;o%W!sI|tI(g(-p~0hx4-OLXK3!y>cy`)$ilXW z!-jXr*r)0h(XZ#_H5!OzP02=p7nO*SI zLZ>kvz%q#a4g&n7v{moC`vb%P|HS7fZacJB<(~bAh%Mq>JQa1AOK&As&QO>UDiOO&kff-yf}-NHqr`7R+XQg6VSjJ`E8CDM1G2J@lMIpXQl5clw!Pv}26^oY#7R_1 zTD?g5>PAHbDl0D<2(YcZojDqSvs0hnO*(SKEtXr_?_WLoX~V4^R>*i`1_U1B{`7m}fW3mBurWTTYwSBG*!WYt+W z;_-PYYrHL}AW3KnOS;+;xHbO)jel}2Bole{Mon}SZB1rWJQwpn{Fh; zLf>gb@FIUpX!A@s(;#Sh$=27>;g=L5evbeI1qjLSIW1~RZh!*IKrMx)E-YbvlXs!y_n*%b?c4LhTs#`R=~YJ6Y?XXfFU2~I1@g=6lcc8 z-L7uVZ5OnF&|p!B+K=`QtAGNGrw-Eyt8Q{pa+zs^izJrz(V#Z z8r2lY=c|uCKr>Xb5P9%lB7DXs4`dG?AMTK_6jxoUn%XMz~97TbAkzNriIFiX?6Qa3A?46-LMyC42={au9pP;zfYl z2a`5$)AuhwU2i%1oRD?7wn_?cY?(L!C(f$Ioi4v?Rmo-tTrwpT(?eF=>b_rbuT&Wh z7j`#6E|F#uPt}Z0+C^I$L%T8uZ3=9`Nj@%lD>Vgks#y&F{bUW7r=0=T0}if>X-T07 z4AN@M*-X`6e$q_!4fh)aDKHLBu%lm>)t|n zbEU__khTK^Uq}brJv=o468RcyOCgrE`s@aH?x}2I?5ZhW&EN*Xknh^+sFoH1C*OY6 z`3i-B9vvC{-4hBFAp=8Q3-w@OHjHl4Y2^8f^;wDMLr@M9HjkPG6&@Q|+)7E{`?6S& zGH5e#L;P0A7O3ytev-M@zO7;QS;2H6!31M_ozXRG6r^;Nwf;x~G;Ih_rGc?{rEMc*WP{93q zI3z18yKG`c$vAU6L}3_03jlq;&1{1P9tQ4h5HGvY7ncH-`(rhe;A}G-TxAs0=_~wK z9_D*G$)#sx5K}a>pTa(fh=3}?JXH=u4vl>VWsxC1_6JqMuZGs?W9r($E%K`$%qrarZ<2`)lpJb+}K+1-05BS}b zU5GUUl_ly{T}Fy?ah&x(lehy-a5q_3WQ~2@%7J+|_{(#3qgGyA=N<$3#Z!%Y(_6Z} zB);QHtJpK_qu*5sHFY7s?<>-!mn7CXP+U{%1Jx;+ccQPWMl^fV zB`%f9G(-6@NJ^)4z71gx)q^*gp*eBcWB-V4Rr2HGz{-m#)ljJ}w|~ zcfZFu-;bG&((FH#lNb8;Q@y%PL{#vTNJnty!Mr}Le^cR`^2Cg^i;Cp8T7+T0+Rq;w zy@&^!Sp`kZS5ZxA6?r^$n4do!eh&dBN|&&Q9{FqpWYvi#{;Use3%PMxCbP>ZsYzT( zI;bO5aV$S#GE?^f<(g9EeUN4%rm3mwE%Xq%^a{>yaY-&L+r3%8t!#0Mr?t<1q%!vd z-K{&QmwHi8WExIu-`O!jEY|47XA>D;E7ER=J zh98S@U3SZ={M49eCDQeg5#rI!GfYcJR5!gjbUK5fWAX+643ipm*|N@h-K4!3YHn*+ zy*D;uCP`S1jXS0Kv^8_spvW>-6V#!D#f0)%rCb0E?g~HCWT0h*;?Dz<>!f3di}tAN5VD| z>ZbW2b^}!;voZJGp-EtM-Gi`!k@igYt>Z6pZZ(!8pCfw=6vMZhu9s3_)t*3$Nlq|| zM``Xilg9rzLA-A`A1P=gVS@<+C(nzeR<4!4ElkzzdUo!uS9O(GxiBRm7n;dMSo-ZK zI^S3by;&>Uo3V!^9A>mw^j^BIzV3^q-v#evq)Bd6b`9&*6rS_aV{o$z?cYqMr4BlJ zu5==A2tKhN5FU*}I(c~bg@y(lEsl3fPgXR%hQ1{s7iCUlqRgN}J_e(8_O+#1h0c1g z58CfTtcTo!0w@MWwnI{+%0|c_+(&gn(?lV1KSO)v1gRzq%1%`^aHVRhcVP=}(8h+n z*oZj&>!(yqlb*%Jp)M7)7y2(Na?F&()1c(!>rCy zKFOOnnE4j4iduQ*rT^aT@Z=^q^RJhqf8_7o%K?n6qKT=5S>XvC39Y#1TVAl0b)aol z82)C~7fL?vm?ub|R)Zs*T$X4bWOiSzt#Rf4em}ni`g=yfR|j>L$k)_SFEwZr z^iW7e?vm!Lgci)~3r6*R&O1Zo8p}5swOu7dY*LL}x&&IGAT&n@wvY>OIS7)%`Ak^vh69r*fej zeYg(gh1{w@E0MpnV;#QK!(3q*5gLh)?t5l$n@yH1w~aYO#!)6BOTvEol#fXb3C8h0 zfA&n|B7}@64%NUY+rVO53qrSvxa2|C#=~O=$t@@GADTTMx4ujMv0GN8m)IxU9{M@? z&WnymANL6S?hYk6ANJ+yofjSzo4Xw0>nyi8*t@o+^5g>>GrWwn2%eVUS>a}=xM zT!B-1pCZgCJ){*nw6Q`_eRNC ztglpmj-s0n5JtTl_x|c#6)k;PfhyI-rdK=3x?JDKf8d0ZoK}bMydw~;I7=`!}aN25n?5R1aCa?ZOVA0a-7>Zfv`9Nt&&xyMF znb)IOghAl1QFX_Ti_Fbil$l>;&-Ti_w54f9l2`YE^w!M0Q&EMXM<+io4Po`(hZwLy zCe)9Pc{Qq`X`TEIK-=NF-oN9AX2Dtni&vYdDxV9?&t2 zuzrABcLP>y+w;^OXU{-sou&tX)X{?YYa6O3zfu{(Pt*bWMbGvipdLOw$0<1L z1RejuJ>KK{6DrNsEnVn=98zBige$>aOA0Yz3=a-!6?eETHTXW_XH)!1wfw*11|H1D zUv9u=`(oOh#BxmCF+mYWaq!ZYe&j45k3I_#`zCso{a~|zJcrbK5F<7`fsFc3IyW}oF4oe zGsol|2ii+5 feature/ # - diff --git a/.github/labeler.yml b/.github/labeler.yml index e925d028..7bec897c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,27 +1,27 @@ Documentation: -- changed-files: - - any-glob-to-any-file: '**/*.md' + - changed-files: + - any-glob-to-any-file: "**/*.md" Feature: - - branch: ['add-*', 'featuere-*', 'feature/**', 'feat-*', 'feature*'] - - title: ['feat:', 'feature:', 'Feature:'] + - branch: [add-*, featuere-*, feature/**, feat-*, feature*] + - title: ["feat:", "feature:", "Feature:"] Fix: - - branch: ['fix-*', 'bugfix-*', 'fix/**', 'bugfix/**', 'fix*', 'bugfix*'] - - title: ['fix:', 'bugfix:', 'Fix:'] + - branch: [fix-*, bugfix-*, fix/**, bugfix/**, fix*, bugfix*] + - title: ["fix:", "bugfix:", "Fix:"] Next-Release: - - branch: ['chore: release*', 'release-please*'] - - title: ['chore: release', 'Release'] + - branch: ["chore: release*", release-please*] + - title: ["chore: release", Release] Command: -- changed-files: - - any-glob-to-any-file: 'src/Console/Command/**' + - changed-files: + - any-glob-to-any-file: src/Console/Command/** Frontend: -- changed-files: - - any-glob-to-any-file: 'src/view/frontend/**' + - changed-files: + - any-glob-to-any-file: src/view/frontend/** Theme-Builder: -- changed-files: - - any-glob-to-any-file: 'src/Service/ThemeBuilder/**' + - changed-files: + - any-glob-to-any-file: src/Service/ThemeBuilder/** diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index dac6c47d..e9d17254 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -56,7 +56,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af with: - node-version: '20' + node-version: "20" - name: Cache Composer packages id: composer-cache diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 7cfcc2fc..a5106c0a 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -8,15 +8,17 @@ name: Labeler on: [pull_request_target] +permissions: + contents: read + jobs: label: - runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" + - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..8442c71e --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,54 @@ +name: Lint + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + mago: + name: Mago (PHP lint + format check) + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Set up PHP + uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2 + with: + php-version: "8.4" + tools: composer:v2 + + - name: Cache Composer packages + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: ~/.composer/cache/files + key: ${{ runner.os }}-composer-lint-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-composer-lint + + - name: Install dev dependencies + run: composer install --no-interaction --no-progress + + - name: Mago lint + run: vendor/bin/mago lint + + - name: Mago format check + run: vendor/bin/mago fmt --dry-run + + trunk: + name: Trunk Check (yaml, markdown, shell, actions, …) + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + + steps: + - name: Checkout code + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Trunk Check + uses: trunk-io/trunk-action@04ba50e7658c81db7356da96657e6e77f220bfa3 # v1.3.1 diff --git a/.github/workflows/magento-compatibility.yml b/.github/workflows/magento-compatibility.yml index 6a0f5543..a4b8fdf6 100644 --- a/.github/workflows/magento-compatibility.yml +++ b/.github/workflows/magento-compatibility.yml @@ -18,15 +18,15 @@ jobs: fail-fast: false matrix: include: - - magento-version: "2.4.7-p10" + - magento-version: 2.4.7-p10 php-version: "8.3" - search-engine-name: "opensearch" - - magento-version: "2.4.8-p5" + search-engine-name: opensearch + - magento-version: 2.4.8-p5 php-version: "8.4" - search-engine-name: "opensearch" - - magento-version: "2.4.9" + search-engine-name: opensearch + - magento-version: 2.4.9 php-version: "8.5" - search-engine-name: "opensearch" + search-engine-name: opensearch services: mysql: diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml index 891a0270..b81655e5 100644 --- a/.github/workflows/phpcs.yml +++ b/.github/workflows/phpcs.yml @@ -22,8 +22,18 @@ jobs: php-version: ${{ env.PHP_VERSION }} tools: composer:v2 - - name: Install Magento Coding Standard - run: composer create-project magento/magento-coding-standard --stability=dev /tmp/magento-coding-standard + - name: Cache Composer packages + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: ~/.composer/cache/files + key: ${{ runner.os }}-composer-phpcs-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-composer-phpcs + + # The coding standard is a require-dev dependency of the module, so CI and + # local development (ddev phpcs) use the same pinned tool versions. + - name: Install dev dependencies + run: composer install --no-interaction --no-progress + # Standard and file list come from phpcs.xml.dist - name: Run PHPCS - run: /tmp/magento-coding-standard/vendor/bin/phpcs -p -s --standard=Magento2 src/ + run: vendor/bin/phpcs -p -s diff --git a/.gitignore b/.gitignore index bc7704f3..732980ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # AI Skills /.agents +# Composer (module dev tooling) +/vendor/ +/composer.lock + .vscode /magento/ /magento-temp/ diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml index b40ee9d7..311401b7 100644 --- a/.trunk/configs/.markdownlint.yaml +++ b/.trunk/configs/.markdownlint.yaml @@ -1,2 +1,6 @@ # Prettier friendly markdownlint config (all formatting rules disabled) extends: markdownlint/style/prettier + +# Allow repeated headings like "### Added" across CHANGELOG release sections +MD024: + siblings_only: true diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index b0fc6613..4e078e1b 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -21,6 +21,11 @@ lint: - linters: [yamllint, prettier] paths: - .ddev/** + # Local-dev container images (ddev-generated); health checks are defined in + # the compose files, and the images run as the upstream default user. + - linters: [checkov] + paths: + - .ddev/** enabled: - checkov@3.2.499 - actionlint@1.7.10 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3efaaeae..46882a42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed -* **Inspector CSS Migration**: Migrated Inspector component from Tailwind CSS to pure Vanilla CSS for universal compatibility +- **Inspector CSS Migration**: Migrated Inspector component from Tailwind CSS to pure Vanilla CSS for universal compatibility - All CSS classes now use `mageforge-*` prefix for namespace isolation - Removed Tailwind build dependency (`tailwind/` directory deprecated) - No npm build step required - direct CSS editing @@ -19,389 +19,340 @@ All notable changes to this project will be documented in this file. ## [0.22.0](https://github.com/OpenForgeProject/mageforge/compare/0.21.1...0.22.0) (2026-06-01) - ### Added -* add CMS block identifier support in InspectorHints and tabs ([dcce46d](https://github.com/OpenForgeProject/mageforge/commit/dcce46d48b9b9deedb02ee82014719da70468561)) -* add Escaper dependency and improve JSON escaping in InspectorHints ([adaa5db](https://github.com/OpenForgeProject/mageforge/commit/adaa5db94326136ebaa9269ffde1a9b58a0ca3f9)) -* add magewire support for Inspector Hints ([f47d497](https://github.com/OpenForgeProject/mageforge/commit/f47d4976315c0be2e9b5a23b08da4ad1fc679b66)) -* add new color group styles to toolbar ([#188](https://github.com/OpenForgeProject/mageforge/issues/188)) ([fc4b7ee](https://github.com/OpenForgeProject/mageforge/commit/fc4b7ee8f6ae90a0d9d560c727339b6f56b83db8)) -* add new color group styles to toolbar ([#188](https://github.com/OpenForgeProject/mageforge/issues/188)) ([3cf6803](https://github.com/OpenForgeProject/mageforge/commit/3cf68032c635820abfa04912116b90a6999f23ab)) -* data-mageforge attribute handling ([35975ac](https://github.com/OpenForgeProject/mageforge/commit/35975ac997b7e107d774e666ee3f7f1e78f19ef6)) -* enable phpcs annotations for method arguments in InspectorHintsFactory ([e8c2ee3](https://github.com/OpenForgeProject/mageforge/commit/e8c2ee3d3d4efd98af21b2b85be1c465cd340b4a)) -* enhance block detection for PageBuilder elements in inspector ([0121ec8](https://github.com/OpenForgeProject/mageforge/commit/0121ec8174e1e98d09e85832216b91ed1ef499b6)) -* enhance InspectorHints to inject data attributes into root HTML elements ([0a9cf42](https://github.com/OpenForgeProject/mageforge/commit/0a9cf42980a7f95627ce3cf0a5a9a18b128624a4)) -* implement InspectorHintsFactory for creating InspectorHints instances ([3a27262](https://github.com/OpenForgeProject/mageforge/commit/3a2726230749ba25c56c13d102c763e42ff68c4d)) -* improve accessibility and functionality of inspector and toolbar components ([2873970](https://github.com/OpenForgeProject/mageforge/commit/287397062c19afa157f8e7b486319db7fca62e39)) -* improve accessibility and styling for inspector and toolbar buttons ([68b6bea](https://github.com/OpenForgeProject/mageforge/commit/68b6beacdf6743f2bd26addbdfc108a21d4a8ff4)) -* update CompatibilityCheckCommand to handle summary directly ([57a0263](https://github.com/OpenForgeProject/mageforge/commit/57a0263144329bd8e29f61ce8e2d894d534ec94e)) - +- add CMS block identifier support in InspectorHints and tabs ([dcce46d](https://github.com/OpenForgeProject/mageforge/commit/dcce46d48b9b9deedb02ee82014719da70468561)) +- add Escaper dependency and improve JSON escaping in InspectorHints ([adaa5db](https://github.com/OpenForgeProject/mageforge/commit/adaa5db94326136ebaa9269ffde1a9b58a0ca3f9)) +- add magewire support for Inspector Hints ([f47d497](https://github.com/OpenForgeProject/mageforge/commit/f47d4976315c0be2e9b5a23b08da4ad1fc679b66)) +- add new color group styles to toolbar ([#188](https://github.com/OpenForgeProject/mageforge/issues/188)) ([fc4b7ee](https://github.com/OpenForgeProject/mageforge/commit/fc4b7ee8f6ae90a0d9d560c727339b6f56b83db8)) +- add new color group styles to toolbar ([#188](https://github.com/OpenForgeProject/mageforge/issues/188)) ([3cf6803](https://github.com/OpenForgeProject/mageforge/commit/3cf68032c635820abfa04912116b90a6999f23ab)) +- data-mageforge attribute handling ([35975ac](https://github.com/OpenForgeProject/mageforge/commit/35975ac997b7e107d774e666ee3f7f1e78f19ef6)) +- enable phpcs annotations for method arguments in InspectorHintsFactory ([e8c2ee3](https://github.com/OpenForgeProject/mageforge/commit/e8c2ee3d3d4efd98af21b2b85be1c465cd340b4a)) +- enhance block detection for PageBuilder elements in inspector ([0121ec8](https://github.com/OpenForgeProject/mageforge/commit/0121ec8174e1e98d09e85832216b91ed1ef499b6)) +- enhance InspectorHints to inject data attributes into root HTML elements ([0a9cf42](https://github.com/OpenForgeProject/mageforge/commit/0a9cf42980a7f95627ce3cf0a5a9a18b128624a4)) +- implement InspectorHintsFactory for creating InspectorHints instances ([3a27262](https://github.com/OpenForgeProject/mageforge/commit/3a2726230749ba25c56c13d102c763e42ff68c4d)) +- improve accessibility and functionality of inspector and toolbar components ([2873970](https://github.com/OpenForgeProject/mageforge/commit/287397062c19afa157f8e7b486319db7fca62e39)) +- improve accessibility and styling for inspector and toolbar buttons ([68b6bea](https://github.com/OpenForgeProject/mageforge/commit/68b6beacdf6743f2bd26addbdfc108a21d4a8ff4)) +- update CompatibilityCheckCommand to handle summary directly ([57a0263](https://github.com/OpenForgeProject/mageforge/commit/57a0263144329bd8e29f61ce8e2d894d534ec94e)) ### Fixed -* simplify warning display logic in CompatibilityChecker ([41a895f](https://github.com/OpenForgeProject/mageforge/commit/41a895f44097e0d8122201f72155dfe16485819f)) +- simplify warning display logic in CompatibilityChecker ([41a895f](https://github.com/OpenForgeProject/mageforge/commit/41a895f44097e0d8122201f72155dfe16485819f)) ## [0.21.1](https://github.com/OpenForgeProject/mageforge/compare/0.21.0...0.21.1) (2026-05-15) - ### Fixed -* cast render result to string in InspectorHints ([#187](https://github.com/OpenForgeProject/mageforge/issues/187)) ([c857129](https://github.com/OpenForgeProject/mageforge/commit/c8571298a7958aaa4e8d921d5a999897d1a08cb0)) -* update shas and update to node24 workflows ([36bd346](https://github.com/OpenForgeProject/mageforge/commit/36bd346ad8fc7944de19505796fafc890016b0e3)) +- cast render result to string in InspectorHints ([#187](https://github.com/OpenForgeProject/mageforge/issues/187)) ([c857129](https://github.com/OpenForgeProject/mageforge/commit/c8571298a7958aaa4e8d921d5a999897d1a08cb0)) +- update shas and update to node24 workflows ([36bd346](https://github.com/OpenForgeProject/mageforge/commit/36bd346ad8fc7944de19505796fafc890016b0e3)) ## [0.21.0](https://github.com/OpenForgeProject/mageforge/compare/0.20.0...0.21.0) (2026-05-11) - ### Added -* add toolbar position configuration and implement in UI ([3f331bf](https://github.com/OpenForgeProject/mageforge/commit/3f331bf0f0cdd8e9b3fd5be6e9d41506dc281db5)) -* health scoring ([#182](https://github.com/OpenForgeProject/mageforge/issues/182)) ([89bba7c](https://github.com/OpenForgeProject/mageforge/commit/89bba7c62b3755729d1ec169026c72aa18691f7b)) - +- add toolbar position configuration and implement in UI ([3f331bf](https://github.com/OpenForgeProject/mageforge/commit/3f331bf0f0cdd8e9b3fd5be6e9d41506dc281db5)) +- health scoring ([#182](https://github.com/OpenForgeProject/mageforge/issues/182)) ([89bba7c](https://github.com/OpenForgeProject/mageforge/commit/89bba7c62b3755729d1ec169026c72aa18691f7b)) ### Fixed -* exclude toolbar elements from tab-order & mark overflow-clipped focusables as unreachable ([1484347](https://github.com/OpenForgeProject/mageforge/commit/1484347108235591ae5e1798e232fa7af7ee6c11)) - +- exclude toolbar elements from tab-order & mark overflow-clipped focusables as unreachable ([1484347](https://github.com/OpenForgeProject/mageforge/commit/1484347108235591ae5e1798e232fa7af7ee6c11)) ### Changed -* centralize inspector configuration constants in Inspector class ([b7c9027](https://github.com/OpenForgeProject/mageforge/commit/b7c9027c242ba23dcf2c69214ce52a41f7dbcfa3)) - +- centralize inspector configuration constants in Inspector class ([b7c9027](https://github.com/OpenForgeProject/mageforge/commit/b7c9027c242ba23dcf2c69214ce52a41f7dbcfa3)) ### Documentation -* add frontend toolbar section and image to README ([1a2fb75](https://github.com/OpenForgeProject/mageforge/commit/1a2fb756ecbd0003704e0d5a6fa62bc267624f5e)) -* update toolbar image from PNG to JPEG format ([1e1bafd](https://github.com/OpenForgeProject/mageforge/commit/1e1bafd824e62ce1ac4603346d5738684997b95b)) +- add frontend toolbar section and image to README ([1a2fb75](https://github.com/OpenForgeProject/mageforge/commit/1a2fb756ecbd0003704e0d5a6fa62bc267624f5e)) +- update toolbar image from PNG to JPEG format ([1e1bafd](https://github.com/OpenForgeProject/mageforge/commit/1e1bafd824e62ce1ac4603346d5738684997b95b)) ## [0.20.0](https://github.com/OpenForgeProject/mageforge/compare/0.19.1...0.20.0) (2026-04-26) - ### Added -* add additional audits for accessibility and usability checks ([2dfea0d](https://github.com/OpenForgeProject/mageforge/commit/2dfea0de47b1e9b59f92260448ff5c679bdc2577)) -* add additional audits for accessibility and usability checks ([ad30fe9](https://github.com/OpenForgeProject/mageforge/commit/ad30fe9461e8f31b7258e877ae7771829f530eb3)) -* add additional check for elements within the toolbar ([877edcd](https://github.com/OpenForgeProject/mageforge/commit/877edcd5269bdee8eb04429d1b493479113722b5)) -* add warning styles and enhance audit checks for toolbar elements ([cfab08a](https://github.com/OpenForgeProject/mageforge/commit/cfab08ac520451ddefac021f4594f433917bdf2f)) -* clarify description for unsafe target="_blank" audit ([2df5ff2](https://github.com/OpenForgeProject/mageforge/commit/2df5ff2f5ce91adbd48ed8d094da5ecfc5f8036a)) -* enhance audits for duplicate IDs and interactive elements ([002d30f](https://github.com/OpenForgeProject/mageforge/commit/002d30fda814240cbb1122f2823521eb12c64607)) -* exclude toolbar elements from highlight application ([bfdcc29](https://github.com/OpenForgeProject/mageforge/commit/bfdcc29a6362cb0b8a2085f66228b30aaa9d9236)) -* update minimum size for small touch targets audit ([d492c1e](https://github.com/OpenForgeProject/mageforge/commit/d492c1edcb7dc99389f3fadfb59fe8aa5cc6827c)) -* update touch target size description for accessibility audit ([81ae5e4](https://github.com/OpenForgeProject/mageforge/commit/81ae5e42b782c2a619503a6ee9c0e8dc598af7ea)) - +- add additional audits for accessibility and usability checks ([2dfea0d](https://github.com/OpenForgeProject/mageforge/commit/2dfea0de47b1e9b59f92260448ff5c679bdc2577)) +- add additional audits for accessibility and usability checks ([ad30fe9](https://github.com/OpenForgeProject/mageforge/commit/ad30fe9461e8f31b7258e877ae7771829f530eb3)) +- add additional check for elements within the toolbar ([877edcd](https://github.com/OpenForgeProject/mageforge/commit/877edcd5269bdee8eb04429d1b493479113722b5)) +- add warning styles and enhance audit checks for toolbar elements ([cfab08a](https://github.com/OpenForgeProject/mageforge/commit/cfab08ac520451ddefac021f4594f433917bdf2f)) +- clarify description for unsafe target="\_blank" audit ([2df5ff2](https://github.com/OpenForgeProject/mageforge/commit/2df5ff2f5ce91adbd48ed8d094da5ecfc5f8036a)) +- enhance audits for duplicate IDs and interactive elements ([002d30f](https://github.com/OpenForgeProject/mageforge/commit/002d30fda814240cbb1122f2823521eb12c64607)) +- exclude toolbar elements from highlight application ([bfdcc29](https://github.com/OpenForgeProject/mageforge/commit/bfdcc29a6362cb0b8a2085f66228b30aaa9d9236)) +- update minimum size for small touch targets audit ([d492c1e](https://github.com/OpenForgeProject/mageforge/commit/d492c1edcb7dc99389f3fadfb59fe8aa5cc6827c)) +- update touch target size description for accessibility audit ([81ae5e4](https://github.com/OpenForgeProject/mageforge/commit/81ae5e42b782c2a619503a6ee9c0e8dc598af7ea)) ### Fixed -* add aria-expanded attribute for burger button accessibility ([363403b](https://github.com/OpenForgeProject/mageforge/commit/363403b0252c79db27d8d3e6367cae13cd8ecac9)) -* cast show labels to integer for consistent data attribute ([37658fb](https://github.com/OpenForgeProject/mageforge/commit/37658fb5e1c3e98dd800722f2c95761da4612d42)) -* disable inspector in config and update layout reference ([#175](https://github.com/OpenForgeProject/mageforge/issues/175)) ([99c71a9](https://github.com/OpenForgeProject/mageforge/commit/99c71a9d4566bf90782e7e26a72edc3ff3ab5486)) -* enhance constructor PHPDoc for Inspector and ThemeSuggester classes ([ad2eb35](https://github.com/OpenForgeProject/mageforge/commit/ad2eb35a77dfef3a93689cd0b26d5ad4cfa8e201)) -* ensure audits are deactivated on toolbar destruction ([b1a16fd](https://github.com/OpenForgeProject/mageforge/commit/b1a16fd2770b62e7524da5139f30ab85148e31f5)) -* improve type safety and clean up PHPDoc in Inspector block ([0c63ac3](https://github.com/OpenForgeProject/mageforge/commit/0c63ac316f32e8f8b74892f8b53f85988eefe883)) -* normalise opacity visibility check across all toolbar audits ([0fb1642](https://github.com/OpenForgeProject/mageforge/commit/0fb16422ef56c406c3d053a6145c2ebadda417ec)) -* refine theme path matching and enhance theme suggestion logic ([3484f34](https://github.com/OpenForgeProject/mageforge/commit/3484f349bf7ab660b9f5574811d675de2ca75f3f)) -* refine theme path matching and enhance theme suggestion logic ([fc1747b](https://github.com/OpenForgeProject/mageforge/commit/fc1747b90cba6a28176225aee7631a1d1744df70)) -* streamline toolbar destruction process and clean up references ([65221fe](https://github.com/OpenForgeProject/mageforge/commit/65221fe830848b823b63c3d0806864e28309f2d0)) -* toolbar fixes ([#177](https://github.com/OpenForgeProject/mageforge/issues/177)) ([f4382b5](https://github.com/OpenForgeProject/mageforge/commit/f4382b52420954e039820b96cc55fa5c8bbecf29)) -* update aria-expanded attribute for collapsible menu groups ([96ac5e1](https://github.com/OpenForgeProject/mageforge/commit/96ac5e17591ce181484d0bbbb8f3237adb21accd)) - +- add aria-expanded attribute for burger button accessibility ([363403b](https://github.com/OpenForgeProject/mageforge/commit/363403b0252c79db27d8d3e6367cae13cd8ecac9)) +- cast show labels to integer for consistent data attribute ([37658fb](https://github.com/OpenForgeProject/mageforge/commit/37658fb5e1c3e98dd800722f2c95761da4612d42)) +- disable inspector in config and update layout reference ([#175](https://github.com/OpenForgeProject/mageforge/issues/175)) ([99c71a9](https://github.com/OpenForgeProject/mageforge/commit/99c71a9d4566bf90782e7e26a72edc3ff3ab5486)) +- enhance constructor PHPDoc for Inspector and ThemeSuggester classes ([ad2eb35](https://github.com/OpenForgeProject/mageforge/commit/ad2eb35a77dfef3a93689cd0b26d5ad4cfa8e201)) +- ensure audits are deactivated on toolbar destruction ([b1a16fd](https://github.com/OpenForgeProject/mageforge/commit/b1a16fd2770b62e7524da5139f30ab85148e31f5)) +- improve type safety and clean up PHPDoc in Inspector block ([0c63ac3](https://github.com/OpenForgeProject/mageforge/commit/0c63ac316f32e8f8b74892f8b53f85988eefe883)) +- normalise opacity visibility check across all toolbar audits ([0fb1642](https://github.com/OpenForgeProject/mageforge/commit/0fb16422ef56c406c3d053a6145c2ebadda417ec)) +- refine theme path matching and enhance theme suggestion logic ([3484f34](https://github.com/OpenForgeProject/mageforge/commit/3484f349bf7ab660b9f5574811d675de2ca75f3f)) +- refine theme path matching and enhance theme suggestion logic ([fc1747b](https://github.com/OpenForgeProject/mageforge/commit/fc1747b90cba6a28176225aee7631a1d1744df70)) +- streamline toolbar destruction process and clean up references ([65221fe](https://github.com/OpenForgeProject/mageforge/commit/65221fe830848b823b63c3d0806864e28309f2d0)) +- toolbar fixes ([#177](https://github.com/OpenForgeProject/mageforge/issues/177)) ([f4382b5](https://github.com/OpenForgeProject/mageforge/commit/f4382b52420954e039820b96cc55fa5c8bbecf29)) +- update aria-expanded attribute for collapsible menu groups ([96ac5e1](https://github.com/OpenForgeProject/mageforge/commit/96ac5e17591ce181484d0bbbb8f3237adb21accd)) ### Styling -* adjust toolbar dimensions for better usability on small devices ([d41c6e2](https://github.com/OpenForgeProject/mageforge/commit/d41c6e2bfb8eb1659d9dd23a37e40aaf79b9f278)) -* update toolbar CSS for improved visibility ([84f80de](https://github.com/OpenForgeProject/mageforge/commit/84f80de1ab7884fe057e27d7356d4e9c31b815a5)) -* update toolbar for improved design ([4871193](https://github.com/OpenForgeProject/mageforge/commit/48711932074ec8867cfb63bd97addccf389b4783)) +- adjust toolbar dimensions for better usability on small devices ([d41c6e2](https://github.com/OpenForgeProject/mageforge/commit/d41c6e2bfb8eb1659d9dd23a37e40aaf79b9f278)) +- update toolbar CSS for improved visibility ([84f80de](https://github.com/OpenForgeProject/mageforge/commit/84f80de1ab7884fe057e27d7356d4e9c31b815a5)) +- update toolbar for improved design ([4871193](https://github.com/OpenForgeProject/mageforge/commit/48711932074ec8867cfb63bd97addccf389b4783)) ## [0.19.1](https://github.com/OpenForgeProject/mageforge/compare/0.19.0...0.19.1) (2026-04-22) - ### Fixed -* remove cacheable attribute from inspector block ([#174](https://github.com/OpenForgeProject/mageforge/issues/174)) ([e12e44e](https://github.com/OpenForgeProject/mageforge/commit/e12e44ecaf5b1372705fe90ef01f476e554e1639)) - +- remove cacheable attribute from inspector block ([#174](https://github.com/OpenForgeProject/mageforge/issues/174)) ([e12e44e](https://github.com/OpenForgeProject/mageforge/commit/e12e44ecaf5b1372705fe90ef01f476e554e1639)) ### Documentation -* Fix commands.md numbering, missing sections, and flag inconsistencies ([#172](https://github.com/OpenForgeProject/mageforge/issues/172)) ([ba5498f](https://github.com/OpenForgeProject/mageforge/commit/ba5498fe8d5741d03da2fb5350003c2f5085d07f)) +- Fix commands.md numbering, missing sections, and flag inconsistencies ([#172](https://github.com/OpenForgeProject/mageforge/issues/172)) ([ba5498f](https://github.com/OpenForgeProject/mageforge/commit/ba5498fe8d5741d03da2fb5350003c2f5085d07f)) ## [0.19.0](https://github.com/OpenForgeProject/mageforge/compare/0.18.0...0.19.0) (2026-04-13) - ### Added -* defer page timing caching until load event and add global metrics ([6721e60](https://github.com/OpenForgeProject/mageforge/commit/6721e60a7ac25118154f3a79ee1704f39ee2bd51)) - +- defer page timing caching until load event and add global metrics ([6721e60](https://github.com/OpenForgeProject/mageforge/commit/6721e60a7ac25118154f3a79ee1704f39ee2bd51)) ### Fixed -* clamp badge dragging within viewport boundaries ([03aee99](https://github.com/OpenForgeProject/mageforge/commit/03aee99cc88b178caf97573c4bdccb7e3f1cbc4b)) -* ensure drag end handler is removed on draggable removal ([8957129](https://github.com/OpenForgeProject/mageforge/commit/8957129173c01ccc506507f90e7cdbab1e9f141d)) - +- clamp badge dragging within viewport boundaries ([03aee99](https://github.com/OpenForgeProject/mageforge/commit/03aee99cc88b178caf97573c4bdccb7e3f1cbc4b)) +- ensure drag end handler is removed on draggable removal ([8957129](https://github.com/OpenForgeProject/mageforge/commit/8957129173c01ccc506507f90e7cdbab1e9f141d)) ### Changed -* enhance toolbar menu display logic with CSS transitions ([e150700](https://github.com/OpenForgeProject/mageforge/commit/e1507005803446c859a9dfa21ba25f40ee95ba63)) -* simplify connector management in draggable methods ([c995694](https://github.com/OpenForgeProject/mageforge/commit/c99569479244263108368d19f63a3fca155996bc)) -* update audit overlay styles and improve highlight logic ([27f1588](https://github.com/OpenForgeProject/mageforge/commit/27f15881db9d30c18e5eb78ea480d86bb0bef15e)) +- enhance toolbar menu display logic with CSS transitions ([e150700](https://github.com/OpenForgeProject/mageforge/commit/e1507005803446c859a9dfa21ba25f40ee95ba63)) +- simplify connector management in draggable methods ([c995694](https://github.com/OpenForgeProject/mageforge/commit/c99569479244263108368d19f63a3fca155996bc)) +- update audit overlay styles and improve highlight logic ([27f1588](https://github.com/OpenForgeProject/mageforge/commit/27f15881db9d30c18e5eb78ea480d86bb0bef15e)) ## [0.18.0](https://github.com/OpenForgeProject/mageforge/compare/0.17.0...0.18.0) (2026-04-13) - ### Added -* toolbar audit highlighting ([4fcfc7d](https://github.com/OpenForgeProject/mageforge/commit/4fcfc7d5cda0c813906dadb2060e1496e90d4504)) +- toolbar audit highlighting ([4fcfc7d](https://github.com/OpenForgeProject/mageforge/commit/4fcfc7d5cda0c813906dadb2060e1496e90d4504)) ## [0.17.0](https://github.com/OpenForgeProject/mageforge/compare/0.16.0...0.17.0) (2026-04-12) - ### Added -* add MageForge Toolbar with basic audits ([#167](https://github.com/OpenForgeProject/mageforge/issues/167)) ([2a8a8ba](https://github.com/OpenForgeProject/mageforge/commit/2a8a8ba02f53befd2b290e06f19f89480571f27e)) - +- add MageForge Toolbar with basic audits ([#167](https://github.com/OpenForgeProject/mageforge/issues/167)) ([2a8a8ba](https://github.com/OpenForgeProject/mageforge/commit/2a8a8ba02f53befd2b290e06f19f89480571f27e)) ### Fixed -* adjust initial badge position and add scroll handler for connector ([#162](https://github.com/OpenForgeProject/mageforge/issues/162)) ([84baaf0](https://github.com/OpenForgeProject/mageforge/commit/84baaf07e328ecec143f1dbae6db5fec504375df)) -* enhance role determination for input elements in accessibility analysis ([adb7996](https://github.com/OpenForgeProject/mageforge/commit/adb799637aab11b040934738f2f47326d2249c0c)) -* enhance structure rendering with additional properties ([109418b](https://github.com/OpenForgeProject/mageforge/commit/109418bb1cd5060fbd56bce30717520eeffef1cd)) -* handle click outside inspector overlay correctly when pinned ([c885f81](https://github.com/OpenForgeProject/mageforge/commit/c885f8133ca6c74292248b17bbe2cbf2da805d05)) -* improve badge update logic to prevent flickering ([5526e15](https://github.com/OpenForgeProject/mageforge/commit/5526e1541ec4eca0a403b1095f975d509d6da866)) -* improve CSS resource matching in element resource categorization ([a1dba6a](https://github.com/OpenForgeProject/mageforge/commit/a1dba6af5557831626f91f12f6833b4282e821b4)) -* remove INP metric tracking from performance and vitals modules ([#165](https://github.com/OpenForgeProject/mageforge/issues/165)) ([6c78a39](https://github.com/OpenForgeProject/mageforge/commit/6c78a399f78f1b13a56db5a96098e3ff7a5a1a1c)) -* remove unused badge offset in position calculation for info badge ([686387b](https://github.com/OpenForgeProject/mageforge/commit/686387b2fad00af960249b329362bdcd8b470da4)) -* update cursor check for interactive elements in accessibility analysis ([c430f99](https://github.com/OpenForgeProject/mageforge/commit/c430f99d7c8b2decb4a494df7cc721ca2bfd1b21)) -* update pull request header for clarity on changes ([ccd5a47](https://github.com/OpenForgeProject/mageforge/commit/ccd5a47c6c50093194cfd14ab8645c0b18415ac9)) -* update pull request title and header formatting in config ([0dbab2e](https://github.com/OpenForgeProject/mageforge/commit/0dbab2ecf6b233b0534e8106d0e9a5951708b144)) - +- adjust initial badge position and add scroll handler for connector ([#162](https://github.com/OpenForgeProject/mageforge/issues/162)) ([84baaf0](https://github.com/OpenForgeProject/mageforge/commit/84baaf07e328ecec143f1dbae6db5fec504375df)) +- enhance role determination for input elements in accessibility analysis ([adb7996](https://github.com/OpenForgeProject/mageforge/commit/adb799637aab11b040934738f2f47326d2249c0c)) +- enhance structure rendering with additional properties ([109418b](https://github.com/OpenForgeProject/mageforge/commit/109418bb1cd5060fbd56bce30717520eeffef1cd)) +- handle click outside inspector overlay correctly when pinned ([c885f81](https://github.com/OpenForgeProject/mageforge/commit/c885f8133ca6c74292248b17bbe2cbf2da805d05)) +- improve badge update logic to prevent flickering ([5526e15](https://github.com/OpenForgeProject/mageforge/commit/5526e1541ec4eca0a403b1095f975d509d6da866)) +- improve CSS resource matching in element resource categorization ([a1dba6a](https://github.com/OpenForgeProject/mageforge/commit/a1dba6af5557831626f91f12f6833b4282e821b4)) +- remove INP metric tracking from performance and vitals modules ([#165](https://github.com/OpenForgeProject/mageforge/issues/165)) ([6c78a39](https://github.com/OpenForgeProject/mageforge/commit/6c78a399f78f1b13a56db5a96098e3ff7a5a1a1c)) +- remove unused badge offset in position calculation for info badge ([686387b](https://github.com/OpenForgeProject/mageforge/commit/686387b2fad00af960249b329362bdcd8b470da4)) +- update cursor check for interactive elements in accessibility analysis ([c430f99](https://github.com/OpenForgeProject/mageforge/commit/c430f99d7c8b2decb4a494df7cc721ca2bfd1b21)) +- update pull request header for clarity on changes ([ccd5a47](https://github.com/OpenForgeProject/mageforge/commit/ccd5a47c6c50093194cfd14ab8645c0b18415ac9)) +- update pull request title and header formatting in config ([0dbab2e](https://github.com/OpenForgeProject/mageforge/commit/0dbab2ecf6b233b0534e8106d0e9a5951708b144)) ### Changed -* remove feature views and new badge logic from inspector ([#164](https://github.com/OpenForgeProject/mageforge/issues/164)) ([3bf7143](https://github.com/OpenForgeProject/mageforge/commit/3bf714332cd1d85d3ca5235318a7e3adbc72f47a)) -* use WeakMap for block data storage in inspector ([#166](https://github.com/OpenForgeProject/mageforge/issues/166)) ([5c383fd](https://github.com/OpenForgeProject/mageforge/commit/5c383fd7e099b8ebe684129cc5e9b07646d3b9eb)) +- remove feature views and new badge logic from inspector ([#164](https://github.com/OpenForgeProject/mageforge/issues/164)) ([3bf7143](https://github.com/OpenForgeProject/mageforge/commit/3bf714332cd1d85d3ca5235318a7e3adbc72f47a)) +- use WeakMap for block data storage in inspector ([#166](https://github.com/OpenForgeProject/mageforge/issues/166)) ([5c383fd](https://github.com/OpenForgeProject/mageforge/commit/5c383fd7e099b8ebe684129cc5e9b07646d3b9eb)) ## [0.16.0](https://github.com/OpenForgeProject/mageforge/compare/0.15.1...0.16.0) (2026-04-10) - ### Added -* add CSP whitelist and update Alpine.js to version 3.15.11 with hash security ([#159](https://github.com/OpenForgeProject/mageforge/issues/159)) ([fa811bd](https://github.com/OpenForgeProject/mageforge/commit/fa811bddbf48d531b528163eb210335a3c01eeca)) -* update PHP and Magento framework requirements in composer.json [#155](https://github.com/OpenForgeProject/mageforge/issues/155) ([#156](https://github.com/OpenForgeProject/mageforge/issues/156)) ([9a3f92d](https://github.com/OpenForgeProject/mageforge/commit/9a3f92dc102a9d7e2671d8b8330a276a18d8b042)) - +- add CSP whitelist and update Alpine.js to version 3.15.11 with hash security ([#159](https://github.com/OpenForgeProject/mageforge/issues/159)) ([fa811bd](https://github.com/OpenForgeProject/mageforge/commit/fa811bddbf48d531b528163eb210335a3c01eeca)) +- update PHP and Magento framework requirements in composer.json [#155](https://github.com/OpenForgeProject/mageforge/issues/155) ([#156](https://github.com/OpenForgeProject/mageforge/issues/156)) ([9a3f92d](https://github.com/OpenForgeProject/mageforge/commit/9a3f92dc102a9d7e2671d8b8330a276a18d8b042)) ### Fixed -* add keydownHandler and impove performance observers to inspector ([#160](https://github.com/OpenForgeProject/mageforge/issues/160)) ([5639b87](https://github.com/OpenForgeProject/mageforge/commit/5639b87ecc92277ca429055f37382997fd48aefb)) -* Refactor inspector.js into ES modules ([#161](https://github.com/OpenForgeProject/mageforge/issues/161)) ([f3fb74d](https://github.com/OpenForgeProject/mageforge/commit/f3fb74dc7e6090de172d0f1350bef713c1803ad5)) -* updated advanced_usage.md for better understanding ([#158](https://github.com/OpenForgeProject/mageforge/issues/158)) ([956efe4](https://github.com/OpenForgeProject/mageforge/commit/956efe4053d6ac75de5cc04b89c685da46e94bf6)) +- add keydownHandler and impove performance observers to inspector ([#160](https://github.com/OpenForgeProject/mageforge/issues/160)) ([5639b87](https://github.com/OpenForgeProject/mageforge/commit/5639b87ecc92277ca429055f37382997fd48aefb)) +- Refactor inspector.js into ES modules ([#161](https://github.com/OpenForgeProject/mageforge/issues/161)) ([f3fb74d](https://github.com/OpenForgeProject/mageforge/commit/f3fb74dc7e6090de172d0f1350bef713c1803ad5)) +- updated advanced_usage.md for better understanding ([#158](https://github.com/OpenForgeProject/mageforge/issues/158)) ([956efe4](https://github.com/OpenForgeProject/mageforge/commit/956efe4053d6ac75de5cc04b89c685da46e94bf6)) ## [0.15.1](https://github.com/OpenForgeProject/mageforge/compare/0.15.0...0.15.1) (2026-03-18) - ### Fixed -* update phpstan to level 9 ([#152](https://github.com/OpenForgeProject/mageforge/issues/152)) ([c57f6c7](https://github.com/OpenForgeProject/mageforge/commit/c57f6c71c4c15a738b115b667db744b395553e5a)) +- update phpstan to level 9 ([#152](https://github.com/OpenForgeProject/mageforge/issues/152)) ([c57f6c7](https://github.com/OpenForgeProject/mageforge/commit/c57f6c71c4c15a738b115b667db744b395553e5a)) ## [0.15.0](https://github.com/OpenForgeProject/mageforge/compare/0.14.1...0.15.0) (2026-03-18) - ### Added -* add wildcard theme resolution to build and clean commands ([#150](https://github.com/OpenForgeProject/mageforge/issues/150)) ([ec4316d](https://github.com/OpenForgeProject/mageforge/commit/ec4316def7318a88395e3566eb1415757990b181)) +- add wildcard theme resolution to build and clean commands ([#150](https://github.com/OpenForgeProject/mageforge/issues/150)) ([ec4316d](https://github.com/OpenForgeProject/mageforge/commit/ec4316def7318a88395e3566eb1415757990b181)) ## [0.14.1](https://github.com/OpenForgeProject/mageforge/compare/0.14.0...0.14.1) (2026-03-12) - ### Fixed -* ensure theme codes are indexed correctly in commands ([#149](https://github.com/OpenForgeProject/mageforge/issues/149)) ([f9175a7](https://github.com/OpenForgeProject/mageforge/commit/f9175a75e017965a0014cd71b940ce354ce64633)) -* update Magento requirement to 2.4.7 with PHP 8.3 in README ([3b4cfca](https://github.com/OpenForgeProject/mageforge/commit/3b4cfca7a041f0dca8b9c3c88f2114789628471c)) -* update Magento version to 2.4.7-p9 in compatibility workflow ([79eb0b2](https://github.com/OpenForgeProject/mageforge/commit/79eb0b264918d662f7e2308c022ea3f6ddd5ea94)) -* update PHP version and Magento version in compatibility matrix ([8d662f6](https://github.com/OpenForgeProject/mageforge/commit/8d662f6864f9a8a7f5a78ab508dc59fe54712adb)) +- ensure theme codes are indexed correctly in commands ([#149](https://github.com/OpenForgeProject/mageforge/issues/149)) ([f9175a7](https://github.com/OpenForgeProject/mageforge/commit/f9175a75e017965a0014cd71b940ce354ce64633)) +- update Magento requirement to 2.4.7 with PHP 8.3 in README ([3b4cfca](https://github.com/OpenForgeProject/mageforge/commit/3b4cfca7a041f0dca8b9c3c88f2114789628471c)) +- update Magento version to 2.4.7-p9 in compatibility workflow ([79eb0b2](https://github.com/OpenForgeProject/mageforge/commit/79eb0b264918d662f7e2308c022ea3f6ddd5ea94)) +- update PHP version and Magento version in compatibility matrix ([8d662f6](https://github.com/OpenForgeProject/mageforge/commit/8d662f6864f9a8a7f5a78ab508dc59fe54712adb)) ## [0.14.0](https://github.com/OpenForgeProject/mageforge/compare/0.13.0...0.14.0) (2026-03-06) - ### Added -* replace MultiSelectPrompt with MultiSearchPrompt for theme selection ([bc89442](https://github.com/OpenForgeProject/mageforge/commit/bc89442fa6f9d77043462c02e842437211065cd7)) +- replace MultiSelectPrompt with MultiSearchPrompt for theme selection ([bc89442](https://github.com/OpenForgeProject/mageforge/commit/bc89442fa6f9d77043462c02e842437211065cd7)) ## [0.13.0](https://github.com/OpenForgeProject/mageforge/compare/0.12.0...0.13.0) (2026-03-03) - ### Added -* add NodeSetupValidator for validating Magento default setup files ([#142](https://github.com/OpenForgeProject/mageforge/issues/142)) ([3f36d43](https://github.com/OpenForgeProject/mageforge/commit/3f36d433a04ac31be0ca84f04cd4495245ecf52e)) - +- add NodeSetupValidator for validating Magento default setup files ([#142](https://github.com/OpenForgeProject/mageforge/issues/142)) ([3f36d43](https://github.com/OpenForgeProject/mageforge/commit/3f36d433a04ac31be0ca84f04cd4495245ecf52e)) ### Fixed -* resolve phpcs errors ([#145](https://github.com/OpenForgeProject/mageforge/issues/145)) ([cb90564](https://github.com/OpenForgeProject/mageforge/commit/cb905645175d6dd49d79b787b5545e1b6c0df422)) -* run mago format ([#146](https://github.com/OpenForgeProject/mageforge/issues/146)) ([fa34cd8](https://github.com/OpenForgeProject/mageforge/commit/fa34cd8c8edc2453ec4b446b56ac16f51cd4858f)) +- resolve phpcs errors ([#145](https://github.com/OpenForgeProject/mageforge/issues/145)) ([cb90564](https://github.com/OpenForgeProject/mageforge/commit/cb905645175d6dd49d79b787b5545e1b6c0df422)) +- run mago format ([#146](https://github.com/OpenForgeProject/mageforge/issues/146)) ([fa34cd8](https://github.com/OpenForgeProject/mageforge/commit/fa34cd8c8edc2453ec4b446b56ac16f51cd4858f)) ## [0.12.0](https://github.com/OpenForgeProject/mageforge/compare/0.11.0...0.12.0) (2026-02-14) - ### Added -* **actions:** replace elasticsearch with opensearch ([#137](https://github.com/OpenForgeProject/mageforge/issues/137)) ([cc8c534](https://github.com/OpenForgeProject/mageforge/commit/cc8c53428288a45b8ad645baf87623bf4a8b9a1f)) - +- **actions:** replace elasticsearch with opensearch ([#137](https://github.com/OpenForgeProject/mageforge/issues/137)) ([cc8c534](https://github.com/OpenForgeProject/mageforge/commit/cc8c53428288a45b8ad645baf87623bf4a8b9a1f)) ### Fixed -* correct font size and border radius in inspector CSS ([7bb3348](https://github.com/OpenForgeProject/mageforge/commit/7bb334806a134687bd06cf55e5f27682947f3c84)) -* phpcs errors ([#138](https://github.com/OpenForgeProject/mageforge/issues/138)) ([625c6da](https://github.com/OpenForgeProject/mageforge/commit/625c6da89882d19605713e4c295af713700890aa)) -* **phpcs:** refactor environment variable handling in commands ([#135](https://github.com/OpenForgeProject/mageforge/issues/135)) ([9c01ce5](https://github.com/OpenForgeProject/mageforge/commit/9c01ce5fe269c0b917c95b5804542c7ee7840af3)) -* update font settings and sizes in inspector CSS ([986ded6](https://github.com/OpenForgeProject/mageforge/commit/986ded6aeafe628c0549dc6d72f6ae119421d9df)) - +- correct font size and border radius in inspector CSS ([7bb3348](https://github.com/OpenForgeProject/mageforge/commit/7bb334806a134687bd06cf55e5f27682947f3c84)) +- phpcs errors ([#138](https://github.com/OpenForgeProject/mageforge/issues/138)) ([625c6da](https://github.com/OpenForgeProject/mageforge/commit/625c6da89882d19605713e4c295af713700890aa)) +- **phpcs:** refactor environment variable handling in commands ([#135](https://github.com/OpenForgeProject/mageforge/issues/135)) ([9c01ce5](https://github.com/OpenForgeProject/mageforge/commit/9c01ce5fe269c0b917c95b5804542c7ee7840af3)) +- update font settings and sizes in inspector CSS ([986ded6](https://github.com/OpenForgeProject/mageforge/commit/986ded6aeafe628c0549dc6d72f6ae119421d9df)) ### Documentation -* update README with custom theme details and add inspector section ([084b528](https://github.com/OpenForgeProject/mageforge/commit/084b52815adb78b4292d748fc100a8be3994844c)) +- update README with custom theme details and add inspector section ([084b528](https://github.com/OpenForgeProject/mageforge/commit/084b52815adb78b4292d748fc100a8be3994844c)) ## [0.11.0](https://github.com/OpenForgeProject/mageforge/compare/0.10.3...0.11.0) (2026-02-10) - ### Added -* add cache and webvitals tabs to inspector and improve ux with dragable overlay ([#127](https://github.com/OpenForgeProject/mageforge/issues/127)) ([eea755d](https://github.com/OpenForgeProject/mageforge/commit/eea755d1b38fe9e736a49157192babc5b98fbb10)) -* implement dark/light mode theme selection and admin configuration section ([#131](https://github.com/OpenForgeProject/mageforge/issues/131)) ([0a95280](https://github.com/OpenForgeProject/mageforge/commit/0a952808b6a5f7102aa5ad4b874e576d67f77bd1)) - +- add cache and webvitals tabs to inspector and improve ux with dragable overlay ([#127](https://github.com/OpenForgeProject/mageforge/issues/127)) ([eea755d](https://github.com/OpenForgeProject/mageforge/commit/eea755d1b38fe9e736a49157192babc5b98fbb10)) +- implement dark/light mode theme selection and admin configuration section ([#131](https://github.com/OpenForgeProject/mageforge/issues/131)) ([0a95280](https://github.com/OpenForgeProject/mageforge/commit/0a952808b6a5f7102aa5ad4b874e576d67f77bd1)) ### Fixed -* remove metric icons and rename metric titles for better ux ([#129](https://github.com/OpenForgeProject/mageforge/issues/129)) ([11d3c45](https://github.com/OpenForgeProject/mageforge/commit/11d3c45991684e5936862386e5a6e731ce7962ff)) +- remove metric icons and rename metric titles for better ux ([#129](https://github.com/OpenForgeProject/mageforge/issues/129)) ([11d3c45](https://github.com/OpenForgeProject/mageforge/commit/11d3c45991684e5936862386e5a6e731ce7962ff)) ## [0.10.3](https://github.com/OpenForgeProject/mageforge/compare/0.10.2...0.10.3) (2026-02-05) - ### Fixed -* update phpcs errors ([#124](https://github.com/OpenForgeProject/mageforge/issues/124)) ([a19e23d](https://github.com/OpenForgeProject/mageforge/commit/a19e23d6bfc61bb255057ed739b3904855971e2f)) +- update phpcs errors ([#124](https://github.com/OpenForgeProject/mageforge/issues/124)) ([a19e23d](https://github.com/OpenForgeProject/mageforge/commit/a19e23d6bfc61bb255057ed739b3904855971e2f)) ## [0.10.2](https://github.com/OpenForgeProject/mageforge/compare/0.10.1...0.10.2) (2026-02-02) - ### Fixed -* return theme parts as array in parseThemeName ([#122](https://github.com/OpenForgeProject/mageforge/issues/122)) ([94aef44](https://github.com/OpenForgeProject/mageforge/commit/94aef44bbc92ef6506ef6cd306ce010f1d6b6ef8)) +- return theme parts as array in parseThemeName ([#122](https://github.com/OpenForgeProject/mageforge/issues/122)) ([94aef44](https://github.com/OpenForgeProject/mageforge/commit/94aef44bbc92ef6506ef6cd306ce010f1d6b6ef8)) ## [0.10.1](https://github.com/OpenForgeProject/mageforge/compare/0.10.0...0.10.1) (2026-01-30) - ### Fixed -* correct spacing and formatting in multiple files ([#120](https://github.com/OpenForgeProject/mageforge/issues/120)) ([3f9048a](https://github.com/OpenForgeProject/mageforge/commit/3f9048abc0b0f2785aa5be3858704037ad14ce5a)) -* update phpstan level to 8 and improve commands ([#119](https://github.com/OpenForgeProject/mageforge/issues/119)) ([e24e138](https://github.com/OpenForgeProject/mageforge/commit/e24e138ae2e5fcdb0013639cdb573da782fcb3fd)) +- correct spacing and formatting in multiple files ([#120](https://github.com/OpenForgeProject/mageforge/issues/120)) ([3f9048a](https://github.com/OpenForgeProject/mageforge/commit/3f9048abc0b0f2785aa5be3858704037ad14ce5a)) +- update phpstan level to 8 and improve commands ([#119](https://github.com/OpenForgeProject/mageforge/issues/119)) ([e24e138](https://github.com/OpenForgeProject/mageforge/commit/e24e138ae2e5fcdb0013639cdb573da782fcb3fd)) ## [0.10.0](https://github.com/OpenForgeProject/mageforge/compare/0.9.0...0.10.0) (2026-01-30) - ### Added -* update phpstan level and add type hints ([#116](https://github.com/OpenForgeProject/mageforge/issues/116)) ([0a4a5fa](https://github.com/OpenForgeProject/mageforge/commit/0a4a5fa45ca77396a87569eca3491b569e3d3539)) - +- update phpstan level and add type hints ([#116](https://github.com/OpenForgeProject/mageforge/issues/116)) ([0a4a5fa](https://github.com/OpenForgeProject/mageforge/commit/0a4a5fa45ca77396a87569eca3491b569e3d3539)) ### Fixed -* update phpstan level to 7 and improve error handling ([#118](https://github.com/OpenForgeProject/mageforge/issues/118)) ([7c84ae7](https://github.com/OpenForgeProject/mageforge/commit/7c84ae75580037b6764c4e570cdca06fc5a3a970)) +- update phpstan level to 7 and improve error handling ([#118](https://github.com/OpenForgeProject/mageforge/issues/118)) ([7c84ae7](https://github.com/OpenForgeProject/mageforge/commit/7c84ae75580037b6764c4e570cdca06fc5a3a970)) ## [0.9.0](https://github.com/OpenForgeProject/mageforge/compare/0.8.1...0.9.0) (2026-01-30) - ### Added -* Node.js/Grunt setup detection for improved build process ([#114](https://github.com/OpenForgeProject/mageforge/issues/114)) ([5330e17](https://github.com/OpenForgeProject/mageforge/commit/5330e1702acc470276bd8c6ea508b0c35ac18a2f)) - +- Node.js/Grunt setup detection for improved build process ([#114](https://github.com/OpenForgeProject/mageforge/issues/114)) ([5330e17](https://github.com/OpenForgeProject/mageforge/commit/5330e1702acc470276bd8c6ea508b0c35ac18a2f)) ### Fixed -* phpstan level 5 errors [#84](https://github.com/OpenForgeProject/mageforge/issues/84) ([#100](https://github.com/OpenForgeProject/mageforge/issues/100)) ([154d15e](https://github.com/OpenForgeProject/mageforge/commit/154d15eba0db013b99cb4141dc0b2cd059147fb0)) +- phpstan level 5 errors [#84](https://github.com/OpenForgeProject/mageforge/issues/84) ([#100](https://github.com/OpenForgeProject/mageforge/issues/100)) ([154d15e](https://github.com/OpenForgeProject/mageforge/commit/154d15eba0db013b99cb4141dc0b2cd059147fb0)) ## [0.8.1](https://github.com/OpenForgeProject/mageforge/compare/0.8.0...0.8.1) (2026-01-27) - ### Fixed -* improve node module installation fallback logic ([#107](https://github.com/OpenForgeProject/mageforge/issues/107)) ([c400732](https://github.com/OpenForgeProject/mageforge/commit/c400732d5dfec183adc7fde9e42ad6b99f573f0e)) +- improve node module installation fallback logic ([#107](https://github.com/OpenForgeProject/mageforge/issues/107)) ([c400732](https://github.com/OpenForgeProject/mageforge/commit/c400732d5dfec183adc7fde9e42ad6b99f573f0e)) ## [0.8.0](https://github.com/OpenForgeProject/mageforge/compare/0.7.0...0.8.0) (2026-01-23) - ### Added -* add functional-tests badge to readme.md ([#95](https://github.com/OpenForgeProject/mageforge/issues/95)) ([7108ef0](https://github.com/OpenForgeProject/mageforge/commit/7108ef0d4408b82f3010acaa00cf6f257880809d)) -* add npm sync validation to NodePackageManager and theme builders ([#93](https://github.com/OpenForgeProject/mageforge/issues/93)) ([5fcbdaf](https://github.com/OpenForgeProject/mageforge/commit/5fcbdaf7ceb19136f4b86fbffd33b44cee1469d6)) -* add phpstan & phpcs ([#96](https://github.com/OpenForgeProject/mageforge/issues/96)) ([06bcfdc](https://github.com/OpenForgeProject/mageforge/commit/06bcfdc82b1a8e0a58ad8712f7a120dc215e850f)) -* add pinning functionality for inspector badge ([#104](https://github.com/OpenForgeProject/mageforge/issues/104)) ([69f7328](https://github.com/OpenForgeProject/mageforge/commit/69f73287754b572ea27349fcbb248f351dd7bc0d)) -* enhance inspector with JSON metadata and comment parsing ([#105](https://github.com/OpenForgeProject/mageforge/issues/105)) ([a2f9ebf](https://github.com/OpenForgeProject/mageforge/commit/a2f9ebf4a188e01576d980866c92b7d9e7bf55f1)) -* separate functional tests from compatibility tests ([effac26](https://github.com/OpenForgeProject/mageforge/commit/effac2637837efa4814b93bc1b09eb8cef306544)) -* update feature request link to direct to new issue template ([7e0b57e](https://github.com/OpenForgeProject/mageforge/commit/7e0b57eb33f927ba307b008af504de42c4a2a5af)) - +- add functional-tests badge to readme.md ([#95](https://github.com/OpenForgeProject/mageforge/issues/95)) ([7108ef0](https://github.com/OpenForgeProject/mageforge/commit/7108ef0d4408b82f3010acaa00cf6f257880809d)) +- add npm sync validation to NodePackageManager and theme builders ([#93](https://github.com/OpenForgeProject/mageforge/issues/93)) ([5fcbdaf](https://github.com/OpenForgeProject/mageforge/commit/5fcbdaf7ceb19136f4b86fbffd33b44cee1469d6)) +- add phpstan & phpcs ([#96](https://github.com/OpenForgeProject/mageforge/issues/96)) ([06bcfdc](https://github.com/OpenForgeProject/mageforge/commit/06bcfdc82b1a8e0a58ad8712f7a120dc215e850f)) +- add pinning functionality for inspector badge ([#104](https://github.com/OpenForgeProject/mageforge/issues/104)) ([69f7328](https://github.com/OpenForgeProject/mageforge/commit/69f73287754b572ea27349fcbb248f351dd7bc0d)) +- enhance inspector with JSON metadata and comment parsing ([#105](https://github.com/OpenForgeProject/mageforge/issues/105)) ([a2f9ebf](https://github.com/OpenForgeProject/mageforge/commit/a2f9ebf4a188e01576d980866c92b7d9e7bf55f1)) +- separate functional tests from compatibility tests ([effac26](https://github.com/OpenForgeProject/mageforge/commit/effac2637837efa4814b93bc1b09eb8cef306544)) +- update feature request link to direct to new issue template ([7e0b57e](https://github.com/OpenForgeProject/mageforge/commit/7e0b57eb33f927ba307b008af504de42c4a2a5af)) ### Fixed -* correct head-branch regex and add new changed-files sections ([53777ea](https://github.com/OpenForgeProject/mageforge/commit/53777eac19920e4de175b2a52704ff8b0c9982de)) -* labeler.yml to simplify Documentation labels ([2d96502](https://github.com/OpenForgeProject/mageforge/commit/2d96502e697fb6bc0c262867163d93086c75c9aa)) -* labeler.yml to update label rules ([79c3fc0](https://github.com/OpenForgeProject/mageforge/commit/79c3fc05b8a468c76b3e69ee9b555e0460bc3928)) -* remove deprecated environment retrieval method ([#98](https://github.com/OpenForgeProject/mageforge/issues/98)) ([3e11ae7](https://github.com/OpenForgeProject/mageforge/commit/3e11ae7a572dff28875167043d5f9e64e7cc67b5)) -* remove unnecessary blank lines in functional tests workflow ([f1e9bb7](https://github.com/OpenForgeProject/mageforge/commit/f1e9bb7ce8ea96f20f5c23b1b4ae78138388ab53)) -* update head-branch patterns and file globbing in labeler.yml ([#103](https://github.com/OpenForgeProject/mageforge/issues/103)) ([bd48b7c](https://github.com/OpenForgeProject/mageforge/commit/bd48b7ced59e405002897e595972bebf97a34bc4)) -* update validateHyvaTheme to include output parameter ([#99](https://github.com/OpenForgeProject/mageforge/issues/99)) ([9b53f8d](https://github.com/OpenForgeProject/mageforge/commit/9b53f8d270df9c56ab13488c2d7c60b367e3fa47)) -* Workflow permissions ([#101](https://github.com/OpenForgeProject/mageforge/issues/101)) ([c0c4c3d](https://github.com/OpenForgeProject/mageforge/commit/c0c4c3dbccda41befc7107b38279dbb11dc77db2)) +- correct head-branch regex and add new changed-files sections ([53777ea](https://github.com/OpenForgeProject/mageforge/commit/53777eac19920e4de175b2a52704ff8b0c9982de)) +- labeler.yml to simplify Documentation labels ([2d96502](https://github.com/OpenForgeProject/mageforge/commit/2d96502e697fb6bc0c262867163d93086c75c9aa)) +- labeler.yml to update label rules ([79c3fc0](https://github.com/OpenForgeProject/mageforge/commit/79c3fc05b8a468c76b3e69ee9b555e0460bc3928)) +- remove deprecated environment retrieval method ([#98](https://github.com/OpenForgeProject/mageforge/issues/98)) ([3e11ae7](https://github.com/OpenForgeProject/mageforge/commit/3e11ae7a572dff28875167043d5f9e64e7cc67b5)) +- remove unnecessary blank lines in functional tests workflow ([f1e9bb7](https://github.com/OpenForgeProject/mageforge/commit/f1e9bb7ce8ea96f20f5c23b1b4ae78138388ab53)) +- update head-branch patterns and file globbing in labeler.yml ([#103](https://github.com/OpenForgeProject/mageforge/issues/103)) ([bd48b7c](https://github.com/OpenForgeProject/mageforge/commit/bd48b7ced59e405002897e595972bebf97a34bc4)) +- update validateHyvaTheme to include output parameter ([#99](https://github.com/OpenForgeProject/mageforge/issues/99)) ([9b53f8d](https://github.com/OpenForgeProject/mageforge/commit/9b53f8d270df9c56ab13488c2d7c60b367e3fa47)) +- Workflow permissions ([#101](https://github.com/OpenForgeProject/mageforge/issues/101)) ([c0c4c3d](https://github.com/OpenForgeProject/mageforge/commit/c0c4c3dbccda41befc7107b38279dbb11dc77db2)) ## [0.7.0](https://github.com/OpenForgeProject/mageforge/compare/0.6.0...0.7.0) (2026-01-20) - ### Added -* add context7 configuration file with URL and public key ([977bee0](https://github.com/OpenForgeProject/mageforge/commit/977bee0d2b2c4301bd2764b07ef82eefb92e29fb)) -* add NodePackageManager service for npm dependency management ([#91](https://github.com/OpenForgeProject/mageforge/issues/91)) ([1ab623f](https://github.com/OpenForgeProject/mageforge/commit/1ab623f5d858c272b6f692acb98edd35bf15ed3d)) -* implement SymlinkCleaner service and integrate into theme builders [#88](https://github.com/OpenForgeProject/mageforge/issues/88) ([#89](https://github.com/OpenForgeProject/mageforge/issues/89)) ([3f40ef6](https://github.com/OpenForgeProject/mageforge/commit/3f40ef64174686fd3c75944d00773ef83515f0f9)) +- add context7 configuration file with URL and public key ([977bee0](https://github.com/OpenForgeProject/mageforge/commit/977bee0d2b2c4301bd2764b07ef82eefb92e29fb)) +- add NodePackageManager service for npm dependency management ([#91](https://github.com/OpenForgeProject/mageforge/issues/91)) ([1ab623f](https://github.com/OpenForgeProject/mageforge/commit/1ab623f5d858c272b6f692acb98edd35bf15ed3d)) +- implement SymlinkCleaner service and integrate into theme builders [#88](https://github.com/OpenForgeProject/mageforge/issues/88) ([#89](https://github.com/OpenForgeProject/mageforge/issues/89)) ([3f40ef6](https://github.com/OpenForgeProject/mageforge/commit/3f40ef64174686fd3c75944d00773ef83515f0f9)) ## [0.6.0](https://github.com/OpenForgeProject/mageforge/compare/0.5.0...0.6.0) (2026-01-19) - ### Added -* dev Inspector Overlay (Frontend) ([#85](https://github.com/OpenForgeProject/mageforge/issues/85)) ([806d04a](https://github.com/OpenForgeProject/mageforge/commit/806d04a252eb70f6f76131a672296d62a7c5372b)) +- dev Inspector Overlay (Frontend) ([#85](https://github.com/OpenForgeProject/mageforge/issues/85)) ([806d04a](https://github.com/OpenForgeProject/mageforge/commit/806d04a252eb70f6f76131a672296d62a7c5372b)) ## [0.5.0](https://github.com/OpenForgeProject/mageforge/compare/0.4.0...0.5.0) (2026-01-17) - ### ⚠ BREAKING CHANGES -* create theme:clean command for cleaning theme static files and cache, remove old mageforge:static:clean command ([#80](https://github.com/OpenForgeProject/mageforge/issues/80)) +- create theme:clean command for cleaning theme static files and cache, remove old mageforge:static:clean command ([#80](https://github.com/OpenForgeProject/mageforge/issues/80)) ### Added -* implement StaticContentCleaner and update theme build commands ([#83](https://github.com/OpenForgeProject/mageforge/issues/83)) ([80a6abf](https://github.com/OpenForgeProject/mageforge/commit/80a6abf8b63dfdf25233f884d3fc3c6a2648b05c)) - +- implement StaticContentCleaner and update theme build commands ([#83](https://github.com/OpenForgeProject/mageforge/issues/83)) ([80a6abf](https://github.com/OpenForgeProject/mageforge/commit/80a6abf8b63dfdf25233f884d3fc3c6a2648b05c)) ### Fixed -* create theme:clean command for cleaning theme static files and cache, remove old mageforge:static:clean command ([#80](https://github.com/OpenForgeProject/mageforge/issues/80)) ([ffd5ec8](https://github.com/OpenForgeProject/mageforge/commit/ffd5ec89e87eb8aa3a1f19eb957bd3f95a5c50b1)) -* update command aliases for consistency and clarity ([#82](https://github.com/OpenForgeProject/mageforge/issues/82)) ([34640fa](https://github.com/OpenForgeProject/mageforge/commit/34640fa88f0b622780b7257f7a74a2b469453391)) +- create theme:clean command for cleaning theme static files and cache, remove old mageforge:static:clean command ([#80](https://github.com/OpenForgeProject/mageforge/issues/80)) ([ffd5ec8](https://github.com/OpenForgeProject/mageforge/commit/ffd5ec89e87eb8aa3a1f19eb957bd3f95a5c50b1)) +- update command aliases for consistency and clarity ([#82](https://github.com/OpenForgeProject/mageforge/issues/82)) ([34640fa](https://github.com/OpenForgeProject/mageforge/commit/34640fa88f0b622780b7257f7a74a2b469453391)) ## [0.4.0](https://github.com/OpenForgeProject/mageforge/compare/0.3.1...0.4.0) (2026-01-17) - ### Added -* add theme suggestion service and integrate with commands [#75](https://github.com/OpenForgeProject/mageforge/issues/75) ([#76](https://github.com/OpenForgeProject/mageforge/issues/76)) ([1347782](https://github.com/OpenForgeProject/mageforge/commit/13477823e82b81bda5412a7f8d4cbd747254d6c5)) -* implement Release Please workflow and update configuration ([d814853](https://github.com/OpenForgeProject/mageforge/commit/d814853c220dd098ad11340ea179ad66f9fb01f7)) - +- add theme suggestion service and integrate with commands [#75](https://github.com/OpenForgeProject/mageforge/issues/75) ([#76](https://github.com/OpenForgeProject/mageforge/issues/76)) ([1347782](https://github.com/OpenForgeProject/mageforge/commit/13477823e82b81bda5412a7f8d4cbd747254d6c5)) +- implement Release Please workflow and update configuration ([d814853](https://github.com/OpenForgeProject/mageforge/commit/d814853c220dd098ad11340ea179ad66f9fb01f7)) ### Fixed -* adjust command argument order and clean up whitespace ([9c4fb73](https://github.com/OpenForgeProject/mageforge/commit/9c4fb7356d23c38096e798d797fdfcb4ec455ff5)) -* enhance interactive mode for compatibility checks and prompts ([#79](https://github.com/OpenForgeProject/mageforge/issues/79)) ([428a133](https://github.com/OpenForgeProject/mageforge/commit/428a1338479a2ad1642ea7a353d0c73e37ef155b)) -* improve theme selection and validation in TokensCommand ([#77](https://github.com/OpenForgeProject/mageforge/issues/77)) ([9167e95](https://github.com/OpenForgeProject/mageforge/commit/9167e956ddd1faebc03f39a26cf9a8434ecbe99a)) - +- adjust command argument order and clean up whitespace ([9c4fb73](https://github.com/OpenForgeProject/mageforge/commit/9c4fb7356d23c38096e798d797fdfcb4ec455ff5)) +- enhance interactive mode for compatibility checks and prompts ([#79](https://github.com/OpenForgeProject/mageforge/issues/79)) ([428a133](https://github.com/OpenForgeProject/mageforge/commit/428a1338479a2ad1642ea7a353d0c73e37ef155b)) +- improve theme selection and validation in TokensCommand ([#77](https://github.com/OpenForgeProject/mageforge/issues/77)) ([9167e95](https://github.com/OpenForgeProject/mageforge/commit/9167e956ddd1faebc03f39a26cf9a8434ecbe99a)) ### Documentation -* update community support links to GitHub Discussions ([c67380e](https://github.com/OpenForgeProject/mageforge/commit/c67380ea8366a364ab5161b7e01c1a66872d3e24)) -* update dependencies and naming conventions in Copilot instructions ([cf98266](https://github.com/OpenForgeProject/mageforge/commit/cf98266c331d41516c96eddaa32983038adc8ee4)) -* update README for command list and support section ([f4fb886](https://github.com/OpenForgeProject/mageforge/commit/f4fb886ca698a8f6d4ed3800bb60937f0f88331f)) +- update community support links to GitHub Discussions ([c67380e](https://github.com/OpenForgeProject/mageforge/commit/c67380ea8366a364ab5161b7e01c1a66872d3e24)) +- update dependencies and naming conventions in Copilot instructions ([cf98266](https://github.com/OpenForgeProject/mageforge/commit/cf98266c331d41516c96eddaa32983038adc8ee4)) +- update README for command list and support section ([f4fb886](https://github.com/OpenForgeProject/mageforge/commit/f4fb886ca698a8f6d4ed3800bb60937f0f88331f)) ### [0.3.1] - 2026-01-12 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e5a6dfc5..5ecb69ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ We use [Conventional Commits](https://www.conventionalcommits.org/) for automate **PR Title Format** (Required): Your PR title **must** follow Conventional Commits format: -``` +```text : Examples: @@ -36,6 +36,7 @@ Examples: ``` **Commit Types**: + - `feat:` - New feature (minor version bump: 0.3.0 → 0.4.0) - `fix:` - Bug fix (patch version bump: 0.3.0 → 0.3.1) - `refactor:` - Code refactoring (no version bump by default) @@ -46,7 +47,8 @@ Examples: - `chore:` - Maintenance tasks (no version bump) **Breaking Changes**: Add `!` after the type for major version bumps: -``` + +```text feat!: remove legacy theme builder API fix!: change command argument order ``` @@ -74,6 +76,7 @@ git commit -m "chore: update GitHub Actions to latest versions" ### Merge Strategy All pull requests are merged using **squash-merge** to maintain a clean, linear git history. This means: + - ✅ Only one commit per PR in `main` branch - ✅ PR title becomes the commit message - ✅ All PR commits are squashed into a single commit @@ -104,7 +107,8 @@ All pull requests are merged using **squash-merge** to maintain a clean, linear - **Indentation**: Use 4 spaces for indentation. - **Naming Conventions**: Choose meaningful names for variables and functions. - **Line Length**: Keep lines under 80 characters wherever possible. -- **Linting**: Run `trunk check` to lint your code before submission. +- **Linting**: Run `trunk check` (non-PHP files) and `ddev mago lint` (PHP) before submission. +- **Formatting**: Run `trunk fmt` (non-PHP files) and `ddev mago fmt` (PHP) to auto-format. --- diff --git a/README.md b/README.md index 8839c806..6cc85e03 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,15 @@ MageForge is a powerful CLI toolkit for Magento 2 front-end development. It simp ![Mageforge Hero](./.github/assets/cli-chooser.png) -| Theme Type | Support Status | -| ------------------------------- | ---------------------------------------------------------- | -| Magento Standard | ✅ Supported | -| Hyvä (TailwindCSS 3.x / 4.x) | ✅ Supported | -| Hyvä Checkout | ✅ Supported | -| Hyvä Fallback | ✅ Supported | -| Custom TailwindCSS (no Hyvä) | ✅ Supported | -| Avanta B2B | ✅ Supported | -| Your Custom Theme | [Create your own Builder](./docs/custom_theme_builders.md) | +| Theme Type | Support Status | +| ---------------------------- | ---------------------------------------------------------- | +| Magento Standard | ✅ Supported | +| Hyvä (TailwindCSS 3.x / 4.x) | ✅ Supported | +| Hyvä Checkout | ✅ Supported | +| Hyvä Fallback | ✅ Supported | +| Custom TailwindCSS (no Hyvä) | ✅ Supported | +| Avanta B2B | ✅ Supported | +| Your Custom Theme | [Create your own Builder](./docs/custom_theme_builders.md) | ## Installation @@ -76,21 +76,26 @@ See [Commands Reference](./docs/commands_reference.md) for the full command list The MageForge Inspector lets you inspect Magento blocks, templates, and performance metrics directly in your browser. **Features:** + - Template paths, block classes, and module names - PHP render times and cache status (lifetime, tags) - Web Vitals: LCP, CLS, INP per element - Accessibility checks: ARIA roles, contrast ratios, alt text -#### Screenshot +### Screenshot + ![Mageforge Toolbar](./.github/assets/toolbar.jpeg) **Enable:** + ```bash bin/magento mageforge:theme:inspector enable ``` -*(Requires Developer Mode. Can also be enabled in Admin: `Stores > Configuration > MageForge > Frontend Inspector`)* + +_(Requires Developer Mode. Can also be enabled in Admin: `Stores > Configuration > MageForge > Frontend Inspector`)_ **Use in Browser:** + - Toggle: `Ctrl+Shift+I` (Windows/Linux) or `Cmd+Option+I` (macOS) - Hover over elements to inspect; click to lock on a specific block @@ -121,13 +126,12 @@ See the dedicated [Commands Reference](./docs/commands_reference.md) for complet - **Discussions:** [GitHub Discussions](https://github.com/OpenForgeProject/mageforge/discussions) - **Contributing:** See [Contributing Guidelines](./CONTRIBUTING.md) - ## Credits MageForge uses the following third-party libraries: -| Library | Author | License | -| ------- | ------ | ------- | +| Library | Author | License | +| --------------------------------------- | -------- | --------------------------------------------------------------- | | [Tabler Icons](https://tabler.io/icons) | codecalm | [MIT](https://github.com/tabler/tabler-icons/blob/main/LICENSE) | --- diff --git a/composer.json b/composer.json index 724d1773..526b47ae 100644 --- a/composer.json +++ b/composer.json @@ -16,5 +16,29 @@ "php": "~8.3.0||~8.4.0||~8.5.0", "magento/framework": "103.0.*", "laravel/prompts": "^0.3.5" + }, + "require-dev": { + "carthage-software/mago": "^1.30", + "magento/magento-coding-standard": "^40" + }, + "repositories": [ + { + "type": "composer", + "url": "https://mirror.mage-os.org/" + } + ], + "config": { + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "magento/composer-dependency-version-audit-plugin": true + } + }, + "scripts": { + "lint": "mago lint", + "fmt": "mago fmt", + "fmt:check": "mago fmt --dry-run", + "phpcs": "phpcs -p -s", + "phpcbf": "phpcbf -p" } } diff --git a/docs/commands_reference.md b/docs/commands_reference.md index 84ab196d..118a1f5a 100644 --- a/docs/commands_reference.md +++ b/docs/commands_reference.md @@ -4,17 +4,17 @@ Complete reference of all CLI commands provided by the MageForge module. ## Quick Overview -| Group | Command | Description | Aliases | -|-------|---------|-------------|---------| -| **Theme** | `mageforge:theme:list` | List all available Magento themes | `frontend:list` | -| **Theme** | `mageforge:theme:build` | Build selected themes (CSS/TailwindCSS) | `frontend:build` | -| **Theme** | `mageforge:theme:watch` | Watch theme files and auto-rebuild | `frontend:watch` | -| **Theme** | `mageforge:theme:clean` | Clean static files and cache directories | `frontend:clean` | -| **Theme** | `mageforge:theme:inspector` | Manage Frontend Inspector (enable/disable/status) | — | -| **Hyvä** | `mageforge:hyva:tokens` | Generate Hyvä design tokens | `hyva:tokens` | -| **Hyvä** | `mageforge:hyva:compatibility:check` | Check modules for Hyvä compatibility issues | `hyva:check` | -| **System** | `mageforge:system:version` | Show current and latest module version | `system:version` | -| **System** | `mageforge:system:check` | Display system information (PHP, Node.js, DB, etc.) | `system:check` | +| Group | Command | Description | Aliases | +| ---------- | ------------------------------------ | --------------------------------------------------- | ---------------- | +| **Theme** | `mageforge:theme:list` | List all available Magento themes | `frontend:list` | +| **Theme** | `mageforge:theme:build` | Build selected themes (CSS/TailwindCSS) | `frontend:build` | +| **Theme** | `mageforge:theme:watch` | Watch theme files and auto-rebuild | `frontend:watch` | +| **Theme** | `mageforge:theme:clean` | Clean static files and cache directories | `frontend:clean` | +| **Theme** | `mageforge:theme:inspector` | Manage Frontend Inspector (enable/disable/status) | — | +| **Hyvä** | `mageforge:hyva:tokens` | Generate Hyvä design tokens | `hyva:tokens` | +| **Hyvä** | `mageforge:hyva:compatibility:check` | Check modules for Hyvä compatibility issues | `hyva:check` | +| **System** | `mageforge:system:version` | Show current and latest module version | `system:version` | +| **System** | `mageforge:system:check` | Display system information (PHP, Node.js, DB, etc.) | `system:check` | --- @@ -44,9 +44,11 @@ bin/magento frontend:build Magento/luma Magento/blank ``` **Arguments:** + - `themeCodes` — One or more theme codes in format `Vendor/theme`. Accepts wildcards like `Magento/*`. **Behavior:** + - If no theme codes are provided, an interactive prompt lets you select themes. - For each theme, the appropriate builder is determined automatically (Hyvä, TailwindCSS, Magento Standard, etc.). - Displays a summary of built themes and execution time. @@ -63,12 +65,15 @@ bin/magento frontend:watch Magento/luma ``` **Arguments:** + - `themeCode` — Optional. Theme to watch in format `Vendor/theme`. If omitted, an interactive prompt appears. **Options:** + - `-t, --theme=VALUE` — Alternative way to specify the theme code. **Behavior:** + - Runs indefinitely until interrupted (Ctrl+C). - Monitors source files (SCSS, JS, etc.) and triggers rebuilds on change. - Useful for active theme development. @@ -86,9 +91,11 @@ bin/magento mageforge:theme:clean --dry-run ``` **Arguments:** + - `themeCodes` — Optional. One or more theme codes to clean. **Options:** + - `-a, --all` — Clean all themes. - `--dry-run` — Show what would be cleaned without actually deleting anything. @@ -105,9 +112,11 @@ bin/magento mageforge:theme:inspector status ``` **Arguments:** + - `action` — Required. One of: `enable`, `disable`, `status`. **Notes:** + - Requires Magento Developer Mode for enabling. - Can also be toggled via Admin: `Stores > Configuration > MageForge > Frontend Inspector`. - Browser shortcut: `Ctrl+Shift+I` (Windows/Linux) or `Cmd+Option+I` (macOS). @@ -127,6 +136,7 @@ bin/magento hyva:tokens Hyva/default ``` **Arguments:** + - `themeCode` — Optional. Theme code in format `Vendor/theme`. If omitted, an interactive prompt appears. **Output:** Creates a `generated/hyva-tokens.css` file from the design tokens configuration. @@ -143,8 +153,9 @@ bin/magento hyva:check ``` **Options:** + - `-a, --show-all` — Show all modules including compatible ones. -- `-t, --third-party-only` — Check only third-party modules (exclude Magento_*). +- `-t, --third-party-only` — Check only third-party modules (exclude Magento\_\*). - `--include-vendor` — Include Magento core modules in the check. - `--detailed` — Show detailed compatibility information. @@ -177,6 +188,7 @@ bin/magento system:check ``` **Reports:** + - PHP version and extensions - Magento version - Database type and version (MySQL/MariaDB) @@ -192,7 +204,7 @@ bin/magento system:check ## Command Groups Summary -``` +```text mageforge:theme:list → List available themes mageforge:theme:build → Build theme assets mageforge:theme:watch → Watch & auto-rebuild diff --git a/docs/custom_theme_builders.md b/docs/custom_theme_builders.md index 7afcd5b6..b75240e0 100644 --- a/docs/custom_theme_builders.md +++ b/docs/custom_theme_builders.md @@ -18,7 +18,7 @@ The ThemeBuilder architecture consists of the following components: To create your own ThemeBuilder, you'll need to set up a custom Magento 2 module with the following structure: -``` +```text app/code/YourCompany/YourModule/ ├── Console/ │ └── Command/ @@ -43,6 +43,7 @@ First, create the basic module structure as shown above: 1. Create the module directory: `app/code/YourCompany/YourModule/` 2. Create a registration.php file: + ```php