← Workstreams

Workstream: KotlinDiffViewer

Status: Planned · Component: Maximize developer productivity

Goal

Make reviewing Kotlin changes a first-class experience outside a full IDE: a standalone, side-by-side Kotlin diff viewer that is both a Compose Desktop application and an embeddable Compose component other desktop apps drop in. It shows two panes — before and after — with real IDE-grade language services on the code in them: jump-to-definition, completion / intellisense, and inline compile errors and warnings, provided by a Kotlin Language Server (LSP).

The defining constraint is decoupling: the viewer depends on the LSP protocol, not the IntelliJ Platform SDK. It is a plain language-server client, so it carries none of the IDE's weight, licensing, or coupling — it needs only a JVM and a language-server process. JetBrains' own kotlin-lsp is the chosen language service: it happens to be built on JetBrains analysis internals, but it runs as a separate process speaking LSP over JSON-RPC, so from the viewer's side the boundary is the protocol and nothing more.

Current state

Today the only "diff with Kotlin smarts" surface in the ecosystem is locked inside the IntelliJ plugin kotlintools-intellij — the "AiPlugin" / net.javadeploy.aiplugin Request Change action. Its MyCustomDiffTool / MyDiffRequestProcessor stack a multi-file diff vertically in a scroll pane and render each file in IntelliJ's standard side-by-side viewer, but they are tightly bound to the IntelliJ platform: a fork of the platform's internal DiffRequestProcessor, the com.intellij.diff.* DiffTool extension points, VirtualFile, and a running IDE for any language intelligence. None of that review experience — and none of its navigation/completion/diagnostics — is usable outside the IDE.

This workstream is brand-new and independent: it does not modify the plugin. kotlintools-intellij is referenced only as prior art and motivation — the review experience we want to liberate from the IDE.

No KotlinDiffViewer repository exists yet. Several existing org pieces are natural building blocks rather than starting points:

Piece Why it's relevant
rsyntaxpane-compose A Compose Desktop syntax-highlighted text editor component (RSyntaxTextArea wrapper) — a candidate for the per-pane editor surface.
WidgetPreviewWithEditableSourceCode A Compose Desktop editor that recompiles and re-renders Kotlin source live — prior art for driving Kotlin tooling from a Compose editor.
git.client.multirepogui A Compose + JGit desktop GUI with tree-view diffs — prior art for Compose-side diffing and the JGit patch handling the plugin also uses.
AIProgrammerImpl The real implementation of the AiProgrammer interface the plugin only mocks; it turns natural-language prompts into unified-diff code modifications. The viewer is the natural review surface for the diffs it produces.
Kotlin Build / kompile Kotlin compilation already in the ecosystem — relevant for resolving a project's classpath so the language server analyzes against real dependencies, not single files in isolation.

Why it accelerates developers

  • Review AI/agent-proposed changes with full Kotlin semantics without launching a multi-gigabyte IDE per review.
  • A reusable diff component for the ecosystem's Compose Desktop tooling (PR dashboards, the multi-repo Git GUI, AIProgrammerImpl review loops) instead of every tool reinventing a diff view.
  • Sheds the heaviest dependency in the review path. Decoupling from the IntelliJ Platform removes its footprint and licensing constraints; the viewer needs only a JVM and a language-server process.
  • Fits the agentic-review story. A lightweight, embeddable, scriptable review surface is exactly what an agent — or a human supervising one — needs to inspect a proposed diff before it is applied, complementing the Request Change loop the plugin pioneered.

Plan / roadmap

These are proposed and need sharpening before work starts.

  • [ ] Side-by-side diff core. A two-pane (before/after), multi-file diff view in Compose Desktop, with scroll-synced panes and changed regions highlighted. Accept changes as unified-diff / patch input (consume AIProgrammerImpl output; reuse java-diff-utils + JGit apply, as the plugin does).
  • [ ] Two delivery shapes from one codebase. Build a standalone Compose Desktop application and an embeddable @Composable component that other Compose Desktop apps drop in — the same viewer, packaged both ways.
  • [ ] Integrate JetBrains kotlin-lsp. Launch and manage the server process and implement a minimal LSP / JSON-RPC client, keeping the dependency strictly at the protocol boundary (no IntelliJ Platform SDK in the viewer).
  • [ ] Wire the three requested services to LSP requests: jump-to-definition (textDocument/definition), intellisense / autosuggest (textDocument/completion), and inline compile errors / warnings (textDocument/publishDiagnostics) — rendered in the diff panes as a completion popup, gutter markers, and squigglies.
  • [ ] Syntax highlighting for the panes (reuse rsyntaxpane-compose or LSP semantic tokens).
  • [ ] Project / classpath awareness so analysis reflects real dependencies — resolve the project model via Kotlin Build / kompile rather than parsing files in isolation.
  • [ ] Align with the platform where it makes sense (standard layered architecture) and add end-to-end tests per the testing standards: drive a real kotlin-lsp instance over a small fixture project and assert real definitions, completions, and diagnostics.

Open questions

  • kotlin-lsp maturity. kotlin-lsp is early / pre-alpha and supports only a subset of LSP features; which of jump-to-definition, completion, and diagnostics are reliable today, and what is the interim experience while it matures? (Committing to kotlin-lsp is the chosen direction — this is about sequencing around its current state, not reopening the choice.)
  • Launching / hosting the server. Bundle a JBR plus the server with the app, or rely on an installed toolchain? One server process per project, or a shared server across diffs?
  • Project model for accurate analysis. How does the viewer hand kotlin-lsp a correct classpath / source-root model for a change that may be only a patch over a few files — does it need a checked-out project, and how does that compose with Kotlin Build?
  • Embedding API surface. What is the minimal @Composable contract (inputs: before/after or a patch + a project root; outputs: accept / reject callbacks) so the PR Dashboard WUI, the multi-repo Git GUI, and an AIProgrammerImpl review loop can all embed it?
  • Beyond desktop. Is a url://-exposed or browser-based variant wanted later for agent / web review, or is Compose Desktop the whole scope?

Graduation

KotlinDiffViewer does not yet exist and has no Documentation Repository project page. This workstream graduates when a KotlinDiffViewer repository ships both the standalone Compose Desktop app and the embeddable component, with kotlin-lsp-backed jump-to-definition, completion, and inline diagnostics working in the side-by-side view, and at least one consumer embeds it (e.g. an AIProgrammerImpl review loop or a Compose Desktop PR / diff tool). At that point, add a Documentation Repository project doc + ALL_PROJECTS entry, and it is no longer tracked as a workstream here.