chart
無料Use when the user asks to visualize data with charts, graphs, or plots using the `chart` tool (bar, line, scatter, pie, time series, etc.).
日本語の概要は準備中です。原文の説明を表示しています。
Use when working on the JetBrains chat session UI or SessionModel/SessionController — transcript cards, retained Swing lifecycle, session background surfaces, editor-derived styling, adding session events, and session/controller testing with FakeSessionRpcApi.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Detailed reference for the chat session feature in packages/kilo-jetbrains/. See packages/kilo-jetbrains/AGENTS.md for the component-model summary and reuse index; this skill covers the full architecture, background/lifecycle rules, and testing helpers.
The chat session UI intentionally uses a single-backdrop model. Do not make every
container paint SessionUiStyle.Colors.sessionBackground() just because it sits
inside the session. This avoids fragile component-hierarchy coupling and prevents
theme-specific artifacts in transparent/rounded Swing painting.
SessionRootPanel is the primary opaque backdrop. It overrides getBackground() and returns SessionUiStyle.Colors.sessionBackground().sessionBackground() follows the panel background, but when that equals the raised editor surface (codeBlockBackground()) — e.g. Islands Dark/Darcula, where panel and editor backgrounds are identical — it shifts by SESSION_DELTA via UiStyle.Colors.contrast (lighter in dark themes, darker in light) so the prompt bubble/input and other raised surfaces stay visible. This is a universal fallback, not a per-theme override.SessionRootPanel.Blocker is the only other session-background opaque panel. It also overrides getBackground() with sessionBackground() for modal blocking.applyStyle(style) must not assign session-background colors. It may update fonts, foregrounds, editor colors, and other non-background styling. Background colors that must be dynamic should come from getBackground() or custom painting.getBackground()-driven: keep an isHovered flag on the hover row/header, set or clear it from mouse enter/exit, and repaint only that row/header. Do not assign row.background or header.background on hover.SessionUiStyle.Colors.codeBlockBackground() (the editor background), using its own insets so the fill covers the whole content. For MdView-backed bodies set md.opaque = false so the prose/body stays transparent while the code/output panes remain the opaque editor surface — do not make the whole body opaque.RoundedContentPanel-based question/login cards) should do that in custom painting or a contentColor() override, not by making every nested panel opaque.DarculaButtonUI's rounded paint (notably visible in Islands Light).DialogView (question, permission, login-required, outcome, revert, onboarding cards) is a fourth documented surface: contentColor() paints SessionUiStyle.View.Dialog.bgColor() — a DIALOG_DELTA contrast shift off the backdrop — while outlined is true, so the card reads as its own panel, distinct from both the backdrop and codeBlockBackground(). Its border is Dialog.outlineColor(), the midpoint between backdrop and card fill, so the edge is a soft transition rather than the hard Outline.brightColor() line a fill-less card needs. setOutlined(false) drops back to the plain backdrop color with no outline, for chrome-free states like an interrupted-run note.When adding a new session view, start with transparent containers and add opaque
painting only for components that are actual visual surfaces. If a component's
background must react to hover/theme state, prefer an override such as
getBackground() over writing background = ... during setup or applyStyle.
Swing is retained-mode UI. For dynamic Swing surfaces such as session cards, transcript parts, hover rows, and collapsible panels, build a stable component tree once and then mutate existing components in response to model or interaction changes.
state -> render() loop for Swing components.render() methods that remove/recreate headers, text areas, markdown views, controls, or scroll panes after every click, hover, or model update.update(model) method that applies model changes directly to existing UI components.update(model), compare before assigning when practical: label text, icons, foregrounds, fonts, body text, visibility, cursor, and containment.scroll.parent === root) rather than maintaining an open boolean.hover boolean.AbstractSessionPartView, which binds click-to-toggle and hover across the whole header subtree automatically (including children added later). Do not re-bind header parts per view. A header control that must not toggle the card (file link, copy button, toolbar action) simply owns its own mouse listener and is skipped automatically.JBTextArea, JBScrollPane, markdown panes, and HTML panes on first expansion or first direct access.revalidate()/repaint() only when they changed preferred size, visibility, containment, or paint output.render() in Swing views invite full tree rebuilds. Prefer names like syncBody(), syncArrow(), syncHtml(), or applyModel().Tests for retained Swing components should assert:
isExpanded() agrees with actual containment.update(model) changes existing labels/body text without duplicating components.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:
set cycles) through the public API.assertSame).EditorFactory.getInstance().allEditors.size against a
baseline captured before the loop.See MdViewHybridStressTest for the reference pattern.
The chat session feature uses a three-layer Model / Controller / View architecture. All files live under
frontend/src/main/kotlin/ai/kilocode/client/session/.
SessionModel (model/SessionModel.kt)
SessionController guarantees all reads and writes happen on the EDT.setState, upsertMessage, setDiff, etc.), never via direct field assignment from outside the model.SessionModelEvent that carries the data needed for rendering — UI never needs to read back from the model after receiving an event.toString() with a compact, stable label (e.g. "MessageAdded msg1", "DiffUpdated files=2"). Tests assert events by comparing joined toString() output.loadHistory() and clear() reset all state fields — diff, todos, compactionCount, messages, and SessionState.Idle. Call them when opening or clearing a session.SessionController (SessionController.kt)
SessionModel. UIs read from model and subscribe to SessionModelEvent via model.addListener().id at construction.
id = null → lazily creates a new session on the first prompt() call. This guarantees events are subscribed before the prompt is sent, eliminating race conditions.id != null → immediately loads history and subscribes to SSE events on construction.recoverPending() seeds state in this priority order: (1) pending permission, (2) pending question, (3) current session status (busy/retry/offline from KiloSessionService.statuses), (4) Idle.sessionID before being handled. session.error events with null sessionID are treated as global and pass through.SessionControllerEvent to registered listeners — keep these separate from the fine-grained SessionModelEvent stream.View (UI classes under ui/)
SessionModelEvent via model.addListener(parent) { event -> when(event) { ... } }.when block must be exhaustive — add -> Unit branches for events the view intentionally ignores so new events surface as compile errors.SessionController actions (prompt(), replyPermission(), etc.) on the EDT; the controller dispatches RPC calls to a coroutine scope.SessionModelEvent with a stable toString().SessionModel. Reset the field in both loadHistory() and clear().ChatEventDto in SessionController.handle() by calling the model mutation method.-> Unit stubs for the new event in any existing exhaustive when blocks in view code.Session UI components that render text using editor fonts or colors must not read global editor settings directly on every paint. Instead they must:
SessionEditorStyleTarget (session/ui/style/SessionEditorStyle.kt).SessionEditorStyle.current().applyStyle(style: SessionEditorStyle) and update all fonts/colors in one place without rebuilding Swing nodes.SessionUi propagates a refreshed SessionEditorStyle to every registered SessionEditorStyleTarget child when the global editor scheme changes. New session elements that depend on editor settings must be registered through this flow, not through ad hoc EditorColorsManager listeners.
Anti-patterns to avoid:
SessionEditorStyle fields through constructors or method parameters when the component can implement the interface and receive updates via applyStyle.font field copied from the style) when holding the full SessionEditorStyle snapshot is cleaner.Controller tests extend SessionControllerTestBase (test/…/session/SessionControllerTestBase.kt),
which provides a real IntelliJ Application and EDT via BasePlatformTestCase, real frontend services
wired to FakeSessionRpcApi, and a set of shared helpers.
Two setups:
| Setup | When to use |
|---|---|
val (m, events, modelEvents) = prompted() | New-session flow — sets app/workspace to ready, creates a controller with no ID, sends an initial prompt. model.showMessages is true. Start all event-driven tests from here. |
controller("ses_test") + manual appRpc/projectRpc setup + flush() | Existing-session flow — opens a specific session, triggers history load and recoverPending(). model.showMessages is false. Use for recovery and history tests. Pass show = false to assertSession. |
Core assertion helpers:
// Full controller state — includes model transcript + status line.
// show=true is the default; pass show=false for existing-session tests.
assertSession("""
assistant#msg1
text#prt1:
hello
[code] [kilo/gpt-5] [idle]
""", m)
// Just the model transcript (no status line)
assertModel("diff: src/A.kt src/B.kt", m)
// Model event stream — one event per line via event.toString()
assertModelEvents("""
MessageAdded msg1
ContentAdded msg1/prt1
""", modelEvents)
// Controller lifecycle events
assertControllerEvents("WorkspaceReady", events)
Emitting events and flushing:
emit(ChatEventDto.TurnOpen("ses_test")) // emits + flushes by default
emit(ChatEventDto.PartDelta(…), flush = false) // batch without intermediate flush
flush() // settle coroutines + drain EDT
FakeSessionRpcApi configurable state:
| Field | Purpose |
|---|---|
rpc.events (MutableSharedFlow) | Emit ChatEventDto events the controller will receive |
rpc.statuses (MutableStateFlow<Map<String, SessionStatusDto>>) | Seed the status map read during recoverPending() |
rpc.history | Messages returned by messages() (history load) |
rpc.pendingPermissionList | Permissions returned during recovery |
rpc.pendingQuestionList | Questions returned during recovery |
rpc.prompts, rpc.permissionReplies, etc. | Call tracking for RPC side-effects |
String format of model.toString() (used by assertModel / assertSession):
role#msgId
text#partId:
line one
line two
---
tool#partId toolName [STATE] optional title
---
question#id
tool: msgId/callId
header: …
prompt: …
option: label - description
multiple: false
custom: true
---
diff: file1 file2
---
todo: [status] content
---
compacted: N
Sections are separated by ---. Only non-empty sections appear. The status line appended by SessionController.toString() is:
[agentName] [provider/modelId] [idle|busy|retry|offline|error|awaiting-question|awaiting-permission] [optional detail]
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when the user asks to visualize data with charts, graphs, or plots using the `chart` tool (bar, line, scatter, pie, time series, etc.).
日本語の概要は準備中です。原文の説明を表示しています。
Work with Effect v4 / effect-smol TypeScript code in this repo
日本語の概要は準備中です。原文の説明を表示しています。
Use when creating, triaging, or commenting on GitHub issues for the Kilo VS Code extension or JetBrains plugin via `gh`. Covers issue templates, project board assignment, title conventions, and required `gh` scopes.
日本語の概要は準備中です。原文の説明を表示しています。
Create or review IntelliJ New UI SVG icons, theme variants, sizes, and palette.
日本語の概要は準備中です。原文の説明を表示しています。
Create or review icons for Kilo's VS Code extension, webviews, and shared icon registry.
日本語の概要は準備中です。原文の説明を表示しています。
Use when adding or moving code across shared/frontend/backend modules in packages/kilo-jetbrains/ — split-mode RPC contracts, serialization classloader pitfall, threading/EDT annotations, services and coroutine scopes, EDT test rules, dependency bundling, and the CLI server protocol.
日本語の概要は準備中です。原文の説明を表示しています。