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
6 changes: 6 additions & 0 deletions .changeset/fix-darwin-cli-startup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@kilocode/cli": patch
"kilo-code": patch
---

Prevent the macOS Apple Silicon CLI from failing to start because of malformed bundled exports.
60 changes: 60 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,64 @@ jobs:
name: kilo-vscode
path: packages/kilo-vscode/out

# kilocode_change start - execute the cross-compiled Apple Silicon binary before publishing it
validate-darwin-arm64:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: The validate-darwin-arm64 job (and validate-linux below) is missing if: github.repository == 'Kilo-Org/kilocode' that every other job in this file has (version, build-cli, build-vscode, smoke-test, publish). In practice it doesn't matter since this workflow is only triggered from the main repo, but it breaks the established pattern and could cause confusion in forks.

name: Validate CLI (darwin-arm64)
needs: build-cli
runs-on: macos-15
timeout-minutes: 15
steps:
- uses: actions/download-artifact@v8
with:
name: kilo-cli.tar.zst
path: /tmp
skip-decompress: true

- name: Unpack CLI dist
run: |
mkdir -p dist
tar --zstd -xf /tmp/kilo-cli.tar.zst -C dist

- name: Run CLI smoke test
run: |
test "$(uname -m)" = "arm64"
./dist/@kilocode/cli-darwin-arm64/bin/kilo --version
# kilocode_change end

# kilocode_change start - execute native Linux x64 and arm64 binaries before publishing them
validate-linux:
name: Validate CLI (linux-${{ matrix.arch }})
needs: build-cli
strategy:
fail-fast: false
matrix:
include:
- arch: x64
runner: ubuntu-24.04
uname: x86_64
- arch: arm64
runner: ubuntu-24.04-arm
uname: aarch64
runs-on: ${{ matrix.runner }}
timeout-minutes: 15
steps:
- uses: actions/download-artifact@v8
with:
name: kilo-cli.tar.zst
path: /tmp
skip-decompress: true

- name: Unpack CLI dist
run: |
mkdir -p dist
tar --zstd -xf /tmp/kilo-cli.tar.zst -C dist

- name: Run CLI smoke test
run: |
test "$(uname -m)" = "${{ matrix.uname }}"
./dist/@kilocode/cli-linux-${{ matrix.arch }}/bin/kilo --version
# kilocode_change end

# kilocode_change start
# Run smoke tests against CLI assets uploaded to the draft GitHub release
# before publishing the release and package artifacts.
Expand All @@ -181,6 +239,8 @@ jobs:
- version
- build-cli
- build-vscode
- validate-darwin-arm64 # kilocode_change
- validate-linux # kilocode_change
- smoke-test
runs-on: ubuntu-24.04
steps:
Expand Down
27 changes: 24 additions & 3 deletions packages/opencode/script/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ const allTargets: {
},
]

// kilocode_change start - isolate target builds because repeated Bun.build calls can corrupt shared chunks
const arg = process.argv.find((item) => item.startsWith("--target="))
const value = arg?.slice("--target=".length)
const selection = value !== undefined && /^(0|[1-9]\d*)$/.test(value) ? Number(value) : -1
const isolated = selection >= 0 && selection < allTargets.length
if (arg !== undefined && !isolated) throw new Error(`Invalid isolated build target: ${arg}`)
// kilocode_change end

const targets = singleFlag
? allTargets.filter((item) => {
if (item.os !== process.platform || item.arch !== process.arch) {
Expand All @@ -213,10 +221,12 @@ const targets = singleFlag
return true
})
: allTargets
if (isolated) targets.splice(0, targets.length, allTargets[selection]!) // kilocode_change - select one target in child

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: targets is a direct reference to allTargets when singleFlag is false (line 223: : allTargets), so targets.splice(...) mutates allTargets itself. This doesn't cause a bug today — the child process exits after one build and never reaches allTargets.indexOf(item) — but it's fragile. Consider using a fresh array to avoid the alias:

if (isolated) targets.splice(0, targets.length, allTargets[selection]!)

Could be rewritten as:

const targets = isolated
  ? [allTargets[selection]!]
  : singleFlag
    ? allTargets.filter(...)
    : allTargets

or simply targets.length = 0; targets.push(allTargets[selection]!) if keeping the current structure.


await $`rm -rf dist` // kilocode_change

const kiloConsoleDist = await buildKiloConsole() // kilocode_change
// kilocode_change start - isolated children reuse the parent's prepared output tree
if (!isolated) await $`rm -rf dist`
const kiloConsoleDist = isolated ? path.resolve(dir, "../kilo-console/dist") : await buildKiloConsole()
// kilocode_change end

const binaries: Record<string, string> = {}
if (!skipInstall) {
Expand All @@ -234,6 +244,15 @@ for (const item of targets) {
]
.filter(Boolean)
.join("-")

// kilocode_change start - isolate Bun's shared-chunk state between cross-platform targets
if (!isolated && targets.length > 1) {
await $`${process.execPath} run script/build.ts --target=${allTargets.indexOf(item)} --skip-install`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: The child subprocess only receives --skip-install. Other flags like --sourcemaps and --baseline are not forwarded. For release builds this is intentional (sourcemaps are disabled via Script.release), but if someone invokes build.ts --sourcemaps on a multi-target build (non---single), the child processes will silently ignore it.

Consider forwarding extra flags explicitly or documenting that multi-target builds don't support --sourcemaps:

const extraFlags = sourcemapsFlag ? ["--sourcemaps"] : []
await $`${process.execPath} run script/build.ts --target=${allTargets.indexOf(item)} --skip-install ${extraFlags}`

binaries[name] = Script.version
continue
}
// kilocode_change end

console.log(`building ${name}`)
await $`mkdir -p dist/${name}/bin`

Expand Down Expand Up @@ -347,6 +366,8 @@ for (const item of targets) {
binaries[name] = Script.version
}

if (isolated) process.exit(0) // kilocode_change - isolated target children leave archive upload to parent

if (Script.release) {
const archives: string[] = [] // kilocode_change
for (const key of Object.keys(binaries)) {
Expand Down
Loading