* Add keyword display to extension cards on website - Add .resource-keywords and .keyword-tag CSS styles for rendering keyword badges - Update renderExtensionsHtml() to display keywords below extension description - Keywords now visible on the website extensions page with styled badges - Regenerate website data to include keyword metadata Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Canvas manifest implementation for all extensions Add per-extension canvas manifests with: - Structured canvas metadata (name, description, version, keywords) - Screenshot definitions (icon and gallery with path/type) - Relative paths for images within each extension directory Enhance extension metadata: - Generate meaningful descriptions from source analysis - Extract and assign keywords for discoverability - Store metadata in package.json and extension source files Update website rendering and data generation: - Include keywords in extension cards and search index - Add per-extension canvas.json files for independent evolution - Support screenshot metadata in manifest structure - Generate extensions.json with full canonical paths for website All 9 local canvas extensions now have complete manifests with descriptions, keywords, and screenshot references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Tweaking some descriptions * Fix description priority to prefer package.json over in-source metadata Reverse the priority in canvasDescription so that package.json descriptions (which contain the enhanced, manually-curated descriptions) take precedence over older in-source descriptions extracted from createCanvas(...) calls. This prevents regression when npm run website:data regenerates outputs, ensuring that committed canvas.json files maintain the current descriptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix canvas validation to skip external.json file The validation script was treating extensions/external.json as if it were a directory, causing false validation failures. Added check to skip files (identified by presence of dot in filename) and only validate actual canvas extension directories. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Chromium Control Canvas
A GitHub Copilot canvas that drives a real headful Chromium window via Playwright.
The host app's built-in browser canvas is WebKit (WKWebView); this gives you actual
Chromium, controllable both from the panel UI and by the agent.
The canvas panel is a control strip (URL bar, back/forward/reload, screenshot). A separate Chromium window does the real rendering, because you can't embed Chromium inside a WebKit iframe.
Files
extension.mjs— the extension: canvas declaration, Playwright launch, a loopback HTTP server for the panel, and the agent actions.index.html— the control strip UI the panel renders.package.json— declares theplaywrightdependency and"type": "module".copilot-extension.json— name/version metadata.
Prerequisites
- Node.js 20.19 or newer (the Copilot SDK requires
node ^20.19.0 || >=22.12.0). The extension runs as a Node child process. - The app's canvas / UI-extensions experiment enabled. Without it, the extension loads but the canvas never appears in the panel. Enable it in the app's Settings → Experiments. (This may not be available to all accounts.)
Install
Drop this folder at ~/.copilot/extensions/chromium-control-canvas/ (user scope) or in a repo's
.github/extensions/chromium-control-canvas/ (project scope), then install dependencies and the
Chromium binary from inside the folder you copied:
# User scope
cd ~/.copilot/extensions/chromium-control-canvas
# Or project scope, from the repository root
cd .github/extensions/chromium-control-canvas
npm install # playwright is declared in package.json
npx playwright install chromium # downloads the browser, a few hundred MB
Reload extensions in the app, then open the chromium-control-canvas canvas.
Note: copying the extension files only places the source. It does not run the commands above or enable the experiment, so those steps are still required on first setup.
Attach to your own Chrome
By default the canvas launches the bundled Chromium with a persistent profile. To drive
a Chrome you already have running instead, start it with a debug port and pass cdpUrl
when opening the canvas:
google-chrome --remote-debugging-port=9222 # then open the canvas with cdpUrl: http://localhost:9222
In this mode the extension connects over CDP and never launches or kills your browser; closing the canvas just disconnects.
Agent actions
navigate { url }— go to a URL or search query (blocklist-guarded).back/forward/reload— history navigation.current_url— current URL and page title.snapshot— structured list of visible interactive elements, each with a stable ref.click { ref | selector }— click an element by snapshot ref or CSS selector.type { ref | selector, text, submit? }— fill an input; optionally press Enter.screenshot { fullPage? }— save a PNG toartifacts/and return its path and size.
Notes
- A persistent profile is stored under
$COPILOT_HOME/extensions/chromium-control-canvas/profile(default~/.copilot/extensions/chromium-control-canvas/profile) so logins survive restarts. Do not commit or share this folder — it contains real session cookies. - Raw
evaluate(arbitrary in-page JS) is intentionally omitted. navigateis checked against a blocklist, and a request interceptor also blocks navigations to blocked hosts that happen via in-page redirects. The shippedBLOCKLISTentries are illustrative examples, not real coverage — edit the list inextension.mjsto fit your environment.- The loopback control server requires a per-launch token (templated into the panel), so other pages in your browser can't drive it.
- Typed text (e.g. passwords) is redacted in
audit.log, and password field values are excluded from snapshots. - Generated at runtime and not part of the source:
node_modules/in the copied extension folder, plusprofile/,artifacts/, andaudit.logunder$COPILOT_HOME/extensions/chromium-control-canvas/.