From b3277d7a6eb4b8bb28de73739df2a0151889d456 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Thu, 22 May 2025 18:30:17 -0700 Subject: [PATCH 1/3] fix: make pnpm commands work reliably across environments This commit addresses several related issues with pnpm command execution: 1. Husky hooks now check if pnpm is in PATH and fall back to npx pnpm if not available, ensuring git hooks work in all environments. 2. Created a robust bootstrap script that handles npm-to-pnpm transitions without recursion or global installation requirements. 3. Modified package.json scripts to use the bootstrap script for install, install:all, and preinstall, preventing infinite recursion while maintaining compatibility with both npm and pnpm. 4. Updated test script to use npx pnpm when invoking turbo, ensuring the package manager binary is found correctly. Fixes: #3875 Fixes: #3876 Fixes: #3877 Fixes: #3878 --- .husky/pre-commit | 12 ++++--- .husky/pre-push | 8 +++-- package.json | 4 ++- scripts/bootstrap.js | 86 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 7 deletions(-) create mode 100755 scripts/bootstrap.js diff --git a/.husky/pre-commit b/.husky/pre-commit index 530ecedd6e..a7b784fcb9 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -9,10 +9,14 @@ fi if [ "$OS" = "Windows_NT" ]; then pnpm_cmd="pnpm.cmd" else - pnpm_cmd="pnpm" + if command -v pnpm >/dev/null 2>&1; then + pnpm_cmd="pnpm" + else + pnpm_cmd="npx pnpm" + fi fi -"$pnpm_cmd" --filter roo-cline generate-types +$pnpm_cmd --filter roo-cline generate-types if [ -n "$(git diff --name-only src/exports/roo-code.d.ts)" ]; then echo "Error: There are unstaged changes to roo-code.d.ts after running 'pnpm --filter roo-cline generate-types'." @@ -27,5 +31,5 @@ else npx_cmd="npx" fi -"$npx_cmd" lint-staged -"$pnpm_cmd" lint +$npx_cmd lint-staged +$pnpm_cmd lint diff --git a/.husky/pre-push b/.husky/pre-push index 95b5e351d4..ce9b06149e 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -9,10 +9,14 @@ fi if [ "$OS" = "Windows_NT" ]; then pnpm_cmd="pnpm.cmd" else - pnpm_cmd="pnpm" + if command -v pnpm >/dev/null 2>&1; then + pnpm_cmd="pnpm" + else + pnpm_cmd="npx pnpm" + fi fi -"$pnpm_cmd" run check-types +$pnpm_cmd run check-types # Check for new changesets. NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') diff --git a/package.json b/package.json index 5031d3d30d..ea3e8549c3 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,10 @@ "node": "20.18.1" }, "scripts": { - "preinstall": "npx only-allow pnpm", + "preinstall": "node scripts/bootstrap.js", "prepare": "husky", + "install": "node scripts/bootstrap.js", + "install:all": "node scripts/bootstrap.js", "lint": "turbo lint --log-order grouped --output-logs new-only", "check-types": "turbo check-types --log-order grouped --output-logs new-only", "test": "turbo test --log-order grouped --output-logs new-only", diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js new file mode 100755 index 0000000000..52f9fb72cc --- /dev/null +++ b/scripts/bootstrap.js @@ -0,0 +1,86 @@ +#!/usr/bin/env node + +const { spawnSync } = require("child_process") + +// Check if we're already bootstrapping +if (process.env.BOOTSTRAP_IN_PROGRESS) { + console.log("Bootstrap already in progress, continuing with normal installation...") + process.exit(0) +} + +// Check if we're running under pnpm +const isPnpm = process.env.npm_execpath && process.env.npm_execpath.includes("pnpm") + +// If we're already using pnpm, just exit normally +if (isPnpm) { + console.log("Already using pnpm, continuing with normal installation...") + process.exit(0) +} + +console.log("Bootstrapping to pnpm...") + +try { + // Check if pnpm is installed + const pnpmCheck = spawnSync("command", ["-v", "pnpm"], { shell: true }) + + let pnpmInstall + + if (pnpmCheck.status === 0) { + // If pnpm is available, use it directly + console.log("pnpm found, using it directly...") + pnpmInstall = spawnSync("pnpm", ["install"], { + stdio: "inherit", + shell: true, + env: { + ...process.env, + BOOTSTRAP_IN_PROGRESS: "1", // Set environment variable to indicate bootstrapping + }, + }) + } else { + // If pnpm is not available, install it temporarily in the project + console.log("pnpm not found, installing it temporarily...") + + // Create a temporary package.json if it doesn't exist + const tempPkgJson = spawnSync( + "node", + [ + "-e", + 'if(!require("fs").existsSync("package.json")){require("fs").writeFileSync("package.json", JSON.stringify({name:"temp",private:true}))}', + ], + { shell: true }, + ) + + // Install pnpm locally without saving it as a dependency + const npmInstall = spawnSync("npm", ["install", "--no-save", "pnpm"], { + stdio: "inherit", + shell: true, + }) + + if (npmInstall.status !== 0) { + console.error("Failed to install pnpm locally") + process.exit(1) + } + + // Use the locally installed pnpm + console.log("Running pnpm install...") + pnpmInstall = spawnSync("node_modules/.bin/pnpm", ["install"], { + stdio: "inherit", + shell: true, + env: { + ...process.env, + BOOTSTRAP_IN_PROGRESS: "1", // Set environment variable to indicate bootstrapping + }, + }) + } + + if (pnpmInstall.status !== 0) { + console.error("pnpm install failed") + process.exit(pnpmInstall.status) + } + + console.log("Bootstrap completed successfully") + process.exit(0) +} catch (error) { + console.error("Bootstrap failed:", error) + process.exit(1) +} From c45e6c7db9b50d63076995c70deb0a849b416fa0 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Thu, 22 May 2025 19:05:49 -0700 Subject: [PATCH 2/3] fix: add compile script to package.json This commit adds a "compile" script to the root package.json that runs the TypeScript compilation and bundling steps without creating the final .vsix package. This is needed for various automation scenarios where we want to verify the code compiles correctly without producing the final package. The compile script runs "pnpm --filter roo-cline bundle" which performs the core compilation steps without packaging. Fixes: #3881 Signed-off-by: Eric Wheeler --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ea3e8549c3..553f280a8e 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "format": "turbo format --log-order grouped --output-logs new-only", "clean": "turbo clean --log-order grouped --output-logs new-only && rimraf dist out bin .vite-port .turbo", "build": "pnpm --filter roo-cline vsix", + "compile": "pnpm --filter roo-cline bundle", "build:nightly": "pnpm --filter @roo-code/vscode-nightly vsix", "changeset:version": "cp CHANGELOG.md src/CHANGELOG.md && changeset version && cp -vf src/CHANGELOG.md .", "knip": "pnpm --filter @roo-code/build build && knip --include files", From 2834cdd1c6ac4354f376dad6ba1e445a8abd350a Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Thu, 22 May 2025 19:13:21 -0700 Subject: [PATCH 3/3] fix: add vsix script alias for build This commit adds a vsix script that is an alias for the build script, fixing a regression with existing build automation that expects to be able to run "npm run vsix" to create a vsix package. This ensures backward compatibility with existing CI/CD pipelines and build scripts that may be using the vsix command directly. Signed-off-by: Eric Wheeler --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 553f280a8e..e76682e66d 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "clean": "turbo clean --log-order grouped --output-logs new-only && rimraf dist out bin .vite-port .turbo", "build": "pnpm --filter roo-cline vsix", "compile": "pnpm --filter roo-cline bundle", + "vsix": "pnpm --filter roo-cline vsix", "build:nightly": "pnpm --filter @roo-code/vscode-nightly vsix", "changeset:version": "cp CHANGELOG.md src/CHANGELOG.md && changeset version && cp -vf src/CHANGELOG.md .", "knip": "pnpm --filter @roo-code/build build && knip --include files",