Commit Graph
3613 Commits
Author SHA1 Message Date
Sameh Khamis 2ba751ace8 feat: read the transit feed catalog through the transit source
Add getFeeds() to the transit source. It reads the public catalog route
the server already serves, so code outside the layer can find feeds
near a location without loading the layer.
2026-10-01 12:19:19 -07:00
Sameh Khamis eb12303f46 refactor: move GBFS station parsing into a portable source module
The bike-share layer parsed station documents inside its model factory.
Move the parsers unchanged to src/sources/gbfsStations.js and have the
model import them, so code outside the layer can read GBFS stations
without constructing the layer.
2026-10-01 12:18:48 -07:00
Sameh Khamis e680a59bf5 feat: add place search and routing tools
Add search_places and places_nearby over the app's Google Places routes,
and plan_route over its OpenStreetMap routing. The place search service
reports when no search key is configured, so an unconfigured server is
not mistaken for an empty result, and rate limits become retry_later.
Route endpoints accept a place name or coordinates.
2026-10-01 12:16:01 -07:00
Sameh Khamis 85fee59da1 feat: add public camera and radio tools
Add find_cctv_cameras, get_cctv_snapshot and find_radio_stations. A
snapshot returns the camera's current frame as image content with its
credit. Tool results may now carry base64 images, which the MCP adapter
sends as image content.
2026-10-01 12:11:00 -07:00
Sameh Khamis d65402eae3 feat: read current camera frames through the CCTV source
Add getFrame(camera) to the CCTV source. It reads one frame through the
registered frame endpoint the layer already uses and returns its content
type and bytes, so code outside the layer can show a camera's view.
2026-10-01 12:11:00 -07:00
Sameh Khamis 22c3fe40b0 feat: add aviation and satellite tools
Add aircraft_in_area, find_aircraft, get_aircraft_track and
get_aircraft_info over the live aircraft sources, with an optional
military feed, and next_satellite_pass and satellites_overhead over the
satellite catalog and the existing pass predictor.

Source failures from the live contract now become tool errors with the
matching code, so a rate limit reaches clients as retry_later with a
wait time. Tool schemas may use pattern.
2026-10-01 12:05:50 -07:00
Sameh Khamis 9895942633 refactor: move TLE text parsing into a portable source module
The satellites layer parsed catalog text inside its Cesium-backed orbit
owner. Move the parser unchanged to src/sources/tle.js, add a catalog
number helper, and have the layer delegate to it so code outside the
layer can read TLE text without loading rendering.
2026-10-01 12:05:41 -07:00
Sameh Khamis c3dfa8e853 feat: add a tool catalog and local MCP server
Define tools that answer questions from the app's data once, independent
of the surface that exposes them. A tool declares its arguments and the
services it reads; applications compose tools with their own services and
optional call interceptors. Queries reuse the layers' portable source
factories, so they run wherever an application routes /api requests.

The first queries are get_earthquakes, get_active_fires and
get_recent_launches, with a shared area argument (place name, bounding
box, or point and radius) and capped lists.

gods-eye-view/tools/mcp adapts a catalog to the Model Context Protocol
with a small JSON-RPC handler and a stateless HTTP transport, adding no
dependencies. npm run mcp serves Core's tools over stdio to local clients
such as Claude Code, reading from a running app. Both exports are
portable and checked by check:boundaries; the app does not import them.
2026-10-01 11:51:59 -07:00
Manjunath 1dbc8a4452 fix(ui): preserve Cyber and Cockpit visual state 2026-10-01 17:00:10 +05:30
Meir Michanie 41378656c6 docs(i18n): translator's guide for the en-only foundation, current-state and changelog
docs/TRANSLATORS.md is rewritten for the foundation state: English
shipped, and the locale-addition recipe front and center — the
one-PR-per-locale procedure (catalogs, registration, CATALOG_LOCALES,
pair behavior, parity gates). CURRENT-STATE.md documents the subsystem
(file map, resolution order, selector, gates, deferrals) and the
CHANGELOG records the foundation.
2026-10-01 12:41:20 +02:00
Meir Michanie 284c4d4601 feat(i18n): presentation extraction — t() call sites, data-i18n templates, locale selector
Route every application-owned presentation string through the i18n
core: t() call sites across the app/layers/ui/data/voice surfaces,
data-i18n* attributes in the src/ui/templates/*.html markup (applied at
boot by applyDocumentTranslations from src/standalone/application.js),
and the dock locale selector (runtime-rendered from the offered pair —
a single EN button while only English ships).

Rebased onto current main, where the extraction follows the module
splits: the shell wiring now lands in the owner modules
(panelChrome, visualSettings, locationNavigation, shareRestoration,
shellFeedback, applicationShell) and the voice status corpus in the
realtime* modules; scene status lives in director.js +
playbackAdapter.js.

Modules shared with the node runtime (loadingFeedback,
installationFeedback, regionalModel, keySetupCore, vessels ingestion)
stay environment-neutral English and localize at their browser render
sites (chip maps in shellFeedback/installations controls, the weather
table in cockpitBriefing, keySetupRequirementEnvVars compositions), so
the package-boundary graph stays clean; the browser boundary groups
now own the i18n modules they reach (scripts/package-boundaries.json).
2026-10-01 12:41:20 +02:00
bassem chagra 03929f1a00 docs(cctv): refresh the CCTV Camera Database size in the model-specs module
The dataset has grown from 12,000+ to 28,000+ camera models (v2.26.0, 75%
with a field of view). The 17 vendored records are unchanged in v2.26.0.
2026-10-01 12:34:07 +02:00
Meir Michanie bde1e430ef feat(i18n): locale core + English catalogs + parity gates
Add the i18n foundation: src/i18n/locale.js (locale resolution with a
configurable GEV_DEFAULT_LOCALE / GEV_SECONDARY_LOCALE pair, guarded
preference storage, one-shot ?lang= override, <html lang>/<html dir>
metadata) and src/i18n/index.js (catalog registry, t(), Intl formatters,
applyDocumentTranslations, persistLocaleAndReload).

English is the only shipped locale in this PR: the four en catalogs
(shell/cockpit/layers/setup) are the reference and the always-shipped
fallback, the built-in pair degenerates to en-only, and English output
is byte-identical to the strings these replace.

Parity gates land with the core (catalog key/placeholder/plural-shape
parity, markup coverage of every data-i18n* attribute, repair-pass
anchors pinning en byte-identity); additional locales ship as stacked
follow-up PRs through the recipe in docs/TRANSLATORS.md.

Rebased onto current main: the client defines live in build/vite.js /
server/standalone/vite.config.js as before.
2026-10-01 12:26:30 +02:00
bassem chagra bfbaa88976 Merge remote-tracking branch 'origin/main' into feat/cctv-model-spec-enrichment
# Conflicts:
#	CHANGELOG.md
2026-10-01 12:24:42 +02:00
bassem chagra 0cfb795845 Merge remote-tracking branch 'origin/main' into feat/wsdot-camera-pack
# Conflicts:
#	CHANGELOG.md
#	docs/CURRENT-STATE.md
2026-10-01 12:23:41 +02:00
bassem chagra 031df60014 Merge remote-tracking branch 'origin/main' into feat/king-county-camera-pack
# Conflicts:
#	CHANGELOG.md
#	docs/CURRENT-STATE.md
2026-10-01 12:20:32 +02:00
Kevin Rajan 2b7f832f45 chore: remove one-shot downstream format fixer 2026-10-01 00:52:50 -05:00
Kevin Rajan a194da21dd chore: add one-shot downstream format fixer 2026-10-01 00:52:08 -05:00
Kevin Rajan abea3f2feb chore: remove one-shot branch formatter 2026-09-30 20:59:48 -05:00
github-actions[bot] 914df05346 style: apply adopted formatting 2026-10-01 01:59:00 +00:00
Kevin Rajan cbd3b13afb chore: add one-shot branch formatter 2026-09-30 20:58:20 -05:00
Kevin Rajan 8acb526d1f fix: include World Packet feed-state dependencies 2026-09-30 20:57:17 -05:00
Kevin Rajan 3c53d63def fix: declare World Packet in application boundary 2026-09-30 20:55:09 -05:00
Kevin Rajan 6a6703e0c6 chore: remove one-shot branch formatter 2026-09-30 20:52:54 -05:00
github-actions[bot] 58b7d2d95e style: apply adopted formatting 2026-10-01 01:52:28 +00:00
Kevin Rajan 05b13e9a78 chore: add one-shot branch formatter 2026-09-30 20:51:48 -05:00
Manjunath e03bf008f3 fix(ui): harden Cyber panel layout and preset restoration 2026-10-01 01:50:31 +05:30
Wilmer AlzateandClaude Opus 5.5 367827e742 perf(vessels): let the scene idle with AIS vessels enabled
Vessels move only when a poll lands, yet enabling the layer held the
continuous render loop for its lifetime, so a parked vessels-only scene
rendered every frame. The layer now:

- requests a frame for every forced visibility pass (new data, selection);
- leaves one trailing frame when the camera moved inside the 800 ms
  visibility cadence, so the view the camera stopped on is evaluated. It is
  keyed to camera motion alone: the pass's own label publication requests a
  frame, and scheduling on that looped at ~1.2 Hz;
- holds 'ais-vessels' only while focus emphasis is animating.

The 80 ms focus pass, which runs while anything is tracked, also skips hidden
sprites whose focus state is at rest (new spriteFocusAtRest) and whose alpha
is already 1: advancing them changes nothing, and with a 12k worldwide feed
they are most of the fleet.

Measured: a parked vessels-only scene (headless SwiftShader) went from
continuous mode and 28 frames in 5 s to idle and 0; horizon visibility had no
mismatches after the camera moved and settled. The focus pass over 12,000
vessels (11,353 hidden) went from ~4.0 ms to ~1.2 ms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 13:01:45 -05:00
Wilmer AlzateandClaude Opus 5.5 81f49406b8 perf(flights): skip dead-reckoning contacts that stay behind the horizon
The fleet tick dead-reckoned, floored and distance-tested every contact on
every ~80 ms tick, then hid the ones behind the horizon. The worldwide feed
carries ~13k contacts; zoomed in, well under 1% are on screen, so nearly all
of that work produced a hidden billboard.

A contact that is already hidden and still behind the horizon at its last
position now re-reckons only on its turn in a staggered one-in-12-ticks
rotation (about once a second, HIDDEN_CONTACT_DR_TICKS). Anything that
position puts in view, and any contact with a fleet model, takes the full
pass immediately, so on-screen behaviour is unchanged. Hidden-inclusive
proximity queries (getNearby includeHidden, getAllPositions) read positions
at most about a second old, well inside the 30 s poll's uncertainty.

Measured in Chrome on a Radeon 780M, ~12.9k contacts, 56 on screen over
Colombia at 4 km, same view before and after:
  fleet tick   7.66 -> 2.03 ms/frame, longest tick 50.9 -> ~16 ms
  frame        20.6 -> 14.0 ms, 42.9 -> 57.8 FPS
Teleporting the camera to Madrid showed 975 contacts within 100 ms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 12:31:59 -05:00
Niccolò Saggese 5083a74413 Merge remote-tracking branch 'upstream/main' into fix/363-geocode-proxy
# Conflicts:
#	CHANGELOG.md
2026-09-29 19:16:15 +02:00
Said Turksever c4514784fc Merge branch 'main' into pr/mapillary-layer 2026-09-29 15:44:25 +01:00
ulihhhh 3bae92fce7 Merge upstream/main into feature/catalonia-cctv-cameras
# Conflicts:
#	docs/CURRENT-STATE.md
2026-09-29 10:08:59 +02:00
Kevin Rajan c55d4d7c25 build: register World Packet package boundary 2026-09-29 03:02:14 -05:00
Kevin Rajan 6439575d15 feat(agent): export World Packet boundary 2026-09-29 03:02:11 -05:00
Kevin Rajan 3c163d09a1 refactor(voice): delegate world state to World Packet builder 2026-09-29 03:02:08 -05:00
Kevin Rajan 5c044a3d8d test(agent): prove World Packet parity and fingerprint semantics 2026-09-29 03:02:05 -05:00
Kevin Rajan 4fc813e175 feat(agent): extract model-free World Packet boundary 2026-09-29 03:02:02 -05:00
Kevin Rajan 28f3243090 feat(cyclones): publish explicit selection to shared context 2026-09-29 00:20:16 -05:00
daikaginza e7dd71e9bc fix(server): read the whole q value, not a numeric prefix
Number.parseFloat accepts any valid numeric prefix, so `gzip;q=1oops` read as 1
and the out-of-range `gzip;q=2` was accepted — both contradicting the comment
two lines above, which promises that a quality this cannot read confidently
fails closed. Matching the qvalue grammar of RFC 9110 section 12.4.2 makes the
code do what it already claimed to do.

Thanks to kvnloo for catching it on review.
2026-09-29 11:13:36 +07:00
daikaginza 47b13ab18e docs(changelog): note OpenSky snapshot compression (#795) 2026-09-29 10:58:18 +07:00
daikaginza daed0be99a feat(server): compress the cached OpenSky snapshot for clients that accept gzip
The ~860 KB snapshot is held for an adaptive 9-300 s TTL and was served as
identity bytes to every request; no response in server/ set Content-Encoding or
Vary. Gzip it once per refresh beside the cached body, off the event loop, and
return the body and the header that names it together so the two can never
disagree. Live against an anonymous snapshot: 874,002 B to 258,012 B, 3.39x,
decompressing byte-identical to the uncompressed response.
2026-09-29 10:57:45 +07:00
daikaginza 2e5dfce1af fix(server): declare Allow: GET on the new 405 responses
RFC 9110 section 15.5.6 requires a 405 to name the methods it accepts, and
/api/radio/stations already does this in-tree. Thanks to kvnloo for catching it
on review. The same gap on the pre-existing handlers is tracked in #809 and is
deliberately left alone here.
2026-09-29 10:56:20 +07:00
daikaginza fb6b4e34f0 docs: changelog entry for the read-only proxy method contract (#794) 2026-09-29 10:52:57 +07:00
daikaginza b09db55149 fix(server): declare the method contract on the three read-only query proxies
/api/opensky, /api/adsblol/mil and /api/route answered any verb with the same
body while ignoring the request entirely. Measured against a running server
before the change: POST /api/opensky returned 200 with 833,759 bytes of live
state vectors, POST /api/adsblol/mil returned 47,372 bytes. Their siblings do
not: /api/geocode, /api/weather and /api/transit answer 405, and /api/overpass
is deliberately POST-only.

These three are read-only query proxies, so they now answer 405 to anything but
GET, using the wording and shape /api/geocode already uses. The refusal comes
first, before rate limiting and before any upstream call, which the tests
assert by stubbing fetch to throw.

Scope, stated plainly: this is a consistency and intent fix. No rate limiter
was being bypassed — /api/route already limits every request regardless of
verb, and the two aircraft routes have no limiter at all, only 9s and 12s
server-side caches that bound upstream cost for any method.

One existing fixture in src/search/geospatial.test.mjs built a request without
a method, which a real Node request always has; it now sets GET.

Verified on a running server after the change: GET still 200 on all three,
POST 405 on all three, /api/overpass and the other proxies unchanged.
Suite goes from 5090 to 5092 tests, 0 failures.
2026-09-29 10:52:26 +07:00
Bilawal Sidhu 9559e7a282 feat(outlines): voice outlines without Overpass — bundled US places and neighborhoods, guarded Nominatim, OpenFreeMap streets and buildings 2026-09-28 22:49:23 -05:00
dajiaohuang b681d094ca docs: correct ADSBDB cache persistence note 2026-09-29 10:43:30 +08:00
Bilawal Sidhu a19897ad15 feat(voice): voice core — honest layer reach, spoken summary with on-screen card, narration, point-and-ask
- Voice layer manifest (src/voice/layerManifest.js) generates the layer enums,
  aliases and analyst field hints; a test fails when a catalog layer has no entry.
- analyst_query validates fields, operators, units, values and scopes, counts up
  to 250,000 loaded records per layer, reports complete/partial/unanswered, tells
  LAYER_OFF / NOT_READY / FEED_UNAVAILABLE apart from zero, refuses mismatched
  follow-ups and never lets a superseded query replace follow-up memory. Seven
  more layers expose analyst records.
- Tool results carry a code-built say line and a display card; the voice card in
  the mic control shows captions, plan steps and the result
  (src/voice/resultDisplay.js is the one adapter). Slow tools narrate their
  current step out of band; holding Space while the assistant talks cuts it off.
  Turn spans go to the debug log; caption transcription is metered; the log
  omits what was said unless GEV_VOICE_LOG_CONTENT=1.
- Point and ask: the Space-down pointer snapshot resolves "this", "that one" and
  "around here" through 'pointer' targets, and "the second one" through
  referent:n from the last numbered list.
- Prompt states each policy once (instructions + tools 48.5k -> 46.7k chars).
- Voice benchmark harness (scripts/qa-voice-bench.mjs, scripts/voice-bench/)
  shares its phrase table and grading with scripts/qa-voice-routing.mjs.
2026-09-28 21:19:23 -05:00
Kevin Rajan cacbbc972b chore: remove temporary formatter diagnostics 2026-09-28 20:57:48 -05:00
Kevin Rajan 989e740d6e style(voice): format viewport policy tests 2026-09-28 20:57:43 -05:00
Kevin Rajan 5195012c7f debug(format): print viewport policy canonical output 2026-09-28 20:55:51 -05:00