* sessions: animate input banner border while an action is running
The CI checks and comments input banners in the Agents window now show an
animated "border beam" while an async action is running, mirroring the chat
input's in-flight border. This is primarily for the CI "Fix Checks" action,
which spends a noticeable amount of time fetching check annotations before
submitting the prompt.
- SessionInputBannerWidget: action run() may return a promise; while it is
pending the banner gets a `.working` class and its buttons are disabled. The
animation is only shown after a 50ms delay so fast actions don't flicker.
- CSS: added the comet/glow ::before/::after rings (padding + inverted mask
trick) driven by a spinning conic gradient, respecting reduced-motion.
- Color matches the chat input working-border token for comments banners, and
the orange accent (same as the primary button) for CI banners.
- Fix Checks / Address Comments await their work; Reveal Checks stays
fire-and-forget. Added a CIFailuresLoading screenshot fixture.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: address input banner loading review feedback
- Disable banner buttons immediately while an action is pending; only the
animated border is delayed by 50ms to avoid flicker.
- Make the click handler explicitly fire-and-forget and swallow action errors
inside _runAction so it can never produce an unhandled rejection.
- Type _executeCommand cleanly as Promise<void> (await + try/catch) instead of
returning the unknown-typed executeCommand result.
- Expose SessionInputBannerWidget.setWorking so the CIFailuresLoading fixture
reflects the real disabled-button state, not just the .working class.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: register session input banner CSS variables for hygiene
The animated banner border introduced new CSS custom properties that must be
listed in build/lib/stylelint/vscode-known-variables.json, otherwise the
hygiene 'Unknown variable' check fails.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(automations): add foundation — types, storage service, scheduler, leader election
Introduces the Automations subsystem core:
- IAutomation types and IAutomationSchedule (interval-based: manual/hourly/daily/weekly)
- DST-safe computeNextRunAt scheduling logic
- IAutomationService with persistent JSON ledger (StorageScope.APPLICATION)
- Optimistic concurrency via revision counter for cross-window safety
- Leader election to ensure single scheduler instance across windows
- AutomationScheduler: periodic tick loop checking due automations
- Feature gate: chat.automations.enabled setting mirrored to context key
- Unit tests for scheduling logic
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: address Copilot Code Review feedback on PR 1
- Add _unsupportedSchema guard to recordRunStart and updateRun
- Localize CRASH_RECOVERY_REASON string via nls.localize()
- Move imports above registerSingleton call in contribution file
- Fix test comment referencing wrong helper name (buildLocalDate -> localDate)
* fix: address CCR round 2 — schema guards, telemetry cleanup, scope fix
- Add _unsupportedSchema guard to markStaleRunsFailed and advanceNextRunAt
- Replace boolean telemetry flags with actual enum values (permissionLevel, isolationMode)
- Remove hasProviderId, hasSessionTypeId, hasModelId, hasMode, hasPermissionLevel flags
- Add scope: ConfigurationScope.MACHINE to runTimeoutMinutes setting
* fix: gate scheduler construction on chat.automations.enabled
AutomationSchedulerCore (and its leader election heartbeat/storage
writes) are now only constructed when the feature setting is enabled.
Uses MutableDisposable for clean teardown on runtime toggle.
Addresses CCR feedback: avoid 30s heartbeat timer + storage writes
when the feature is disabled.
* fix: isolate per-automation errors in dispatch loop
Wrap advanceNextRunAt + runOneWithTimeout in try/catch so a failure
in one automation does not abort dispatch of remaining due automations.
* fix: register automations path in i18n resources
Adds vs/sessions/contrib/automations to the translation resources
so nls.localize calls pass the eslint translation-remind rule.
* fix: validate enum fields at write boundary and harden persist()
- Normalize permissionLevel/isolationMode in createAutomation and
mergeAutomation: reject unknown values to keep persisted data and
GDPR-classified telemetry low-cardinality.
- Wrap persist() storage read and write in try/catch so storage
failures degrade gracefully instead of breaking the scheduler.
* fix: scheduler to Eventually phase, simplify persist(), document serial dispatch
- Move scheduler registration from AfterRestored to Eventually —
background concern that doesn't need to block workbench restore.
- Remove re-read-before-write in persist() — refreshFromStorage via
onDidChangeValue already handles cross-window sync. Eliminates
redundant JSON.parse on every mutation and the misleading optimistic
concurrency check that overwrote anyway.
- Document that _pendingRuns serializes dispatch intentionally.
* style: remove em dashes and obscure acronyms from comments
Replace all em dashes with periods or semicolons. Remove TOCTOU
acronym. Replace multiplication sign with plain x.
* Signing commit
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* chore: bump electron@42.4.0
* chore: apply temp dir workaround for short paths
* chore: use 24.15.x for CI node
* chore: update nodejs build
* chore: bump electron@42.5.0
* fix: unblock playwright install on node 24.17
Node 24.16+ made Readable pause()/resume() a no-op on destroyed streams
which makes yauzl 2.x / extract-zip 2.x and older playwright extraction
hang forever.
- extensions/copilot: add "yauzl": "^3.3.1" override (was missed by #318682)
so electron and @vscode/vsce no longer resolve the broken yauzl 2.10, fixing the
hung `npm ci` in the Copilot and Extract chat-lib pipelines.
- extensions/copilot: bump electron ^39.8.5 -> ^42.5.0 so its install
script uses the native @electron-internal/extract-zip instead of extract-zip.
- bump @playwright/test ^1.56.1 -> ^1.61.1 so `playwright install`
uses the fixed extractor, unblocking the "Download Electron and
Playwright" step in all electron test pipelines.
* chore: update build
* agentHost: fix macOS sandbox smoke sentinel parsing
On macOS CI, the AgentHost sandbox smoke test resolves the shell to
/bin/sh, which uses the sentinel-based completion path. In that path, the
parser could consume the echoed sentinel command text
(`<<<COPILOT_SENTINEL_..._EXIT_$?>>>`) before the real numeric marker
arrived, causing a false `Exit code: -1` failure even though the command
later completed successfully.
Harden the sentinel parser to ignore echoed/non-numeric sentinel text
and use the latest complete numeric marker instead. Also force the
macOS AgentHost sandbox smoke test to use /bin/sh and assert that in the
suite log so local runs exercise the same path as CI.
Adds a regression test for echoed sentinel command text.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* chore: update screenshot baseline after playwright bump
* chore: bump distro
* chore: fix typecheck
* chore: bump distro
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The GitHub Actions PR test workflows run integration/smoke tests out of
sources, so each test section launches scripts/code.bat, which runs
build/lib/preLaunch.ts. Unlike the Azure Pipelines product builds, the
GitHub workflows did not set VSCODE_SKIP_PRELAUNCH, so preLaunch ran on
every section and getElectron() unconditionally deleted and re-downloaded
.build/electron each time. On Windows this races with file locks held by
the just-exited Electron process and intermittently fails the whole job
with the bare 'The system cannot find the path specified.' error.
- Set VSCODE_SKIP_PRELAUNCH=1 on the unit/integration/remote test steps of
the win32, linux and darwin PR workflows, matching Azure Pipelines (the
workflows already prepare node_modules, out, built-in extensions and
Electron in dedicated steps before the tests run).
- Make getElectron() version-aware: skip the destructive re-download when
the installed Electron already matches the expected version, falling back
to a download on any detection failure.
- Make scripts/code.bat fail fast with a clear message when preLaunch.ts
fails instead of falling through to launch a missing executable.
- Retry rimraf on EBUSY/EPERM (Windows file-lock codes), not just ENOTEMPTY.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The checked-in policyData.jsonc was generated with the Copilot extension
loaded, which injected referencedSettings linking the OTel extension
settings to the core CopilotOtel* policies. The PolicyExport integration
test regenerates using the test fixture distro with no user extensions, so
those referencedSettings are absent. Regenerate in an isolated environment
to match the fixture-based export.
* Gate Claude3PIntegration behind editor preview policy
Flip ownership of the `Claude3PIntegration` enterprise policy so it can
honor the account-side editor preview-features flag.
Previously the policy was owned by the copilot-chat extension setting
`github.copilot.chat.claudeAgent.enabled` via the distro `product.json`
`extensionConfigurationPolicy` block. Because `product.json` is pure JSON
it cannot carry a `value(policyData)` callback, so the policy only
responded to OS/MDM admin policy and never honored
`chat_preview_features_enabled` (sourced from the Copilot token's
`editor_preview_features`). Codex works because its core setting owns
`Codex3PIntegration` in code with a value callback.
Now the in-code core setting `chat.agentHost.claudeAgent.enabled` owns
`Claude3PIntegration` with the preview-features value callback, and the
extension setting attaches via a `policyReference` declared from
`product.json`. To express that, an `extensionConfigurationPolicy` entry
can now be either form:
- the current owner/"parent" syntax (full `IPolicy`: name, category,
minimumVersion, description), or
- a reference: `{ "policyReference": { "name": "<owner>" } }`, mirroring
the in-code `policyReference` configuration field.
`configurationExtensionPoint` and the policy exporter detect the
`policyReference` key to route entries to `.policy` vs `.policyReference`;
the exporter links reference entries into the owner's `referencedSettings`
and skips type validation for settings not registered in the headless
export process.
Regenerates `policyData.jsonc` and updates the export test fixture.
Requires the companion change in microsoft/vscode-distro that turns the
claude entry into a `policyReference`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Bump distro to pick up Claude3PIntegration policy reference
Update the distro pin to 7abf39b86c07d094722a4b3ec9f37e78fe3d5db3, which
includes the merged change turning the `github.copilot.chat.claudeAgent.enabled`
`extensionConfigurationPolicy` entry into a `policyReference` to the in-code
`Claude3PIntegration` owner (microsoft/vscode-distro#1434).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Ubuntu <josh@ahp.4mywozgnka0etnlo23z031udwc.xx.internal.cloudapp.net>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On a narrow Agents window, auto-hide the sessions sidebar while both the
editor and the side panel (auxiliary bar) are open, and show it again once
either closes or the window grows wide. A manual close suppresses auto-show
until the user opens it again; suspended while the editor is maximized or
multiple sessions are visible. Gated by the experimental setting
`sessions.layout.autoCollapseSessionsSidebar` (default on in non-stable builds).
Session navigation never auto-hides the sidebar: a base-controller restore
epoch (`_withSessionLayoutRestore` / `_isRestoringSessionLayout`) wraps both
the aux-bar restore and the editor working-set apply (`_applyWorkingSet`, which
reveals the editor part after an await). The D7 autorun re-baselines instead of
reacting while a restore is in flight. The epoch is a depth counter so the
guard stays up across overlapping/independently-settling restores, and it
decrements synchronously for void work so it never leaks for no-op restores.
Layout-controller registration moves to a new
`sessions.layout.contribution.ts` that picks the desktop or mobile controller
per platform and registers the experimental setting.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Bump Copilot CLI packages to @github/copilot@1.0.64-1 and @github/copilot-sdk@1.0.3
* Resolve Agent Host Copilot CLI through @github/copilot/bin.copilot
* Materialize @github/copilot/sdk from @github/copilot-<platform> in extension postinstall
* Package @github/copilot-<platform>/copilot for Agent Host and linuxmusl
* Exclude Copilot optional native payloads from extension package
* Scan @github/copilot-*/copilot for Linux package dependencies
* Tighten Copilot SDK 1.0.64-1 attachment and RPC typings
* Increase Copilot SDK native binary scan test timeout
* Update amd64 deb deps for @github/copilot-linux-x64/copilot
* Update arm64 rpm deps for Copilot package layout
* Update x64 rpm deps for @github/copilot-linux-x64/copilot
* Try to fix windows smoke test
* Try to fix platform runtime files for agent host
* exclude copilot computer.node from agent host packaging
* Another attempt to try to get packaging right
* Should only try to load 1.0.64-1
* Try to fix packaing for windows, macos, deb deps
* Update armhf/arm64 deb and x64 rpm Copilot dependency baselines
* Copilot darwin ripgrep universal merge and arm64 rpm deps
* Restore target Copilot SDK prebuilds for built-in extension packaging
* see if changes to gulpfile.reh.ts would help
* dont mess with formatting
* Launch copilot cli from platform index.js and exclude SEA
* sessions: contribute PR pill as session header meta toolbar action
The session header pull request pill was rendered as bespoke DOM directly in sessionHeader.ts. Instead contribute it as an action into the existing Menus.SessionHeaderMeta toolbar, mirroring how the changes view contributes the diff-stats action.
- Add OpenPullRequestAction + OpenPullRequestActionViewItem (renders the #<number> pill, opens the PR on GitHub) in contrib/github/browser/pullRequestActions.ts, registered via IActionViewItemService.
- Gate it on a new per-view SessionHasPullRequestContext key, set by SessionView from the session's GitHub info (parallel to SessionHasChangesContext).
- Remove the manual PR pill DOM, fields, handlers and IOpenerService/URI usage from sessionHeader.ts; the meta toolbar now owns both the diff-stats and PR pills.
- Share the pill CSS between the diff-stats and PR action view items.
- Replace the header fixture's PR-pill variants with a dedicated openPullRequest fixture for the new action view item.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: document PR pill in Agents window accessibility help
Add a line to the SessionsChat accessibility help dialog describing the session header pull request pill and referencing its command keybinding placeholder, mirroring the existing diff-stats entry so screen reader users can discover it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: register vs/sessions/contrib/github for i18n
The new pullRequestActions.ts introduces the first localized strings under vs/sessions/contrib/github. Add the module to build/lib/i18n.resources.json so the code-translation-remind eslint rule passes (it was failing Compile & Hygiene).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fixtures: render PR + diff pills in session header fixture
The session header fixture rendered the real SessionHeader, but its meta toolbar (Menus.SessionHeaderMeta) was backed by the empty TestMenuService / NullActionViewItemService, so the contributed pull request and diff-stats pills never appeared.
Wire the fixture's meta toolbar through the production code path: use FixtureMenuService for IMenuService, a small Map-backed IActionViewItemService, and a bound ISessionContext, then register the real OpenPullRequestActionViewItem / ViewAllChangesActionViewItem factories and contribute the matching menu items (gated on the mock session having a PR / changes). The header now shows 'folder #<number> +X -Y' as in production.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: add CI failures and created-comments banners above the chat input
Add two dismissible banners that render directly above the active session's
chat input in the Agents window:
- A CI failures banner (orange accent) shown when the active session has at
least one failed CI check. It reads "X of N checks failed" (ellipsized) with
a floating right-aligned button bar: Fix Checks (same as the Changes view
fix-ci action) and Reveal Checks (opens the Changes view and expands +
focuses the CI checks section).
- A created-comments banner (neutral accent) shown when the active session has
reviewable (PR/Agent review) comments still in the Created state. It reads
"N comments" with Address Comments (sends /act-on-feedback) and Reveal
Comments (opens the first comment in the editor).
Each banner has its own dismiss (x) that permanently hides it for that session,
persisted across reloads via the storage service.
The presentational card is a self-contained SessionInputBannerWidget so it can
be rendered in a Component Explorer fixture; the reactive SessionInputBanners
host composes it and the chat view mounts it above the input via the public
IChatWidget.inputPart.element API.
Also adds CIStatusWidget.expand()/focus(), ChangesViewPane.revealChecks(), and a
Reveal Checks command, plus Component Explorer fixtures for the banners.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: register sessionInputBanners in i18n.resources.json
Fixes the Compile & Hygiene CI failure: the new contrib uses localize() so its
folder must be listed for translation extraction.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: address PR feedback on input banner widget
- Use the shared Button widget for banner action buttons so theming, focus,
keyboard/touch, and accessibility stay consistent (primary = button colors,
secondary = ghost), mirroring the chat input notification widget.
- Make the ThemeIcon import type-only.
- Use the --vscode-strokeThickness token for the 1px border and focus outlines.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: make the Fix Checks button orange to match the CI banner accent
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: give secondary banner buttons a visible border
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: label comments banner by kind (PR / agent / mixed)
Show 'N PR comments' when all counted comments are PR reviews, 'N agent
comments' when all are agent reviews, and 'N comments' for a mix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add onboarding spotlight tour for the Agents window
Introduce a presentation-agnostic onboarding scenario engine
(vs/workbench/contrib/onboarding) with a reusable spotlight presentation
(dim overlay, masked highlight, anchored callout) and a first Agents-window
tour that highlights running sessions in parallel, the isolation picker and
the workspace picker. The new-session tour triggers via an observable for new
users after they send a request and the session stays visible, with an
onboarding.developerMode setting to bypass usage gating for testing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix leaked onAbort listener in onboarding shutdown test
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address PR review: dedupe in-flight runScenario, fix focus trap and keyboard advance
- runScenario joins an in-flight run instead of scheduling a second one
- focus trap handles focus not being on a tracked element (no -1 wrap-around)
- advanceOnTargetClick keeps the spotlighted target keyboard-reachable: it joins
the focus trap, receives Tab/Esc handling, and gets initial focus so keyboard
users can activate it to advance
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix CI: register onboarding i18n namespaces and make focus-trap test deterministic
- Add vs/workbench/contrib/onboarding and vs/sessions/contrib/onboardingTours to
build/lib/i18n.resources.json (code-translation-remind eslint rule failed CI)
- Set keyCode on the synthetic Tab event via Object.defineProperty so
StandardKeyboardEvent recognizes it (init-dict keyCode is not honored), fixing
the flaky markdown focus-trap assertion
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix CI: use KeyMod.Shift for Shift+Tab in spotlight focus trap
The focus trap matched 'KeyCode.Shift | KeyCode.Tab', a meaningless OR of two
key codes, so Shift+Tab was never recognized and focus wasn't trapped. Use
KeyMod.Shift | KeyCode.Tab. This fixes the failing focus-trap unit test and
makes reverse focus navigation work for real keyboard users.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: derive GitHub token from Monaco GitHub App instead of PAT
Replace the github-distro-mixin-password PAT (subject to 7-day rotation)
with a GitHub App installation token extracted from the persisted checkout
credentials. The token is republished under the same variable name to avoid
churning the many GITHUB_TOKEN consumers, and the distro netrc auth now uses
the x-access-token login.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: probe vscode-distro checkout via Monaco GitHub App endpoint
Reverts the failed token-extraction approach (1ES persists only a credential
placeholder, so the GitHub App token cannot be read from disk).
Instead validate Option A: add microsoft/vscode-distro as a pipeline repository
resource authenticated via the Monaco GitHub App endpoint, then check out the
exact pinned SHA locally. This probe job confirms the agent can authenticate the
distro checkout and that a local `git checkout <sha>` resolves the pinned commit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: check out vscode-distro via Monaco GitHub App instead of PAT
Replace the PAT-based zipball download of the private microsoft/vscode-distro
repository with an agent-authenticated checkout of the distro repository
resource (Monaco GitHub App). The distro is checked out into .build/distro and
the pinned commit from package.json is checked out locally, preserving the
existing contract for mixin-npm.ts / mixin-quality.ts.
Self is pinned to the default sources directory so the added distro checkout
does not relocate it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: route vscode-capi and vscode-encrypt through Monaco GitHub App
The github-distro-mixin-password PAT was also (via netrc) authenticating two
other private repositories that are no longer reachable once the netrc is gone:
- vscode-capi: cloned by common/mixin-vscode-capi.yml. Now checked out as a
Monaco GitHub App repository resource and consumed from .build/vscode-capi.
- vscode-encrypt: a cargo git dependency injected by the distro cli-patches.
Checked out via the Monaco GitHub App and redirected with git insteadOf to the
local checkout so cargo (CARGO_NET_GIT_FETCH_WITH_CLI) resolves it without a PAT.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: also route vsda cargo dependency through Monaco GitHub App
The distro cli-patches inject both vscode-encrypt and vsda as private cargo git
dependencies. Add vsda as a Monaco GitHub App repository resource and redirect it
to a local checkout via git insteadOf, mirroring the vscode-encrypt handling.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: drop github-distro-mixin-password PAT
Replace the broad github-distro-mixin-password PAT with:
- Monaco GitHub App repo-resource checkouts for private repos
(vscode-distro, vscode-capi, vscode-encrypt, vsda)
- the public github-token-code-oss secret (vscode-oss-build-secrets
keyvault) for generic GITHUB_TOKEN rate-limit usages
Copilot now checks out vscode-capi via the Monaco App instead of a
netrc clone; checkDistroCommit derives the distro branch head from the
local checkout instead of the private GitHub API.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: check out vscode-extensions-loc via Monaco App
The copilot l10n import cloned the private microsoft/vscode-extensions-loc
repository with the distro PAT. Replace it with a Monaco GitHub App
repo-resource checkout (sparse) so no PAT is needed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: download prebuilt Electron from Azure Artifacts feed
Replaces the private GitHub release download (which required the
github-distro-mixin-password PAT) with an on-demand fetch from the
vscode-electron-prebuilt Azure Artifacts feed, via the new asset-resolver
support in @vscode/gulp-electron 1.42.0.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: resolve private vsda/vscode-encrypt git deps via local checkouts
The distro's npm postinstall and the CLI cargo patches both depend on the
private microsoft/vsda and microsoft/vscode-encrypt repositories. Now that the
distro PAT/.netrc is gone, redirect their public GitHub URLs (https and ssh) to
local GitHub App checkouts via git insteadOf in download-distro.yml so every job
that consumes the distro can resolve them without a PAT.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: download Alpine musl Node.js from Azure Artifacts feed
The Alpine build downloaded the musl Node.js tarball from the private
microsoft/vscode-node GitHub releases, which the public github-token-code-oss
cannot access. Consume the new vscode-node Azure Artifacts feed via
az artifacts universal download instead (authenticated with System.AccessToken),
mirroring the Electron prebuilt download.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: resolve private vscode-regexp-languagedetection git dep via local checkout
The distro's npm dependencies reference microsoft/vscode-regexp-languagedetection
in addition to microsoft/vsda. Check it out via the Monaco GitHub App and redirect
its public GitHub URL (https and ssh) to the local checkout so the distro npm
postinstall resolves it without a PAT.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: download server Node.js from Azure Artifacts feed
Fetch the prebuilt server (reh) Node.js binaries on demand from the
vscode-node Azure Artifacts feed (gated on VSCODE_NODEJS_INTERNAL_FEED)
instead of from a private GitHub release, so the build no longer needs a
long-lived PAT. Extracts the shared az universal-package download helper
into build/lib/azureFeed.ts, reused by the Electron resolver. Bumps the
server node ms_build_id to 449655 to match the feed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: resolve distro private git deps inside the Alpine container
The Alpine server build installs the distro's npm dependencies (which
reference the private vsda and vscode-regexp-languagedetection git repos)
inside a docker container. The host git insteadOf redirects are not
visible there and use host paths, so emit a container-pathed gitconfig
(.build/.gitconfig-distro) from download-distro.yml and bind-mount it as
/root/.gitconfig, replacing the now-unused .netrc mount.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: use Electron/Node feeds job-wide and fix cmd.exe git redirect
Promote VSCODE_ELECTRON_PREBUILT_FEED, VSCODE_NODEJS_INTERNAL_FEED and
AZURE_DEVOPS_EXT_PAT to job-level variables so every step (including the
integration/smoke test steps that download Electron) resolves binaries
from our Azure Artifacts feeds instead of private GitHub releases.
Also keep the cross-platform private git redirect step to plain 'git
config' invocations so it works in cmd.exe on Windows agents, and move
the bash-only container gitconfig generation into a Linux-only step.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: pin server Node.js to build 438265 to match distro checksums
The distro overlays build/checksums/nodejs.txt with checksums for the
original 24.15.0-438265 Node.js build (including the Alpine musl binary,
whose contents differ from later rebuilds). Republish the original
438265 artifacts to the vscode-node Azure Artifacts feed and pin
ms_build_id back to 438265 so feed downloads match the pinned checksums.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: require ADO org/project from pipeline env vars
Resolve the Azure Artifacts organization and project from the
SYSTEM_COLLECTIONURI / SYSTEM_TEAMPROJECT pipeline variables (the
predefined System.CollectionUri / System.TeamProject), failing fast if
either is missing instead of falling back to hardcoded values.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor: remove internal feed variables for Node.js and Electron from build configurations
* build: scope AZURE_DEVOPS_EXT_PAT to individual steps
Move the System.AccessToken propagation out of the job-level variables in
the alpine/darwin/linux/win32 product-build jobs and onto only the steps
that actually download Electron or Node.js from the Azure Artifacts feeds.
Adds it to the test 'Download Electron and Playwright' step (the sole feed
download outside the compile templates); every other download step already
declared it at step scope.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* :lipsitck:
* update distro
* build: declare vscode-capi for SDL scan in copilot recovery pipeline
The Copilot build steps now check out microsoft/vscode-capi via the Monaco
GitHub App (instead of a PAT). The product-copilot-recovery pipeline extends
the 1ES extension template, which requires every checked-out repository to be
declared under sdl.sourceRepositoriesToScan. Re-declare the template's default
excludes plus capi to fix 'repository "capi" ... has not been specified'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor: add assertDistroCheckout function to validate vscode-distro checkout
* build: fix NPM registry corruption in copilot recovery pipeline
setup-npm-registry.ts silently substituted the literal string "undefined"
into package-lock.json resolved URLs when invoked without a registry URL,
producing build/undefined<pkg>/... paths that npm ci could not resolve.
- Fail fast in setup-npm-registry.ts when no registry URL is provided.
- Set NPM_REGISTRY=none in product-copilot-recovery.yml so the shared
copilot/setup-steps.yml skips its registry rewrite; the 1ES extension
template already configures the registry via customNPMRegistry.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: fix self checkout and l10n in copilot recovery pipeline
The 1ES extension template's package job runs import-localized-files before
buildSteps, relying on an implicit self checkout. That implicit checkout is
disabled because copilot/build-steps.yml checks out microsoft/vscode-capi,
so the source tree was missing and the l10n-detection step failed with
'Not found workingDirectory: .../extensions/copilot'.
Mirror product-copilot.yml: check out self at the start of buildSteps, import
translations via copilot/l10n-steps.yml (with the vscode_loc resource), and
disable the template's own l10n jobs/import (l10nShouldProcess: false).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: exclude vscode build-tooling natives from copilot recovery GLIBC check
The 1ES extension template's GLIBC/GLIBCXX check scans every .node under the
sources root, but only extensions/copilot is packaged into the VSIX. Native
modules outside it (e.g. build/node_modules/tree-sitter) belong to the vscode
build tooling and are never shipped, yet their newer GLIBC/GLIBCXX deps fail
the check. Remove them before the check so it only validates the copilot
extension's own shipped natives, alongside the existing pvrecorder removal.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: disable sysroot GLIBC check in copilot recovery pipeline
The copilot extension is bundled with esbuild and vendors prebuilt native
modules (@os-theme, @picovoice/pvrecorder-node) that depend on a newer GLIBC
than the 1ES template's sysroot check allows. The main product build ships
these natives without a sysroot or GLIBC check, so set useSysroot: false on the
recovery pipeline's Linux platform for parity, which skips the toolchain setup
and the GLIBC/GLIBCXX verification. Drop the now-unnecessary native-removal
workaround.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: update distro version in package.json
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: escape XML special characters in ADML/profile output (#320551)
Policy descriptions containing angle brackets (e.g. `<plugin>@<marketplace>`,
`<url>`) produced invalid XML in generated ADML and macOS profile files,
causing Intune and Active Directory upload failures.
Add `escapeXml` helper that escapes `&`, `<`, and `>` in text content
and apply it in `renderADMLString` and `renderProfileString`. Add unit
tests for the escaper and an E2E regression test with angle-bracket
descriptions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: replace angle brackets with curly braces in plugin description placeholders (#320551)
The policy descriptions for ChatEnabledPlugins and ChatExtraMarketplaces
used `<plugin>`, `<marketplace>`, and `<url>` as placeholder tokens.
These are not HTML/XML tags — replace with `{plugin}`, `{marketplace}`,
and `{url}` to avoid ambiguity and eliminate the source of the invalid
XML that was fixed in the previous commit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* address PR review: remove useless backtick escapes, clarify test name
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Edit mode is now hidden for everyone, so the chat.editMode.hidden
setting and its DeprecatedEditModeHidden policy are no longer needed.
This removes the setting registration, policy, exported policy data
entry, and the settings layout reference. The custom Edit mode file in
the built-in Copilot extension (and its provider registration) is
removed as well. The mode picker no longer special-cases a custom
`edit` mode by name for its icon or built-in grouping; the legacy
built-in Edit mode (shown when agent mode is disabled by policy) keeps
its own icon.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Gate chat.agentHost.enabled behind editor preview policy
Add a policy block to the agent host enabled setting so that
organizations with chat_preview_features_enabled set to false
will have the setting forced to false, matching the pattern used
by ChatHooks, ChatToolsAutoApprove, and other preview-gated settings.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix minimumVersion, reuse NLS key, and update policy data
Address review feedback:
- Set minimumVersion to 1.126 (current VS Code version)
- Reuse existing NLS key to avoid duplicate translation entries
- Add ChatAgentHostEnabled to generated policyData.jsonc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Gate chat.agentHost.enabled behind editor preview policy
Register the bare setting (type + default) in the common layer so the
main process knows the default for agent host spawning. The policy block
with its value callback is added via updateConfigurations in the browser
layer (agentHost/browser/agentHost.config.contribution.ts) because
functions cannot be structured-cloned over Electron IPC.
Co-authored-by: digitarald <digitarald@github.com>
---------
Co-authored-by: digitarald <digitarald@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* config: allow one policy to govern multiple settings via policyReference
Previously each enterprise policy mapped to exactly one configuration
setting: `ConfigurationRegistry` enforced a strict 1:1 policy-name guard
and rejected any second setting reusing a policy name. This made it
impossible for a single admin policy to lock more than one setting (for
example, gating the same agent in both the editor window and the Agents
window).
This introduces an explicit, subordinate attachment mechanism while
keeping the strict owner guard:
- Add `IPolicyReference` (name + optional runtime-only `value` /
`managedSettings`). A setting may declare `policyReference` to be
governed by a policy that is *owned* (fully declared via `policy`) by
another setting. References deliberately carry no catalog metadata
(category / minimumVersion / localization) so exactly one owner per
policy name provides those, keeping the exported catalog and generated
ADMX/plist unambiguous.
- `ConfigurationRegistry` keeps `getPolicyConfigurations()` 1:1 (owners)
and adds `getPolicyReferenceConfigurations()` (name -> set of
subordinate settings). The duplicate-owner guard is retained; a setting
declaring both `policy` and `policyReference` is rejected.
- `PolicyConfiguration` resolves references: owners win when present, and
a reference synthesizes a per-process definition from its own schema
type so the policy still resolves in processes where the owner is not
loaded. Policy changes now fan out to the owner and all references.
- Developer "policy-controlled settings" diagnostics list references
(tagged) alongside owners, and trace logging reports owner/reference
registration and fan-out for debugging.
Adds unit tests covering registration, the both-declared rejection,
owner+reference value application, change propagation, and orphan
references (owner registered elsewhere).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: gate Claude/Codex 3P agents across editor and Agents windows
Uses the new policyReference mechanism to extend enterprise policy
control over the agent-host third-party agents.
- Reuse the existing `Claude3PIntegration` policy (owned by the Copilot
extension setting `github.copilot.chat.claudeAgent.enabled`) by adding
`policyReference`s on the agent-host setting
`chat.agentHost.claudeAgent.enabled` and the Agents window setting
`sessions.chat.claudeAgent.enabled`. Disabling Claude via policy now
applies across the editor window and the Agents window.
- Add a new `Codex3PIntegration` policy, owned by
`chat.agentHost.codexAgent.enabled` — the single runtime through which
Codex is surfaced in both windows.
- Both references and the Codex owner respect
`chat_preview_features_enabled === false` so organizations that disable
preview features automatically disable these agents.
- Regenerate the policy catalog entry for Codex3PIntegration;
Claude3PIntegration stays owned by the existing extension setting.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy export: link referenced settings in the exported catalog
The exported policy catalog (build/lib/policies/policyData.jsonc) drives
enterprise docs. Now that one policy can govern multiple settings via
policyReference, each catalog entry should list every setting the policy
controls so docs can surface all of them.
- Add `referencedSettings?: string[]` to PolicyDto.
- During export, populate it for each policy: references registered in
the workbench process are discovered from the configuration registry,
and references that live in app surfaces not loaded during export (the
Agents window, a separate layer the workbench cannot import) are
supplemented from a small documented CROSS_SURFACE_POLICY_REFERENCES
map. The union is sorted for stable output.
- Regenerate the catalog: Claude3PIntegration now links both
`chat.agentHost.claudeAgent.enabled` and
`sessions.chat.claudeAgent.enabled`. Codex3PIntegration governs only
its owning setting, so it has no referencedSettings.
- Add trace diagnostics reporting how many referenced settings were
linked.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* config: make policy owners win over references regardless of registration order
Council review found that a late-registering policy owner could not replace
an earlier subordinate `policyReference`. `AbstractPolicyService.updatePolicyDefinitions`
merged existing-wins and only re-ran when the definition *count* grew, while
`PolicyConfiguration` only gave owners precedence within a single batch. So when a
reference registered before its owner across separate update cycles — exactly the
editor-window case, where the agent-host Claude reference loads eagerly via
chat.shared.contribution while the Copilot extension owner loads later — the owner's
`value`/`managedSettings`/`restrictedValue` were silently dropped.
Fix:
- `AbstractPolicyService.updatePolicyDefinitions` now replaces an existing definition
for a policy name when a different definition object is submitted, and re-runs
`_updatePolicyDefinitions` whenever anything changed (not only on count growth).
- `PolicyConfiguration` resolves each policy name owner-first against the registry
(not just the current batch) and caches the source schema object per name, so it
submits a stable definition object and only re-submits on a real change (e.g. a
reference being upgraded to its owner). This keeps owners authoritative regardless
of registration order while avoiding redundant policy-service / watcher churn.
Adds regression tests: owner definition wins when both are present, and a
late-registering owner supersedes an earlier reference definition.
Verified: node config/policy suites and browser AccountPolicyService /
MultiplexPolicyService tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: drop non-cloneable value callback from serialized policiesData
CI's `policyExport.integrationTest` hung (60s timeout) on all Electron jobs.
Root cause: `AbstractPolicyService.serialize()` included the full `PolicyDefinition`
— including its `value` callback (a function) — in the `policiesData` that the main
process sends to the renderer as part of the window configuration. Electron structure-
clones that payload over IPC, and a function cannot be cloned ("An object could not be
cloned"), so window-configuration resolution never completed and the export window
never exited.
This only surfaced now because the agent host settings contribution
(`agentHostStarter.config.contribution.ts`) is imported in the main process, making it
the first policy with a `value` callback registered in the main process policy service.
Renderer-only policies reach the main service through the IPC channel, which already
drops functions, so their callbacks never entered `policiesData`.
Fix: `serialize()` now emits a structured-clone-safe definition (type, managedSettings,
restrictedValue) via `toSerializablePolicyDefinition`, dropping the `value` callback.
The callback is only evaluated by account-based policy services in the owning process
and is never read by `PolicyChannelClient` consumers, so nothing depends on it being
transported.
Adds a regression test asserting `serialize()` output is structured-clone-safe.
Verified: the local `--export-policy-data` run now completes and its output matches the
checked-in build/lib/policies/policyData.jsonc under the integration test's normalization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* config: simplify policyReference implementation
Trim the policyReference change in response to review feedback that it was
larger than necessary:
- Drop the defensive policy type-consistency guard (`findPolicyTypeMismatch`)
and its tests. The owner is authoritative for the resolved definition's type,
so a mismatched reference type is harmless in practice; the strict owner guard
and the both-declared guard remain.
- Revert the developer "policy-controlled settings" diagnostics changes — that
was a debug-only nicety, not needed for the feature.
- Condense verbose comments and remove redundant trace logging in
PolicyConfiguration and the IPolicyReference doc.
No behavior change to policy resolution; the regression tests (owner-wins,
late-owner, reference resolution, serialize clone-safety) are unchanged and
still pass, and the policy export still matches the checked-in catalog.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* config: merge reference runtime bits so a policy callback is never dropped
Second council review found that owner-first resolution dropped a reference's
account-policy `value` callback. Claude3PIntegration's owner is the Copilot
extension setting (contributed via product.extensionConfigurationPolicy as JSON),
which cannot carry a `value` function; the `chat_preview_features_enabled` callback
lives only on the agent-host and sessions `policyReference`s. Because the owner won
unconditionally, AccountPolicyService (which only evaluates gating when
`policy.value` exists) never applied preview-feature gating to Claude in any process
where the Copilot extension is loaded.
Fix: `resolvePolicyDefinition` now merges — the owner provides the authoritative
type plus any runtime bits it declares, and references fill `value` / `managedSettings`
the owner does not provide (and still supply the whole definition when no owner is
loaded). This keeps owners authoritative while letting a reference contribute the
callback an extension/distro owner cannot declare.
Also fixes a related gap (flagged in review): deregistering a policy owner now
re-resolves the policy name so the definition falls back to a surviving reference,
tracked via a key→policy-name map. Definition change detection now compares the
resolved definition's fields (callbacks come from stable registry objects) instead
of the source object identity.
Adds regression tests: a value-less owner uses the reference's callback, and owner
deregistration falls back to the reference. Export still matches the checked-in catalog.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* config: make policyReference a pure pointer (drop value/managedSettings)
A `policyReference` should not redefine policy semantics — the owner is the single
source of truth. Allowing references to carry their own `value` callback recreated
the owner-vs-reference divergence that required merge/precedence rules and produced
the bug the previous review round fixed.
`IPolicyReference` is now just `{ name }`. A reference contributes only the policy
name so the setting is gated and the OS policy watcher observes the name in processes
where the owner is not loaded; the owner provides the type, value callback and all
other runtime behaviour. `resolvePolicyDefinition` is correspondingly simplified back
to owner-authoritative (no value/managedSettings merge).
Behavioural effect: the Claude agent-host and Agents-window settings are no longer
auto-disabled by the `chat_preview_features_enabled` GitHub account policy — they are
gated by the `Claude3PIntegration` policy itself (admin OS/MDM + account policy by
name), exactly as the editor-window extension setting already behaves on main. That
preview-features auto-disable was an artifact of the reference-value workaround, not a
requirement; the extension-owned `Claude3PIntegration` cannot express a callback
anyway. Codex keeps its preview-features auto-disable because its owner is core code.
Tests updated: owner definition is authoritative, reference only contributes the name.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: enforce policyReference type match; diagnostics + cleanups
- export throws if a policyReference setting's type differs from the owning policy's type
- drop hardcoded CROSS_SURFACE_POLICY_REFERENCES (referencedSettings now registry-driven)
- Developer: Policy Diagnostics lists policyReference settings
- rename updateToPolicyDefinitionType -> toPolicyDefinitionType, fix 'proprety' typo, tighten comment
- regenerate policyData.jsonc
* policy: address PR review nits
- make Codex3PIntegration policy description surface-agnostic (drop 'directly in the editor'); sync policyData.jsonc
- fix 'acutal' -> 'actual' typo in the policyReference tests added by this PR
* policy: trim verbose policyReference comments to one-liners
* policy: trim verbose comments across the PR
* policy: trim comments in policy.ts
---------
Co-authored-by: Ubuntu <josh@ahp.4mywozgnka0etnlo23z031udwc.xx.internal.cloudapp.net>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
We've had this enabled for watch for many months. Let's finish the move by switching this over now too
Also gives a better name to the typecheck script
Adds an enterprise policy to allow admins to control the Codex agent
provider registration, mirroring the existing Claude3PIntegration policy.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: inline rename for chats in the chat composite bar
Support renaming a chat directly inside its tab in the chat composite
bar, mirroring the inline rename of the session title. Double-click a
tab (or use the context menu "Rename") to reveal a themed InputBox
pre-filled with the chat title; Enter commits via renameChat, Escape or
blur cancels.
The rename input lives in a stable, empty per-tab container that is
toggled via the tab's `editing` CSS class; the InputBox is created lazily
only while editing and disposed when done, so no DOM is inserted/removed
on demand and unused tabs carry no widget overhead.
Also adds a component fixture (chatCompositeBar.fixture.ts) covering the
two-tab, mixed-status, long-title and renaming states for screenshot
testing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: switch tabs via click, keep rename blur a pure cancel
Address PR review: the tab click handler bailed out while editing and the
input blur handler switched tabs via relatedTarget. Because blur clears
the editing state before the trailing click fires, this could switch
twice (extra openChat/flicker) and was order-sensitive.
Now blur only cancels the rename, and the tab click handler cancels any
in-progress edit before switching, so tab switching follows the normal
click path.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* extensions: migrate auto update setting to on/off values
Migrate `extensions.autoUpdate` from the boolean/enum values (`true`,
`onlyEnabledExtensions`, `false`) to simple `on`/`off` string values:
- `on` replaces the previous `onlyEnabledExtensions` behavior (the
retired `true` and insiders `delayed` values also map to `on`)
- `off` replaces `false` (and the internal `onlySelectedExtensions`)
Also add a new `extensions.autoUpdateDelay` setting (in hours) to
control the delay before a published update is auto-installed, replacing
the previously hardcoded 2 hour period.
Both settings are policy-enabled for enterprise management.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* extensions: address PR review feedback
- Add required enumDescriptions to extensions.autoUpdate policy localization
(string-enum policies must provide them or export-policy-data fails)
- React to extensions.autoUpdateDelay config changes by rescheduling the
delayed auto-update check
- Update pluginAutoUpdate doc comment to reflect normalized 'on'/'off' values
- Update user-facing strings/command titles to drop 'All Extensions' since
'on' now means only enabled extensions are auto-updated
- Stub the delay key in tests
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* extensions: regenerate policy data for auto update settings
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>