mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
build: prepare and bundle CLI binary during extension build
This commit is contained in:
@@ -99,11 +99,12 @@
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "pnpm run package",
|
||||
"compile": "pnpm run check-types && pnpm run lint && node esbuild.js",
|
||||
"prepare:cli-binary": "node scripts/prepare-cli-binary.mjs",
|
||||
"compile": "pnpm run prepare:cli-binary && pnpm run check-types && pnpm run lint && node esbuild.js",
|
||||
"watch": "npm-run-all -p watch:*",
|
||||
"watch:esbuild": "node esbuild.js --watch",
|
||||
"watch:esbuild": "pnpm run prepare:cli-binary && node esbuild.js --watch",
|
||||
"watch:tsc": "tsc --noEmit --watch --project tsconfig.json",
|
||||
"package": "pnpm run check-types && pnpm run lint && node esbuild.js --production",
|
||||
"package": "pnpm run prepare:cli-binary && pnpm run check-types && pnpm run lint && node esbuild.js --production",
|
||||
"compile-tests": "tsc -p . --outDir out",
|
||||
"watch-tests": "tsc -p . -w --outDir out",
|
||||
"pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint",
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import { existsSync, mkdirSync, readdirSync, statSync, copyFileSync, chmodSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
/**
|
||||
* Ensures the VS Code extension has a CLI binary at `packages/kilo-vscode/bin/kilo`.
|
||||
*
|
||||
* Strategy:
|
||||
* 1) If `bin/kilo` already exists -> ok.
|
||||
* 2) Else try to locate a prebuilt binary produced by `packages/opencode` build.
|
||||
* 3) Else try to build it via `bun run build --single` in `packages/opencode`.
|
||||
* 4) Copy the resulting binary into `packages/kilo-vscode/bin/kilo` and chmod +x.
|
||||
*
|
||||
* This script is intended to be run from `packages/kilo-vscode` as part of build/package.
|
||||
*/
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const kiloVscodeDir = path.resolve(__dirname, "..");
|
||||
const repoRootDir = path.resolve(kiloVscodeDir, "..");
|
||||
const opencodeDir = path.resolve(repoRootDir, "opencode");
|
||||
|
||||
const targetBinDir = path.resolve(kiloVscodeDir, "bin");
|
||||
const targetBinPath = path.resolve(targetBinDir, "kilo");
|
||||
|
||||
function log(msg) {
|
||||
// Keep logs machine-grep friendly in CI
|
||||
console.log(`[prepare-cli-binary] ${msg}`);
|
||||
}
|
||||
|
||||
function findKiloBinaryInOpencodeDist() {
|
||||
const distDir = path.resolve(opencodeDir, "dist");
|
||||
if (!existsSync(distDir)) return null;
|
||||
|
||||
// Expected: packages/opencode/dist/@kilocode/cli-<platform>/bin/kilo
|
||||
// But keep it flexible: find any dist/**/bin/kilo
|
||||
/** @type {string[]} */
|
||||
const queue = [distDir];
|
||||
while (queue.length) {
|
||||
const dir = queue.pop();
|
||||
if (!dir) continue;
|
||||
let entries;
|
||||
try {
|
||||
entries = readdirSync(dir, { withFileTypes: true });
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (const e of entries) {
|
||||
const p = path.join(dir, e.name);
|
||||
if (e.isDirectory()) {
|
||||
queue.push(p);
|
||||
continue;
|
||||
}
|
||||
if (e.isFile() && e.name === "kilo" && path.basename(path.dirname(p)) === "bin") {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function ensureBuiltBinary() {
|
||||
const found = findKiloBinaryInOpencodeDist();
|
||||
if (found) return found;
|
||||
|
||||
log(`No prebuilt binary found under ${path.relative(kiloVscodeDir, path.resolve(opencodeDir, "dist"))} - attempting build via bun.`);
|
||||
|
||||
try {
|
||||
execSync("bun --version", { stdio: "ignore" });
|
||||
} catch {
|
||||
throw new Error(
|
||||
`Bun is required to build the CLI binary, but was not found on PATH. ` +
|
||||
`Install bun, or build the CLI separately in ${opencodeDir} and re-run.`
|
||||
);
|
||||
}
|
||||
|
||||
// Build using the opencode package script.
|
||||
execSync("bun run build --single", {
|
||||
cwd: opencodeDir,
|
||||
stdio: "inherit",
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
const built = findKiloBinaryInOpencodeDist();
|
||||
if (!built) {
|
||||
throw new Error(
|
||||
`CLI build completed but no binary was found in ${path.resolve(opencodeDir, "dist")} (expected dist/**/bin/kilo).`
|
||||
);
|
||||
}
|
||||
return built;
|
||||
}
|
||||
|
||||
function main() {
|
||||
if (existsSync(targetBinPath)) {
|
||||
const st = statSync(targetBinPath);
|
||||
log(`CLI binary already present at ${path.relative(kiloVscodeDir, targetBinPath)} (${Math.round(st.size / 1024 / 1024)}MB).`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!existsSync(opencodeDir)) {
|
||||
throw new Error(`Expected opencode package at ${opencodeDir}, but it does not exist.`);
|
||||
}
|
||||
|
||||
const sourceBinPath = ensureBuiltBinary();
|
||||
mkdirSync(targetBinDir, { recursive: true });
|
||||
copyFileSync(sourceBinPath, targetBinPath);
|
||||
chmodSync(targetBinPath, 0o755);
|
||||
|
||||
log(`Copied CLI binary from ${path.relative(repoRootDir, sourceBinPath)} -> ${path.relative(kiloVscodeDir, targetBinPath)}`);
|
||||
}
|
||||
|
||||
try {
|
||||
main();
|
||||
} catch (err) {
|
||||
console.error(`[prepare-cli-binary] ERROR: ${err instanceof Error ? err.message : String(err)}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user