2
0

link-packages.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env node
  2. const { spawn, execSync } = require("child_process")
  3. const path = require("path")
  4. const fs = require("fs")
  5. // Package configuration - Add new packages here as needed.
  6. const config = {
  7. packages: [
  8. {
  9. name: "@roo-code/cloud",
  10. sourcePath: "../Roo-Code-Cloud/packages/sdk",
  11. targetPath: "src/node_modules/@roo-code/cloud",
  12. npmPath: "npm",
  13. watchCommand: "pnpm build:development:watch",
  14. },
  15. ],
  16. }
  17. const args = process.argv.slice(2)
  18. const packageName = args.find((arg) => !arg.startsWith("--"))
  19. const watch = !args.includes("--no-watch")
  20. const unlink = args.includes("--unlink")
  21. const packages = packageName ? config.packages.filter((p) => p.name === packageName) : config.packages
  22. if (!packages.length) {
  23. console.error(`Package '${packageName}' not found`)
  24. process.exit(1)
  25. }
  26. packages.forEach(unlink ? unlinkPackage : linkPackage)
  27. // After unlinking, restore npm packages with a single pnpm install.
  28. if (unlink && packages.length > 0) {
  29. const srcPath = path.resolve(__dirname, "..", "src")
  30. console.log("\nRestoring npm packages...")
  31. try {
  32. execSync("pnpm install", { cwd: srcPath, stdio: "inherit" })
  33. console.log("Successfully restored npm packages")
  34. } catch (error) {
  35. console.error(`Failed to restore packages: ${error.message}`)
  36. console.log("You may need to run 'pnpm install' manually in the src directory")
  37. }
  38. }
  39. if (!unlink && watch) {
  40. const watchers = packages.filter((pkg) => pkg.watchCommand).map(startWatch)
  41. if (watchers.length) {
  42. process.on("SIGINT", () => {
  43. console.log("\nStopping...")
  44. watchers.forEach((w) => w.kill())
  45. process.exit(0)
  46. })
  47. console.log("\nWatching for changes. Press Ctrl+C to stop.\n")
  48. }
  49. }
  50. function generateNpmPackageJson(sourcePath, npmPath) {
  51. const npmDir = path.join(sourcePath, npmPath)
  52. const npmPackagePath = path.join(npmDir, "package.json")
  53. const npmMetadataPath = path.join(npmDir, "package.metadata.json")
  54. const monorepoPackagePath = path.join(sourcePath, "package.json")
  55. if (fs.existsSync(npmPackagePath)) {
  56. console.log(` ✓ npm/package.json already exists`)
  57. return
  58. }
  59. if (!fs.existsSync(npmMetadataPath)) {
  60. console.log(` ⚠ No package.metadata.json found, skipping npm package.json generation`)
  61. return
  62. }
  63. try {
  64. console.log(` 📦 Generating npm/package.json...`)
  65. const monorepoPackage = JSON.parse(fs.readFileSync(monorepoPackagePath, "utf8"))
  66. const npmMetadata = JSON.parse(fs.readFileSync(npmMetadataPath, "utf8"))
  67. const npmPackage = {
  68. ...npmMetadata,
  69. type: "module",
  70. dependencies: monorepoPackage.dependencies || {},
  71. main: "./dist/index.cjs",
  72. module: "./dist/index.js",
  73. types: "./dist/index.d.ts",
  74. exports: {
  75. ".": {
  76. types: "./dist/index.d.ts",
  77. import: "./dist/index.js",
  78. require: {
  79. types: "./dist/index.d.cts",
  80. default: "./dist/index.cjs",
  81. },
  82. },
  83. },
  84. files: ["dist"],
  85. }
  86. fs.writeFileSync(npmPackagePath, JSON.stringify(npmPackage, null, 2) + "\n")
  87. console.log(` ✓ Generated npm/package.json for ${npmPackage.name}`)
  88. } catch (error) {
  89. console.error(` ✗ Failed to generate npm/package.json: ${error.message}`)
  90. }
  91. }
  92. function linkPackage(pkg) {
  93. const sourcePath = path.resolve(__dirname, "..", pkg.sourcePath)
  94. const targetPath = path.resolve(__dirname, "..", pkg.targetPath)
  95. if (!fs.existsSync(sourcePath)) {
  96. console.error(`Source not found: ${sourcePath}`)
  97. process.exit(1)
  98. }
  99. // Install dependencies if needed.
  100. if (!fs.existsSync(path.join(sourcePath, "node_modules"))) {
  101. console.log(`Installing dependencies for ${pkg.name}...`)
  102. try {
  103. execSync("pnpm install", { cwd: sourcePath, stdio: "inherit" })
  104. } catch (e) {
  105. execSync("pnpm install --no-frozen-lockfile", { cwd: sourcePath, stdio: "inherit" })
  106. }
  107. }
  108. // If npmPath is specified, check if we need to generate package.json.
  109. if (pkg.npmPath) {
  110. generateNpmPackageJson(sourcePath, pkg.npmPath)
  111. }
  112. // Create symlink.
  113. fs.rmSync(targetPath, { recursive: true, force: true })
  114. fs.mkdirSync(path.dirname(targetPath), { recursive: true })
  115. const linkSource = pkg.npmPath ? path.join(sourcePath, pkg.npmPath) : sourcePath
  116. fs.symlinkSync(linkSource, targetPath, "dir")
  117. console.log(`Linked ${pkg.name}`)
  118. }
  119. function unlinkPackage(pkg) {
  120. const targetPath = path.resolve(__dirname, "..", pkg.targetPath)
  121. if (fs.existsSync(targetPath)) {
  122. fs.rmSync(targetPath, { recursive: true, force: true })
  123. console.log(`Unlinked ${pkg.name}`)
  124. }
  125. }
  126. function startWatch(pkg) {
  127. console.log(`Watching ${pkg.name}...`)
  128. const [cmd, ...args] = pkg.watchCommand.split(" ")
  129. return spawn(cmd, args, {
  130. cwd: path.resolve(__dirname, "..", pkg.sourcePath),
  131. stdio: "inherit",
  132. shell: true,
  133. })
  134. }