From fa664426b4af81db817d08ed59558db192dd0df1 Mon Sep 17 00:00:00 2001 From: Shinyaigeek Date: Sun, 28 Jun 2026 23:42:23 +0900 Subject: [PATCH 1/2] chore: pin Node.js to v24 (LTS) Standardize the toolchain on Node.js 24.18.0 (current LTS, "Krypton"): - Add a `.node-version` file so local tooling (nvm/fnm/mise/Volta) and CI resolve the same Node version. - Have both GitHub Actions workflows read the version from `.node-version` via `node-version-file` instead of a hardcoded `node-version: 20`, keeping a single source of truth. - Declare the requirement in package.json `engines.node` (exact match to `.node-version`). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build-js.yml | 2 +- .github/workflows/publish-npm-package.yml | 2 +- .node-version | 1 + package.json | 3 +++ 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 .node-version diff --git a/.github/workflows/build-js.yml b/.github/workflows/build-js.yml index c69e5db80..77598517c 100644 --- a/.github/workflows/build-js.yml +++ b/.github/workflows/build-js.yml @@ -18,7 +18,7 @@ jobs: version: 9.0.6 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version-file: '.node-version' cache: pnpm cache-dependency-path: 'pnpm-lock.yaml' diff --git a/.github/workflows/publish-npm-package.yml b/.github/workflows/publish-npm-package.yml index 2ee8ba613..684b8b0c9 100644 --- a/.github/workflows/publish-npm-package.yml +++ b/.github/workflows/publish-npm-package.yml @@ -34,7 +34,7 @@ jobs: version: 9.15.4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version-file: ".node-version" registry-url: "https://registry.npmjs.org" cache: pnpm cache-dependency-path: "**/pnpm-lock.yaml" diff --git a/.node-version b/.node-version new file mode 100644 index 000000000..ca5c35005 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +24.18.0 diff --git a/package.json b/package.json index f9231c4ca..4e4de6155 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,9 @@ { "name": "OpenUI", "version": "1.0.0", + "engines": { + "node": "24.18.0" + }, "description": "The open standard for generative UI — a streaming-first language, React runtime, and component libraries for building AI-powered chat and copilot interfaces", "main": "index.js", "scripts": { From 2641ab0174b36dae8df15abb2ce01e21333e072e Mon Sep 17 00:00:00 2001 From: Shinyaigeek Date: Sun, 28 Jun 2026 23:55:19 +0900 Subject: [PATCH 2/2] chore(pnpm): add supply-chain hardening Harden the pnpm setup against supply-chain attacks. Requires Node >= 22.13 (pnpm 11), hence stacked on the Node 24 bump. - Pin pnpm via `packageManager: pnpm@11.9.0`; both workflows now resolve it from that field through `pnpm/action-setup@v4` (single source of truth, replacing the divergent 9.0.6 / 9.15.4 pins). - Block lifecycle scripts by default (pnpm 11) and allow only the few deps that genuinely need a native build via `allowBuilds`; telemetry/cosmetic scripts (@scarf/scarf, core-js, protobufjs, @google/genai) stay blocked. - Add `minimumReleaseAge: 1440` (24h cooldown) to avoid installing freshly-published, potentially-compromised releases. - Add `verifyDepsBeforeRun: install` so scripts never run against a stale or tampered dependency tree. - Migrate the CVE-pin `overrides` from the package.json `pnpm` field to `pnpm-workspace.yaml` (pnpm 11 no longer reads the package.json field). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build-js.yml | 5 ++- .github/workflows/publish-npm-package.yml | 5 ++- package.json | 13 +------- pnpm-workspace.yaml | 40 +++++++++++++++++++++++ 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-js.yml b/.github/workflows/build-js.yml index 77598517c..258957ba6 100644 --- a/.github/workflows/build-js.yml +++ b/.github/workflows/build-js.yml @@ -13,9 +13,8 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: pnpm/action-setup@v2 - with: - version: 9.0.6 + # Version is read from the root package.json "packageManager" field. + - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: node-version-file: '.node-version' diff --git a/.github/workflows/publish-npm-package.yml b/.github/workflows/publish-npm-package.yml index 684b8b0c9..334ab5e57 100644 --- a/.github/workflows/publish-npm-package.yml +++ b/.github/workflows/publish-npm-package.yml @@ -29,9 +29,8 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: pnpm/action-setup@v2 - with: - version: 9.15.4 + # Version is read from the root package.json "packageManager" field. + - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: node-version-file: ".node-version" diff --git a/package.json b/package.json index 4e4de6155..d43606a47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "OpenUI", "version": "1.0.0", + "packageManager": "pnpm@11.9.0", "engines": { "node": "24.18.0" }, @@ -47,17 +48,5 @@ }, "bugs": { "url": "https://github.com/thesysdev/openui/issues" - }, - "pnpm": { - "overrides": { - "langsmith@<0.6.0": "^0.6.0", - "ip-address@<10.1.1": ">=10.1.1", - "postcss@<8.5.10": ">=8.5.10", - "qs@<6.15.2": ">=6.15.2", - "uuid@<11.1.1": "^11.1.1", - "cookie@<0.7.0": ">=0.7.0", - "prismjs@<1.30.0": ">=1.30.0", - "@ai-sdk/provider-utils@<=3.0.97": "^4.0.27" - } } } diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 58e5a2736..44bd4f470 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,46 @@ packages: - "docs/" - "!**/src/templates/**" +# --- Supply-chain hardening (pnpm 11+) --- +# Lifecycle (preinstall/install/postinstall) scripts are blocked by default in +# pnpm 11. Every dependency that has a build script must be explicitly decided +# here (true = allowed to run, false = blocked). Anything not listed is blocked +# AND re-prompts on install, so we list all of them. Keep `true` minimal and +# limited to dependencies that genuinely need a native/binary build. +allowBuilds: + # Native/binary builds we actually need: + "@parcel/watcher": true # native file-watcher (nitropack/vite) + esbuild: true # fetches the platform binary + sharp: true # native libvips image processing + unrs-resolver: true # native module-resolution binding + # Intentionally blocked (telemetry / cosmetic / unnecessary): + "@google/genai": false # preinstall notice only + "@scarf/scarf": false # analytics/telemetry beacon + core-js: false # postinstall console ad + protobufjs: false # not needed at install time + +# Cooldown: refuse to install package versions published less than this many +# minutes ago. Defends against freshly-published compromised releases +# (e.g. self-propagating npm worms) by giving the ecosystem time to react. +# 1440 = 24h. Raise for stronger protection at the cost of update latency. +minimumReleaseAge: 1440 + +# Make sure node_modules matches the lockfile before running any script, so +# scripts never execute against a stale or tampered-with dependency tree. +verifyDepsBeforeRun: install + +# Security overrides for known-vulnerable transitive dependencies (CVE pins). +# pnpm 11 reads overrides from here, NOT from the package.json "pnpm" field. +overrides: + "langsmith@<0.6.0": "^0.6.0" + "ip-address@<10.1.1": ">=10.1.1" + "postcss@<8.5.10": ">=8.5.10" + "qs@<6.15.2": ">=6.15.2" + "uuid@<11.1.1": "^11.1.1" + "cookie@<0.7.0": ">=0.7.0" + "prismjs@<1.30.0": ">=1.30.0" + "@ai-sdk/provider-utils@<=3.0.97": "^4.0.27" + # Centralized dependency versions shared across packages. # Reference these from a package.json with the "catalog:" protocol. catalog: