.kilo/plans/1787183917922-jetbrains-unsupported-workspace-banner.md
ConnectionPanel) instead of silently
showing "Loading…" forever. It gets the same recovery options as other
connection errors (Try again → Retry / Restart / Reinstall Core).RemoteDirectory.detect() returns a reason
code and KiloBackendWorkspace sets KiloWorkspaceState.Unsupported(reason),
mapped to KiloWorkspaceStateDto(status = UNSUPPORTED, error = reason)
(KiloWorkspaceRpcApiImpl.kt:507). Reason string is in the DTO error field.
Reason codes: devcontainer_virtual_filesystem, wsl_virtual_filesystem,
invalid_virtual_path.SessionModel.workspace; syncConnectionState() already runs
on every WorkspaceChanged (SessionController.kt:982-984).SessionController.resolveConnectionState() (SessionController.kt:2353-2393)
has no UNSUPPORTED branch, so it falls through to ShowConnecting
(line 2392) → banner reads "Loading…" indefinitely.ConnectionPanel (session/ui/ConnectionPanel.kt), driven
by ConnectionChanged.ShowError/ShowWarning/…. Its "Try again" link opens a
popup with Retry / Restart / Reinstall (recoveryGroup()).DETAILS_LINES = 10 (line 45). scrollHeight() coerces the
row count to 1..DETAILS_LINES (line 304), getPreferredSize() uses it
(line 295-301), and maxExpandedHeight() (line 345) exposes the fixed cap.SessionUi.kt:442-452 anchors the banner just above the
prompt using child.preferredSize.height as the banner height; bottom edge is
promptTop - gap, and it grows upward.All touched files are Kilo-owned JetBrains frontend paths — no kilocode_change
markers required. No backend / shared DTO changes needed.
ShowError path unchanged — same red
banner, same "Try again" popup (Retry / Restart / Reinstall). No new event
type and no retry flag. (Reverses the earlier "hide retry" idea per user.)ConnectionPanel so preferred height reflects
the whole detail text; clamp the rendered banner height to the transcript space
above the prompt in the overlay layout (where pane geometry is known). The
existing internal JBScrollPane (VERTICAL_SCROLLBAR_AS_NEEDED) scrolls the
overflow. This applies to every error/warning banner uniformly.SessionController.resolveConnectionState() (SessionController.kt:2353)
workspace.status == KiloWorkspaceStatusDto.UNSUPPORTED
(place it next to the workspace ERROR branch, before the READY branches):
KiloBundle.message("session.connection.unsupported")workspace.errorsource = "workspace" (retry link shows by default; no flag change)unsupported) mapping the
workspace.error reason code to a bundle string:
devcontainer_virtual_filesystem → session.connection.unsupported.devcontainerwsl_virtual_filesystem → session.connection.unsupported.wslinvalid_virtual_path → session.connection.unsupported.invalidsession.connection.unsupported.unknown (or raw reason)KiloBundle.properties (resources/messages/, after line 17)
session.connection.unsupported=Workspace not supportedsession.connection.unsupported.devcontainer=Dev Container virtual filesystem paths can't be reached by the host-side Kilo runtime.session.connection.unsupported.wsl=WSL virtual filesystem paths aren't supported by the host-side Kilo runtime.session.connection.unsupported.invalid=This workspace path can't be resolved on the local filesystem.session.connection.unsupported.unknown=This workspace isn't supported by the host-side Kilo runtime.ConnectionPanel.kt (session/ui/) — remove the fixed cap so details fit
the whole text:
DETAILS_LINES (line 45) usage in scrollHeight() (line 303-306):
compute rows from the full logical line count (coerceAtLeast(1)), no upper
bound. getPreferredSize() (line 295-301) then reports the full detail
height when expanded.maxExpandedHeight() (line 345) or repurpose it; it encodes the
10-line cap and is only used by the outgoing test.JBScrollPane policies as-is so overflow scrolls when the overlay
clamps the banner shorter than preferred.SessionUi.kt overlay layout for connection (lines 442-452) — clamp the
banner height to the transcript area above the prompt:
full = child.preferredSize.heightavail = (point.y - gap).coerceAtLeast(0) (space from pane top to just above
the prompt)h = full.coerceAtMost(avail)x = point.x + gap, y = point.y - h - gap,
width = (prompt.width - gap*2).coerceAtLeast(0), height = hpromptTop - gap (unchanged) while
preventing the top from overflowing above the transcript region; the panel's
internal scroll pane handles the remainder. Applies to every banner state.ConnectionDelayTest.kt (session/controller/): add a test mirroring
test persistent workspace error is delayed — set
projectRpc.state.value = KiloWorkspaceStateDto(status = UNSUPPORTED, error = "wsl_virtual_filesystem"),
assert a ShowError with summary "Workspace not supported", the mapped WSL
detail, and source == "workspace"; assert it no longer resolves to
ShowConnecting.ConnectionPanelTest.kt (session/ui/):
test expanded details height is capped at ten lines (lines 140-150)
with a test asserting the expanded preferred height grows with the full text
(e.g. 30 lines yields a preferred height clearly larger than the old
10-line height / a computed full-text height), i.e. no fixed cap.ShowError still shows
the retry link and uses the Core recovery group (parity with existing
test retry popup group uses core recovery actions).SessionUiLayoutTest.kt: add a test that with a large detail body and a
constrained root/pane height, the expanded banner is clamped to the transcript
area — connection.y >= 0 (does not overflow above the transcript), bottom
still anchored at promptTop - gap, detailsVisible() true, and the internal
JBScrollPane shows/needs its vertical scrollbar. Reuse the anchoring
assertions from test expanded connection panel remains anchored above prompt
(lines 261-276).From packages/kilo-jetbrains/:
./gradlew typecheck./gradlew test (or targeted: ConnectionPanelTest, ConnectionDelayTest,
SessionUiLayoutTest)Requires Java 21; only check Java if Gradle fails with a Java-version error.
UNSUPPORTED + error=reason already reach
the frontend.RemoteDirectory.kt today; the new bundle keys are
the first human-readable mapping. New reason codes fall back to unknown.session.connection.unsupported*
strings (placeholder copy above).