perf(vscode): parallelize build validation and cache SDK generation - #12807
Conversation
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.
| "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", |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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 = [ |
There was a problem hiding this comment.
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/ui — packages/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" |
There was a problem hiding this comment.
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.
Code Review SummaryStatus: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (4 files)
Assumptions
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 |
…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.
Problem
bun run extensionruns 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
tsc --noEmitwith the repository-standardtsgofor both typechecksnode_modules/.cache/eslintpackages/kilo-vscode/script/prepare-sdk.ts) keyed by CLI/API input fingerprint and generated SDK output fingerprinttsgofor the webviewExplicit
compile,package, andrebuild-sdkcommands still force full SDK regeneration, so release validation behavior is unchanged. No extension runtime code was changed.Measured Results
bun run extension, SDK cache emptybun run extension, SDK cache validValidation
bun run packagepassesbun run knipcleanbun run check-kilocode-changecleangit diff --checkclean