Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
19 changes: 18 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/kilo-vscode/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
6 changes: 6 additions & 0 deletions packages/kilo-vscode/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
out/**
node_modules/**
src/**
webview-ui/**
.gitignore
.yarnrc
.npmrc
esbuild.js
vsc-extension-quickstart.md
**/tsconfig.json
**/eslint.config.mjs
**/*.map
**/*.ts
**/.vscode-test.*
pnpm-lock.yaml

# Include bin/ directory for CLI binary (production)
!bin/**
8 changes: 5 additions & 3 deletions packages/kilo-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -125,6 +126,7 @@
"typescript-eslint": "^8.54.0"
},
"dependencies": {
"eventsource": "^2.0.2",
"solid-js": "^1.9.11"
}
}
17 changes: 11 additions & 6 deletions packages/kilo-vscode/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

120 changes: 120 additions & 0 deletions packages/kilo-vscode/scripts/prepare-cli-binary.mjs
Original file line number Diff line number Diff line change
@@ -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);
}

Loading
Loading