chat: warn when changing model/options mid-session breaks the prompt cache
The model and options pickers surface a cache-break cost hint when the
chat session's prompt cache is warm — switching the model or changing
options mid-session resets that warm cache and may increase cost. The hint
includes a "Learn more" link (rendered via the shared Link widget through
a new optional headerLink on the action list header banner) pointing at
the Copilot docs on optimizing AI usage.
Warmth is derived directly from the session's request history at the
picker rather than tracked in a parallel in-memory map: getRequests()
length for the default chat, and session status leaving Untitled for
agent-host sessions. Both warm as soon as the first request is sent, so
the signal is drift-free and consistent across surfaces — it covers
reloaded/restored sessions, every request path, and the agents window.
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>
* chat plugins: add policy-backed enabledPlugins / marketplaces / strictMarketplaces settings
Adds three new chat.plugins.* settings, each policy-backed:
- chat.plugins.enabledPlugins (policy: objectChatEnabledPlugins)
mapping plugin IDs (`<plugin>@<marketplace>`) to enable/disable.
- chat.plugins.marketplaces (policy: array ofChatPluginMarketplaces)
marketplace references (GitHub shorthand or Git URI). User entries
survive alongside policy entries.
- chat.plugins.strictMarketplaces (policy: ChatStrictMarketplaces)
boolean restricting trust to listed marketplaces only.
All three are gated on `tags: ['experimental']`. Consumers (plugin
discovery, install, URL handler, marketplace service, quick-pick action)
now read via `inspect()` so default + user + policy layers all flow
through. A shared `readConfiguredMarketplaces` helper in
marketplaceReference.ts dedups the inspect pattern across 5 sites.
Adds three matching fields to IPolicyData so the policy framework has
slots to fill in once the wiring lands; until then they're undefined and
behave like an empty policy (no-op). Plugin discovery now distinguishes
filesystem-path entries (removable from UI) from enterprise plugin IDs
(non-removable) via a single shared loop; `IAgentPlugin.remove` is
optional accordingly.
build/lib/policies/policyData.jsonc regenerated for the new policy keys.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: implement ADR-002 enterprise managed_settings fetch & policy wiring
Wires the previously-added chat.plugins.* policy slots to the new
`/copilot_internal/managed_settings` endpoint on the authenticated
Copilot host.
Core behavior in DefaultAccountProvider:
- Fetches managed_settings alongside entitlements; shares the 1-hour
cache used by other account-policy fetches.
- Silent fallback to local-only policy on any non-2xx, network error,
parse error, or missing managedSettingsUrl.
- Rate-limit-aware: backs off all /copilot_internal/* calls when the
endpoint signals 429, 403 + X-RateLimit-Remaining: 0, or any non-2xx
with Retry-After.
- adaptManagedSettings flattens the API's structured
extraKnownMarketplaces map into the existing string-array shape that
chat.plugins.marketplaces consumes; tolerates malformed entries and
unknown response keys (forward-compatible).
- Telemetry: emits `defaultaccount:managedSettings:fetch` (owner:
joshspicer) with an `outcome` bucket (ok / no-response / parse-error /
status:NNN) and a `rateLimitBackoffActive` flag.
Surface area:
- IDefaultAccountProvider/Service expose managedSettingsFetchStatus and
managedSettingsFetchedAt; ManagedSettingsFetchStatus is a named union.
- Developer: Policy Diagnostics shows a Managed Settings section with
the URL status, last-fetched timestamp, and a JSON dump of the
applied managed-settings policy slice.
- product.json adds a managedSettingsUrl key (populated via distro).
Refactor: `readHeader` and `retryAfterFromHeaders` are moved to
`platform/request/common/request.ts` so githubRepoFetcher.ts and this
new code share one implementation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* bump distro to 36d906669669f12466c6912bd65d9eeb47c6522d
Pulls in managedSettingsUrl from microsoft/vscode-distro#1422.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* update policyData
* policy: address PR review feedback
- Restore historical default for chat.plugins.marketplaces
(['github/copilot-plugins', 'github/awesome-copilot#marketplace']) so
existing users don't lose the two built-in marketplaces on update.
Regenerate policyData.jsonc accordingly.
- Seed _managedSettingsFetchStatus = 'ok' on cache-hit so Policy
Diagnostics reports the applied state after a process restart that
warm-starts from cached policyData (instead of stuck at 'not yet
fetched').
- Scope the <plugin>@<marketplace> ID-resolution rule to the enterprise
ChatEnabledPlugins setting only. User-typed entries in
chat.pluginLocations that happen to contain '@' are now treated as
filesystem paths, as a user would expect, not silently rewritten to
~/.copilot/installed-plugins/<x>/<y>/. Split _resolvePluginPath into
a path-only resolver and a dedicated _resolveEnterprisePluginId.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: revert unnecessary _pluginLocationsConfig refactor
chat.pluginLocations has no policy slot, so observableConfigValue
(which uses getValue() under the hood) is functionally equivalent to
the hand-rolled inspect() version. Reverting reduces diff thechurn
inspect-based observable is now used only for _enterpriseEnabledPluginsConfig
where the default+user+policy merge actually matters.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: split managed marketplaces into dedicated policy-only setting
Adds chat.plugins.extraMarketplaces (ChatExtraMarketplaces policy,
included: false so it's hidden from the Settings UI). This receives the
'extraKnownMarketplaces' payload from the managed_settings API.
Restores chat.plugins.marketplaces to its pre-PR shape: no policy slot,
no inspect()-juggling required in consumers, no risk of accidentally
clobbering user data. Users write to chat.plugins.marketplaces; the
enterprise writes to chat.plugins.extraMarketplaces; the effective set
is the union.
Consumer simplifications:
- readConfiguredMarketplaces returns { userValues, extraValues,
two getValue() reads, no inspect() needed.effectiveValues }
- Write-back is now just [...userValues, refValue] in all three sites.
- 'Manage Plugin Marketplaces' still surfaces the 'managed by enterprise
policy' badge by checking ref membership in extraValues.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: tidy managed_settings code paths
- fetchMarketplacePlugins: drop the over-engineered pre-dedup-by-string;
parseMarketplaceReferences already dedups by canonical id.
- agentPluginServiceImpl: pass source.remove directly to _toPlugin instead
of wrapping in a null-asserted closure.
- adaptManagedSettings: use a Set for flatten-and-dedup (insertion order
is preserved).
- getDefaultAccountFromAuthenticatedSessions: spread merge instead of
three explicit field assignments.
- developerActions: collapse the 'ok' branch into the catch-all backtick
wrap; same behavior, less code.
- marketplaceReference.ts: tighter JSDoc on IConfiguredMarketplaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: enforce ChatEnabledPlugins and strict-marketplace gates at discovery
Previously the enterprise-managed policy values were delivered into the
policy framework but not a plugin already installed locallyenforced
(e.g. via the marketplace discovery path) would remain active even when
the policy excluded it or strict-marketplace mode rejected its source.
Adds policy enforcement on AgentPluginService.plugins, applied after
discovery dedup/sort and gated by two observables:
- ChatEnabledPlugins policy: when set, filters the surfaced plugin set
to only those whose '<name>@<marketplace>' ID appears in the policy
map with value true. Plugins without a marketplace provenance
(filesystem entries from chat.pluginLocations) are unaffected.
- ChatStrictMarketplaces: when on, filters out plugins whose source
marketplace is not trusted. Trust is sourced ONLY from
chat.plugins.extraMarketplaces (the policy-only user-setslot)
entries in chat.plugins.marketplaces do NOT grant trust under strict
mode. This matches the ADR-002 semantics: strict mode hands full
marketplace control to the enterprise.
Also updates the chat.plugins.strictMarketplaces description text to
match the new behavior (was still pointing at the user setting).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: extract managed_settings adapter to dedicated helper
Moves IManagedSettingsResponse and adaptManagedSettings out of
defaultAccount.ts and into a new managedSettings.ts in the same folder.
Adapter is a pure transformation function with no service dependencies,
so it belongs in its own file alongside the HTTP/wiring code.
Renames the test file to managedSettings.test.ts to match what it
actually tests and tightens the suite name.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: tidy enforcement filter and sync strict-marketplace policy description
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: show policy-blocked plugins as disabled instead of hiding them
Blocked plugins (ChatEnabledPlugins / strict marketplaces) now stay
visible but are forced disabled via their enablement observable, and the
enable affordance notifies the user instead of re-enabling.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: enforce enabledPlugins/strictMarketplaces for Copilot-CLI plugins
CLI-installed plugins under `~/.copilot/installed-plugins/<marketplace>/<plugin>/`
have no `fromMarketplace` metadata, so they previously bypassed enterprise
policy. Derive their identity from the install-path bucket (matching the
convention used by `_resolveEnterprisePluginId`) so enabledPlugins gating
applies, and add a bucket-name heuristic for strict marketplaces.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* log raw managed_settings response at trace level
Helps debug schema drift / unknown server fields that get dropped by
adaptManagedSettings(). Trace-only so it's off by default.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* improve managed_settings warning for missing repo/url
When a github source is missing 'repo' or a git source is missing 'url',
emit a specific warning naming the missing field instead of the misleading
'unknown source type' message.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* preserve marketplace name through managed_settings policy delivery
The managed_settings adapter previously flattened extraKnownMarketplaces
entries to bare "<owner>/<repo>" or "<url>" strings, losing the marketplace
name. That broke enabledPlugins matching because plugin IDs are keyed as
"<plugin>@<marketplace-name>" but our parsed reference's displayLabel was
derived from the URL/repo instead.
Changes:
- adapter now emits { name, source } objects preserving the full shape
- IPolicyData.extraKnownMarketplaces accepts string | object entries
- parseMarketplaceReferences gains object-handling, using name as displayLabel
- workspacePluginSettingsService shares the object parser
- policy schema relaxed to allow object items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: clarify chat.plugins.enabledPlugins description
The previous 'Merged with entries from chat.pluginLocations' was misleading:
the two settings use different key namespaces (plugin IDs vs filesystem paths)
and the enabledPlugins policy also acts as an allowlist that gates
marketplace-discovered not a symmetric merge.plugins
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: add description for chat.plugins.extraMarketplaces
The setting was missing a markdownDescription, so the Settings UI card
rendered empty when shown under 'Managed by organization'. Also updated
the policy localization to mention the new { name, source } object form.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: shorten chat.plugins.extraMarketplaces description
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: drop policy name from extraMarketplaces description
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: re-fetch plugin marketplaces when ExtraMarketplaces policy changes
pluginMarketplaceService.onDidChangeMarketplaces only listened for
PluginsEnabled and PluginMarketplaces config changes, so the
ExtraMarketplaces values delivered by the ChatExtraMarketplaces policy
never triggered a the union was stale until the next user editrefetch
to chat.plugins.marketplaces or a workspace-trust change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: extract IExtraKnownMarketplaceEntry to base/common/managedSettings
Move the enterprise-managed marketplace entry type out of defaultAccount.ts
into a dedicated managedSettings.ts so the type lives alongside other
managed-settings-specific code.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: cleanup pass
- Sync policyData.jsonc ChatExtraMarketplaces description with the
source declaration in chat.shared.contribution.ts (object-form
entries were missing from the policy artifact).
- Reorder Event import in agentPluginServiceImpl.ts to keep base/common
imports alphabetical.
- Fix stale doc reference (COPILOT_CLI_INSTALLED_PLUGINS_DIR -> the
function it actually mirrors).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: accept host-only git URLs in extraKnownMarketplaces
ADR-002 describes the `git` source `url` as a free-form `(string)`
the example happens to be a full clone URL, but the schema doesn't
require a repo path. Our marketplace-URI parser was rejecting host-only
HTTPS endpoints (e.g. `https://plugins.internal.example.com`), so
enterprise policy entries with marketplace-registry-style URLs were
silently dropped before they ever reached the UI.
Relax `parseUriMarketplaceReference` to accept host-only URLs and
treat them as a marketplace endpoint identified by host alone. The
canonical id becomes `git:<host>/` so distinct hosts still dedupe
correctly. Existing path-aware behavior is preserved unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: fix string entry guard in extraKnownMarketplaces policy.value; fix test cloneUrl expectation
- Handle string-typed entries in extraKnownMarketplaces (IPolicyData allows string | IExtraKnownMarketplaceEntry)
- Fix test expectation: URI.parse normalizes host-only URLs to include trailing slash
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: read extraMarketplaces dict and convert to nested entry shape
The setting schema is now `{ [name]: url-or-shorthand }` (object), so
readConfiguredMarketplaces must convert each entry to the nested
IExtraMarketplaceObjectEntry shape that parseMarketplaceReferences expects.
Uses a regex to detect GitHub shorthand (owner/repo[#ref]) vs URI.
TypeError in CI:
'extraValues is not iterable' on [...userValues, ...extraValues].
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: extract extraKnownMarketplacesToConfigDict helper + add regression tests for Settings Editor display
Extract the policy.value conversion for ChatExtraMarketplaces out of
chat.shared.contribution.ts into a reusable, unit-testable helper. The
helper converts the IExtraKnownMarketplaceEntry[] policy payload into the
{ [name]: url-or-shorthand } dict that:
- the Settings Editor's ComplexObject renderer can display inline as
key/value rows (instead of just 'Edit in settings.json'), and
- readConfiguredMarketplaces reverses back into IExtraMarketplaceObjectEntry[]
so parseMarketplaceReferences preserves displayLabel = name.
Tests added:
undefined
owner/repo
owner/repo#ref
raw URL (+ optional #ref)
parseMarketplaceReferences flow (the regression test that catches the
'extraValues is not iterable' bug we just hit in CI)
- schema-shape: chat.plugins.extraMarketplaces is registered with
type=object + additionalProperties.type=['string'], the exact shape
the Settings Editor requires to render as ComplexObject
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: stop spurious 'invalid marketplace entry' warnings for object-form entries
url dict, policy
entries always reach the marketplace fetcher as IExtraMarketplaceObjectEntry
objects (not strings). The validation loop was only accepting strings,
producing a 'Ignoring invalid marketplace entry: [object Object]' debug log
for every valid policy entry.
Validate using parseMarketplaceObjectEntry for object values so the warning
fires only for genuinely-unparseable entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: drop schema-shape test that double-registered chat contribution commands
The schema-shape test for chat.plugins.extraMarketplaces imported the full
chat.shared.contribution module to populate the configuration registry.
This re-registered commands (already registered by the workbench under
test), producing 'Cannot register two commands with the same id:
workbench.action.chat.markHelpful' and cascading disposable leaks in
unrelated suites (EditorService, WorkingCopyBackupTracker).
The other 5 tests (extraKnownMarketplacesToConfigDict + end-to-end round
trip) cover the actual behavior that broke; the schema shape is exercised
implicitly by the round-trip test.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* policy: normalize github.com URI/SSH refs to the GitHub shorthand canonical id
Plugin marketplace trust under strict mode compares canonicalId. A plugin
discovered from 'https://github.com/microsoft/vscode-team-kit.git' was
being blocked even though 'microsoft/vscode-team-kit' was in the trusted
list, because the URI parser produced 'git:github.com/microsoft/vscode-team-kit.git'
while the shorthand parser produced 'github:microsoft/vscode-team-kit'.
When parseUriMarketplaceReference / parseScpMarketplaceReference detect a
github.com authority, emit the same canonical id form the shorthand parser
uses so all three forms (shorthand, https URI, SCP) collapse to a single
trusted reference.
Existing dedup test now expects 1 entry instead of 2; ref-distinction test
collapses the https+#ref entry with its shorthand sibling. Added a focused
regression test asserting all four forms produce identical canonical ids.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* update policy
* fix dupe policy export
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* shared application storage
* add tests
* fix tests
Co-authored-by: Copilot <copilot@github.com>
* add logging and address feedback
* Add application shared storage scope
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add fallback migration for APPLICATION_SHARED storage
VS Code: AbstractStorageService.get() falls back from
APPLICATION_SHARED to APPLICATION scope transparently,
enabling lazy per-key migration without a registry.
Agents App: SharedSQLiteStorageDatabase reads the host
(VS Code) app's application storage DB as a fallback
during getItems(), merging missing keys so shared data
is available even before VS Code runs with new scope code.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Move storage fallback into Storage class with auto-migration
Move the APPLICATION → APPLICATION_SHARED fallback logic from
AbstractStorageService into the base Storage class via the new
fallbackStorage property on IStorage. When a key is not found,
the fallback is checked and the value is automatically written
through to persist the migration.
This eliminates duplicated fallback code in get/getBoolean/
getNumber and ensures write-through happens for all access
patterns.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Make fallbackStorage an implementation detail of Storage
Remove fallbackStorage from IStorage interface. It is now a
property on the Storage class only, set directly by callers
that have access to the concrete type.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Pass fallback storage via ApplicationSharedStorageMain constructor
Wire up the application storage as fallback during doCreate()
instead of post-init. The ApplicationStorageMain is created
first and passed to ApplicationSharedStorageMain's constructor.
The fallback is set on the Storage instance when the shared
database is created, so it's ready by the time reads happen.
Removes setFallbackStorage() method and post-init wiring.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Remove fallbackDatabasePath - use fallbackStorage only
The in-memory fallbackStorage (application storage) makes the
DB-level fallback (reading VS Code's DB from disk) redundant.
Both VS Code and Agents App now use the same mechanism: the
Storage.fallbackStorage property that reads from application
storage and auto-migrates on hit.
Removes getHostUserDataPath, IProductService dependency, and
INativeEnvironmentService from StorageMainService.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add MigratingStorage with persisted migration tracking
Introduce MigratingStorage that migrates keys from a fallback
storage on first access. Migrated keys are tracked via a
persisted marker key (__$__migratedStorageMarker) in the DB
so deleted keys are never resurrected from the fallback.
- VS Code windows: MigratingStorage falls back to own
APPLICATION storage for transparent key migration
- Sessions windows: MigratingStorage falls back to host
(VS Code) application storage loaded via IPC
- Main process: ApplicationSharedStorageMain uses
HostApplicationStorageMain for embedded app fallback
- sharedDataFolderName added to product configuration
- Workspace trust migration simplified (handled by
MigratingStorage automatically)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix compilation
* minimise changes
* some fixes
Co-authored-by: Copilot <copilot@github.com>
* fixes
* fix
* delete migrated key
* fix removing migrated key
* update distro
* feedback
* Fix MigratingStorage: persist marker only on actual migration
Add key to migratedKeys immediately before checking fallback
to prevent redundant lookups. Only persist the MIGRATED_KEY
marker when a value was actually found and migrated, avoiding
unnecessary writes when the key doesn't exist in the fallback.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feedback
* fix tests
Co-authored-by: Copilot <copilot@github.com>
* fix application storage path
* fix compilation
---------
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: welcome onboarding walkthrough variations A/B/C/D
* improve onboarding: sign-in CTA, keyboard mapping, skeleton themes, extensions step
* fix theme colors, keyboard mapping hint, clickable session cards, extension styling in B
* feat: add Variation E - in-context UI tour with spotlight overlay
* polish: cleaner theme skeletons, keyboard mapping pills, and session cards
* fix tour alignment: ID-based targeting, centered popovers, welcome tab setup
* tour: add sign-in as final step
* removed variations
* updated layout to match sessions experience
* refined
* Feature clean up and polish
* Refactor onboarding layout and styles for improved user experience
* updated ghe button
* removed other variations. changed command to Welcome Onboarding 2026
* removed keyboard maps for cursor and windsurf, added more theme options
* added support for other ides
* Add telemetry
* Addressing code review comments
* Remove 2 extension reccs and add setting to control onboarding
* Remove button click from feature cards and update command category
* - Removed the preview properties from IOnboardingThemeOption and related theme options.
- Deleted IOnboardingKeymapOption interface and ONBOARDING_KEYMAP_OPTIONS array.
- Consolidated AI collaboration preferences into a single enum and options array.
- Added new SVG files for theme previews: dark 2026, high contrast dark, high contrast light, light 2026, solarized dark, and solarized light.
* Refine agent sessions step and footer layout
- Rename Background Agents to Copilot CLI
- Move video tutorials link to bottom of content area (above footer)
- Move sign-in nudge button to footer left with visible border
- Remove agents tutorial link and sessions-docs separator
- Add footerLeft container for last-step footer elements
- Remove unused _renderSignInNudge method
- Make doc-link icon inherit link color
* Refactor onboarding service and update startup page
* Resolve merge conflicts, move theme options to product.json, default onboarding setting to false
Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/da410dab-8ffb-4cc5-9afd-6e968b0c5ed6
Co-authored-by: cwebster-99 <60238438+cwebster-99@users.noreply.github.com>
* Update src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts
* Update src/vs/workbench/contrib/welcomeGettingStarted/browser/startupPage.ts
Co-authored-by: Josh Spicer <23246594+joshspicer@users.noreply.github.com>
* Fix timing for onboarding widget on startup
* update distro to 84f56fc18b
* pass --skip-welcome
---------
Co-authored-by: cwebster-99 <cowebster@microsoft.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cwebster-99 <60238438+cwebster-99@users.noreply.github.com>
Co-authored-by: Josh Spicer <23246594+joshspicer@users.noreply.github.com>
Add a shared keychain service that stores secrets directly in the macOS
Keychain, allowing Code and its embedded Agents app to share auth tokens
without re-authentication.
Architecture:
- ISharedKeychainService (common interface) with ISharedKeychainMainService
running in the Electron main process, exposed to renderer via IPC
- SharedKeychainMainService wraps @vscode/macos-keychain native addon
- NativeSecretStorageService now writes to both the shared keychain and
the legacy safeStorage+SQLite pipeline (for rollback safety)
- On read, shared keychain is tried first, falling back to legacy
Product configuration:
- darwinSharedKeychainServiceName: per-flavor service name for data
isolation between Stable/Insiders/Exploration
- Access group auto-detected from entitlements by the native addon
Key design decisions:
- Shared keychain only used when type is 'persisted' (not in-memory)
- BaseSecretStorageService refactored to expose protected _doGet/_doSet/
_doDelete/_doGetKeys for use by subclasses within sequencer tasks
- Native addon is an optional dependency (macOS-only)
Files:
- build/azure-pipelines/darwin/app-entitlements.plist (keychain-access-groups)
- src/vs/platform/secrets/common/sharedKeychainService.ts (interface)
- src/vs/platform/secrets/electron-main/sharedKeychainMainService.ts (impl)
- src/vs/workbench/services/secrets/electron-browser/sharedKeychainService.ts (IPC proxy)
- src/vs/workbench/services/secrets/electron-browser/secretStorageService.ts (wiring)
Issue: #308028
- Updates js-debug extension from version 1.110.0 to 1.112.0
- Updates corresponding sha256 hash for verification
(Commit message generated by Copilot)
* generate configuration policy and manifests
* add darwin pipeline job
* argument for per-platform generation of policy
* adopt argument in pipeline
* formatting tweaks in generated profile (+ check in .js file)
* tidy up output plists
* copy policy definitions
* implement the remaining renderProfileValue()
* remove unnecessary platform option
* copy to .app in vscode-darwin-$PLATFORM-min-ci gulp task
* add darwinProfileUUID and darwinProfilePayloadUUID to product.json
* better way to package in gulp script
* bump distro commit (c3ec5ba485)
* Add bundles policy paths to macOS universal build 'filesToSkip'
Needs this when creating universal macOS app:
Expected all non-binary files to have identical SHAs when creating a universal build
but "Contents/Resources/app/policies/cs-cz/com.microsoft.VSCodeInsiders.plist" did not
See:
298a872f5f/src/index.ts (L163-L172)