mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-10-24 23:13:35 +08:00
feat(vscode): auto-rebuild CLI binary on opencode source changes
- Add watch-cli.ts script that watches packages/opencode/src/ for changes, triggers a rebuild (bun run build --single --skip-install), and copies the new binary to packages/kilo-vscode/bin/kilo - Add watch:cli npm script in kilo-vscode package.json - Add 'VSCode - CLI Watch' task in .vscode/tasks.json - Include CLI watch in the composite 'VSCode - Watch' task so it runs automatically when launching the extension via F5
This commit is contained in:
Vendored
+20
-1
@@ -5,13 +5,16 @@
|
||||
"tasks": [
|
||||
{
|
||||
"label": "VSCode - Watch",
|
||||
"dependsOn": ["VSCode - TSC", "VSCode - ESBuild"],
|
||||
"dependsOn": ["VSCode - TSC", "VSCode - ESBuild", "VSCode - CLI Watch"],
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"runOptions": {
|
||||
"runOn": "folderOpen"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -46,6 +49,22 @@
|
||||
"cwd": "${workspaceFolder}/packages/kilo-vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "VSCode - CLI Watch",
|
||||
"type": "shell",
|
||||
"command": "bun",
|
||||
"args": ["run", "watch:cli"],
|
||||
"group": "build",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"group": "watch",
|
||||
"reveal": "never"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/packages/kilo-vscode"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "VSCode - Tests",
|
||||
"type": "shell",
|
||||
|
||||
@@ -259,6 +259,7 @@
|
||||
"watch": "bun run --parallel watch:esbuild watch:tsc",
|
||||
"watch:esbuild": "bun run prepare:cli-binary && node esbuild.js --watch",
|
||||
"watch:tsc": "tsc --noEmit --watch --project tsconfig.json",
|
||||
"watch:cli": "bun script/watch-cli.ts",
|
||||
"package": "bun run prepare:cli-binary && bun run check-types && bun run lint && node esbuild.js --production",
|
||||
"compile-tests": "tsc -p . --outDir out",
|
||||
"watch-tests": "tsc -p . -w --outDir out",
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* Watches packages/opencode/src/ for changes and rebuilds the CLI binary,
|
||||
* then copies it into packages/kilo-vscode/bin/kilo.
|
||||
*
|
||||
* Used during development so the VS Code extension always has an up-to-date
|
||||
* CLI backend without manual rebuild steps.
|
||||
*/
|
||||
import { watch, chmodSync } from "node:fs"
|
||||
import { join, relative } from "node:path"
|
||||
import { $ } from "bun"
|
||||
|
||||
const kiloVscodeDir = join(import.meta.dir, "..")
|
||||
const packagesDir = join(kiloVscodeDir, "..")
|
||||
const opencodeDir = join(packagesDir, "opencode")
|
||||
const opencodeSrcDir = join(opencodeDir, "src")
|
||||
const targetBinDir = join(kiloVscodeDir, "bin")
|
||||
const targetBinPath = join(targetBinDir, "kilo")
|
||||
|
||||
let building = false
|
||||
let pending = false
|
||||
let installed = false
|
||||
|
||||
function log(msg: string) {
|
||||
console.log(`[watch-cli] ${msg}`)
|
||||
}
|
||||
|
||||
function sourceBinaryPath(): string {
|
||||
return join(opencodeDir, "dist", `@kilocode/cli-${process.platform}-${process.arch}`, "bin", "kilo")
|
||||
}
|
||||
|
||||
async function rebuild() {
|
||||
if (building) {
|
||||
pending = true
|
||||
return
|
||||
}
|
||||
building = true
|
||||
pending = false
|
||||
|
||||
try {
|
||||
log("Rebuilding CLI binary...")
|
||||
const start = performance.now()
|
||||
|
||||
const args = installed ? ["run", "build", "--single", "--skip-install"] : ["run", "build", "--single"]
|
||||
const result = await $`bun ${args}`.cwd(opencodeDir).nothrow().quiet()
|
||||
if (result.exitCode !== 0) {
|
||||
log(`Build failed (exit ${result.exitCode}):\n${result.stderr.toString()}`)
|
||||
return
|
||||
}
|
||||
installed = true
|
||||
|
||||
const source = sourceBinaryPath()
|
||||
if (!await Bun.file(source).exists()) {
|
||||
log(`ERROR: Build completed but no binary found at ${relative(packagesDir, source)}`)
|
||||
return
|
||||
}
|
||||
|
||||
await $`mkdir -p ${targetBinDir}`
|
||||
await $`cp ${source} ${targetBinPath}`
|
||||
chmodSync(targetBinPath, 0o755)
|
||||
|
||||
const elapsed = ((performance.now() - start) / 1000).toFixed(1)
|
||||
log(`Binary updated (${elapsed}s): ${relative(packagesDir, source)} -> bin/kilo`)
|
||||
} catch (err) {
|
||||
log(`ERROR: ${err instanceof Error ? err.message : String(err)}`)
|
||||
} finally {
|
||||
building = false
|
||||
if (pending) rebuild()
|
||||
}
|
||||
}
|
||||
|
||||
// Initial build
|
||||
await rebuild()
|
||||
|
||||
// Watch for changes
|
||||
log(`Watching ${relative(kiloVscodeDir, opencodeSrcDir)}/ for changes...`)
|
||||
|
||||
const debounce = 500
|
||||
let timer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
watch(opencodeSrcDir, { recursive: true }, (_event, filename) => {
|
||||
if (!filename) return
|
||||
// Skip non-source files and build-generated files
|
||||
if (filename.endsWith(".test.ts") || filename.endsWith(".test.tsx")) return
|
||||
if (filename.includes("models-snapshot")) return
|
||||
|
||||
if (timer) clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
log(`Change detected: ${filename}`)
|
||||
rebuild()
|
||||
}, debounce)
|
||||
})
|
||||
|
||||
log("CLI watcher running. Press Ctrl+C to stop.")
|
||||
Reference in New Issue
Block a user