Skip to content

perf(vscode): parallelize build validation and cache SDK generation - #12807

Merged
marius-kilocode merged 1 commit into
mainfrom
profile-and-optimize-extension-build-run
Aug 3, 2026
Merged

perf(vscode): parallelize build validation and cache SDK generation#12807
marius-kilocode merged 1 commit into
mainfrom
profile-and-optimize-extension-build-run

Conversation

@marius-kilocode

Copy link
Copy Markdown
Collaborator

Problem

bun run extension runs every build step serially and regenerates the SDK on every launch. The warm build takes ~36s; with an empty SDK cache it takes ~70s. Most of that time is spent waiting for independent tasks to finish one after another.

Changes

  • Run extension typecheck, webview typecheck, ESLint, and esbuild concurrently
  • Replace tsc --noEmit with the repository-standard tsgo for both typechecks
  • Enable ESLint's content-addressed cache at node_modules/.cache/eslint
  • Run the esbuild driver with Bun instead of Node
  • Add a launch-only SDK generation cache (packages/kilo-vscode/script/prepare-sdk.ts) keyed by CLI/API input fingerprint and generated SDK output fingerprint
  • Add CSS module declarations required by tsgo for the webview

Explicit compile, package, and rebuild-sdk commands still force full SDK regeneration, so release validation behavior is unchanged. No extension runtime code was changed.

Measured Results

Scenario Before After
Warm full package build 36.43s
bun run extension, SDK cache empty 70.28s 15.66s
bun run extension, SDK cache valid 6.60-9.35s
ESLint, first cached run 7.30s 7.30s
ESLint, subsequent cached run 1.53s
SDK preparation, cache miss 9.02s 9.02s
SDK preparation, cache hit 0.14s

Validation

  • bun run package passes
  • 3,668 unit tests pass
  • bun run knip clean
  • bun run check-kilocode-change clean
  • Prettier and git diff --check clean
  • Isolated VS Code launch: Kilo sidebar renders correctly, no Kilo-related console errors

Run extension typecheck, webview typecheck, ESLint, and esbuild
concurrently instead of serially. Replace tsc with the
repository-standard tsgo for both typechecks. Enable ESLint's
content-addressed cache. Run the esbuild driver with Bun instead
of Node.

Add a launch-only SDK generation cache keyed by CLI/API input
fingerprint and generated SDK output fingerprint. Explicit compile,
package, and rebuild-sdk commands still force full SDK regeneration.

Add CSS module declarations required by tsgo for the webview.
@marius-kilocode
marius-kilocode enabled auto-merge (squash) August 3, 2026 11:41
"watch:cli": "bun script/watch-cli.ts",
"package": "bun run prepare:cli-binary && bun run rebuild-sdk && bun run typecheck && bun run lint && node esbuild.js --production",
"package": "bun run prepare:cli-binary && bun run rebuild-sdk && bun run build:check:production",
"build:check": "bun run --parallel check-types check-types:webview lint bundle",

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.

WARNING: Verify that bun run --parallel propagates a non-zero exit code when one of the parallel scripts fails

build:check, build:check:production, and typecheck are now the only gates for type and lint errors in this package (turbo typecheck in CI runs typecheck, and release validation runs package). Before this PR the && chain guaranteed that a tsc/eslint failure aborted the whole command. --parallel was previously only used for watch, where exit codes are irrelevant, so this is the first time correctness depends on it. If Bun aggregates only the last (or the first-finishing) script's status, type and lint errors will silently pass CI. Worth adding a one-off check (e.g. temporarily introduce a type error and confirm bun run typecheck exits non-zero).

Secondary point that holds regardless: with parallel execution bundle/bundle:production now writes dist/ even when check-types or lint fail, so a failed compile/package leaves behind a bundle that looks valid. script/launch.ts is safe because $ throws, but anything that inspects dist/ after a failed build (e.g. --mode vsix reruns, cached CI steps) can now pick up artifacts that never passed validation.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"check-types": "tsc --noEmit",
"check-types:webview": "tsc --noEmit --project webview-ui/tsconfig.json",
"typecheck": "bun run check-types && bun run check-types:webview",
"check-types": "tsgo --noEmit",

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.

WARNING: tsgo is invoked but @typescript/native-preview is not a dependency of this package

Every other package in the monorepo that runs tsgo declares @typescript/native-preview: "catalog:" (packages/opencode, packages/sdk/js, packages/server, packages/ui, ...). packages/kilo-vscode only declares typescript: ^5.9.3, so tsgo resolves purely through Bun's root node_modules/.bin hoisting. That works today but breaks on an isolated/package-local install or if the last root consumer of the catalog entry is removed, and the failure mode is a confusing command not found in the build gate. Suggest adding @typescript/native-preview: "catalog:" to this package's devDependencies.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

const repo = join(root, "..", "..")
const sdk = join(repo, "packages", "sdk", "js")
const cache = join(root, "node_modules", ".cache", "sdk-build.json")
const inputs = [

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.

WARNING: The hand-maintained input allowlist omits packages that are in the OpenAPI generation module graph, so the cache can silently serve a stale SDK

packages/sdk/js/script/build.ts produces the spec via bun dev generate in packages/opencode, which imports src/server/server and transitively most of the CLI. That graph includes at least packages/uipackages/opencode/src/kilocode/provider/metadata.ts:1 imports @opencode-ai/ui/icons/provider, and provider metadata feeds the generated types. packages/http-recorder, packages/script, and packages/tui are also direct workspace dependencies of packages/opencode and are absent from this list.

Because a missed input produces a cache hit, the failure is silent: bun run extension links an SDK client that doesn't match the server routes, and the developer debugs a phantom API mismatch. The list will also drift every time a new workspace package is added upstream.

Suggest making this fail-safe rather than fail-open — e.g. fingerprint packages/ as a whole and exclude only the paths that provably cannot affect generation (kilo-vscode, kilo-docs, kilo-jetbrains), or derive the set from packages/opencode/package.json's workspace:* dependencies. The cache-hit path is already 0.14s, so a slightly wider git ls-tree/git diff is cheap compared to shipping a stale client.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

export default src
}

declare module "*.css"

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: These shorthand ambient declarations resolve to any and permanently silence resolution errors for the specifiers

declare module "*.css" with no body makes every .css specifier any, and declare module "@kilocode/kilo-ui/styles" shadows whatever that subpath export actually resolves to — if kilo-ui ever exports typed values from ./styles, the webview typecheck will keep seeing any instead of the real types, with no error to reveal it.

Since these are side-effect-only imports (import "@kilocode/kilo-ui/styles" in webview-ui/src/index.tsx), a narrower fix keeps the type surface intact: either set allowArbitraryExtensions: true in webview-ui/tsconfig.json, or give the declarations a body so the shape is explicit rather than any. Also worth noting the divergence this introduces — watch:tsc, compile-tests, and watch-tests still run tsc, so watch-mode diagnostics no longer match the tsgo build gate that required these declarations.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 4 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/package.json 1202 bun run --parallel is now the only gate for type/lint errors in typecheck, compile, and package; confirm it propagates a non-zero exit code on script failure. Also, bundle now writes dist/ even when validation fails.
packages/kilo-vscode/package.json 1209 tsgo is invoked but @typescript/native-preview is not declared in this package's devDependencies; resolution relies on root hoisting, unlike every other package in the monorepo.
packages/kilo-vscode/script/prepare-sdk.ts 11 Hand-maintained input allowlist omits packages/ui (reachable from opencode/src/kilocode/provider/metadata.ts), plus packages/http-recorder, packages/script, packages/tui. A missed input yields a cache hit, silently linking a stale SDK client.

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/src/assets.d.ts 6 Shorthand ambient declarations resolve to any and permanently mask @kilocode/kilo-ui/styles types; allowArbitraryExtensions or a typed declaration body is narrower. watch:tsc/compile-tests still use tsc, diverging from the tsgo gate.
Files Reviewed (4 files)
  • packages/kilo-vscode/package.json - 2 issues
  • packages/kilo-vscode/script/prepare-sdk.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/assets.d.ts - 1 issue
  • packages/kilo-vscode/script/launch.ts - no issues
Assumptions
  • Bun's --parallel exit-code aggregation could not be verified in this environment (command execution is unavailable in read-only review mode), so it is raised as a verification request rather than a confirmed defect.
  • The generated SDK sources under packages/sdk/js/src are git-tracked, so the output fingerprint in prepare-sdk.ts does capture generated content correctly.
  • No changeset is expected: this PR changes build tooling only, with no user-facing behavior change.

Fix these issues in Kilo Cloud


Reviewed by claude-opus-5 · Input: 60 · Output: 25.2K · Cached: 1.7M

Review guidance: REVIEW.md from base branch main

@marius-kilocode
marius-kilocode merged commit 6833812 into main Aug 3, 2026
23 checks passed
@marius-kilocode
marius-kilocode deleted the profile-and-optimize-extension-build-run branch August 3, 2026 14:33
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…ilo-Org#12807)

Run extension typecheck, webview typecheck, ESLint, and esbuild
concurrently instead of serially. Replace tsc with the
repository-standard tsgo for both typechecks. Enable ESLint's
content-addressed cache. Run the esbuild driver with Bun instead
of Node.

Add a launch-only SDK generation cache keyed by CLI/API input
fingerprint and generated SDK output fingerprint. Explicit compile,
package, and rebuild-sdk commands still force full SDK regeneration.

Add CSS module declarations required by tsgo for the webview.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants