diff --git a/gradle.properties b/gradle.properties
index 3426d92392..04f63453d4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -10,7 +10,7 @@ pluginRepositoryUrl = https://github.com/unit-mesh/auto-dev
pluginVersion = 2.4.6
# MPP Unified Version (mpp-core, mpp-ui, mpp-server)
-mppVersion = 0.3.3
+mppVersion = 0.3.4
# Supported IDEs: idea, pycharm
baseIDE=idea
diff --git a/mpp-ui/package.json b/mpp-ui/package.json
index acd01a6ee0..1d84ac95de 100644
--- a/mpp-ui/package.json
+++ b/mpp-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@autodev/cli",
- "version": "0.3.3",
+ "version": "0.3.4",
"description": "AutoDev CLI - Terminal UI for AI-powered development assistant",
"type": "module",
"bin": {
diff --git a/mpp-ui/package.json.backup b/mpp-ui/package.json.backup
new file mode 100644
index 0000000000..1d84ac95de
--- /dev/null
+++ b/mpp-ui/package.json.backup
@@ -0,0 +1,82 @@
+{
+ "name": "@autodev/cli",
+ "version": "0.3.4",
+ "description": "AutoDev CLI - Terminal UI for AI-powered development assistant",
+ "type": "module",
+ "bin": {
+ "autodev": "./dist/jsMain/typescript/index.js"
+ },
+ "scripts": {
+ "build:kotlin": "cd .. && ./gradlew :mpp-core:assembleJsPackage",
+ "build:kotlin-deps": "cd ../mpp-core/build/packages/js && npm install --ignore-scripts",
+ "build:ts": "cd .. && ./gradlew :mpp-ui:compileKotlinJs && cd mpp-ui && tsc && chmod +x dist/jsMain/typescript/index.js",
+ "build": "npm run build:kotlin && npm run build:kotlin-deps && npm run build:ts",
+ "dev": "tsc --watch",
+ "start": "node dist/jsMain/typescript/index.js",
+ "code": "node dist/jsMain/typescript/index.js code",
+ "test": "vitest run",
+ "test:unit": "vitest run src/jsMain/typescript/**/*.test.ts",
+ "test:git": "npm run build:kotlin && node ../docs/test-scripts/test-git-nodejs.js",
+ "test:cli": "node test-cli-completion.js",
+ "test:all": "npm test && npm run test:completion && npm run test:cli",
+ "test:ci": "npm run build && npm run test:integration",
+ "test:framework": "node src/test/framework/validate-structure.cjs",
+ "test:integration-v2": "npm run build:ts && npm test src/test/integration-v2 -- --reporter=verbose",
+ "test:json-scenarios": "npm run build:ts && npm test src/test/integration-v2/json-scenarios.test.ts -- --reporter=verbose",
+ "analyze-test-results": "node scripts/analyze-test-results.cjs",
+ "generate:scenario:interactive": "node scripts/generate-test-scenario.js --interactive",
+ "validate:scenarios": "node scripts/validate-scenarios.js",
+ "clean": "rm -rf dist build",
+ "icon:convert": "bash scripts/convert-icon.sh && python3 scripts/convert-icon-windows.py",
+ "prepublish:local": "npm run build",
+ "publish:local": "node scripts/publish-local.js",
+ "prepublish:remote": "npm run build",
+ "publish:remote": "node scripts/publish-remote.js",
+ "postinstall": "node scripts/check-mpp-core.js || echo 'Warning: mpp-core not found, run npm run build:kotlin first'"
+ },
+ "packageManager": "pnpm@10.20.0",
+ "keywords": [
+ "ai",
+ "cli",
+ "terminal",
+ "coding-assistant",
+ "autodev",
+ "tui"
+ ],
+ "author": "AutoDev Team",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "dependencies": {
+ "@autodev/mpp-core": "file:../mpp-core/build/packages/js",
+ "@js-joda/core": "^5.6.5",
+ "@modelcontextprotocol/sdk": "^1.0.4",
+ "@unit-mesh/treesitter-artifacts": "^1.7.7",
+ "chalk": "^5.3.0",
+ "commander": "^12.1.0",
+ "diff": "^7.0.0",
+ "dotenv": "^16.4.5",
+ "highlight.js": "^11.11.1",
+ "ink": "^5.0.1",
+ "ink-select-input": "^6.0.0",
+ "ink-spinner": "^5.0.0",
+ "ink-text-input": "^6.0.0",
+ "node-fetch": "^3.3.2",
+ "react": "^18.3.1",
+ "web-tree-sitter": "^0.22.2",
+ "yaml": "^2.6.1"
+ },
+ "devDependencies": {
+ "@types/diff": "^6.0.0",
+ "@types/node": "^20.11.24",
+ "@types/react": "^18.3.12",
+ "ink-testing-library": "^4.0.0",
+ "typescript": "^5.3.3",
+ "vitest": "^2.1.8"
+ },
+ "files": [
+ "dist/",
+ "README.md"
+ ]
+}
diff --git a/mpp-vscode/.vscodeignore b/mpp-vscode/.vscodeignore
new file mode 100644
index 0000000000..9682a7483e
--- /dev/null
+++ b/mpp-vscode/.vscodeignore
@@ -0,0 +1,32 @@
+# VSCode extension ignore file
+# Exclude source files and build artifacts not needed in the packaged extension
+
+# Source files
+src/
+webview/src/
+webview/node_modules/
+
+# Build artifacts
+*.map
+tsconfig.json
+.eslintrc.json
+
+# Development files
+.vscode/
+node_modules/
+.gitignore
+.git/
+
+# Test files
+**/__tests__/**
+**/*.test.*
+**/*.spec.*
+
+# Documentation
+README.md
+CHANGELOG.md
+
+# Keep dist and wasm folders
+!dist/
+!wasm/
+
diff --git a/mpp-vscode/README.md b/mpp-vscode/README.md
index e7febba66f..95df1b59d2 100644
--- a/mpp-vscode/README.md
+++ b/mpp-vscode/README.md
@@ -1,139 +1,165 @@
-# mpp-vscode
+
+
+
+AutoDev for VSCode (KMP Edition)
+
+
+
+
+
+
+
+
+
+> 🧙 AI-powered coding wizard with multilingual support 🌐, auto code generation 🏗️, and a helpful bug-slaying assistant 🐞! Built with **Kotlin Multiplatform** for cross-platform capabilities. 🚀
+
+This is the **Kotlin Multiplatform (KMP) edition** of AutoDev, rewritten from the ground up to leverage Kotlin's cross-platform capabilities for future iOS, Android, and Desktop support.
+
+## 🌟 Key Features
+
+- **💬 Chat Mode**: Interactive AI assistant with context-aware code understanding
+- **🔍 CodeLens**: Inline AI actions above functions and classes
+ - Quick Chat, Explain Code, Optimize Code
+ - Auto Comment, Auto Test, Auto Method
+- **🧪 Auto Test Generation**: Generate unit tests with Tree-sitter AST parsing
+- **📝 Auto Documentation**: Generate JSDoc/DocString comments
+- **🔧 Code Actions**: Explain, optimize, and fix code with AI
+- **🤖 Agent Support**: Extensible agent system via MCP (Model Context Protocol)
+- **🌐 Multi-LLM Support**: OpenAI, Anthropic, Google, DeepSeek, Ollama, OpenRouter
+
+## 🚀 Quick Start
+
+1. **Install the Extension**: Search for "AutoDev" in VSCode Marketplace
+2. **Configure LLM Provider**: Open Settings → AutoDev → Set your API key and model
+3. **Start Coding**: Press `Cmd+Shift+A` (Mac) / `Ctrl+Shift+A` (Windows/Linux) to open chat
+
+## 📖 Configuration
+
+### LLM Provider Setup
+
+```json
+{
+ "autodev.provider": "openai",
+ "autodev.model": "gpt-4o-mini",
+ "autodev.apiKey": "your-api-key-here"
+}
+```
+
+### CodeLens Settings
+
+```json
+{
+ "autodev.codelens.enable": true,
+ "autodev.codelens.displayMode": "expand",
+ "autodev.codelens.items": [
+ "quickChat",
+ "autoTest",
+ "autoComment"
+ ]
+}
+```
+
+## 🏗️ Architecture (Kotlin Multiplatform)
-基于 Kotlin Multiplatform (KMP) 的 VSCode 扩展,复用 mpp-core 的核心能力。
+This version is built with:
-## 架构概述
+- **mpp-core**: Kotlin Multiplatform core library (shared logic)
+- **mpp-vscode**: VSCode extension (TypeScript + mpp-core via JS bindings)
+- **Tree-sitter**: Accurate code parsing for 8 languages (TS, JS, Python, Java, Kotlin, Go, Rust, etc.)
+- **MCP Protocol**: Model Context Protocol for IDE server integration
+
+### Project Structure
```
mpp-vscode/
-├── package.json # VSCode 扩展配置
-├── src/
-│ ├── extension.ts # 入口点
-│ ├── services/
-│ │ ├── ide-server.ts # MCP 协议服务器
-│ │ ├── diff-manager.ts # Diff 管理
-│ │ └── chat-service.ts # Chat 服务
-│ ├── providers/
-│ │ ├── chat-view.ts # Webview Provider
-│ │ └── diff-content.ts # Diff Content Provider
-│ ├── commands/
-│ │ └── index.ts # 命令注册
-│ └── bridge/
-│ └── mpp-core.ts # mpp-core 桥接层
-├── webview/ # Webview UI
-│ ├── src/
-│ │ ├── App.tsx
-│ │ └── components/
-│ └── package.json
-└── tsconfig.json
+├── src/ # TypeScript extension code
+│ ├── extension.ts # Main entry point
+│ ├── providers/ # CodeLens, Chat providers
+│ ├── services/ # IDE Server, Diff Manager
+│ └── commands/ # CodeLens commands
+├── webview/ # React-based chat UI
+├── dist/ # Build output
+│ └── wasm/ # Tree-sitter WASM files
+└── scripts/ # Build scripts
```
-## TODO List
-
-### Phase 1: 项目基础设施 ✅
-- [x] 创建项目目录结构
-- [x] 创建 package.json (VSCode 扩展配置)
-- [x] 创建 tsconfig.json
-- [x] 配置 esbuild 打包
-- [x] 配置 vitest 测试框架
-
-### Phase 2: 核心服务 ✅
-- [x] 实现 mpp-core 桥接层 (`src/bridge/mpp-core.ts`)
- - [x] 导入 @autodev/mpp-core
- - [x] 封装 LLMService (JsKoogLLMService)
- - [x] 封装 CodingAgent (JsCodingAgent)
- - [x] 封装 ToolRegistry (JsToolRegistry)
- - [x] 封装 CompletionManager (JsCompletionManager)
- - [x] 封装 DevInsCompiler (JsDevInsCompiler)
-- [x] 实现 extension.ts 入口
- - [x] 扩展激活/停用
- - [x] 服务初始化
-- [x] 添加单元测试 (`test/bridge/mpp-core.test.ts`)
-
-### Phase 3: IDE 集成 ✅
-- [x] 实现 IDE Server (MCP 协议)
- - [x] Express HTTP 服务器
- - [x] 端点: /health, /context, /diff/open, /diff/close, /file/read, /file/write
- - [x] 认证和 CORS 保护
- - [x] 端口文件写入 (~/.autodev/ide-server.json)
-- [x] 实现 Diff Manager
- - [x] showDiff() - 显示差异
- - [x] acceptDiff() - 接受更改
- - [x] cancelDiff() - 取消更改
- - [x] closeDiffByPath() - 按路径关闭
- - [x] DiffContentProvider
-- [x] 添加单元测试 (`test/services/`)
-
-### Phase 4: Chat 界面 ✅
-- [x] 实现 Chat Webview Provider
- - [x] Webview 创建和管理
- - [x] 消息桥接 (VSCode ↔ Webview)
- - [x] LLM 服务集成
-- [x] 创建 Webview UI (内嵌 HTML)
- - [x] 聊天消息组件
- - [x] 输入框组件
- - [x] 流式响应显示
-
-### Phase 5: 命令和功能 ✅
-- [x] 注册 VSCode 命令
- - [x] autodev.chat - 打开聊天
- - [x] autodev.acceptDiff - 接受差异
- - [x] autodev.cancelDiff - 取消差异
- - [x] autodev.runAgent - 运行 Agent
-- [x] 快捷键绑定 (Cmd+Shift+A)
-- [x] 状态栏集成
-
-### Phase 6: 高级功能 ✅
-- [x] DevIns 语言支持
- - [x] 语法高亮 (TextMate grammar)
- - [x] 自动补全 (/, @, $ 触发)
-- [x] React Webview UI
- - [x] React + Vite 构建
- - [x] Markdown 渲染 (react-markdown + remark-gfm)
- - [x] VSCode 主题集成
- - [x] 流式响应动画
-- [ ] 代码索引集成
-- [ ] 领域词典支持
-
-## 参考项目
-
-1. **autodev-vscode** - 早期 AutoDev VSCode 版本,全功能实现
-2. **gemini-cli/vscode-ide-companion** - Gemini 的轻量级 MCP 桥接器
-3. **mpp-ui** - 现有的 CLI 工具,展示如何使用 mpp-core
-
-## 开发指南
-
-### 构建 mpp-core
+## 🔌 Supported Languages
-```bash
-cd /Volumes/source/ai/autocrud
-./gradlew :mpp-core:assembleJsPackage
-```
+CodeLens and code parsing support:
-### 安装依赖
+- TypeScript/JavaScript (including React/TSX)
+- Python
+- Java
+- Kotlin
+- Go
+- Rust
+
+## 🛠️ Development
+
+### Prerequisites
+
+- Node.js 18+
+- VSCode 1.77+
+
+### Build from Source
```bash
+# Install dependencies
cd mpp-vscode
npm install
-```
-### 开发模式
+# Build
+npm run build
-```bash
+# Watch mode
npm run watch
-```
-### 打包扩展
-
-```bash
+# Package extension
npm run package
```
-## 技术栈
+## 📚 Documentation
+
+- **Official Docs**: [https://vscode.unitmesh.cc/](https://vscode.unitmesh.cc/)
+- **JetBrains IDE Version**: [https://github.com/unit-mesh/auto-dev](https://github.com/unit-mesh/auto-dev)
+- **Contributing**: [https://vscode.unitmesh.cc/development](https://vscode.unitmesh.cc/development)
+
+## 🤝 Join the Community
+
+
+
+If you are interested in AutoDev, you can join our WeChat group by scanning the QR code above.
+
+(如果群二维码过期,可以添加我的微信号:`phodal02`,注明 `AutoDev`,我拉你入群)
+
+## 📋 Feature Comparison
+
+| Feature | KMP Edition | Original VSCode |
+|------------------------|-------------|-----------------|
+| Chat mode | ✅ | ✅ |
+| CodeLens | ✅ | ✅ |
+| AutoDoc | ✅ | ✅ |
+| AutoTest | ✅ | ✅ |
+| Tree-sitter Parsing | ✅ | ✅ |
+| MCP Protocol | ✅ | ❌ |
+| Cross-platform Core | ✅ (KMP) | ❌ |
+| iOS Support (Future) | 🚧 | ❌ |
+| Android Support (Future)| 🚧 | ❌ |
+
+## 🎯 Roadmap
+
+- [x] Basic Chat functionality
+- [x] CodeLens with Tree-sitter
+- [x] Auto Test/Doc/Method
+- [x] Multi-LLM support
+- [ ] Enhanced agent system
+- [ ] iOS/Android support (via KMP)
+- [ ] Desktop standalone app
+
+## 📄 License
+
+Apache-2.0
-- **TypeScript** - 主要开发语言
-- **mpp-core (Kotlin/JS)** - 核心 LLM 和 Agent 能力
-- **React** - Webview UI
-- **Express** - MCP 服务器
-- **esbuild** - 打包工具
+## 🙏 Acknowledgments
+Built on the foundation of [AutoDev VSCode](https://github.com/unit-mesh/auto-dev-vscode), reimagined with Kotlin Multiplatform for next-generation cross-platform AI coding assistance.
diff --git a/mpp-vscode/media/autodev-dark.svg b/mpp-vscode/media/autodev-dark.svg
new file mode 100644
index 0000000000..468b267be6
--- /dev/null
+++ b/mpp-vscode/media/autodev-dark.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/mpp-vscode/media/autodev.woff b/mpp-vscode/media/autodev.woff
new file mode 100644
index 0000000000..58b206cdb6
Binary files /dev/null and b/mpp-vscode/media/autodev.woff differ
diff --git a/mpp-vscode/media/icon.svg b/mpp-vscode/media/icon.svg
new file mode 100644
index 0000000000..c8927a0a72
--- /dev/null
+++ b/mpp-vscode/media/icon.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/mpp-vscode/media/pluginIcon.png b/mpp-vscode/media/pluginIcon.png
new file mode 100644
index 0000000000..acc84e5ede
Binary files /dev/null and b/mpp-vscode/media/pluginIcon.png differ
diff --git a/mpp-vscode/package.json b/mpp-vscode/package.json
index 86f202abfb..736117ca9e 100644
--- a/mpp-vscode/package.json
+++ b/mpp-vscode/package.json
@@ -1,31 +1,57 @@
{
- "name": "autodev-vscode",
- "displayName": "AutoDev",
- "description": "AI-powered coding assistant based on Kotlin Multiplatform",
- "version": "0.1.0",
- "publisher": "phodal",
+ "name": "autodev",
+ "displayName": "AutoDev - 🧙the AI-powered coding wizard (KMP Edition).",
+ "description": "🧙 AI-powered coding wizard with multilingual support 🌐, auto code generation 🏗️, based on Kotlin Multiplatform. AutoDev provides CodeLens, Chat, and powerful agent features! 🚀",
+ "version": "0.5.3",
+ "publisher": "Phodal",
"license": "Apache-2.0",
"repository": {
"type": "git",
- "url": "https://github.com/phodal/auto-dev-sketch"
+ "url": "https://github.com/unit-mesh/auto-dev-vscode"
},
+ "bugs": {
+ "url": "https://github.com/unit-mesh/auto-dev-vscode/issues"
+ },
+ "homepage": "https://vscode.unitmesh.cc",
+ "qna": "https://github.com/unit-mesh/auto-dev-vscode/issues/new/choose",
+ "pricing": "Free",
+ "icon": "media/pluginIcon.png",
"engines": {
"vscode": "^1.85.0"
},
+ "vsce": {
+ "dependencies": true,
+ "yarn": false
+ },
"categories": [
"Programming Languages",
+ "Education",
"Machine Learning",
- "Other"
+ "Snippets"
],
"keywords": [
"ai",
"coding assistant",
"llm",
- "autodev"
+ "autodev",
+ "kotlin multiplatform",
+ "kmp"
],
"activationEvents": [
+ "onLanguage:java",
+ "onLanguage:javascript",
+ "onLanguage:kotlin",
+ "onLanguage:typescript",
+ "onLanguage:typescriptreact",
+ "onLanguage:python",
+ "onLanguage:rust",
+ "onLanguage:go",
"onStartupFinished"
],
+ "extensionKind": [
+ "ui",
+ "workspace"
+ ],
"main": "./dist/extension.js",
"contributes": {
"commands": [
@@ -44,6 +70,34 @@
{
"command": "autodev.runAgent",
"title": "AutoDev: Run Coding Agent"
+ },
+ {
+ "command": "autodev.codelens.quickChat",
+ "title": "AutoDev: Quick Chat"
+ },
+ {
+ "command": "autodev.codelens.explainCode",
+ "title": "AutoDev: Explain Code"
+ },
+ {
+ "command": "autodev.codelens.optimizeCode",
+ "title": "AutoDev: Optimize Code"
+ },
+ {
+ "command": "autodev.codelens.autoComment",
+ "title": "AutoDev: Auto Comment"
+ },
+ {
+ "command": "autodev.codelens.autoTest",
+ "title": "AutoDev: Auto Test"
+ },
+ {
+ "command": "autodev.codelens.autoMethod",
+ "title": "AutoDev: Auto Method"
+ },
+ {
+ "command": "autodev.codelens.showMenu",
+ "title": "AutoDev: Show CodeLens Menu"
}
],
"viewsContainers": {
@@ -99,6 +153,44 @@
"type": "number",
"default": 23120,
"description": "Port for the IDE server (MCP protocol)"
+ },
+ "autodev.codelens.enable": {
+ "type": "boolean",
+ "default": true,
+ "description": "Enable CodeLens to show AI actions above functions and classes"
+ },
+ "autodev.codelens.displayMode": {
+ "type": "string",
+ "default": "expand",
+ "enum": [
+ "expand",
+ "collapse"
+ ],
+ "enumDescriptions": [
+ "Show all actions separately",
+ "Show a collapsed menu"
+ ],
+ "description": "CodeLens display mode"
+ },
+ "autodev.codelens.items": {
+ "type": "array",
+ "default": [
+ "quickChat",
+ "autoTest",
+ "autoComment"
+ ],
+ "items": {
+ "type": "string",
+ "enum": [
+ "quickChat",
+ "explainCode",
+ "optimizeCode",
+ "autoComment",
+ "autoTest",
+ "autoMethod"
+ ]
+ },
+ "description": "CodeLens items to display"
}
}
},
@@ -137,9 +229,10 @@
},
"scripts": {
"vscode:prepublish": "npm run build",
- "build": "npm run build:extension && npm run build:webview",
- "build:extension": "esbuild ./src/extension.ts --bundle --outfile=dist/extension.js --external:vscode --external:ws --format=cjs --platform=node",
+ "build": "npm run build:extension && npm run build:webview && npm run copy:wasm",
+ "build:extension": "esbuild ./src/extension.ts --bundle --outfile=dist/extension.js --external:vscode --external:ws --external:web-tree-sitter --format=cjs --platform=node",
"build:webview": "cd webview && npm install && npm run build",
+ "copy:wasm": "node scripts/copy-wasm.js",
"watch": "npm run build:extension -- --watch",
"package": "vsce package",
"lint": "eslint src --ext ts",
@@ -160,10 +253,12 @@
"vitest": "^1.0.0"
},
"dependencies": {
- "@autodev/mpp-core": "file:../mpp-core/build/packages/js",
+ "@autodev/mpp-core": "0.3.4",
"@modelcontextprotocol/sdk": "^1.0.0",
+ "@unit-mesh/treesitter-artifacts": "^1.7.7",
"cors": "^2.8.5",
"express": "^4.18.2",
+ "web-tree-sitter": "^0.25.10",
"yaml": "^2.8.2",
"zod": "^3.22.4"
}
diff --git a/mpp-vscode/scripts/copy-wasm.js b/mpp-vscode/scripts/copy-wasm.js
new file mode 100644
index 0000000000..e28f2b9fb9
--- /dev/null
+++ b/mpp-vscode/scripts/copy-wasm.js
@@ -0,0 +1,49 @@
+#!/usr/bin/env node
+/**
+ * Copy WASM files from @unit-mesh/treesitter-artifacts to dist/wasm
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+const sourceDir = path.join(__dirname, '../node_modules/@unit-mesh/treesitter-artifacts/wasm');
+const targetDir = path.join(__dirname, '../dist/wasm');
+
+// Create target directory if it doesn't exist
+if (!fs.existsSync(targetDir)) {
+ fs.mkdirSync(targetDir, { recursive: true });
+}
+
+// List of required WASM files
+const wasmFiles = [
+ 'tree-sitter-typescript.wasm',
+ 'tree-sitter-tsx.wasm',
+ 'tree-sitter-javascript.wasm',
+ 'tree-sitter-python.wasm',
+ 'tree-sitter-java.wasm',
+ 'tree-sitter-kotlin.wasm',
+ 'tree-sitter-go.wasm',
+ 'tree-sitter-rust.wasm'
+];
+
+// Copy each WASM file
+let copiedCount = 0;
+for (const file of wasmFiles) {
+ const sourcePath = path.join(sourceDir, file);
+ const targetPath = path.join(targetDir, file);
+
+ try {
+ if (fs.existsSync(sourcePath)) {
+ fs.copyFileSync(sourcePath, targetPath);
+ console.log(`✓ Copied ${file}`);
+ copiedCount++;
+ } else {
+ console.warn(`⚠ Warning: ${file} not found in source directory`);
+ }
+ } catch (error) {
+ console.error(`✗ Failed to copy ${file}: ${error.message}`);
+ }
+}
+
+console.log(`\nCopied ${copiedCount}/${wasmFiles.length} WASM files to dist/wasm/`);
+
diff --git a/mpp-vscode/src/actions/auto-actions.ts b/mpp-vscode/src/actions/auto-actions.ts
new file mode 100644
index 0000000000..d3dfef876d
--- /dev/null
+++ b/mpp-vscode/src/actions/auto-actions.ts
@@ -0,0 +1,254 @@
+/**
+ * Auto Actions - AutoComment, AutoTest, AutoMethod implementations
+ *
+ * Based on autodev-vscode's action executors, adapted for mpp-vscode.
+ */
+
+import * as vscode from 'vscode';
+import { CodeElement } from '../providers/code-element-parser';
+import { LLMService, ModelConfig } from '../bridge/mpp-core';
+import { DiffManager } from '../services/diff-manager';
+import {
+ generateAutoDocPrompt,
+ generateAutoTestPrompt,
+ generateAutoMethodPrompt,
+ parseCodeBlock,
+ LANGUAGE_COMMENT_MAP,
+ getTestFramework,
+ getTestFilePath,
+ AutoDocContext,
+ AutoTestContext,
+ AutoMethodContext
+} from '../prompts/prompt-templates';
+
+export interface ActionContext {
+ document: vscode.TextDocument;
+ element: CodeElement;
+ config: ModelConfig;
+ log: (message: string) => void;
+}
+
+/**
+ * Execute AutoComment action - generates documentation comments
+ */
+export async function executeAutoComment(context: ActionContext): Promise {
+ const { document, element, config, log } = context;
+ const language = document.languageId;
+
+ log(`AutoComment: Generating documentation for ${element.name}`);
+
+ const commentSymbols = LANGUAGE_COMMENT_MAP[language] || { start: '/**', end: '*/' };
+
+ const promptContext: AutoDocContext = {
+ language,
+ code: element.code,
+ startSymbol: commentSymbols.start,
+ endSymbol: commentSymbols.end,
+ };
+
+ const prompt = generateAutoDocPrompt(promptContext);
+
+ try {
+ await vscode.window.withProgress({
+ location: vscode.ProgressLocation.Notification,
+ title: `Generating documentation for ${element.name}...`,
+ cancellable: true
+ }, async (progress, token) => {
+ const llmService = new LLMService(config);
+
+ let response = '';
+ await llmService.streamMessage(prompt, (chunk) => {
+ response += chunk;
+ progress.report({ message: 'Generating...' });
+ });
+
+ if (token.isCancellationRequested) return;
+
+ const docComment = parseCodeBlock(response, language);
+ if (!docComment) {
+ vscode.window.showWarningMessage('Failed to generate documentation');
+ return;
+ }
+
+ const formattedDoc = formatDocComment(docComment, document, element);
+ const insertPosition = new vscode.Position(element.bodyRange.start.line, 0);
+
+ const diffManager = new DiffManager(log);
+ const originalContent = document.getText();
+ const newContent = insertTextAtPosition(originalContent, formattedDoc, document.offsetAt(insertPosition));
+
+ await diffManager.showDiff(document.uri.fsPath, originalContent, newContent);
+ log(`AutoComment: Documentation generated for ${element.name}`);
+ });
+ } catch (error) {
+ const message = error instanceof Error ? error.message : String(error);
+ log(`AutoComment error: ${message}`);
+ vscode.window.showErrorMessage(`Failed to generate documentation: ${message}`);
+ }
+}
+
+/**
+ * Execute AutoTest action - generates unit tests
+ */
+export async function executeAutoTest(context: ActionContext): Promise {
+ const { document, element, config, log } = context;
+ const language = document.languageId;
+
+ log(`AutoTest: Generating tests for ${element.name}`);
+
+ const promptContext: AutoTestContext = {
+ language,
+ sourceCode: element.code,
+ className: element.type === 'structure' ? element.name : undefined,
+ methodName: element.type === 'method' ? element.name : undefined,
+ testFramework: getTestFramework(language),
+ isNewFile: true,
+ };
+
+ const prompt = generateAutoTestPrompt(promptContext);
+
+ try {
+ await vscode.window.withProgress({
+ location: vscode.ProgressLocation.Notification,
+ title: `Generating tests for ${element.name}...`,
+ cancellable: true
+ }, async (progress, token) => {
+ const llmService = new LLMService(config);
+
+ let response = '';
+ await llmService.streamMessage(prompt, (chunk) => {
+ response += chunk;
+ progress.report({ message: 'Generating...' });
+ });
+
+ if (token.isCancellationRequested) return;
+
+ const testCode = parseCodeBlock(response, language);
+ if (!testCode) {
+ vscode.window.showWarningMessage('Failed to generate test code');
+ return;
+ }
+
+ const testFilePath = getTestFilePath(document.uri.fsPath, language);
+ const testFileUri = vscode.Uri.file(testFilePath);
+
+ let existingContent = '';
+ try {
+ const existingDoc = await vscode.workspace.openTextDocument(testFileUri);
+ existingContent = existingDoc.getText();
+ } catch { /* File doesn't exist */ }
+
+ const diffManager = new DiffManager(log);
+ if (existingContent) {
+ const newContent = existingContent + '\n\n' + testCode;
+ await diffManager.showDiff(testFilePath, existingContent, newContent);
+ } else {
+ await diffManager.showDiff(testFilePath, '', testCode);
+ }
+
+ log(`AutoTest: Tests generated for ${element.name}`);
+ });
+ } catch (error) {
+ const message = error instanceof Error ? error.message : String(error);
+ log(`AutoTest error: ${message}`);
+ vscode.window.showErrorMessage(`Failed to generate tests: ${message}`);
+ }
+}
+
+/**
+ * Execute AutoMethod action - generates method implementation
+ */
+export async function executeAutoMethod(context: ActionContext): Promise {
+ const { document, element, config, log } = context;
+ const language = document.languageId;
+
+ log(`AutoMethod: Generating implementation for ${element.name}`);
+
+ const promptContext: AutoMethodContext = {
+ language,
+ code: element.code,
+ methodSignature: extractMethodSignature(element.code),
+ className: findContainingClass(document, element),
+ };
+
+ const prompt = generateAutoMethodPrompt(promptContext);
+
+ try {
+ await vscode.window.withProgress({
+ location: vscode.ProgressLocation.Notification,
+ title: `Generating implementation for ${element.name}...`,
+ cancellable: true
+ }, async (progress, token) => {
+ const llmService = new LLMService(config);
+
+ let response = '';
+ await llmService.streamMessage(prompt, (chunk) => {
+ response += chunk;
+ progress.report({ message: 'Generating...' });
+ });
+
+ if (token.isCancellationRequested) return;
+
+ const methodCode = parseCodeBlock(response, language);
+ if (!methodCode) {
+ vscode.window.showWarningMessage('Failed to generate method implementation');
+ return;
+ }
+
+ const diffManager = new DiffManager(log);
+ const originalContent = document.getText();
+ const newContent = replaceMethodBody(originalContent, element, methodCode, document);
+
+ await diffManager.showDiff(document.uri.fsPath, originalContent, newContent);
+ log(`AutoMethod: Implementation generated for ${element.name}`);
+ });
+ } catch (error) {
+ const message = error instanceof Error ? error.message : String(error);
+ log(`AutoMethod error: ${message}`);
+ vscode.window.showErrorMessage(`Failed to generate implementation: ${message}`);
+ }
+}
+
+// Helper functions
+
+function formatDocComment(docComment: string, document: vscode.TextDocument, element: CodeElement): string {
+ const line = document.lineAt(element.bodyRange.start.line);
+ const indent = line.text.substring(0, line.firstNonWhitespaceCharacterIndex);
+
+ let formatted = docComment.trim();
+ if (!formatted.endsWith('\n')) formatted += '\n';
+
+ const lines = formatted.split('\n');
+ return lines.map(l => l ? indent + l : l).join('\n');
+}
+
+function insertTextAtPosition(content: string, text: string, position: number): string {
+ return content.substring(0, position) + text + content.substring(position);
+}
+
+function extractMethodSignature(code: string): string {
+ const lines = code.split('\n');
+ const signatureLines: string[] = [];
+ for (const line of lines) {
+ signatureLines.push(line);
+ if (line.includes('{') || line.includes(':')) break;
+ }
+ return signatureLines.join('\n').trim();
+}
+
+function findContainingClass(document: vscode.TextDocument, element: CodeElement): string | undefined {
+ const text = document.getText(new vscode.Range(new vscode.Position(0, 0), element.bodyRange.start));
+ const classMatch = text.match(/class\s+(\w+)/g);
+ if (classMatch && classMatch.length > 0) {
+ const lastMatch = classMatch[classMatch.length - 1];
+ const nameMatch = lastMatch.match(/class\s+(\w+)/);
+ return nameMatch ? nameMatch[1] : undefined;
+ }
+ return undefined;
+}
+
+function replaceMethodBody(content: string, element: CodeElement, newMethodCode: string, document: vscode.TextDocument): string {
+ const startOffset = document.offsetAt(element.bodyRange.start);
+ const endOffset = document.offsetAt(element.bodyRange.end);
+ return content.substring(0, startOffset) + newMethodCode + content.substring(endOffset);
+}
diff --git a/mpp-vscode/src/commands/codelens-commands.ts b/mpp-vscode/src/commands/codelens-commands.ts
new file mode 100644
index 0000000000..1520ae44a6
--- /dev/null
+++ b/mpp-vscode/src/commands/codelens-commands.ts
@@ -0,0 +1,254 @@
+/**
+ * CodeLens 命令实现
+ *
+ * 实现 CodeLens 点击后的各种操作
+ */
+
+import * as vscode from 'vscode';
+import { CodeElement } from '../providers/code-element-parser';
+import { executeAutoComment, executeAutoTest, executeAutoMethod, ActionContext } from '../actions/auto-actions';
+import { ModelConfig } from '../bridge/mpp-core';
+
+export class CodeLensCommands {
+ constructor(
+ private log: (message: string) => void,
+ private getChatViewProvider: () => any | undefined,
+ private getModelConfig: () => ModelConfig | undefined
+ ) {}
+
+ /**
+ * 注册所有 CodeLens 命令
+ */
+ register(context: vscode.ExtensionContext): vscode.Disposable[] {
+ return [
+ // Quick Chat - 将代码发送到聊天
+ vscode.commands.registerCommand(
+ 'autodev.codelens.quickChat',
+ async (document: vscode.TextDocument, element: CodeElement) => {
+ await this.handleQuickChat(document, element);
+ }
+ ),
+
+ // Explain Code - 解释代码
+ vscode.commands.registerCommand(
+ 'autodev.codelens.explainCode',
+ async (document: vscode.TextDocument, element: CodeElement) => {
+ await this.handleExplainCode(document, element);
+ }
+ ),
+
+ // Optimize Code - 优化代码
+ vscode.commands.registerCommand(
+ 'autodev.codelens.optimizeCode',
+ async (document: vscode.TextDocument, element: CodeElement) => {
+ await this.handleOptimizeCode(document, element);
+ }
+ ),
+
+ // AutoComment - 生成文档注释
+ vscode.commands.registerCommand(
+ 'autodev.codelens.autoComment',
+ async (document: vscode.TextDocument, element: CodeElement) => {
+ await this.handleAutoComment(document, element);
+ }
+ ),
+
+ // AutoTest - 生成测试
+ vscode.commands.registerCommand(
+ 'autodev.codelens.autoTest',
+ async (document: vscode.TextDocument, element: CodeElement) => {
+ await this.handleAutoTest(document, element);
+ }
+ ),
+
+ // AutoMethod - 方法补全
+ vscode.commands.registerCommand(
+ 'autodev.codelens.autoMethod',
+ async (document: vscode.TextDocument, element: CodeElement) => {
+ await this.handleAutoMethod(document, element);
+ }
+ ),
+
+ // Show Menu - 显示折叠菜单
+ vscode.commands.registerCommand(
+ 'autodev.codelens.showMenu',
+ async (commands: vscode.Command[]) => {
+ await this.handleShowMenu(commands);
+ }
+ )
+ ];
+ }
+
+ /**
+ * Quick Chat: 将代码发送到聊天
+ */
+ private async handleQuickChat(document: vscode.TextDocument, element: CodeElement) {
+ this.log(`Quick Chat: ${element.type} ${element.name}`);
+
+ const chatView = this.getChatViewProvider();
+ if (!chatView) {
+ vscode.window.showWarningMessage('Chat view not available');
+ return;
+ }
+
+ await vscode.commands.executeCommand('autodev.chatView.focus');
+ const codeContext = this.buildCodeContext(document, element);
+ chatView.sendCodeContext(codeContext);
+ }
+
+ /**
+ * Explain Code: 解释代码
+ */
+ private async handleExplainCode(document: vscode.TextDocument, element: CodeElement) {
+ this.log(`Explain Code: ${element.type} ${element.name}`);
+
+ const chatView = this.getChatViewProvider();
+ if (!chatView) {
+ vscode.window.showWarningMessage('Chat view not available');
+ return;
+ }
+
+ await vscode.commands.executeCommand('autodev.chatView.focus');
+ const codeContext = this.buildCodeContext(document, element);
+ chatView.sendCodeContext(codeContext);
+
+ setTimeout(() => {
+ chatView.sendMessage('Explain this code in detail, including:\n1. What it does\n2. How it works\n3. Any potential issues or improvements');
+ }, 300);
+ }
+
+ /**
+ * Optimize Code: 优化代码
+ */
+ private async handleOptimizeCode(document: vscode.TextDocument, element: CodeElement) {
+ this.log(`Optimize Code: ${element.type} ${element.name}`);
+
+ const chatView = this.getChatViewProvider();
+ if (!chatView) {
+ vscode.window.showWarningMessage('Chat view not available');
+ return;
+ }
+
+ await vscode.commands.executeCommand('autodev.chatView.focus');
+ const codeContext = this.buildCodeContext(document, element);
+ chatView.sendCodeContext(codeContext);
+
+ setTimeout(() => {
+ chatView.sendMessage('Optimize this code for better performance, readability, and maintainability');
+ }, 300);
+ }
+
+ /**
+ * AutoComment: 生成文档注释
+ */
+ private async handleAutoComment(document: vscode.TextDocument, element: CodeElement) {
+ this.log(`AutoComment: ${element.type} ${element.name}`);
+
+ const config = this.getModelConfig();
+ if (!config) {
+ vscode.window.showWarningMessage('Please configure a model first');
+ return;
+ }
+
+ const context: ActionContext = {
+ document,
+ element,
+ config,
+ log: this.log
+ };
+
+ await executeAutoComment(context);
+ }
+
+ /**
+ * AutoTest: 生成测试
+ */
+ private async handleAutoTest(document: vscode.TextDocument, element: CodeElement) {
+ this.log(`AutoTest: ${element.type} ${element.name}`);
+
+ const config = this.getModelConfig();
+ if (!config) {
+ vscode.window.showWarningMessage('Please configure a model first');
+ return;
+ }
+
+ const context: ActionContext = {
+ document,
+ element,
+ config,
+ log: this.log
+ };
+
+ await executeAutoTest(context);
+ }
+
+ /**
+ * AutoMethod: 方法补全
+ */
+ private async handleAutoMethod(document: vscode.TextDocument, element: CodeElement) {
+ this.log(`AutoMethod: ${element.type} ${element.name}`);
+
+ const config = this.getModelConfig();
+ if (!config) {
+ vscode.window.showWarningMessage('Please configure a model first');
+ return;
+ }
+
+ const context: ActionContext = {
+ document,
+ element,
+ config,
+ log: this.log
+ };
+
+ await executeAutoMethod(context);
+ }
+
+ /**
+ * Show Menu: 显示折叠菜单
+ */
+ private async handleShowMenu(commands: vscode.Command[]) {
+ const items = commands.map(cmd => ({
+ label: cmd.title,
+ description: cmd.tooltip,
+ command: cmd
+ }));
+
+ const selected = await vscode.window.showQuickPick(items, {
+ placeHolder: 'Select an action'
+ });
+
+ if (selected && selected.command.command) {
+ await vscode.commands.executeCommand(
+ selected.command.command,
+ ...(selected.command.arguments || [])
+ );
+ }
+ }
+
+ /**
+ * 构建代码上下文
+ */
+ private buildCodeContext(document: vscode.TextDocument, element: CodeElement) {
+ return {
+ filepath: document.uri.fsPath,
+ language: document.languageId,
+ element: {
+ type: element.type,
+ name: element.name,
+ code: element.code,
+ range: {
+ start: {
+ line: element.bodyRange.start.line,
+ character: element.bodyRange.start.character
+ },
+ end: {
+ line: element.bodyRange.end.line,
+ character: element.bodyRange.end.character
+ }
+ }
+ }
+ };
+ }
+}
+
diff --git a/mpp-vscode/src/extension.ts b/mpp-vscode/src/extension.ts
index 1ec3be2c86..6a88655ce0 100644
--- a/mpp-vscode/src/extension.ts
+++ b/mpp-vscode/src/extension.ts
@@ -10,6 +10,8 @@ import { DiffManager, DiffContentProvider } from './services/diff-manager';
import { ChatViewProvider } from './providers/chat-view';
import { StatusBarManager } from './services/status-bar';
import { registerDevInsCompletionProvider } from './providers/devins-completion';
+import { AutoDevCodeLensProvider } from './providers/codelens-provider';
+import { CodeLensCommands } from './commands/codelens-commands';
import { createLogger } from './utils/logger';
export const DIFF_SCHEME = 'autodev-diff';
@@ -124,6 +126,34 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(registerDevInsCompletionProvider(context));
log('DevIns language support registered');
+ // Register CodeLens Provider
+ const codeLensProvider = new AutoDevCodeLensProvider(log, context.extensionPath);
+ const codeLensCommands = new CodeLensCommands(log, () => chatViewProvider, () => chatViewProvider.getCurrentModelConfig());
+
+ // Register for supported languages
+ const supportedLanguages = [
+ 'typescript', 'javascript', 'typescriptreact', 'javascriptreact',
+ 'python', 'java', 'kotlin', 'go', 'rust'
+ ];
+
+ context.subscriptions.push(
+ vscode.languages.registerCodeLensProvider(
+ supportedLanguages.map(lang => ({ language: lang })),
+ codeLensProvider
+ ),
+ ...codeLensCommands.register(context)
+ );
+ log('CodeLens Provider registered');
+
+ // Configuration change listener - refresh CodeLens
+ context.subscriptions.push(
+ vscode.workspace.onDidChangeConfiguration((e) => {
+ if (e.affectsConfiguration('autodev.codelens')) {
+ codeLensProvider.refresh();
+ }
+ })
+ );
+
// Show welcome message on first install
const welcomeShownKey = 'autodev.welcomeShown';
if (!context.globalState.get(welcomeShownKey)) {
diff --git a/mpp-vscode/src/prompts/prompt-templates.ts b/mpp-vscode/src/prompts/prompt-templates.ts
new file mode 100644
index 0000000000..08f3f1c63d
--- /dev/null
+++ b/mpp-vscode/src/prompts/prompt-templates.ts
@@ -0,0 +1,167 @@
+/**
+ * Prompt Templates for CodeLens Actions
+ *
+ * Based on autodev-vscode's Velocity templates, converted to TypeScript template strings.
+ */
+
+export interface AutoDocContext {
+ language: string;
+ code: string;
+ startSymbol: string;
+ endSymbol: string;
+ originalComments?: string[];
+ chatContext?: string;
+}
+
+export interface AutoTestContext {
+ language: string;
+ sourceCode: string;
+ className?: string;
+ methodName?: string;
+ imports?: string;
+ relatedClasses?: string;
+ chatContext?: string;
+ isNewFile?: boolean;
+ testFramework?: string;
+}
+
+export interface AutoMethodContext {
+ language: string;
+ code: string;
+ methodSignature: string;
+ className?: string;
+ chatContext?: string;
+}
+
+export const LANGUAGE_COMMENT_MAP: Record = {
+ typescript: { start: '/**', end: '*/' },
+ javascript: { start: '/**', end: '*/' },
+ typescriptreact: { start: '/**', end: '*/' },
+ javascriptreact: { start: '/**', end: '*/' },
+ java: { start: '/**', end: '*/' },
+ kotlin: { start: '/**', end: '*/' },
+ python: { start: '"""', end: '"""' },
+ go: { start: '/*', end: '*/' },
+ rust: { start: '///', end: '' },
+ csharp: { start: '///', end: '' },
+};
+
+export function generateAutoDocPrompt(context: AutoDocContext): string {
+ let prompt = `Write documentation for the following ${context.language} code.\n\n`;
+ if (context.chatContext) prompt += `Additional context:\n${context.chatContext}\n\n`;
+ prompt += `Requirements:
+- Start your documentation with \`${context.startSymbol}\` and end with \`${context.endSymbol}\`
+- Include a brief description of what the code does
+- Document parameters and return values if applicable
+- Use proper ${context.language} documentation format
+
+Here is the code:
+\`\`\`${context.language}
+${context.code}
+\`\`\`
+
+Please write the documentation inside a Markdown code block.`;
+ return prompt;
+}
+
+export function generateAutoTestPrompt(context: AutoTestContext): string {
+ let prompt = `Write unit tests for the following ${context.language} code.\n\n`;
+ if (context.chatContext) prompt += `Additional context:\n${context.chatContext}\n\n`;
+ if (context.relatedClasses) prompt += `Related classes:\n${context.relatedClasses}\n\n`;
+ if (context.imports) prompt += `Imports used:\n${context.imports}\n\n`;
+ if (context.testFramework) prompt += `Use ${context.testFramework} testing framework.\n\n`;
+ prompt += `Source code to test:
+\`\`\`${context.language}
+${context.sourceCode}
+\`\`\`
+
+Requirements:
+- Write comprehensive unit tests covering main functionality
+- Include edge cases and error handling tests
+- Use descriptive test names
+- Follow ${context.language} testing best practices
+`;
+ if (context.className) prompt += `Generate tests for class: ${context.className}\n`;
+ if (context.methodName) prompt += `Focus on method: ${context.methodName}\n`;
+ prompt += `\nStart the test code with a ${context.language} Markdown code block:`;
+ return prompt;
+}
+
+export function generateAutoMethodPrompt(context: AutoMethodContext): string {
+ let prompt = `Complete the implementation for the following ${context.language} method.\n\n`;
+ if (context.chatContext) prompt += `Additional context:\n${context.chatContext}\n\n`;
+ if (context.className) prompt += `Class: ${context.className}\n`;
+ prompt += `Method signature:
+\`\`\`${context.language}
+${context.methodSignature}
+\`\`\`
+
+Current code context:
+\`\`\`${context.language}
+${context.code}
+\`\`\`
+
+Requirements:
+- Implement the method body based on the signature and context
+- Follow ${context.language} best practices
+- Handle edge cases appropriately
+- Add inline comments for complex logic
+
+Please provide the complete method implementation inside a Markdown code block.`;
+ return prompt;
+}
+
+export function parseCodeBlock(response: string, language?: string): string {
+ const codeBlockRegex = /```(?:\w+)?\n([\s\S]*?)```/g;
+ const matches = [...response.matchAll(codeBlockRegex)];
+ if (matches.length > 0) return matches[0][1].trim();
+ return response.trim();
+}
+
+export function getTestFramework(language: string): string {
+ const frameworks: Record = {
+ typescript: 'Jest or Vitest',
+ javascript: 'Jest or Vitest',
+ typescriptreact: 'Jest with React Testing Library',
+ javascriptreact: 'Jest with React Testing Library',
+ java: 'JUnit 5',
+ kotlin: 'JUnit 5 or Kotest',
+ python: 'pytest',
+ go: 'testing package',
+ rust: 'built-in test framework',
+ csharp: 'xUnit or NUnit',
+ };
+ return frameworks[language] || 'appropriate testing framework';
+}
+
+export function getTestFilePath(sourcePath: string, language: string): string {
+ const pathParts = sourcePath.split('/');
+ const fileName = pathParts.pop() || '';
+ const dirPath = pathParts.join('/');
+ const extIndex = fileName.lastIndexOf('.');
+ const baseName = extIndex > 0 ? fileName.substring(0, extIndex) : fileName;
+ const ext = extIndex > 0 ? fileName.substring(extIndex) : '';
+
+ const testSuffixes: Record = {
+ typescript: '.test.ts',
+ javascript: '.test.js',
+ typescriptreact: '.test.tsx',
+ javascriptreact: '.test.jsx',
+ java: 'Test.java',
+ kotlin: 'Test.kt',
+ python: '.py',
+ go: '_test.go',
+ rust: '',
+ csharp: 'Tests.cs',
+ };
+
+ const testSuffix = testSuffixes[language] || `.test${ext}`;
+
+ if (language === 'java' || language === 'kotlin') {
+ const testDir = dirPath.replace('/src/main/', '/src/test/');
+ return `${testDir}/${baseName}${testSuffix}`;
+ }
+ // Python uses test_ prefix for pytest convention
+ if (language === 'python') return `${dirPath}/test_${baseName}${testSuffix}`;
+ return `${dirPath}/${baseName}${testSuffix}`;
+}
diff --git a/mpp-vscode/src/providers/chat-view.ts b/mpp-vscode/src/providers/chat-view.ts
index 6756e7ec02..9f7ddb93dc 100644
--- a/mpp-vscode/src/providers/chat-view.ts
+++ b/mpp-vscode/src/providers/chat-view.ts
@@ -228,6 +228,39 @@ export class ChatViewProvider implements vscode.WebviewViewProvider, vscode.Disp
await this.handleUserMessage(content);
}
+ /**
+ * Send code context to the chat (for CodeLens integration)
+ */
+ sendCodeContext(context: {
+ filepath: string;
+ language: string;
+ element: {
+ type: string;
+ name: string;
+ code: string;
+ range: {
+ start: { line: number; character: number };
+ end: { line: number; character: number };
+ };
+ };
+ }) {
+ // Format code context message
+ const codeBlock = `\`\`\`${context.language}\n${context.element.code}\n\`\`\``;
+ const message = `**${context.element.type}: ${context.element.name}**\n\nFile: \`${context.filepath}\`\n\n${codeBlock}`;
+
+ // Show the view if not visible
+ if (this.webviewView) {
+ this.webviewView.show(true);
+ }
+
+ // Send the formatted message to webview
+ this.postMessage({
+ type: 'addCodeContext',
+ content: message,
+ context: context
+ });
+ }
+
/**
* Post a message to the webview
*/
@@ -1050,5 +1083,23 @@ User's original prompt:`;