Commit Graph
100 Commits
Author SHA1 Message Date
Sameh Khamis 27a986f40f Accept authoritative empty vessel coverage without an outage 2026-10-09 20:50:19 -07:00
Sameh Khamis eacfc1b06a Persist explicit provider toggles through the layer state coordinator 2026-10-09 19:09:30 -07:00
Sameh Khamis 3ba8c6d61b Use a neutral compact switch codec and clarify provider size limits 2026-10-09 18:47:04 -07:00
Sameh Khamis fbe118aab9 Merge branch 'refactor/route-imagery-sources' into fix/street-level-provider-sharing 2026-10-09 18:44:12 -07:00
Sameh Khamis 8d7c47ec39 Merge branch 'feat/optional-catalog-sources' into refactor/route-imagery-sources
# Conflicts:
#	CHANGELOG.md
2026-10-09 18:44:07 -07:00
Sameh Khamis 161a3a796a Keep source availability in the catalog and cover absent military acquisition 2026-10-09 18:43:44 -07:00
Sameh Khamis 7b1b2df764 Preserve custom Street Level provider switches in shared state 2026-10-09 17:53:47 -07:00
Sameh Khamis 3b840ebdf3 Merge branch 'feat/optional-catalog-sources' into refactor/route-imagery-sources
# Conflicts:
#	CHANGELOG.md
#	docs/CURRENT-STATE.md
2026-10-09 17:50:12 -07:00
Sameh Khamis b78ff7a915 Use shared availability for an empty Street Level provider list 2026-10-09 17:49:58 -07:00
Sameh Khamis 0d9bfdf9de Merge branch 'fix/optional-street-level-providers' into feat/optional-catalog-sources 2026-10-09 17:49:41 -07:00
Sameh Khamis 893294c7d4 Assert Street Level expansion timeout and document provider precedence 2026-10-09 17:49:26 -07:00
Sameh Khamis 99988cb348 Separate route and recent imagery acquisition from application assembly 2026-10-09 17:42:00 -07:00
Sameh Khamis 5756ae92a8 Make catalog feed configuration optional and explicit 2026-10-09 17:35:38 -07:00
Sameh Khamis 1ee07468c4 Explain empty imagery configuration in Street Level controls 2026-10-09 17:21:31 -07:00
Sameh Khamis 940b277460 Allow optional Street Level provider composition 2026-10-09 17:18:49 -07:00
Sameh Khamis cb1d008505 docs(state): scope caption metering to API-key voice sessions 2026-10-08 11:20:03 -07:00
Sameh KhamisandClaude Opus 5.5 f5c4f3fda3 fix(qa): restore Google 3D before switching Street View off in gate cleanup
The Street View step's cleanup switched the Street View chip off after the
step had left Google 3D, where the chip is hidden by design. The click then
threw "failed to find element", replacing the step's real result (here, a
Google key refusal) with a selector error. Return to Google 3D first, then
switch the chips and restore the original map.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 11:05:43 -07:00
Sameh Khamis 30cc16052a docs(changelog): credit #621 and #653 for ChatGPT OAuth voice 2026-10-08 11:03:23 -07:00
Sameh Khamis 8979d159bb docs(voice): note the Windows Codex login workaround 2026-10-08 11:03:18 -07:00
Sameh Khamis d32cc71682 docs(security): document the Codex sign-in boundary for OAuth voice
Add the Codex auth.json credential to the secrets table and describe the
loopback-only OAuth routes, the codex login launch and its limits.
2026-10-08 11:03:12 -07:00
Sameh Khamis d587249ce9 fix(setup): stop presenting ChatGPT OAuth as the default voice fallback
Doctor and dev-fresh told every user without an OpenAI key that voice could
use ChatGPT OAuth, whether or not Codex was installed. Say voice is off
until a key is added or a Codex sign-in is selected, and mark that path
experimental.
2026-10-08 11:02:52 -07:00
Sameh Khamis 3fa5bb7f5f fix(voice): start codex login without the server's provider secrets
The login child inherited the whole server environment, including
OPENAI_API_KEY and every other provider credential. Pass only what Codex
needs to find its home, open a browser and reach OpenAI through a proxy.
2026-10-08 11:02:12 -07:00
Sameh Khamis c99653047f fix(voice): count OAuth caption transcriptions instead of pricing them
Voice-card captions from main priced transcription usage into the API-key
dollar meter. In a ChatGPT OAuth session that could trip the $2 warning or
$5 cap while the readout said COST UNKNOWN. Count them with the session's
other OAuth usage instead.
2026-10-08 11:01:43 -07:00
Sameh Khamis fb1596d2f1 Merge main into PR #621 (ChatGPT OAuth for Realtime voice)
Resolve conflicts with the voice-core captions, panel resize and MCP
panel key changes by keeping both sides.
2026-10-08 11:00:54 -07:00
Sameh KhamisandClaude 4f2b304ea3 docs: note tile origin follows tileJsonUrl and credit #935
Co-Authored-By: Claude <[email protected]>
2026-10-08 10:44:56 -07:00
Sameh Khamis 563ca10d26 Merge main into PR #935 2026-10-08 10:44:12 -07:00
Sameh KhamisandClaude Opus 5.5 84f634efb0 fix(street-level): pause Street View details retries after a failure
Maintainer follow-up to #966 review:

- A failed panorama-details lookup now waits DETAILS_RETRY_COOLDOWN_MS
  (5 s) per panorama before a view event can retry it, so dragging the
  view after a failure no longer issues a lookup on every pov change. A
  success clears the pause; one panorama's failure does not delay another.
- SECURITY.md notes that allowing maps.googleapis.com in script-src also
  trusts its JSONP endpoints, an accepted limitation alongside the
  existing 'unsafe-eval' allowance.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 10:38:01 -07:00
Sameh Khamis 64a0200ea8 Merge main after MCP port correction 2026-10-07 15:24:15 -07:00
Sameh Khamis acda360cf0 fix(mcp): serialize shared panel key repair and credit report 2026-10-07 15:12:44 -07:00
Sameh Khamis 7592718415 Merge remote-tracking branch 'origin/main' into integration/mcp-panel-key-pr958 2026-10-07 15:10:44 -07:00
Sameh Khamisandshirunjies8-png 2d3d99864b docs: credit both contributors for MCP port correction
Credit the equivalent contribution in PR #959 alongside PR #934, while preserving the original PR author's commits.

Co-authored-by: shirunjies8-png <[email protected]>
2026-10-07 14:37:10 -07:00
Sameh Khamis 700e54401d Merge remote-tracking branch 'origin/main' into integration/mcp-port-pr934 2026-10-07 14:36:58 -07:00
Sameh Khamis b5cb75bcf9 fix(voice): resolve follow-up review edge cases 2026-10-07 14:21:46 -07:00
Sameh Khamis 1594db9497 Merge main into feat/voice-core and reconcile layer capabilities 2026-10-07 13:14:31 -07:00
Sameh Khamis ae1b6abda1 fix(voice): omit tool result content from debug logs 2026-10-07 12:00:29 -07:00
Sameh Khamis 0b3bed3bfa docs: clarify risk-based community PR review 2026-10-07 11:17:58 -07:00
Sameh Khamis bff921ccb3 fix(flights): start a new grounded aircraft on the floor under its delayed position
The fleet draws a grounded contact at its delayed position lifted onto the floor under it, but a new billboard was created at the delayed position without that lift. A taxiing aircraft whose reported fix sat lower than the ground under its delayed position started on the fix's floor and then rose on the next fleet tick. Creation now applies the same floor the fleet pass does.
2026-10-06 13:42:37 -07:00
Sameh Khamis d9737d94f2 fix(military): start new contacts at their delayed display position
The military fleet also renders behind real time and projects a fresh contact's first fix back to that delayed time, but its billboard was created at the raw fix. A new contact therefore appeared ahead of where the next fleet tick put it and jumped back. The snapshot renderer now receives the layer's motion and creates the billboard at the dead-reckoned delayed position.
2026-10-06 12:01:56 -07:00
Sameh Khamis 7b328232ed fix(flights): start new aircraft at their delayed display position
The fleet renders behind real time, so a newly seen aircraft is displayed at its fix projected back to that delayed time. Its billboard was created at the raw fix instead, so it appeared ahead of where the next fleet tick put it and then jumped back about one render delay of travel before moving forward.
2026-10-06 11:46:34 -07:00
Sameh Khamis f86d1c3296 fix: recover near-view places through the application's place search 2026-10-05 19:27:36 -07:00
Sameh Khamis a2f61d4def feat: load Google 3D with short-lived server tokens
Without a browser key, the app asks its server for a short-lived Google
access token (GET /api/google/tiles-token, answering accessToken and
expiresAt) and loads Photorealistic 3D Tiles directly with it as a
header. A tile refused for an expired token gets a renewed one and is
retried once. A server that does not offer tokens changes nothing: the
app continues through ion or the keyless globe as before.
2026-10-04 10:49:06 -07:00
Sameh Khamis b0483dc546 test: name the vessel provider in the feed-failure QA fixture
The fixture answers /api/vessels without X-Feed-Source, so the source
fell back to the feed's name and the attribution check failed. Send
AISStream as the bundled server does.
2026-10-03 23:20:42 -07:00
Sameh Khamis 60644c5f5d feat: name live feed routes and sources for what they serve
The flight, military and vessel feeds were named after the providers the
bundled server uses (/api/opensky, /api/adsblol/mil, /api/ais-live and
their track routes; createOpenSkySource, createAdsbLolSource,
createAisStreamSource). Any server should be able to answer a feed from
its own provider, so the feeds are now:

  /api/flights   /api/flights/track?icao24=
  /api/military  /api/military/track?hex=
  /api/vessels   /api/vessels/track?mmsi=

with createFlightSource, createMilitarySource and createVesselSource. The
old routes are removed. Each server names its provider in X-Feed-Source
(the bundled server sends OpenSky Network, adsb.lol and AISStream, so its
attribution is unchanged) and the military feed's cache state and age in
X-Feed-Cache and X-Feed-Age-Ms. Sources report the provider the server
names and fall back to the feed's name.
2026-10-03 23:10:32 -07:00
Sameh Khamis e8e49a49e0 feat: ask for vessels by area
The vessel source accepts an optional area and sends it as lat, lon and
radius_km. The vessel layer asks for the area the camera shows (centered
on the middle of the screen, sized by camera height), or every vessel
from high enough up, and asks again when the view moves or zooms by a
quarter of that radius. vessels_in_area names its area too. Servers that
hold every vessel may ignore the area; callers still keep only what is
inside it.
2026-10-03 22:44:45 -07:00
Sameh Khamis a2099358fd chore: classify the tools/panel export
Add the tools-panel boundary group for the new export.
2026-10-03 21:20:04 -07:00
Sameh Khamis ee05e922c0 feat: export the globe panel for MCP servers
MCP servers that compose Core's tools can now serve the globe panel:
@gods-eye-view/core/tools/panel exports createGlobePanelResource,
panelRuntime, GLOBE_PANEL_URI and PANEL_BASE. The local MCP server uses
the same entry point.
2026-10-03 21:17:47 -07:00
Sameh Khamis f752b5eea1 fix: resolve bundled data URLs when used, not at import
The submarine cable source and the infrastructure data URLs built their
asset URLs from import.meta.url while the module loaded. Importing the
tool services therefore failed in runtimes without a usable module URL,
even for tools that never read those files. Build the URLs when they are
read; Vite still rewrites them in browser builds.
2026-10-03 18:47:31 -07:00
Sameh Khamis 80fc8f0e1c chore(release): prepare v0.2.1
Date the changes since v0.2.0 as 0.2.1, move the live CCTV video entry
into the 0.2.0 section where it shipped, and align the package metadata.
2026-10-02 22:19:04 -07:00
Sameh KhamisandClaude Opus 5.5 9c87fabf88 build: ship each bundled data pack once
loadBundledJson's callers passed a literal JSON import as a Node fallback,
which made the production build emit a JavaScript copy of every pack beside
the JSON the browser fetches. The loader now reads file: URLs itself under
Node (through process.getBuiltinModule, synchronously, as promptly as the
cached import it replaces), and the callers pass only the URL. On a Node too
old to provide getBuiltinModule it says that Node 24.14 or newer is needed.
dist/ drops from 54 MB to 42 MB. A test keeps app code from importing a pack
as a module.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 21:08:11 -07:00
Sameh KhamisandClaude Opus 5.5 0646630dec fix(server): let the CSP load the Nepal event's embedded media
The Content-Security-Policy blocked the YouTube player API, the Facebook
video SDK and X's post widget that src/data/bhoteKoshiEmbeddedMedia.js
loads, along with their players and posts in frames. script-src now allows
exactly those three script origins and a new frame-src allows YouTube,
youtube-nocookie, Facebook and X embeds. A test ties the policy to the
frames the media module builds and pins the allowed script origins.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:21:23 -07:00
Sameh KhamisandClaude Opus 5.5 913d45bc07 fix(server): keep cost throttles on for positive fractional limits
A limit such as 0.5 floored to 0 and disabled the throttle, although only an
explicit 0 is meant to. Positive values below 1 now count as 1.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:17:21 -07:00
Sameh KhamisandClaude Opus 5.5 9b4ccbff62 fix(server): gate Google text search against cross-site requests
/api/google/text-search spends the same Google quota as nearby-places but
was not behind the cross-site gate. It now refuses cross-site requests
before calling Google, and a test covers both paid Google routes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:16:39 -07:00
Sameh KhamisandClaude Opus 5.5 e6f1dd70a1 fix(server): apply the Host check before the app's own routes
Vite installs its Host check after the middleware plugins add in
configureServer, so the provider and /api routes answered any Host,
including a DNS-rebinding name. hostCheckPlugin runs first on the dev and
preview servers and applies Vite's rule with the same allowed hosts: IP
addresses, localhost and *.localhost, the configured server host, and the
listed names. A test drives a real Vite server with an unlisted Host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:15:54 -07:00
Sameh KhamisandClaude Opus 5.5 81513f9aae fix(mcp): refuse panel requests to routes reached through a dot suffix
The server routes a mounted path when a dot follows it, so /mcp.json reached
the MCP endpoint while panel_request refused only /mcp and /mcp/...; the same
held for the provider-settings, credential and model routes. The refusals now
match a dot after the route as well. A regression test drives panel_request
against a real Vite server.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:10:47 -07:00
Sameh KhamisandClaude Opus 5.5 6cdd6c8af9 refactor(server): share one proxy-header check across the local gates
localRequestGate.mjs owns the reverse-proxy header list and hasProxySignals;
Provider Settings, the cross-site gate and /mcp all use it instead of two
copies of the same nine names. The changelog credits the cross-site gate.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 20:02:48 -07:00
bbf4976f5e fix(server): keep debug-log timestamps server-owned and send nosniff
The voice debug log writes the server's timestamp after the client's record,
so a record can no longer replace loggedAt. The dev and preview servers also
send X-Content-Type-Options: nosniff with their shared browser headers.

From the findings in #710.

Co-authored-by: Sunil <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 20:00:11 -07:00
Sameh KhamisandClaude Opus 5.5 42faed3aea docs: describe the MCP server and panel in the security guide
SECURITY.md gains a section on what /mcp accepts, the panel's request key,
the browser keys the panel build carries and embed-mode framing. TOOLS.md
now describes what panel_request may request, and the changelog records
the recent MCP and embed changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 19:47:37 -07:00
Sameh KhamisandClaude Opus 5.5 857767842f fix(mcp): bound panel requests, request bodies and cancelled calls
Panels on one MCP server share six requests in flight; further requests
wait their turn (up to 256 waiting) instead of failing, and a waiting
request leaves the queue when its caller cancels. Held responses belong to
their own MCP server rather than to the process. /mcp request bodies must
arrive within 30 seconds. Over stdio, a client's notifications/cancelled
aborts the named request, which then gets no response.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 19:47:37 -07:00
Sameh KhamisandClaude Opus 5.5 fec93aa817 fix(mcp): accept only direct local requests at /mcp
The /mcp route now applies the same proxy and sharing checks as Provider
Settings: requests carrying forwarding headers, or arriving while launcher
sharing is on, are refused. The Host must name the port the request reached
and a browser Origin must match that host exactly. The proxy and sharing
checks move into shared helpers in keySetupCore; Provider Settings behaves
as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 19:47:37 -07:00
Sameh KhamisandClaude Opus 5.5 f7d3db5875 fix(embed): make embed-mode framing opt-in
Embed-mode documents now keep the server's framing protection unless
GEV_EMBED_FRAME_ANCESTORS names the pages that may frame them (or * for any
page). The MCP Apps panel loads the app into its own page and needs no
framing. View answers are posted to the origin that sent the view rather
than to any origin.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 19:47:37 -07:00
Sameh KhamisandClaude Opus 5.5 3318390e3f fix(mcp): require the panel key for panel requests
panel_request now requires a key that each MCP server generates and places
in its panel page, which keeps the tool from clients that list it to the
model without loading the panel. The key is not access control: any MCP
client can read the panel page. Routes the panel never loads (provider
settings, credential and model endpoints, the MCP endpoint and development
server internals) are refused to every caller, regardless of letter case or
encoding.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-02 19:47:37 -07:00
Sameh Khamis b86239aa6d chore(release): prepare v0.2.0
Group the changes since v0.1.1 under a dated 0.2.0 section and align the
package metadata.
2026-10-02 18:47:29 -07:00
Sameh Khamis a55d260551 docs: drop the server check from the MCP setup 2026-10-02 18:29:42 -07:00
Sameh Khamis bcbc350354 docs: add a one-page MCP setup for Claude and Codex
Steps people and coding agents can follow to run the app, add the MCP
server to Claude Code, Claude Desktop, the Codex CLI and the Codex and
ChatGPT desktop apps, and check it works, linked from the README and the
tools guide.
2026-10-02 18:29:42 -07:00
Sameh Khamis b69d34bad2 Frame a view that only follows an aircraft where the aircraft is
Asked for an aircraft's cockpit view, assistants passed only the follow,
which failed for want of an area or camera, so every such request took
a second call. show_in_gods_eye_view now looks the aircraft up and frames
the view on it, and says so when the aircraft is not reported.
2026-10-02 18:29:42 -07:00
Sameh Khamis ae00f009e6 Log why a tool call failed in the stdio server's log
A failed call's reason went only to the client, so client logs showed a
failure without its cause.
2026-10-02 18:29:42 -07:00
Sameh Khamis e82ab7440d Run the worker prelude ahead of Cesium's own workers script
Cesium's script sets CESIUM_WORKERS itself when it loads, so the panel's
combined workers script was never used, and neither was the embedded
terrain-heights file: the worker still requested it from the panel
page's site. The panel build now writes only the prelude, and the panel
puts it ahead of whatever Cesium assigns to CESIUM_WORKERS. The separate
esbuild bundle of Cesium's workers is gone.
2026-10-02 18:29:42 -07:00
Sameh Khamis 9e5ef78f91 Embed the files Cesium's workers load in the panel's workers script
The ground-polyline worker loads approximateTerrainHeights.json itself,
and a worker's requests go to the panel page's own site, where they
failed with 404 and stopped rendering once ground-clamped lines such as
military installations appeared. The panel build now embeds that file in
the workers script, which answers the worker's request from memory.
2026-10-02 18:29:42 -07:00
Sameh Khamis d4311a9d54 Let a view show an aircraft's cockpit view
A view's follow may ask for cockpit view, which the app enters after it
follows the aircraft; links cannot carry it and open the app following.
Applying a view no longer flies the camera when the followed entity is
already there, since the flight ended the follow; it flies only while
waiting for the entity. The panel applies its first view again only
when it asks for cockpit view.
2026-10-02 18:29:42 -07:00
Sameh Khamis 89a448ee83 Do not apply a panel's first view twice
The panel starts the app from the first view's link, which the app
restores, following included. Sending the same view again once the app
was ready flew the camera to it, which ended the follow and left cockpit
view. The panel now sends only views that arrive while the app loads.
2026-10-02 18:29:42 -07:00
Sameh Khamis 9bc031c753 docs: describe God's Eye View in conversations in the changelog and current state 2026-10-02 18:29:42 -07:00
Sameh Khamis abca609708 Keep panel requests on the app's server and bounded
panel_request resolved paths with a check for a leading //, but URL
parsing also reads /\host as another host, so it could request other
servers. It now resolves the path against the app's address, refuses
any other origin, matches refused routes decoded as well, and does not
follow redirects. Responses are capped at 64 MiB while reading, with a
deadline; held responses make room on arrival and expire by time only,
so a response being read keeps its parts.

The panel keeps converted images only for its build files, so live
camera frames no longer accumulate, and failed build loads are retried.
The dev server answers a malformed /panel/ path with 400 instead of
crashing.
2026-10-02 18:29:42 -07:00
Sameh Khamis efdee8d255 Clean up the panel after host testing
Drop the render restarts added while chasing the black overlays; keep
the full render-error report and stop the timer after an error, as
Cesium does. Correct comments the investigation outran, share the
panel_request name, and document the host differences the panel works
around.
2026-10-02 18:29:42 -07:00
Sameh Khamis d0da4b0722 Keep the panel's 2D canvases in memory
In Claude, the app's 2D overlay canvases covered the globe in black
while the host treated the panel as off screen, and the globe showed
once they were hidden. The panel now asks for 2D canvases backed by
memory rather than the GPU.
2026-10-02 18:29:42 -07:00
Sameh Khamis dbbdef0f78 Offer fullscreen in the panel, and hold images in inserted HTML
Where the host offers fullscreen, an Expand button asks for it; the page
fills the room it is given. Images in markup the app inserts as HTML
text now wait for their files instead of requesting the panel host's
site, which ended the mic.svg and Cesium credit 404s.
2026-10-02 18:29:42 -07:00
Sameh Khamis 5ad0dd0004 Report a panel's render errors in full and restart drawing
Cesium stops drawing after a render error and prints worker failures as
[object Object]. An inline panel now logs the error's details and starts
drawing again, up to three times.
2026-10-02 18:29:42 -07:00
Sameh Khamis 47742f335d Keep an inline panel drawing when its host reports it hidden
Claude reports a panel on screen as hidden, which stopped the app's
render loop and the browser's animation frames, so no map was drawn. An
inline panel no longer suspends rendering when hidden, and draws from a
timer while animation frames stop arriving.
2026-10-02 18:29:42 -07:00
Sameh Khamis 62468c547f Fit the panel to Codex's and Claude's panel rules
Images and stylesheet files load as data: URLs, which hosts allow where
some refuse blob: images; the scene-asset source gets an https app
address the panel serves, since Codex pages use their own scheme; and a
panel whose 3D context the browser takes back says so.
2026-10-02 18:29:42 -07:00
Sameh Khamis 996b95eb45 Load the God's Eye View panel through the MCP server
Hosts serve panels from their own sites and may refuse other addresses;
Codex refuses any address on the user's machine. The panel now never
requests the app's server: it loads the app's panel build and data
through panel_request, a tool only the panel may call, which requests
the path from the app's server. One path in every host; only map
providers load directly.

npm run build:panel writes the panel build to dist/panel, served at
/panel/: one app script, one stylesheet, Cesium's script, and Cesium's
workers as one script Cesium runs from memory. Tools may now be marked
app-only. The panel CORS rules are gone.
2026-10-02 18:29:42 -07:00
Sameh Khamis b11d54d8b8 Support panel hosts that serve the page from their own scheme
Codex serves panels from codex-sandbox:// pages, where origins are
opaque: the panel recognizes the app's own addresses by scheme and host,
the vessels feed resolves against the document address, and the dev
server answers Codex's sandbox origins with CORS.
2026-10-02 15:21:37 -07:00
Sameh Khamis 64c1b1951f Answer panel origins only through the CORS plugin 2026-10-02 15:21:37 -07:00
Sameh Khamis 282efac862 Start the panel's app at the first view instead of the default place 2026-10-02 15:21:37 -07:00
Sameh Khamis 5b555d7708 Load images the panel redirects to the app's server with CORS
The app treats those images as its own site's and loads them without
CORS, so once they come from the app's server WebGL refuses them and
Cesium stops rendering.
2026-10-02 15:21:37 -07:00
Sameh Khamis 06460020d0 Send the panel's app requests to the app's server without <base>
Claude refuses <base> in panels, so relative addresses reached the
host's site: styles, Cesium assets and API calls all failed. The panel
now points fetch, XHR, beacons, images, media, links, workers and added
style url()s at the app's server, and declares its policy under OpenAI's
widget key as well.
2026-10-02 15:21:37 -07:00
Sameh Khamis d9ecd126c8 Let the app run under a panel page's document base
A panel page loads the app with <base> pointing at the app's server, so
addresses the app builds resolve against the document base instead of
the page location, and hash updates stay on the page's own address.
The dev server answers panel origins with CORS on the API routes too.
2026-10-02 15:21:37 -07:00
Sameh Khamis 63341b947e Run God's Eye View inside the MCP Apps panel instead of framing it
Hosts such as Claude do not let a panel frame other sites, so the panel
now loads the app's page, styles and scripts into itself in inline embed
mode, and declares the app and map providers as resource and connect
domains. The dev server answers panel origins with CORS.
2026-10-02 15:21:37 -07:00
Sameh Khamis cb04fd5b19 feat: say in the panel what a host's security policy blocked
When a host's content security policy refuses part of the panel, such as
its frame, the panel now names the blocked directive and address instead of
waiting until its load timeout.
2026-10-02 15:21:37 -07:00
Sameh Khamis d368df533d fix: complete the MCP Apps handshake the way hosts validate it
The panel sent clientInfo and capabilities in ui/initialize, where the MCP
Apps schema requires appInfo, so hosts such as Claude rejected the handshake
and never showed the panel. It now sends exactly appCapabilities, appInfo and
protocolVersion, sends initialized without parameters, says so when a host
rejects it, and offers the link when God's Eye View does not load within 20
seconds. Checked against the MCP Apps SDK's own host bridge.
2026-10-02 15:21:37 -07:00
Sameh Khamis ba751d9433 fix: also name a tool's UI resource with the flat ui/resourceUri key
Some MCP Apps hosts read the earlier flat _meta key; the MCP Apps SDK sends
it alongside _meta.ui.resourceUri, and so does the adapter now.
2026-10-02 15:21:37 -07:00
Sameh Khamis 5775eb9053 feat: log local MCP requests to stderr by method
The stdio server writes each request's method, and the tool or resource it
names, to stderr, which clients such as Claude Desktop copy into their logs.
Arguments and results are never logged.
2026-10-02 15:21:36 -07:00
Sameh Khamis 47ef168815 refactor: name the view tool show_in_gods_eye_view
The tool and its panel now say "Show in God's Eye View" rather than
"show on the globe", in tool names, descriptions, server instructions and
docs.
2026-10-02 15:21:36 -07:00
Sameh Khamis 216a75ac71 feat: show views as the live globe in MCP Apps clients
show_on_globe replaces open_in_gods_eye_view and names an MCP Apps view, a
ui:// panel that loads the app in embed mode and posts each later view to it,
so the globe in the conversation changes without reloading. It also takes a
view another answer returned. Tools can declare a UI resource, and the MCP
adapter serves resources/list and resources/read and lists each tool's
resource in _meta.ui.resourceUri.
2026-10-02 15:21:36 -07:00
Sameh Khamis 60c40865e9 feat: add an embed mode that shows only the globe
?embed=1 shows the globe alone: clean view with the HUD, panels, welcome and
setup prompts hidden, and provider attribution kept. The page that frames it
sends views with postMessage; the app applies each through its own actions
and reports every step. Annotations in any link are drawn once it restores.
Only embed-mode documents may be framed; every other page keeps
X-Frame-Options DENY and frame-ancestors 'none', and
GEV_EMBED_FRAME_ANCESTORS can restrict who frames them.
2026-10-02 15:21:36 -07:00
Sameh Khamis f68aa988ec feat: carry annotations in views and aim tilted views at the area
A view can carry the marks the app's annotate_map action draws, and links
carry them in the an parameter, bounded in count and size. A tilted view of
an area now places the camera behind its center so the area stays in the
middle of the frame.
2026-10-02 15:21:36 -07:00
Sameh Khamis af8856cedf feat: lead the MCP tool list with what the globe shows
MCP no longer lists place search, routing, plain weather and wind, the
regional brief, the HUD caption, radio, bike share and transit. Assistants
already cover these or they add little without the globe; voice keeps them,
and tools that combine others still reach them.
2026-10-02 15:21:36 -07:00
Sameh Khamis d6473b6049 feat: return the view that shows each answer
Tool answers with something to show now include data.view: the view with
the matching layers on, the area framed from above or a single aircraft or
satellite followed, and the link that opens it. Area framing moves to
src/tools/views.js so links and answers frame alike.
2026-10-02 15:21:36 -07:00
Sameh Khamis 96a8a9addb feat: describe what the app shows as a view
A view is a camera, data layers, visual style, map imagery and an aircraft,
military aircraft or satellite to follow, written in the share-link format
the app already restores. gods-eye-view/view builds, encodes and decodes one,
and share links take their style names from it. open_in_gods_eye_view now
builds its link from a full view: an area or camera, layers, style, map and
something to follow.
2026-10-02 15:21:36 -07:00
Sameh Khamis de1e0836b3 fix: send "vessels" to the ships layer in voice
Voice hears audio directly, and "vessels" is easily heard as "visuals",
which the instructions route to visual styles, so asking for vessels turned
on other layers or a CRT style. The instructions now say a vessels request
without a style name means the ships layer, and a style needs its name.
2026-10-02 15:21:36 -07:00
Sameh Khamis 759d05db4e fix: name only tools voice offers in its instructions
The voice instructions recommended aircraft_in_area, vessels_in_area and
get_earthquakes, which voice no longer offers, and the docs said voice gets
nearly every query. The instructions now name tools voice has and send
aircraft, ship and hazard questions to analyst_query; a test keeps the
instructions to tools the voice session lists.
2026-10-02 15:21:36 -07:00
Sameh Khamis 33445aec73 fix: keep each aircraft feed's freshness in search answers
find_aircraft merged the records of the feeds that answered and dropped their
freshness, so a stale OpenSky snapshot read as a current "not reported".
Answers now list each feed with its freshness and coverage and say which
feed's data may be stale.
2026-10-02 15:21:36 -07:00