Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
849d97e
smooth panel animations
eli-w-king Feb 9, 2026
ba7ffdb
faster transitions
eli-w-king Feb 9, 2026
09eede5
fixed command palette animation
eli-w-king Feb 9, 2026
c6a5412
fixed full screen bug
eli-w-king Feb 9, 2026
ac6fb3b
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 9, 2026
572f142
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 9, 2026
fe391a6
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 10, 2026
f3349e3
added subtle fade, fixed command palette
eli-w-king Feb 10, 2026
57c442b
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 10, 2026
42f2854
Initial plan
Copilot Feb 10, 2026
9040876
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 10, 2026
a650799
Fix transitionend event filtering for quick input animations
Copilot Feb 11, 2026
f6d820e
Merge pull request #294261 from microsoft/copilot/sub-pr-294021
eli-w-king Feb 11, 2026
4b7db41
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 11, 2026
f491c58
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 11, 2026
6384830
Refactor view visibility management and centralize animation logic
benibenj Feb 11, 2026
6d68704
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 11, 2026
797e995
Initial plan
Copilot Feb 11, 2026
83c7589
Updating no auth widget for agent welcome
cwebster-99 Feb 11, 2026
f8aa99f
Refactor quick input animations to use CSS classes instead of inline …
Copilot Feb 11, 2026
69cd1ec
Fix entrance animation cleanup to preserve visibility and remove trai…
Copilot Feb 11, 2026
bd3b736
Add comments to document CSS animation duration constants and display…
Copilot Feb 11, 2026
c4f5414
Advertise full context rather than just prompt (#294696)
lramos15 Feb 11, 2026
6fccacb
Merge pull request #294704 from microsoft/copilot/sub-pr-294021
eli-w-king Feb 11, 2026
e76d0c4
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 11, 2026
b714f06
Merge pull request #294706 from microsoft/evident-roundworm
cwebster-99 Feb 11, 2026
0356195
Clean up esbuilding of extensions
mjbvz Feb 11, 2026
438d64a
Improve tips styling and behavior (#294702)
meganrogge Feb 12, 2026
dd8c734
Simplify quick input animations with CSS @keyframes (#294737)
Copilot Feb 12, 2026
cb714c7
Addressing code review comments
mjbvz Feb 12, 2026
e77cb13
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 12, 2026
5423e1a
Update ignore file list
mjbvz Feb 12, 2026
5cf6aa6
slowed animations by 25ms
eli-w-king Feb 12, 2026
252f81c
Update hook settings (#294732)
pwang347 Feb 12, 2026
ff2c046
Refactor quick input exit animation cleanup to eliminate duplication …
Copilot Feb 12, 2026
849d938
fixed unused error
eli-w-king Feb 12, 2026
e8cc00b
restored codicon.ttf
eli-w-king Feb 12, 2026
d04bc91
Apply suggestion from @TylerLeonhardt
TylerLeonhardt Feb 12, 2026
3ce73d4
Apply suggestion from @TylerLeonhardt
TylerLeonhardt Feb 12, 2026
7566dfb
Switch to unified `js/ts` settings for inlay hints
mjbvz Feb 12, 2026
b288514
Merge branch 'main' into eli/workbench-motion
eli-w-king Feb 12, 2026
9134030
adjusted speed
eli-w-king Feb 12, 2026
2354a3c
add `chat.autoReply` (#294715)
meganrogge Feb 12, 2026
386be26
Fix vertical alignment of Last Synced label in Settings header (#294663)
Copilot Feb 12, 2026
7e632ad
Merge pull request #294021 from microsoft/eli/workbench-motion
eli-w-king Feb 12, 2026
6c1af3f
Add customizations telemetry (#294741)
pwang347 Feb 12, 2026
962b547
Hook parsing fixes (#294745)
pwang347 Feb 12, 2026
317a20c
Merge pull request #294742 from mjbvz/dev/mjbvz/wicked-boa
mjbvz Feb 12, 2026
5cc2b2a
Merge pull request #294716 from microsoft/dev/mjbvz/more-esbuild-ext-…
mjbvz Feb 12, 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
14 changes: 9 additions & 5 deletions build/gulpfile.extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ const tasks = compilations.map(function (tsconfigFile) {
const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, async () => {
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'], { dot: true }));
const copyNonTs = util.streamToPromise(nonts.pipe(gulp.dest(out)));
const tsgo = spawnTsgo(absolutePath, { reporterId: 'extensions' }, () => rewriteTsgoSourceMappingUrlsIfNeeded(false, out, baseUrl));
const tsgo = spawnTsgo(absolutePath, { taskName: 'extensions' }, () => rewriteTsgoSourceMappingUrlsIfNeeded(false, out, baseUrl));

await Promise.all([copyNonTs, tsgo]);
}));
Expand All @@ -175,7 +175,7 @@ const tasks = compilations.map(function (tsconfigFile) {
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'], { dot: true }));
const watchInput = watcher(src, { ...srcOpts, ...{ readDelay: 200 } });
const watchNonTs = watchInput.pipe(filter(['**', '!**/*.ts'], { dot: true })).pipe(gulp.dest(out));
const tsgoStream = watchInput.pipe(util.debounce(() => createTsgoStream(absolutePath, { reporterId: 'extensions' }, () => rewriteTsgoSourceMappingUrlsIfNeeded(false, out, baseUrl)), 200));
const tsgoStream = watchInput.pipe(util.debounce(() => createTsgoStream(absolutePath, { taskName: 'extensions' }, () => rewriteTsgoSourceMappingUrlsIfNeeded(false, out, baseUrl)), 200));
const watchStream = es.merge(nonts.pipe(gulp.dest(out)), watchNonTs, tsgoStream);

return watchStream;
Expand Down Expand Up @@ -276,9 +276,9 @@ gulp.task(watchWebExtensionsTask);
async function buildWebExtensions(isWatch: boolean): Promise<void> {
const extensionsPath = path.join(root, 'extensions');

// Find all esbuild-browser.ts files
// Find all esbuild.browser.mts files
const esbuildConfigLocations = await nodeUtil.promisify(glob)(
path.join(extensionsPath, '**', 'esbuild-browser.ts'),
path.join(extensionsPath, '**', 'esbuild.browser.mts'),
{ ignore: ['**/node_modules'] }
);

Expand All @@ -293,7 +293,11 @@ async function buildWebExtensions(isWatch: boolean): Promise<void> {

// Esbuild for extensions
if (esbuildConfigLocations.length > 0) {
promises.push(ext.esbuildExtensions('packaging web extension (esbuild)', isWatch, esbuildConfigLocations.map(script => ({ script }))));
promises.push(
ext.esbuildExtensions('packaging web extension (esbuild)', isWatch, esbuildConfigLocations.map(script => ({ script }))),
// Also run type check on extensions
...esbuildConfigLocations.map(script => ext.typeCheckExtension(path.dirname(script), true))
);
}

// Run webpack for remaining extensions
Expand Down
50 changes: 34 additions & 16 deletions build/lib/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { getProductionDependencies } from './dependencies.ts';
import { type IExtensionDefinition, getExtensionStream } from './builtInExtensions.ts';
import { getVersion } from './getVersion.ts';
import { fetchUrls, fetchGithub } from './fetch.ts';
import { createTsgoStream, spawnTsgo } from './tsgo.ts';
import vzip from 'gulp-vinyl-zip';

import { createRequire } from 'module';
Expand Down Expand Up @@ -67,23 +68,27 @@ function updateExtensionPackageJSON(input: Stream, update: (data: any) => any):
function fromLocal(extensionPath: string, forWeb: boolean, disableMangle: boolean): Stream {

const esbuildConfigFileName = forWeb
? 'esbuild-browser.ts'
: 'esbuild.ts';
? 'esbuild.browser.mts'
: 'esbuild.mts';

const webpackConfigFileName = forWeb
? `extension-browser.webpack.config.js`
: `extension.webpack.config.js`;

const hasEsbuild = fs.existsSync(path.join(extensionPath, esbuildConfigFileName));
const isWebPacked = fs.existsSync(path.join(extensionPath, webpackConfigFileName));
const hasWebpack = fs.existsSync(path.join(extensionPath, webpackConfigFileName));

let input: Stream;
let isBundled = false;

if (hasEsbuild) {
input = fromLocalEsbuild(extensionPath, esbuildConfigFileName);
// Unlike webpack, esbuild only does bundling so we still want to run a separate type check step
input = es.merge(
fromLocalEsbuild(extensionPath, esbuildConfigFileName),
typeCheckExtensionStream(extensionPath, forWeb),
);
isBundled = true;
} else if (isWebPacked) {
} else if (hasWebpack) {
input = fromLocalWebpack(extensionPath, webpackConfigFileName, disableMangle);
isBundled = true;
} else {
Expand All @@ -105,6 +110,17 @@ function fromLocal(extensionPath: string, forWeb: boolean, disableMangle: boolea
return input;
}

export function typeCheckExtension(extensionPath: string, forWeb: boolean): Promise<void> {
const tsconfigFileName = forWeb ? 'tsconfig.browser.json' : 'tsconfig.json';
const tsconfigPath = path.join(extensionPath, tsconfigFileName);
return spawnTsgo(tsconfigPath, { taskName: 'typechecking extension (tsgo)', noEmit: true });
}

export function typeCheckExtensionStream(extensionPath: string, forWeb: boolean): Stream {
const tsconfigFileName = forWeb ? 'tsconfig.browser.json' : 'tsconfig.json';
const tsconfigPath = path.join(extensionPath, tsconfigFileName);
return createTsgoStream(tsconfigPath, { taskName: 'typechecking extension (tsgo)', noEmit: true });
}

function fromLocalWebpack(extensionPath: string, webpackConfigFileName: string, disableMangle: boolean): Stream {
const vsce = require('@vscode/vsce') as typeof import('@vscode/vsce');
Expand Down Expand Up @@ -267,6 +283,7 @@ function fromLocalEsbuild(extensionPath: string, esbuildConfigFileName: string):
if (error) {
return reject(error);
}

const matches = (stderr || '').match(/\> (.+): error: (.+)?/g);
fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), esbuildConfigFileName))} with ${matches ? matches.length : 0} errors.`);
for (const match of matches || []) {
Expand Down Expand Up @@ -632,17 +649,6 @@ export function translatePackageJSON(packageJSON: string, packageNLSPath: string

const extensionsPath = path.join(root, 'extensions');

// Additional projects to run esbuild on. These typically build code for webviews
const esbuildMediaScripts = [
'ipynb/esbuild.mjs',
'markdown-language-features/esbuild-notebook.mjs',
'markdown-language-features/esbuild-preview.mjs',
'markdown-math/esbuild.mjs',
'mermaid-chat-features/esbuild-chat-webview.mjs',
'notebook-renderers/esbuild.mjs',
'simple-browser/esbuild-preview.mjs',
];

export async function webpackExtensions(taskName: string, isWatch: boolean, webpackConfigLocations: { configPath: string; outputRoot?: string }[]) {
const webpack = require('webpack') as typeof import('webpack');

Expand Down Expand Up @@ -742,6 +748,18 @@ export async function esbuildExtensions(taskName: string, isWatch: boolean, scri
await Promise.all(tasks);
}


// Additional projects to run esbuild on. These typically build code for webviews
const esbuildMediaScripts = [
'ipynb/esbuild.notebook.mts',
'markdown-language-features/esbuild.notebook.mts',
'markdown-language-features/esbuild.webview.mts',
'markdown-math/esbuild.notebook.mts',
'mermaid-chat-features/esbuild.webview.mts',
'notebook-renderers/esbuild.notebook.mts',
'simple-browser/esbuild.webview.mts',
];

export function buildExtensionMedia(isWatch: boolean, outputRoot?: string): Promise<void> {
return esbuildExtensions('esbuilding extension media', isWatch, esbuildMediaScripts.map(p => ({
script: path.join(extensionsPath, p),
Expand Down
14 changes: 14 additions & 0 deletions build/lib/policies/policyData.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,20 @@
"type": "boolean",
"default": true
},
{
"key": "chat.useHooks",
"name": "ChatHooks",
"category": "InteractiveSession",
"minimumVersion": "1.109",
"localization": {
"description": {
"key": "chat.useHooks.description",
"value": "Controls whether chat hooks are executed at strategic points during an agent's workflow. Hooks are loaded from the files configured in `#chat.hookFilesLocations#`."
}
},
"type": "boolean",
"default": true
},
{
"key": "chat.tools.terminal.enableAutoApprove",
"name": "ChatToolsTerminalEnableAutoApprove",
Expand Down
56 changes: 19 additions & 37 deletions build/lib/tsgo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,31 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import ansiColors from 'ansi-colors';
import * as cp from 'child_process';
import es from 'event-stream';
import fancyLog from 'fancy-log';
import * as path from 'path';
import { createReporter } from './reporter.ts';

const root = path.dirname(path.dirname(import.meta.dirname));
const npx = process.platform === 'win32' ? 'npx.cmd' : 'npx';
const ansiRegex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;

export function spawnTsgo(projectPath: string, config: { reporterId: string }, onComplete?: () => Promise<void> | void): Promise<void> {
const reporter = createReporter(config.reporterId);
let report: NodeJS.ReadWriteStream | undefined;

const beginReport = (emitError: boolean) => {
if (report) {
report.end();
}
report = reporter.end(emitError);
};

const endReport = () => {
if (!report) {
return;
export function spawnTsgo(projectPath: string, config: { taskName: string; noEmit?: boolean }, onComplete?: () => Promise<void> | void): Promise<void> {
function reporter(stdError: string) {
const matches = (stdError || '').match(/^error \w+: (.+)?/g);
fancyLog(`Finished ${ansiColors.green(config.taskName)} ${projectPath} with ${matches ? matches.length : 0} errors.`);
for (const match of matches || []) {
fancyLog.error(match);
}
report.end();
report = undefined;
};

beginReport(false);

const args = ['tsgo', '--project', projectPath, '--pretty', 'false', '--sourceMap', '--inlineSources'];
}

const args = ['tsgo', '--project', projectPath, '--pretty', 'false'];
if (config.noEmit) {
args.push('--noEmit');
} else {
args.push('--sourceMap', '--inlineSources');
}
const child = cp.spawn(npx, args, {
cwd: root,
stdio: ['ignore', 'pipe', 'pipe'],
Expand All @@ -47,23 +41,13 @@ export function spawnTsgo(projectPath: string, config: { reporterId: string }, o
return;
}
if (/Starting compilation|File change detected/i.test(trimmed)) {
beginReport(false);
return;
}
if (/Compilation complete/i.test(trimmed)) {
endReport();
return;
}

const match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(trimmed);

if (match) {
const fullpath = path.isAbsolute(match[1]) ? match[1] : path.join(root, match[1]);
const message = match[3];
reporter(fullpath + message);
} else {
reporter(trimmed);
}
reporter(trimmed);
};

const handleData = (data: Buffer) => {
Expand All @@ -84,7 +68,7 @@ export function spawnTsgo(projectPath: string, config: { reporterId: string }, o
handleLine(buffer);
buffer = '';
}
endReport();

if (code === 0) {
Promise.resolve(onComplete?.()).then(() => resolve(), reject);
} else {
Expand All @@ -93,15 +77,13 @@ export function spawnTsgo(projectPath: string, config: { reporterId: string }, o
});

child.on('error', err => {
endReport();
reject(err);
});
});
}

export function createTsgoStream(projectPath: string, config: { reporterId: string }, onComplete?: () => Promise<void> | void): NodeJS.ReadWriteStream {
export function createTsgoStream(projectPath: string, config: { taskName: string; noEmit?: boolean }, onComplete?: () => Promise<void> | void): NodeJS.ReadWriteStream {
const stream = es.through();

spawnTsgo(projectPath, config, onComplete).then(() => {
stream.emit('end');
}).catch(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,22 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// @ts-check

/**
* @fileoverview Common build script for extension scripts used in in webviews.
* Common build script for extension scripts used in in webviews.
*/
import path from 'node:path';
import esbuild from 'esbuild';

/**
* @typedef {Partial<import('esbuild').BuildOptions> & {
* entryPoints: string[] | Record<string, string> | { in: string, out: string }[];
* outdir: string;
* }} BuildOptions
*/
export type BuildOptions = Partial<esbuild.BuildOptions> & {
entryPoints: string[] | Record<string, string> | { in: string; out: string }[];
outdir: string;
};

/**
* Build the source code once using esbuild.
*
* @param {BuildOptions} options
* @param {(outDir: string) => unknown} [didBuild]
*/
async function build(options, didBuild) {
async function build(options: BuildOptions, didBuild?: (outDir: string) => unknown): Promise<void> {
await esbuild.build({
bundle: true,
minify: true,
Expand All @@ -38,29 +33,25 @@ async function build(options, didBuild) {

/**
* Build the source code once using esbuild, logging errors instead of throwing.
*
* @param {BuildOptions} options
* @param {(outDir: string) => unknown} [didBuild]
*/
async function tryBuild(options, didBuild) {
async function tryBuild(options: BuildOptions, didBuild?: (outDir: string) => unknown): Promise<void> {
try {
await build(options, didBuild);
} catch (err) {
console.error(err);
}
}

/**
* @param {{
* srcDir: string;
* outdir: string;
* entryPoints: string[] | Record<string, string> | { in: string, out: string }[];
* additionalOptions?: Partial<import('esbuild').BuildOptions>
* }} config
* @param {string[]} args
* @param {(outDir: string) => unknown} [didBuild]
*/
export async function run(config, args, didBuild) {
export async function run(
config: {
srcDir: string;
outdir: string;
entryPoints: BuildOptions['entryPoints'];
additionalOptions?: Partial<esbuild.BuildOptions>;
},
args: string[],
didBuild?: (outDir: string) => unknown
): Promise<void> {
let outdir = config.outdir;
const outputRootIndex = args.indexOf('--outputRoot');
if (outputRootIndex >= 0) {
Expand All @@ -69,8 +60,7 @@ export async function run(config, args, didBuild) {
outdir = path.join(outputRoot, outputDirName);
}

/** @type {BuildOptions} */
const resolvedOptions = {
const resolvedOptions: BuildOptions = {
entryPoints: config.entryPoints,
outdir,
logOverride: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// @ts-check
import path from 'node:path';
import { run } from '../esbuild-webview-common.mjs';
import { run } from '../esbuild-webview-common.mts';

const srcDir = path.join(import.meta.dirname, 'notebook-src');
const outDir = path.join(import.meta.dirname, 'notebook-out');
Expand Down
2 changes: 1 addition & 1 deletion extensions/ipynb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
"scripts": {
"compile": "npx gulp compile-extension:ipynb && npm run build-notebook",
"watch": "npx gulp watch-extension:ipynb",
"build-notebook": "node ./esbuild.mjs"
"build-notebook": "node ./esbuild.notebook.mts"
},
"dependencies": {
"@enonic/fnv-plus": "^1.3.0",
Expand Down
8 changes: 2 additions & 6 deletions extensions/markdown-language-features/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ test/**
test-workspace/**
src/**
notebook/**
tsconfig.json
tsconfig.*.json
tsconfig*.json
esbuild*
out/test/**
out/**
extension.webpack.config.js
extension-browser.webpack.config.js
cgmanifest.json
package-lock.json
preview-src/**
webpack.config.js
esbuild-*
.gitignore
**/*.d.ts
Loading
Loading