Add flight-map-canvas extension - #2482
Merged
Merged
Conversation
A canvas port of the Flight Map VSCode extension: a first-person satellite terrain map flown with flight simulator controls, for session breaks while an agent works. The simulator under game/ is copied verbatim from the source extension's media/ folder. That page already reached its host through one seam - an acquireVsCodeApi() object and a placeholder in its head - so extension.mjs fills that seam for the canvas: a loopback server that injects a policy, the render configuration, and a shim translating Server-Sent Events into the messages the page already handles. Two agent actions: fly_to sends the flight to a capital, a geocoded city, or a raw lat/lng, and picks a random capital when called with no input; report_job shows the current job step under the HUD. Adds the vendored three.min.js to the codespell skip list, matching the existing entry for arcade-canvas's phaser.min.js. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an installable flight-simulator canvas using satellite imagery, Three.js, and agent-driven destination/status actions.
Changes:
- Adds the loopback canvas host and simulator frontend.
- Adds destination search, flight controls, rendering configuration, and assets.
- Registers the extension in the GitHub Copilot marketplace.
Reviewed changes
Copilot reviewed 18 out of 22 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
.codespellrc |
Excludes vendored Three.js. |
.github/plugin/marketplace.json |
Registers the extension. |
extensions/flight-map-canvas/.github/plugin/plugin.json |
Defines marketplace metadata. |
extensions/flight-map-canvas/README.md |
Documents installation and usage. |
extensions/flight-map-canvas/assets/icon.png |
Provides the application icon. |
extensions/flight-map-canvas/assets/preview.png |
Provides the gallery preview. |
extensions/flight-map-canvas/copilot-extension.json |
Defines extension identity. |
extensions/flight-map-canvas/extension.mjs |
Implements canvas hosting and actions. |
extensions/flight-map-canvas/game/app.js |
Implements the map and simulation. |
extensions/flight-map-canvas/game/capitals.js |
Supplies capital destinations. |
extensions/flight-map-canvas/game/destinationInput.js |
Implements destination selection. |
extensions/flight-map-canvas/game/flightControls.js |
Implements flight controls. |
extensions/flight-map-canvas/game/geocoder.js |
Integrates Nominatim geocoding. |
extensions/flight-map-canvas/game/hostBridge.js |
Bridges host messages. |
extensions/flight-map-canvas/game/index.html |
Defines the simulator UI. |
extensions/flight-map-canvas/game/renderConfig.js |
Manages rendering configuration. |
extensions/flight-map-canvas/game/styles.css |
Styles the simulator interface. |
extensions/flight-map-canvas/game/terrainFill.js |
Generates terrain and cloud fill. |
extensions/flight-map-canvas/game/vendor/three.min.js |
Vendors Three.js r128. |
extensions/flight-map-canvas/package-lock.json |
Locks dependencies. |
extensions/flight-map-canvas/package.json |
Declares package metadata. |
extensions/flight-map-canvas/renderMap.json |
Provides initial render settings. |
Files not reviewed (1)
- extensions/flight-map-canvas/package-lock.json: Generated file
Comments suppressed due to low confidence (1)
extensions/flight-map-canvas/game/app.js:908
- The same falsy latitude check also disables zoom reloads for valid equatorial destinations. Check whether a destination has been loaded rather than treating latitude zero as absent.
if (!originLat) return;
jhauga
marked this pull request as draft
July 29, 2026 22:17
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 22 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- extensions/flight-map-canvas/package-lock.json: Generated file
Comments suppressed due to low confidence (5)
extensions/flight-map-canvas/game/app.js:268
- Checking only that the key exists is unsafe after
clearAllTiles(): selecting/reloading the same destination can recreate the same key while the old request is still pending. The old callback then writes to its disposed mesh, marks the replacement tile loaded, and leaks the returned texture. Capture the tile record and requireloadedTiles[key]to be that exact record in every primary/fallback callback, disposing textures returned for stale records.
textureLoader.load(url, function (texture) {
if (!loadedTiles[key]) return; // Already unloaded
extensions/flight-map-canvas/extension.mjs:367
- These SSE handlers dispatch updates without updating
init. During startup,HostBridgehas not registered the page command handlers yet, so an action arriving then is dropped; the laterreadyreplay can also overwrite it with the stale opening destination/job. Save each parsed SSE payload intoinitbefore dispatching so the ready replay always carries the latest state.
events.addEventListener('flyTo', function (event) {
try { dispatch({ command: 'flyTo', destination: JSON.parse(event.data).destination }); } catch (e) {}
});
events.addEventListener('jobStatus', function (event) {
try { dispatch({ command: 'jobStatus', job: JSON.parse(event.data).job }); } catch (e) {}
extensions/flight-map-canvas/extension.mjs:180
- The server-side geocoder does not enforce the one-request-per-second limit described above. Concurrent
fly_to/opencalls (and requests from multiple canvas instances) callfetchin parallel, while the browser geocoder has a separate queue, so this can exceed Nominatim's limit and cause the shared client IP to be throttled. Route all Nominatim traffic through one shared, rate-limited queue (ideally via the loopback server).
response = await fetch(`${NOMINATIM}?${params}`, {
headers: { "user-agent": USER_AGENT, accept: "application/json" },
});
extensions/flight-map-canvas/game/destinationInput.js:160
- A search response is not tied to the dialog session or query that started it. If the user cancels, reopens, and starts another search before the first request returns, the first callback can replace the new search with stale results and re-enable the button while the newer request is pending. Add a monotonically increasing request/session token and ignore callbacks whose token is no longer current.
}, function (error, found) {
setSearching(false);
extensions/flight-map-canvas/game/app.js:265
tileYis sent to both providers without checking the valid Web Mercator row range[0, 2^zoom - 1]. Since the public input accepts latitude ±85.0511, opening at either limit immediately schedules roughly half of the load disk with negative or out-of-range rows (and flight can move farther beyond it), producing repeated primary and fallback failures. Filter invalid rows before scheduling requests and constrain flight at the projection boundary.
This issue also appears on line 267 of the same file.
var urlX = wrapTileX(tileX, TILE_ZOOM);
var url = getTileUrl(urlX, tileY, TILE_ZOOM);
aaronpowell
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
A canvas first-person flight-simulator using satellite terrain from
Google Maps. For session breaks while an agent works.
Test:
Prompt
Results
See screenshot below:
Type of Contribution
By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.