Files
vscode/scripts/mock-policy-server/README.md
T
Josh Spicer 593c7f2366 policy: 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>
2026-06-18 21:55:01 +00:00

83 lines
3.9 KiB
Markdown

# Mock Copilot policy endpoints
A standalone dev tool that mocks the Copilot **policy** endpoints that
`DefaultAccountService`
(`src/vs/workbench/services/accounts/browser/defaultAccount.ts`) calls, so you
can exercise the entitlement / token / MCP-registry / managed-settings (policy)
pipeline locally without the real GitHub backend.
It is **not** part of the shipped product — it is a local Node server + web GUI.
## What it mocks
| Endpoint | Path | `product.json` key | Response |
| --- | --- | --- | --- |
| Entitlements | `/copilot_internal/user` | `entitlementUrl` | `IEntitlementsData` (`chat_enabled`, `copilot_plan`, `cloud_session_storage_enabled`, …) |
| Token | `/copilot_internal/v2/token` | `tokenEntitlementUrl` | `{ token: "agent_mode=1;editor_preview_features=1;mcp=1;…:sig" }` |
| MCP registry | `/copilot/mcp_registry` | `mcpRegistryDataUrl` | `{ mcp_registries: [{ url, registry_access }] }` |
| Managed settings | `/copilot_internal/managed_settings` | `managedSettingsUrl` | `IManagedSettingsResponse` (enterprise `settings.json`) |
The flow is gated: the **token** and **managed settings** are only fetched when
entitlements report `chat_enabled: true`, and the **MCP registry** only when the
token enables `mcp`.
## Usage
```sh
npm run mock-policy-server # starts on http://127.0.0.1:3000
npm run mock-policy-server -- --port 4000
npm run mock-policy-server -- --schema ./copilot-agent-runtime/schema/managed-settings-schema.json
```
1. Open the printed GUI URL.
2. Pick an endpoint tab, choose a preset or edit the JSON, and **Save**.
3. Click **Wire all endpoints** to point `product.overrides.json` at this server.
4. **Reload** Code OSS (running from sources, so `VSCODE_DEV` is set).
5. Sign in with your GitHub/Copilot account.
6. Run **Developer: Sync Account Policy** (forces a refresh).
7. Run **Developer: Policy Diagnostics** to inspect the applied values.
Click **Unwire** to restore the original URLs.
## Managed-settings schema
The GUI loads the managed-settings JSON schema and, on the **Managed Settings**
tab, warns about top-level keys that are not declared in it (mirroring how
`projectManagedSettings` drops undeclared keys). The schema source is resolved in
this order:
1. `--schema <url | file-uri | path>` CLI flag
2. `MANAGED_SETTINGS_SCHEMA` environment variable
3. Default: `./copilot-agent-runtime/schema/managed-settings-schema.json`,
resolved against the **app's current working directory** (normally the vscode
repo root, where the schema repo sits side-by-side).
`http(s)://` URLs and `file://` URIs are both accepted; relative paths are
resolved from the cwd. The schema is re-read on every **Refresh**, so you can
edit it without restarting the server. A missing schema is non-fatal — the GUI
just shows the resolved path and skips schema validation.
## How wiring works
`src/bootstrap-meta.ts` merges `product.overrides.json` over `product.json` with
a shallow, top-level `Object.assign`, only when `VSCODE_DEV` is set, and the file
is git-ignored. To override nested keys the tool writes back the **entire**
`defaultChatAgent` object (seeded from `product.json`) with only the four
endpoint URLs flipped, preserving every other key. Unwiring restores those URLs
to their `product.json` values and removes the file if nothing else remains.
## Caveats
- Works for the **default (github.com) provider** path, which reads these URLs
directly from config. The enterprise provider derives some URLs from the
enterprise host instead.
- You must be **signed in**; the fetch only fires for an authenticated account.
- Overrides require a **reload** and only apply when running from sources.
- The server ignores the `Authorization` header — any token is accepted.
## Files
- `server.js` — zero-dependency Node `http` server (endpoints + control API + schema loader + static).
- `endpoints.js` — shared endpoint definitions and presets (used by server and GUI).
- `public/` — the web GUI (`index.html`, `app.js`, `style.css`).