Files
vscode/scripts/mock-policy-server/public/index.html
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

121 lines
4.0 KiB
HTML

<!--
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License. See License.txt in the project root for license information.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Policy Server</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<header>
<div class="header-content">
<div>
<h1>Policy Server</h1>
<p class="sub">Mock Copilot policy endpoints</p>
</div>
</div>
</header>
<main>
<section class="editor-panel">
<div class="tabs-header">
<nav id="tabs" class="tabs" aria-label="Policy endpoints"></nav>
</div>
<div class="content-section">
<p id="endpoint-meta" class="endpoint-description"></p>
<div class="form-group">
<div class="label-row">
<label for="preset">Preset</label>
</div>
<div class="row">
<select id="preset"></select>
<button id="apply-preset" type="button" class="btn-secondary">Apply</button>
</div>
</div>
<div id="schema-section" class="section-block" hidden>
<div class="section-header section-header-toggle" id="schema-toggle">
<span class="chevron" id="schema-chevron">&#9654;</span>
<h2>Schema</h2>
<span id="schema-badge" class="schema-badge" data-tooltip="">&hellip;</span>
<span class="info-icon" data-tooltip="Clone github/copilot-agent-runtime for the schema">&#9432;</span>
</div>
<div id="schema-details" class="schema-details" hidden>
<input id="schema-source" type="text" class="schema-source-input" placeholder="Path or URL to schema JSON">
<div class="button-group">
<button id="refresh-schema" type="button" class="btn-secondary">Load</button>
<button id="hydrate-schema" type="button" class="btn-secondary">Generate example</button>
<button id="toggle-schema" type="button" class="btn-secondary">View</button>
</div>
<pre id="schema-view" class="code schema-view" hidden></pre>
</div>
</div>
<div class="form-group">
<div class="label-row">
<label for="editor">Response body (JSON)</label>
</div>
<textarea id="editor" spellcheck="false" autocomplete="off"></textarea>
<p id="editor-status" class="status" aria-live="polite"></p>
<div id="validation-results" hidden></div>
</div>
<div class="button-group">
<button id="format" type="button" class="btn-secondary">Format JSON</button>
</div>
<div class="endpoint-url-box">
<span class="label-small">Endpoint URL</span>
<span id="endpoint-url" class="code endpoint-url"></span>
</div>
</div>
</section>
<aside class="sidebar-panel">
<div class="section-block">
<div class="section-header">
<h2>product.overrides.json</h2>
<span class="info-icon" data-tooltip="Redirects Copilot policy URLs to this local server. Restore reverts to the original file. Reload Code OSS after.">&#9432;</span>
</div>
<div class="status-box">
<span class="label-small">Status</span>
<strong id="wired-status">&#8230;</strong>
</div>
<div class="button-group-vertical">
<button id="wire" type="button" class="btn-primary btn-full">Apply overrides</button>
<button id="unwire" type="button" class="btn-secondary btn-full">Restore original</button>
<button id="copy-overrides" type="button" class="btn-secondary btn-full">&#128203; Copy JSON</button>
<button id="copy-overrides-path" type="button" class="btn-secondary btn-full">&#128203; Copy file path</button>
</div>
</div>
<div class="section-block">
<div class="section-header">
<h2>Apply changes</h2>
</div>
<ol class="steps">
<li>Reload Code OSS window</li>
<li>Sign in with GitHub account</li>
<li>Run <strong>Developer: Sync Account Policy</strong></li>
<li>Run <strong>Developer: Policy Diagnostics</strong></li>
</ol>
</div>
</aside>
</main>
<script src="./endpoints.js"></script>
<script src="./app.js"></script>
</body>
</html>