Back to Kilocode

Plan: JetBrains Feedback & Support Button

.kilo/plans/1780256109130-stellar-forest.md

7.3.287.4 KB
Original Source

Plan: JetBrains Feedback & Support Button

Goal

Add the VS Code empty-state Feedback & Support affordance to the JetBrains plugin, including a non-modal popup with the same three destinations:

  • GitHub issues: https://github.com/Kilo-Org/kilocode/issues/new/choose
  • Discord: https://kilo.ai/discord
  • Customer support: https://kilo.ai/support

The popup must hide when clicking outside or pressing Escape.

Findings

  • The JetBrains empty state is packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/EmptySessionPanel.kt.
  • It already renders the logo, welcome copy, recents, and Show History; this is the right place to add the button.
  • The VS Code implementation is:
    • Button: packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx
    • Popup content: packages/kilo-vscode/webview-ui/src/components/chat/FeedbackDialog.tsx
    • Styling: packages/kilo-vscode/webview-ui/src/styles/welcome.css
  • Local IntelliJ API source is available at $INTELLIJ_REPO=/Users/kirillk/products/intellij-community.
  • IntelliJ popup API confirmed in local source:
    • JBPopupFactory.getInstance().createComponentPopupBuilder(content, focusComponent)
    • setModalContext(false) for non-modal context
    • setRequestFocus(false) / setFocusable(false) if we want the popup not to steal focus
    • setCancelOnClickOutside(true) for outside-click dismissal
    • setCancelKeyEnabled(true) for Escape dismissal
    • setCancelOnWindowDeactivation(true) and setCancelOnOtherWindowOpen(true) are available and appropriate for cleanup
  • IntelliJ platform icons found in AllIcons:
    • Feedback button: AllIcons.Ide.Feedback
    • GitHub action: AllIcons.Vcs.Vendors.Github
    • Support/help action: AllIcons.Actions.Help or AllIcons.General.ContextHelp
    • Discord: no platform icon found. Add a Discord icon by borrowing the existing VS Code/kilo-ui Discord SVG artwork and adapting it into the JetBrains plugin resources with IntelliJ-compatible SVG colors and dark variant if needed.

Implementation Steps

  1. Add localized JetBrains bundle keys.

    • Add base English strings to frontend/src/main/resources/messages/KiloBundle.properties:
      • feedback.button=Feedback & Support
      • feedback.dialog.message=We'd love to hear your feedback or help with any issues you're experiencing.
      • feedback.dialog.github=Report an issue on GitHub
      • feedback.dialog.discord=Join our Discord community
      • feedback.dialog.support=Customer Support
      • Reuse existing cancel text if present; otherwise add common.cancel=Cancel only if needed.
    • Add matching keys to localized KiloBundle_*.properties files. If accurate translations are not already available from the VS Code i18n files, copy the VS Code translations for matching locales where practical and leave English fallback only if the JetBrains bundle mechanism supports it cleanly.
  2. Extend EmptySessionPanel UI.

    • Add a new retained FeedbackButton, styled to match VS Code conceptually:
      • feedback icon + Feedback & Support text
      • dashed link-colored border
      • transparent background
      • hand cursor
      • hover state fills with link color and flips foreground/background for contrast
    • Use IntelliJ theme APIs instead of raw colors:
      • link color: JBUI.CurrentTheme.Link.Foreground.ENABLED
      • hover link color: JBUI.CurrentTheme.Link.Foreground.HOVERED if useful
      • editor/panel background from existing session style or UiStyle.Colors.editorBackground() / component background
      • spacing via UiStyle.Gap / JBUI.Borders
      • rounded arc via UiStyle.Arc.component() or JBUI.getInt("Button.arc", 6) at paint time
    • Add the feedback button below the existing Show History button in the empty-state south area, keeping the current centered layout.
    • Keep Swing mutations on EDT and preserve retained-component behavior.
  3. Implement the feedback popup in frontend Swing code.

    • Add a small popup builder method/class inside EmptySessionPanel.kt or a new nearby UI file if the file would become too large.
    • Content should mirror VS Code:
      • Kilo logo at top using existing /icons/kilo-content.svg
      • message text
      • three action buttons/rows for GitHub, Discord, and Customer Support
      • every action should have an icon: AllIcons.Vcs.Vendors.Github for GitHub, the borrowed Discord SVG for Discord, and AllIcons.Actions.Help or AllIcons.General.ContextHelp for Customer Support
      • optional Cancel button if it fits the JetBrains UX; Escape/outside click already dismisses
    • Add the Discord icon asset under frontend/src/main/resources/icons/ using the plugin's existing icon naming pattern, for example discord.svg and discord_dark.svg if the borrowed asset needs separate theme variants.
    • Load the Discord icon with IconLoader.getIcon("/icons/discord.svg", EmptySessionPanel::class.java) or a small Kilo-owned icon object if multiple call sites need it.
    • Use BrowserUtil.browse(url) to open links.
    • Close the popup after opening a URL.
    • Use JBPopupFactory.createComponentPopupBuilder(content, null) and configure:
      • .setModalContext(false)
      • .setRequestFocus(false)
      • .setFocusable(false) unless keyboard tabbing inside popup is desired; if buttons need keyboard focus, use .setFocusable(true) with .setRequestFocus(false)
      • .setCancelOnClickOutside(true)
      • .setCancelKeyEnabled(true)
      • .setCancelOnWindowDeactivation(true)
      • .setCancelOnOtherWindowOpen(true)
      • .setResizable(false)
      • .setMovable(false)
    • Show with popup.showUnderneathOf(feedbackButton).
  4. Add test coverage in EmptySessionPanelTest.kt.

    • Assert feedback button text uses KiloBundle.message("feedback.button").
    • Assert feedback button has hand cursor and visible border semantics.
    • Add an injectable browse callback or popup action callback only if needed for testing without launching browsers; keep it minimal and avoid production-only test hooks if component traversal can exercise enough behavior.
    • Add a test that clicking the feedback button creates/shows popup content, if feasible in BasePlatformTestCase; otherwise test the retained popup content builder/action rows directly through package-internal methods.
    • Assert the three action labels exist and URL callbacks map to the same URLs as VS Code.
    • Assert the Discord action has an icon, so the plan cannot regress to a text-only Discord row.
  5. Add release note.

    • This is user-facing for the JetBrains plugin, so add a patch changeset under .changeset/ unless the repo has a JetBrains-specific release-note mechanism that supersedes changesets.
    • Suggested text: Add Feedback & Support to the JetBrains empty session screen.
  6. Verify.

    • Run the focused frontend/JetBrains tests first, preferably from packages/kilo-jetbrains/:
      • ./gradlew :frontend:test --tests "ai.kilocode.client.session.ui.EmptySessionPanelTest"
    • Run JetBrains typecheck from packages/kilo-jetbrains/:
      • bun run typecheck or ./gradlew typecheck
    • If touching only frontend UI and tests pass, no backend/SDK generation is needed.

Notes

  • Do not add Kotlin UI DSL, Compose, or JCEF.
  • Do not modify shared opencode files; this work is entirely under packages/kilo-jetbrains/ plus a changeset.
  • Prefer platform icons where available, but explicitly borrow/add the Discord icon because AllIcons does not provide one and the popup should match the VS Code button set visually.