Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
92a3158
style: improve CSS selector performance and maintainability by avoidi…
mrleemurray Aug 18, 2026
3d262c5
fix: center Modern UI panel title tabs in the 32px header
cipheraxat Aug 19, 2026
74225c2
modern ui: reset panel title border-top fully and focus regression test
cipheraxat Aug 19, 2026
4008ee0
chore: shorten code comments in panel tab fix
cipheraxat Aug 19, 2026
bc9e689
Merge branch 'main' into fix/331013-panel-tab-padding
cipheraxat Aug 19, 2026
5392037
Merge branch 'main' into fix/331013-panel-tab-padding
cipheraxat Aug 19, 2026
4d652f1
Merge branch 'main' into fix/331013-panel-tab-padding
cipheraxat Aug 19, 2026
0d5a370
Use Agent Host configuration for proxy settings (#331488)
chrmarti Aug 19, 2026
7ead38d
Modern UI: Fix hover background color for inactive tabs in active and…
mrleemurray Aug 19, 2026
b5f99ab
fix: memory leak in mainThreadDocumentsAndEditors (#331170)
SimonSiefke Aug 19, 2026
22fee65
Merge pull request #331490 from microsoft/mrleemurray/ratty-aqua-chin…
mrleemurray Aug 19, 2026
773e610
Await Workspace Trust transition completion in setUrisTrust() (#328626)
zainnadeem786 Aug 19, 2026
48ceba3
Agents - do not show "Create Session from Pull Request" action for wo…
lszomoru Aug 19, 2026
716116e
Fix package.json hover metadata broken in npm 12+ (#327951)
guimmd2 Aug 19, 2026
965b939
Update file icon mask properties for improved styling (#331640)
mrleemurray Aug 19, 2026
aabaf29
markdown: chore: schedule editor dependency updates (#331631)
ulugbekna Aug 19, 2026
90e3f90
Update @vscode/codicons to version 0.0.46-37 and add new icons (#331630)
mrleemurray Aug 19, 2026
6a69379
Batch Agent Host session catalog updates (#331446)
Copilot Aug 19, 2026
2c79ffb
sessions: fix: guard chat grid neighbor lookup before layout (#331617)
ulugbekna Aug 19, 2026
c6f9c7c
Merge pull request #331612 from cipheraxat/fix/331013-panel-tab-padding
mrleemurray Aug 19, 2026
30491a4
Modern UI: Update activity bar background colors (#331628)
mrleemurray Aug 19, 2026
5b7b8b5
Preserve user-defined casing for File Explorer workspace titles (#331…
mrleemurray Aug 19, 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
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ updates:
directory: "/extensions/markdown-language-features"
schedule:
interval: "daily"
time: "16:00"
timezone: "America/Los_Angeles"
allow:
- dependency-name: "@vscode/markdown-editor"
1 change: 1 addition & 0 deletions .github/instructions/css-best-practices.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ applyTo: "**/*.css"
## Selectors

- Avoid `:has()` selectors. Because their result depends on descendant state, DOM mutations can invalidate styles on ancestors and cause expensive style recalculation, especially when selectors are broadly scoped. Instead, represent the state explicitly with a class or data attribute on the smallest container you own, and scope selectors to that marker. Add and remove the marker together with the state it represents.
- Never match the `class` attribute by substring (`[class*="…"]`, `[class^="…"]`, `[class$="…"]`). A single such selector anywhere in the workbench stylesheet defeats Blink's per-class invalidation: every `classList` change then forces a style recalculation for that element, even when no rule references the class that changed. Measured on a 3.7k-node workbench, the ten `[class*="monaco-decoration-itemColor"]` selectors in the Modern UI tab styles alone made a full style recalculation 2.4x slower. When a class carries a generated suffix, have the code that applies it also set a stable marker class (see `DECORATION_LABEL_COLOR_CLASS`) and match that instead.
5 changes: 5 additions & 0 deletions .vscode-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ const extensions = [
workspaceFolder: path.join(os.tmpdir(), `confeditout-${Math.floor(Math.random() * 100000)}`),
mocha: { timeout: 60_000 }
},
{
label: 'npm',
workspaceFolder: path.join(os.tmpdir(), `npmout-${Math.floor(Math.random() * 100000)}`),
mocha: { timeout: 60_000 }
},
{
label: 'github-authentication',
workspaceFolder: path.join(os.tmpdir(), `msft-auth-${Math.floor(Math.random() * 100000)}`),
Expand Down
40 changes: 40 additions & 0 deletions extensions/npm/src/features/npmViewParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface ViewPackageInfo {
description: string;
version?: string;
time?: string;
homepage?: string;
installedVersion?: string;
}

export interface NpmViewRecord {
description?: string;
version?: string;
homepage?: string;
time?: { [version: string]: string };
'dist-tags.latest'?: string;
}

/**
* Parses the output of `npm view --json`. npm 12+ always returns an array `[{...}]`,
* even for a single package, while older versions return the object directly.
*/
export function parseNpmViewOutput(stdout: string): ViewPackageInfo | undefined {
try {
const parsed = JSON.parse(stdout) as NpmViewRecord | NpmViewRecord[];
const content = Array.isArray(parsed) ? parsed[0] : parsed;
const version = content['dist-tags.latest'] || content.version;
return {
description: content.description ?? '',
version,
time: version ? content.time?.[version] : undefined,
homepage: content.homepage
};
} catch (e) {
return undefined;
}
}
25 changes: 2 additions & 23 deletions extensions/npm/src/features/packageJSONContribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Location } from 'jsonc-parser';
import type * as cp from 'child_process';
import { dirname } from 'path';
import { fromNow } from './date';
import { parseNpmViewOutput, ViewPackageInfo } from './npmViewParser';

const LIMIT = 40;

Expand Down Expand Up @@ -325,21 +326,7 @@ export class PackageJSONContribution implements IJSONContribution {
private async npmView(npmCommandPath: string, pack: string, resource: Uri | undefined): Promise<ViewPackageInfo | undefined> {
const args = ['view', '--json', '--', pack, 'description', 'dist-tags.latest', 'homepage', 'version', 'time'];
const stdout = await this.runNpmCommand(npmCommandPath, args, resource);
if (stdout) {
try {
const content = JSON.parse(stdout);
const version = content['dist-tags.latest'] || content['version'];
return {
description: content['description'],
version,
time: content.time?.[version],
homepage: content['homepage']
};
} catch (e) {
// ignore
}
}
return undefined;
return stdout ? parseNpmViewOutput(stdout) : undefined;
}

private async npmjsView(pack: string): Promise<ViewPackageInfo | undefined> {
Expand Down Expand Up @@ -429,11 +416,3 @@ interface SearchPackageInfo {
version?: string;
links?: { homepage?: string };
}

interface ViewPackageInfo {
description: string;
version?: string;
time?: string;
homepage?: string;
installedVersion?: string;
}
42 changes: 42 additions & 0 deletions extensions/npm/src/test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as path from 'path';
import * as testRunner from '../../../../test/integration/electron/testrunner';

const options: import('mocha').MochaOptions = {
ui: 'tdd',
color: true,
timeout: 60000
};

// These integration tests is being run in multiple environments (electron, web, remote)
// so we need to set the suite name based on the environment as the suite name is used
// for the test results file name
let suite = '';
if (process.env.VSCODE_BROWSER) {
suite = `${process.env.VSCODE_BROWSER} Browser Integration Npm Tests`;
} else if (process.env.REMOTE_VSCODE) {
suite = 'Remote Integration Npm Tests';
} else {
suite = 'Integration Npm Tests';
}

if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY || process.env.GITHUB_WORKSPACE) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY || process.env.GITHUB_WORKSPACE || __dirname,
`test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}

testRunner.configure(options);

export = testRunner;
105 changes: 105 additions & 0 deletions extensions/npm/src/test/npmViewParser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as assert from 'assert';
import { NpmViewRecord, parseNpmViewOutput } from '../features/npmViewParser';

const npmViewOutput: NpmViewRecord = {
description: 'React is a JavaScript library for building user interfaces.',
'dist-tags.latest': '19.1.0',
homepage: 'https://react.dev/',
version: '19.1.0',
time: {
'19.1.0': '2025-05-20T20:58:48.397Z',
'0.0.0-experimental-98e8ed76': '2026-07-25T21:39:01.123Z'
}
};

suite('npmViewParser', () => {

test('parses object output (npm <= 11)', () => {
const info = parseNpmViewOutput(JSON.stringify(npmViewOutput));
assert.ok(info);
assert.strictEqual(info!.description, 'React is a JavaScript library for building user interfaces.');
assert.strictEqual(info!.version, '19.1.0');
assert.strictEqual(info!.time, '2025-05-20T20:58:48.397Z');
assert.strictEqual(info!.homepage, 'https://react.dev/');
});

test('parses array output (npm 12+)', () => {
const info = parseNpmViewOutput(JSON.stringify([npmViewOutput]));
assert.ok(info);
assert.strictEqual(info!.description, 'React is a JavaScript library for building user interfaces.');
assert.strictEqual(info!.version, '19.1.0');
assert.strictEqual(info!.time, '2025-05-20T20:58:48.397Z');
assert.strictEqual(info!.homepage, 'https://react.dev/');
});

test('prefers dist-tags.latest over version', () => {
const info = parseNpmViewOutput(JSON.stringify({
'dist-tags.latest': '19.1.0',
version: '0.0.0-experimental-98e8ed76',
time: {
'19.1.0': '2025-05-20T20:58:48.397Z',
'0.0.0-experimental-98e8ed76': '2026-07-25T21:39:01.123Z'
}
}));
assert.ok(info);
assert.strictEqual(info!.version, '19.1.0');
assert.strictEqual(info!.time, '2025-05-20T20:58:48.397Z');
assert.notStrictEqual(info!.time, '2026-07-25T21:39:01.123Z');
});

test('uses the first element when the array contains multiple packages', () => {
const first = { ...npmViewOutput, description: 'first package' };
const second = { ...npmViewOutput, description: 'second package' };
const info = parseNpmViewOutput(JSON.stringify([first, second]));
assert.ok(info);
assert.strictEqual(info!.description, 'first package');
});

test('falls back to the version field when dist-tags.latest is missing', () => {
const info = parseNpmViewOutput(JSON.stringify([
{ version: '0.0.0-experimental-98e8ed76', time: { '0.0.0-experimental-98e8ed76': '2026-07-25T21:39:01.123Z' } }
]));
assert.ok(info);
assert.strictEqual(info!.version, '0.0.0-experimental-98e8ed76');
assert.strictEqual(info!.time, '2026-07-25T21:39:01.123Z');
assert.strictEqual(info!.description, '');
assert.strictEqual(info!.homepage, undefined);
});

test('returns undefined version and time when neither field is present', () => {
const info = parseNpmViewOutput(JSON.stringify({ description: 'React is a JavaScript library for building user interfaces.' }));
assert.ok(info);
assert.strictEqual(info!.version, undefined);
assert.strictEqual(info!.time, undefined);
});

test('returns empty description when description is missing', () => {
const info = parseNpmViewOutput(JSON.stringify({ 'dist-tags.latest': '19.1.0' }));
assert.ok(info);
assert.strictEqual(info!.description, '');
assert.strictEqual(info!.version, '19.1.0');
});

test('returns undefined time when the resolved version has no matching time entry', () => {
const info = parseNpmViewOutput(JSON.stringify({ 'dist-tags.latest': '19.1.0', time: { '18.3.1': '2024-04-26T09:39:52.159Z' } }));
assert.ok(info);
assert.strictEqual(info!.version, '19.1.0');
assert.strictEqual(info!.time, undefined);
});

test('returns undefined for invalid JSON', () => {
assert.strictEqual(parseNpmViewOutput('not json'), undefined);
assert.strictEqual(parseNpmViewOutput('{'), undefined);
assert.strictEqual(parseNpmViewOutput(''), undefined);
});

test('returns undefined for non-object output', () => {
assert.strictEqual(parseNpmViewOutput('null'), undefined);
assert.strictEqual(parseNpmViewOutput('[]'), undefined);
});
});
1 change: 1 addition & 0 deletions extensions/theme-abyss/themes/abyss-color-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@
"surface.border": "#00000000",
"modernActivityBar.activeBackground": "#08286b",
"modernActivityBar.hoverBackground": "#08286b87",
"modernActivityBar.background": "#00000000",
},
"semanticHighlighting": true
}
1 change: 1 addition & 0 deletions extensions/theme-defaults/themes/dark_vs.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"surface.border": "#252526",
"modernActivityBar.activeBackground": "#1E1E1E",
"modernActivityBar.hoverBackground": "#1E1E1E66",
"modernActivityBar.background": "#00000000",
},
"tokenColors": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
"agentsCard.border": "#00000000",
// modern ui
"surface.border": "#00000000",
"modernActivityBar.background": "#00000000",
"modernActivityBar.activeBackground": "#353535",
"modernActivityBar.hoverBackground": "#35353566",
},
"tokenColors": [
{
Expand Down
1 change: 1 addition & 0 deletions extensions/theme-monokai/themes/monokai-color-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"terminal.ansiBrightWhite": "#f8f8f2",
// modern ui
"surface.border": "#272822",
"modernActivityBar.background": "#00000000",
},
"tokenColors": [
{
Expand Down
3 changes: 3 additions & 0 deletions extensions/theme-red/themes/Red-color-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"surface.border": "#00000000",
// "agentsBottomPanel.border": "#00000000",
// "agentsCard.border": "#00000000",
"modernActivityBar.background": "#00000000",
"modernActivityBar.activeBackground": "#580000",
"modernActivityBar.hoverBackground": "#58000087",
},
"tokenColors": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@
"surface.border": "#00222c",
"modernActivityBar.activeBackground": "#005A6F",
"modernActivityBar.hoverBackground": "#005A6F87",
"modernActivityBar.background": "#00000000",
},
"semanticHighlighting": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@
// modern ui
"surface.border": "#ddd6c1",
"modernActivityBar.activeBackground": "#DFCA88",
"modernActivityBar.background": "#00000000",
},
"semanticHighlighting": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"agentsCard.border": "#00000000",
// modern ui
"surface.border": "#00000000",
"modernActivityBar.background": "#00000000",
},
"tokenColors": [
{
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
"@microsoft/mxc-sdk": "0.7.0",
"@parcel/watcher": "^2.5.6",
"@types/semver": "^7.5.8",
"@vscode/codicons": "^0.0.46-36",
"@vscode/codicons": "^0.0.46-37",
"@vscode/copilot-api": "^0.5.2",
"@vscode/deviceid": "^0.1.1",
"@vscode/diff": "0.0.2-7",
Expand Down
8 changes: 4 additions & 4 deletions remote/web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion remote/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"dependencies": {
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@vscode/codicons": "^0.0.46-36",
"@vscode/codicons": "^0.0.46-37",
"@vscode/iconv-lite-umd": "0.7.1",
"@vscode/tree-sitter-wasm": "^0.3.1",
"@vscode/vscode-languagedetection": "1.0.23",
Expand Down
3 changes: 3 additions & 0 deletions src/vs/base/common/codiconsLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -762,4 +762,7 @@ export const codiconsLibrary = {
xai: register('xai', 0xecec),
arrowCircleUpSparkle: register('arrow-circle-up-sparkle', 0xeced),
closeSmall: register('close-small', 0xecee),
bookCompact: register('book-compact', 0xecef),
micOff: register('mic-off', 0xecf0),
micOffCompact: register('mic-off-compact', 0xecf1),
} as const;
Loading
Loading