joshspicer
90d · built 2026-08-09
90-day totals
- Commits
- 35
- Grow
- 10.5
- Maintenance
- 2.9
- Fixes
- 1.4
- Total ETV
- 14.8
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 42 %
- By Growth share
- Top 4 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↓-11.8 %
vs 17 prior
↑+13.3 pp
recent vs prior
↑+12.7 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 2.0ETVpolicy: dev mock server for copilot_internal policy endpoints (#321871) * policy: add dev mock server for copilot_internal policy endpoints Adds scripts/mock-policy-server, a standalone dev tool (npm run mock-policy-server) that mocks the Copilot policy endpoints DefaultAccountService calls: entitlements (/copilot_internal/user), token (/copilot_internal/v2/token), MCP registry (/copilot/mcp_registry) and managed settings (/copilot_internal/managed_settings). A small web GUI lets devs pick presets or edit each JSON response, and Wire/Unwire buttons point product.overrides.json at the local server (preserving the rest of defaultChatAgent, since bootstrap-meta merges overrides shallowly). The managed-settings JSON schema is loaded from --schema/MANAGED_SETTINGS_SCHEMA, defaulting to ./copilot-agent-runtime/schema/managed-settings-schema.json relative to the app cwd; web URLs and file URIs are accepted, and the GUI warns about keys not declared in the schema. The three browser/shared .js files are added to .eslint-allowed-javascript-files since the GUI loads them directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: address mock-policy-server review feedback - Scope permissive CORS to the mocked GET endpoints only; keep /api/* same-origin so a website can't drive /api/wire and rewrite product.overrides.json (CSRF). - Coerce an empty editor body to {} instead of "" so mocked responses stay JSON objects. - Build the endpoint meta line with textContent/DOM nodes instead of innerHTML. - Drop the misused tablist/tab ARIA roles; the nav now has an aria-label and the active item uses aria-current. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: document mock policy server in add-policy skill Add local-testing.md to the add-policy skill with basic steps for using the mock policy server (scripts/mock-policy-server) to exercise the account/managed-settings flow locally, and link it from SKILL.md and github-managed-settings.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: polish mock server GUI — schema validation, wiring backup, localStorage persistence * policy: auto-save, rename wiring to product.overrides.json, copy path button * mock-policy-server: convert server.js to TypeScript; add raw response diagnostics - Convert server.js → server.ts (runs via --experimental-strip-types) - Add endpoints.d.ts type declarations for the UMD endpoints module - Add managedSettingsRawResponse to IDefaultAccountProvider/IDefaultAccountService - Show raw response in Developer: Sync Account Policy output - Remove server.js from eslint allowed-javascript-files * mock-policy-server: convert all JS to TypeScript - endpoints.js → endpoints.ts with proper interfaces (replaces .d.ts) - public/app.js → public/app.ts with full type annotations - Server uses module.stripTypeScriptTypes() to serve .ts as plain JS to the browser — no build step needed - Remove all mock-policy-server entries from .eslint-allowed-javascript-files --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 593c7f23 · 2026-06-18
- 2.0ETVpolicy: enterprise managed_settings for Copilot clients (#318623) * 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>github.com-microsoft-vscode · b24c5e38 · 2026-05-29
- 1.2ETVAdd discovery of copilot MDM policy (#320991) * Add Copilot managed settings policy source * Refactor Copilot managed settings policy evaluation * Clarify raw managed settings bridge policy * Use dedicated Copilot managed settings service * Avoid Copilot managed settings IPC update loopgithub.com-microsoft-vscode · d72b81a9 · 2026-06-12
- 1.1ETVLoad managed-settings.json from well-known disk path (#321870) Add a file-based managed-settings delivery channel that reads managed-settings.json from a well-known per-OS disk path in the main process and exposes it to renderer windows over IPC. Mirrors the existing Copilot managed-settings (server / native MDM) channels. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 865f5a0b · 2026-06-24
- 1.0ETVchat: Enforce per-marketplace plugin auto-updates (#327844) * chat: Enforce per-marketplace plugin auto-updates Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: Address plugin auto-update review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: Regenerate marketplace policy data Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · d5eb7d2e · 2026-07-31
- 0.9ETVImprove managed settings policy diagnostics (#327332) * Improve managed settings diagnostics * Fix local managed settings diagnostics routinggithub.com-microsoft-vscode · 95307914 · 2026-07-24
- 0.7ETVAdopt forceRemoteSettingsRefresh managed control Treat the managed setting as a transport control, resolve native MDM precedence before serving a fresh cache, and retry transient native IPC initialization failures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d323b28f-73e8-4505-a40d-ceeeff683be6github.com-microsoft-vscode · 346d7c52 · 2026-08-05
- 0.7ETVchat: enforce managed customization lockdown (#327843) * chat: enforce managed customization lockdown Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: address customization lockdown review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: align lockdown controls with boolean schema Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * build: keep policy catalog changes focused Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: include instructions in plugin-only lockdown Block standalone instruction and agent-instruction files when strict plugin-only customization is enforced, while preserving plugin instructions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · fc931f57 · 2026-07-31
- 0.7ETVRefactor Copilot managed-settings for maintainability (#322439) * Refactor Copilot managed-settings for maintainability Centralize structured (object/array) managed-setting handling behind a single descriptor table so adding a key touches one place, consolidate the duplicated equality helpers onto `equals`, and add shared `hasManagedSettingsDefinitions` and `managedSettingValue` helpers. Strictly behavior-preserving. Incorporates a 3-model maintainability review: - `adaptManagedSettings` builds the scalar remainder via `{ ...response }` plus delete (CopyDataProperties) instead of for..in + assignment, so a server-sent own `__proto__` key cannot trigger the inherited setter. This matches the original `...rest` semantics; adds a regression test. - `managedSettingValue` is memoized per key so its policy-definition reference identity is real rather than incidental to the call site. - Corrected JSDoc and skill docs that overstated `responseField` as compiler-checked; it is a hand-maintained union backstopped by tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify why structured managed-settings keys must declare type: 'string' The bag-carrying `type` is load-bearing, not cosmetic: `projectManagedSettings` gates each value with `typeof value === type` and drops mismatches, and the native MDM watcher reads the registry/plist value as that type. Spell out that omitting it (or declaring the object/array type) makes a structured key fail projection and silently never apply. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: allocation-free empty check, __proto__ test, doc accuracy - hasManagedSettingsDefinitions: reuse the allocation-free isEmptyObject helper instead of Object.keys(...).length (the bot's only valid nit). - Add a primitive `__proto__` regression test proving a server-sent `{"__proto__": true}` scalar is dropped, never pollutes the result (disproves the reviewer's prototype-pollution concern). - Fix github-managed-settings.md: omitting `type` or declaring `'object'`/`'array'` is a compile error (the field is required and constrained to `'string' | 'number' | 'boolean'`), not a runtime drop; only `'number'`/`'boolean'` compile-but-drop-at-runtime. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Surface managed-settings source in Policy Diagnostics Centralize the server-over-MDM precedence into a shared selectManagedSettings helper (plus a ManagedSettingsSource union) and reuse it in both AccountPolicyService and the Policy Diagnostics report, so the report can never drift from the source that policy evaluation actually applies. Rewrite the diagnostics "Managed Settings" section to: - show the Active source (GitHub Server API / Native MDM / None) - break down each channel (server fetch status + raw response, native MDM bag) - label the raw response as the last *successful* fetch, so a later failed fetch (e.g. a 404) no longer looks like it contradicts an empty effective bag - compute the true effective bag via the shared projectManagedSettings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix mock policy server "Generate example" not persisting The "Generate example" button filled the editor and the localStorage draft but never called debouncedSave(), so the generated body was never POSTed to /api/state and the endpoint kept serving the empty preset. Add the missing debouncedSave() to match applyPreset() and the editor input handler. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Strip prose from Policy Diagnostics and collect managed-settings parse errors The Developer: Policy Diagnostics "Managed Settings" section now renders data only (tables and JSON blocks, no explanatory paragraphs). It also collects non-fatal parsing/normalization warnings from every stage of the managed-settings pipeline, jsonc-style (accumulate, never throw), and surfaces them in a new "Parse Errors" section: - adapt: re-runs adaptManagedSettings on the raw server response - project: re-runs projectManagedSettings against the declared policy keys - parse: re-parses JSON-payload string values with the jsonc parser This explains why a key is silently dropped. For example a server extraKnownMarketplaces entry with source "github" but no "repo" now shows the "requires \"repo\"" warning instead of just vanishing from the bag. Adds a focused test for that github-without-repo normalization case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Tighten Policy Diagnostics managed-settings rendering (review follow-up) Code-quality pass on the managed-settings diagnostics section: - Extract a jsonBlock() helper for the repeated fenced-JSON rendering (4 call sites collapsed). - Parse only the known JSON-payload keys (enabledPlugins, strictKnownMarketplaces, extraKnownMarketplaces) instead of a leading-brace heuristic. This mirrors what PolicyConfiguration actually parses, avoids mis-sniffing scalar values, and catches malformed payloads that don't start with a brace. - Unify the raw-response guard on isObject() so the printed raw response and the adapt-stage warning harvest use one predicate. - Drop the defensive object copy in projectManagedSettings(); it is read-only, so normalize undefined with `?? {}` instead of spreading. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix native MDM availability in Policy Diagnostics; tidy table headers The diagnostics report showed "Native MDM | Available | no (desktop only)" even on desktop. ICopilotManagedSettingsService was registered only in the electron-main process and hand-plumbed into AccountPolicyService, but never placed in the renderer service collection, so the report's accessor.get(ICopilotManagedSettingsService) always threw and mislabeled the channel as unavailable. Register the CopilotManagedSettingsChannelClient (the renderer's handle to the main-process service) in the service collection in both desktop.main.ts and sessions.main.ts. The diagnostics now resolves it on desktop and Agents windows and reports real native MDM availability and values; web still has no native channel and correctly reports unavailable. Also tidy the report builder: extract a PROPERTY_VALUE_TABLE_HEADER constant for the five repeated two-column table headers, and drop the now-misleading "(desktop only)" annotation on the availability row. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · a4ce08f7 · 2026-06-23
- 0.6ETVAllow one policy to apply to many settings (#321515) * 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>github.com-microsoft-vscode · 2fcb6694 · 2026-06-17
- 0.5ETVAgent Host: Require confirmation for managed permission asks (#327383) * Agent Host: Require confirmation for managed permission asks Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 18f1bbc1-6001-43e2-b293-724505087f6a * Agent Host: Route managed asks to client confirmation Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 18f1bbc1-6001-43e2-b293-724505087f6a * docs: align managed selector name with Domain Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c7f00b84-b0a7-4cdf-aca9-ffd49737f26e * Agent Host: Keep managed approvals one-time Remove session-scoped confirmation options for managed asks and ignore persisted allow-session responses defensively. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c7f00b84-b0a7-4cdf-aca9-ffd49737f26e * Agent Host: Preserve managed client tool confirmations Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 00fdaf07-fd6e-43e3-bcb8-dfc812c50913 --------- Copilot-Session: 18f1bbc1-6001-43e2-b293-724505087f6a Copilot-Session: c7f00b84-b0a7-4cdf-aca9-ffd49737f26e Copilot-Session: 00fdaf07-fd6e-43e3-bcb8-dfc812c50913github.com-microsoft-vscode · 13124ea3 · 2026-07-28
- 0.5ETVplugins: use manifest `name` for direct-install plugin labels (#315888) * plugins: use manifest `name` for direct-install plugin labels Direct-installed plugins (no marketplace metadata) were displaying their filesystem basename (e.g. `sukumarp2022--slide-creator-plugin`) instead of the human-readable `name` declared in their `plugin.json` manifest. Pre-read the manifest at plugin construction time and extend the label fallback chain to `fromMarketplace?.name ?? manifestName ?? basename(uri)`, matching the pattern already used by `readSinglePluginManifest`. Also introduces a tighter `IPluginManifest` interface to replace the loose `Record<string, unknown>` type. Fixes #315855 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * plugins: address PR review - Guard `manifest.name` with `typeof === 'string'` to defend against untrusted JSON (e.g. `name: 123`), which TypeScript can't catch because the parsed manifest is cast from `unknown`. - Add tests covering the manifest-name label fallback: one for the happy path (direct install with manifest `name`) and one for the fallback to basename when `name` is missing, blank, or non-string. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · e04aa9d8 · 2026-05-12
- 0.4ETVAlign managed settings MDM and account-based (#321218) * Route Copilot plugin/marketplace policies through the single managed-settings flow Make `IPolicyData.managedSettings` the single channel for enterprise-managed Copilot settings so server-delivered and native MDM-delivered settings resolve identically — the only difference is the source. - `adaptManagedSettings` now emits only the canonical `managedSettings` bag: scalars flatten to dot-paths; `enabledPlugins` / `extraKnownMarketplaces` are carried as canonical JSON strings (the same shape an admin authors via native MDM). `PolicyConfiguration` parses them back into the object-typed settings. - `ChatEnabledPlugins` / `ChatExtraMarketplaces` / `ChatStrictMarketplaces` now read from `policyData.managedSettings` and declare their managed-setting keys; removed the typed `enabledPlugins` / `extraKnownMarketplaces` / `strictKnownMarketplaces` fields from `IPolicyData`. - Relocate `extraKnownMarketplacesToConfigDict` to `base/common/managedSettings` for layering; re-export from the chat contrib. - Tests: rewrite `adaptManagedSettings` assertions to the canonical bag; add an end-to-end equivalence test proving a server JSON string and a native MDM JSON string resolve to the identical typed object. * Address review feedback - Reword `adaptManagedSettings` doc to not imply it enforces the declared schema; clarify that declaration-driven filtering happens later in `projectManagedSettings`. - Short-circuit `hasManagedSettingsPolicyDefinitions` instead of building the full aggregated definitions object just to answer a boolean.github.com-microsoft-vscode · 976d9981 · 2026-06-12
- 0.4ETVAdd managed settings refresh regression tests Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d323b28f-73e8-4505-a40d-ceeeff683be6github.com-microsoft-vscode · 68349311 · 2026-08-05
- 0.3ETVAllow remote resolver terminals before workspace trust (#329228) * Allow remote resolver terminals before trust Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 907702b2-eba4-43b0-9fca-eb56c92d0443 * Harden remote resolver terminal trust bypass Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 907702b2-eba4-43b0-9fca-eb56c92d0443 * Trim unrelated terminal lifecycle changes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f1887ba9-d3d8-4f0d-af4c-0046e73507ed * Scope resolver terminal startup path Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f1887ba9-d3d8-4f0d-af4c-0046e73507ed * Remove resolver trust timing constraint Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f1887ba9-d3d8-4f0d-af4c-0046e73507ed * Simplify resolver terminal trust bypass Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Minimize resolver terminal trust changes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Test resolver terminal proposal gate Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 907702b2-eba4-43b0-9fca-eb56c92d0443 Copilot-Session: f1887ba9-d3d8-4f0d-af4c-0046e73507edgithub.com-microsoft-vscode · 75f55934 · 2026-08-07
- 0.2ETVUpdate 'Policy and Managed Settings' skill (#329499) * docs: simplify enterprise policy guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: broaden enterprise policy skill trigger Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: rename enterprise settings skill Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 70ee5ae2 · 2026-08-07
- 0.2ETVAdd telemetry for applied enterprise policies (#326686) * Add telemetry for applied managed settings and device policies Emit a consolidated policy.applied event reporting which managed settings and OS/MDM device policies are applied, value buckets (e.g. default model forced to auto, telemetry level), and per-policy delivery source attribution (osPolicy/nativeMdm/server/file/accountData/ accountGate). A browser-layer workbench contribution consumes IPolicyService and fires once at startup plus on relevant policy, managed-settings, account-data, and gate changes (debounced, deduped). No raw policy values are collected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify applied policy telemetry * Coalesce policy telemetry during startup * Bucket invalid telemetry policy values --------- Co-authored-by: digitarald <hkirschner@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · d3afb120 · 2026-07-20
- 0.2ETVpolicy: resolve managed settings per-key across delivery channels (#323780) * policy: resolve managed settings per-key across delivery channels Managed settings previously used a single authoritative source: the first non-empty delivery channel (native MDM > server > file) won wholesale and the others were ignored entirely. Switch to per-key precedence: the same order is honored, but resolved key-by-key. A key locked by a higher-precedence channel still cannot be overwritten, while keys a higher channel leaves unset are now filled in by a lower channel. Centralize the resolution in a new pickManagedSettings() (replacing selectManagedSettings) that returns the merged bag, per-key provenance, and the active sources, so policy evaluation and the Policy Diagnostics report share one implementation. Build the merged bag with Object.fromEntries so an untrusted __proto__ key cannot corrupt its prototype chain. Rework the Policy Diagnostics report to show every contributing source, a per-key Resolution table (effective value, winning source, and struck-through overrides), and per-key policy attribution. Add unit coverage for the per-key merge (provenance, fill-down, falsy values, ordering, prototype-pollution guard) plus an end-to-end test proving two keys can win from two different channels and both reach policy evaluation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: iterate managed-settings bags with Object.keys over own props Address PR feedback: switch pickManagedSettings from `for...in` to a guarded `Object.keys` loop so only own enumerable properties are visited (managed-settings bags are untrusted input) and absent channels are skipped explicitly. Note: `for...in` over an undefined bag was already a no-op (never threw), so this is a robustness/clarity improvement rather than a crash fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: tidy pickManagedSettings unit suite Drop two redundant cases (distinct-keys and standalone activeSources ordering, both already covered by the headline and empty/absent tests) and fold the non-contributing-middle-channel ordering check into the empty/absent snapshot. Verified against the live node unit runner (all green). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 5a270e6d · 2026-07-01
- 0.2ETVGate Claude3PIntegration behind editor preview policy (#322851) * 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>github.com-microsoft-vscode · bf6124c4 · 2026-06-25
- 0.2ETVTidy Copilot managed-settings structured table for consistency (#323613) * Tidy Copilot managed-settings structured table for consistency Give every STRUCTURED_MANAGED_SETTINGS row a named encode* helper (encodeObject, encodeArray, encodeExtraMarketplaces) co-located with the existing encodeStringMap, instead of mixing inline lambdas with named refs. This keeps the central deserialization/mapping table uniform and easy to extend. No behavior change. base/common/managedSettings.ts stays the shared base-layer module (consumed by both the policy layer and chat plugin code), and IStrictMarketplaceSource is retained. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Harden extraKnownMarketplacesToConfigDict against prototype pollution Marketplace names arrive from managed settings (untrusted input) and are written as object keys, so skip __proto__/constructor/prototype keys, mirroring the guard already present in the managed-settings string-map encoder. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Centralize the default-model managed-settings value callback The model managed setting was the only managed-settings-driven control whose policy value callback was hand-rolled inline in chat.shared.contribution.ts (pass-through + trim + empty->undefined), while enabledPlugins / extraMarketplaces / strictMarketplaces all use the shared managedSettingValue() helper. Add a memoized managedModelValue() helper in copilotManagedSettings.ts that holds the model-specific trim/empty normalization, and wire the policy with value: managedModelValue() so every managed-settings control is declared the same way and the model normalization lives with the rest of the managed-settings logic. No behavior change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · fc8ff1bb · 2026-06-30