From 81080eaa8f90d906bc840da5d8e6812a317b5f2f Mon Sep 17 00:00:00 2001 From: Jonas Scholl <43819845+JonasScholl@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:16:49 +0200 Subject: [PATCH] chore: roll out SonarQube, Cursor agents, Lefthook, and CI quality gate SonarLint/MCP/hooks (JS+PHP commit gate), Lefthook replacing Husky, yearly Dependabot (npm, github-actions, composer), and Sonar quality gate. Co-authored-by: Cursor --- .cursor/hooks.json | 48 ++++++++ .cursor/hooks/sonar-gate-commit.sh | 62 ++++++++++ .../build-scripts/before-read-file-secrets.sh | 5 + .../build-scripts/pre-tool-use-secrets.sh | 5 + .../build-scripts/prompt-secrets.sh | 5 + .cursor/hooks/sonar-track-analysis.sh | 38 ++++++ .cursor/mcp.json | 18 +++ .cursor/rules/sonarqube_mcp_instructions.mdc | 14 +++ .github/dependabot.yml | 23 +++- .github/workflows/branch.yaml | 13 +++ .gitignore | 5 + .husky/pre-commit | 1 - .sonarlint/connectedMode.json | 4 + .vscode/extensions.json | 3 + .vscode/settings.json | 32 +++-- AGENTS.md | 8 +- CLAUDE.md | 1 + docs/ci.md | 19 +++ lefthook.yml | 6 + package.json | 4 +- pnpm-lock.yaml | 110 ++++++++++++++++-- pnpm-workspace.yaml | 1 + 22 files changed, 398 insertions(+), 27 deletions(-) create mode 100644 .cursor/hooks.json create mode 100755 .cursor/hooks/sonar-gate-commit.sh create mode 100755 .cursor/hooks/sonar-secrets/build-scripts/before-read-file-secrets.sh create mode 100755 .cursor/hooks/sonar-secrets/build-scripts/pre-tool-use-secrets.sh create mode 100755 .cursor/hooks/sonar-secrets/build-scripts/prompt-secrets.sh create mode 100755 .cursor/hooks/sonar-track-analysis.sh create mode 100644 .cursor/mcp.json create mode 100644 .cursor/rules/sonarqube_mcp_instructions.mdc delete mode 100755 .husky/pre-commit create mode 100644 .sonarlint/connectedMode.json create mode 100644 .vscode/extensions.json create mode 120000 CLAUDE.md create mode 100644 docs/ci.md create mode 100644 lefthook.yml diff --git a/.cursor/hooks.json b/.cursor/hooks.json new file mode 100644 index 00000000..4dd8bff3 --- /dev/null +++ b/.cursor/hooks.json @@ -0,0 +1,48 @@ +{ + "version": 1, + "hooks": { + "afterMCPExecution": [ + { + "command": ".cursor/hooks/sonar-track-analysis.sh", + "matcher": "analyze_file_list|analyze_code_snippet" + } + ], + "postToolUse": [ + { + "command": ".cursor/hooks/sonar-track-analysis.sh", + "matcher": "CallDynamicTool|MCP:.*(analyze_file_list|analyze_code_snippet)" + } + ], + "beforeShellExecution": [ + { + "command": ".cursor/hooks/sonar-gate-commit.sh", + "matcher": "git\\s+commit", + "failClosed": true + } + ], + "preToolUse": [ + { + "command": ".cursor/hooks/sonar-secrets/build-scripts/pre-tool-use-secrets.sh", + "matcher": "Read", + "timeout": 60, + "failClosed": false + } + ], + "beforeReadFile": [ + { + "command": ".cursor/hooks/sonar-secrets/build-scripts/before-read-file-secrets.sh", + "matcher": "Read|TabRead", + "timeout": 60, + "failClosed": false + } + ], + "beforeSubmitPrompt": [ + { + "command": ".cursor/hooks/sonar-secrets/build-scripts/prompt-secrets.sh", + "matcher": "UserPromptSubmit", + "timeout": 60, + "failClosed": false + } + ] + } +} diff --git a/.cursor/hooks/sonar-gate-commit.sh b/.cursor/hooks/sonar-gate-commit.sh new file mode 100755 index 00000000..4ec67c0d --- /dev/null +++ b/.cursor/hooks/sonar-gate-commit.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# Deny agent git commits that stage JS/TS/PHP unless Sonar MCP analysis ran this session. +set -euo pipefail + +input=$(cat) +command=$(printf '%s' "$input" | node -e ' + let d=""; process.stdin.on("data",c=>d+=c); process.stdin.on("end",()=>{ + try { console.log(JSON.parse(d).command||""); } catch { console.log(""); } + }); +') + +# Only gate real commits (not commit --help / dry-run style if ever passed oddly). +if ! printf '%s' "$command" | grep -Eq '(^|[[:space:];|&])git[[:space:]]+commit([[:space:]]|$)'; then + printf '%s\n' '{"permission":"allow"}' + exit 0 +fi + +root="${CURSOR_PROJECT_DIR:-.}" +cd "$root" + +staged=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null || true) +analyzed=$(printf '%s\n' "$staged" | grep -E '\.(ts|tsx|js|jsx|php)$' || true) + +if [[ -z "$analyzed" ]]; then + printf '%s\n' '{"permission":"allow"}' + exit 0 +fi + +stamp_file="$root/.git/sonar-agent-analyzed" +if [[ ! -f "$stamp_file" ]]; then + node -e ' + const msg = "Sonar before commit: staged JS/TS/PHP files require SonarQube MCP analyze_code_snippet on each changed file first (see AGENTS.md). Fix any issues, then retry the commit. Lefthook/Biome is not a substitute."; + console.log(JSON.stringify({ + permission: "deny", + user_message: "Blocked: run SonarQube MCP analyze_code_snippet on staged JS/TS/PHP before committing.", + agent_message: msg + })); + ' + exit 0 +fi + +# Require a successful analysis stamp from the last hour (same agent session window). +if ! node -e ' + const fs = require("fs"); + const path = process.argv[1]; + const st = fs.statSync(path); + const ageMs = Date.now() - st.mtimeMs; + process.exit(ageMs <= 60 * 60 * 1000 ? 0 : 1); +' "$stamp_file"; then + node -e ' + const msg = "Sonar before commit: previous analyze_code_snippet stamp is stale (>1h). Re-run SonarQube MCP analyze_code_snippet on each staged JS/TS/PHP file, then retry the commit."; + console.log(JSON.stringify({ + permission: "deny", + user_message: "Blocked: Sonar analysis stamp is stale. Re-analyze staged JS/TS/PHP before committing.", + agent_message: msg + })); + ' + exit 0 +fi + +printf '%s\n' '{"permission":"allow"}' +exit 0 diff --git a/.cursor/hooks/sonar-secrets/build-scripts/before-read-file-secrets.sh b/.cursor/hooks/sonar-secrets/build-scripts/before-read-file-secrets.sh new file mode 100755 index 00000000..5d5f0fd6 --- /dev/null +++ b/.cursor/hooks/sonar-secrets/build-scripts/before-read-file-secrets.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if ! command -v sonar &> /dev/null; then + exit 0 +fi +sonar hook cursor-pre-file-read diff --git a/.cursor/hooks/sonar-secrets/build-scripts/pre-tool-use-secrets.sh b/.cursor/hooks/sonar-secrets/build-scripts/pre-tool-use-secrets.sh new file mode 100755 index 00000000..5eae3931 --- /dev/null +++ b/.cursor/hooks/sonar-secrets/build-scripts/pre-tool-use-secrets.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if ! command -v sonar &> /dev/null; then + exit 0 +fi +sonar hook cursor-pre-tool-use diff --git a/.cursor/hooks/sonar-secrets/build-scripts/prompt-secrets.sh b/.cursor/hooks/sonar-secrets/build-scripts/prompt-secrets.sh new file mode 100755 index 00000000..21876194 --- /dev/null +++ b/.cursor/hooks/sonar-secrets/build-scripts/prompt-secrets.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if ! command -v sonar &> /dev/null; then + exit 0 +fi +sonar hook cursor-prompt-submit diff --git a/.cursor/hooks/sonar-track-analysis.sh b/.cursor/hooks/sonar-track-analysis.sh new file mode 100755 index 00000000..3eeab040 --- /dev/null +++ b/.cursor/hooks/sonar-track-analysis.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Record successful SonarQube MCP live-analysis calls for the commit gate. +set -euo pipefail + +input=$(cat) +root="${CURSOR_PROJECT_DIR:-$(pwd)}" +stamp_dir="${root}/.git" +stamp_file="${stamp_dir}/sonar-agent-analyzed" + +is_analyze=$(printf '%s' "$input" | node -e ' + let d=""; process.stdin.on("data",c=>d+=c); process.stdin.on("end",()=>{ + try { + const j=JSON.parse(d); + const blob=JSON.stringify(j).toLowerCase(); + const hit = + blob.includes("analyze_file_list") || + blob.includes("analyze_code_snippet") || + /analyze_file_list|analyze_code_snippet/.test( + String(j.toolName||j.tool_name||j.name||j.tool||"") + ); + const failed = + /"status"\s*:\s*"(error|failed|failure|denied)"/i.test(blob) || + j.error != null; + process.stdout.write(hit && !failed ? "yes" : "no"); + } catch { + process.stdout.write("no"); + } + }); +') + +if [[ "$is_analyze" != "yes" ]]; then + exit 0 +fi + +mkdir -p "$stamp_dir" +date -u +%Y-%m-%dT%H:%M:%SZ >> "$stamp_file" +tail -n 50 "$stamp_file" > "${stamp_file}.tmp" && mv "${stamp_file}.tmp" "$stamp_file" +exit 0 diff --git a/.cursor/mcp.json b/.cursor/mcp.json new file mode 100644 index 00000000..e9bc2b7c --- /dev/null +++ b/.cursor/mcp.json @@ -0,0 +1,18 @@ +{ + "mcpServers": { + "sonarqube": { + "command": "sonar", + "args": [ + "run", + "mcp", + "--project", + "tebuto_wordpress-plugin_d85838b5-fae9-48e3-9636-0ec145a330f3", + "--toolsets", + "analysis,ide,issues,quality-gates,rules,duplications,measures,security-hotspots,coverage" + ], + "env": { + "SONARQUBE_IDE_PORT": "64120" + } + } + } +} diff --git a/.cursor/rules/sonarqube_mcp_instructions.mdc b/.cursor/rules/sonarqube_mcp_instructions.mdc new file mode 100644 index 00000000..29ac2863 --- /dev/null +++ b/.cursor/rules/sonarqube_mcp_instructions.mdc @@ -0,0 +1,14 @@ +--- +description: SonarQube live analysis for agents +alwaysApply: true +--- + +# SonarQube (local) + +Live analysis is SonarQube MCP `analyze_code_snippet` (workspace-mounted; pass project-relative `filePath`, `language`, `scope`). Use `analyze_file_list` instead only if that tool exists. Do not run `sonar-scanner`. Do not use `search_sonar_issues_in_projects` to verify edits (the server lags local analysis). + +Project key is `sonar.projectKey` in `sonar-project.properties`. Do not look it up. + +After creating or modifying `*.ts`, `*.tsx`, `*.js`, `*.jsx`, or `*.php`, analyze each changed file. Fix every issue, re-analyze, then finish. The same analysis is required before `git commit` of JS/TS/PHP (Lefthook/Biome/PHPCS is not a substitute). + +Leave IDE automatic analysis on. Do not call `toggle_automatic_analysis`. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0b6bd83f..fce0b22b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,22 +4,35 @@ updates: directory: / target-branch: main schedule: - interval: monthly + interval: yearly + open-pull-requests-limit: 10 assignees: - jonasscholl groups: - all: + dependencies: patterns: - "*" - package-ecosystem: github-actions directory: / schedule: - interval: weekly + interval: yearly + open-pull-requests-limit: 5 assignees: - JonasScholl - open-pull-requests-limit: 10 groups: - all: + github-actions: + patterns: + - "*" + + - package-ecosystem: composer + directory: / + schedule: + interval: yearly + open-pull-requests-limit: 5 + assignees: + - jonasscholl + groups: + composer: patterns: - "*" diff --git a/.github/workflows/branch.yaml b/.github/workflows/branch.yaml index ca419e87..e614ea79 100644 --- a/.github/workflows/branch.yaml +++ b/.github/workflows/branch.yaml @@ -1,11 +1,17 @@ name: Branch +# Runner: ubuntu-latest (tebuto org) — see docs/ci.md. + on: push: branches: - main pull_request: +concurrency: + group: branch-${{ github.ref }} + cancel-in-progress: true + jobs: build: name: Build & Lint @@ -69,3 +75,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + + - name: SonarQube Quality Gate + uses: SonarSource/sonarqube-quality-gate-action@v1 + timeout-minutes: 5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} diff --git a/.gitignore b/.gitignore index ad07a31e..f12e085e 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,11 @@ vendor/ # Local tooling .playwright-mcp/ +.scannerwork/ + +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json # npm lockfiles (this repo uses pnpm) package-lock.json diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 23b9a806..00000000 --- a/.husky/pre-commit +++ /dev/null @@ -1 +0,0 @@ -pnpm lint:fix diff --git a/.sonarlint/connectedMode.json b/.sonarlint/connectedMode.json new file mode 100644 index 00000000..bd322727 --- /dev/null +++ b/.sonarlint/connectedMode.json @@ -0,0 +1,4 @@ +{ + "sonarQubeUri": "https://sonar.artus-engineering.de", + "projectKey": "tebuto_wordpress-plugin_d85838b5-fae9-48e3-9636-0ec145a330f3" +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..bfef60b0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["biomejs.biome", "sonarsource.sonarlint-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 22b1c785..6c960224 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,15 +1,33 @@ { + "editor.defaultFormatter": "biomejs.biome", "editor.formatOnSave": true, - "files.insertFinalNewline": true, - "files.trimTrailingWhitespace": true, + "editor.codeActionsOnSave": { + "source.fixAll.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, "[javascript]": { - "editor.defaultFormatter": "vscode.json-language-features" + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" }, "[json]": { - "editor.defaultFormatter": "vscode.json-language-features" + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" }, - "[markdown]": { - "editor.defaultFormatter": "vscode.markdown-language-features" + "[css]": { + "editor.defaultFormatter": "biomejs.biome" }, - "markdown.extension.toc.levels": "1..6" + "sonarlint.connectedMode.project": { + "connectionId": "https-sonar-artus-engineering-de", + "projectKey": "tebuto_wordpress-plugin_d85838b5-fae9-48e3-9636-0ec145a330f3" + } } diff --git a/AGENTS.md b/AGENTS.md index bf62a0f0..d1368d5b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -71,9 +71,13 @@ pnpm version:bump 2.3.0 # Bump version in all tracked files (or patch/minor/ma Local WordPress: http://localhost:8000 — plugin path `wordpress/wp-content/plugins/tebuto-online-terminbuchung/`. -CI (`.github/workflows/branch.yaml`): `pnpm install --frozen-lockfile`, `composer install`, `lint`, `build:block`, `version:check`, `build.sh`. +CI (`.github/workflows/branch.yaml`): `pnpm install --frozen-lockfile`, `composer install`, `lint`, `build:block`, `version:check`, `build.sh` → SonarQube scan + quality gate on `ubuntu-latest`. See [`docs/ci.md`](docs/ci.md). -Pre-commit (Husky): runs `pnpm lint:fix` on the whole codebase (Biome + PHPCS). Requires `pnpm install` and `composer install`. +**Lefthook** formats/lints staged JS/JSON/CSS on commit (`lefthook.yml`). Run `pnpm lint` / `pnpm lint:php` for PHP before committing PHP changes. + +**SonarQube:** `sonar-project.properties`, SonarLint, Cursor MCP `analyze_code_snippet` on changed JS/TS/PHP before agent commits. See `.cursor/rules/sonarqube_mcp_instructions.mdc`. Lefthook/Biome/PHPCS is not a substitute. + +**Dependabot** runs yearly; weekly updates via Cursor Automation. Cross-project guide: Artus portal wiki **Repository Tooling (SonarQube, CI, Cursor Agents)**. ## Coding conventions diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 00000000..47dc3e3d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/docs/ci.md b/docs/ci.md new file mode 100644 index 00000000..6c1c6325 --- /dev/null +++ b/docs/ci.md @@ -0,0 +1,19 @@ +# CI (GitHub Actions) + +Runner: `ubuntu-latest` for tebuto org repos. Cross-project tooling: Artus portal wiki **Repository Tooling (SonarQube, CI, Cursor Agents)**. + +## Workflows + +| File | Purpose | +| --- | --- | +| `.github/workflows/branch.yaml` | Build, lint (JS + PHP) → SonarQube scan → quality gate | + +## Required checks + +After rollout, enable on `main`: + +- **Build & Lint** +- **SonarQube Scan** +- **SonarQube Quality Gate** + +Secrets: `SONAR_TOKEN`, `SONAR_HOST_URL`. diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 00000000..30dcc442 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,6 @@ +pre-commit: + commands: + check: + glob: "*.{js,ts,mts,cts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,css}" + run: pnpm exec biome check --write --no-errors-on-unmatched --files-ignore-unknown=true {staged_files} + stage_fixed: true diff --git a/package.json b/package.json index b36cfd83..fe4bd938 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "lint:php": "composer lint", "lint:php:fix": "composer fix || [ $? -eq 1 ]", "lint:fix": "pnpm format && pnpm lint:php:fix && pnpm lint", - "prepare": "husky", + "prepare": "node -e \"const on=v=>!!v&&v!=='0'&&v!=='false';if(on(process.env.CI)&&!on(process.env.LEFTHOOK))process.exit(0);try{require('child_process').execSync('lefthook install --reset-hooks-path',{stdio:'inherit'})}catch{}\"", "start": "pnpm --filter tebuto-online-terminbuchung-block run start", "dev:setup": "./scripts/dev-setup.sh", "dev:up": "docker compose up -d", @@ -53,6 +53,6 @@ "@biomejs/biome": "2.5.9", "chokidar-cli": "^3", "concurrently": "^10.0.5", - "husky": "^9" + "lefthook": "^2.1.10" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7147e54..92a3547e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,9 +25,9 @@ importers: concurrently: specifier: ^10.0.5 version: 10.0.5 - husky: - specifier: ^9 - version: 9.1.7 + lefthook: + specifier: ^2.1.10 + version: 2.1.10 tebuto-online-terminbuchung/block: dependencies: @@ -4678,11 +4678,6 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - husky@9.1.7: - resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} - engines: {node: '>=18'} - hasBin: true - hyperdyperid@1.2.0: resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} engines: {node: '>=10.18'} @@ -5248,6 +5243,60 @@ packages: launch-editor@2.14.1: resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + lefthook-darwin-arm64@2.1.10: + resolution: {integrity: sha512-nw+X8wRNDoUUV6WSteyKBbcLySq+fsmZt5WV/s50ZJpysmsDKJOUMln6SllNfP+60dzUahAO7REco/2633BsLg==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@2.1.10: + resolution: {integrity: sha512-KQ/bHmvpkFdHMn4pZnUdTf+GuSC+aBBgBTxZT4GW+6cSf+qbErKZBhK7cH6BmILsvx43+VzEArvHYY7YOfRFOQ==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@2.1.10: + resolution: {integrity: sha512-8su6DwydP7+pv7kG0zCtjphqsw4ouOnfexRUErapy5GTxYBoUOhYz3RSHTSWNRsK6W4jva7FPUh2Lp5/PSn30w==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@2.1.10: + resolution: {integrity: sha512-GeAJEFxko3Lk+AsnS3NleAFrpyMLFUKOlgJvPKuU0xHwVEI/z+ZoCcmuO0BX+4CS0NLbZhC/YQAvBASqDvvVdQ==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@2.1.10: + resolution: {integrity: sha512-1sHTCmpTWjVMs+yKPBLRNT1kuuIr1yjietlk7rCB6wFPVOS6Ph3o2zPFH2AvW1UymHlqwyHXzBr9EtDpQ7j1mQ==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@2.1.10: + resolution: {integrity: sha512-z/VlRB3bh6mBvW3r1rwnJ5vP8z+Krx5gJzkZ4veDXh+6FlRTx8wtd3g3fllOv/yZMxkgmL3fQoFXv05Esa7vBQ==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@2.1.10: + resolution: {integrity: sha512-430zL8sSIKw5P0YXGG6PB+eAhHa06n0PXuaERaAQE4Ss3odfqwnl5Mq9hQmkEnOS1EGiQEKkd0UHv/i4PtMNIQ==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@2.1.10: + resolution: {integrity: sha512-bgkO8PphGZVDhQgCJ524aYYPI5491pVmCiLPGjBIo1AvOSlIyw4N1Y+1C3QfqwEmechzw+Aq16SNc8pqv6UuXg==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@2.1.10: + resolution: {integrity: sha512-5Q6etF0Fla2DDA4ilDySrdNgiR5+W7cJZwnZ69Je3kvWCaWm4wnkuc8FEdjp3kiL2x3ZXipdI00f5vpO8aWmog==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@2.1.10: + resolution: {integrity: sha512-c/XH8YZtylG4XaxzqFfXluvq2LXq2W/p54Bnzn3+Z7E5X2Fk3JlFJAibulMbIt2+w8T7UI/r97ok5GqE4kGaeA==} + cpu: [x64] + os: [win32] + + lefthook@2.1.10: + resolution: {integrity: sha512-K7mM4WoqMwqfXYK11EHy+lSH1uW8XHni3Yn/bSqyerPkUPygGdf3xn18JoV5HyA06xuQL3ofGAOjG01QX9oJ4w==} + hasBin: true + legacy-javascript@0.0.1: resolution: {integrity: sha512-lPyntS4/aS7jpuvOlitZDFifBCb4W8L/3QU0PLbUTUj+zYah8rfVjYic88yG7ZKTxhS5h9iz7duT8oUXKszLhg==} @@ -13416,8 +13465,6 @@ snapshots: human-signals@2.1.0: {} - husky@9.1.7: {} - hyperdyperid@1.2.0: {} iconv-lite@0.4.24: @@ -14177,6 +14224,49 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.10.0 + lefthook-darwin-arm64@2.1.10: + optional: true + + lefthook-darwin-x64@2.1.10: + optional: true + + lefthook-freebsd-arm64@2.1.10: + optional: true + + lefthook-freebsd-x64@2.1.10: + optional: true + + lefthook-linux-arm64@2.1.10: + optional: true + + lefthook-linux-x64@2.1.10: + optional: true + + lefthook-openbsd-arm64@2.1.10: + optional: true + + lefthook-openbsd-x64@2.1.10: + optional: true + + lefthook-windows-arm64@2.1.10: + optional: true + + lefthook-windows-x64@2.1.10: + optional: true + + lefthook@2.1.10: + optionalDependencies: + lefthook-darwin-arm64: 2.1.10 + lefthook-darwin-x64: 2.1.10 + lefthook-freebsd-arm64: 2.1.10 + lefthook-freebsd-x64: 2.1.10 + lefthook-linux-arm64: 2.1.10 + lefthook-linux-x64: 2.1.10 + lefthook-openbsd-arm64: 2.1.10 + lefthook-openbsd-x64: 2.1.10 + lefthook-windows-arm64: 2.1.10 + lefthook-windows-x64: 2.1.10 + legacy-javascript@0.0.1: {} leven@3.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5614dad9..96bcc0cf 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -20,4 +20,5 @@ allowBuilds: core-js: false core-js-pure: false fsevents: false + lefthook: true unrs-resolver: false