jetbrains-plugin
jetbrains-plugin
This document provides a technical overview of the jetbrains-plugin module, detailing its architecture, key components, and operational flow within the JetBrains IDE environment.
Code Buddy JetBrains Plugin
The jetbrains-plugin module implements the client-side integration for the Code Buddy AI assistant within JetBrains IDEs. Its primary purpose is to provide a seamless interface for developers to interact with an external Code Buddy server, leveraging AI capabilities for tasks like code explanation, review, test generation, and error fixing directly within their development workflow.
Architecture Overview
The plugin follows a standard JetBrains plugin architecture, extending various platform extension points to integrate its functionality. It consists of several core components:
- Actions: User-triggered commands (e.g., "Explain Code", "Fix Error") that gather context from the IDE.
- UI Components: A dedicated tool window (
ChatPanel) for AI interaction and a status bar widget for connection status. - API Client: A singleton (
CodeBuddyClient) responsible for all communication with the external Code Buddy server. - Settings: Persistent storage and a UI for configuring the server connection and AI model.
The general flow for an AI interaction initiated by a user action is:
- User triggers an
AnAction. - The action gathers relevant code context (selected text, file content, cursor position).
- A health check is performed against the Code Buddy server via
CodeBuddyClient. - If connected, a prompt message is constructed and sent to the
ChatPanel. - The
ChatPanelthen usesCodeBuddyClientto send the message to the server. - The server's AI response is received and displayed in the
ChatPanel.
graph TD
A[User Interaction] --> B(AnAction Triggered)
B --> C{Gather IDE Context}
B --> D(CodeBuddyClient.healthCheck)
D -- Connected --> E(Construct AI Prompt)
E --> F(ChatPanel.sendMessageFromAction)
F --> G(CodeBuddyClient.chat)
G -- HTTP Request --> H[Code Buddy Server]
H -- HTTP Response --> G
G --> F
F --> I(Display Response in ChatPanel)
subgraph JetBrains Plugin
B
C
D
E
F
G
I
J[CodeBuddySettings]
K[CodeBuddyConfigurable]
L[CodeBuddyStatusBarWidget]
end
J -- Configures --> G
K -- Modifies --> J
L -- Periodically calls --> D
Key Components
1. Plugin Entry Point (jetbrains-plugin/src/main/resources/META-INF/plugin.xml)
This XML file is the manifest for the plugin, declaring its capabilities and how it integrates with the JetBrains platform.
id,name,vendor,description: Basic plugin metadata.: Specifiescom.intellij.modules.platform, indicating a dependency on the core IntelliJ Platform.:toolWindow: Registers the "Code Buddy" tool window, managed byChatToolWindowFactory. It's a secondary tool window anchored to the right.statusBarWidgetFactory: RegistersCodeBuddyStatusBarWidgetFactoryto display connection status in the IDE's status bar.applicationConfigurable: IntegratesCodeBuddyConfigurableinto the IDE's settings under the "Tools" section, allowing users to configure plugin settings.applicationService: DeclaresCodeBuddySettingsas an application-level service, ensuring a single instance for managing persistent settings.notificationGroup: Defines a notification group for plugin-related messages.:CodeBuddy.Menu: A top-level menu group under "Tools" containing various AI actions.CodeBuddy.EditorPopup: A context menu group that appears when right-clicking in the editor, providing quick access to relevant actions.- Individual
tags define specific commands likeAskQuestionAction,ExplainCodeAction,ReviewFileAction,GenerateTestsAction, andFixErrorAction, linking them to their respective Kotlin classes and providing metadata (text, description, icon, keyboard shortcuts).
2. User Actions (com.codebuddy.plugin.actions.*)
These classes extend com.intellij.openapi.actionSystem.AnAction and provide the entry points for user-initiated AI interactions.
AskQuestionAction: Prompts the user for a question viaMessages.showInputDialogand sends it to the AI.ExplainCodeAction: Explains the currently selected code in the editor.FixErrorAction: Gathers code context around the cursor (and optionally selected error text) to ask the AI for a fix. It intelligently extracts line numbers, file names, and language.GenerateTestsAction: Generates unit tests for the selected code, attempting to guess the appropriate test framework based on the file extension.ReviewFileAction: Sends the content of the current file (truncated for very large files) to the AI for a code review.
Common Action Flow:
All actions share a similar actionPerformed logic:
- Retrieve
ProjectandEditor(if applicable) fromAnActionEvent. - Perform a
CodeBuddyClient.healthCheck()on a pooled thread to ensure server connectivity. - If the server is disconnected, display a warning using
Messages.showWarningDialog. - If connected, construct a detailed prompt message based on the action's purpose and gathered context.
- Open the "Code Buddy" tool window (
ToolWindowManager.getInstance(project).getToolWindow("Code Buddy")?.show) and send the constructed message to the activeChatPanelinstance viaChatPanel.getActiveInstance()?.sendMessageFromAction(message). - The
updatemethod controls when an action is enabled and visible based on project context, editor selection, etc.
3. Core Communication (com.codebuddy.plugin.api.CodeBuddyClient)
This class is the sole interface for interacting with the external Code Buddy server.
CodeBuddyClient: A singleton (companion object { getInstance() }) that manages HTTP communication.- Uses
okhttp3for making network requests andcom.google.gsonfor JSON serialization/deserialization. - Configures
OkHttpClientwith timeouts for robust network operations. - Retrieves
serverUrlandapiKeyfromCodeBuddySettings. chat(message: String, context: String? = null):- Constructs a JSON request body including the
message, optionalcontext, and the configuredmodel. - Sends a POST request to
$serverUrl/api/chat. - Includes an
Authorizationheader with the API key if configured. - Parses the JSON response into a
ChatResponsedata class, handling potential server errors or connection failures. healthCheck():- Sends a GET request to
$serverUrl/api/health. - Includes an
Authorizationheader if an API key is present. - Returns a
HealthStatusindicating connectivity, server version, and active model. This is crucial for providing immediate feedback to the user about server availability.
4. User Interface (com.codebuddy.plugin.ui.*)
These classes manage the visual components of the plugin.
ChatToolWindowFactory:- Implements
ToolWindowFactoryto create the content for the "Code Buddy" tool window. - Instantiates
ChatPaneland sets it as theactiveInstancefor global access. - Performs an initial
healthCheck()on tool window creation ifCodeBuddySettings.autoConnectis enabled, displaying a connection status message in the chat. ChatPanel:- The main UI panel for displaying chat history and user input.
messagesPane: AJEditorPaneconfigured with anHTMLEditorKitand custom CSS (StyleSheet) to render chat messages with basic styling (user, assistant, error roles, code blocks).inputArea: AJBTextAreafor user input, supportingShift+Enterfor newlines andEnterto send.sendButton: TriggerssendMessage().sendMessage(): Called when the user sends a message from the input area. Disables input, appends the user message, callsCodeBuddyClient.chat()on a pooled thread, and then re-enables input and displays the AI response or error.sendMessageFromAction(message: String): An entry point forAnActionclasses to send pre-formatted messages to the AI. It follows a similar flow tosendMessage().appendMessage(role: String, content: String): Formats and appends a new message to themessagesPane.markdownToHtml(text: String): A utility function to convert basic Markdown (code blocks, inline code, bold, italic, headers) into HTML for display inmessagesPane.escapeHtml(text: String): Escapes HTML special characters to prevent injection issues.companion object { getActiveInstance(), setActiveInstance() }: Provides a static way to access the currently activeChatPanelinstance, which is essential for actions to communicate with the tool window.StatusBarWidgetFactory/CodeBuddyStatusBarWidget:CodeBuddyStatusBarWidgetFactory: Registers the status bar widget.CodeBuddyStatusBarWidget: ImplementsStatusBarWidgetto display the connection status to the Code Buddy server.startPolling(): Initiates a scheduled task (scheduler.scheduleWithFixedDelay) to periodically callcheckConnection().checkConnection(): CallsCodeBuddyClient.healthCheck()on a pooled thread, updates theconnectedandmodelNamestate, and refreshes the widget's display (statusBar?.updateWidget(ID())).getText(): Returns "CB: Connected" (with model name if available) or "CB: Disconnected".getTooltipText(): Provides detailed connection information on hover.
5. Configuration and Persistence (com.codebuddy.plugin.settings.*)
These classes handle the plugin's settings, allowing users to configure the Code Buddy server details.
CodeBuddySettings:- Implements
PersistentStateComponentand is declared as anApplicationService. This means its state is persisted across IDE restarts at the application level. @State: Specifies the name (CodeBuddySettings) and storage location (CodeBuddyPlugin.xml) for the settings.data class State: Defines the data structure for the persistent settings:serverUrl,apiKey,model, andautoConnect.- Provides
getInstance()for easy access to the singleton settings service. - Exposes read-only properties (
serverUrl,apiKey, etc.) for convenience. CodeBuddyConfigurable:- Implements
Configurableto provide a UI for editingCodeBuddySettingsin the IDE's preferences. createComponent(): Builds the Swing UI usingFormBuilder, includingJBTextFieldfor URL and model,JBPasswordFieldfor API key, andJBCheckBoxfor auto-connect.isModified(): Checks if the current UI values differ from the persisted settings.apply(): Saves the current UI values toCodeBuddySettings.state.reset(): Loads the persisted settings into the UI fields.disposeUIResources(): Cleans up UI components when the settings panel is closed.
Development Guidelines
Adding New Actions
- Create a new Kotlin class extending
AnActionincom.codebuddy.plugin.actions. - Implement
actionPerformed(e: AnActionEvent)to gather context, perform ahealthCheck(), construct a prompt, and callChatPanel.getActiveInstance()?.sendMessageFromAction(message). - Implement
update(e: AnActionEvent)to control when the action is enabled/visible. - Register the action in
plugin.xmlwithin an appropriate(e.g.,CodeBuddy.MenuorCodeBuddy.EditorPopup).
UI Styling
The ChatPanel uses HTMLEditorKit and a StyleSheet to render messages. To modify the appearance of chat messages:
- Edit the CSS rules within
ChatPanel.init { ... style.addRule(...) }. - The current roles are
.user,.assistant, and.error. - Markdown rendering is handled by
markdownToHtml(). If more advanced Markdown features are needed, consider integrating a dedicated Markdown-to-HTML library.
Error Handling
- Network errors and server-side errors from
CodeBuddyClientare caught and returned inChatResponse.errororHealthStatus.connected = false. - These errors are then displayed in the
ChatPanelwith the.errorstyle or asMessages.showWarningDialogfor critical connection issues. - Ensure all calls to
CodeBuddyClientare wrapped inApplicationManager.getApplication().executeOnPooledThread { ... }to prevent blocking the UI thread.
Threading Model
JetBrains IDEs are sensitive to UI blocking. Adhere to the following:
- Long-running operations (network requests, heavy computations): Must be executed on a background thread using
ApplicationManager.getApplication().executeOnPooledThread { ... }. - UI updates: Must be performed on the Event Dispatch Thread (EDT) using
ApplicationManager.getApplication().invokeLater { ... }orjavax.swing.SwingUtilities.invokeLater { ... }. - The
CodeBuddyClientmethods (chat,healthCheck) are blocking, so they must be called from a background thread. The actions and UI components correctly follow this pattern.