Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/vscode-nightly/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
139 changes: 139 additions & 0 deletions apps/vscode-nightly/esbuild.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as esbuild from "esbuild"
import * as fs from "fs"
import * as path from "path"
import { fileURLToPath } from "url"

import { copyPaths, copyLocales, copyWasms } from "@roo-code/build"

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

async function main() {
const production = process.argv.includes("--production")
const minify = production
const sourcemap = !production

/**
* @type {import('esbuild').BuildOptions}
*/
const buildOptions = {
bundle: true,
minify,
sourcemap,
logLevel: "silent",
format: "cjs",
sourcesContent: false,
platform: "node",
}

const srcDir = path.join(__dirname, "..", "..", "src")
const buildDir = path.join(__dirname, "build")
const distDir = path.join(buildDir, "dist")

/**
* @type {import('esbuild').Plugin[]}
*/
const plugins = [
{
name: "copy-src",
setup(build) {
build.onEnd(() => {
const paths = [
["LICENSE", "LICENSE"],
[".vscodeignore", ".vscodeignore"],
["assets", "assets"],
["integrations", "integrations"],
["node_modules/vscode-material-icons/generated", "assets/vscode-material-icons"],
["../webview-ui/audio", "webview-ui/audio"],
]

copyPaths(paths, srcDir, buildDir)

let count = 0

fs.readdirSync(path.join(srcDir)).forEach((file) => {
if (file.startsWith("package.nls")) {
fs.copyFileSync(path.join(srcDir, file), path.join(buildDir, file))
count++
}
})

console.log(`[copy-src] Copied ${count} package.nls*.json files to ${buildDir}`)
})
},
},
{
name: "generate-package-json",
setup(build) {
build.onEnd(() => {
const packageJson = JSON.parse(fs.readFileSync(path.join(srcDir, "package.json"), "utf8"))

const packageNightlyJson = JSON.parse(
fs.readFileSync(path.join(__dirname, "package.nightly.json"), "utf8"),
)

fs.writeFileSync(
path.join(buildDir, "package.json"),
JSON.stringify({ ...packageJson, ...packageNightlyJson }, null, 2),
)

console.log(`[generate-package-json] Generated package.json from package.nightly.json`)
})
},
},
{
name: "copy-wasms",
setup(build) {
build.onEnd(() => {
copyWasms(srcDir, distDir)
})
},
},
{
name: "copy-locales",
setup(build) {
build.onEnd(() => {
copyLocales(srcDir, distDir)
})
},
},
]

/**
* @type {import('esbuild').BuildOptions}
*/
const extensionBuildOptions = {
...buildOptions,
plugins,
entryPoints: [path.join(srcDir, "extension.ts")],
outfile: path.join(distDir, "extension.js"),
external: ["vscode"],
}

/**
* @type {import('esbuild').BuildOptions}
*/
const workerBuildOptions = {
...buildOptions,
entryPoints: [path.join(srcDir, "workers", "countTokens.ts")],
outdir: path.join(distDir, "workers"),
}

const [extensionBuildContext, workerBuildContext] = await Promise.all([
esbuild.context(extensionBuildOptions),
esbuild.context(workerBuildOptions),
])

await Promise.all([
extensionBuildContext.rebuild(),
extensionBuildContext.dispose(),

workerBuildContext.rebuild(),
workerBuildContext.dispose(),
])
}

main().catch((e) => {
console.error(e)
process.exit(1)
})
25 changes: 25 additions & 0 deletions apps/vscode-nightly/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "import",
"format": ["camelCase", "PascalCase"]
}
],
"@typescript-eslint/semi": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }],
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off"
},
"ignorePatterns": ["dist"]
}
20 changes: 20 additions & 0 deletions apps/vscode-nightly/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@roo-code/vscode-nightly",
"description": "Nightly build for the Roo Code VSCode extension.",
"private": true,
"packageManager": "[email protected]",
"scripts": {
"build": "rimraf build && pnpm --filter @roo-code/build build && node esbuild.mjs --production && pnpm --filter @roo-code/vscode-webview build --mode nightly",
"vsix": "pnpm build && cd build && npx vsce package --no-dependencies --out ../../../bin",
"clean": "rimraf build"
},
"dependencies": {
"@roo-code/build": "workspace:^"
},
"devDependencies": {
"@vscode/vsce": "3.3.2",
"esbuild": "^0.25.0",
"mkdirp": "^3.0.1",
"rimraf": "^6.0.1"
}
}
8 changes: 8 additions & 0 deletions apps/vscode-nightly/package.nightly.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "roo-code-nightly",
"displayName": "Roo Code Nightly",
"publisher": "RooVeterinaryInc",
"version": "0.0.1",
"icon": "assets/icons/icon-nightly.png",
"scripts": {}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"test": "turbo test --log-order grouped --output-logs new-only",
"format": "turbo format --log-order grouped --output-logs new-only",
"build": "pnpm --filter roo-cline vsix",
"build:nightly": "pnpm --filter @roo-code/vscode-nightly vsix",
"changeset": "changeset",
"knip": "knip --include files",
"update-contributors": "node scripts/update-contributors.js"
Expand Down
25 changes: 25 additions & 0 deletions packages/build/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "import",
"format": ["camelCase", "PascalCase"]
}
],
"@typescript-eslint/semi": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }],
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off"
},
"ignorePatterns": ["dist"]
}
13 changes: 13 additions & 0 deletions packages/build/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@roo-code/build",
"description": "ESBuild utilities for Roo Code.",
"private": true,
"type": "module",
"exports": "./dist/index.js",
"scripts": {
"build": "tsc"
},
"devDependencies": {
"@types/node": "^22.15.20"
}
}
122 changes: 122 additions & 0 deletions packages/build/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import * as fs from "fs"
import * as path from "path"

/**
* Copies all files or directories from source to destination
* @param paths Array of file or directory paths to copy
* @param srcDir Source directory path
* @param dstDir Destination directory path
*/
export function copyPaths(copyPaths: [string, string][], srcDir: string, dstDir: string) {
copyPaths.forEach(([srcRelPath, dstRelPath]) => {
const stats = fs.lstatSync(path.join(srcDir, srcRelPath))

console.log(`[copy-src] ${srcRelPath} -> ${dstRelPath}`)

if (stats.isDirectory()) {
if (fs.existsSync(path.join(dstDir, dstRelPath))) {
fs.rmSync(path.join(dstDir, dstRelPath), { recursive: true })
}

fs.mkdirSync(path.join(dstDir, dstRelPath), { recursive: true })

const count = copyDir(path.join(srcDir, srcRelPath), path.join(dstDir, dstRelPath), 0)
console.log(`[copy-src] Copied ${count} files from ${srcRelPath} to ${dstRelPath}`)
} else {
fs.copyFileSync(path.join(srcDir, srcRelPath), path.join(dstDir, dstRelPath))
console.log(`[copy-src] Copied ${srcRelPath} to ${dstRelPath}`)
}
})
}

/**
* Recursively copies files from source directory to destination directory
* @param srcDir Source directory path
* @param dstDir Destination directory path
* @param count Counter for number of files copied
* @returns Updated count of files copied
*/
export function copyDir(srcDir: string, dstDir: string, count: number): number {
const entries = fs.readdirSync(srcDir, { withFileTypes: true })

for (const entry of entries) {
const srcPath = path.join(srcDir, entry.name)
const dstPath = path.join(dstDir, entry.name)

if (entry.isDirectory()) {
fs.mkdirSync(dstPath, { recursive: true })
count = copyDir(srcPath, dstPath, count)
} else {
count = count + 1
fs.copyFileSync(srcPath, dstPath)
}
}

return count
}

/**
* Copies WASM files from node_modules to the distribution directory
* @param srcDir Source directory path
* @param distDir Distribution directory path
*/
export function copyWasms(srcDir: string, distDir: string): void {
const nodeModulesDir = path.join(srcDir, "node_modules")

fs.mkdirSync(distDir, { recursive: true })

// Tiktoken WASM file.
fs.copyFileSync(
path.join(nodeModulesDir, "tiktoken", "lite", "tiktoken_bg.wasm"),
path.join(distDir, "tiktoken_bg.wasm"),
)

console.log(`[copy-wasm-files] Copied tiktoken WASMs to ${distDir}`)

// Also copy Tiktoken WASMs to the workers directory.
const workersDir = path.join(distDir, "workers")
fs.mkdirSync(workersDir, { recursive: true })

fs.copyFileSync(
path.join(nodeModulesDir, "tiktoken", "lite", "tiktoken_bg.wasm"),
path.join(workersDir, "tiktoken_bg.wasm"),
)

console.log(`[copy-wasm-files] Copied tiktoken WASMs to ${workersDir}`)

// Main tree-sitter WASM file.
fs.copyFileSync(
path.join(nodeModulesDir, "web-tree-sitter", "tree-sitter.wasm"),
path.join(distDir, "tree-sitter.wasm"),
)

console.log(`[copy-wasm-files] Copied tree-sitter.wasm to ${distDir}`)

// Copy language-specific WASM files.
const languageWasmDir = path.join(nodeModulesDir, "tree-sitter-wasms", "out")

if (!fs.existsSync(languageWasmDir)) {
throw new Error(`Directory does not exist: ${languageWasmDir}`)
}

// Dynamically read all WASM files from the directory instead of using a hardcoded list.
const wasmFiles = fs.readdirSync(languageWasmDir).filter((file) => file.endsWith(".wasm"))

wasmFiles.forEach((filename) => {
fs.copyFileSync(path.join(languageWasmDir, filename), path.join(distDir, filename))
})

console.log(`[copy-wasm-files] Copied ${wasmFiles.length} tree-sitter language wasms to ${distDir}`)
}

/**
* Copies locale files to the distribution directory
* @param srcDir Source directory path
* @param distDir Distribution directory path
*/
export function copyLocales(srcDir: string, distDir: string): void {
const destDir = path.join(distDir, "i18n", "locales")
fs.mkdirSync(destDir, { recursive: true })
const count = copyDir(path.join(srcDir, "i18n", "locales"), destDir, 0)
console.log(`[copy-locales-files] Copied ${count} locale files to ${destDir}`)
}
21 changes: 21 additions & 0 deletions packages/build/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"incremental": false,
"isolatedModules": true,
"lib": ["es2022", "DOM", "DOM.Iterable"],
"module": "NodeNext",
"moduleDetection": "force",
"moduleResolution": "NodeNext",
"noUncheckedIndexedAccess": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "ES2022",
"outDir": "dist"
},
"include": ["src"]
}
Loading