-
Notifications
You must be signed in to change notification settings - Fork 1
feat(mpp-vscode): implement CodeLens with Tree-sitter and fix CodeFence parsing #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
b34a64d
2a39530
b047e4f
254e488
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,30 @@ | |
| { | ||
| "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" | ||
| } | ||
| ], | ||
| "viewsContainers": { | ||
|
|
@@ -99,6 +123,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" | ||
| } | ||
| } | ||
| }, | ||
|
|
@@ -162,8 +224,10 @@ | |
| "dependencies": { | ||
| "@autodev/mpp-core": "file:../mpp-core/build/packages/js", | ||
| "@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", | ||
|
Comment on lines
+258
to
+261
|
||
| "yaml": "^2.8.2", | ||
| "zod": "^3.22.4" | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+56
to
+65
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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...' }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+119
to
+122
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await llmService.streamMessage(prompt, (chunk) => { | |
| response += chunk; | |
| progress.report({ message: 'Generating...' }); | |
| }); | |
| const abortController = new AbortController(); | |
| const cancellationListener = token.onCancellationRequested(() => { | |
| abortController.abort(); | |
| }); | |
| try { | |
| await llmService.streamMessage( | |
| prompt, | |
| (chunk) => { | |
| response += chunk; | |
| progress.report({ message: 'Generating...' }); | |
| }, | |
| { abortSignal: abortController.signal } | |
| ); | |
| } catch (err) { | |
| if (abortController.signal.aborted) { | |
| // Cancelled by user, exit early | |
| return; | |
| } | |
| throw err; | |
| } finally { | |
| cancellationListener.dispose(); | |
| } |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same cancellation token issue exists here as well.
| }); | |
| }, token); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The command
autodev.codelens.showMenuis registered incodelens-commands.tsand used incodelens-provider.ts(line 198), but it's not declared in thecommandssection of package.json. While VS Code allows undeclared commands for internal use, it's better practice to declare all commands for discoverability and consistency.Add the command declaration:
{ "command": "autodev.codelens.showMenu", "title": "AutoDev: Show CodeLens Menu" }