Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3b76248
fix(jetbrains): hide markdown separators
kirillk Jun 5, 2026
01f2886
fix(jetbrains): speed up session mouse wheel scrolling
kirillk Jun 5, 2026
cd80323
test(jetbrains): add markdown stress leak coverage
kirillk Jun 5, 2026
d1214fc
Merge remote-tracking branch 'origin/main' into tide-clipper
kirillk Jun 5, 2026
d505677
fix(jetbrains): prevent transcript scrollbar overlap
kirillk Jun 5, 2026
3411c37
Merge remote-tracking branch 'origin/main' into tide-clipper
kirillk Jun 5, 2026
256fe3a
fix(jetbrains): improve streaming reasoning display
kirillk Jun 5, 2026
cdccebe
fix(jetbrains): refine reasoning block spacing
kirillk Jun 7, 2026
9fd2251
Merge remote-tracking branch 'origin/main' into tiny-chokeberry
kirillk Jun 8, 2026
6add313
Merge remote-tracking branch 'origin/main' into tide-clipper
kirillk Jun 8, 2026
c772cc4
Merge remote-tracking branch 'origin/tiny-chokeberry' into tide-clipper
kirillk Jun 8, 2026
5736a39
feat(jetbrains): render search tools with dedicated views
kirillk Jun 8, 2026
7afccae
refactor(jetbrains): split tool view renderers
kirillk Jun 8, 2026
5518d66
feat(jetbrains): render tool output with editor bodies
kirillk Jun 8, 2026
406f92a
fix(jetbrains): left-align search tool targets
kirillk Jun 8, 2026
38c774c
fix(jetbrains): preserve scroll position on expand
kirillk Jun 8, 2026
e56e0f2
chore: remove local plan files
kirillk Jun 8, 2026
8c4c337
fix(jetbrains): show search paths relative to repo
kirillk Jun 8, 2026
1864e44
fix(jetbrains): render search targets as regular text
kirillk Jun 8, 2026
b9bff3b
fix(jetbrains): reset session card hover styling
kirillk Jun 8, 2026
952241e
fix(jetbrains): refine session card outlines
kirillk Jun 8, 2026
a0c3f4b
fix(jetbrains): align session progress footer
kirillk Jun 8, 2026
2c0b176
fix(jetbrains): tune question card spacing
kirillk Jun 8, 2026
5cf95c5
fix(jetbrains): align reasoning toggle
kirillk Jun 8, 2026
d8b4052
chore(jetbrains): add UI implementation plans
kirillk Jun 8, 2026
d1fa450
fix(jetbrains): align session view icons
kirillk Jun 9, 2026
bbe6f25
fix(jetbrains): bound streaming reasoning resources
kirillk Jun 9, 2026
3658dea
fix(jetbrains): keep completed reasoning expanded
kirillk Jun 9, 2026
b7d4f7e
style(jetbrains): compact session spacing
kirillk Jun 9, 2026
bfa719a
Merge branch 'main' into tide-clipper
kirillk Jun 9, 2026
c90846a
fix(jetbrains): preserve session scroll intent
kirillk Jun 9, 2026
5792f44
fix(jetbrains): release session UI editors in tests
kirillk Jun 9, 2026
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
5 changes: 5 additions & 0 deletions .changeset/fix-jetbrains-reasoning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Improve JetBrains reasoning blocks so active reasoning opens while streaming, completed reasoning collapses automatically, empty blocks stay hidden, and adjacent reasoning renders as one block.
5 changes: 5 additions & 0 deletions .changeset/fix-jetbrains-session-scroll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Fix JetBrains session scrolling so mouse wheel and keyboard scrolling no longer snap back or bounce near the transcript bottom.
5 changes: 5 additions & 0 deletions .changeset/gentle-canyon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Prevent the JetBrains session scrollbar from covering transcript content.
5 changes: 5 additions & 0 deletions .changeset/glob-jetbrains-view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Render glob search results in the JetBrains chat as collapsible tool output with separate directory and pattern rows.
5 changes: 5 additions & 0 deletions .changeset/jetbrains-session-icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Use matching VS Code-style icons for JetBrains session views.
5 changes: 5 additions & 0 deletions .changeset/quiet-jetbrains-separators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Hide thematic separator lines in JetBrains chat markdown while preserving surrounding prose and code blocks.
5 changes: 5 additions & 0 deletions .changeset/refine-jetbrains-card-borders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Refine JetBrains session card borders so prompt and question surfaces use brighter outlines while reasoning and tool cards use softer default borders.
5 changes: 5 additions & 0 deletions .changeset/relative-jetbrains-search-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Display JetBrains search tool paths relative to the current repository when possible.
5 changes: 5 additions & 0 deletions .changeset/reset-jetbrains-session-hover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Reset stale hover styling when moving between JetBrains session cards and draw card outlines only while expanded.
5 changes: 5 additions & 0 deletions .changeset/search-jetbrains-view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Render grep searches in the JetBrains chat with a dedicated search header that shows stacked, clipped targets.
5 changes: 5 additions & 0 deletions .changeset/stellar-wolf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Improve mouse wheel scrolling speed in the JetBrains session view.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ tsconfig.tsbuildinfo
.kilo/bun.lock
.kilo/yarn.lock
.kilo/node_modules
.kilo/plans/
.kilo/plans/*upstream-merge-report-*.md
.kilocode/.gitignore
.kilocode/package.json
Expand Down
16 changes: 16 additions & 0 deletions packages/kilo-jetbrains/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,22 @@ Tests for retained Swing components should assert:
- `update(model)` changes existing labels/body text without duplicating components.
- Updates while collapsed do not eagerly create lazy bodies.
- No-op updates, empty deltas, repeated hover values, and toggling non-expandable cards do not repaint/revalidate the whole view.
- Streaming/rebuilding surfaces additionally require stress + leak tests (see below).

### Stress and Leak Tests for Streaming UI

Session/transcript UI that streams updates or rebuilds its component tree (markdown
views, code blocks, transcript parts, collapsible cards) must ship stress + leak tests in
addition to behavior tests. These tests must:

- Drive many updates (hundreds of streamed deltas or `set` cycles) through the public API.
- Assert that retained component instances stay identical across updates (`assertSame`).
- Assert the component count stays bounded — no growth per update.
- Assert disposable-backed resources return to baseline after churn + clear/dispose.
For code editors, compare `EditorFactory.getInstance().allEditors.size` against a
baseline captured before the loop.

See `MdViewHybridStressTest` for the reference pattern.

### Platform Components and Utilities

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,18 @@ class SessionUi(
dismiss = { controller.dismissLoginRequired() },
selection = selection,
)
messageBody = SessionMessageListPanel(controller.model, this, question, permission, login, ::openFile, ::openUrl, selection)
messageBody = SessionMessageListPanel(
controller.model,
this,
question,
permission,
login,
::openFile,
::openUrl,
selection,
repo = workspace.directory,
resize = { anchor, fn -> scroll.preserve(anchor, fn) },
)
header = SessionHeaderPanel(controller, this)

scroll = SessionScroll(root, sessionContent, messageBody, blankBody)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ internal class SessionScroll(
private var opening = false
private var stable = -1
private var seq = 0
private var pause = false
private var user = false
private var value = 0
private var question = false
private var restoring = false

init {
jump = JBLabel(ScrollButtonIcon.create()).apply {
Expand All @@ -73,7 +73,6 @@ internal class SessionScroll(
user = true
}
})
component.viewport.addChangeListener { onViewport() }
component.verticalScrollBar.addAdjustmentListener { onScroll() }
root.addOverlay(jump) { _, child ->
val size = child.preferredSize
Expand All @@ -98,11 +97,10 @@ internal class SessionScroll(

@RequiresEdt
fun atBottom(): Boolean {
val bar = component.verticalScrollBar
return when {
component.viewport.view !== messages -> tail
bar.maximum <= bar.visibleAmount -> true
else -> bar.value + bar.visibleAmount >= bar.maximum - JBUI.scale(THRESHOLD)
!tail -> false
else -> near()
}
}

Expand All @@ -114,6 +112,7 @@ internal class SessionScroll(
return
}
user = false
pause = false
tail = true
stable = -1
auto = true
Expand All @@ -139,11 +138,44 @@ internal class SessionScroll(
return component.viewport.view === messages && tail
}

@RequiresEdt
fun preserve(anchor: JComponent, action: () -> Unit) {
if (component.viewport.view !== messages) {
action()
return
}
val pos = SwingUtilities.convertPoint(anchor, Point(0, 0), messages)
val delta = pos.y - component.viewport.viewPosition.y
seq++
stable = -1
user = false
pause = false
auto = true
try {
action()
layoutScroll()
val next = SwingUtilities.convertPoint(anchor, Point(0, 0), messages)
val y = (next.y - delta).coerceIn(0, bottom())
component.viewport.viewPosition = Point(0, y)
bar.value = y
} finally {
auto = false
}
tail = atBottom()
syncValue()
updateJump()
if (tail) {
stable = -1
seq++
}
}

@RequiresEdt
fun openBottom(done: () -> Unit) {
opening = true
stable = -1
user = false
pause = false
tail = true
auto = true
show(messages)
Expand All @@ -169,8 +201,8 @@ internal class SessionScroll(
@RequiresEdt
fun applyStyle(style: SessionEditorStyle) {
this.style = style
component.background = SessionUiStyle.View.transcript()
component.viewport.background = SessionUiStyle.View.transcript()
component.background = SessionUiStyle.Transcript.bgColor()
component.viewport.background = SessionUiStyle.Transcript.bgColor()
syncIcon()
messages.applyStyle(style)
val view = component.viewport.view
Expand All @@ -189,6 +221,7 @@ internal class SessionScroll(
opening = false
stable = -1
user = false
pause = false
tail = true
auto = true
show(messages)
Expand Down Expand Up @@ -272,48 +305,61 @@ internal class SessionScroll(
}

@RequiresEdt
private fun onViewport() {
if (restoring || auto || opening || user || tail || component.viewport.view !== messages) return
val y = value.coerceIn(0, bottom())
if (component.viewport.viewPosition.y == y && bar.value == y) return
restoring = true
try {
component.viewport.viewPosition = Point(0, y)
bar.value = y
} finally {
restoring = false
}
updateJump()
private fun bottom(): Int {
val bar = component.verticalScrollBar
return (bar.maximum - bar.visibleAmount).coerceAtLeast(bar.minimum)
}

@RequiresEdt
private fun bottom(): Int {
private fun near(): Boolean {
val bar = component.verticalScrollBar
return (bar.maximum - bar.visibleAmount).coerceAtLeast(bar.minimum)
return bar.maximum <= bar.visibleAmount || bar.value + bar.visibleAmount >= bar.maximum - JBUI.scale(THRESHOLD)
}

@RequiresEdt
private fun onScroll() {
val prev = value
val moved = bar.value != value
val down = bar.value > value
syncValue()
if (auto || opening) {
updateJump()
return
}
if (component.viewport.view === messages) {
val bottom = atBottom()
val bottom = near()
if (bottom) {
tail = true
if (user && moved && !down) {
tail = false
pause = true
} else if (!tail && !user) {
if (moved) {
auto = true
try {
bar.value = prev.coerceIn(bar.minimum, bottom())
} finally {
auto = false
}
syncValue()
}
tail = false
} else if (pause && !user) {
tail = false
} else {
tail = true
pause = false
}
user = false
updateJump()
return
}
if (tail && (!user || !moved)) {
if (tail && !user && !moved) {
user = false
followBottom(true)
return
}
tail = false
pause = false
user = false
seq++
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class ConnectionPanel(
// Keep the banner solid so expanded details cover transcript content beneath it.
isOpaque = true
background = UiStyle.Colors.bg()
border = JBUI.Borders.customLine(SessionUiStyle.View.line(), 1, 0, 0, 0)
border = JBUI.Borders.customLine(SessionUiStyle.View.Outline.color(), SessionUiStyle.View.Outline.width(), 0, 0, 0)
left.add(toggle, BorderLayout.WEST)
left.add(label, BorderLayout.CENTER)
header.add(left, BorderLayout.CENTER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import ai.kilocode.client.session.model.SessionModelEvent
import ai.kilocode.client.session.model.SessionState
import ai.kilocode.client.session.ui.style.SessionEditorStyle
import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget
import ai.kilocode.client.session.ui.style.SessionUiStyle
import ai.kilocode.client.ui.UiStyle
import ai.kilocode.client.ui.layout.Stack
import ai.kilocode.client.ui.layout.StackAxis
import com.intellij.openapi.Disposable
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.components.JBLabel
import com.intellij.util.ui.JBUI

/**
* Progress footer rendered at the bottom of the session transcript while the
Expand All @@ -35,6 +37,12 @@ class ProgressPanel(
init {
isOpaque = false
isVisible = false
border = JBUI.Borders.empty(
UiStyle.Gap.sm(),
JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING),
0,
0,
)
applyStyle(SessionEditorStyle.current())

next(JBLabel(AnimatedIcon.Default()))
Expand Down
Loading
Loading