-
Notifications
You must be signed in to change notification settings - Fork 37.6k
Add a title for generated mermaid diagrams and use this for opened editors #291454
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
Add a title for generated mermaid diagrams and use this for opened editors #291454
Conversation
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.
Pull request overview
This PR adds support for optional titles for Mermaid diagrams generated through the language model tool. The title is provided by the LM when calling the renderMermaidDiagram tool and flows through the chat output renderer to be displayed as the editor title when the diagram is opened in a dedicated editor panel.
Changes:
- Added optional
titleparameter to therenderMermaidDiagramLM tool schema - Updated data encoding/decoding to support title in JSON format with backward compatibility for legacy plain-text format
- Modified webview manager to track title information for each webview
- Enhanced editor manager to accept and display custom titles when opening diagram previews
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| package.json | Added optional title field to the renderMermaidDiagram tool input schema |
| chatOutputRenderer.ts | Updated tool output encoding to include title in JSON format, added backward-compatible decoder, and created fence generation utility |
| webviewManager.ts | Extended MermaidWebviewInfo interface and registerWebview method to include title parameter |
| editorManager.ts | Modified openPreview and MermaidPreview.create to accept and use title parameter for panel titles |
|
|
||
| // Register with the webview manager | ||
| this._register(this._webviewManager.registerWebview(this.diagramId, this._webviewPanel.webview, this._mermaidSource, 'editor')); | ||
| this._register(this._webviewManager.registerWebview(this.diagramId, this._webviewPanel.webview, this._mermaidSource, undefined, 'editor')); |
Copilot
AI
Jan 29, 2026
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 title parameter is not being passed through to the webview registration. The title is received in the create method and used to set the panel title, but it's then discarded. At line 178, undefined is hardcoded as the title parameter when registering the webview. This means the title won't be available in the MermaidWebviewInfo, and won't be passed when opening the diagram in an editor from the revive path.
To fix this, the title should be stored in the MermaidPreview class (e.g., as a private readonly field) and passed to registerWebview instead of undefined.
| this._register(this._webviewManager.registerWebview(this.diagramId, this._webviewPanel.webview, this._mermaidSource, undefined, 'editor')); | |
| this._register(this._webviewManager.registerWebview(this.diagramId, this._webviewPanel.webview, this._mermaidSource, this._webviewPanel.title, 'editor')); |
| const backtickMatch = content.matchAll(/`+/g); | ||
| if (!backtickMatch) { | ||
| return '```'; | ||
| } | ||
|
|
||
| const maxBackticks = Math.max(...Array.from(backtickMatch, s => s[0].length)); |
Copilot
AI
Jan 29, 2026
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 logic for checking if backtickMatch is falsy is incorrect. The matchAll() method always returns an iterator object, never null or undefined, so the condition on line 186 will never be true. Additionally, if there are no backticks in the content, the Array.from() call on line 190 will create an empty array, and Math.max() with an empty array returns -Infinity, which will cause Math.max(3, -Infinity + 1) to return 3 but only by accident.
The correct approach would be to convert the iterator to an array first, check if the array is empty, and handle that case explicitly.
| const backtickMatch = content.matchAll(/`+/g); | |
| if (!backtickMatch) { | |
| return '```'; | |
| } | |
| const maxBackticks = Math.max(...Array.from(backtickMatch, s => s[0].length)); | |
| const backtickMatches = Array.from(content.matchAll(/`+/g)); | |
| if (backtickMatches.length === 0) { | |
| return '```'; | |
| } | |
| const maxBackticks = Math.max(...backtickMatches.map(s => s[0].length)); |
| if (typeof parsed === 'object' && typeof parsed.source === 'string') { | ||
| return { title: parsed.title, source: parsed.source }; |
Copilot
AI
Jan 29, 2026
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 type validation for the title field is incomplete. While the code checks that parsed.source is a string (line 205), it doesn't validate that parsed.title is either undefined or a string. If the parsed JSON contains a title field with an invalid type (e.g., number, object, array), it will be assigned to the title field without validation, potentially causing type safety issues downstream.
Add a check to ensure that if title exists, it must be a string: (parsed.title === undefined || typeof parsed.title === 'string')
| if (typeof parsed === 'object' && typeof parsed.source === 'string') { | |
| return { title: parsed.title, source: parsed.source }; | |
| if (typeof parsed === 'object' | |
| && parsed !== null | |
| && typeof (parsed as { source?: unknown }).source === 'string' | |
| && ((parsed as { title?: unknown }).title === undefined || typeof (parsed as { title?: unknown }).title === 'string')) { | |
| return { title: (parsed as { title?: string }).title, source: (parsed as { source: string }).source }; |
Provides a better editor title when the diagram is opened