Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b7edac1
nes: feat: implement early cancellation if user's cursor-line changes…
ulugbekna Apr 8, 2026
eb756b1
fix: Add NSLocalNetworkUsageDescription to Info.plist (#308457)
deepak1556 Apr 8, 2026
147c606
Sessions - add noTrack option to worktree creation and adopt new opti…
lszomoru Apr 8, 2026
f006960
convert built-in prompt files to skills (#308472)
aeschli Apr 8, 2026
9f15197
Adds memory file path support to the artifacts view
hediet Apr 8, 2026
e62187b
Restrict memory tool invocations to specific tool ID in artifact extr…
hediet Apr 8, 2026
5207a1a
Update Responses API compaction and telemetry (#308436)
dileepyavan Apr 8, 2026
e9c8a5c
disable copilot chat extension by default and adopt accordingly (#308…
sandy081 Apr 8, 2026
5be5cff
nes: fix: NES cache should respect line endings when applying edits t…
ulugbekna Apr 8, 2026
a63d14d
Initial plan
Copilot Apr 8, 2026
d789bac
Fix duplicated Fix entry points on marker hover
Copilot Apr 8, 2026
1434429
Fix env.open external not working on folders (#308492)
lramos15 Apr 8, 2026
5fe8ed6
nes: cleanup: unite params by semantic proximity into entities (#308481)
ulugbekna Apr 8, 2026
d7286a4
Merge pull request #308488 from microsoft/copilot/fix-duplicate-fix-e…
jrieken Apr 8, 2026
71404a1
fix: add keybinding expression for hiding inline suggestions (#308187)
jrieken Apr 8, 2026
98f1161
nes: add tests for cursor jump and recursion (#308499)
ulugbekna Apr 8, 2026
72189fe
bump distro (#308498)
joaomoreno Apr 8, 2026
0ff0f8b
inlineChat: remove gutter affordance experiment
jrieken Apr 8, 2026
8be4565
update d.ts in copilot (#308502)
aeschli Apr 8, 2026
065a133
adds more NES fixtures
hediet Apr 8, 2026
7f5c298
Sessions - fix changes view when initializing a repository (#308513)
lszomoru Apr 8, 2026
1f40e56
ci: bump github runner to ubuntu-24.04 to address fontconfig crash (…
deepak1556 Apr 8, 2026
82030bd
Merge pull request #308512 from microsoft/joh/remove-gutter-affordance
jrieken Apr 8, 2026
9b1276d
mark auto updatable built in extensions as application scoped always …
sandy081 Apr 8, 2026
23fcfdd
add tools and model to ChatCustomAgent (#308523)
aeschli Apr 8, 2026
5f30c37
remove internal skill support (#308467)
aeschli Apr 8, 2026
4a5375b
Bump @hono/node-server from 1.19.10 to 1.19.13 in /test/mcp (#308403)
dependabot[bot] Apr 8, 2026
eb014b6
Bump hono from 4.12.7 to 4.12.12 in /test/mcp (#308404)
dependabot[bot] Apr 8, 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
37 changes: 36 additions & 1 deletion .github/workflows/pr-linux-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
jobs:
linux-test:
name: ${{ inputs.job_name }}
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
env:
ARTIFACT_NAME: ${{ (inputs.electron_tests && 'electron') || (inputs.browser_tests && 'browser') || (inputs.remote_tests && 'remote') || 'unknown' }}
NPM_ARCH: x64
Expand All @@ -36,6 +36,9 @@ jobs:
- name: Setup system services
run: |
set -e
# Allow unprivileged user namespaces for Chromium's namespace sandbox
# Ubuntu 24.04 restricts this by default via AppArmor
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
# Start X server
./build/azure-pipelines/linux/apt-retry.sh sudo apt-get update
./build/azure-pipelines/linux/apt-retry.sh sudo apt-get install -y pkg-config \
Expand Down Expand Up @@ -133,6 +136,38 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Fontconfig diagnostics and cache reset
run: |
set -e
echo "--- Font package versions ---"
dpkg -l | grep -E 'libexpat|fontconfig|libfreetype|libpango' || true
echo ""
echo "--- Installed font packages ---"
apt list --installed 2>/dev/null | grep -E 'fonts-|fontconfig' || true
echo ""
echo "--- Verify fonts.conf integrity ---"
python3 -c "
import xml.etree.ElementTree as ET, glob, sys
for f in ['/etc/fonts/fonts.conf'] + sorted(glob.glob('/etc/fonts/conf.d/*.conf')):
try:
ET.parse(f)
except Exception as e:
print(f'WARNING: {f} is invalid: {e}', file=sys.stderr)
print('Font config XML validation complete')
"
echo ""
echo "--- Check for symlink loops in font dirs ---"
find /usr/share/fonts -maxdepth 3 -type l -exec test -d {} \; -print 2>/dev/null | head -10 || true
echo ""
echo "--- Clear and rebuild font cache ---"
sudo rm -rf /var/cache/fontconfig 2>/dev/null || true
rm -rf ~/.cache/fontconfig 2>/dev/null || true
fc-cache -f -v 2>&1 | tail -5
echo ""
echo "--- fontconfig version ---"
fc-cache --version 2>&1 | head -1
continue-on-error: true

- name: Transpile client and extensions
run: npm run gulp transpile-client-esbuild transpile-extensions

Expand Down
48 changes: 48 additions & 0 deletions build/darwin/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ async function main(buildDir?: string): Promise<void> {
const appRoot = path.join(buildDir, `VSCode-darwin-${arch}`);
const appName = product.nameLong + '.app';
const infoPlistPath = path.resolve(appRoot, appName, 'Contents', 'Info.plist');
const embeddedInfoPlistPath = product.embedded
? path.resolve(appRoot, appName, 'Contents', 'Applications', `${product.embedded.nameShort}.app`, 'Contents', 'Info.plist')
: undefined;

const appOpts: SignOptions = {
app: path.join(appRoot, appName),
Expand Down Expand Up @@ -124,6 +127,51 @@ async function main(buildDir?: string): Promise<void> {
'An application in Visual Studio Code wants to use Audio Capture.',
`${infoPlistPath}`
]);
await spawn('plutil', [
'-insert',
'NSLocalNetworkUsageDescription',
'-string',
'The app uses your local network for DNS resolution and to connect to locally running services.',
`${infoPlistPath}`
]);

if (embeddedInfoPlistPath && fs.existsSync(embeddedInfoPlistPath)) {
await spawn('plutil', [
'-insert',
'NSAppleEventsUsageDescription',
'-string',
`An application in ${product.embedded.nameShort} wants to use AppleScript.`,
`${embeddedInfoPlistPath}`
]);
await spawn('plutil', [
'-replace',
'NSMicrophoneUsageDescription',
'-string',
`An application in ${product.embedded.nameShort} wants to use the Microphone.`,
`${embeddedInfoPlistPath}`
]);
await spawn('plutil', [
'-replace',
'NSCameraUsageDescription',
'-string',
`An application in ${product.embedded.nameShort} wants to use the Camera.`,
`${embeddedInfoPlistPath}`
]);
await spawn('plutil', [
'-replace',
'NSAudioCaptureUsageDescription',
'-string',
`An application in ${product.embedded.nameShort} wants to use Audio Capture.`,
`${embeddedInfoPlistPath}`
]);
await spawn('plutil', [
'-insert',
'NSLocalNetworkUsageDescription',
'-string',
`The app uses your local network for DNS resolution and to connect to locally running services.`,
`${embeddedInfoPlistPath}`
]);
}
}

await retrySignOnKeychainError(() => sign(appOpts));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: agent-customization
user-invocable: false # don't show as slash command, we have sepcialized create-agent, create-instructions, create-hook prompts for that
description: '**WORKFLOW SKILL** — Create, update, review, fix, or debug VS Code agent customization files (.instructions.md, .prompt.md, .agent.md, SKILL.md, copilot-instructions.md, AGENTS.md). USE FOR: saving coding preferences; troubleshooting why instructions/skills/agents are ignored or not invoked; configuring applyTo patterns; defining tool restrictions; creating custom agent modes or specialized workflows; packaging domain knowledge; fixing YAML frontmatter syntax. DO NOT USE FOR: general coding questions (use default agent); runtime debugging or error diagnosis; MCP server configuration (use MCP docs directly); VS Code extension development. INVOKES: file system tools (read/write customization files), ask-questions tool (interview user for requirements), subagents for codebase exploration. FOR SINGLE OPERATIONS: For quick YAML frontmatter fixes or creating a single file from a known pattern, edit the file directly — no skill needed.'
---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: create-agent
description: 'Create a custom agent (.agent.md) for a specific job.'
argument-hint: What job should this agent do and how?
agent: agent
disable-model-invocation: true
---
Related skill: `agent-customization`. Load and follow **agents.md** for template and principles.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: create-hook
description: 'Create a hook (.json) to enforce policy or automate agent lifecycle events.'
argument-hint: What should be enforced or automated?
agent: agent
disable-model-invocation: true
---
Related skill: `agent-customization`. Load and follow **hooks.md** for template and principles.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: create-instructions
description: 'Create an instructions file (.instructions.md) for a project rule or convention.'
argument-hint: What rule or convention to enforce?
agent: agent
disable-model-invocation: true
---
Related skill: `agent-customization`. Load and follow **instructions.md** for template and principles.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: create-prompt
description: 'Create a reusable prompt file (.prompt.md) for a common task.'
argument-hint: What task should this prompt help with?
agent: agent
disable-model-invocation: true
---
Related skill: `agent-customization`. Load and follow **prompts.md** for template and principles.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: create-skill
description: 'Create a reusable skill (SKILL.md) that packages a workflow.'
argument-hint: What should this skill produce?
agent: agent
disable-model-invocation: true
---
Related skill: `agent-customization`. Load and follow **skills.md** for template and principles.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: init
description: Generate or update workspace instructions file for AI coding agents
argument-hint: Optionally specify a focus area or pattern to document for agents
agent: agent
disable-model-invocation: true
---
Related skill: `agent-customization`. Load and follow **workspace-instructions.md** for template, principles, and anti-patterns.

Expand Down
50 changes: 25 additions & 25 deletions extensions/copilot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6152,30 +6152,6 @@
{
"path": "./assets/prompts/plan.prompt.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/init.prompt.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/create-prompt.prompt.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/create-instructions.prompt.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/create-skill.prompt.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/create-agent.prompt.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/create-hook.prompt.md",
"when": "chatSessionType == local"
}
],
"chatSkills": [
Expand All @@ -6202,6 +6178,30 @@
{
"path": "./assets/prompts/skills/agent-customization/SKILL.md",
"when": "chatSessionType == local || chatSessionType == copilotcli"
},
{
"path": "./assets/prompts/skills/init/SKILL.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/skills/create-prompt/SKILL.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/skills/create-instructions/SKILL.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/skills/create-skill/SKILL.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/skills/create-agent/SKILL.md",
"when": "chatSessionType == local"
},
{
"path": "./assets/prompts/skills/create-hook/SKILL.md",
"when": "chatSessionType == local"
}
],
"terminal": {
Expand Down Expand Up @@ -6413,7 +6413,7 @@
"node-gyp": "npm:node-gyp@10.3.1",
"zod": "3.25.76"
},
"vscodeCommit": "20b24833bc088c84b778ee89be4c17f15660441a",
"vscodeCommit": "5be5cffdefe8d8961ea7a21397a936de68b04628",
"__metadata": {
"id": "7ec7d6e6-b89e-4cc5-a59b-d6c4d238246f",
"publisherId": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ParsedPromptFile } from '../../../platform/promptFiles/common/promptsService';
import type { ChatCustomAgent } from 'vscode';
import { createServiceIdentifier } from '../../../util/common/services';
import { Event } from '../../../util/vs/base/common/event';
import { IDisposable } from '../../../util/vs/base/common/lifecycle';
Expand All @@ -13,5 +13,5 @@ export const IChatCustomAgentsService = createServiceIdentifier<IChatCustomAgent
export interface IChatCustomAgentsService extends IDisposable {
readonly _serviceBrand: undefined;
readonly onDidChangeCustomAgents: Event<void>;
getCustomAgents(): ParsedPromptFile[];
getCustomAgents(): readonly ChatCustomAgent[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import { ILogService } from '../../../platform/log/common/logService';
import { IPromptsService, ParsedPromptFile } from '../../../platform/promptFiles/common/promptsService';
import { coalesce } from '../../../util/vs/base/common/arrays';
import { CancellationToken, CancellationTokenSource } from '../../../util/vs/base/common/cancellation';
import { isCancellationError } from '../../../util/vs/base/common/errors';
import { Emitter, Event } from '../../../util/vs/base/common/event';
import { Disposable } from '../../../util/vs/base/common/lifecycle';
import { IChatCustomAgentsService } from '../common/chatCustomAgentsService';
Expand All @@ -19,12 +15,10 @@ export class ChatCustomAgentsService extends Disposable implements IChatCustomAg
private readonly _onDidChangeCustomAgents = this._register(new Emitter<void>());
readonly onDidChangeCustomAgents: Event<void> = this._onDidChangeCustomAgents.event;

private customAgents: ParsedPromptFile[] = [];
private customAgents: readonly vscode.ChatCustomAgent[] = [];
private refreshCts: CancellationTokenSource | undefined;

constructor(
@IPromptsService private readonly promptsService: IPromptsService,
@ILogService private readonly logService: ILogService,
) {
super();

Expand All @@ -35,8 +29,8 @@ export class ChatCustomAgentsService extends Disposable implements IChatCustomAg
this.triggerRefreshCustomAgents();
}

getCustomAgents(): ParsedPromptFile[] {
return [...this.customAgents];
getCustomAgents(): readonly vscode.ChatCustomAgent[] {
return this.customAgents;
}

override dispose(): void {
Expand All @@ -59,23 +53,21 @@ export class ChatCustomAgentsService extends Disposable implements IChatCustomAg
}

private async refreshCustomAgents(token: CancellationToken): Promise<void> {
const parsedAgents = coalesce(await Promise.all(vscode.chat.customAgents.map(async resource => {
try {
return await this.promptsService.parseFile(resource.uri, token);
} catch (error) {
if (isCancellationError(error) || token.isCancellationRequested) {
return undefined;
}
this.logService.error(`[ChatCustomAgentsService] Failed to parse custom agent ${resource.uri.toString()}`, error);
return undefined;
try {
const customAgents = await vscode.chat.getCustomAgents(token);

if (token.isCancellationRequested) {
return;
}
})));

if (token.isCancellationRequested) {
return;
}
this.customAgents = customAgents;
this._onDidChangeCustomAgents.fire();
} catch (error) {
if (token.isCancellationRequested) {
return;
}

this.customAgents = parsedAgents;
this._onDidChangeCustomAgents.fire();
console.error('Failed to refresh custom agents', error);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class ChatSessionWorktreeService extends Disposable implements IChatSessi
}
}

const worktreePath = await this.gitService.createWorktree(activeRepository.rootUri, { branch, commitish: baseBranch });
const worktreePath = await this.gitService.createWorktree(activeRepository.rootUri, { branch, commitish: baseBranch, noTrack: true });

if (worktreePath && activeRepository.headCommitHash && activeRepository.headBranchName) {
const baseBranchName = baseBranch ?? activeRepository.headBranchName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { StopWatch } from '../../../util/vs/base/common/stopwatch';
import { hasKey } from '../../../util/vs/base/common/types';
import { EXTENSION_ID } from '../../common/constants';
import { GitBranchNameGenerator } from '../../prompt/node/gitBranch';
import { IChatSessionMetadataStore } from '../common/chatSessionMetadataStore';
import { IChatSessionMetadataStore, RepositoryProperties } from '../common/chatSessionMetadataStore';
import { IChatSessionWorkspaceFolderService } from '../common/chatSessionWorkspaceFolderService';
import { IChatSessionWorktreeService } from '../common/chatSessionWorktreeService';
import { IChatFolderMruService, IFolderRepositoryManager, IsolationMode } from '../common/folderRepositoryManager';
Expand Down Expand Up @@ -1360,7 +1360,14 @@ export function registerCLIChatCommands(
return;
}

copilotCliWorkspaceSession.trackSessionWorkspaceFolder(sessionId, workspaceFolder.fsPath, repository.headBranchName ? { repositoryPath: repository.rootUri.fsPath, branchName: repository.headBranchName } : undefined);
const repositoryProperties = repository.headBranchName
? {
repositoryPath: repository.rootUri.fsPath,
branchName: repository.headBranchName
} satisfies RepositoryProperties
: undefined;

await copilotCliWorkspaceSession.trackSessionWorkspaceFolder(sessionId, workspaceFolder.fsPath, repositoryProperties);
copilotCliWorkspaceSession.clearWorkspaceChanges(sessionId);

await contentProvider.refreshSession({ reason: 'update', sessionId });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2390,7 +2390,7 @@ export function registerCLIChatCommands(
} satisfies RepositoryProperties
: undefined;

copilotCliWorkspaceSession.trackSessionWorkspaceFolder(sessionId, workspaceFolder.fsPath, repositoryProperties);
await copilotCliWorkspaceSession.trackSessionWorkspaceFolder(sessionId, workspaceFolder.fsPath, repositoryProperties);
copilotCliWorkspaceSession.clearWorkspaceChanges(sessionId);

copilotcliSessionItemProvider.notifySessionsChange();
Expand Down
Loading
Loading