Skip to content
This repository was archived by the owner on May 20, 2026. It is now read-only.

Commit bb63b09

Browse files
alexr00joaomoreno
andauthored
The reckoning: Update all the vscode.proposed.*.d.ts files (#3895)
* The reckoning: Update all the vscode.proposed.*.d.ts files and run the update on post install * Improve proposed update and check - Pin it to a commit - Require that update be run manually, not as post install - Add PR check --------- Co-authored-by: João Moreno <joaomoreno@users.noreply.github.com>
1 parent 83f1f9b commit bb63b09

44 files changed

Lines changed: 419 additions & 177 deletions

File tree

Some content is hidden

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

.github/workflows/pr.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ jobs:
121121
mkdir -p .build/build_cache
122122
tar -czf .build/build_cache/cache.tgz --files-from .build/build_cache_list.txt
123123
124+
- name: Ensure proposed API types are up to date
125+
run: npm run vscode-dts:check
126+
124127
- name: TypeScript type checking
125128
run: npm run typecheck
126129

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5785,8 +5785,10 @@
57855785
"scripts": {
57865786
"postinstall": "tsx ./script/postinstall.ts",
57875787
"prepare": "husky",
5788-
"vscode-dts:dev": "node node_modules/@vscode/dts/index.js dev && mv vscode.proposed.*.ts src/extension",
5789-
"vscode-dts:main": "node node_modules/@vscode/dts/index.js main && mv vscode.d.ts src/extension",
5788+
"vscode-dts:update": "node script/build/vscodeDtsUpdate.js",
5789+
"vscode-dts:check": "node script/build/vscodeDtsCheck.js",
5790+
"vscode-dts:dev": "node node_modules/@vscode/dts/index.js dev && node script/build/moveProposedDts.js",
5791+
"vscode-dts:main": "node node_modules/@vscode/dts/index.js main && node script/build/moveProposedDts.js",
57905792
"build": "node .esbuild.ts --sourcemaps",
57915793
"compile": "node .esbuild.ts --dev",
57925794
"watch": "npm-run-all -p watch:*",
@@ -5959,5 +5961,6 @@
59595961
"string_decoder": "npm:string_decoder@1.2.0",
59605962
"node-gyp": "npm:node-gyp@10.3.1",
59615963
"zod": "3.25.76"
5962-
}
5964+
},
5965+
"vscodeCommit": "7a0b83f270038305afab4f7e2a23493152c834df"
59635966
}

script/applyLocalDts.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
#---------------------------------------------------------------------------------------------
44

5-
DIR="$(dirname "$0")"
6-
cp "$DIR"/../../vscode/src/vscode-dts/vscode.proposed.*chat* "$DIR/../src/extension/"
5+
echo "Push your proposal changes and run \`npm run vscode-dts:dev\` instead."

script/build/moveProposedDts.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
const fs = require('fs');
7+
const path = require('path');
8+
const files = fs.readdirSync('.').filter(f => f.startsWith('vscode.') && f.endsWith('.ts'));
9+
for (const f of files) {
10+
fs.renameSync(f, path.join('src', 'extension', f));
11+
}

script/build/vscodeDtsCheck.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
// Usage: node script/build/vscodeDtsCheck.js
7+
// Reads vscodeCommit from package.json, re-downloads proposed d.ts files
8+
// at that commit, checks if any differ from what's committed, then restores
9+
// the originals. Exits with code 1 if files are out of date.
10+
11+
const { execSync } = require('child_process');
12+
const fs = require('fs');
13+
const path = require('path');
14+
15+
const targetDir = path.resolve('src', 'extension');
16+
17+
function main() {
18+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
19+
const sha = pkg.vscodeCommit;
20+
if (!sha) {
21+
console.error('No vscodeCommit found in package.json. Run "npm run vscode-dts:update" first.');
22+
process.exit(1);
23+
}
24+
25+
console.log(`Checking proposed d.ts files against vscodeCommit: ${sha}`);
26+
27+
// Download proposed d.ts files using the commit SHA
28+
execSync(`node node_modules/@vscode/dts/index.js dev ${sha}`, { stdio: 'inherit' });
29+
30+
// Compare downloaded files with committed ones
31+
const downloaded = fs.readdirSync('.').filter(f => f.startsWith('vscode.') && f.endsWith('.ts'));
32+
const mismatched = [];
33+
34+
for (const f of downloaded) {
35+
const committedPath = path.join(targetDir, f);
36+
const newContent = fs.readFileSync(f, 'utf-8');
37+
38+
if (!fs.existsSync(committedPath)) {
39+
mismatched.push(f + ' (missing)');
40+
} else {
41+
const oldContent = fs.readFileSync(committedPath, 'utf-8');
42+
if (oldContent !== newContent) {
43+
mismatched.push(f);
44+
}
45+
}
46+
47+
// Clean up the downloaded file
48+
fs.unlinkSync(f);
49+
}
50+
51+
if (mismatched.length > 0) {
52+
console.error('The following proposed API type definitions are out of date:');
53+
for (const f of mismatched) {
54+
console.error(` - ${f}`);
55+
}
56+
console.error('Run "npm run vscode-dts:update" and commit the changes.');
57+
process.exit(1);
58+
}
59+
60+
console.log('All proposed API type definitions are up to date.');
61+
}
62+
63+
main();

script/build/vscodeDtsUpdate.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
// Usage: node script/build/vscodeDtsUpdate.js [branch]
7+
// Downloads proposed API d.ts files from the given branch (default: main)
8+
// of microsoft/vscode and writes the resolved commit SHA to package.json.
9+
10+
const { execSync } = require('child_process');
11+
const fs = require('fs');
12+
const path = require('path');
13+
const https = require('https');
14+
15+
const branch = process.argv[2] || 'main';
16+
17+
function resolveCommitSha(branch) {
18+
return new Promise((resolve, reject) => {
19+
const options = {
20+
hostname: 'api.github.com',
21+
path: `/repos/microsoft/vscode/commits/${encodeURIComponent(branch)}`,
22+
headers: { 'User-Agent': 'vscode-copilot-chat', 'Accept': 'application/vnd.github.sha' }
23+
};
24+
https.get(options, res => {
25+
if (res.statusCode !== 200) {
26+
reject(new Error(`Failed to resolve commit for branch "${branch}": HTTP ${res.statusCode}`));
27+
return;
28+
}
29+
let data = '';
30+
res.on('data', chunk => data += chunk);
31+
res.on('end', () => resolve(data.trim()));
32+
}).on('error', reject);
33+
});
34+
}
35+
36+
async function main() {
37+
const sha = await resolveCommitSha(branch);
38+
console.log(`Resolved branch "${branch}" to commit ${sha}`);
39+
40+
// Download proposed d.ts files using the commit SHA
41+
execSync(`node node_modules/@vscode/dts/index.js dev ${sha}`, { stdio: 'inherit' });
42+
43+
// Move downloaded files to src/extension/
44+
const files = fs.readdirSync('.').filter(f => f.startsWith('vscode.') && f.endsWith('.ts'));
45+
for (const f of files) {
46+
fs.renameSync(f, path.join('src', 'extension', f));
47+
}
48+
49+
// Write the commit SHA to package.json
50+
const pkgPath = path.resolve('package.json');
51+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
52+
pkg.vscodeCommit = sha;
53+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, '\t') + '\n');
54+
console.log(`Wrote vscodeCommit: ${sha} to package.json`);
55+
}
56+
57+
main().catch(err => {
58+
console.error(err);
59+
process.exit(1);
60+
});

src/extension/agents/claude/common/test/toolInvocationFormatter.spec.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ describe('completeToolInvocation', () => {
303303
it('populates terminal output data', () => {
304304
const toolUse = createToolUseBlock(ClaudeToolNames.Bash, { command: 'npm install' });
305305
const toolResult = createToolResultBlock('test-tool-id-123', 'added 150 packages\nDone in 5.2s');
306-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
306+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
307307

308308
completeToolInvocation(toolUse, toolResult, invocation);
309309

@@ -318,7 +318,7 @@ describe('completeToolInvocation', () => {
318318
it('parses exit code from output', () => {
319319
const toolUse = createToolUseBlock(ClaudeToolNames.Bash, { command: 'npm test' });
320320
const toolResult = createToolResultBlock('test-tool-id-123', 'Tests failed\nexit code: 1');
321-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
321+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
322322

323323
completeToolInvocation(toolUse, toolResult, invocation);
324324

@@ -330,7 +330,7 @@ describe('completeToolInvocation', () => {
330330
it('parses "exited with" format exit code', () => {
331331
const toolUse = createToolUseBlock(ClaudeToolNames.Bash, { command: 'false' });
332332
const toolResult = createToolResultBlock('test-tool-id-123', 'Command failed\nexited with 127');
333-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
333+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
334334

335335
completeToolInvocation(toolUse, toolResult, invocation);
336336

@@ -341,7 +341,7 @@ describe('completeToolInvocation', () => {
341341
it('handles empty output', () => {
342342
const toolUse = createToolUseBlock(ClaudeToolNames.Bash, { command: 'true' });
343343
const toolResult = createToolResultBlock('test-tool-id-123', '');
344-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
344+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
345345

346346
completeToolInvocation(toolUse, toolResult, invocation);
347347

@@ -352,7 +352,7 @@ describe('completeToolInvocation', () => {
352352
it('converts newlines to CRLF for terminal display', () => {
353353
const toolUse = createToolUseBlock(ClaudeToolNames.Bash, { command: 'ls' });
354354
const toolResult = createToolResultBlock('test-tool-id-123', 'file1.ts\nfile2.ts\nfile3.ts');
355-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
355+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
356356

357357
completeToolInvocation(toolUse, toolResult, invocation);
358358

@@ -366,7 +366,7 @@ describe('completeToolInvocation', () => {
366366
const toolUse = createToolUseBlock(ClaudeToolNames.Read, { file_path: '/path/to/file.ts' });
367367
const fileContent = 'export function hello() {\n return "world";\n}';
368368
const toolResult = createToolResultBlock('test-tool-id-123', fileContent);
369-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
369+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
370370

371371
completeToolInvocation(toolUse, toolResult, invocation);
372372

@@ -379,7 +379,7 @@ describe('completeToolInvocation', () => {
379379
it('does not populate data when content is empty', () => {
380380
const toolUse = createToolUseBlock(ClaudeToolNames.Read, { file_path: '/path/to/empty.ts' });
381381
const toolResult = createToolResultBlock('test-tool-id-123', '');
382-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
382+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
383383

384384
completeToolInvocation(toolUse, toolResult, invocation);
385385

@@ -392,7 +392,7 @@ describe('completeToolInvocation', () => {
392392
const toolUse = createToolUseBlock(ClaudeToolNames.LS, { path: '/project/src' });
393393
const listing = 'index.ts\nutils/\ncomponents/';
394394
const toolResult = createToolResultBlock('test-tool-id-123', listing);
395-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
395+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
396396

397397
completeToolInvocation(toolUse, toolResult, invocation);
398398

@@ -408,7 +408,7 @@ describe('completeToolInvocation', () => {
408408
const toolUse = createToolUseBlock(ClaudeToolNames.Glob, { pattern: '**/*.spec.ts' });
409409
const results = '/src/a.spec.ts\n/src/b.spec.ts\n/test/c.spec.ts';
410410
const toolResult = createToolResultBlock('test-tool-id-123', results);
411-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
411+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
412412

413413
completeToolInvocation(toolUse, toolResult, invocation);
414414

@@ -424,7 +424,7 @@ describe('completeToolInvocation', () => {
424424
const toolUse = createToolUseBlock(ClaudeToolNames.Grep, { pattern: 'TODO' });
425425
const results = '/src/file.ts:10: // TODO: fix this\n/src/other.ts:25: // TODO: refactor';
426426
const toolResult = createToolResultBlock('test-tool-id-123', results);
427-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
427+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
428428

429429
completeToolInvocation(toolUse, toolResult, invocation);
430430

@@ -439,7 +439,7 @@ describe('completeToolInvocation', () => {
439439
it('does not populate data for Edit tool (has separate UI)', () => {
440440
const toolUse = createToolUseBlock(ClaudeToolNames.Edit, { file_path: '/path/to/file.ts' });
441441
const toolResult = createToolResultBlock('test-tool-id-123', 'File edited successfully');
442-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
442+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
443443

444444
completeToolInvocation(toolUse, toolResult, invocation);
445445

@@ -449,7 +449,7 @@ describe('completeToolInvocation', () => {
449449
it('does not populate data for Write tool (has separate UI)', () => {
450450
const toolUse = createToolUseBlock(ClaudeToolNames.Write, { file_path: '/path/to/new.ts' });
451451
const toolResult = createToolResultBlock('test-tool-id-123', 'File created');
452-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
452+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
453453

454454
completeToolInvocation(toolUse, toolResult, invocation);
455455

@@ -459,7 +459,7 @@ describe('completeToolInvocation', () => {
459459
it('does not populate data for TodoWrite tool (has separate UI)', () => {
460460
const toolUse = createToolUseBlock(ClaudeToolNames.TodoWrite, { todos: [] });
461461
const toolResult = createToolResultBlock('test-tool-id-123', 'Todos updated');
462-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
462+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
463463

464464
completeToolInvocation(toolUse, toolResult, invocation);
465465

@@ -511,7 +511,7 @@ describe('completeToolInvocation', () => {
511511
it('populates JSON input and string output', () => {
512512
const toolUse = createToolUseBlock('CustomTool', { arg1: 'value1', arg2: 42 });
513513
const toolResult = createToolResultBlock('test-tool-id-123', 'Custom tool completed successfully');
514-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
514+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
515515

516516
completeToolInvocation(toolUse, toolResult, invocation);
517517

@@ -524,7 +524,7 @@ describe('completeToolInvocation', () => {
524524
it('does not populate data when output is empty', () => {
525525
const toolUse = createToolUseBlock('CustomTool', { arg: 'value' });
526526
const toolResult = createToolResultBlock('test-tool-id-123', '');
527-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
527+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
528528

529529
completeToolInvocation(toolUse, toolResult, invocation);
530530

@@ -536,7 +536,7 @@ describe('completeToolInvocation', () => {
536536
it('handles string content directly', () => {
537537
const toolUse = createToolUseBlock(ClaudeToolNames.Read, { file_path: '/file.ts' });
538538
const toolResult = createToolResultBlock('test-tool-id-123', 'plain string content');
539-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
539+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
540540

541541
completeToolInvocation(toolUse, toolResult, invocation);
542542

@@ -550,7 +550,7 @@ describe('completeToolInvocation', () => {
550550
{ type: 'text' as const, text: 'first block' },
551551
{ type: 'text' as const, text: 'second block' }
552552
]);
553-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
553+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
554554

555555
completeToolInvocation(toolUse, toolResult, invocation);
556556

@@ -564,7 +564,7 @@ describe('completeToolInvocation', () => {
564564
{ type: 'text' as const, text: 'text content' },
565565
{ type: 'image' as const, source: { type: 'base64' as const, media_type: 'image/png' as const, data: 'abc' } }
566566
]);
567-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
567+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
568568

569569
completeToolInvocation(toolUse, toolResult, invocation);
570570

@@ -575,7 +575,7 @@ describe('completeToolInvocation', () => {
575575
it('handles undefined content', () => {
576576
const toolUse = createToolUseBlock(ClaudeToolNames.Read, { file_path: '/file.ts' });
577577
const toolResult = createToolResultBlock('test-tool-id-123', undefined);
578-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
578+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
579579

580580
completeToolInvocation(toolUse, toolResult, invocation);
581581

src/extension/agents/claude/common/toolInvocationFormatter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export function createFormattedToolInvocation(
197197
toolUse: Anthropic.ToolUseBlock,
198198
complete?: boolean
199199
): ChatToolInvocationPart | undefined {
200-
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false);
200+
const invocation = new ChatToolInvocationPart(toolUse.name, toolUse.id, false as unknown as string);
201201
if (complete !== undefined) {
202202
invocation.isConfirmed = complete;
203203
invocation.isComplete = complete;

src/extension/agents/copilotcli/common/copilotCLITools.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ export function createCopilotCLIToolInvocation(data: {
631631
if (!Object.hasOwn(ToolFriendlyNameAndHandlers, data.toolName)) {
632632
const mcpServer = l10n.t('MCP Server');
633633
const toolName = data.mcpServerName && data.mcpToolName ? `${data.mcpServerName}, ${data.mcpToolName} (${mcpServer})` : data.toolName;
634-
const invocation = new ChatToolInvocationPart(toolName ?? 'unknown', data.toolCallId ?? '', false);
634+
const invocation = new ChatToolInvocationPart(toolName ?? 'unknown', data.toolCallId ?? '', false as unknown as string);
635635
invocation.isConfirmed = false;
636636
invocation.isComplete = false;
637637
invocation.invocationMessage = l10n.t("Using tool: {0}", toolName ?? 'unknown');
@@ -653,7 +653,7 @@ export function createCopilotCLIToolInvocation(data: {
653653
}
654654

655655
const [friendlyToolName, formatter] = ToolFriendlyNameAndHandlers[toolCall.toolName];
656-
const invocation = new ChatToolInvocationPart(friendlyToolName ?? toolCall.toolName ?? 'unknown', toolCall.toolCallId ?? '', false);
656+
const invocation = new ChatToolInvocationPart(friendlyToolName ?? toolCall.toolName ?? 'unknown', toolCall.toolCallId ?? '', false as unknown as string);
657657
invocation.isConfirmed = false;
658658
invocation.isComplete = false;
659659

src/extension/conversation/vscode-node/chatParticipants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ class ChatAgents implements IDisposable {
132132
if (!user) {
133133
return false;
134134
}
135-
defaultAgent.requester = {
135+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
136+
(defaultAgent as any).requester = {
136137
name: user.login,
137138
icon: URI.parse(user?.avatar_url ?? `https://avatars.githubusercontent.com/${user.login}`)
138139
};

0 commit comments

Comments
 (0)