Roo-Code/scripts/link-packages.js
2025-08-13 01:40:00 -07:00

158 lines
4.6 KiB
JavaScript
Executable file

#!/usr/bin/env node
const { spawn, execSync } = require("child_process")
const path = require("path")
const fs = require("fs")
// Package configuration - Add new packages here as needed.
const config = {
packages: [
{
name: "@roo-code/cloud",
sourcePath: "../Roo-Code-Cloud/packages/sdk",
targetPath: "src/node_modules/@roo-code/cloud",
npmPath: "npm",
watchCommand: "pnpm build:development:watch",
},
],
}
const args = process.argv.slice(2)
const packageName = args.find((arg) => !arg.startsWith("--"))
const watch = !args.includes("--no-watch")
const unlink = args.includes("--unlink")
const packages = packageName ? config.packages.filter((p) => p.name === packageName) : config.packages
if (!packages.length) {
console.error(`Package '${packageName}' not found`)
process.exit(1)
}
packages.forEach(unlink ? unlinkPackage : linkPackage)
// After unlinking, restore npm packages with a single pnpm install.
if (unlink && packages.length > 0) {
const srcPath = path.resolve(__dirname, "..", "src")
console.log("\nRestoring npm packages...")
try {
execSync("pnpm install", { cwd: srcPath, stdio: "inherit" })
console.log("Successfully restored npm packages")
} catch (error) {
console.error(`Failed to restore packages: ${error.message}`)
console.log("You may need to run 'pnpm install' manually in the src directory")
}
}
if (!unlink && watch) {
const watchers = packages.filter((pkg) => pkg.watchCommand).map(startWatch)
if (watchers.length) {
process.on("SIGINT", () => {
console.log("\nStopping...")
watchers.forEach((w) => w.kill())
process.exit(0)
})
console.log("\nWatching for changes. Press Ctrl+C to stop.\n")
}
}
function generateNpmPackageJson(sourcePath, npmPath) {
const npmDir = path.join(sourcePath, npmPath)
const npmPackagePath = path.join(npmDir, "package.json")
const npmMetadataPath = path.join(npmDir, "package.metadata.json")
const monorepoPackagePath = path.join(sourcePath, "package.json")
if (fs.existsSync(npmPackagePath)) {
console.log(` ✓ npm/package.json already exists`)
return
}
if (!fs.existsSync(npmMetadataPath)) {
console.log(` ⚠ No package.metadata.json found, skipping npm package.json generation`)
return
}
try {
console.log(` 📦 Generating npm/package.json...`)
const monorepoPackage = JSON.parse(fs.readFileSync(monorepoPackagePath, "utf8"))
const npmMetadata = JSON.parse(fs.readFileSync(npmMetadataPath, "utf8"))
const npmPackage = {
...npmMetadata,
type: "module",
dependencies: monorepoPackage.dependencies || {},
main: "./dist/index.cjs",
module: "./dist/index.js",
types: "./dist/index.d.ts",
exports: {
".": {
types: "./dist/index.d.ts",
import: "./dist/index.js",
require: {
types: "./dist/index.d.cts",
default: "./dist/index.cjs",
},
},
},
files: ["dist"],
}
fs.writeFileSync(npmPackagePath, JSON.stringify(npmPackage, null, 2) + "\n")
console.log(` ✓ Generated npm/package.json for ${npmPackage.name}`)
} catch (error) {
console.error(` ✗ Failed to generate npm/package.json: ${error.message}`)
}
}
function linkPackage(pkg) {
const sourcePath = path.resolve(__dirname, "..", pkg.sourcePath)
const targetPath = path.resolve(__dirname, "..", pkg.targetPath)
if (!fs.existsSync(sourcePath)) {
console.error(`Source not found: ${sourcePath}`)
process.exit(1)
}
// Install dependencies if needed.
if (!fs.existsSync(path.join(sourcePath, "node_modules"))) {
console.log(`Installing dependencies for ${pkg.name}...`)
try {
execSync("pnpm install", { cwd: sourcePath, stdio: "inherit" })
} catch (e) {
execSync("pnpm install --no-frozen-lockfile", { cwd: sourcePath, stdio: "inherit" })
}
}
// If npmPath is specified, check if we need to generate package.json.
if (pkg.npmPath) {
generateNpmPackageJson(sourcePath, pkg.npmPath)
}
// Create symlink.
fs.rmSync(targetPath, { recursive: true, force: true })
fs.mkdirSync(path.dirname(targetPath), { recursive: true })
const linkSource = pkg.npmPath ? path.join(sourcePath, pkg.npmPath) : sourcePath
fs.symlinkSync(linkSource, targetPath, "dir")
console.log(`Linked ${pkg.name}`)
}
function unlinkPackage(pkg) {
const targetPath = path.resolve(__dirname, "..", pkg.targetPath)
if (fs.existsSync(targetPath)) {
fs.rmSync(targetPath, { recursive: true, force: true })
console.log(`Unlinked ${pkg.name}`)
}
}
function startWatch(pkg) {
console.log(`Watching ${pkg.name}...`)
const [cmd, ...args] = pkg.watchCommand.split(" ")
return spawn(cmd, args, {
cwd: path.resolve(__dirname, "..", pkg.sourcePath),
stdio: "inherit",
shell: true,
})
}