Files
awesome-copilot/extensions/flight-map-canvas
Aaron Powell a7fdcd5006 Migrate plugins and canvas extensions to Agent Plugins spec (#2546)
* feat: migrate plugins and extensions to Agent Plugins v1.0.0 spec

- Add \ to all 69 curated plugin manifests
- Migrate all 18 extension manifests: add \, move logo into
  xtensions.com.github.copilot.logo namespace, remove top-level
  logo and string xtensions: '.'
- Update eng/validate-plugins.mjs: require \, validate
  namespace-keyed extensions object for canvas extensions, widen
  name pattern to allow dots (spec §5.5, max 64 chars)
- Update eng/materialize-plugins.mjs: emit spec-clean served manifests
  (only spec fields: \, name, version, description, author,
  homepage, repository, license, keywords, extensions)
- Update eng/generate-website-data.mjs: read logo from namespace
  with fallback to top-level logo for compatibility
- Update eng/create-plugin.mjs: scaffold emits \
- Add .github/workflows/validate-plugins.yml: blocking CI for PRs
  touching plugins/** or extensions/**
- Add spec compliance check to external plugin quality gates:
  non-blocking warnings with /⚠️/🛑 emoji legend
- Update AGENTS.md: document new extension manifest shape,
  add \ to plugin checklist

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* refactor: consolidate canvas extension plugins

- Move all extension plugin manifests from extensions/<name> to plugins/<name>
- Keep extensions/<name> as reusable source only
- Remove standalone extension discovery from marketplace and website plugin catalogs
- Auto-bundle same-name extension sources during materialization
- Add build-only extensions.json references for sharing extensions across plugins
- Remove x-awesome-copilot extension metadata support
- Update validation and contributor documentation

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* feat: add canvas extension scaffolding skill

- Add repo-local skill for creating canvas extension sources
- Generate spec-compliant plugin manifests under plugins/
- Support registering reusable extensions with multiple plugins
- Remove guidance for extension-local plugin manifests and custom fields

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* fix: align extension namespaces with current guidance

- Use each extension ID as its manifest namespace key
- Update validation and website generation to resolve extension-specific namespaces
- Upsert plugin validation PR comments using the existing repository pattern

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* fix: use Copilot extension namespace

- Adopt com.github.copilot for all canvas extension manifests
- Require the namespace during validation and website generation
- Update extension scaffolding guidance

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* docs: regenerate plugin catalog after merge

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* refactor(plugins): move manifests to plugin roots

Use root plugin.json manifests and namespaced extension directories throughout local tooling, validation, generation, and contributor documentation. Restore materialize-plugins.mjs line breaks so the source remains readable in GitHub.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* feat(plugins): migrate manifests to namespaced composition

Move repository composition metadata under com.github.awesome-copilot, materialize reusable extensions into the plugin extensions directory, and improve contributor and PR validation guidance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* fix(validation): address plugin review findings

Restore executable build scripts, validate namespaced manifests and hook directories, improve README item counts, and manage validation comments across reruns.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76
2026-08-06 22:29:31 +10:00
..

Flight Map Canvas

A GitHub Copilot canvas that generates a view where Google Maps can be explored using 3D controls, as if a flight simulator. No 3D plane model as the focus is the aerial landscape. Fly around in 1st person for several minutes, starting from a capital city while Copilot works.

It is a canvas port of the Flight Map VSCode extension. Satellite imagery tiles stream in around the camera as it moves, unloaded gaps are filled with color sampled from the viewport, and drifting procedural clouds sit over the fill. The HUD reads heading, speed, altitude, pitch, and live coordinates, with the city, region, and country under the camera looked up as it flies.

While an agent works in the session, it can send the flight somewhere new and report what it is doing on a status strip under the HUD.

Files

  • extension.mjs — canvas declaration, loopback game server, the host shim it injects into the page, destination resolution, and agent actions.
  • game/ — the simulator itself, byte for byte the VSCode extension's media/ folder. index.html is its flightMap.html; the rest is the Three.js scene, tile loader, flight controls, terrain fill, HUD, and configuration panel.
  • game/vendor/three.min.js — vendored Three.js r128, so the only remote requests are the ones the simulation makes for imagery and place names.
  • renderMap.json — the render configuration the canvas starts on.
  • assets/ — app icon and preview.png for the extensions gallery.
  • package.json — declares the Copilot SDK dependency and ESM entry point.
  • copilot-extension.json — Copilot extension name/version metadata.

Prerequisites

  • Node.js 20.19 or newer, because the Copilot SDK requires node ^20.19.0 || >=22.12.0.
  • A WebGL-capable canvas surface; the scene is rendered through Three.js.
  • Network access. Satellite tiles, the location label, and destination lookups are all fetched at runtime.
  • The GitHub Copilot app canvas / UI-extensions experiment enabled.

Install

Drop this folder at ~/.copilot/extensions/flight-map-canvas/ for user scope, or in a repository at .github/extensions/flight-map-canvas/ for project scope. Then install dependencies from inside the copied folder:

# User scope
cd ~/.copilot/extensions/flight-map-canvas

# Or project scope, from the repository root
cd .github/extensions/flight-map-canvas

npm install

Reload extensions in the GitHub Copilot app, then open the flight-map-canvas canvas. Pick a destination from the menu, click the view to start flying, and use the controls below.

The canvas accepts optional open inputs, resolved the same way fly_to resolves them:

Input Type Description
capital string A world capital by city or country name. Matched against the capitals the canvas ships with.
city string City name for anywhere that is not a shipped capital. Geocoded on the way in.
state string State, region, province, or district that narrows the city.
country string Country that narrows the city.
lat / lng number Raw coordinates, which skip the geocoder entirely. Latitude runs -85.0511 to 85.0511, the limit of the Web Mercator tile imagery; longitude runs -180 to 180. Give both or neither.

Opened with no input, the canvas starts on its own welcome screen and waits for a destination.

Controls

Input Action
W / S or Up / Down Throttle
Mouse (after clicking the view) Pitch and yaw
A / D or Left / Right Roll
Q / E Rudder yaw
R / F Climb / descend
Space Auto-level
Shift Boost
P Pause / resume
Esc Release the view

Mouse look prefers pointer lock. If the canvas host refuses it, the controls fall back to drag look: hold the left mouse button and move to steer. The on-screen help says which mode is active.

The Destination menu lists the world capitals grouped by continent and opens with Input Destination, which takes a typed state/region and city plus a country from a menu, then lists what matched so one can be selected. Config opens live rendering sliders, and Export JSON downloads the current configuration as renderMap.json.

Agent actions

  • fly_to { capital?, city?, state?, country?, lat?, lng? } — send the flight to a destination. A capital is matched against the shipped list, a city is geocoded, and a lat/lng pair is flown to directly. Called with no input it picks a random world capital, which is the way to say "take me somewhere else".
  • report_job { status, tokens?, done? } — report the current job step. The status shows on a strip under the HUD and the token count runs beside it. Call it when work starts, again on each new step, and once more with done: true when finished.

To have the agent narrate itself automatically, reference these actions from a .github/copilot-instructions.md so it calls report_job on each step of a chat request.

How the port works

The simulator under game/ is unchanged from the VSCode extension. That page was already written to run in two places, and it reaches whatever is hosting it through one seam: an acquireVsCodeApi() object for messaging, and a <!--{{HOST_HEAD}}--> placeholder in its <head> that the host fills with a content security policy and its render configuration.

extension.mjs fills that seam for the canvas:

  • A loopback HTTP server serves the page and its assets, replacing the placeholder with a policy, the render configuration read from renderMap.json, and a shim that defines acquireVsCodeApi().
  • Agent activity is streamed to the page over Server-Sent Events at /events. The shim translates those events into the exact flyTo and jobStatus commands the page already registers handlers for.
  • The page's export button has no save dialog to reach here, so the shim falls back to the browser download the standalone page uses.
  • Destinations are resolved server-side before broadcasting, against the page's own capitals.js for shipped capitals and OpenStreetMap Nominatim for everything else.

This mirrors the backrooms-canvas and arcade-canvas architecture: a static frontend served from a loopback server, with the agent driving it through canvas actions.

Development

The port is a copy, not a fork. Everything under game/ comes from the VSCode extension's media/ folder, so edits belong there.

In that repository the two are held together by symlinks, which means there is only ever one copy to edit and the port cannot go stale. Submission needs real files, though, because a link pointing at a sibling repository resolves to nothing anywhere else, so the stage command resolves every link on the way out:

# In the vscode-flight-map repository
npm run canvas:link                     # create or repair the symlinks
npm run canvas:check                    # verify them; non-zero when stale
npm run canvas:stage -- <destination>   # real-file copy for submission

media/flightMap.html is linked as game/index.html; nothing else is renamed and no file is rewritten. To run the simulator outside a canvas while working on it, open media/flightMap.html in a browser.

Credits

  • Source extension and canvas port: vscode-flight-map by John Haugabook.
  • Satellite imagery: Google Maps tiles, with Esri World Imagery as the fallback provider. The imagery is served by, and remains the property of, those providers; this canvas only displays it, subject to their respective terms of service.
  • Place names and destination lookups: OpenStreetMap Nominatim. Data © OpenStreetMap contributors, available under the Open Database License.
  • 3D rendering: Three.js r128.

License

MIT