Skip to content

Commit c725a4c

Browse files
committed
Merge branch 'main' of https://github.com/microsoft/vscode into copilot/fix-agent-sessions-welcome-gating
2 parents 23415e0 + e32b95e commit c725a4c

File tree

55 files changed

+1097
-256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1097
-256
lines changed

.github/commands.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@
513513
"action": "updateLabels",
514514
"addLabel": "verification-steps-needed",
515515
"removeLabel": "~verification-steps-needed",
516-
"comment": "Friendly ping! Looks like this issue requires some further steps to be verified. Please provide us with the steps necessary to verify this issue."
516+
"comment": "Friendly ping for the VS Code team member who owns this issue- Looks like this issue requires some further steps to be verified. Please provide us with the steps necessary to verify this issue."
517517
},
518518
{
519519
"type": "label",

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ function f(x: number, y: string): void { }
139139
- When adding tooltips to UI elements, prefer the use of IHoverService service.
140140
- Do not duplicate code. Always look for existing utility functions, helpers, or patterns in the codebase before implementing new functionality. Reuse and extend existing code whenever possible.
141141
- You MUST deal with disposables by registering them immediately after creation for later disposal. Use helpers such as `DisposableStore`, `MutableDisposable` or `DisposableMap`. Do NOT register a disposable to the containing class if the object is created within a method that is called repeadedly to avoid leaks. Instead, return a `IDisposable` from such method and let the caller register it.
142+
- You MUST NOT use storage keys of another component only to make changes to that component. You MUST come up with proper API to change another component.
142143

143144
## Learnings
144145
- Minimize the amount of assertions in tests. Prefer one snapshot-style `assert.deepStrictEqual` over multiple precise assertions, as they are much more difficult to understand and to update.

.vscode/notebooks/my-endgame.github-issues

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
{
1313
"kind": 2,
1414
"language": "github-issues",
15-
"value": "$NOT_TEAM_MEMBERS=-author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:bamurtaugh -author:bpasero -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:ntrogh -author:hediet -author:isidorn -author:joaomoreno -author:jrieken -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger -author:karthiknadig -author:eleanorjboyd -author:Yoyokrazy -author:ulugbekna -author:aiday-mar -author:bhavyaus -author:justschen -author:benibenj -author:luabud -author:anthonykim1 -author:joshspicer -author:osortega -author:hawkticehurst -author:pierceboggan -author:benvillalobos -author:dileepyavan -author:dineshc-msft -author:dmitrivMS -author:eli-w-king -author:jo-oikawa -author:jruales -author:jytjyt05 -author:kycutler -author:mrleemurray -author:pwang347 -author:vijayupadya -author:bryanchen-d -author:cwebster-99"
15+
"value": "$NOT_TEAM_MEMBERS=-author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:bamurtaugh -author:bpasero -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:ntrogh -author:hediet -author:isidorn -author:joaomoreno -author:jrieken -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger -author:karthiknadig -author:eleanorjboyd -author:Yoyokrazy -author:ulugbekna -author:aiday-mar -author:bhavyaus -author:justschen -author:benibenj -author:luabud -author:anthonykim1 -author:joshspicer -author:osortega -author:hawkticehurst -author:pierceboggan -author:benvillalobos -author:dileepyavan -author:dineshc-msft -author:dmitrivMS -author:eli-w-king -author:jo-oikawa -author:jruales -author:jytjyt05 -author:kycutler -author:mrleemurray -author:pwang347 -author:vijayupadya -author:bryanchen-d -author:cwebster-99 -author:rwoll -author:lostintangent -author:jukasper -author:zhichli"
1616
},
1717
{
1818
"kind": 1,

build/azure-pipelines/common/sanity-tests.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,13 @@ jobs:
4949
versionFilePath: .nvmrc
5050
displayName: Install Node.js
5151

52-
- bash: |
53-
npm config set registry "$(NPM_REGISTRY)"
54-
echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)"
52+
- script: npm config set registry "$(NPM_REGISTRY)" --location=project
53+
workingDirectory: $(TEST_DIR)
5554
displayName: Configure NPM Registry
5655

5756
- task: npmAuthenticate@0
5857
inputs:
59-
workingFile: $(NPMRC_PATH)
58+
workingFile: $(TEST_DIR)/.npmrc
6059
displayName: Authenticate with NPM Registry
6160

6261
- script: npm ci

build/azure-pipelines/product-sanity-tests.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,9 @@ extends:
8989
- template: build/azure-pipelines/common/sanity-tests.yml@self
9090
parameters:
9191
name: windows_arm64
92-
displayName: Windows arm64 (no runtime)
93-
poolName: 1es-windows-2022-x64
92+
displayName: Windows arm64
93+
poolName: 1es-windows-2022-arm64
9494
os: windows
95-
args: --no-detection --grep "win32-arm64"
9695

9796
# Alpine 3.22
9897
- template: build/azure-pipelines/common/sanity-tests.yml@self

build/npm/gyp/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/mermaid-chat-features/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@
102102
"markup": {
103103
"type": "string",
104104
"description": "The mermaid diagram markup to render as a Mermaid diagram. This should only be the markup of the diagram. Do not include a wrapping code block."
105+
},
106+
"title": {
107+
"type": "string",
108+
"description": "A short title that describes the diagram."
105109
}
106110
}
107111
}

extensions/mermaid-chat-features/src/chatOutputRenderer.ts

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@ class MermaidChatOutputRenderer implements vscode.ChatOutputRenderer {
2828

2929
async renderChatOutput({ value }: vscode.ChatOutputDataItem, chatOutputWebview: vscode.ChatOutputWebview, _ctx: unknown, _token: vscode.CancellationToken): Promise<void> {
3030
const webview = chatOutputWebview.webview;
31-
const mermaidSource = new TextDecoder().decode(value);
31+
const decoded = decodeMermaidData(value);
32+
const mermaidSource = decoded.source;
33+
const title = decoded.title;
3234

3335
// Generate unique ID for this webview
3436
const webviewId = generateUuid();
3537

3638
const disposables: vscode.Disposable[] = [];
3739

3840
// Register and set as active
39-
disposables.push(this._webviewManager.registerWebview(webviewId, webview, mermaidSource, 'chat'));
41+
disposables.push(this._webviewManager.registerWebview(webviewId, webview, mermaidSource, title, 'chat'));
4042

4143
// Listen for messages from the webview
4244
disposables.push(webview.onDidReceiveMessage(message => {
@@ -135,17 +137,18 @@ export function registerChatSupport(
135137
vscode.commands.registerCommand('_mermaid-chat.openInEditor', (ctx?: { mermaidWebviewId?: string }) => {
136138
const webviewInfo = ctx?.mermaidWebviewId ? webviewManager.getWebview(ctx.mermaidWebviewId) : webviewManager.activeWebview;
137139
if (webviewInfo) {
138-
editorManager.openPreview(webviewInfo.mermaidSource);
140+
editorManager.openPreview(webviewInfo.mermaidSource, webviewInfo.title);
139141
}
140142
})
141143
);
142144

143145
// Register lm tools
144146
disposables.push(
145-
vscode.lm.registerTool<{ markup: string }>('renderMermaidDiagram', {
147+
vscode.lm.registerTool<{ markup: string; title?: string }>('renderMermaidDiagram', {
146148
invoke: async (options, _token) => {
147149
const sourceCode = options.input.markup;
148-
return writeMermaidToolOutput(sourceCode);
150+
const title = options.input.title;
151+
return writeMermaidToolOutput(sourceCode, title);
149152
},
150153
})
151154
);
@@ -159,19 +162,52 @@ export function registerChatSupport(
159162
return vscode.Disposable.from(...disposables);
160163
}
161164

162-
function writeMermaidToolOutput(sourceCode: string): vscode.LanguageModelToolResult {
163-
// Expose the source code as a tool result for the LM
165+
function writeMermaidToolOutput(sourceCode: string, title: string | undefined): vscode.LanguageModelToolResult {
166+
// Expose the source code as a markdown mermaid code block
167+
const fence = getFenceForContent(sourceCode);
164168
const result = new vscode.LanguageModelToolResult([
165-
new vscode.LanguageModelTextPart(sourceCode)
169+
new vscode.LanguageModelTextPart(`${fence}mermaid\n${sourceCode}\n${fence}`)
166170
]);
167171

168172
// And store custom data in the tool result details to indicate that a custom renderer should be used for it.
169-
// In this case we just store the source code as binary data.
173+
// Encode source and optional title as JSON.
174+
const data = JSON.stringify({ source: sourceCode, title });
170175
// Add cast to use proposed API
171176
(result as vscode.ExtendedLanguageModelToolResult2).toolResultDetails2 = {
172177
mime,
173-
value: new TextEncoder().encode(sourceCode),
178+
value: new TextEncoder().encode(data),
174179
};
175180

176181
return result;
177182
}
183+
184+
function getFenceForContent(content: string): string {
185+
const backtickMatch = content.matchAll(/`+/g);
186+
if (!backtickMatch) {
187+
return '```';
188+
}
189+
190+
const maxBackticks = Math.max(...Array.from(backtickMatch, s => s[0].length));
191+
return '`'.repeat(Math.max(3, maxBackticks + 1));
192+
}
193+
194+
interface MermaidData {
195+
readonly title: string | undefined;
196+
readonly source: string;
197+
}
198+
199+
function decodeMermaidData(value: Uint8Array): MermaidData {
200+
const text = new TextDecoder().decode(value);
201+
202+
// Try to parse as JSON (new format with title), fall back to plain text (legacy format)
203+
try {
204+
const parsed = JSON.parse(text);
205+
if (typeof parsed === 'object' && typeof parsed.source === 'string') {
206+
return { title: parsed.title, source: parsed.source };
207+
}
208+
} catch {
209+
// Not JSON, treat as legacy plain text format
210+
}
211+
212+
return { title: undefined, source: text };
213+
}

extensions/mermaid-chat-features/src/editorManager.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class MermaidEditorManager extends Disposable implements vscode.WebviewPa
3636
*
3737
* If a preview already exists for this diagram, it will be revealed instead of creating a new one.
3838
*/
39-
public openPreview(mermaidSource: string): void {
39+
public openPreview(mermaidSource: string, title?: string): void {
4040
const webviewId = getWebviewId(mermaidSource);
4141
const existingPreview = this._previews.get(webviewId);
4242
if (existingPreview) {
@@ -47,6 +47,7 @@ export class MermaidEditorManager extends Disposable implements vscode.WebviewPa
4747
const preview = MermaidPreview.create(
4848
webviewId,
4949
mermaidSource,
50+
title,
5051
this._extensionUri,
5152
this._webviewManager,
5253
vscode.ViewColumn.Active);
@@ -126,13 +127,14 @@ class MermaidPreview extends Disposable {
126127
public static create(
127128
diagramId: string,
128129
mermaidSource: string,
130+
title: string | undefined,
129131
extensionUri: vscode.Uri,
130132
webviewManager: MermaidWebviewManager,
131133
viewColumn: vscode.ViewColumn
132134
): MermaidPreview {
133135
const webviewPanel = vscode.window.createWebviewPanel(
134136
mermaidEditorViewType,
135-
'', // Filled in later
137+
title ?? vscode.l10n.t('Mermaid Diagram'),
136138
viewColumn,
137139
{
138140
retainContextWhenHidden: false,
@@ -161,7 +163,6 @@ class MermaidPreview extends Disposable {
161163
) {
162164
super();
163165

164-
this._webviewPanel.title = vscode.l10n.t('Mermaid Diagram'); // TODO: Can we generate a better title from the content?
165166
this._webviewPanel.iconPath = new vscode.ThemeIcon('graph');
166167

167168
this._webviewPanel.webview.options = {
@@ -174,7 +175,7 @@ class MermaidPreview extends Disposable {
174175
this._webviewPanel.webview.html = this._getHtml();
175176

176177
// Register with the webview manager
177-
this._register(this._webviewManager.registerWebview(this.diagramId, this._webviewPanel.webview, this._mermaidSource, 'editor'));
178+
this._register(this._webviewManager.registerWebview(this.diagramId, this._webviewPanel.webview, this._mermaidSource, undefined, 'editor'));
178179

179180
this._register(this._webviewPanel.onDidChangeViewState(e => {
180181
if (e.webviewPanel.active) {

extensions/mermaid-chat-features/src/webviewManager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface MermaidWebviewInfo {
88
readonly id: string;
99
readonly webview: vscode.Webview;
1010
readonly mermaidSource: string;
11+
readonly title: string | undefined;
1112
readonly type: 'chat' | 'editor';
1213
}
1314

@@ -27,7 +28,7 @@ export class MermaidWebviewManager {
2728
return this._activeWebviewId ? this._webviews.get(this._activeWebviewId) : undefined;
2829
}
2930

30-
public registerWebview(id: string, webview: vscode.Webview, mermaidSource: string, type: 'chat' | 'editor'): vscode.Disposable {
31+
public registerWebview(id: string, webview: vscode.Webview, mermaidSource: string, title: string | undefined, type: 'chat' | 'editor'): vscode.Disposable {
3132
if (this._webviews.has(id)) {
3233
throw new Error(`Webview with id ${id} is already registered.`);
3334
}
@@ -36,6 +37,7 @@ export class MermaidWebviewManager {
3637
id,
3738
webview,
3839
mermaidSource,
40+
title,
3941
type
4042
};
4143
this._webviews.set(id, info);

0 commit comments

Comments
 (0)