### Setup and Build Examples Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Demonstrates advanced usage for setup and build scripts, including verbose output, debug mode, building specific components, and custom output directories. ```bash # First time setup ./scripts/setup.sh --verbose # Build in debug mode ./scripts/build.sh --mode debug # Build specific component ./scripts/build.sh idea # Build with custom output directory ./scripts/build.sh --output ./dist ``` -------------------------------- ### Setup Development Environment Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Run this script to set up the development environment. It installs necessary dependencies and configures the project. ```bash ./scripts/setup.sh ``` -------------------------------- ### Run Extension Host in Development Mode Source: https://github.com/wecode-ai/runvsagent/blob/main/README.md Commands to start the extension host in development mode. Requires navigating to the extension_host directory and installing dependencies. ```bash cd extension_host npm install npm run dev ``` -------------------------------- ### Initialize Development Environment Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Run the setup script to initialize all necessary components for development. Use the --verbose flag for detailed output during the first-time setup. ```bash # Run the setup script to initialize everything ./scripts/setup.sh # For verbose output (recommended for first-time setup) ./scripts/setup.sh --verbose ``` -------------------------------- ### Project Setup and Build Scripts (Bash) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Scripts for first-time setup, building release or debug versions, and development mode with hot-reloading. ```bash # ── First-time setup ────────────────────────────────────────────── git clone https://github.com/wecode-ai/RunVSAgent.git cd RunVSAgent git submodule update --init --recursive # pulls the VSCode base submodule ./scripts/setup.sh --verbose # install Node deps, verify JDK, Gradle wrapper # ── Build ───────────────────────────────────────────────────────── ./scripts/build.sh # release build (default) ./scripts/build.sh --mode debug # debug build with source maps ./scripts/build.sh idea # only build the JetBrains plugin BUILD_MODE=debug ./scripts/build.sh # via environment variable # Output: jetbrains_plugin/build/distributions/RunVSAgent-.zip # ── Development mode (hot-reload) ───────────────────────────────── cd extension_host && npm install && npm run dev # compile TS + start Node host # In a second terminal: cd jetbrains_plugin && ./gradlew runIde # launches a sandbox IntelliJ instance ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Examples demonstrating the conventional commit format for various types. ```markdown Examples: ``` feat(extension-host): add support for WebView API fix(jetbrains-plugin): resolve RPC connection timeout issue docs: update installation guide for Windows users test(rpc): add unit tests for message serialization ``` ``` -------------------------------- ### Write Unit Tests in Kotlin with JUnit 5 Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Example of writing unit tests for ExtensionHostManager using JUnit 5. Covers setup, startup, and failure handling. ```kotlin // jetbrains_plugin/src/test/kotlin/ExtensionHostManagerTest.kt import org.junit.jupiter.api.Test import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.* import kotlinx.coroutines.test.runTest class ExtensionHostManagerTest { private lateinit var manager: ExtensionHostManager private lateinit var mockProject: Project @BeforeEach fun setUp() { mockProject = createMockProject() manager = ExtensionHostManager(mockProject) } @AfterEach fun tearDown() { manager.dispose() } @Test fun `should start extension host successfully`() = runTest { // Arrange val config = createValidConfig() // Act val result = manager.startExtensionHost(config) // Assert assertTrue(result.isSuccess) assertTrue(manager.isRunning) } @Test fun `should handle startup failure gracefully`() = runTest { // Arrange val invalidConfig = createInvalidConfig() // Act val result = manager.startExtensionHost(invalidConfig) // Assert assertTrue(result.isFailure) assertFalse(manager.isRunning) } } ``` -------------------------------- ### Initialize, Build, Test, and Clean on Linux/macOS Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Execute core project operations using the setup, build, test, and clean scripts. Ensure scripts are executable before running. ```bash # Initialize development environment ./scripts/setup.sh # Build the project ./scripts/build.sh # Run tests ./scripts/test.sh # Clean build artifacts ./scripts/clean.sh ``` -------------------------------- ### Testing Examples Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Illustrates various ways to run tests, including all tests, specific test types (e.g., lint), with coverage, and in watch mode for continuous testing. ```bash # Run all tests ./scripts/test.sh # Run specific test type ./scripts/test.sh lint # Run tests with coverage ./scripts/test.sh --coverage # Run tests in watch mode ./scripts/test.sh --watch ``` -------------------------------- ### Run Extension Host in Development Mode Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Start the extension host in development mode. This command should be run from the extension_host directory. ```bash # Start extension host in development mode cd extension_host npm run dev ``` -------------------------------- ### Cleaning Examples Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Shows different cleaning options, such as cleaning only build artifacts, cleaning everything, cleaning dependencies, and performing a forced clean without confirmation. ```bash # Clean build artifacts only ./scripts/clean.sh # Clean everything ./scripts/clean.sh all # Clean dependencies ./scripts/clean.sh deps # Force clean without confirmation ./scripts/clean.sh --force all ``` -------------------------------- ### Clean and Rebuild Project Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Execute the clean, setup, and build scripts in sequence for a full project rebuild. ```bash ./scripts/clean.sh all ./scripts/setup.sh --force ./scripts/build.sh --verbose ``` -------------------------------- ### Conventional Commit Example Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Example of staging changes and committing them using the conventional commit format. ```bash git add . git commit -m "feat: add support for new VSCode agent API" ``` -------------------------------- ### EditorConfig File Example Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Configuration settings for editor consistency across different editors and IDEs. ```ini root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.{ts,js}] indent_style = space indent_size = 2 [*.kt] indent_style = space indent_size = 4 [*.md] trim_trailing_whitespace = false ``` -------------------------------- ### Switch ExtensionProvider at Runtime (Kotlin) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Example of switching to a different agent provider at runtime using the ExtensionManager. The result indicates if the switch was successful. ```kotlin // Switch to Cline at runtime val switched = manager.setCurrentProvider("cline", forceRestart = false) println("Switched to Cline: $switched") // true if cline files are present ``` -------------------------------- ### Download JCEF-Compatible JetBrains Runtime Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Example filename for a JCEF-compatible JetBrains Runtime. Ensure the correct architecture for your OS. ```text jbr_jcef-17.0.11-osx-aarch64-b1063.2.tar.gz ``` -------------------------------- ### Clone Repository and Setup Upstream Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Fork the repository on GitHub, clone your fork, and add the original repository as an upstream remote. ```bash # Fork the repository on GitHub, then clone your fork git clone https://github.com/YOUR_USERNAME/RunVSAgent.git cd RunVSAgent # Add the original repository as upstream git remote add upstream https://github.com/original-org/RunVSAgent.git ``` -------------------------------- ### Run Scripts with PowerShell Source: https://context7.com/wecode-ai/runvsagent/llms.txt Execute setup, build, or test commands using PowerShell scripts on Windows. ```powershell .\scripts\run.ps1 setup ``` ```powershell .\scripts\run.ps1 build ``` ```powershell .\scripts\run.ps1 test ``` -------------------------------- ### Initialize ExtensionManager (Kotlin) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Example usage of initializing the ExtensionManager during project startup, specifying an initial configured extension ID. ```kotlin // Usage during project startup val manager = project.getService(ExtensionManager::class.java) manager.initialize(configuredExtensionId = "roo-code") ``` -------------------------------- ### Write Unit Tests in TypeScript with Jest Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Example of writing unit tests for ExtensionManager using Jest. Includes setup, loading extensions, and error handling. ```typescript // extension_host/src/__tests__/extensionManager.test.ts import { ExtensionManager } from '../extensionManager'; import { mockExtensionConfig } from './mocks'; describe('ExtensionManager', () => { let extensionManager: ExtensionManager; beforeEach(() => { extensionManager = new ExtensionManager(); }); afterEach(() => { extensionManager.dispose(); }); describe('loadExtension', () => { it('should load a valid extension', async () => { // Arrange const config = mockExtensionConfig(); // Act const extension = await extensionManager.loadExtension(config); // Assert expect(extension).toBeDefined(); expect(extension.isActive).toBe(true); }); it('should throw error for invalid extension', async () => { // Arrange const invalidConfig = { ...mockExtensionConfig(), name: '' }; // Act & Assert await expect(extensionManager.loadExtension(invalidConfig)) .rejects.toThrow('Extension name cannot be empty'); }); }); }); ``` -------------------------------- ### Verify Node.js Installation Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Run this command in your terminal to check if Node.js is installed and accessible. ```bash node --version ``` -------------------------------- ### Push Changes Example Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Push your feature branch to the origin remote. ```bash git push origin feature/your-feature-name ``` -------------------------------- ### Implement ClineExtensionProvider (Kotlin) Source: https://context7.com/wecode-ai/runvsagent/llms.txt A minimal example implementation of the ExtensionProvider interface for a Cline AI integration. It defines basic metadata and logic for checking availability. ```kotlin // jetbrains_plugin/src/main/kotlin/com/sina/weibo/agent/extensions/core/ExtensionProvider.kt class ClineExtensionProvider : ExtensionProvider { override fun getExtensionId() = "cline" override fun getDisplayName() = "Cline AI" override fun getDescription() = "AI-powered coding assistant with advanced features" override fun initialize(project: Project) { ExtensionConfiguration.getInstance(project).initialize() try { ExtensionManagerFactory.getInstance(project).initialize() } catch (e: Exception) { /* optional factory; continue */ } } override fun isAvailable(project: Project): Boolean { val config = ExtensionConfiguration.getInstance(project).getConfig(ExtensionType.CLINE) val extensionDir = "${VsixManager.getBaseDirectory()}/${config.codeDir}" if (File(extensionDir).exists()) return true return try { val resourcePath = PluginResourceUtil.getResourcePath(PluginConstants.PLUGIN_ID, config.codeDir) resourcePath != null && File(resourcePath).exists() } catch (e: Exception) { false } } override fun getConfiguration(project: Project): ExtensionMetadata = ExtensionConfiguration.getInstance(project).getConfig(ExtensionType.CLINE) override fun dispose() { /* release resources */ } } ``` -------------------------------- ### Changelog Format Example Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Example of the Keep a Changelog format used for maintaining the CHANGELOG.md file. Includes sections for Added, Changed, Deprecated, Removed, Fixed, and Security. ```markdown # Changelog ## [Unreleased] ### Added - New feature descriptions ### Changed - Changes in existing functionality ### Deprecated - Soon-to-be removed features ### Removed - Now removed features ### Fixed - Bug fixes ### Security - Security improvements ## [1.2.0] - 2023-12-01 ### Added - Support for VSCode WebView API - New RPC communication protocol ### Fixed - Memory leak in extension host - Connection timeout issues ``` -------------------------------- ### Branch Naming Conventions Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Examples of standard branch naming conventions for different types of contributions. ```bash feature/add-new-agent-support bugfix/fix-rpc-connection-issue hotfix/critical-security-patch release/v1.2.0 docs/update-contributing-guide test/improve-unit-test-coverage ``` -------------------------------- ### Integration Test RPC Communication Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Example of an integration test for RPC communication between JetBrains plugin and Extension Host. Covers setup, command execution, and assertions. ```typescript // integration-tests/rpc-communication.test.ts describe('RPC Communication Integration', () => { let jetbrainsPlugin: MockJetBrainsPlugin; let extensionHost: ExtensionHost; beforeAll(async () => { jetbrainsPlugin = new MockJetBrainsPlugin(); extensionHost = new ExtensionHost(); await jetbrainsPlugin.start(); await extensionHost.start(); await establishConnection(jetbrainsPlugin, extensionHost); }); afterAll(async () => { await extensionHost.stop(); await jetbrainsPlugin.stop(); }); it('should execute commands end-to-end', async () => { // Arrange const command = 'extension.test.command'; const params = { text: 'Hello, World!' }; // Act const response = await jetbrainsPlugin.executeCommand(command, params); // Assert expect(response.success).toBe(true); expect(response.result).toContain('Hello, World!'); }); }); ``` -------------------------------- ### Check and Update Node.js Version Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Verify the installed Node.js version and provides guidance on updating it if necessary. This is crucial for projects with specific Node.js version requirements. ```bash # Check Node.js version node --version # Update Node.js if needed # Use nvm, n, or download from nodejs.org ``` -------------------------------- ### JetBrains Plugin: Toolbar Button Integration (Kotlin) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Implement `ButtonProvider` to define toolbar buttons for an agent. Includes a WebView availability guard to prevent silent failures when starting new tasks. ```kotlin class ClineButtonProvider : ButtonProvider { override fun getButtons(project: Project): List = listOf( PlusAction(), McpAction(), HistoryAction(), AccountAction(), SettingsAction() ) private inner class PlusAction : AnAction("New Task", "Start new Cline task", Icons.Plus) { override fun actionPerformed(e: AnActionEvent) { val project = e.project ?: return val webViewManager = project.getService(WebViewManager::class.java) if (webViewManager == null) { // Manager not initialized — log only, avoid dialog spam Logger.getInstance(javaClass).warn("WebViewManager not available") return } val latestWebView = webViewManager.getLatestWebView() if (latestWebView != null) { executeCommand("cline.plusButtonClicked", project, hasArgs = false) } else { Messages.showWarningDialog( project, "No active WebView found. Please ensure the Cline extension is properly initialized.", "WebView Not Available" ) } } } // Button visibility configuration — controls which buttons are shown in the toolbar private class ClineButtonConfiguration : ButtonConfiguration { override fun isButtonVisible(buttonType: ButtonType) = when (buttonType) { ButtonType.PLUS, ButtonType.PROMPTS, ButtonType.HISTORY, ButtonType.SETTINGS -> true ButtonType.MCP, ButtonType.MARKETPLACE -> false } } } ``` -------------------------------- ### Jest Configuration for Extension Host Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Configuration file for Jest, specifying test environment, roots, matching patterns, coverage collection, and setup files. ```javascript module.exports = { preset: 'ts-jest', testEnvironment: 'node', roots: ['/src'], testMatch: ['**/__tests__/**/*.test.ts'], collectCoverageFrom: [ 'src/**/*.ts', '!src/**/*.d.ts', '!src/**/__tests__/**', ], coverageThreshold: { global: { branches: 80, functions: 80, lines: 80, statements: 80, }, }, setupFilesAfterEnv: ['/src/__tests__/setup.ts'], }; ``` -------------------------------- ### Build Project Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Build the project. This command should be run after setting up the development environment. ```bash ./scripts/build.sh ``` -------------------------------- ### Build Project with Bash Script Source: https://github.com/wecode-ai/runvsagent/blob/main/README.md Steps to clone the repository, set up the development environment, and build the project using provided bash scripts. ```bash git clone https://github.com/your-org/RunVSAgent.git cd RunVSAgent ./scripts/setup.sh ./scripts/build.sh # Plugin file located at: jetbrains_plugin/build/distributions/ # In IDE: Settings → Plugins → Install Plugin from Disk ``` -------------------------------- ### Build and Test Project Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Build the project to ensure all components are working correctly and run the test suite. ```bash # Build the project to ensure everything is working ./scripts/build.sh # Run tests ./scripts/test.sh ``` -------------------------------- ### Prepare Sandbox with Gradle Source: https://context7.com/wecode-ai/runvsagent/llms.txt Prepare the sandbox environment using Gradle with different debug modes and VSCode plugin configurations. Requires `platform.zip` for release mode. ```bash ./gradlew prepareSandbox -PdebugMode=idea -PvscodePlugin=roo-code ``` ```bash ./gradlew prepareSandbox -PdebugMode=release ``` -------------------------------- ### Initialize WebViewManager and Handle Events (TypeScript) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Sets up the WebViewManager, registers a webview view provider, updates its HTML content, and posts a message to it. Includes cleanup by disposing of the manager. ```typescript import { WebViewManager } from './src/webViewManager.js'; import { IRPCProtocol } from './vscode/vs/workbench/services/extensions/common/proxyIdentifier.js'; // Created inside RPCManager.setupRooCodeRequiredProtocols() and shared across // MainThreadWebviewViews and MainThreadWebviews protocol slots. function setupWebViewHandling(rpcProtocol: IRPCProtocol): WebViewManager { const webViewManager = new WebViewManager(rpcProtocol); // When the extension calls vscode.window.registerWebviewViewProvider(...) // the host fires $registerWebviewViewProvider, which: // 1. Creates a SimpleWebview instance // 2. Stores it under the viewType key // 3. Calls _proxy.$resolveWebviewView(handle, viewType, ...) // so the extension can populate the view // Simulating what the protocol layer calls: webViewManager.$registerWebviewViewProvider( { id: 'roo-code', displayName: 'Roo Code' } as any, 'roo-codeai.SidebarProvider', { retainContextWhenHidden: true, serializeBuffersForPostMessage: false } ); // Send an HTML update from the IDE side webViewManager.$setHtml( 'webview-roo-codeai.SidebarProvider-1716000000000', 'Loading Roo Code...' ); // Post a JSON message into the webview webViewManager.$postMessage( 'webview-roo-codeai.SidebarProvider-1716000000000', JSON.stringify({ type: 'init', payload: { theme: 'dark' } }) ).then(sent => console.log('Message delivered:', sent)); // true // Cleanup webViewManager.dispose(); return webViewManager; } ``` -------------------------------- ### Main Extension Host Startup Sequence (TypeScript) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Orchestrates the Extension Host lifecycle by forking a child process, setting up a TCP server for communication, and performing the Ready/Initialized handshake. Handles graceful shutdown via SIGINT. ```typescript // The entry point is run via: node ./dist/src/main.js // It performs these steps automatically: import * as net from 'net'; import { fork } from 'child_process'; import { ExtensionManager } from './src/extensionManager.js'; import { RPCManager } from './src/rpcManager.js'; // Step 1 – Register extensions before the socket server starts const extensionManager = new ExtensionManager(); const rooCodeIdentifier = extensionManager.registerExtension('roo-code').identifier; // Step 2 – Create a TCP server on a random loopback port const server = net.createServer((socket) => { socket.setNoDelay(true); // Wrap socket → PersistentProtocol, listen for MessageType.Ready / MessageType.Initialized // On Ready → send IExtensionHostInitData (workspace, environment, extensions list, etc.) // On Initialized → new RPCManager(protocol, extensionManager) // rpcManager.startInitialize() // extensionManager.activateExtension(rooCodeIdentifier.value, rpcProtocol) }); // Step 3 – Fork extension host child process with socket coordinates server.listen(0, '127.0.0.1', () => { const port = (server.address() as net.AddressInfo).port; const child = fork('./dist/src/extension.js', [], { env: { ...process.env, VSCODE_EXTHOST_WILL_SEND_SOCKET: '1', VSCODE_EXTHOST_SOCKET_HOST: '127.0.0.1', VSCODE_EXTHOST_SOCKET_PORT: String(port), NODE_OPTIONS: '--inspect=9229' } }); child.on('exit', (code, signal) => { console.log(`Extension host exited: code=${code} signal=${signal}`); server.close(); }); }); // Step 4 – Graceful shutdown process.on('SIGINT', () => { // Sends MessageType.Terminate over the protocol before closing server.close(); process.exit(0); }); ``` -------------------------------- ### Initialize, Build, Test, and Clean on Windows Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Perform project operations on Windows using the PowerShell wrapper script. This provides a unified interface for common tasks. ```powershell # Initialize development environment . scripts\run.ps1 setup # Build the project . scripts\run.ps1 build # Run tests . scripts\run.ps1 test # Clean build artifacts . scripts\run.ps1 clean ``` -------------------------------- ### Build Plugin with Gradle Source: https://context7.com/wecode-ai/runvsagent/llms.txt Build the distributable plugin zip file using the Gradle build command. ```bash ./gradlew buildPlugin # produces the distributable .zip ``` -------------------------------- ### Run Full Test Suite Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Execute the complete test suite for the project. Ensure all tests pass before submitting changes. ```bash ./scripts/test.sh ``` -------------------------------- ### Build Project Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Execute the build script to compile the project in debug mode. ```bash ./scripts/build.sh --mode debug ``` -------------------------------- ### Verify PATH Configuration (Windows) Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Check your system's PATH environment variable on Windows to ensure Node.js is included. ```cmd echo %PATH% ``` -------------------------------- ### Create Extension Package Directory Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Use this command to create the necessary directory structure for a new extension within the project. ```bash mkdir -p src/main/kotlin/com/sina/weibo/agent/extensions/yourextension ``` -------------------------------- ### Run Extension Tests with Gradle Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Execute the extension tests using the Gradle wrapper. Specify the test class to run for focused testing. ```bash ./gradlew test --tests "com.sina.weibo.agent.extensions.ExtensionDecouplingTest" ``` -------------------------------- ### Initialize RPCManager for Extension Host Communication Source: https://context7.com/wecode-ai/runvsagent/llms.txt Create an RPCManager to wrap the PersistentProtocol socket and register necessary MainThread handlers. Call startInitialize() to push initial configuration and workspace state. ```typescript import { RPCManager } from './src/rpcManager.js'; import { ExtensionManager } from './src/extensionManager.js'; import { PersistentProtocol } from './vscode/vs/base/parts/ipc/common/ipc.net.js'; // Constructed once the extension host sends the "Initialized" message over the socket function createRPCManager( protocol: PersistentProtocol, extensionManager: ExtensionManager ): RPCManager { // Constructor registers: // setupDefaultProtocols() — errors, console, logger, commands, terminal, window, search, task, configuration, filesystem, language model tools // setupExtensionRequiredProtocols() — extension service, telemetry, debug service // setupRooCodeRequiredProtocols() — text editors, storage, output service, webview, URLs const rpcManager = new RPCManager(protocol, extensionManager); // Push empty ConfigurationModel and null workspace to the extension host // so it can complete its own initialization sequence rpcManager.startInitialize(); // Retrieve the underlying IRPCProtocol to call getProxy() for other interactions const rpcProtocol = rpcManager.getRPCProtocol(); console.log('RPC protocol ready:', rpcProtocol !== null); // true return rpcManager; } // --- RPC message format used internally --- // interface RpcMessage { id: string; method: string; params: unknown[]; timestamp: number; } // interface RpcResponse { id: string; result?: unknown; error?: RpcError; timestamp: number; } ``` -------------------------------- ### Enable JCEF via Custom VM Options Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Add this line to your IDE's VM options file to enable JCEF. Restart the IDE for changes to take effect. ```properties -Didea.browser.enable.jcef=true ``` -------------------------------- ### Run JetBrains Plugin in Development Mode Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Launch the JetBrains plugin in development mode using the Gradle wrapper. This command should be run from the jetbrains_plugin directory. ```bash # In another terminal, run JetBrains plugin in development mode cd jetbrains_plugin ./gradlew runIde ``` -------------------------------- ### Configure Extension via File Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Specify the desired AI extension by creating a `.vscode-agent` file in your project root. Supported values include `roo-code`, `cline`, `kilo-code`, and `costrict`. ```properties extension.type=roo-code ``` -------------------------------- ### Verify PATH Configuration (Linux/macOS) Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Check your system's PATH environment variable on Linux or macOS to ensure Node.js is included. ```bash echo $PATH ``` -------------------------------- ### Implement ExtensionManager (Kotlin) Source: https://context7.com/wecode-ai/runvsagent/llms.txt A project-scoped service that registers and manages ExtensionProvider implementations. It coordinates dynamic UI elements and configuration state, allowing switching between agents. ```kotlin // Register all providers on plugin startup class ExtensionManager(private val project: Project) { private val extensionProviders = mutableMapOf() private var currentProvider: ExtensionProvider? = null fun initialize(configuredExtensionId: String? = null) { registerExtensionProviders() // populates extensionProviders map configuredExtensionId?.let { setCurrentProvider(it) } } fun registerExtensionProvider(provider: ExtensionProvider) { extensionProviders[provider.getExtensionId()] = provider } // Switch to a different agent; refreshes buttons/menus automatically fun setCurrentProvider(extensionId: String, forceRestart: Boolean = false): Boolean { val provider = extensionProviders[extensionId] ?: return false if (!provider.isAvailable(project)) return false currentProvider = provider provider.initialize(project) // Refresh dynamic UI DynamicButtonManager.getInstance(project).refresh(provider) DynamicContextMenuManager.getInstance(project).refresh(provider) ExtensionConfigurationManager.setCurrentExtensionId(extensionId) // Broadcast so other components react (e.g., tool window title) project.messageBus.syncPublisher(ExtensionChangeListener.TOPIC) .onExtensionChanged(extensionId) return true } } ``` -------------------------------- ### Create and Push Git Tag Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Create an annotated Git tag for the release and push it to the origin. This marks the release version. ```bash git tag -a v1.2.0 -m "Release version 1.2.0" git push origin v1.2.0 ``` -------------------------------- ### Running Tests Command Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md This command is used to execute the test suite for the project. ```bash ```bash ``` -------------------------------- ### Make Scripts Executable and Check PATH Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Troubleshoot 'Command not found' errors by ensuring scripts have execute permissions and verifying that the script directory is included in your system's PATH environment variable. ```bash # Make scripts executable chmod +x scripts/*.sh # Check PATH echo $PATH ``` -------------------------------- ### JetBrains Plugin: Context Menu Integration (Kotlin) Source: https://context7.com/wecode-ai/runvsagent/llms.txt Implement `ContextMenuProvider` to declare right-click IDE actions for an agent. Optionally, attach agent commands directly to editor selections by returning concrete `AnAction` items. ```kotlin class ClineContextMenuProvider : ContextMenuProvider { // Controls which categories appear in the editor right-click menu override fun isActionVisible(actionType: ContextMenuActionType) = when (actionType) { ContextMenuActionType.EXPLAIN_CODE, ContextMenuActionType.FIX_CODE, ContextMenuActionType.IMPROVE_CODE, ContextMenuActionType.ADD_TO_CONTEXT, ContextMenuActionType.NEW_TASK -> true ContextMenuActionType.FIX_LOGIC -> false } // Optionally return concrete actions wired to agent commands override fun getContextMenuActions(project: Project): List = listOf( object : AnAction("Explain Code with Cline") { override fun actionPerformed(e: AnActionEvent) { val editor = e.getData(CommonDataKeys.EDITOR) ?: return val selected = editor.selectionModel.selectedText ?: return executeCommand("cline.explainCode", project, args = listOf(selected)) } }, object : AnAction("Add to Cline Context") { override fun actionPerformed(e: AnActionEvent) { executeCommand("cline.addToContext", project, hasArgs = false) } } ) } ``` -------------------------------- ### Run Tests with Different Options Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Execute tests using the provided script with various flags for different testing needs. ```bash ./scripts/test.sh ``` ```bash ./scripts/test.sh unit ``` ```bash ./scripts/test.sh integration ``` ```bash ./scripts/test.sh lint ``` ```bash ./scripts/test.sh --coverage ``` ```bash ./scripts/test.sh --watch ``` -------------------------------- ### Implement ExtensionProvider Interface Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Implement this interface to provide core information and lifecycle management for your extension. Ensure all methods are correctly implemented to integrate with the ExtensionManager. ```kotlin interface ExtensionProvider { fun getExtensionId(): String fun getDisplayName(): String fun getDescription(): String fun initialize(project: Project) fun isAvailable(project: Project): Boolean fun getConfiguration(project: Project): ExtensionConfiguration fun dispose() } ``` -------------------------------- ### Manually Configure PATH (Linux/macOS) Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Add this line to your shell profile file (e.g., .bashrc, .zshrc) to manually add Node.js to your PATH. Adjust the path as necessary. ```bash export PATH="/usr/local/nodejs/bin:$PATH" ``` -------------------------------- ### Initialize Cline Extension Provider Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/plugin_interation/example/EXAMPLE_INTEGRATION_EN.md Initializes the Cline extension configuration and the extension manager factory. Handles potential exceptions if the factory is not available, allowing Cline to function independently. ```kotlin class ClineExtensionProvider : ExtensionProvider { override fun getExtensionId(): String = "cline" override fun getDisplayName(): String = "Cline AI" override fun getDescription(): String = "AI-powered coding assistant with advanced features" override fun initialize(project: Project) { // Initialize cline extension configuration val extensionConfig = ExtensionConfiguration.getInstance(project) extensionConfig.initialize() // Initialize extension manager factory if needed try { val extensionManagerFactory = ExtensionManagerFactory.getInstance(project) extensionManagerFactory.initialize() } catch (e: Exception) { // If ExtensionManagerFactory is not available, continue without it // This allows cline to work independently } } } ``` -------------------------------- ### Define Extension Configuration Service Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Use this Kotlin service to manage your extension's configuration within a project. It provides methods to initialize and retrieve the current configuration. ```kotlin @Service(Service.Level.PROJECT) class YourExtensionConfiguration(private val project: Project) { companion object { fun getInstance(project: Project): YourExtensionConfiguration { return project.getService(YourExtensionConfiguration::class.java) ?: error("YourExtensionConfiguration not found") } } fun initialize() { // Initialize configuration } fun getCurrentConfig(): YourExtensionConfig { return YourExtensionConfig.getDefault() } } data class YourExtensionConfig( val codeDir: String, val displayName: String, val description: String, val publisher: String, val version: String, val mainFile: String, val activationEvents: List, val engines: Map, val capabilities: Map, val extensionDependencies: List ) { companion object { fun getDefault(): YourExtensionConfig { return YourExtensionConfig( codeDir = "your-extension", displayName = "Your Extension", description = "Your extension description", publisher = "YourPublisher", version = "1.0.0", mainFile = "./dist/extension.js", activationEvents = listOf("onStartupFinished"), engines = mapOf("vscode" to "^1.0.0"), capabilities = emptyMap(), extensionDependencies = emptyList() ) } } } ``` -------------------------------- ### Run Tests with Different Configurations Source: https://context7.com/wecode-ai/runvsagent/llms.txt Execute various test suites using the test script. Options include running all tests, linting only, unit tests, generating coverage reports, or using Jest watch mode. ```bash ./scripts/test.sh # all tests (lint + unit + integration) ``` ```bash ./scripts/test.sh lint # ktlint + ESLint only ``` ```bash ./scripts/test.sh unit # Jest (extension_host) + JUnit (jetbrains_plugin) ``` ```bash ./scripts/test.sh --coverage # generate coverage reports ``` ```bash ./scripts/test.sh --watch # Jest watch mode for TS ``` -------------------------------- ### Handle Cline Button Click Event Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/plugin_interation/example/EXAMPLE_INTEGRATION_EN.md Logs the button click event and checks for WebView availability before executing a command. Displays a warning dialog if no WebView instances are found. ```kotlin override fun actionPerformed(e: AnActionEvent) { val logger = Logger.getInstance(this::class.java) logger.info("🔍 Cline Plus button clicked, command: cline.plusButtonClicked") logger.info("🔍 Project: ${e.project?.name}") // Check WebView status before executing command val project = e.project if (project != null) { try { val webViewManager = project.getService(WebViewManager::class.java) if (webViewManager != null) { val latestWebView = webViewManager.getLatestWebView() if (latestWebView != null) { logger.info("✅ WebView instances available, executing command...") executeCommand("cline.plusButtonClicked", project, hasArgs = false) logger.info("✅ Command executed successfully") } else { logger.warn("⚠️ No WebView instances available") Messages.showWarningDialog( project, "No active WebView found. Please ensure the Cline extension is properly initialized.", "WebView Not Available" ) } ``` -------------------------------- ### YourExtensionConfiguration Service Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Manages the configuration for a specific extension within a project. ```APIDOC ## YourExtensionConfiguration Service ### Description Manages the configuration for a specific extension within a project. It provides methods to initialize the configuration and retrieve the current configuration settings. ### Methods - `getInstance(project: Project): YourExtensionConfiguration`: Retrieves the service instance for the given project. - `initialize()`: Initializes the extension configuration. - `getCurrentConfig(): YourExtensionConfig`: Returns the current configuration for the extension. ``` -------------------------------- ### Run JetBrains Plugin in Development Mode Source: https://github.com/wecode-ai/runvsagent/blob/main/README.md Commands to run the JetBrains plugin in development mode. Requires navigating to the jetbrains_plugin directory. ```bash cd jetbrains_plugin ./gradlew runIde ``` -------------------------------- ### Create Release Branch Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Command to create a new release branch for version management. ```bash # Create release branch git checkout -b release/v1.2.0 ``` -------------------------------- ### Build in Debug Mode using Script or Environment Variable Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Build the project in debug mode. This can be achieved by passing the `--mode debug` flag to the build script or by setting the `BUILD_MODE` environment variable. ```bash # Debug build ./scripts/build.sh --mode debug # Or set environment variable BUILD_MODE=debug ./scripts/build.sh ``` -------------------------------- ### Implement ExtensionProvider Interface Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Implement the `ExtensionProvider` interface to define the behavior and configuration of your custom AI extension. This includes providing extension details, initialization logic, availability checks, and configuration. ```kotlin // src/main/kotlin/com/sina/weibo/agent/extensions/yourextension/YourExtensionProvider.kt package com.sina.weibo.agent.extensions.yourextension import com.intellij.openapi.project.Project import com.sina.weibo.agent.extensions.ExtensionProvider class YourExtensionProvider : ExtensionProvider { override fun getExtensionId(): String = "your-extension" override fun getDisplayName(): String = "Your Extension" override fun getDescription(): String = "Your extension description" override fun initialize(project: Project) { // Initialize your extension } override fun isAvailable(project: Project): Boolean { val projectPath = project.basePath ?: return false return java.io.File("$projectPath/your-extension").exists() } override fun getConfiguration(project: Project): ExtensionConfiguration { return object : ExtensionConfiguration { override fun getCodeDir(): String = "your-extension" override fun getPublisher(): String = "YourPublisher" override fun getVersion(): String = "1.0.0" override fun getMainFile(): String = "./dist/extension.js" override fun getActivationEvents(): List = listOf("onStartupFinished") override fun getEngines(): Map = mapOf("vscode" to "^1.0.0") override fun getCapabilities(): Map = emptyMap() override fun getExtensionDependencies(): List = emptyList() } } override fun dispose() { // Cleanup resources } } ``` -------------------------------- ### Extension File Structure Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Organize your custom extension's files within a dedicated directory, including `package.json`, compiled JavaScript in `dist/`, and source files in `src/`. ```text your-extension/ ├── package.json ├── dist/ │ └── extension.js └── src/ └── extension.ts ``` -------------------------------- ### Test Script Syntax and Functionality Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Check the syntax of shell scripts using bash -n and shellcheck, and execute the main test suite. ```bash # Test script syntax bash -n scripts/script-name.sh ``` ```bash # Test with shellcheck (if available) shellcheck scripts/*.sh ``` ```bash # Test functionality ./scripts/test.sh ``` -------------------------------- ### Create Mock Extension Configuration Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Utility function to generate a mock ExtensionConfig object for testing purposes. Includes basic properties like name, version, and main entry point. ```typescript // extension_host/src/__tests__/mocks/index.ts export function mockExtensionConfig(): ExtensionConfig { return { name: 'test-extension', version: '1.0.0', main: './main.js', contributes: { commands: [ { command: 'test.command', title: 'Test Command' } ] } }; } export function createMockRpcChannel(): MockRpcChannel { return new MockRpcChannel(); } ``` -------------------------------- ### Clean Build Artifacts Source: https://context7.com/wecode-ai/runvsagent/llms.txt Manage build artifacts and dependencies using the clean script. Options range from removing build artifacts to a full, forceful clean. ```bash ./scripts/clean.sh # remove build artifacts ``` ```bash ./scripts/clean.sh deps # also remove node_modules and Gradle caches ``` ```bash ./scripts/clean.sh --force all # full clean, no confirmation ``` -------------------------------- ### Automated Code Formatting Commands Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Commands to format TypeScript and Kotlin code, and to check overall code linting. ```bash # Format TypeScript code cd extension_host npm run format # Format Kotlin code cd jetbrains_plugin ./gradlew ktlintFormat # Check formatting ./scripts/test.sh lint ``` -------------------------------- ### Enable JCEF via Custom Properties Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/KNOWN_ISSUES.md Add this line to your IDE's properties file to enable JCEF. Restart the IDE for changes to take effect. ```properties idea.browser.enable.jcef=true ``` -------------------------------- ### Activate Extension via ExtensionManager Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/plugin_interation/example/EXAMPLE_INTEGRATION_EN.md Activates a specified extension using the ExtensionManager and an RPC protocol. Handles extension not found errors and logs activation status. Converts a LazyPromise to a CompletableFuture for asynchronous handling. ```kotlin fun activateExtension(extensionId: String, rpcProtocol: IRPCProtocol): CompletableFuture { LOG.info("Activating extension: $extensionId") try { // Get extension description val extension = extensions[extensionId] if (extension == null) { LOG.error("Extension not found: $extensionId") val future = CompletableFuture() future.completeExceptionally(IllegalArgumentException("Extension not found: $extensionId")) return future } // Create activation parameters val activationParams = mapOf( "startup" to true, "extensionId" to extension.identifier, "activationEvent" to "api" ) // Get proxy of ExtHostExtensionServiceShape type val extHostService = rpcProtocol.getProxy(ServiceProxyRegistry.ExtHostContext.ExtHostExtensionService) try { // Get LazyPromise instance and convert it to CompletableFuture val lazyPromise = extHostService.activate(extension.identifier.value, activationParams) return lazyPromise.toCompletableFuture().thenApply { result -> val boolResult = when (result) { is Boolean -> result else -> false } LOG.info("Extension activation ${if (boolResult) "successful" else "failed"}: $extensionId") boolResult }.exceptionally { throwable -> LOG.error("Failed to activate extension: $extensionId", throwable) false } ``` -------------------------------- ### Register New Extension Provider Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Add your custom extension provider to the `ExtensionManager` by calling `registerExtensionProvider` with an instance of your provider class. ```kotlin // In ExtensionManager.kt private fun registerExtensionProviders() { // ... existing providers ... // Register your extension provider val yourProvider = com.sina.weibo.agent.extensions.yourextension.YourExtensionProvider() registerExtensionProvider(yourProvider) } ``` -------------------------------- ### Interact with ExtensionManager Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Use these Kotlin snippets to manage extensions through the ExtensionManager. Obtain instances, switch providers, and retrieve available or specific extension providers. ```kotlin // Get extension manager instance val extensionManager = ExtensionManager.getInstance(project) // Get current provider val currentProvider = extensionManager.getCurrentProvider() // Switch to different extension extensionManager.setCurrentProvider("xxxx") // Get all available providers val availableProviders = extensionManager.getAvailableProviders() // Get specific provider val rooProvider = extensionManager.getProvider("roo-code") ``` -------------------------------- ### Kotlin Good vs Bad Style Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Shows correct and incorrect usage of naming conventions and class structure in Kotlin. ```kotlin // ✅ Good class ExtensionHostManager( private val project: Project, private val logger: Logger ) { companion object { private const val DEFAULT_TIMEOUT = 5000L private const val MAX_RETRY_COUNT = 3 } suspend fun startExtensionHost(): Result { return try { val host = createExtensionHost() host.start() Result.success(host) } catch (e: Exception) { logger.error("Failed to start extension host", e) Result.failure(e) } } } // ❌ Bad class extensionhostmanager(project: Project, logger: Logger) { fun startExtensionHost(): ExtensionHost? { try { val host = createExtensionHost() host.start() return host } catch (e: Exception) { return null } } } ``` -------------------------------- ### Switch Extension Provider in Kotlin Source: https://github.com/wecode-ai/runvsagent/blob/main/docs/plugin_interation/example/EXAMPLE_INTEGRATION_EN.md Use `setCurrentProvider` to switch the active extension provider. Optionally, set `forceRestart` to true to ensure a full switch procedure, which restarts related processes and UI. This method invokes the new provider's `initialize` method and updates the configuration center. ```kotlin fun setCurrentProvider(extensionId: String, forceRestart: Boolean? = false): Boolean { val provider = extensionProviders[extensionId] if (provider != null && provider.isAvailable(project)) { val oldProvider = currentProvider if (forceRestart == false) { currentProvider = provider } // Initialize new provider (but don't restart the process) provider.initialize(project) ``` -------------------------------- ### ExtensionConfiguration Interface Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md Defines the structure for extension-specific configuration. ```APIDOC ## ExtensionConfiguration Interface ### Description Defines the interface for accessing extension-specific configuration properties. ### Methods - `getCodeDir(): String`: Returns the code directory for the extension. - `getPublisher(): String`: Returns the publisher of the extension. - `getVersion(): String`: Returns the version of the extension. - `getMainFile(): String`: Returns the main entry point file for the extension. - `getActivationEvents(): List`: Returns a list of events that activate the extension. - `getEngines(): Map`: Returns a map of supported engine versions. - `getCapabilities(): Map`: Returns a map of extension capabilities. - `getExtensionDependencies(): List`: Returns a list of other extensions this extension depends on. ``` -------------------------------- ### Create Feature Branch Source: https://github.com/wecode-ai/runvsagent/blob/main/CONTRIBUTING.md Steps to create a new feature branch, ensuring it's up-to-date with the main branch before branching. ```bash # Sync with upstream git fetch upstream git checkout main git merge upstream/main # Create and switch to a new branch git checkout -b feature/your-feature-name ``` -------------------------------- ### Build Script Debugging Modes Source: https://github.com/wecode-ai/runvsagent/blob/main/BUILD.md Utilize different flags and environment variables to control build script output and behavior for debugging purposes. ```bash # Verbose mode ./scripts/build.sh --verbose ``` ```bash # Dry run mode (show what would be done) ./scripts/build.sh --dry-run ``` ```bash # Debug environment VERBOSE=true ./scripts/build.sh ``` -------------------------------- ### Configure Agent Settings in .vscode-agent Source: https://github.com/wecode-ai/runvsagent/blob/main/jetbrains_plugin/README_EXTENSIONS.md This properties file is used to configure the agent and its extensions. Set extension types, debug modes, and extension-specific parameters like API endpoints and authentication tokens. ```properties # Extension type to use extension.type=roo-code # Debug mode debug.mode=idea debug.resource=/path/to/debug/resources # Extension-specific settings roo.debug.enabled=false roo.api.endpoint=https://api.roo-code.com copilot.auth.token=your_github_token copilot.auto_suggest=true claude.api.key=your_anthropic_api_key claude.model=claude-3-sonnet-20240229 ```