Skip to content

JetBrains/IntelliJ plugin: reuse the localhost + webview surface via JCEF (and make the shared UI responsive for desktop) #128

Description

@zo-sol

Summary

Ship AgentNet as a JetBrains (IntelliJ Platform) plugin by reusing the existing
surfaces/localhost Node server and surfaces/webview React app, hosted inside a thin
Kotlin shell via JCEF (the Chromium browser bundled with every JetBrains IDE). This is the
same shell pattern the Android app already uses, moved to the desktop.

The important secondary point: doing this exposes a gap. The reused webview UI is tuned for
Android portrait (a narrow, single column). A JetBrains tool window (and the web/localhost
surface in general) is wide/landscape, so the shared UI needs a responsive pass before it
looks right on desktop. Tracked as a sub-task below.

Why this is cheap

surfaces/localhost/src/index.ts is already a self-contained Node HTTP + WebSocket server:
it wires createChatSession + connect + localWallet from packages/core, serves the
surfaces/webview React app, and handles the Google OAuth callback on its own route. The
Android app is just a native WebView shell pointed at http://127.0.0.1:PORT.

A JetBrains port is that same pattern on desktop:

JetBrains plugin (Kotlin)
  └─ ToolWindow
       └─ JBCefBrowser  ──▶  http://127.0.0.1:PORT
                                   │
                                   └─ surfaces/localhost (Node)
                                        ├─ packages/core (chat, wallet, marketplace, session sync)
                                        └─ serves surfaces/webview (React UI)

No core logic is rewritten. JCEF is Chromium, and our webview already targets Chromium
(VS Code webview and Android WebView are both Blink), so CSS/JS compatibility is a non-issue.

Reuse vs new

Component Status
packages/core (chat, wallet, marketplace, session sync) Reused, 0 rewrite
surfaces/webview (React UI) Reused
surfaces/localhost (Node server) Reused
Plugin scaffold (plugin.xml + Gradle IntelliJ plugin) New (Kotlin)
ToolWindow + JBCefBrowser New (small)
Node sidecar lifecycle (spawn on plugin load, kill on unload) New (small)
openUrl -> system browser (OAuth / Drive links) New (a few lines)

The Kotlin we write is essentially "open a browser panel and manage a child process,"
mirroring the Android MainActivity shell.

Open problems

  1. Node runtime distribution (the real work). The localhost server needs Node on the user's
    machine. For a dev PoC we can require a local node. For distribution we bundle a
    per-platform Node binary, the same problem Android solved with its bundled runtime. This
    is the largest and riskiest piece.
  2. Responsive UI (the portrait-only gap). See sub-task below.
  3. UI parity expectation. The recent VS Code-native polish (sidebar WebviewViewProvider,
    status bar, native panels) lives in the VS Code webview path (packages/core/.../chat/ui/webview.ts).
    localhost serves the React app instead, so the JetBrains build inherits the mobile/web
    look, not the VS Code look. That is fine, but we should decide and set expectations.
  4. JetBrains Marketplace is a separate publishing channel with its own review (lighter than
    the Solana dApp Store, but still a distinct submission).

Sub-task: make the shared webview UI responsive for wide/desktop layouts

The surfaces/webview React UI is currently designed for Android portrait: narrow, single
column, full-width rows and sheets. On a JetBrains tool window (which can be docked wide,
tall, or floating) and on the desktop web/localhost surface, that layout leaves large empty
gutters or stretches components awkwardly.

Work here:

  • Audit the webview components (session list, chat, composer, skills/market sheets) for
    hard-coded narrow assumptions.
  • Add breakpoints so wide viewports use the available horizontal space (e.g. a persistent
    session rail beside the chat instead of a slide-over sheet, constrained max-width for the
    message column).
  • Verify portrait/narrow still looks correct (Android must not regress).

This benefits the existing web/localhost surface immediately, independent of whether the
JetBrains shell ships.

Suggested phasing

  1. PoC: Kotlin plugin + JBCefBrowser pointed at a manually started surfaces/localhost,
    assuming system Node. Confirm chat, wallet, and marketplace work end to end in JCEF.
  2. Node sidecar lifecycle inside the plugin (auto start/stop, port selection, health check).
  3. Responsive UI pass (sub-task above).
  4. Node runtime bundling for distribution.
  5. JetBrains Marketplace submission.

Open questions

  • Do we bundle Node or require it? (Affects plugin size and install friction.)
  • One shared responsive UI for web + JetBrains + Android, or a desktop-specific layout?
  • Do we want the VS Code-native look on JetBrains eventually, or is the web/React UI the
    intended target?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions