mirror of
https://github.com/cline/cline.git
synced 2026-09-24 23:20:16 +08:00
* Fix check for debug build in package-standalone script
* Support node modules that include binaries
Add support to the scripts/package-standalone.js for node modules that use platform-specific binary modules.
By default the script bundles the module for all platforms, this can be disabled with -s for single platform builds.
The module for each platform will be bundled into standalone.zip in platform specific directories:
```
binaries/linux-arm64/node_modules
binaries/darwin-x64/node_modules
binaries/win32-x64/node_modules
binaries/darwin-arm64/node_modules
binaries/linux-x64/node_modules
```
When running cline-core add the correct directory to the NODE_PATH, e.g.
```
$ export NODE_PATH=./node_modules/:./binaries/darwin-arm64/node_modules/
cline:/tmp/1$ node cline-core.js
Loading stubs...
Finished loading stubs
Loading stub impls...
Finished loading stub impls...
Cline environment: production
XS variant configuration warnings: [
'Component overrides for unused components: TOOL_USE_SECTION, TOOLS_SECTION, MCP_SECTION, TODO_SECTION, FEEDBACK_SECTION',
'Missing recommended components: TOOL_USE_SECTION'
]
[2025-09-05T19:53:00.853] #bot.cline.server.ts Running standalone cline 0.0.1
[2025-09-05T19:53:00.854] #bot.cline.server.ts Using settings dir: /Users/sjf/.cline/data
Finished loading vscode context...
[2025-09-05T19:53:00.858] #bot.cline.server.ts
Starting cline-core service...
sjfsjf created DBBBBBBBBB: Database {
name: '/tmp/db.sql',
open: true,
inTransaction: false,
readonly: false,
memory: false
}
```
* Apply suggestion from @ellipsis-dev[bot]
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* Apply suggestion from @ellipsis-dev[bot]
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* Support node modules that include binaries
Add support to the scripts/package-standalone.js for node modules that use platform-specific binary modules.
By default the script bundles the module for all platforms, this can be disabled with -s for single platform builds.
The module for each platform will be bundled into standalone.zip in platform specific directories:
```
binaries/linux-arm64/node_modules
binaries/darwin-x64/node_modules
binaries/win32-x64/node_modules
binaries/darwin-arm64/node_modules
binaries/linux-x64/node_modules
```
When running cline-core add the correct directory to the NODE_PATH, e.g.
```
$ export NODE_PATH=./node_modules/:./binaries/darwin-arm64/node_modules/
cline:/tmp/1$ node cline-core.js
Loading stubs...
Finished loading stubs
Loading stub impls...
Finished loading stub impls...
Cline environment: production
XS variant configuration warnings: [
'Component overrides for unused components: TOOL_USE_SECTION, TOOLS_SECTION, MCP_SECTION, TODO_SECTION, FEEDBACK_SECTION',
'Missing recommended components: TOOL_USE_SECTION'
]
[2025-09-05T19:53:00.853] #bot.cline.server.ts Running standalone cline 0.0.1
[2025-09-05T19:53:00.854] #bot.cline.server.ts Using settings dir: /Users/sjf/.cline/data
Finished loading vscode context...
[2025-09-05T19:53:00.858] #bot.cline.server.ts
Starting cline-core service...
sjfsjf created DBBBBBBBBB: Database {
name: '/tmp/db.sql',
open: true,
inTransaction: false,
readonly: false,
memory: false
}
```
* Apply suggestion from @ellipsis-dev[bot]
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* Apply suggestion from @ellipsis-dev[bot]
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* Apply suggestion from @ellipsis-dev[bot]
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* Remove test code
* Use the correct target directory for the binaries
The directory structure that the JB host expects is does
not exactly match ${arch}-${os}
* Update package-standalone script
Warn if there is module that needs binaries, but it is not being used.
Reset the binaries dir before packaging.
---------
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
193 lines
5.3 KiB
JavaScript
193 lines
5.3 KiB
JavaScript
import fs from "node:fs"
|
|
import path from "node:path"
|
|
import { fileURLToPath } from "node:url"
|
|
import * as esbuild from "esbuild"
|
|
|
|
const __filename = fileURLToPath(import.meta.url)
|
|
const __dirname = path.dirname(__filename)
|
|
|
|
const production = process.argv.includes("--production")
|
|
const watch = process.argv.includes("--watch")
|
|
const standalone = process.argv.includes("--standalone")
|
|
const e2eBuild = process.argv.includes("--e2e-build")
|
|
const destDir = standalone ? "dist-standalone" : "dist"
|
|
|
|
/**
|
|
* @type {import('esbuild').Plugin}
|
|
*/
|
|
const aliasResolverPlugin = {
|
|
name: "alias-resolver",
|
|
setup(build) {
|
|
const aliases = {
|
|
"@": path.resolve(__dirname, "src"),
|
|
"@core": path.resolve(__dirname, "src/core"),
|
|
"@integrations": path.resolve(__dirname, "src/integrations"),
|
|
"@services": path.resolve(__dirname, "src/services"),
|
|
"@shared": path.resolve(__dirname, "src/shared"),
|
|
"@utils": path.resolve(__dirname, "src/utils"),
|
|
"@packages": path.resolve(__dirname, "src/packages"),
|
|
}
|
|
|
|
// For each alias entry, create a resolver
|
|
Object.entries(aliases).forEach(([alias, aliasPath]) => {
|
|
const aliasRegex = new RegExp(`^${alias}($|/.*)`)
|
|
build.onResolve({ filter: aliasRegex }, (args) => {
|
|
const importPath = args.path.replace(alias, aliasPath)
|
|
|
|
// First, check if the path exists as is
|
|
if (fs.existsSync(importPath)) {
|
|
const stats = fs.statSync(importPath)
|
|
if (stats.isDirectory()) {
|
|
// If it's a directory, try to find index files
|
|
const extensions = [".ts", ".tsx", ".js", ".jsx"]
|
|
for (const ext of extensions) {
|
|
const indexFile = path.join(importPath, `index${ext}`)
|
|
if (fs.existsSync(indexFile)) {
|
|
return { path: indexFile }
|
|
}
|
|
}
|
|
} else {
|
|
// It's a file that exists, so return it
|
|
return { path: importPath }
|
|
}
|
|
}
|
|
|
|
// If the path doesn't exist, try appending extensions
|
|
const extensions = [".ts", ".tsx", ".js", ".jsx"]
|
|
for (const ext of extensions) {
|
|
const pathWithExtension = `${importPath}${ext}`
|
|
if (fs.existsSync(pathWithExtension)) {
|
|
return { path: pathWithExtension }
|
|
}
|
|
}
|
|
|
|
// If nothing worked, return the original path and let esbuild handle the error
|
|
return { path: importPath }
|
|
})
|
|
})
|
|
},
|
|
}
|
|
|
|
const esbuildProblemMatcherPlugin = {
|
|
name: "esbuild-problem-matcher",
|
|
|
|
setup(build) {
|
|
build.onStart(() => {
|
|
console.log("[watch] build started")
|
|
})
|
|
build.onEnd((result) => {
|
|
result.errors.forEach(({ text, location }) => {
|
|
console.error(`✘ [ERROR] ${text}`)
|
|
console.error(` ${location.file}:${location.line}:${location.column}:`)
|
|
})
|
|
console.log("[watch] build finished")
|
|
})
|
|
},
|
|
}
|
|
|
|
const copyWasmFiles = {
|
|
name: "copy-wasm-files",
|
|
setup(build) {
|
|
build.onEnd(() => {
|
|
// tree sitter
|
|
const sourceDir = path.join(__dirname, "node_modules", "web-tree-sitter")
|
|
const targetDir = path.join(__dirname, destDir)
|
|
|
|
// Copy tree-sitter.wasm
|
|
fs.copyFileSync(path.join(sourceDir, "tree-sitter.wasm"), path.join(targetDir, "tree-sitter.wasm"))
|
|
|
|
// Copy language-specific WASM files
|
|
const languageWasmDir = path.join(__dirname, "node_modules", "tree-sitter-wasms", "out")
|
|
const languages = [
|
|
"typescript",
|
|
"tsx",
|
|
"python",
|
|
"rust",
|
|
"javascript",
|
|
"go",
|
|
"cpp",
|
|
"c",
|
|
"c_sharp",
|
|
"ruby",
|
|
"java",
|
|
"php",
|
|
"swift",
|
|
"kotlin",
|
|
]
|
|
|
|
languages.forEach((lang) => {
|
|
const filename = `tree-sitter-${lang}.wasm`
|
|
fs.copyFileSync(path.join(languageWasmDir, filename), path.join(targetDir, filename))
|
|
})
|
|
})
|
|
},
|
|
}
|
|
|
|
// Base configuration shared between extension and standalone builds
|
|
const baseConfig = {
|
|
bundle: true,
|
|
minify: production,
|
|
sourcemap: !production,
|
|
logLevel: "silent",
|
|
define: production
|
|
? { "import.meta.url": "_importMetaUrl", "process.env.IS_DEV": JSON.stringify(!production) }
|
|
: { "import.meta.url": "_importMetaUrl" },
|
|
tsconfig: path.resolve(__dirname, "tsconfig.json"),
|
|
plugins: [
|
|
copyWasmFiles,
|
|
aliasResolverPlugin,
|
|
/* add to the end of plugins array */
|
|
esbuildProblemMatcherPlugin,
|
|
],
|
|
format: "cjs",
|
|
sourcesContent: false,
|
|
platform: "node",
|
|
banner: {
|
|
js: "const _importMetaUrl=require('url').pathToFileURL(__filename)",
|
|
},
|
|
}
|
|
|
|
// Extension-specific configuration
|
|
const extensionConfig = {
|
|
...baseConfig,
|
|
entryPoints: ["src/extension.ts"],
|
|
outfile: `${destDir}/extension.js`,
|
|
external: ["vscode"],
|
|
}
|
|
|
|
// Standalone-specific configuration
|
|
const standaloneConfig = {
|
|
...baseConfig,
|
|
entryPoints: ["src/standalone/cline-core.ts"],
|
|
outfile: `${destDir}/cline-core.js`,
|
|
// These modules need to load files from the module directory at runtime,
|
|
// so they cannot be bundled.
|
|
external: ["vscode", "@grpc/reflection", "grpc-health-check", "better-sqlite3"],
|
|
}
|
|
|
|
// E2E build script configuration
|
|
const e2eBuildConfig = {
|
|
...baseConfig,
|
|
entryPoints: ["src/test/e2e/utils/build.ts"],
|
|
outfile: `${destDir}/e2e-build.mjs`,
|
|
external: ["@vscode/test-electron", "execa"],
|
|
sourcemap: false,
|
|
plugins: [aliasResolverPlugin, esbuildProblemMatcherPlugin],
|
|
}
|
|
|
|
async function main() {
|
|
const config = standalone ? standaloneConfig : e2eBuild ? e2eBuildConfig : extensionConfig
|
|
const extensionCtx = await esbuild.context(config)
|
|
if (watch) {
|
|
await extensionCtx.watch()
|
|
} else {
|
|
await extensionCtx.rebuild()
|
|
await extensionCtx.dispose()
|
|
}
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error(e)
|
|
process.exit(1)
|
|
})
|