Repository navigation
feat(jetbrains): add Kilo Swarm board support - #14253
Conversation
Bring the JetBrains plugin to VS Code parity for Kilo Swarm, which was previously reachable only through the CLI: the board tools were already active in JetBrains sessions but rendered as raw JSON, with no toggle and no way to read the board. Wire the top-level shared_agent_board config key through the DTO and parser layers and expose it as a toggle on the Agent Behavior settings page, defaulting to on to match the CLI's BoardEnabled.resolve. Render board_post/board_read as route plus message instead of raw JSON, falling back to the generic tool card when a payload cannot be parsed. Add a board viewer reached from the session header or the session menu that pages backward, opens a participating subagent, and resets the board under a revision guard. The entry points stay hidden until the board actually holds a message, probed event-driven rather than polled, because a subagent's post lands in its own transcript and cannot be derived locally.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (2 files, incremental since `6562943`)
Verified the extraction is behavior-preserving: Previous Review Summaries (6 snapshots, latest commit 6562943)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 6562943)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (3 files, incremental since `eee5a486`)
Fix these issues in Kilo Cloud Previous review (commit eee5a48)Status: 2 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (27 files)
Fix these issues in Kilo Cloud Previous review (commit a573611)Status: No Issues Found | Recommendation: Merge Files Reviewed (1 file)
Previous review (commit d5bee8e)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (3 files)
Fix these issues in Kilo Cloud Previous review (commit fa6d784)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (7 files)
Fix these issues in Kilo Cloud Previous review (commit de6397c)Status: 6 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (60 files)
Verified against the CLI ( Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0 Review guidance: REVIEW.md from base branch |
Correct Traditional Chinese 看枕 (pillow) to 看板 (board) and the simplified 中断 to 中斷, the Japanese negative conditional なけれ to なければ, and four Korean words that were not real words. Also drop the space after the sentence-ending 。 in ja/zh_CN/zh_TW, where it is wrong typography, and tighten a Korean particle. Move the swarm avatar palette into UiStyle.Colors behind semantic named color keys so themes can override it, per the plugin UI guidance against numeric JBColor literals in runtime code, and resolve the fill at paint time so a cached icon follows a Look and Feel change. Key the avatar cache on the drawn glyph rather than the participant id. Session ids never repeat, so the old key grew the map for the life of the IDE; the glyph space is bounded and reuses entries instead.
swarmAvatarCount() had no callers; remove it rather than leave speculative API in UiStyle.Colors. Also remove BoardToolView.bodyMarkdownText(), which existed only so a test could read the body. Tests now assert through markdown(), the same API the body sync and header popup use, per the plugin rule against production methods whose only purpose is test access.
The previous revision asserted through markdown(), which re-derives from the tool part rather than reading the body view, so the assertions passed whether or not syncBody() ran and the collapse-cycle check compared a value against itself. Read the body's JBHtmlPane from the component tree instead, and compare pane identity across collapse cycles so lazy creation and reuse stay covered. Verified by temporarily stubbing syncBody(), which now fails all three tests.
… body The board stays useful while the session and its subagents keep working, so it no longer blocks the IDE. showAndGet() throws on a non-modal dialog, so the handle and caller move to show(), and the post-close board re-probe moves onto the dialog's disposable. Rename the banner toggle to Show more / Show less, and rename load_more to loadMore so the key matches the bundle's camelCase convention. Indent the board message body under the header title instead of the card edge, which is what the task card already did. Its private border helper moves to ToolSupport as toolBodyBorder so both cards share one definition rather than drifting. Drop a duplicate settings.agentBehavior.save.failed this PR had added on top of the existing shared key, restore that key's original English, and reuse the existing saving / save.failed keys instead of introducing new ones. Translate both shared keys, which were English-only, and complete the swarm settings and action strings across all 18 locales.
The board became non-modal, so it now outlives showBoard(). Nothing disposed it when the session went away, so closing the session tab left the window alive holding a disposed SessionUi, its service, and the dialog's own coroutine scope. Register the dialog's disposable on the session, which disposes the dialog and closes the window with the tab, and skip the post-close re-probe when the session is the thing going away. Also drop SessionBoardDialogHandle: nothing referenced it as a type and its documented purpose no longer held once the dialog stopped being modal.
The previous test re-created the registration from showBoard() instead of calling it, so removing the production statement left the test green. It guarded a copy of the wiring, not the wiring. Split the create-and-bind step into openBoard(), which showBoard() now delegates to, and assert disposal through that call. Verified by removing the production registration, which now fails the test.
Issue
No tracking issue exists for JetBrains Swarm support; I searched open and closed issues and found none. Raising this as an exception rather than filing a retroactive issue — happy to open one if maintainers prefer.
Context
Kilo Swarm had no JetBrains client support, but it was already partially live there. The board gate is a CLI config key, and the plugin only layers
KILO_CONFIG_CONTENTon top of global config, so anyone who enabled Swarm in VS Code already hadboard_post/board_readrunning inside JetBrains sessions — rendered as raw JSON in the generic tool card, with no toggle to control it and no way to read or reset the board.This brings the plugin to VS Code parity: a settings toggle, readable board messages in the transcript, and a board viewer.
Implementation
Config.
shared_agent_boardis a top-level CLI config key (it was retired out ofexperimental.*, whereretireExperimentalFlagsnow deletes and warns on the old path). It is wired throughConfigDto/ConfigPatchDtoand the parser, and surfaces as a toggle on the Agent Behavior page, mirroring where VS Code puts it. Default is on, matchingBoardEnabled.resolve, and the toggle always writes an explicit boolean so an opt-out survives default-on resolution. This convertsAgentBehaviorConfigurablefrom a navigation-only stub into a draft/apply page; the sub-page links are unchanged and the toggle sits below them behind its own separator.Rendering.
BoardToolParser+BoardToolViewrenderboard_post/board_readas route plus message via the markdown pipeline.canRenderreturns false for pending, running, or unparseable payloads so anything unexpected falls back to the genericToolViewrather than showing a broken card.Viewer.
SessionBoardDialogpages backward throughGET /kilocode/session/:id/board, opens a participating subagent in the existing read-only tab, and resets under a revision guard where HTTP 409 reloads instead of retrying blindly. These routes are called over raw HTTP because they are newer than the generated client built from the pinned CLI release.Three things worth reviewer attention:
board_postis recorded in its own session — the root transcript can stay empty while the board is not. The probe is event-driven (session load, busy→idle, config change, dialog close) and never polled, and message traffic skips it once the board is known non-empty so a busy turn does not fire one request per message.getDimensionServiceKeyis deliberately absent, because a remembered width defeats the frame-relative clamp on reopen. Manual resizes are therefore not remembered — say the word if that trade is wrong.boardWidth,boardWrap) rather than inline logic. That is not gold-plating: a headless test has no IDE frame, so asserting the clamp through the live dialog silently passes without checking anything. I hit exactly that and it is why these are extracted.Requires CLI ≥ 7.6.0. The board endpoints first shipped in 7.6.0; the repo pin is already 7.7.2, and I confirmed the routes are present in that release binary. No
packages/opencode/changes, so there is no upstream merge-conflict surface.Screenshots / Video
board_postrendered as raw JSON in the generic tool card; no toggle; no viewersession → ALLwith anINFObadge; Kilo Swarm toggle under Agent Behavior; board viewer titledKilo Swarm — <session name>with a collapsible info bannerHow to Test
Manual/local verification
Executed by the agent:
./gradlew typecheckfrompackages/kilo-jetbrains/— clean../gradlew testfrompackages/kilo-jetbrains/— full suite green acrossshared,frontend,backend.SessionBoardDialogTest(16),BoardDialogSizeTest(7),BoardToolParserTest(16),SessionBoardActionsTest(13),AgentBehaviorSettingsUiTest(6),AgentBehaviorSettingsStateTest(7),KiloBackendSessionManagerBoardTest(9), plus parser/app-service round trips for the config key.bun run script/check-md-table-padding.tsandcheck-kilocode-change— pass.session.board.*across all 18 locales against the base bundle, no duplicates, no unescaped apostrophes in{0}strings, and one sentence terminator per localeintro.Executed by the human author, in a sandbox IDE:
Reviewer test steps
packages/kilo-jetbrains/, run./gradlew --no-configuration-cache runIdeSplitMode.Use board_post to send an INFO message to ALL saying "hello board", then board_read it back.board_postcard renders as<session> → ALLwith anINFObadge instead of JSON.Kilo Swarm — <session name>, the info banner toggles between Expand and Collapse, and Reset board prompts before clearing.Blocked checks and substitute verification
th,ar,ko, andbswould be worthwhile before release.Checklist
.changeset/jetbrains-kilo-swarm-board.md(minor)Get in Touch