diff --git a/.claude/agents/recce-pr-verifier.md b/.claude/agents/recce-pr-verifier.md index b7dc9c9ee..09b27e4aa 100644 --- a/.claude/agents/recce-pr-verifier.md +++ b/.claude/agents/recce-pr-verifier.md @@ -95,7 +95,7 @@ uv run pytest tests/test_foo.py --cov=recce.module --cov-report=term-missing ### Frontend (TypeScript) — only if `js/` changed -For frontend tooling specifics (pnpm v11 quirks, Biome config, style conventions), see **[`js/CLAUDE.md`](../../js/CLAUDE.md)**. +For frontend tooling specifics (pnpm v12 quirks, Biome config, style conventions), see **[`js/CLAUDE.md`](../../js/CLAUDE.md)**. ```bash cd js diff --git a/.claude/skills/address-dependabot/skill.md b/.claude/skills/address-dependabot/skill.md index a82a01cee..b9a41767c 100644 --- a/.claude/skills/address-dependabot/skill.md +++ b/.claude/skills/address-dependabot/skill.md @@ -50,7 +50,7 @@ digraph address_dependabot { This repo contains `@datarecce/ui`, a **published npm package** consumed by external projects. Its `dependencies` field is a contract with consumers. This shapes how dependency updates are applied. -For frontend tooling context (pnpm v11 `strictDepBuilds`/`allowBuilds`, Biome migration on bump, Node.js 26 via `nave`), reference **[`js/CLAUDE.md`](../../../js/CLAUDE.md)** before applying npm updates. +For frontend tooling context (pnpm v12 `strictDepBuilds`/`allowBuilds`, Biome migration on bump, Node.js 26 via `nave`), reference **[`js/CLAUDE.md`](../../../js/CLAUDE.md)** before applying npm updates. ### The Three Zones diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index c284d8503..b1b06d109 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,6 +1,6 @@ # Recce Copilot Instructions -> Claude Code and other agents using `CLAUDE.md` should also consult **[`js/CLAUDE.md`](../js/CLAUDE.md)** for frontend tooling specifics (pnpm commands, Biome, Vitest, `@datarecce/ui` publishing, pnpm v11 `strictDepBuilds`/`allowBuilds`, style conventions). This file remains the canonical Copilot context. +> Claude Code and other agents using `CLAUDE.md` should also consult **[`js/CLAUDE.md`](../js/CLAUDE.md)** for frontend tooling specifics (pnpm commands, Biome, Vitest, `@datarecce/ui` publishing, pnpm v12 `strictDepBuilds`/`allowBuilds`, style conventions). This file remains the canonical Copilot context. ## Project Overview @@ -86,7 +86,7 @@ below: ```bash cd js -pnpm install # Uses pnpm 11, NOT npm or yarn +pnpm install # Uses pnpm 12, NOT npm or yarn ``` **Development Server:** @@ -218,7 +218,7 @@ recce/ ``` js/ -├── package.json # pnpm 11, Node >=26.5.0, React 19, Next.js 16 +├── package.json # pnpm 12, Node >=26.5.0, React 19, Next.js 16 ├── tsconfig.json # TypeScript config ├── next.config.js # Next.js config (output: 'export') ├── app/ # OSS Next.js App Router shell (routes/layout only) diff --git a/.github/instructions/frontend-instructions.md b/.github/instructions/frontend-instructions.md index 6ff5eb069..518ea02f1 100644 --- a/.github/instructions/frontend-instructions.md +++ b/.github/instructions/frontend-instructions.md @@ -4,7 +4,7 @@ applyTo: "js/**/*.ts,js/**/*.tsx,js/**/*.js,js/**/*.jsx,js/**/*.json,js/**/*.mjs # Frontend Build Instructions (js/ Directory) -> This file is the **Copilot-targeted** frontend guide (scoped via `applyTo:` frontmatter). Claude Code and other agents using `CLAUDE.md` should consult **[`js/CLAUDE.md`](../../js/CLAUDE.md)** for the equivalent guidance — both should stay in sync on tooling specifics (pnpm v11, Biome, `@datarecce/ui` publishing, style conventions). +> This file is the **Copilot-targeted** frontend guide (scoped via `applyTo:` frontmatter). Claude Code and other agents using `CLAUDE.md` should consult **[`js/CLAUDE.md`](../../js/CLAUDE.md)** for the equivalent guidance — both should stay in sync on tooling specifics (pnpm v12, Biome, `@datarecce/ui` publishing, style conventions). ## Critical Frontend Build Requirements @@ -27,7 +27,7 @@ pnpm run build ## Package Manager - MUST use pnpm ```bash -# CORRECT - Always use pnpm (version 11) +# CORRECT - Always use pnpm (version 12) pnpm install pnpm dev pnpm run build @@ -87,7 +87,7 @@ pnpm run clean ## Tech Stack - **Node.js >=26.5.0** - JavaScript runtime (required) -- **pnpm 11** - Package manager (NOT npm or yarn) +- **pnpm 12** - Package manager (NOT npm or yarn) - **Next.js 16** - React framework with App Router - **React 19.2** - UI library with new JSX transform - **React DOM 19.2** - React renderer @@ -130,7 +130,7 @@ js/ **package.json:** - Requires Node.js >=26.5.0 -- Uses pnpm@11.1.1 as package manager (pinned via Corepack) +- Uses pnpm@12.4.1 as package manager (pinned via Corepack) - Key scripts: - `dev`: Start development server with Turbopack - `build`: Clean, build Next.js, move to ../recce/data @@ -225,7 +225,7 @@ pnpm test # Watch mode **What it checks:** 1. Node.js 26.5.0 setup from `js/.nvmrc` -2. pnpm 11 installation +2. pnpm 12 installation 3. Dependency install with frozen lockfile 4. Biome linting (`pnpm lint`) 5. Production build (`pnpm run build`) diff --git a/.github/workflows/address-dependabot.yaml b/.github/workflows/address-dependabot.yaml index 04fc41013..ce8e89539 100644 --- a/.github/workflows/address-dependabot.yaml +++ b/.github/workflows/address-dependabot.yaml @@ -41,9 +41,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml + + - name: Verify pnpm version + working-directory: ./js + run: | + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Install frontend dependencies working-directory: ./js diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index f42017b52..8d2f23817 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -40,9 +40,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml + + - name: Verify pnpm version + working-directory: ./js + run: | + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Install dependencies run: | diff --git a/.github/workflows/release-ui.yaml b/.github/workflows/release-ui.yaml index 30723713a..14af29ab1 100644 --- a/.github/workflows/release-ui.yaml +++ b/.github/workflows/release-ui.yaml @@ -44,18 +44,28 @@ jobs: # For workflow_run, checkout the same ref that triggered the parent workflow ref: ${{ github.event.workflow_run.head_sha || github.sha }} - - uses: pnpm/action-setup@v6 - with: - version: 11.1.1 - - name: Setup Node.js 26 uses: actions/setup-node@v7 with: node-version-file: 'js/.nvmrc' # Node 26 includes npm 11+ with OIDC support - cache: 'pnpm' - cache-dependency-path: js/pnpm-lock.yaml registry-url: 'https://registry.npmjs.org' + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 + with: + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml + + - name: Verify pnpm version + working-directory: ./js + run: | + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" + - name: Verify npm version run: | NPM_VERSION=$(npm --version) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1f2881124..3163a36cd 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -27,9 +27,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml + + - name: Verify pnpm version + working-directory: ./js + run: | + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Install dependencies run: | diff --git a/.github/workflows/tests-js.yaml b/.github/workflows/tests-js.yaml index 42b972da3..1284cc297 100644 --- a/.github/workflows/tests-js.yaml +++ b/.github/workflows/tests-js.yaml @@ -23,23 +23,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 - run_install: false + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml - - name: Get pnpm store directory - shell: bash + - name: Verify pnpm version + working-directory: ./js run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - uses: actions/cache@v4 - name: Setup pnpm cache - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Install dependencies working-directory: ./js @@ -60,23 +58,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 - run_install: false + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml - - name: Get pnpm store directory - shell: bash + - name: Verify pnpm version + working-directory: ./js run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - uses: actions/cache@v4 - name: Setup pnpm cache - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Install dependencies working-directory: ./js diff --git a/.github/workflows/tests-python.yaml b/.github/workflows/tests-python.yaml index 3f9eb3d95..e647b122c 100644 --- a/.github/workflows/tests-python.yaml +++ b/.github/workflows/tests-python.yaml @@ -74,10 +74,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 - run_install: false + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml + + - name: Verify pnpm version + working-directory: ./js + run: | + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Build frontend assets run: make build-frontend @@ -117,10 +128,21 @@ jobs: with: node-version-file: 'js/.nvmrc' - - uses: pnpm/action-setup@v6 + - name: Set up pnpm + uses: pnpm/setup@84cb39b217b10273981911c288cd62326dc7c6d2 # v2.0.2 with: - version: 11.1.1 - run_install: false + package-json-file: js/package.json + install: false + cache: true + cache-dependency-path: js/pnpm-lock.yaml + + - name: Verify pnpm version + working-directory: ./js + run: | + expected=$(node -p "require('./package.json').packageManager.match(/^pnpm@([^+]+)/)[1]") + actual=$(pnpm --version) + echo "pnpm version: $actual" + test "$actual" = "$expected" - name: Build frontend assets run: make build-frontend diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b4c7089fb..2b983f286 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,8 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + # pnpm 12 lockfiles are valid multi-document YAML streams. + exclude: ^js/pnpm-lock\.yaml$ - id: check-added-large-files exclude: ^uv\.lock$ diff --git a/CLAUDE.md b/CLAUDE.md index 431f2d60d..1ae6109ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ ## Quick Reference → `docs/KNOWLEDGE_BASE.md` - Architecture, code patterns, frontend structure, testing, debugging -→ `js/CLAUDE.md` - Frontend conventions and tooling (Node.js 26 via `nave`, Biome, Vitest, pnpm v11 +→ `js/CLAUDE.md` - Frontend conventions and tooling (Node.js 26 via `nave`, Biome, Vitest, pnpm v12 quirks, Storybook imports, CSS color format, rem vs px, shell vs shared code) ## Working Preferences diff --git a/Makefile b/Makefile index c96bdc035..16de8a1a4 100644 --- a/Makefile +++ b/Makefile @@ -94,8 +94,10 @@ test-tox-python-versions: @tox run-parallel -e 3.10,3.11,3.12,3.13 install-frontend-requires: -# Install pnpm if not installed - @command -v pnpm || npm install -g pnpm +# Install Corepack if needed, then provision the pnpm version pinned by js/package.json + @command -v corepack >/dev/null || npm install -g corepack@latest + @corepack enable + @cd js && corepack install @cd js && pnpm install dev: install-frontend-requires diff --git a/docs/KNOWLEDGE_BASE.md b/docs/KNOWLEDGE_BASE.md index cd9251fd8..a4e08a6e0 100644 --- a/docs/KNOWLEDGE_BASE.md +++ b/docs/KNOWLEDGE_BASE.md @@ -21,7 +21,7 @@ Separation of concerns across models, APIs, tasks, adapters, and state. Import r Monorepo with `@datarecce/ui` shared package. OSS app (`js/app/`) stays thin; shared components, hooks, and API clients live in `js/packages/ui/`. → `docs/frontend.md` (structure, import rules, build process) -→ `js/CLAUDE.md` (tooling: pnpm, Biome, Vitest, @datarecce/ui publishing, style conventions, pnpm v11 quirks) +→ `js/CLAUDE.md` (tooling: pnpm, Biome, Vitest, @datarecce/ui publishing, style conventions, pnpm v12 quirks) ## Testing diff --git a/docs/frontend.md b/docs/frontend.md index 601f19d12..13529738b 100644 --- a/docs/frontend.md +++ b/docs/frontend.md @@ -1,6 +1,6 @@ # Frontend Structure -> For frontend tooling specifics (pnpm commands, Biome, Vitest, `@datarecce/ui` publishing, pnpm v11 `strictDepBuilds`/`allowBuilds`, and style conventions), see **[`js/CLAUDE.md`](../js/CLAUDE.md)**. This document focuses on monorepo structure, package boundaries, and the build pipeline. +> For frontend tooling specifics (pnpm commands, Biome, Vitest, `@datarecce/ui` publishing, pnpm v12 `strictDepBuilds`/`allowBuilds`, and style conventions), see **[`js/CLAUDE.md`](../js/CLAUDE.md)**. This document focuses on monorepo structure, package boundaries, and the build pipeline. ## Monorepo Layout diff --git a/js/CLAUDE.md b/js/CLAUDE.md index de808b43e..7e9701a07 100644 --- a/js/CLAUDE.md +++ b/js/CLAUDE.md @@ -46,17 +46,29 @@ When updating frontend deps: Packages requiring overrides (exist in multiple `package.json`): `@emotion/react`, `@mui/material`, `@tanstack/react-query`, `@xyflow/react`, `axios`, `date-fns`, `lodash`, `tailwindcss`, `typescript`, `vitest`. -## pnpm v11 — strictDepBuilds + allowBuilds +## pnpm v12 — strictDepBuilds + allowBuilds -The repo runs on pnpm v11.1.1 (since DRC-3439, 2026-05-13). Four non-obvious behaviors: +The repo runs on pnpm v12.4.1 (updated 2026-09-14). Five non-obvious behaviors: 1. **`strictDepBuilds: true` is on by default.** Any transitive package with a `postinstall` script that isn't explicitly listed in `pnpm-workspace.yaml#allowBuilds` will cause `pnpm install --frozen-lockfile` to hard-fail in CI with `ERR_PNPM_IGNORED_BUILDS`. When a new dep triggers this, add it to `allowBuilds` as `true` (run its postinstall) or `false` (acknowledge it exists, do NOT run postinstall). 2. **Local repro requires CI parity.** Use `CI=true pnpm install --frozen-lockfile` to match CI exactly. The `--ignore-scripts` flag will MASK this failure — do not use it as a verification path. -3. **pnpm 11 silently appends placeholder lines.** If you run `pnpm install` in a non-TTY context and it hits an ignored build, pnpm appends `: set this to true or false` to `pnpm-workspace.yaml#allowBuilds`. Always `git status` after running install — never commit these placeholders. +3. **Never accept generated `allowBuilds` placeholders.** If a non-TTY install discovers an ignored build, inspect `pnpm-workspace.yaml#allowBuilds` for `: set this to true or false`. Always run `git status` after an install and replace any placeholder with a reviewed boolean decision before committing. -4. **`packageManager` must be exact semver.** Corepack rejects ranges like `pnpm@11`. Pin the full `pnpm@11.x.y+sha512.` via `corepack use pnpm@11.x.y` (note the `.` separator between `sha512` and the hash — not `:`). +4. **`packageManager` must be exact semver.** Do not use ranges or dist-tags such as `pnpm@12`, `latest`, or `next-12`. Pin the full `pnpm@12.x.y+sha512.` via `corepack use pnpm@12.x.y` (note the `.` separator between `sha512` and the hash — not `:`). + +5. **The lockfile pins pnpm's platform executables.** Changing `packageManager` requires regenerating `pnpm-lock.yaml` so its leading `packageManagerDependencies` document records pnpm and every supported platform package with integrity hashes. CI's frozen install rejects a mismatched pin. GitHub Actions must read the version from `js/package.json` through the SHA-pinned `pnpm/setup` action rather than duplicate the version in workflow YAML. + +Release notes reviewed for this pin: [12.1](https://pnpm.io/blog/releases/12.1), +[12.2–12.3](https://pnpm.io/blog/releases/12.2-12.3), and +[12.4 / 12.4.1](https://pnpm.io/blog/releases/12.4). +The first install after 12.4 refetches registry metadata because cache keys now +include the full registry URL; the package store remains reusable. Version 12.4.1 +also fixes filesystem copy fallbacks, workspace dependency links, and install +scripts whose side effects live outside their package directory. Verify both +fresh and repeat frozen installs when updating the pin. Python dependencies +continue to use uv; pnpm's experimental Python/Cargo support is opt-in. Canonical `allowBuilds` examples live in recce-cloud-infra: - `recce-cloud-infra/recce-cloud/pnpm-workspace.yaml` diff --git a/js/README.md b/js/README.md index d59c2f503..4342ee3c6 100644 --- a/js/README.md +++ b/js/README.md @@ -5,7 +5,7 @@ nave install "$(cat .nvmrc)" nave use "$(cat .nvmrc)" ``` -2. pnpm +2. pnpm 12 (the exact version is pinned in `package.json`) ``` npm install -g corepack@latest diff --git a/js/package.json b/js/package.json index 958b7be07..88a5cb15f 100644 --- a/js/package.json +++ b/js/package.json @@ -8,7 +8,7 @@ "engines": { "node": ">=26.5.0" }, - "packageManager": "pnpm@11.1.1+sha512.d1fdf5f73c617b64fa1a56a81c3c8dfe0e966e33a6010aa256b517ae77be21d93e05affc0de1a83b0e4f29d569f68b446ae8f068cd7247c0bb3df0fb4d7bdf9a", + "packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c", "scripts": { "dev": "next dev --turbopack", "build": "next build && cp -R out/. ../recce/data/ && rm -rf out", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 73b41aff0..d04c7b1a5 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -1,3 +1,161 @@ +--- +lockfileVersion: '9.0' + +importers: + + .: + configDependencies: {} + packageManagerDependencies: + pnpm: + specifier: 12.4.1 + version: 12.4.1 + +packages: + + '@pnpm/exe.android-arm64@12.4.1': + resolution: {integrity: sha512-/HwsqXMSmlOfgtV9+O0ratzjV6Vd/8n1hh4rGHpCGmDURvt52MwZxdbhyxP4K03ZfvgSDvotFPr8O+RzE5Eu8A==} + cpu: [arm64] + os: [android] + + '@pnpm/exe.android-x64@12.4.1': + resolution: {integrity: sha512-+l74Qb4c2YjOzNKHXJLg+1wr8xHM1ckkUhnU5KRUK9TJqiiczt6yeTZqqzHIlJ8i6pAoj5V0OJevDRwnQKLgrQ==} + cpu: [x64] + os: [android] + + '@pnpm/exe.darwin-arm64@12.4.1': + resolution: {integrity: sha512-6rkZkT3iGfaxknUdGHraqSWFvTa6N0ajAHluv9Ax0GRWs0sIcGNiFhDopv6xSZCsJZmG483aNS/b6UEDy3blfw==} + cpu: [arm64] + os: [darwin] + + '@pnpm/exe.darwin-x64@12.4.1': + resolution: {integrity: sha512-Vb1CHlR88HghC1qUxjxjs82zQSXnXacPD+btG2CmG8Q/hBU7Q0/b2YWJKSQqZXicunV5khFtfTlAwJddV9RkYA==} + cpu: [x64] + os: [darwin] + + '@pnpm/exe.freebsd-x64@12.4.1': + resolution: {integrity: sha512-iT3iHz3Nl0Sxxj7UPOtZ/aQ81AFsQhjoeWMAlPkSRO04gsgDGAXv3UYxOFaesMWsfNxaGn0A+CITbuCHFF66FA==} + cpu: [x64] + os: [freebsd] + + '@pnpm/exe.linux-arm64-musl@12.4.1': + resolution: {integrity: sha512-aBooZfNXM5f+OGUgCAMFWpE/kAhsWfvmqIyMtHy6zl3aNxyInWrcY/Saln/UElzo7lZWMC0Yktroxd/2J26lNQ==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-arm64@12.4.1': + resolution: {integrity: sha512-TlOdacTTP09BgcMvwWBFRsu8VAjfwqwnslBj+XSq1JFM3ck4f3k+1O/747EuctxZxs3/o785b6Q3s7Pd92Ptsg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-ppc64@12.4.1': + resolution: {integrity: sha512-r/ab/MlIBo75oizUP5ITiziCCrnXz4SJwfErLQ+603AshB+Yq7xTMCoMtzTSCAMu6aaymIKkAFtZvd2J75Wq0w==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-riscv64@12.4.1': + resolution: {integrity: sha512-C/D1QWdKMiB8+wv/spl1rGITFUuqC+aI/fb6h8NB5sqxsOaGXeYc/g891oCuzggHn6SODk9p+I09hI76x/cMNw==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-s390x@12.4.1': + resolution: {integrity: sha512-nxz5zD4yXt94uzbStDk0QTPKW+aE92hH1b5tFXK9ctB1HE9Xcq1vjTiA2LsZMFC6p4gdu5OwQeFqYNAVGa6QlA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-x64-musl@12.4.1': + resolution: {integrity: sha512-5AwgFdGhVUg2kIweYGfxzSLEHiIG77PQhZAkXC3TwofQHsu1Wr+TrV5/rNX2PopFnHRzuE581zoB8F6Wle32yg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-x64@12.4.1': + resolution: {integrity: sha512-FJOZuuuQMhp0oLzBtcKkLXknBI92hfkmSnlKc47vfin4HrmfID5khY2lGekL9tCzk1cpR+HShEw/meFl+nHtzQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.win32-arm64@12.4.1': + resolution: {integrity: sha512-OO7eKBL9S+xk5hRy+JUUZSNJknGuGe3GEUffsrlC2LbqKF02g+VX1anGIzSbJDvkkdnpJhSlxF5AUz2JzJu2Jw==} + cpu: [arm64] + os: [win32] + + '@pnpm/exe.win32-x64@12.4.1': + resolution: {integrity: sha512-x7gJHZgHo6hp354xCYA2NvoFzYJkHwovt2kVsUBK5EmXULLcP51JGMq09CX+5FRFJUZFKoXjLu3mZWmfP7o6PQ==} + cpu: [x64] + os: [win32] + + pnpm@12.4.1: + resolution: {integrity: sha512-LoHjmdc/6DkNqyXgaqeIq3pZCCSNL1o3D4K0gRR6ano2e/gEj5pv22Rg8hpm8FQt7bi5TKLIcjWWdBkgsWVtTA==} + engines: {node: '>=18.*'} + hasBin: true + +snapshots: + + '@pnpm/exe.android-arm64@12.4.1': + optional: true + + '@pnpm/exe.android-x64@12.4.1': + optional: true + + '@pnpm/exe.darwin-arm64@12.4.1': + optional: true + + '@pnpm/exe.darwin-x64@12.4.1': + optional: true + + '@pnpm/exe.freebsd-x64@12.4.1': + optional: true + + '@pnpm/exe.linux-arm64-musl@12.4.1': + optional: true + + '@pnpm/exe.linux-arm64@12.4.1': + optional: true + + '@pnpm/exe.linux-ppc64@12.4.1': + optional: true + + '@pnpm/exe.linux-riscv64@12.4.1': + optional: true + + '@pnpm/exe.linux-s390x@12.4.1': + optional: true + + '@pnpm/exe.linux-x64-musl@12.4.1': + optional: true + + '@pnpm/exe.linux-x64@12.4.1': + optional: true + + '@pnpm/exe.win32-arm64@12.4.1': + optional: true + + '@pnpm/exe.win32-x64@12.4.1': + optional: true + + pnpm@12.4.1: + optionalDependencies: + '@pnpm/exe.android-arm64': 12.4.1 + '@pnpm/exe.android-x64': 12.4.1 + '@pnpm/exe.darwin-arm64': 12.4.1 + '@pnpm/exe.darwin-x64': 12.4.1 + '@pnpm/exe.freebsd-x64': 12.4.1 + '@pnpm/exe.linux-arm64': 12.4.1 + '@pnpm/exe.linux-arm64-musl': 12.4.1 + '@pnpm/exe.linux-ppc64': 12.4.1 + '@pnpm/exe.linux-riscv64': 12.4.1 + '@pnpm/exe.linux-s390x': 12.4.1 + '@pnpm/exe.linux-x64': 12.4.1 + '@pnpm/exe.linux-x64-musl': 12.4.1 + '@pnpm/exe.win32-arm64': 12.4.1 + '@pnpm/exe.win32-x64': 12.4.1 + +--- lockfileVersion: '9.0' settings: