Commit Graph
122 Commits
Author SHA1 Message Date
Alex Alecu 12c2d86c84 feat(cli): show open PR for current branch in sidebar 2026-04-23 16:46:22 +03:00
Marius 00ec003c11 perf(streaming): four fixes that unfreeze long-session streaming (#9341)
* perf(vscode): stop O(N) reactive cascade on every streaming token

The webview DataBridge wrapped the whole session Data shape in a
`createMemo`, whose body walked `store.parts[msg.id]` for every message
in the session family. Any single part mutation — i.e. every token
delta — invalidated the memo, produced a fresh POJO, and invalidated
every downstream consumer (including O(N) scans inside each mounted
SessionTurn). On a 200-message session a Chrome CPU profile showed
three back-to-back 440ms main-thread blocks per SSE batch, ~46% of
the time in Solid reactive runtime alone.

Expose `data` as a plain object with reactive getters over
`session.allMessages`/`allParts`/`allStatusMap` so consumers reading
`data.store.part[Y]` subscribe to only that key. Removes the now-unused
`familyData` helper and its interface/mock entries.

* perf(ui): drop TextShimmer JS timer — CSS-only animation

A createEffect inside TextShimmer ran clearTimeout + setTimeout on every
`active` prop change to gate the sweep animation via a `data-run`
attribute. During LLM token streaming in long sessions, `active` props
(bound to `pending()` / `running()` accessors) thrashed as tools
started/finished across many shimmer instances. CPU profile of a 7s
streaming window showed ~2,500 timer operations — 16% of the blocked
main-thread time.

Remove the effect and drive the animation purely from the `data-active`
attribute. The opacity transition on the shimmer char (220ms) already
handles the fade, so visual behavior is unchanged. Adds one static
regression guard and one runtime perf assertion (with happy-dom) that
toggling the prop 1000 times results in zero timer calls.

* perf(kilo-ui): skip layout reads in GrowBox watch-mode ResizeObserver

The GrowBox component wraps each assistant part and, when watch=true
(which is set on the currently-streaming text part), runs a
ResizeObserver that called body.getBoundingClientRect() via
targetHeight() on every body-size change. During streaming this fires
at ~60Hz and each call forces a synchronous layout. CPU profile of a
7s streaming window showed 1,362 gBCR samples (~9% of blocked
main-thread time) all attributable to this path.

Reuse the browser's pre-measured contentBoxSize / contentRect from the
observer entries — no extra layout read. Also skip sub-pixel updates
(<2px) that the spring absorbs imperceptibly anyway, cutting per-token
spring work when tokens add tiny height deltas.

* perf(ui): coalesce markdown parse to one per animation frame

During LLM token streaming, the Markdown render effect ran
temp.innerHTML = content + morphdom on every content update. SSE
tokens arrive at 60–200Hz and each delta reparsed the entire
accumulated HTML. CPU profile of a 7s streaming window showed 2,940
ParseHTML events totaling ~619ms (~46% of blocked main-thread time).

Queue the latest content in a component-scoped pending variable and
run the morphdom pass inside requestAnimationFrame. K rapid updates
before the frame fires now collapse to one parse. The onCleanup
handler cancels any queued frame so it doesn't touch an unmounted
DOM. Fast-path is preserved untouched so non-streaming first paint
stays synchronous.

* chore(changeset): consolidate streaming-perf changesets into one

Per-commit changesets produced four nearly-identical release-note
entries. The user-visible change is a single perceptual improvement —
streaming is smooth in long sessions — so roll them up into one
feature-oriented entry.

* test(vscode): consolidate streaming perf tests + wire into CI

Replace three synthetic reactivity tests with a single end-to-end
streaming perf benchmark that:
- Renders the real TextShimmer component and asserts zero setTimeout/
  clearTimeout calls during a 100-toggle burst (TextShimmer fix).
- Asserts per-key Solid reactivity: 100 text deltas on one message
  must re-run only that message's consumer, not O(N) consumers
  (DataBridge cascade fix).
- Uses only count-based assertions against deterministic APIs
  (setTimeout/clearTimeout/innerHTML setter) — no wall-clock
  thresholds, so it doesn't flake under CI load.

Also wire `bun run test:webview-reactivity` into the test-vscode
workflow so the benchmark runs on every PR that touches
packages/kilo-vscode, packages/ui, or packages/kilo-ui. Without this
wiring the perf regression guard would have shipped dormant.

* test(vscode): declare @happy-dom/global-registrator as devDep

The streaming-perf benchmark imports @happy-dom/global-registrator to
get a DOM for mounting the real TextShimmer component. It resolved
locally through workspace hoisting but CI's clean install didn't have
it. Make the dependency explicit.

* test(vscode): import TextShimmer via package export so JSX resolves

Using the deep relative path (../../../ui/src/components/text-shimmer)
made Bun's test transpiler apply kilo-vscode's tsconfig — which has no
`jsxImportSource` — so the .tsx file was compiled with the default
React runtime, producing "React is not defined" in CI.

Resolving through the package export (@opencode-ai/ui/text-shimmer)
picks up packages/ui/tsconfig.json which sets
`jsxImportSource: solid-js`. Works consistently across Linux/macOS/
Windows CI without needing bunfig-level JSX overrides.

* test(vscode): address bot review — add runtime coverage for Markdown + GrowBox, drop empty smoke test

Two kilo-code-bot findings on the streaming perf bench:

1. The 'benchmark completes quickly' smoke test timed an empty block,
   so `elapsed` was always near zero and the assertion never fired.
   Drop it — the real benchmarks below already complete in ~90ms.

2. The original file installed spy counters for innerHTML writes and
   getBoundingClientRect but never asserted against them, leaving
   Markdown rAF coalescing and GrowBox layout-read regressions silently
   uncaught.

Add two runtime mirrors:
- Markdown rAF pattern: 100 async content updates coalesce to <20 parses
  (would be exactly 100 pre-fix).
- GrowBox ResizeObserver pattern: 100 synthetic resize callbacks using
  contentBoxSize/contentRect trigger zero getBoundingClientRect calls
  (would be exactly 100 pre-fix).

Source-level regression guards in tests/unit/markdown-raf-coalesce.test.ts
and tests/unit/growbox-no-layout-thrash.test.ts cover the actual
component code. The runtime tests here prove the patterns the guards
require actually deliver the perf property at runtime.

Benchmark runs in ~90ms, 5 consecutive local runs all green.

* test(vscode): drop unstable TextShimmer runtime mount from streaming perf bench

The benchmark tried to mount the real @opencode-ai/ui TextShimmer to
assert zero setTimeout/clearTimeout calls. That required Bun's test
runner to transpile text-shimmer.tsx with Solid's JSX runtime, which
depends on tsconfig resolution walking up to packages/ui/tsconfig.json.
In CI (fresh workspace, different node_modules layout) this resolution
was unstable and kept falling back to React JSX ("React is not
defined").

Keep the three runtime patterns that don't need JSX transpilation
(DataBridge cascade, Markdown rAF coalescing, GrowBox contentRect),
plus the source-level regression guard at
tests/unit/textshimmer-no-timer.test.ts which asserts text-shimmer.tsx
contains no setTimeout/clearTimeout/createEffect/data-run. Together
these cover all four fixes without CI flakiness.

5 consecutive local runs pass in ~80ms.

* test(vscode): remove streaming perf tests

Static source-parsing guards and pattern-mirror runtime tests didn't
actually exercise the fixed component code — a regression in the real
code could have left them green. Remove them along with the
test:webview-reactivity script, the workflow step, the
@happy-dom/global-registrator devDep, and the tests/webview-reactivity
directory. The four perf fixes stand on their own; adding dubious
guards was worse than adding none.

* test(vscode): restore static perf-regression guards wired to real source

Restore four guards that each parse the actual fixed component source
and fail loudly if the fix pattern is removed:

- databridge-shape.test.ts     reads webview-ui/src/App.tsx, asserts
                               `data` is not wrapped in createMemo
- textshimmer-no-timer.test.ts reads ui/src/components/text-shimmer.tsx
                               + .css, asserts no setTimeout/
                               clearTimeout/createEffect, animation
                               gated on data-active
- markdown-raf-coalesce.test.ts reads ui/src/components/markdown.tsx,
                                asserts the render createEffect uses
                                requestAnimationFrame + cancelAnimationFrame
- growbox-no-layout-thrash.test.ts reads kilo-ui/src/components/grow-box.tsx,
                                   asserts the ResizeObserver callback
                                   does not call gBCR, uses contentRect/
                                   contentBoxSize, and has the sub-pixel
                                   delta guard

Verified by mutation: each guard fails when its fix pattern is removed
from the real source file and passes again once restored. Runs as part
of the existing test:unit script (no extra CI wiring).
2026-04-23 10:40:15 +02:00
Marius 48c0553bb7 feat(vscode): xterm.js terminal tabs in agent manager (#9268)
Click the chevron next to the + tab button and pick 'New Terminal' (or hit Cmd+Shift+T / Ctrl+Shift+T) to spawn a real shell inside the selected worktree or Local directory. Each terminal runs via the Kilo CLI's PTY backend, streamed over a direct loopback WebSocket so raw bytes bypass postMessage. Tabs mirror the worktree split-button pattern, support mixed drag-reorder with session tabs, and survive worktree-context switches without losing xterm state (slots are opacity-toggled in a persistent absolute-positioned layer, never unmounted). The legacy Cmd+/ integrated-terminal shortcut and console icon are preserved so existing muscle memory keeps working.
2026-04-22 16:20:40 +00:00
Alex Alecu 6f5dbe050e Merge remote-tracking branch 'origin/main' into cli-suggest-non-blocking
# Conflicts:
#	packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
2026-04-22 17:54:46 +03:00
kirillk cad39b92b3 Merge remote-tracking branch 'origin/main' into small-taleggio 2026-04-22 09:48:06 -04:00
Marian Alexandru Alecu 3bbe667c8c Merge pull request #9119 from Kilo-Org/fix/snapshot-diff-freeze
fix(cli): fix hanging sessions on huge-file diffs
2026-04-22 16:29:03 +03:00
Marian Alexandru Alecu 740c2b4e8b Merge pull request #9344 from Kilo-Org/fix/infinite-compact
fix(cli): cap per-turn compaction attempts
2026-04-22 16:10:11 +03:00
Kirill Kalishev d147f782f7 Merge pull request #9335 from Kilo-Org/productive-move
fix(vscode): restore explicit submit for question dock
2026-04-22 08:59:24 -04:00
Alex Alecu cdd5dc095d Merge remote-tracking branch 'origin/main' into cli-suggest-non-blocking 2026-04-22 15:25:33 +03:00
kilo-maintainer[bot] 475f836904 release: v7.2.19 2026-04-22 11:42:59 +00:00
Alex Alecu 40cb8889fe tui(cli): redesign inline suggest bar to match VS Code single-row layout
Replaces the number-prefixed question-picker block with a full-width tinted
row: icon + suggestion text on the left, clickable action buttons on the
right. Removes keyboard shortcuts and the esc-dismiss hint -- dismissal
already happens automatically server-side when the user sends a new prompt.
2026-04-22 14:24:56 +03:00
kilo-maintainer[bot] fe76dffa50 release: v7.2.18 2026-04-22 10:51:47 +00:00
Mark IJbema 45b9923fc9 Merge pull request #9319 from Kilo-Org/mark/fix-fim-upstream-timeout
fix(gateway): timeout autocomplete fim streams
2026-04-22 12:10:21 +02:00
Alex Alecu 8d06a083bc tui(cli): render non-blocking suggestions inline in the conversation
Moves the 'Run review?' suggestion picker out of the footer bar above the
prompt and into the conversation itself, at the position of the suggest
tool call. Frees up vertical space for reading while scrolling and
matches where the VS Code extension shows the same picker. Clicking an
option still accepts, digit keys 1/2 fast-accept when the prompt isn't
focused, and Esc dismisses. Blocking suggestions keep the above-prompt
overlay.
2026-04-22 09:59:02 +03:00
Alex Alecu c032fc2021 fix(cli): cap per-turn compaction attempts to stop infinite busy loop
When every compaction round still overflowed the model context, SessionPrompt.runLoop would keep calling compaction forever and report the turn as completed. Cap attempts at three per turn and surface exhaustion as a ContextOverflowError on the assistant message with TurnClose reason=error.
2026-04-22 09:54:11 +03:00
kirillk 85c578ed84 feat(jetbrains): improve session logging and sandbox diagnostics 2026-04-21 15:51:06 -04:00
kirillk 6015ac6e7d fix(vscode): restore explicit submit for question dock 2026-04-21 14:49:58 -04:00
Marian Alexandru Alecu ed665ed960 Merge pull request #9300 from Kilo-Org/fix/plan-in-agent-manager
fix(agent-manager): start-new-session tab on slow handover
2026-04-21 17:38:47 +03:00
kilo-maintainer[bot] ba98c5c402 release: v7.2.17 2026-04-21 14:28:13 +00:00
Mark IJbema 5bc0a4ad92 Merge branch 'main' into mark/fix-fim-upstream-timeout 2026-04-21 16:00:41 +02:00
Mark IJbema 230eceb9bc Merge pull request #9316 from Kilo-Org/mark/fix-autocomplete-ignore-cache
fix(vscode): bound autocomplete ignore cache
2026-04-21 14:31:40 +02:00
Mark IJbema b4dfbfcb75 Merge pull request #9318 from Kilo-Org/mark/fix-autocomplete-debounce-promise-leak
fix(vscode): settle canceled autocomplete debounce
2026-04-21 14:21:49 +02:00
Mark IJbema 06c5dc0a9c Merge pull request #9305 from Kilo-Org/mark/autocomplete-backend-prewarm
fix(vscode): prewarm autocomplete backend
2026-04-21 14:07:23 +02:00
kiloconnect[bot] bf98bbe34d fix(vscode): bound autocomplete ignore cache 2026-04-21 11:58:23 +00:00
Alex Alecu b6b6802dd4 fix(cli): keep follow-up session busy during handover
Mark new plan follow-up sessions busy as soon as the tab opens so the UI
shows work is still in progress while the handover summary is generated.
Clear the temporary busy state if that pre-loop handover phase is aborted
or fails before the normal prompt loop takes over.
2026-04-21 14:46:06 +03:00
Alex Alecu c5a83b3cc9 fix(cli): align non-blocking suggest picker behavior
Remove the synthetic Dismiss row and let Esc dismiss suggestions so the picker matches its visible controls while the main input stays active.
2026-04-21 14:43:26 +03:00
Alex Alecu e696fe6ea4 fix(cli): inject plan message immediately, append handover in-place
Show the plan text right away in the new session tab without waiting
for the handover LLM call. The message part is created with plan+todos
as soon as the session opens; the handover section is upserted onto the
same part once the slow LLM call resolves.
2026-04-21 13:28:48 +03:00
kiloconnect[bot] b4cb8c3c04 chore: add changeset for autocomplete backend prewarm 2026-04-21 10:19:03 +00:00
kiloconnect[bot] 3b73cf474e fix(gateway): timeout autocomplete fim streams 2026-04-21 09:44:42 +00:00
kiloconnect[bot] bfe44822ed fix(vscode): settle canceled autocomplete debounce 2026-04-21 09:33:18 +00:00
kiloconnect[bot] 79a4f37627 Merge remote-tracking branch 'origin/main' into fix/custom-provider-variant-validation 2026-04-21 08:52:45 +00:00
Alex Alecu 0d0dabe598 fix(cli): start-new-session tab on slow plan handover
Create the follow-up session before running the handover LLM call so
the extension's pendingFollowup SSE gate fires inside its 30s TTL. The
handover and todos are now injected into the already-live session
after it resolves, instead of blocking session creation.
2026-04-21 11:50:13 +03:00
Alex Alecu 2ba203b6bd fix(cli): render suggest above an active input prompt
Emit suggestions as non-blocking so the main CLI input stays focused and submittable while the picker is visible, matching the VS Code extension. Submitting a new message auto-dismisses the pending suggestion.
2026-04-21 11:24:13 +03:00
Alex Alecu 94e8c788e0 core: stop TUI freeze when viewing diffs of huge files
Files over a few thousand lines no longer hang the session for minutes during
summary generation or file view. Diffs for files of any size now render with
full content in the TUI, VS Code sidebar, and web UI — previously they either
froze the event loop or were reported with empty patch text.
2026-04-21 11:24:05 +03:00
Christiaan Arnoldus f0bc029662 Merge branch 'main' into bash-optional-description 2026-04-21 10:00:07 +02:00
Marian Alexandru Alecu e2e89aeb8a Merge branch 'main' into fix/snapshot-diff-freeze 2026-04-21 09:58:18 +03:00
Marian Alexandru Alecu 60a1f3c36d Merge pull request #9246 from Kilo-Org/fix/plan-followup-translations
feat(i18n): translate plan follow-up options
2026-04-21 09:57:23 +03:00
kiloconnect[bot] e6310c5292 fix(cli): add alibaba to kiloProviderOptions thinking translation 2026-04-20 19:19:42 +00:00
kiloconnect[bot] e7ac4d5512 Merge remote-tracking branch 'origin/main' into bash-optional-description
# Conflicts:
#	packages/opencode/src/tool/bash.ts
2026-04-20 15:30:04 +00:00
Alex Alecu 00ad8f9c87 Merge remote-tracking branch 'origin/main' into fix/plan-followup-translations
# Conflicts:
#	packages/kilo-vscode/tests/unit/question-dock-utils.test.ts
#	packages/kilo-vscode/webview-ui/src/components/chat/QuestionDock.tsx
#	packages/kilo-vscode/webview-ui/src/components/chat/question-dock-utils.ts
#	packages/opencode/src/kilocode/plan-followup.ts
#	packages/opencode/test/kilocode/plan-followup.test.ts
2026-04-20 18:09:05 +03:00
kiloconnect[bot] 34e16b3622 Merge remote-tracking branch 'origin/main' into add-alibaba-provider 2026-04-20 15:02:20 +00:00
Christiaan Arnoldus 8d49b48d79 Merge branch 'main' into fix/custom-provider-variant-validation 2026-04-20 16:57:02 +02:00
Alex Alecu ec5ac2e19f fix(vscode,cli): make plan_exit "Continue here" work again
Restore custom: false on the plan follow-up question — the "Type your own answer" row was redundant because the main prompt already routes typed text as a question reply. Auto-submit single-question single-select option picks in the VS Code QuestionDock so the button behaves like the TUI instead of silently waiting for a second Submit click.
2026-04-20 17:16:48 +03:00
Marius 18442f695d feat(vscode): support sidebar message forks (#9244)
* feat(vscode): support sidebar message forks

* fix(vscode): type sidebar fork message
2026-04-20 13:54:28 +00:00
Alex Alecu c529142d72 feat(i18n): translate plan_exit follow-up options in the VS Code sidebar
Add optional `labelKey`/`descriptionKey` to Question.Option and `questionKey`/`headerKey` to Question.Info, annotated with `kilocode_change` markers. Populate these keys from the plan follow-up so the "Ready to implement?" question, "Start new session", and "Continue here" buttons render in the sidebar language while the canonical English labels remain on the reply wire (unchanged server-side matching).
2026-04-20 16:15:06 +03:00
kiloconnect[bot] 6c0439b000 chore: add changeset for variant validation fix 2026-04-20 13:14:26 +00:00
Mariusandgithub-actions[bot] 2b17a7b4e8 fix: persist custom provider model and variant deletions (#9239)
* fix: persist custom provider model and variant deletions

The CLI config.update endpoint deep-merges its payload with existing
global config, so removing a model or reasoning variant from a custom
provider in the UI had no effect on disk. Save payloads now emit null
sentinels for removed IDs, and the Provider schema accepts nullable
record values so stripNulls can delete them during the merge.

Closes #9186

* chore: update kilo-vscode visual regression baselines

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-20 13:05:49 +00:00
Marius 6f17bb753b fix(vscode,ui): keep user scroll position while session is busy (#9236)
* fix(vscode,ui): keep user scroll position while session is busy

Virtua's measurement-driven resize events race ahead of the debounced
user-scroll detection in createAutoScroll, snapping the viewport back
to the bottom while the user is mid-gesture. The QuestionDock's focus
call on mount also triggers the browser's focus-into-view behavior,
which yanks the view down whenever the user has scrolled up.

Fixes #9198

* fix(ui): guard recentlyInteracted against initial lastInteraction=0
2026-04-20 14:58:12 +02:00
Alex Alecu eca1cc7d42 Merge remote-tracking branch 'origin/main' into fix/snapshot-diff-freeze
# Conflicts:
#	packages/opencode/src/snapshot/index.ts
2026-04-20 15:56:07 +03:00
Mariusandgithub-actions[bot] 4d85c23268 Add message-level Agent Manager session forks (#9207)
* feat(agent-manager): fork sessions from user messages

* fix(agent-manager): handle unassigned message forks

* test(vscode): register chat tool overrides

* fix(vscode): make tool overrides idempotent

* chore: update kilo-vscode visual regression baselines

* test(vscode): revert chat story override registration

* chore: update kilo-vscode visual regression baselines

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-20 14:48:55 +02:00