Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
86da917
Use `tsgo` to run type checks on client in watch mode
mjbvz Feb 19, 2026
dbbe583
Update build/lib/compilation.ts
mjbvz Feb 19, 2026
cc10bc7
Enable incremental builds to speed up updates after first build
mjbvz Feb 19, 2026
de7206f
Merge branch 'main' into dev/mjbvz/wonderful-piranha
mjbvz Apr 20, 2026
2cb278e
Fix task watching
mjbvz Apr 20, 2026
7b8f4a2
Add back basic rendering of contributed chat status items
mjbvz Apr 21, 2026
c95b566
Merge branch 'main' into dev/mjbvz/wonderful-piranha
mjbvz Apr 21, 2026
9d2498a
Update tsgo-typecheck task
mjbvz Apr 21, 2026
69c0477
Increase timeout for "waiting for artifacts" in macOS build (#311721)
alexr00 Apr 21, 2026
f0b6f9b
Merge pull request #296215 from mjbvz/dev/mjbvz/wonderful-piranha
mjbvz Apr 21, 2026
5f5f6a9
Agents app improvements (#311730)
sandy081 Apr 21, 2026
da4ab52
Merge pull request #311613 from mjbvz/dev/mjbvz/encouraging-junglefowl
mjbvz Apr 21, 2026
d822faf
refactor notif handling to use instance id (#311727)
meganrogge Apr 21, 2026
0e1575f
Update distro commit (main) (#311726)
vs-code-engineering[bot] Apr 21, 2026
eeafd9c
Rewrite `run_in_terminal` "may be waiting for input" steering text to…
meganrogge Apr 21, 2026
73e7e1b
Remove deprecated properties for chat sessions proposal
mjbvz Apr 21, 2026
4dabc9b
feat: add leakWarningName to emitters for better leak error telemetry…
bryanchen-d Apr 21, 2026
a54f527
Fix watch task matcher for tsgo
mjbvz Apr 21, 2026
6b77674
Support Controller API sessions in Agents App (#311608)
TylerLeonhardt Apr 21, 2026
78f74a5
Add reasoning effort configuration to Claude session management (#311…
TylerLeonhardt Apr 21, 2026
29d154d
Refactor chat send button styles for enhanced visual effects (#311740)
mrleemurray Apr 21, 2026
c2b76c5
Merge pull request #311743 from mjbvz/dev/mjbvz/wandering-piranha
mjbvz Apr 21, 2026
4253b36
Add messagesApi.refusal telemetry and remove noisy unknownContentBloc…
bhavyaus Apr 21, 2026
ea91ac3
Merge pull request #311746 from mjbvz/dev/mjbvz/informal-zebra
mjbvz Apr 21, 2026
dbadc07
Merge pull request #311706 from microsoft/ulugbekna/fix-plugin-instal…
ulugbekna Apr 21, 2026
2e33f3d
agentHost: fix ah diffs not showing for historic sessions and missing…
connor4312 Apr 21, 2026
8bcc077
Don't restore agents window from previous session (#311560)
roblourens Apr 21, 2026
d0b379e
Agents - refactor SCM contributions (#311755)
lszomoru Apr 21, 2026
fed5bec
Changing upgrade hover for Pro users
cwebster-99 Apr 21, 2026
38e6e03
Merge branch 'main' into ltd-felidae
cwebster-99 Apr 21, 2026
ba6a4b1
Generalize model picker to be used with Claude (#311761)
TylerLeonhardt Apr 21, 2026
6101c49
Use parent session metadata for Copilot chat grouping (#311724)
sandy081 Apr 21, 2026
51d818f
Rule files with applyTo globs are eagerly read regardless of paths pa…
aeschli Apr 21, 2026
318e2ea
Merge branch 'main' into ltd-felidae
cwebster-99 Apr 21, 2026
b000854
fix compilation (#311793)
sandy081 Apr 21, 2026
b2eb25c
Merge branch 'main' into ltd-felidae
cwebster-99 Apr 21, 2026
e53a040
Add promptTypes to summarizedConversationHistory telemetry (#311790)
bhavyaus Apr 21, 2026
76021b0
Allow local agent host and Copilot CLI sessions providers to coexist …
roblourens Apr 21, 2026
498c469
Merge pull request #311762 from microsoft/ltd-felidae
cwebster-99 Apr 21, 2026
9a60a6f
chore: bump windows-process-tree (#311781)
rzhao271 Apr 21, 2026
6b7525f
re #311393. introduce chat info part api (#311772)
rebornix Apr 21, 2026
04d0511
Agents web: add tunnel indicator dropdown (#311751)
osortega Apr 21, 2026
895cf90
Fix listener leak in FocusSessionActionViewItem (#311759)
roblourens Apr 21, 2026
9a5b011
claude extension contributes dropdown to permission picker (#311593)
justschen Apr 22, 2026
6baf58b
Lazily create chat code block toolbar (#311747)
roblourens Apr 22, 2026
abc8fbc
add back confirmation expanding (#311809)
justschen Apr 22, 2026
1861d4a
Agents web: scope workspace picker to selected host (#311808)
osortega Apr 22, 2026
d8a9dd1
Add /remote slash command with Mission Control integration for Copilo…
pierceboggan Apr 22, 2026
05a1029
terminal: fix duplicate agent host terminals and hide tool-created on…
connor4312 Apr 22, 2026
6994450
agentHost: use actual filename in diff editor title (#311771)
connor4312 Apr 22, 2026
cc33dc6
Fixes for the chat perf pipeline (#311605)
pwang347 Apr 22, 2026
214df4b
Copilot CLI in chat panel should handle /compact gracefully (#311805)
anthonykim1 Apr 22, 2026
0a84983
Fix remote agent host protocol client lifecycle (#311814)
roblourens Apr 22, 2026
a1abedf
Update @github/copilot SDK to ^1.0.28 (#311807)
roblourens Apr 22, 2026
ad53118
fix int id. (#311822)
rebornix Apr 22, 2026
ea09c84
Fix broken sessions list (#311828)
roblourens Apr 22, 2026
70d194f
Exclude agent host folders from prompt-file discovery (#311831)
roblourens Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/skills/chat-perf/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ Launches VS Code via Playwright Electron, opens the chat panel, sends a message
| `--production-build` | — | Build a local bundled package via `gulp vscode` for comparison against a release baseline. |
| `--no-cache` | — | Ignore cached baseline data, always run fresh. |
| `--force` | — | Skip build mode mismatch confirmation prompt. |
| `--ci` | — | CI mode: write Markdown summary to `ci-summary.md` (implies `--no-cache`). |
| `--ci` | — | CI mode: write Markdown summary to `ci-summary.md` (implies `--no-cache`, `--heap-snapshots`, `--cleanup-diagnostics`). |
| `--heap-snapshots` | — | Take heap snapshots after each run (slow; auto-enabled in `--ci` mode). |
| `--cleanup-diagnostics` | — | Delete heap snapshots, CPU profiles, and traces to save disk. During runs, only the latest run's files are kept; after comparison, files for non-regressed scenarios are deleted. Auto-enabled in `--ci` mode. |
| `--setting <k=v>` | — | Set a VS Code setting override for all builds (repeatable). |
| `--test-setting <k=v>` | — | Set a VS Code setting override for the test build only. |
| `--baseline-setting <k=v>` | — | Set a VS Code setting override for the baseline build only. |
Expand Down
70 changes: 61 additions & 9 deletions .github/workflows/chat-perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ jobs:
outputs:
test_is_version: ${{ steps.resolve.outputs.is_version }}
test_build_arg: ${{ steps.resolve.outputs.build_arg }}
perf_matrix: ${{ steps.count_scenarios.outputs.matrix }}
steps:
- name: Resolve test build type
id: resolve
Expand Down Expand Up @@ -143,6 +144,28 @@ jobs:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package.json') }}

- name: Compute perf matrix
id: count_scenarios
run: |
node -e "
require('./scripts/chat-simulation/common/perf-scenarios').registerPerfScenarios();
const { getScenarioIds } = require('./scripts/chat-simulation/common/mock-llm-server');
const userInput = process.env.SCENARIOS_INPUT || '';
const parsed = userInput.split(',').map(s => s.trim()).filter(Boolean);
const allScens = parsed.length > 0 ? parsed : getScenarioIds();
if (allScens.length === 0) {
console.error('No scenarios found. Provide a non-empty scenarios input or ensure getScenarioIds() returns at least one scenario.');
process.exit(1);
}
const maxGroups = 4;
const needed = Math.min(allScens.length, maxGroups);
const groups = Array.from({ length: needed }, (_, i) => i + 1);
const fs = require('fs');
const matrix = JSON.stringify({ group: groups });
fs.appendFileSync(process.env.GITHUB_OUTPUT, 'matrix=' + matrix + '\\n');
console.log('Total scenarios: ' + allScens.length + ', groups: ' + needed);
"

- name: Upload build output
uses: actions/upload-artifact@v7
with:
Expand All @@ -160,8 +183,7 @@ jobs:
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
group: [ 1, 2, 3, 4 ]
matrix: ${{ fromJSON(needs.setup.outputs.perf_matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down Expand Up @@ -223,10 +245,9 @@ jobs:
require('./scripts/chat-simulation/common/perf-scenarios').registerPerfScenarios();
const { getScenarioIds } = require('./scripts/chat-simulation/common/mock-llm-server');
const userInput = process.env.SCENARIOS_INPUT || '';
const allScens = userInput
? userInput.split(',').map(s => s.trim()).filter(Boolean)
: getScenarioIds();
const groups = 4;
const parsed = userInput.split(',').map(s => s.trim()).filter(Boolean);
const allScens = parsed.length > 0 ? parsed : getScenarioIds();
const groups = parseInt(process.env.TOTAL_GROUPS, 10);
const group = parseInt(process.env.MATRIX_GROUP, 10);
// Distribute scenarios round-robin across groups
const groupScens = allScens.filter((_, i) => (i % groups) + 1 === group);
Expand All @@ -242,6 +263,7 @@ jobs:
"
env:
MATRIX_GROUP: ${{ matrix.group }}
TOTAL_GROUPS: ${{ strategy.job-total }}

- name: Run chat perf comparison
id: perf
Expand Down Expand Up @@ -287,6 +309,16 @@ jobs:
2>&1 | tee perf-output.log
echo "exit_code=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT"

- name: Clean up temporary build artifacts
if: always() && steps.scenarios.outputs.skip != 'true'
run: |
# Clean up tmp dirs used by VS Code instances
rm -rf /tmp/vscode-chat-simulation 2>/dev/null || true
# Remove the production build to free space for artifact upload
rm -rf ../VSCode-* 2>/dev/null || true
echo "Disk usage after cleanup:"
df -h . | tail -1

- name: Upload perf results
if: always() && steps.scenarios.outputs.skip != 'true'
uses: actions/upload-artifact@v7
Expand All @@ -298,6 +330,19 @@ jobs:
.chat-simulation-data/
retention-days: 30

- name: Upload perf summary data
if: always() && steps.scenarios.outputs.skip != 'true'
uses: actions/upload-artifact@v7
with:
name: perf-summary-${{ matrix.group }}
include-hidden-files: true
path: |
perf-output.log
.chat-simulation-data/**/results.json
.chat-simulation-data/**/baseline-*.json
.chat-simulation-data/ci-summary.md
retention-days: 1

- name: Check for regressions
if: always() && steps.perf.outputs.exit_code != '' &&
steps.perf.outputs.exit_code != '0'
Expand Down Expand Up @@ -380,6 +425,11 @@ jobs:
2>&1 | tee leak-output.log
echo "exit_code=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT"

- name: Clean up temporary files
if: always()
run: |
rm -rf /tmp/vscode-chat-simulation 2>/dev/null || true

- name: Upload leak results
if: always()
uses: actions/upload-artifact@v7
Expand All @@ -402,7 +452,7 @@ jobs:
# ── Report: collect results, write summary, fail on regression ──────
report:
name: Report
needs: [ chat-perf, leak-check ]
needs: [ setup, chat-perf, leak-check ]
if: always()
runs-on: ubuntu-latest
timeout-minutes: 30
Expand All @@ -417,10 +467,10 @@ jobs:
with:
node-version-file: .nvmrc

- name: Download all perf results
- name: Download perf summary data
uses: actions/download-artifact@v7
with:
pattern: perf-results-*
pattern: perf-summary-*
path: perf-results

- name: Download leak results
Expand All @@ -432,6 +482,8 @@ jobs:
continue-on-error: true

- name: Generate unified summary
env:
TEST_COMMIT: ${{ needs.setup.outputs.test_build_arg || github.sha }}
run: |
LEAK_ARG=""
if [[ -f leak-results/.chat-simulation-data/ci-summary-leak.md ]]; then
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
".git": true,
".build": true,
".profile-oss": true,
"**/*.tsbuildinfo": true,
"**/.DS_Store": true,
".vscode-test": true,
"cli/target": true,
Expand Down
24 changes: 10 additions & 14 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@
"fileLocation": [
"absolute"
],
"pattern": {
"regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$",
"file": 1,
"location": 2,
"message": 3
},
"pattern": "$tsc",
"background": {
"beginsPattern": "Starting compilation\\.\\.\\.",
"endsPattern": "Finished compilation with"
Expand All @@ -76,12 +71,7 @@
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "\\] ([^(]+)\\((\\d+,\\d+)\\): (.*)$",
"file": 1,
"location": 2,
"message": 3
},
"pattern": "$tsc",
"background": {
"beginsPattern": "Starting compilation",
"endsPattern": "Finished compilation"
Expand Down Expand Up @@ -275,14 +265,20 @@
},
{
"label": "Run and Compile Agents - OSS",
"dependsOn": ["Transpile Client", "Run Dev Agents"],
"dependsOn": [
"Transpile Client",
"Run Dev Agents"
],
"dependsOrder": "sequence",
"inAgents": true,
"problemMatcher": []
},
{
"label": "Run and Compile Code - OSS",
"dependsOn": ["Transpile Client", "Run Dev"],
"dependsOn": [
"Transpile Client",
"Run Dev"
],
"dependsOrder": "sequence",
"inAgents": true,
"problemMatcher": []
Expand Down
8 changes: 4 additions & 4 deletions build/azure-pipelines/common/waitForArtifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ async function main(artifacts: string[]): Promise<void> {
throw new Error(`Usage: node waitForArtifacts.ts <artifactName1> <artifactName2> ...`);
}

// This loop will run for 30 minutes and waits to the x64 and arm64 artifacts
// This loop will run for 60 minutes and waits to the x64 and arm64 artifacts
// to be uploaded to the pipeline by the `macOS` and `macOSARM64` jobs. As soon
// as these artifacts are found, the loop completes and the `macOSUnivesrsal`
// job resumes.
for (let index = 0; index < 60; index++) {
for (let index = 0; index < 120; index++) {
try {
console.log(`Waiting for artifacts (${artifacts.join(', ')}) to be uploaded (${index + 1}/60)...`);
console.log(`Waiting for artifacts (${artifacts.join(', ')}) to be uploaded (${index + 1}/120)...`);
const allArtifacts = await retry(() => getPipelineArtifacts());
console.log(` * Artifacts attached to the pipelines: ${allArtifacts.length > 0 ? allArtifacts.map(a => a.name).join(', ') : 'none'}`);

Expand All @@ -40,7 +40,7 @@ async function main(artifacts: string[]): Promise<void> {
await new Promise(c => setTimeout(c, 30_000));
}

throw new Error(`ERROR: Artifacts (${artifacts.join(', ')}) were not uploaded within 30 minutes.`);
throw new Error(`ERROR: Artifacts (${artifacts.join(', ')}) were not uploaded within 60 minutes.`);
}

main(process.argv.splice(2)).then(() => {
Expand Down
5 changes: 1 addition & 4 deletions build/gulpfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { compileExtensionMediaTask, compileExtensionsTask, watchExtensionsTask }
import * as compilation from './lib/compilation.ts';
import * as task from './lib/task.ts';
import * as util from './lib/util.ts';
import { useEsbuildTranspile } from './buildConfig.ts';

// Extension point names
gulp.task(compilation.compileExtensionPointNamesTask);
Expand All @@ -36,9 +35,7 @@ gulp.task(transpileClientTask);
const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), compilation.copyCodiconsTask, compilation.compileApiProposalNamesTask, compilation.compileExtensionPointNamesTask, compilation.compileTask('src', 'out', false)));
gulp.task(compileClientTask);

const watchClientTask = useEsbuildTranspile
? task.define('watch-client', task.parallel(compilation.watchTask('out', false, 'src', { noEmit: true }), compilation.watchApiProposalNamesTask, compilation.watchExtensionPointNamesTask, compilation.watchCodiconsTask))
: task.define('watch-client', task.series(util.rimraf('out'), task.parallel(compilation.watchTask('out', false), compilation.watchApiProposalNamesTask, compilation.watchExtensionPointNamesTask, compilation.watchCodiconsTask)));
const watchClientTask = task.define('watch-client', task.parallel(compilation.watchTypeCheckTask('src'), compilation.watchApiProposalNamesTask, compilation.watchExtensionPointNamesTask, compilation.watchCodiconsTask));
gulp.task(watchClientTask);

// All
Expand Down
22 changes: 2 additions & 20 deletions build/gulpfile.vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { promisify } from 'util';
import globCallback from 'glob';
import rceditCallback from 'rcedit';
import * as cp from 'child_process';
import { spawnTsgo } from './lib/tsgo.ts';


const glob = promisify(globCallback);
Expand Down Expand Up @@ -221,25 +222,6 @@ function runEsbuildBundle(outDir: string, minify: boolean, nls: boolean, target:
});
}

function runTsGoTypeCheck(): Promise<void> {
return new Promise((resolve, reject) => {
const proc = cp.spawn('tsgo', ['--project', 'src/tsconfig.json', '--noEmit', '--skipLibCheck'], {
cwd: root,
stdio: 'inherit',
shell: true
});

proc.on('error', reject);
proc.on('close', code => {
if (code === 0) {
resolve();
} else {
reject(new Error(`tsgo typecheck failed with exit code ${code}`));
}
});
});
}

const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`;
const isCI = !!process.env['CI'] || !!process.env['BUILD_ARTIFACTSTAGINGDIRECTORY'] || !!process.env['GITHUB_WORKSPACE'];
const useCdnSourceMapsForPackagingTasks = isCI;
Expand All @@ -266,7 +248,7 @@ gulp.task(task.define('core-ci', task.series(
compileExtensionMediaBuildTask,
writeISODate('out-build'),
// Type-check with tsgo (no emit)
task.define('tsgo-typecheck', () => runTsGoTypeCheck()),
task.define('tsgo-typecheck', () => spawnTsgo(path.join(root, 'src', 'tsconfig.json'), { taskName: 'tsgo-typecheck', noEmit: true })),
// Transpile individual files to out-build first (for unit tests)
task.define('esbuild-out-build', () => runEsbuildTranspile('out-build', false)),
// Then bundle for shipping (bundles also write NLS files to out-build)
Expand Down
36 changes: 20 additions & 16 deletions build/lib/compilation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import watch from './watch/index.ts';
import bom from 'gulp-bom';
import * as tsb from './tsb/index.ts';
import sourcemaps from 'gulp-sourcemaps';
import { createTsgoStream } from './tsgo.ts';


import { extractExtensionPointNamesFromFile } from './extractExtensionPoints.ts';
Expand Down Expand Up @@ -170,24 +171,27 @@ export function compileTask(src: string, out: string, build: boolean, options: {
return task;
}

export function watchTask(out: string, build: boolean, srcPath: string = 'src', options?: { noEmit?: boolean }): task.StreamTask {

const task = () => {
const compile = createCompile(srcPath, { build, emitError: false, transpileOnly: false, preserveEnglish: false, noEmit: options?.noEmit });

const src = gulp.src(`${srcPath}/**`, { base: srcPath });
const watchSrc = watch(`${srcPath}/**`, { base: srcPath, readDelay: 200 });

export function watchTypeCheckTask(src: string): task.Task {
return task.define(`watch-typecheck-${path.basename(src)}`, () => {
const projectPath = path.join(import.meta.dirname, '../../', src, 'tsconfig.json');
const generator = new MonacoGenerator(true);
generator.execute();

return watchSrc
.pipe(generator.stream)
.pipe(util.incremental(compile, src, true))
.pipe(gulp.dest(out));
};
task.taskName = `watch-${path.basename(out)}`;
return task;
const watchInput = watch(`${src}/**`, { base: src, readDelay: 200 });
const tsgoStream = watchInput.pipe(generator.stream).pipe(util.debounce(() => {
const stream = createTsgoStream(projectPath, { taskName: 'watch-client-noEmit', noEmit: true });
const result = es.through();
stream.on('end', () => {
result.emit('end');
});
stream.on('error', err => {
reporter(err);
fancyLog.error(ansiColors.red('[tsgo] watch-client-noEmit failed'));
result.emit('end');
});
return result.pipe(reporter.end(false));
}));
return tsgoStream;
});
}

const REPO_SRC_FOLDER = path.join(import.meta.dirname, '../../src');
Expand Down
10 changes: 4 additions & 6 deletions build/lib/tsgo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ export function spawnTsgo(projectPath: string, config: { taskName: string; noEmi
function runReporter(output: string) {
const lines = (output || '').split('\n');
const errorLines = lines.filter(line => /error \w+:/.test(line));
if (errorLines.length > 0) {
fancyLog(`Finished ${ansiColors.green(config.taskName)} ${projectPath} with ${errorLines.length} errors.`);
for (const line of errorLines) {
fancyLog(line);
}
fancyLog(`Finished ${ansiColors.green(config.taskName)} ${projectPath} with ${errorLines.length} errors.`);
for (const line of errorLines) {
fancyLog(line);
}
}

const args = ['tsgo', '--project', projectPath, '--pretty', 'false'];
const args = ['tsgo', '--project', projectPath, '--pretty', 'false', '--incremental'];
if (config.noEmit) {
args.push('--noEmit');
} else {
Expand Down
1 change: 1 addition & 0 deletions extensions/configuration-editing/.vscodeignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
test/**
src/**
tsconfig*.json
**/*.tsbuildinfo
out/**
esbuild*
package-lock.json
Expand Down
Loading
Loading