From 0c9410df5839cdf5edbeb5653bb89a3367456fd5 Mon Sep 17 00:00:00 2001 From: ChanHyung-Lee Date: Thu, 13 Aug 2026 16:22:10 +0900 Subject: [PATCH 1/7] docs: design Node 24 runtime upgrade --- ...26-08-13-node-24-runtime-upgrade-design.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md diff --git a/docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md b/docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md new file mode 100644 index 000000000..8659163b8 --- /dev/null +++ b/docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md @@ -0,0 +1,94 @@ +# Node 24 런타임 전환 설계 + +레포 개발 환경과 CI를 Node.js 24 LTS로 통일한다. 현재 CI에서 검증된 `24.18.0`을 정확한 실행 버전으로 사용하고, Node 25 이상이 자동 선택되지 않도록 허용 범위를 제한한다. + +## 배경 + +Node.js 20은 2026년 4월 30일 지원이 끝났다. 레포의 `.nvmrc`는 여전히 `20.20.2`를 가리키지만, 최근 `quality.yml`의 모든 잡은 `24.18.0`에서 통과했다. 로컬 기준과 실제 검증 환경이 다르고, 현재 `>=20.20.2` 범위는 향후 Node 25나 26도 허용한다. + +`packages/codemod`도 이번 전환 대상에 포함한다. 현재 선언한 `>=14.21.3`은 `globby@15`와 `meow@14`의 Node 20 이상 요구사항과도 맞지 않는다. 이번 변경 후 codemod 소비자는 Node.js 24.18.0 이상 25 미만을 사용해야 한다. + +## 목표 + +- 로컬 개발과 프로젝트 CI에서 Node.js `24.18.0`을 사용한다. +- 레포와 전환 대상 패키지는 `>=24.18.0 <25`만 허용한다. +- CI가 `package.json`의 범위를 임의 해석하지 않고 `.nvmrc`의 정확한 버전을 사용하게 한다. +- Node.js 24 전용으로 실행하는 도구의 빌드 타깃과 타입 정의를 맞춘다. +- 기존 품질 검사와 패키지별 검사를 모두 통과한다. + +## 제외 범위 + +- codemod 외 배포 패키지의 Node.js 소비자 계약은 바꾸지 않는다. +- Node.js 20이나 22 호환성 CI 매트릭스를 추가하지 않는다. +- GitHub Action 자체의 Node.js 런타임 메이저 업그레이드는 별도 변경으로 처리한다. +- 새 버전 관리 도구나 자동 업데이트 설정을 추가하지 않는다. + +## 버전 정책 + +| 대상 | 값 | 역할 | +| --- | --- | --- | +| `.nvmrc` | `24.18.0` | 로컬과 프로젝트 CI의 정확한 실행 버전 | +| 루트 `engines.node` | `>=24.18.0 <25` | 지원하지 않는 개발 런타임 차단 | +| `ts-api-extractor` `engines.node` | `>=24.18.0 <25` | 내부 CLI 런타임 계약 | +| `codemod` `engines.node` | `>=24.18.0 <25` | 배포 CLI 소비자 런타임 계약 | +| Node.js 빌드 타깃 | `node24` | Node.js 24 문법과 API를 기준으로 출력 생성 | + +정확한 실행 버전과 허용 범위를 분리한다. `.nvmrc`를 갱신하면 개발자와 CI가 같은 패치 버전을 사용한다. `engines.node`는 같은 메이저의 이후 보안 패치 버전을 허용하지만 Node.js 25 이상은 거부한다. + +## 변경 설계 + +### 런타임 선언 + +`.nvmrc`, 루트 `package.json`, `scripts/ts-api-extractor/package.json`, `packages/codemod/package.json`을 버전 정책에 맞춘다. `CONTRIBUTING.md`와 `CONTRIBUTING.ko.md`는 이미 `.nvmrc`를 참조하므로 수정하지 않는다. + +`.github/composite/install/action.yml`의 `node-version-file`을 `package.json`에서 `.nvmrc`로 바꾼다. 이 변경으로 모든 workspace 설치 잡은 범위 내 임의 버전이 아닌 `24.18.0`을 사용한다. + +`release.yml`의 `promote-docs` 잡은 workspace를 설치하지 않아 공통 install 액션을 사용하지 않는다. Vercel CLI를 설치하기 전에 Node.js 24를 직접 설정해 runner 기본 버전에 의존하지 않게 한다. + +### 빌드와 타입 기준 + +`scripts/ts-api-extractor/tsup.config.ts`의 `node20` 타깃을 `node24`로 바꾼다. `packages/codemod/tsup.config.ts`에도 `node24` 타깃을 명시한다. + +Node.js 24 런타임을 직접 사용하는 다음 개발 의존성만 `@types/node@^24.13.3`으로 갱신한다. + +- 루트 도구 +- `apps/website` +- `scripts/ts-api-extractor` +- `packages/codemod` + +다른 배포 패키지의 `@types/node`는 소비자 호환성 범위를 넓히지 않도록 유지한다. 의존성 변경 후 `pnpm-lock.yaml`을 다시 생성한다. + +### 문서 + +`.gemini/styleguide.md`의 Node.js 기준을 `>=24.18.0 <25`로 고친다. `ts-api-extractor`의 오래된 `>=20.19` 주석은 값 중복을 피하기 위해 제거한다. + +### GitHub Action 런타임 + +프로젝트 Node.js 전환과 GitHub Action 실행 런타임은 서로 다른 계층이다. `actions/checkout`, `actions/setup-node`, `pnpm/action-setup` 등의 메이저 업그레이드는 별도 변경으로 수행한다. Node.js 24 전환 PR에서는 프로젝트 명령의 런타임만 고정해 검증 범위를 작게 유지한다. + +## 검증 방법 + +Node.js `24.18.0`에서 다음 명령을 순서대로 실행한다. + +```bash +nvm use +node --version +pnpm install --frozen-lockfile +pnpm build +pnpm lint +pnpm typecheck +pnpm format:check +pnpm test +pnpm --filter @vapor-ui/codemod test +pnpm --filter @vapor-ui/ts-api-extractor test:run +``` + +`node --version`은 `v24.18.0`을 출력해야 한다. PR의 `quality.yml` 5개 잡도 같은 버전을 사용해야 한다. Node.js 엔진 오류, 타입 오류, 테스트 실패가 없으면 전환을 완료한다. + +## 완료 조건 + +- 로컬과 모든 workspace CI 잡이 Node.js `24.18.0`을 사용한다. +- 루트, ts-api-extractor, codemod가 `>=24.18.0 <25`를 선언한다. +- ts-api-extractor와 codemod가 `node24`를 빌드 타깃으로 사용한다. +- codemod를 제외한 배포 패키지의 소비자 계약은 바뀌지 않는다. +- 전체 빌드, 린트, 타입 검사, 포맷 검사, 테스트가 통과한다. From deabceae1ddcc243c4757bae15526284f22e9897 Mon Sep 17 00:00:00 2001 From: ChanHyung-Lee Date: Thu, 13 Aug 2026 16:40:35 +0900 Subject: [PATCH 2/7] chore(node): migrate dev and CI runtime to Node 24 LTS --- .gemini/styleguide.md | 2 +- .github/composite/install/action.yml | 2 +- .github/workflows/release.yml | 7 + .nvmrc | 2 +- apps/website/package.json | 2 +- package.json | 4 +- packages/codemod/package.json | 4 +- packages/codemod/tsup.config.ts | 2 + pnpm-lock.yaml | 387 ++++++++++++++---------- scripts/ts-api-extractor/package.json | 4 +- scripts/ts-api-extractor/tsup.config.ts | 4 +- 11 files changed, 253 insertions(+), 167 deletions(-) diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index 2d6f97971..5ef2110e6 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -7,7 +7,7 @@ --- - **Package Manager**: PNPM (workspace 기반 모노레포) -- **Node.js**: `>=20.19` (`.nvmrc`, `package.json` engines 기준) +- **Node.js**: `>=24.18.0 <25` (`.nvmrc`, `package.json` engines 기준) - **UI Primitives**: `@base-ui/react` (Accessible unstyled components) - **Styling**: Vanilla Extract (`@vanilla-extract/css`, `@vanilla-extract/recipes`) - **Testing**: Vitest + React Testing Library + vitest-axe diff --git a/.github/composite/install/action.yml b/.github/composite/install/action.yml index 45c7b06cb..0987cbd4a 100644 --- a/.github/composite/install/action.yml +++ b/.github/composite/install/action.yml @@ -11,7 +11,7 @@ runs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version-file: 'package.json' + node-version-file: '.nvmrc' cache: 'pnpm' - name: Install Dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28e14522c..253aacb33 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -67,6 +67,13 @@ jobs: VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} steps: + # This job does not check out the repository, so .nvmrc is unavailable. + # Only the Vercel CLI runs here, so the major version is enough. + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + - name: Install Vercel CLI run: npm install -g vercel@^50 diff --git a/.nvmrc b/.nvmrc index ccc4c6c7f..ca5c35005 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.20.2 +24.18.0 diff --git a/apps/website/package.json b/apps/website/package.json index e4aa90e90..2528dc2b1 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -57,7 +57,7 @@ "@tailwindcss/postcss": "^4.3.3", "@types/lodash-es": "^4.17.12", "@types/mdx": "^2.0.14", - "@types/node": "^22.20.1", + "@types/node": "^24.13.3", "@types/react": "catalog:", "@types/react-dom": "catalog:", "@vapor-ui/ts-api-extractor": "workspace:*", diff --git a/package.json b/package.json index 662fe8711..5144b1890 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@changesets/cli": "^2.31.1", "@changesets/get-github-info": "^0.8.0", "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "^22.20.1", + "@types/node": "^24.13.3", "dotenv": "^17.4.2", "husky": "^9.1.7", "lodash-es": "^4.18.1", @@ -63,6 +63,6 @@ }, "packageManager": "pnpm@10.34.5", "engines": { - "node": ">=20.20.2" + "node": ">=24.18.0 <25" } } diff --git a/packages/codemod/package.json b/packages/codemod/package.json index 0a613f42e..63b9cb788 100644 --- a/packages/codemod/package.json +++ b/packages/codemod/package.json @@ -43,7 +43,7 @@ "@types/is-git-clean": "^1.1.2", "@types/jest": "^29.5.14", "@types/jscodeshift": "^17.3.0", - "@types/node": "^20.19.43", + "@types/node": "^24.13.3", "@vapor-ui/core": "workspace:*", "@vapor-ui/icons": "workspace:*", "eslint": "catalog:", @@ -53,7 +53,7 @@ "tsup": "^8.5.1" }, "engines": { - "node": ">=14.21.3" + "node": ">=24.18.0 <25" }, "publishConfig": { "access": "public" diff --git a/packages/codemod/tsup.config.ts b/packages/codemod/tsup.config.ts index b416cd305..3f96b5e58 100644 --- a/packages/codemod/tsup.config.ts +++ b/packages/codemod/tsup.config.ts @@ -5,6 +5,7 @@ export default defineConfig([ { entry: { 'bin/cli': 'src/bin/cli.ts' }, format: ['esm'], + target: 'node24', outDir: './dist', clean: true, sourcemap: false, @@ -16,6 +17,7 @@ export default defineConfig([ { entry: ['src/transforms/**/*.ts', '!src/**/*.test.ts', '!src/**/*.spec.ts'], format: ['esm'], + target: 'node24', outDir: './dist/transforms', clean: true, sourcemap: false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 99ba89173..b9b8ecf08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,7 +43,7 @@ importers: devDependencies: '@changesets/cli': specifier: ^2.31.1 - version: 2.31.1(@types/node@22.20.1) + version: 2.31.1(@types/node@24.13.3) '@changesets/get-github-info': specifier: ^0.8.0 version: 0.8.0 @@ -51,8 +51,8 @@ importers: specifier: ^5.2.2 version: 5.2.2(prettier@3.9.6) '@types/node': - specifier: ^22.20.1 - version: 22.20.1 + specifier: ^24.13.3 + version: 24.13.3 dotenv: specifier: ^17.4.2 version: 17.4.2 @@ -282,7 +282,7 @@ importers: version: 3.0.10(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/estree@1.0.9)(@types/hast@3.0.4)(@types/mdast@4.0.4)(fumadocs-core@16.8.11(@mdx-js/mdx@3.1.1)(@oramacloud/client@2.1.4)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.8))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(mdast-util-mdx@3.0.0) fumadocs-mdx: specifier: 14.3.2 - version: 14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.17)(fumadocs-core@16.8.11(@mdx-js/mdx@3.1.1)(@oramacloud/client@2.1.4)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.8))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react@19.2.8)(vite@7.3.6(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0)) + version: 14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.17)(fumadocs-core@16.8.11(@mdx-js/mdx@3.1.1)(@oramacloud/client@2.1.4)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.8))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react@19.2.8)(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0)) fumadocs-typescript: specifier: 5.2.6 version: 5.2.6(ca26bbd54a66b7cc33a19a6355e52a20) @@ -354,8 +354,8 @@ importers: specifier: ^2.0.14 version: 2.0.14 '@types/node': - specifier: ^22.20.1 - version: 22.20.1 + specifier: ^24.13.3 + version: 24.13.3 '@types/react': specifier: 'catalog:' version: 19.2.17 @@ -385,7 +385,7 @@ importers: dependencies: '@inquirer/prompts': specifier: ^7.10.1 - version: 7.10.1(@types/node@20.19.43) + version: 7.10.1(@types/node@24.13.3) globby: specifier: ^15.0.0 version: 15.0.0 @@ -421,8 +421,8 @@ importers: specifier: ^17.3.0 version: 17.3.0 '@types/node': - specifier: ^20.19.43 - version: 20.19.43 + specifier: ^24.13.3 + version: 24.13.3 '@vapor-ui/core': specifier: workspace:* version: link:../core @@ -434,13 +434,13 @@ importers: version: 9.39.5(jiti@2.7.0) jest: specifier: ^30.4.2 - version: 30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + version: 30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) rimraf: specifier: ^6.1.3 version: 6.1.3 ts-jest: specifier: ^29.4.12 - version: 29.4.12(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.12(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)))(typescript@5.9.3) tsup: specifier: ^8.5.1 version: 8.5.1(jiti@2.7.0)(postcss@8.5.26)(tsx@4.23.11)(typescript@5.9.3)(yaml@2.9.0) @@ -846,8 +846,8 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.19.43 - version: 20.19.43 + specifier: ^24.13.3 + version: 24.13.3 '@vitest/coverage-v8': specifier: 'catalog:' version: 3.2.7(@vitest/browser@3.2.7)(vitest@3.2.7) @@ -865,7 +865,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.7(@types/debug@4.1.12)(@types/node@20.19.43)(@vitest/browser@3.2.7)(happy-dom@20.10.6)(jiti@2.7.0)(jsdom@29.0.2(@noble/hashes@1.8.0))(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.12)(@types/node@24.13.3)(@vitest/browser@3.2.7)(happy-dom@20.10.6)(jiti@2.7.0)(jsdom@29.0.2(@noble/hashes@1.8.0))(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) packages: @@ -4414,6 +4414,9 @@ packages: '@types/node@22.20.1': resolution: {integrity: sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==} + '@types/node@24.13.3': + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} + '@types/node@25.5.0': resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} @@ -10608,7 +10611,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.31.1(@types/node@22.20.1)': + '@changesets/cli@2.31.1(@types/node@24.13.3)': dependencies: '@changesets/apply-release-plan': 7.1.1 '@changesets/assemble-release-plan': 6.0.10 @@ -10624,7 +10627,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@22.20.1) + '@inquirer/external-editor': 1.0.3(@types/node@24.13.3) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 enquirer: 2.4.1 @@ -11288,135 +11291,128 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/checkbox@4.3.2(@types/node@20.19.43)': + '@inquirer/checkbox@4.3.2(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/type': 3.0.10(@types/node@24.13.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/confirm@5.1.21(@types/node@20.19.43)': + '@inquirer/confirm@5.1.21(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/core@10.3.2(@types/node@20.19.43)': + '@inquirer/core@10.3.2(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/type': 3.0.10(@types/node@24.13.3) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/editor@4.2.23(@types/node@20.19.43)': + '@inquirer/editor@4.2.23(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/external-editor': 1.0.3(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/external-editor': 1.0.3(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/expand@4.0.23(@types/node@20.19.43)': + '@inquirer/expand@4.0.23(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/external-editor@1.0.3(@types/node@20.19.43)': + '@inquirer/external-editor@1.0.3(@types/node@24.13.3)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.0 optionalDependencies: - '@types/node': 20.19.43 - - '@inquirer/external-editor@1.0.3(@types/node@22.20.1)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.0 - optionalDependencies: - '@types/node': 22.20.1 + '@types/node': 24.13.3 '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.3.1(@types/node@20.19.43)': + '@inquirer/input@4.3.1(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/number@3.0.23(@types/node@20.19.43)': + '@inquirer/number@3.0.23(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/password@4.0.23(@types/node@20.19.43)': + '@inquirer/password@4.0.23(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) optionalDependencies: - '@types/node': 20.19.43 - - '@inquirer/prompts@7.10.1(@types/node@20.19.43)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@20.19.43) - '@inquirer/confirm': 5.1.21(@types/node@20.19.43) - '@inquirer/editor': 4.2.23(@types/node@20.19.43) - '@inquirer/expand': 4.0.23(@types/node@20.19.43) - '@inquirer/input': 4.3.1(@types/node@20.19.43) - '@inquirer/number': 3.0.23(@types/node@20.19.43) - '@inquirer/password': 4.0.23(@types/node@20.19.43) - '@inquirer/rawlist': 4.1.11(@types/node@20.19.43) - '@inquirer/search': 3.2.2(@types/node@20.19.43) - '@inquirer/select': 4.4.2(@types/node@20.19.43) + '@types/node': 24.13.3 + + '@inquirer/prompts@7.10.1(@types/node@24.13.3)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@24.13.3) + '@inquirer/confirm': 5.1.21(@types/node@24.13.3) + '@inquirer/editor': 4.2.23(@types/node@24.13.3) + '@inquirer/expand': 4.0.23(@types/node@24.13.3) + '@inquirer/input': 4.3.1(@types/node@24.13.3) + '@inquirer/number': 3.0.23(@types/node@24.13.3) + '@inquirer/password': 4.0.23(@types/node@24.13.3) + '@inquirer/rawlist': 4.1.11(@types/node@24.13.3) + '@inquirer/search': 3.2.2(@types/node@24.13.3) + '@inquirer/select': 4.4.2(@types/node@24.13.3) optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/rawlist@4.1.11(@types/node@20.19.43)': + '@inquirer/rawlist@4.1.11(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) + '@inquirer/type': 3.0.10(@types/node@24.13.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/search@3.2.2(@types/node@20.19.43)': + '@inquirer/search@3.2.2(@types/node@24.13.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/type': 3.0.10(@types/node@24.13.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/select@4.4.2(@types/node@20.19.43)': + '@inquirer/select@4.4.2(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@20.19.43) + '@inquirer/core': 10.3.2(@types/node@24.13.3) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.43) + '@inquirer/type': 3.0.10(@types/node@24.13.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 - '@inquirer/type@3.0.10(@types/node@20.19.43)': + '@inquirer/type@3.0.10(@types/node@24.13.3)': optionalDependencies: - '@types/node': 20.19.43 + '@types/node': 24.13.3 '@isaacs/cliui@8.0.2': dependencies: @@ -11440,13 +11436,13 @@ snapshots: '@jest/console@30.4.1': dependencies: '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 jest-message-util: 30.4.1 jest-util: 30.4.1 slash: 3.0.0 - '@jest/core@30.4.2(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3))': + '@jest/core@30.4.2(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3))': dependencies: '@jest/console': 30.4.1 '@jest/pattern': 30.4.0 @@ -11454,7 +11450,7 @@ snapshots: '@jest/test-result': 30.4.1 '@jest/transform': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 4.3.1 @@ -11462,7 +11458,7 @@ snapshots: fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 jest-changed-files: 30.4.1 - jest-config: 30.4.2(@types/node@22.20.1)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + jest-config: 30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) jest-haste-map: 30.4.1 jest-message-util: 30.4.1 jest-regex-util: 30.4.0 @@ -11488,7 +11484,7 @@ snapshots: dependencies: '@jest/fake-timers': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 jest-mock: 30.4.1 '@jest/expect-utils@29.7.0': @@ -11510,7 +11506,7 @@ snapshots: dependencies: '@jest/types': 30.4.1 '@sinonjs/fake-timers': 15.4.0 - '@types/node': 22.20.1 + '@types/node': 24.13.3 jest-message-util: 30.4.1 jest-mock: 30.4.1 jest-util: 30.4.1 @@ -11528,7 +11524,7 @@ snapshots: '@jest/pattern@30.4.0': dependencies: - '@types/node': 22.20.1 + '@types/node': 24.13.3 jest-regex-util: 30.4.0 '@jest/reporters@30.4.1': @@ -11539,7 +11535,7 @@ snapshots: '@jest/transform': 30.4.1 '@jest/types': 30.4.1 '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit-x: 0.2.2 @@ -11618,7 +11614,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.20.1 + '@types/node': 24.13.3 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -11628,7 +11624,7 @@ snapshots: '@jest/schemas': 30.4.1 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.20.1 + '@types/node': 24.13.3 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -13040,6 +13036,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@24.13.3': + dependencies: + undici-types: 7.18.2 + '@types/node@25.5.0': dependencies: undici-types: 7.18.2 @@ -13481,6 +13481,26 @@ snapshots: - utf-8-validate - vite + '@vitest/browser@3.2.7(playwright@1.61.1)(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0))(vitest@3.2.7)': + dependencies: + '@testing-library/dom': 10.4.1 + '@testing-library/user-event': 14.6.3(@testing-library/dom@10.4.1) + '@vitest/mocker': 3.2.7(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0)) + '@vitest/utils': 3.2.7 + magic-string: 0.30.21 + sirv: 3.0.2 + tinyrainbow: 2.0.0 + vitest: 3.2.7(@types/debug@4.1.12)(@types/node@24.13.3)(@vitest/browser@3.2.7)(happy-dom@20.10.6)(jiti@2.7.0)(jsdom@29.0.2(@noble/hashes@1.8.0))(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + ws: 8.21.1 + optionalDependencies: + playwright: 1.61.1 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true + '@vitest/coverage-v8@3.2.7(@vitest/browser@3.2.7)(vitest@3.2.7)': dependencies: '@ampproject/remapping': 2.3.0 @@ -13550,6 +13570,14 @@ snapshots: optionalDependencies: vite: 7.3.6(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + '@vitest/mocker@3.2.7(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 3.2.7 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 @@ -15096,7 +15124,7 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - fumadocs-mdx@14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.17)(fumadocs-core@16.8.11(@mdx-js/mdx@3.1.1)(@oramacloud/client@2.1.4)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.8))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react@19.2.8)(vite@7.3.6(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0)): + fumadocs-mdx@14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.17)(fumadocs-core@16.8.11(@mdx-js/mdx@3.1.1)(@oramacloud/client@2.1.4)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.8))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0))(react@19.2.8)(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.1.0 @@ -15122,7 +15150,7 @@ snapshots: '@types/react': 19.2.17 next: 16.2.12(@babel/core@7.28.4)(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(sass@1.101.0) react: 19.2.8 - vite: 7.3.6(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -15710,7 +15738,7 @@ snapshots: '@jest/expect': 30.4.1 '@jest/test-result': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.0 @@ -15730,15 +15758,15 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)): + jest-cli@30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)): dependencies: - '@jest/core': 30.4.2(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + '@jest/core': 30.4.2(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) '@jest/test-result': 30.4.1 '@jest/types': 30.4.1 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + jest-config: 30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) jest-util: 30.4.1 jest-validate: 30.4.1 yargs: 17.7.2 @@ -15749,40 +15777,7 @@ snapshots: - supports-color - ts-node - jest-config@30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)): - dependencies: - '@babel/core': 7.29.0 - '@jest/get-type': 30.1.0 - '@jest/pattern': 30.4.0 - '@jest/test-sequencer': 30.4.1 - '@jest/types': 30.4.1 - babel-jest: 30.4.1(@babel/core@7.29.0) - chalk: 4.1.2 - ci-info: 4.3.1 - deepmerge: 4.3.1 - glob: 10.5.0 - graceful-fs: 4.2.11 - jest-circus: 30.4.2 - jest-docblock: 30.4.0 - jest-environment-node: 30.4.1 - jest-regex-util: 30.4.0 - jest-resolve: 30.4.1 - jest-runner: 30.4.2 - jest-util: 30.4.1 - jest-validate: 30.4.1 - parse-json: 5.2.0 - pretty-format: 30.4.1 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 20.19.43 - esbuild-register: 3.6.0(esbuild@0.27.7) - ts-node: 10.9.2(@types/node@20.19.43)(typescript@5.9.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@30.4.2(@types/node@22.20.1)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)): + jest-config@30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)): dependencies: '@babel/core': 7.29.0 '@jest/get-type': 30.1.0 @@ -15808,9 +15803,9 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.20.1 + '@types/node': 24.13.3 esbuild-register: 3.6.0(esbuild@0.27.7) - ts-node: 10.9.2(@types/node@20.19.43)(typescript@5.9.3) + ts-node: 10.9.2(@types/node@24.13.3)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -15846,7 +15841,7 @@ snapshots: '@jest/environment': 30.4.1 '@jest/fake-timers': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 jest-mock: 30.4.1 jest-util: 30.4.1 jest-validate: 30.4.1 @@ -15856,7 +15851,7 @@ snapshots: jest-haste-map@30.4.1: dependencies: '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -15915,7 +15910,7 @@ snapshots: jest-mock@30.4.1: dependencies: '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 jest-util: 30.4.1 jest-pnp-resolver@1.2.3(jest-resolve@30.4.1): @@ -15949,7 +15944,7 @@ snapshots: '@jest/test-result': 30.4.1 '@jest/transform': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 emittery: 0.13.1 exit-x: 0.2.2 @@ -15978,7 +15973,7 @@ snapshots: '@jest/test-result': 30.4.1 '@jest/transform': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 cjs-module-lexer: 2.1.1 collect-v8-coverage: 1.0.2 @@ -16025,7 +16020,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -16034,7 +16029,7 @@ snapshots: jest-util@30.4.1: dependencies: '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 chalk: 4.1.2 ci-info: 4.3.1 graceful-fs: 4.2.11 @@ -16053,7 +16048,7 @@ snapshots: dependencies: '@jest/test-result': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 22.20.1 + '@types/node': 24.13.3 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -16062,18 +16057,18 @@ snapshots: jest-worker@30.4.1: dependencies: - '@types/node': 22.20.1 + '@types/node': 24.13.3 '@ungap/structured-clone': 1.3.0 jest-util: 30.4.1 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)): + jest@30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)): dependencies: - '@jest/core': 30.4.2(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + '@jest/core': 30.4.2(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) '@jest/types': 30.4.1 import-local: 3.2.0 - jest-cli: 30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + jest-cli: 30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -18265,12 +18260,12 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.4.12(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)))(typescript@5.9.3): + ts-jest@29.4.12(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.9 - jest: 30.4.2(@types/node@20.19.43)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)) + jest: 30.4.2(@types/node@24.13.3)(esbuild-register@3.6.0(esbuild@0.27.7))(ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -18296,14 +18291,14 @@ snapshots: '@ts-morph/common': 0.29.0 code-block-writer: 13.0.3 - ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3): + ts-node@10.9.2(@types/node@24.13.3)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.43 + '@types/node': 24.13.3 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 @@ -18443,8 +18438,7 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.18.2: - optional: true + undici-types@7.18.2: {} undici@7.25.0: optional: true @@ -18662,6 +18656,27 @@ snapshots: - tsx - yaml + vite-node@3.2.4(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite-node@3.2.4(@types/node@25.5.0)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0): dependencies: cac: 6.7.14 @@ -18724,6 +18739,23 @@ snapshots: tsx: 4.23.11 yaml: 2.9.0 + vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0): + dependencies: + esbuild: 0.28.2 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.25 + rollup: 4.62.2 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 24.13.3 + fsevents: 2.3.3 + jiti: 2.7.0 + lightningcss: 1.32.0 + sass: 1.101.0 + tsx: 4.23.11 + yaml: 2.9.0 + vite@7.3.6(@types/node@25.5.0)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0): dependencies: esbuild: 0.28.2 @@ -18839,6 +18871,51 @@ snapshots: - tsx - yaml + vitest@3.2.7(@types/debug@4.1.12)(@types/node@24.13.3)(@vitest/browser@3.2.7)(happy-dom@20.10.6)(jiti@2.7.0)(jsdom@29.0.2(@noble/hashes@1.8.0))(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.7 + '@vitest/mocker': 3.2.7(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0)) + '@vitest/pretty-format': 3.2.7 + '@vitest/runner': 3.2.7 + '@vitest/snapshot': 3.2.7 + '@vitest/spy': 3.2.7 + '@vitest/utils': 3.2.7 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.2.2 + magic-string: 0.30.21 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.17 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + vite-node: 3.2.4(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 24.13.3 + '@vitest/browser': 3.2.7(playwright@1.61.1)(vite@7.3.6(@types/node@24.13.3)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.101.0)(tsx@4.23.11)(yaml@2.9.0))(vitest@3.2.7) + happy-dom: 20.10.6 + jsdom: 29.0.2(@noble/hashes@1.8.0) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 diff --git a/scripts/ts-api-extractor/package.json b/scripts/ts-api-extractor/package.json index 24760d6fb..52f7940ce 100644 --- a/scripts/ts-api-extractor/package.json +++ b/scripts/ts-api-extractor/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "@repo/eslint-config": "workspace:*", - "@types/node": "^20.19.43", + "@types/node": "^24.13.3", "@vitest/coverage-v8": "catalog:", "eslint": "^9.39.5", "tsup": "^8.5.1", @@ -46,6 +46,6 @@ "typescript": ">=5.9.3" }, "engines": { - "node": ">=20.20.2" + "node": ">=24.18.0 <25" } } diff --git a/scripts/ts-api-extractor/tsup.config.ts b/scripts/ts-api-extractor/tsup.config.ts index 6ea924aa5..2361d71a7 100644 --- a/scripts/ts-api-extractor/tsup.config.ts +++ b/scripts/ts-api-extractor/tsup.config.ts @@ -8,7 +8,7 @@ export default defineConfig([ format: ['esm'], sourcemap: true, splitting: false, - target: 'node20', // matches package.json engines (>=20.19) + target: 'node24', esbuildOptions(options) { options.alias = { '~': path.resolve(__dirname, './src'), @@ -24,7 +24,7 @@ export default defineConfig([ format: ['esm'], sourcemap: true, splitting: false, - target: 'node20', // matches package.json engines (>=20.19) + target: 'node24', esbuildOptions(options) { options.alias = { '~': path.resolve(__dirname, './src'), From 41b38556175ccbafae39c4681e4d1bdc5f397673 Mon Sep 17 00:00:00 2001 From: ChanHyung-Lee Date: Thu, 13 Aug 2026 16:49:24 +0900 Subject: [PATCH 3/7] chore: revert vercel node version --- .github/workflows/release.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 253aacb33..28e14522c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -67,13 +67,6 @@ jobs: VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} steps: - # This job does not check out the repository, so .nvmrc is unavailable. - # Only the Vercel CLI runs here, so the major version is enough. - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: '24' - - name: Install Vercel CLI run: npm install -g vercel@^50 From 0f25f82b24f65af0d56e3131615e2420ae67db36 Mon Sep 17 00:00:00 2001 From: ChanHyung-Lee Date: Thu, 13 Aug 2026 16:49:57 +0900 Subject: [PATCH 4/7] chore: remove docs --- ...26-08-13-node-24-runtime-upgrade-design.md | 94 ------------------- 1 file changed, 94 deletions(-) delete mode 100644 docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md diff --git a/docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md b/docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md deleted file mode 100644 index 8659163b8..000000000 --- a/docs/superpowers/specs/2026-08-13-node-24-runtime-upgrade-design.md +++ /dev/null @@ -1,94 +0,0 @@ -# Node 24 런타임 전환 설계 - -레포 개발 환경과 CI를 Node.js 24 LTS로 통일한다. 현재 CI에서 검증된 `24.18.0`을 정확한 실행 버전으로 사용하고, Node 25 이상이 자동 선택되지 않도록 허용 범위를 제한한다. - -## 배경 - -Node.js 20은 2026년 4월 30일 지원이 끝났다. 레포의 `.nvmrc`는 여전히 `20.20.2`를 가리키지만, 최근 `quality.yml`의 모든 잡은 `24.18.0`에서 통과했다. 로컬 기준과 실제 검증 환경이 다르고, 현재 `>=20.20.2` 범위는 향후 Node 25나 26도 허용한다. - -`packages/codemod`도 이번 전환 대상에 포함한다. 현재 선언한 `>=14.21.3`은 `globby@15`와 `meow@14`의 Node 20 이상 요구사항과도 맞지 않는다. 이번 변경 후 codemod 소비자는 Node.js 24.18.0 이상 25 미만을 사용해야 한다. - -## 목표 - -- 로컬 개발과 프로젝트 CI에서 Node.js `24.18.0`을 사용한다. -- 레포와 전환 대상 패키지는 `>=24.18.0 <25`만 허용한다. -- CI가 `package.json`의 범위를 임의 해석하지 않고 `.nvmrc`의 정확한 버전을 사용하게 한다. -- Node.js 24 전용으로 실행하는 도구의 빌드 타깃과 타입 정의를 맞춘다. -- 기존 품질 검사와 패키지별 검사를 모두 통과한다. - -## 제외 범위 - -- codemod 외 배포 패키지의 Node.js 소비자 계약은 바꾸지 않는다. -- Node.js 20이나 22 호환성 CI 매트릭스를 추가하지 않는다. -- GitHub Action 자체의 Node.js 런타임 메이저 업그레이드는 별도 변경으로 처리한다. -- 새 버전 관리 도구나 자동 업데이트 설정을 추가하지 않는다. - -## 버전 정책 - -| 대상 | 값 | 역할 | -| --- | --- | --- | -| `.nvmrc` | `24.18.0` | 로컬과 프로젝트 CI의 정확한 실행 버전 | -| 루트 `engines.node` | `>=24.18.0 <25` | 지원하지 않는 개발 런타임 차단 | -| `ts-api-extractor` `engines.node` | `>=24.18.0 <25` | 내부 CLI 런타임 계약 | -| `codemod` `engines.node` | `>=24.18.0 <25` | 배포 CLI 소비자 런타임 계약 | -| Node.js 빌드 타깃 | `node24` | Node.js 24 문법과 API를 기준으로 출력 생성 | - -정확한 실행 버전과 허용 범위를 분리한다. `.nvmrc`를 갱신하면 개발자와 CI가 같은 패치 버전을 사용한다. `engines.node`는 같은 메이저의 이후 보안 패치 버전을 허용하지만 Node.js 25 이상은 거부한다. - -## 변경 설계 - -### 런타임 선언 - -`.nvmrc`, 루트 `package.json`, `scripts/ts-api-extractor/package.json`, `packages/codemod/package.json`을 버전 정책에 맞춘다. `CONTRIBUTING.md`와 `CONTRIBUTING.ko.md`는 이미 `.nvmrc`를 참조하므로 수정하지 않는다. - -`.github/composite/install/action.yml`의 `node-version-file`을 `package.json`에서 `.nvmrc`로 바꾼다. 이 변경으로 모든 workspace 설치 잡은 범위 내 임의 버전이 아닌 `24.18.0`을 사용한다. - -`release.yml`의 `promote-docs` 잡은 workspace를 설치하지 않아 공통 install 액션을 사용하지 않는다. Vercel CLI를 설치하기 전에 Node.js 24를 직접 설정해 runner 기본 버전에 의존하지 않게 한다. - -### 빌드와 타입 기준 - -`scripts/ts-api-extractor/tsup.config.ts`의 `node20` 타깃을 `node24`로 바꾼다. `packages/codemod/tsup.config.ts`에도 `node24` 타깃을 명시한다. - -Node.js 24 런타임을 직접 사용하는 다음 개발 의존성만 `@types/node@^24.13.3`으로 갱신한다. - -- 루트 도구 -- `apps/website` -- `scripts/ts-api-extractor` -- `packages/codemod` - -다른 배포 패키지의 `@types/node`는 소비자 호환성 범위를 넓히지 않도록 유지한다. 의존성 변경 후 `pnpm-lock.yaml`을 다시 생성한다. - -### 문서 - -`.gemini/styleguide.md`의 Node.js 기준을 `>=24.18.0 <25`로 고친다. `ts-api-extractor`의 오래된 `>=20.19` 주석은 값 중복을 피하기 위해 제거한다. - -### GitHub Action 런타임 - -프로젝트 Node.js 전환과 GitHub Action 실행 런타임은 서로 다른 계층이다. `actions/checkout`, `actions/setup-node`, `pnpm/action-setup` 등의 메이저 업그레이드는 별도 변경으로 수행한다. Node.js 24 전환 PR에서는 프로젝트 명령의 런타임만 고정해 검증 범위를 작게 유지한다. - -## 검증 방법 - -Node.js `24.18.0`에서 다음 명령을 순서대로 실행한다. - -```bash -nvm use -node --version -pnpm install --frozen-lockfile -pnpm build -pnpm lint -pnpm typecheck -pnpm format:check -pnpm test -pnpm --filter @vapor-ui/codemod test -pnpm --filter @vapor-ui/ts-api-extractor test:run -``` - -`node --version`은 `v24.18.0`을 출력해야 한다. PR의 `quality.yml` 5개 잡도 같은 버전을 사용해야 한다. Node.js 엔진 오류, 타입 오류, 테스트 실패가 없으면 전환을 완료한다. - -## 완료 조건 - -- 로컬과 모든 workspace CI 잡이 Node.js `24.18.0`을 사용한다. -- 루트, ts-api-extractor, codemod가 `>=24.18.0 <25`를 선언한다. -- ts-api-extractor와 codemod가 `node24`를 빌드 타깃으로 사용한다. -- codemod를 제외한 배포 패키지의 소비자 계약은 바뀌지 않는다. -- 전체 빌드, 린트, 타입 검사, 포맷 검사, 테스트가 통과한다. From 3ae681d4fe7abb644cf96bd4c5f9e7444da49466 Mon Sep 17 00:00:00 2001 From: MaxLee-dev Date: Fri, 4 Sep 2026 14:29:58 +0900 Subject: [PATCH 5/7] chore(node): enforce Node 24 via engineStrict and loosen pin to major --- .changeset/codemod-node-24.md | 5 +++++ .gemini/styleguide.md | 2 +- .nvmrc | 2 +- CONTRIBUTING.md | 6 ++++-- package.json | 4 ++-- packages/codemod/package.json | 2 +- pnpm-workspace.yaml | 8 ++++++++ scripts/ts-api-extractor/package.json | 3 --- 8 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 .changeset/codemod-node-24.md diff --git a/.changeset/codemod-node-24.md b/.changeset/codemod-node-24.md new file mode 100644 index 000000000..00e927c70 --- /dev/null +++ b/.changeset/codemod-node-24.md @@ -0,0 +1,5 @@ +--- +'@vapor-ui/codemod': minor +--- + +Require Node.js 24 or later diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index 5ef2110e6..f41c4501b 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -7,7 +7,7 @@ --- - **Package Manager**: PNPM (workspace 기반 모노레포) -- **Node.js**: `>=24.18.0 <25` (`.nvmrc`, `package.json` engines 기준) +- **Node.js**: `>=24` (`.nvmrc`, `package.json` engines 기준) - **UI Primitives**: `@base-ui/react` (Accessible unstyled components) - **Styling**: Vanilla Extract (`@vanilla-extract/css`, `@vanilla-extract/recipes`) - **Testing**: Vitest + React Testing Library + vitest-axe diff --git a/.nvmrc b/.nvmrc index ca5c35005..a45fd52cc 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.18.0 +24 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6de7b410d..258abdddb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,12 +40,14 @@ cd vapor-ui git remote add upstream https://github.com/goorm-dev/vapor-ui.git ``` -2. Ensure your Node version matches the [.nvmrc](../.nvmrc): +2. Switch to the Node version in [.nvmrc](../.nvmrc) (`pnpm install` refuses to run on any other major version): ```bash -node -v +nvm use # or: fnm use ``` +pnpm itself is pinned by the `packageManager` field in `package.json` and switches automatically. + 3. Install dependencies: ```bash diff --git a/package.json b/package.json index 5144b1890..f8c421971 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,8 @@ "turbo": "^2.10.9", "typescript": "catalog:" }, - "packageManager": "pnpm@10.34.5", + "packageManager": "pnpm@11.21.0", "engines": { - "node": ">=24.18.0 <25" + "node": ">=24" } } diff --git a/packages/codemod/package.json b/packages/codemod/package.json index 63b9cb788..1e10fca69 100644 --- a/packages/codemod/package.json +++ b/packages/codemod/package.json @@ -53,7 +53,7 @@ "tsup": "^8.5.1" }, "engines": { - "node": ">=24.18.0 <25" + "node": ">=24" }, "publishConfig": { "access": "public" diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 357225d6b..6ff6a76c7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,14 @@ packages: - scripts/ts-api-extractor - scripts/sync-figma +engineStrict: true + +allowBuilds: + '@parcel/watcher': true + esbuild: true + sharp: true + unrs-resolver: true + # Unified React 19 for entire monorepo # Libraries (packages/*) maintain peerDependencies for React 17/18/19 compatibility catalog: diff --git a/scripts/ts-api-extractor/package.json b/scripts/ts-api-extractor/package.json index 2a3695e1e..22a7cccea 100644 --- a/scripts/ts-api-extractor/package.json +++ b/scripts/ts-api-extractor/package.json @@ -44,8 +44,5 @@ }, "peerDependencies": { "typescript": ">=5.9.3" - }, - "engines": { - "node": ">=24.18.0 <25" } } From 546bf22d827d3f8ea64cef4a8fa11edbd790573b Mon Sep 17 00:00:00 2001 From: MaxLee-dev Date: Fri, 4 Sep 2026 14:49:06 +0900 Subject: [PATCH 6/7] docs(contributing): fix .nvmrc link path --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 258abdddb..7729f9162 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ cd vapor-ui git remote add upstream https://github.com/goorm-dev/vapor-ui.git ``` -2. Switch to the Node version in [.nvmrc](../.nvmrc) (`pnpm install` refuses to run on any other major version): +2. Switch to the Node version in [.nvmrc](./.nvmrc) (`pnpm install` refuses to run on any other major version): ```bash nvm use # or: fnm use From 370e87691ae929894ac8678a2146cffa010c122b Mon Sep 17 00:00:00 2001 From: MaxLee-dev Date: Mon, 14 Sep 2026 16:24:34 +0900 Subject: [PATCH 7/7] docs(contributing): state the Node.js 24 minimum explicitly --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7729f9162..58fe31b6e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ cd vapor-ui git remote add upstream https://github.com/goorm-dev/vapor-ui.git ``` -2. Switch to the Node version in [.nvmrc](./.nvmrc) (`pnpm install` refuses to run on any other major version): +2. Switch to the Node version in [.nvmrc](./.nvmrc) (`pnpm install` requires Node.js 24 or newer): ```bash nvm use # or: fnm use