mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
fix(jetbrains): resolve Bun path for repo CLI generation under IDE Gradle runs
IDE-launched Gradle runs (e.g. Run IDE Split Mode) can have a stripped PATH where 'bun' isn't resolvable, so :backend:generateOpenApiSpec and :backend:buildRepoCli failed with 'A problem occurred starting process command bun' in repo-CLI (unpinned) mode. The jetbrains-cli-pin skill's unpin/regen commands now write an ignored, worktree-local Bun path hint (.gradle/kilo-cli-pin.properties) that backend/build.gradle.kts resolves and passes as an absolute path to the affected tasks. pin removes the hint since pinned mode doesn't depend on local Bun.
This commit is contained in:
@@ -34,9 +34,9 @@ bun .kilo/skills/jetbrains-cli-pin/script/cli-pin.ts <command> [--no-verify]
|
||||
|
||||
| Command | Steps |
|
||||
|---|---|
|
||||
| `pin` | Clean -> set `kilo.cli.pinned=true` -> bump `package.json` to latest release (via `set-pin.ts --latest`, which validates release assets) -> verify with a cold `gradlew clean typecheck`. |
|
||||
| `unpin` | Clean -> set `kilo.cli.pinned=false` -> `:backend:buildRepoCli` (fresh CLI) -> `:backend:stageRepoCli` -> assert staged `kilo-cli.zip` -> verify with `gradlew typecheck`. |
|
||||
| `regen` | Fast dev loop while unpinned: `rm -rf dist` -> `buildRepoCli` -> `stageRepoCli`. Refuses to run unless `kilo.cli.pinned=false`. |
|
||||
| `pin` | Clean -> set `kilo.cli.pinned=true` -> remove the repo-CLI Bun path hint -> bump `package.json` to latest release (via `set-pin.ts --latest`, which validates release assets) -> verify with a cold `gradlew clean typecheck`. |
|
||||
| `unpin` | Clean -> set `kilo.cli.pinned=false` -> write the repo-CLI Bun path hint -> `:backend:buildRepoCli` (fresh CLI) -> `:backend:stageRepoCli` -> assert staged `kilo-cli.zip` -> verify with `gradlew typecheck`. |
|
||||
| `regen` | Fast dev loop while unpinned: refresh the repo-CLI Bun path hint -> `rm -rf dist` -> `buildRepoCli` -> `stageRepoCli`. Refuses to run unless `kilo.cli.pinned=false`. |
|
||||
| `clean` | Run the shared artifact clean only. |
|
||||
|
||||
`--no-verify` skips the gradle verification build (rewrites + clean only). Use it when
|
||||
@@ -60,6 +60,19 @@ The staged `kilo-cli.zip` is the nastiest leak: once it lands in `backend/build/
|
||||
from an unpinned build, runtime prefers the bundled zip over downloading. A full clean is
|
||||
the only reliable reset.
|
||||
|
||||
## Bun Path Hint
|
||||
|
||||
In repo CLI mode, Gradle's `generateOpenApiSpec` task runs the local CLI source through
|
||||
`bun run --conditions=browser ./src/index.ts generate`. IDE-launched Gradle runs can have
|
||||
worktree-local hint:
|
||||
|
||||
```text
|
||||
packages/kilo-jetbrains/.gradle/kilo-cli-pin.properties
|
||||
```
|
||||
|
||||
The file contains `bun.path=<absolute path>` and is consumed by `backend/build.gradle.kts`
|
||||
for repo CLI tasks. `pin` removes it because pinned mode should not depend on local Bun.
|
||||
|
||||
## Notes
|
||||
|
||||
- Verification builds pass `--no-configuration-cache` so the changed `kilo.cli.pinned`
|
||||
|
||||
@@ -8,6 +8,7 @@ const jb = "packages/kilo-jetbrains"
|
||||
const props = `${jb}/gradle.properties`
|
||||
const pkg = `${jb}/package.json`
|
||||
const zip = `${jb}/backend/build/generated/kilo-cli-res/kilo-cli.zip`
|
||||
const hint = `${jb}/.gradle/kilo-cli-pin.properties`
|
||||
|
||||
const arg = Bun.argv[2]
|
||||
const cmd = arg && !arg.startsWith("-") ? arg : undefined
|
||||
@@ -52,6 +53,23 @@ async function setPinned(value: boolean) {
|
||||
await Bun.write(props, text.replace(/^kilo\.cli\.pinned=.*$/m, `kilo.cli.pinned=${value}`))
|
||||
}
|
||||
|
||||
async function bunPath() {
|
||||
const result = await $`command -v bun`.quiet().nothrow()
|
||||
const bin = result.exitCode === 0 ? result.stdout.toString().trim() : ""
|
||||
return bin || process.execPath
|
||||
}
|
||||
|
||||
async function writeBunHint() {
|
||||
const path = await bunPath()
|
||||
await $`mkdir -p ${jb}/.gradle`
|
||||
await Bun.write(hint, `# Generated by jetbrains-cli-pin so IDE-launched Gradle can find Bun in repo CLI mode.\nbun.path=${path}\n`)
|
||||
console.log(`Wrote Bun path hint for repo CLI mode: ${path}`)
|
||||
}
|
||||
|
||||
async function removeBunHint() {
|
||||
await $`rm -f ${hint}`.nothrow()
|
||||
}
|
||||
|
||||
async function report() {
|
||||
const version = (await Bun.file(pkg).json()).version
|
||||
console.log(`\nState: kilo.cli.pinned=${await pinned()}, package.json version=${version}`)
|
||||
@@ -60,6 +78,7 @@ async function report() {
|
||||
if (cmd === "pin") {
|
||||
await clean()
|
||||
await setPinned(true)
|
||||
await removeBunHint()
|
||||
// set-pin.ts bumps package.json to the latest release and refuses versions with
|
||||
// missing runtime assets, so we do not reimplement release/asset validation.
|
||||
await $`bun .kilo/skills/release-jetbrains/script/set-pin.ts --latest`
|
||||
@@ -71,6 +90,7 @@ if (cmd === "pin") {
|
||||
} else if (cmd === "unpin") {
|
||||
await clean()
|
||||
await setPinned(false)
|
||||
await writeBunHint()
|
||||
// build.ts does rm -rf dist internally, producing a fresh single-platform binary.
|
||||
await $`./gradlew :backend:buildRepoCli --no-configuration-cache`.cwd(jb)
|
||||
// stageRepoCli has upToDateWhen{false}; force it so the staged zip matches this build.
|
||||
@@ -82,6 +102,7 @@ if (cmd === "pin") {
|
||||
await report()
|
||||
} else if (cmd === "regen") {
|
||||
if (await pinned()) throw new Error("regen requires the unpinned state; run 'unpin' first")
|
||||
await writeBunHint()
|
||||
await $`rm -rf packages/opencode/dist`
|
||||
await $`./gradlew :backend:buildRepoCli --no-configuration-cache`.cwd(jb)
|
||||
await $`./gradlew :backend:stageRepoCli --no-configuration-cache`.cwd(jb)
|
||||
|
||||
@@ -26,6 +26,13 @@ val repoCli = pinned.map { !it }
|
||||
val bundled = providers.gradleProperty("kilo.cli.bundled").map { it.trim().toBoolean() }.orElse(false)
|
||||
val downloadsCli = repoCli.zip(bundled) { repo, bundle -> !repo && !bundle }
|
||||
val repoRootDir = rootProject.layout.projectDirectory.dir("../opencode")
|
||||
val local = rootProject.layout.projectDirectory.file(".gradle/kilo-cli-pin.properties")
|
||||
val bunPathProvider = providers.fileContents(local).asText.map { text ->
|
||||
text.lineSequence().firstNotNullOfOrNull { line ->
|
||||
val pair = line.split("=", limit = 2)
|
||||
if (pair.getOrNull(0)?.trim() == "bun.path") pair.getOrNull(1)?.trim()?.takeIf { it.isNotEmpty() } else null
|
||||
} ?: "bun"
|
||||
}.orElse("bun")
|
||||
|
||||
val pinnedCliVersion = providers.fileContents(rootProject.layout.projectDirectory.file("package.json")).asText.map { text ->
|
||||
Regex("\"version\"\\s*:\\s*\"([^\"]+)\"").find(text)?.groupValues?.get(1)
|
||||
@@ -64,12 +71,13 @@ val generateOpenApiSpec by tasks.registering(GenerateOpenApiSpecTask::class) {
|
||||
)
|
||||
cacheDir.set(layout.buildDirectory.dir("cli-cache"))
|
||||
spec.set(rawSpec)
|
||||
bunPath.set(bunPathProvider)
|
||||
}
|
||||
|
||||
val buildRepoCli by tasks.registering(Exec::class) {
|
||||
description = "Build the local repo CLI for the current platform"
|
||||
workingDir = repoRootDir.asFile
|
||||
commandLine("bun", "run", "script/build.ts", "--single", "--skip-install")
|
||||
commandLine(bunPathProvider.get(), "run", "script/build.ts", "--single", "--skip-install")
|
||||
}
|
||||
|
||||
fun platform(): String {
|
||||
|
||||
@@ -49,6 +49,9 @@ abstract class GenerateOpenApiSpecTask : DefaultTask() {
|
||||
@get:Internal
|
||||
abstract val cacheDir: DirectoryProperty
|
||||
|
||||
@get:Internal
|
||||
abstract val bunPath: Property<String>
|
||||
|
||||
@get:OutputFile
|
||||
abstract val spec: RegularFileProperty
|
||||
|
||||
@@ -76,7 +79,7 @@ abstract class GenerateOpenApiSpecTask : DefaultTask() {
|
||||
val err = ByteArrayOutputStream()
|
||||
val result = exec.exec {
|
||||
workingDir = root
|
||||
commandLine("bun", "run", "--conditions=browser", "./src/index.ts", "generate")
|
||||
commandLine(bunPath.get(), "run", "--conditions=browser", "./src/index.ts", "generate")
|
||||
standardOutput = out
|
||||
errorOutput = err
|
||||
isIgnoreExitValue = true
|
||||
|
||||
Reference in New Issue
Block a user