Skip to content

fix(vscode): enforce unfiltered webview typechecks - #12402

Merged
chrarnoldus merged 9 commits into
mainfrom
fix/vscode-unfiltered-typecheck
Jul 21, 2026
Merged

fix(vscode): enforce unfiltered webview typechecks#12402
chrarnoldus merged 9 commits into
mainfrom
fix/vscode-unfiltered-typecheck

Conversation

@chrarnoldus

@chrarnoldus chrarnoldus commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

What changed

Run the webview TypeScript compiler directly and remove the custom wrapper that filtered diagnostics. Fix the first-party errors this exposes by:

  • declaring SVG and worker URL modules provided by the webview bundler
  • preserving the DiffPair file-input types lost when splitProps processes the discriminated union
  • registering the ambient declaration as a Knip entry

Why

The wrapper discarded every diagnostic whose path started with .., assuming those paths referred to parent node_modules. In this workspace they also identify source-exporting first-party packages such as kilo-ui and ui, so genuine compatibility errors in the webview compilation boundary were hidden.

The wrapper also inferred success from filtered output instead of propagating the compiler exit status, which could make process failures such as a missing tsc executable appear successful. Direct tsc now reports all diagnostics and exits normally on compiler failures.

The Diff adjustment is type-only: DiffProps requires before and after in the pair variant, but splitProps loses that narrowing. It does not add runtime guards or change rendering behavior.

The final PR head passes the complete CI suite, including typecheck, unit tests, and both visual-regression jobs.

@chrarnoldus chrarnoldus self-assigned this Jul 20, 2026
} else {
const oldFile = local.before
const newFile = local.after
if (!oldFile || !newFile) return

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: Silent no-op guard skips downstream render-completion work

When metadata is falsy this branch is only reachable for the DiffPair variant, where before/after are required (non-optional) at the type level -- the undefined only shows up because local merges both union members. So this guard should never actually trigger at runtime given valid props, but if it ever does (e.g. a caller bug that supplies neither fileDiff nor before/after), the effect now returns before applyScheme(), patchSeparatorLayout(), setRendered(...), and notifyRendered() run -- silently leaving the diff view in a "stuck" state (e.g. onRendered never firing) with no error surfaced. Consider a dev-time warning/invariant here instead of a bare early return, so a misuse is visible rather than manifesting as a UI that never finishes "rendering".


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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 00c5da3. The narrowing guard now throws a descriptive invariant error when fileDiff is absent without valid before/after inputs, so malformed props surface immediately instead of silently skipping render-completion work. Direct extension/webview typecheck, lint, and formatting pass.

@kilo-code-bot

kilo-code-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
packages/kilo-ui/src/components/diff.tsx 744 Non-null assertions (local.before!, local.after!) replaced the throwing invariant with no runtime guard at all, so a caller bug that supplies neither fileDiff nor before/after silently spreads an incomplete file object into instance.render(...) instead of surfacing an error
Files Reviewed (5 files changed since previous review)
  • packages/kilo-ui/src/components/diff.tsx - 1 issue (previous WARNING on the throw resolved by removing it, but the removal itself reintroduces the earlier silent-misuse risk)
  • packages/kilo-vscode/knip.json - no issues
  • packages/kilo-vscode/package.json - no issues
  • packages/kilo-vscode/script/typecheck.ts - deleted, no issues
  • packages/kilo-vscode/webview-ui/src/assets.d.ts - no issues

Fix these issues in Kilo Cloud

Previous Review Summaries (2 snapshots, latest commit 00c5da3)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 00c5da3)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
packages/kilo-ui/src/components/diff.tsx 745 The previous silent no-op guard now throws inside the render createEffect, but by then container.innerHTML has been cleared and instance reassigned, and no ErrorBoundary wraps Diff usages, so the raw throw can crash the surrounding component tree instead of failing just this diff view
Files Reviewed (1 file changed since previous review)
  • packages/kilo-ui/src/components/diff.tsx - 1 issue (previous SUGGESTION on this line resolved by the fix; new WARNING raised on the fix itself)

Fix these issues in Kilo Cloud

Previous review (commit 5cb0382)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

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

SUGGESTION

File Line Issue
packages/kilo-ui/src/components/diff.tsx 745 New early return for before/after narrowing silently skips render-completion callbacks (applyScheme, setRendered, notifyRendered) if it ever fires; type system says it shouldn't, but consider a dev-time warning instead of silent no-op
Files Reviewed (5 files)
  • packages/kilo-ui/src/components/diff.tsx - 1 issue
  • packages/kilo-vscode/knip.json - no issues
  • packages/kilo-vscode/package.json - no issues
  • packages/kilo-vscode/script/typecheck.ts (deleted) - no issues
  • packages/kilo-vscode/webview-ui/src/assets.d.ts (new) - no issues

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-5 · Input: 42 · Output: 9.2K · Cached: 935.4K

Review guidance: REVIEW.md from base branch main

} else {
const oldFile = local.before
const newFile = local.after
if (!oldFile || !newFile) throw new Error("Diff requires before and after contents when fileDiff is absent")

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: Uncaught throw inside createEffect with no ErrorBoundary

This now throws directly inside the render createEffect instead of silently no-oping. That fixes the previous silent-stuck-UI issue, but by this point in the effect container.innerHTML = "" has already run and instance/setCurrent(instance) have already been reassigned, so the throw leaves the DOM cleared with no completed render. More importantly, neither packages/kilo-ui nor the webview usages of Diff wrap this component in a SolidJS ErrorBoundary, so an uncaught error here propagates out of the reactive effect and can crash the surrounding component tree rather than failing just this diff view. Consider catching this at a boundary (or reporting via a callback prop) rather than throwing raw, or wrap Diff usages in an ErrorBoundary.


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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 39a09ff. Since this branch is only reachable for the DiffPair variant, before and after are guaranteed by DiffProps; the loss of narrowing comes from splitProps over the union. The fix now uses non-null assertions solely to restore that type information. There is no runtime guard, early return, throw, or new error-boundary requirement, and valid rendering behavior remains unchanged. Formatting and whitespace checks pass; fresh CI is running the full typecheck and test suite.

})
} else {
const oldFile = local.before!
const newFile = local.after!

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: Non-null assertions removed the last runtime guard for malformed Diff props

This replaces the throwing invariant with bare ! assertions and drops the runtime check entirely. The type-level reasoning is sound (local.fileDiff falsy + patchDiff() falsy implies the DiffPair variant, where before/after are required), but it only holds if every caller actually satisfies the discriminated union at runtime. Diff is a shared kilo-ui component consumed across the webview, so a caller bug that supplies neither fileDiff nor before/after is exactly the scenario the original SUGGESTION comment on this line called out.

With the guard gone, that misuse is no longer visible: { ...oldFile, contents, cacheKey } with oldFile undefined silently spreads to nothing (object spread of undefined doesn't throw), producing a oldFile/newFile missing required fields like path, which gets handed to instance.render(...) after container.innerHTML has already been cleared and instance reassigned. That reintroduces a stuck/broken diff view with no error surfaced anywhere — the same failure mode flagged before the throw was added, just without even a console error this time.


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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Pushing back on this one: the malformed-props behavior is unchanged from main, not introduced by this PR. The base code already executes { ...local.before, ... } / { ...local.after, ... } with no runtime guard. The final patch only assigns those same values to locals with non-null assertions before spreading them, because splitProps loses the DiffProps discriminated-union narrowing. Non-null assertions emit no JavaScript, so the runtime behavior is identical. Adding runtime validation or an error-reporting API would be a separate behavioral change outside this typecheck cleanup. The reviewed commit also passed the complete CI suite, including typecheck and both visual-regression jobs.

@chrarnoldus chrarnoldus changed the title fix(vscode): stop filtering typecheck errors fix(vscode): enforce unfiltered webview typechecks Jul 20, 2026
@chrarnoldus
chrarnoldus merged commit bcbb691 into main Jul 21, 2026
28 checks passed
@chrarnoldus
chrarnoldus deleted the fix/vscode-unfiltered-typecheck branch July 21, 2026 11:21
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…-typecheck

fix(vscode): enforce unfiltered webview typechecks
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