Repository navigation
Releases
v0.2.10
Eye Of Hermes v0.2.10
Audit follow-up after the v0.2.9 catalog-review fixes (mojomast/EOH#29, #30, #31). Still exactly 11 composable tools. The v0.2.9 prompt-trust and confirm fixes are unchanged.
Changed
- Security and correctness (#29): cap live-relay and HUD-bridge request bodies and reject invalid lengths; route untrusted and keyed HTTP through the public-address fetch helper with connection pinning and per-hop redirect checks. Private-LAN Overpass, Nominatim, Valhalla, OSRM, and Wayback URLs are refused; public HTTPS and explicit loopback still work. Scrub secrets from tool errors, refuse credential-like import paths, lock the MCP pending map, and tighten HUD token file mode, child environments, and outbound header values.
- Capabilities (#30): add
godseye_queryop=sdr_receiversto list nearest public SDR receivers (filter by platform, band, or frequency; does not start audio). Tighten tool-errorfixtext, document shipped extension ops, and drop the retired "key install" mention from the admin schema lead. - Tests, CI and install docs (#31): GitHub Actions CI for pytest, Node unit tests,
hermes plugins validateagainst Hermes v0.23.0, andscripts/secret_scan.py.
Notes
- Requires mojomast/gods-eye-view
mainat or after b361a25 (merge of pull request #5, public SDR receiver layer). Without that app checkout, the layer is not available on the globe. - Plugin id remains
godseye; install via Hermes plugins / catalog when the pin lands.
v0.2.9
Eye Of Hermes v0.2.9
Catalog review follow-up for NousResearch/hermes-agent#149691 (mojomast/EOH#32). Still exactly 11 composable tools.
Changed
- Watch-alert titles are treated as quoted third-party data: newlines and control characters are stripped, titles are length-capped, and they are shown as
title="…". The system prompt no longer tells the model to trust[EOH watch alert]lines. This applies on bothpre_llm_callanddeliver=inject. godseye_adminapp_start,app_stop,app_restartandrebuildrequireconfirm=true, and those ops are refused insidebatch. Pane Start/Stop buttons are unchanged.ui/open-linkandhermes-gev:askonly act after a click on an Open/Copy bar in the pane.- Runtime config re-posting stops once the app acknowledges
gev:config-applied.
Notes
- Requires mojomast/gods-eye-view
mainat or after b361a25 (merge of pull request #5, public SDR receiver layer). Without that app checkout, the layer is not available on the globe. - Plugin id remains
godseye; install via Hermes plugins / catalog when the pin lands.
v0.2.8
Eye Of Hermes v0.2.8
Public SDR receivers layer (docs + tool enum on the EOH side). Still exactly 11 composable tools.
Added
sdr-receiversin the live layer tools /tools_snapshot, with analyst-skill docs for the PUBLIC SDR card, floating waterfall, audio+waterfall filter, pin-click play gesture, deep links, and native-audio limits.
Notes
- Requires mojomast/gods-eye-view
mainat or after b361a25 (merge of pull request #5, public SDR receiver layer). Without that app checkout, the layer is not available on the globe. - Plugin id remains
godseye; install via Hermes plugins / catalog when the pin lands.
v0.2.6
Eye Of Hermes v0.2.6
Hermes-declared street-level secrets. Still exactly 11 composable tools.
Changed
GOOGLE_MAPS_API_KEY, alternateGOOGLE_API_KEY, andMAPILLARY_CLIENT_TOKENare declared inplugin.yamlrequires_env(rich form, optional in the description,secret: true) and read only via Hermesagent.secret_scope.get_secret.- Removed the v0.2.4 fallback that read
~/.config/gods-eye-view.env/GEV_ENV_FILE/GODSEYE_ENV_FILE(Hermes catalog rule 11). - Missing keys return
KEY_MISSINGwith a Hermes fix hint;register()never crashes.
Notes
- Install prompts for the optional street-level keys; skip them and the rest of EOH still loads.
- God's Eye View's own pane/client env file is unchanged for the Node app; it is not a credential source for this plugin's street-level server lookups.
v0.2.5 — fix plugin.yaml duplicate name
Fixed
Restored a clean plugin.yaml after v0.2.4 introduced a duplicated name: godseye (Hermes: found duplicate key name), which blocked the EOH toolset from loading. Added a safe bump script and a strict YAML duplicate-key test.
Still exactly 11 composable tools.
v0.2.4 — streetlevel keys, pane capture, osm Overpass fallback
Fixed
- Street-level keys fall back to
~/.config/gods-eye-view.env(orGEV_ENV_FILE/GODSEYE_ENV_FILE) when unset in the process. Values never appear in results, errors, or logs. godseye_captureop=panecaptures insidescene.postRenderafterrequestRenderso the WebGL drawing buffer is intact.godseye_queryop=osmfalls back to the same public Overpass mirrors asfind_placeswhen the pane returnsOVERPASS_NOT_CONFIGURED.
Still exactly 11 composable tools. Catalog pin unchanged. Deploy to moltussy-1 not included in this release step.
v0.2.3 — compare/timeline surface host
Fixed
Compare swipe and Wayback timeline no longer leave a black globe on a photoreal stack. Both acquire a visible imagery surface first (GEV acquireImageryComparison({ switchPolicy: 'esri-if-photoreal' }), with Esri globe fallback) before draping XYZ layers, and release the lease on stop. Returns no_visible_surface instead of a hide-only swipe when no host is available.
Still exactly 11 composable tools. Catalog pin unchanged.
Eye Of Hermes v0.2.2
Eye Of Hermes (EOH) v0.2.2
Polish sweep from the moltussy-1 feature pass. Plugin id remains godseye. Exactly 11 composable tools.
Fixes
- Resolve Esri Wayback tile releases from
waybackconfig.json(black globe after imagery A/B, zoom, or pin drawers). - Chicago geocoding + weather preset under
pane_busy/no_pane. - Transit
follow_vehicle: real follow or clear unsupported error (no false ok). - Fire watches: default
radius_kmfor center areas; FIRMS retry/backoff. - Pin research grounding (Louvre vs homonyms) and stable pin IDs.
- Overlays HTTP fallback when the relay lives in another process; action to open the Overlays sidebar.
- Harden WebGL context recovery.
- Prefer most recently focused visible pane; cut pane command timeout to ~20–30s.
- Skill: never re-enable user-disabled layers unless asked; do not
skill_managegodseye-analyst. - Composer/scene respect user-disabled layers.
- Cesium pin warnings (
heightReference/ outline on terrain). - Clearer feed-down status and adsb.lol flights fallback note.
- Document Hermes chat markdown table rendering (upstream Webapp).
godseye_captureacceptsdetail(concise|full).
Verify
python3 -m pytest -q tests— 405 passed, 1 skipped (at PR tip).- Schema measure: 11 tools, o200k ≈ 7861.
Install: pin mojomast/EOH at tag v0.2.2.
Eye Of Hermes v0.2.0
The user-facing name is Eye Of Hermes (EOH). Plugin id godseye, the godseye_ tool prefix, /gev, routes, and the repository name are unchanged.
The model catalog is eleven composable tools: godseye_view, godseye_query, godseye_layers, godseye_feeds, godseye_annotate, godseye_nav, godseye_track, godseye_scene, godseye_watch, godseye_capture, and godseye_admin. Their registered schemas are about 6.6k o200k_base tokens (6636). The catalog those tools replaced was about 30k o200k_base tokens (30133) across 97 tools, measured on this tree before investigation export. Old Hermes names are not registered. router.dispatch_legacy is the only path that still runs one.
This release also adds a per-turn map line, concise tool output (detail defaults to concise), and fix-it errors (code, message, fix). Pins are ground-clamped, and a pin info drawer shows title, markdown, images, and links. godseye_query op=brief_and_show flies a brief onto the globe. Live commands route to the chat's pane. /gev slash commands, the godseye:godseye-analyst playbook, godseye_doctor, a saved home view, share links, and guided tours are included. Annotations, camera, and caption persist per session and come back when a pane reopens. godseye_scene op=export writes GeoJSON, KML, and an optional pack zip. Tests replay hand-written HTTP fixtures and block the public network. A lost WebGL context is recovered in the same pane, and recovery calls window.__godsEyeView.recreateViewer when that hook is present. The time slider is godseye_nav op=timeline: mode=wayback scrubs Esri World Imagery Wayback releases, and mode=events shows earthquakes, fires, and stored watch alerts.
Breaking changes
- Retired tool names are no longer registered and are not listed in
plugin.yamlprovides_tools. Call one of the eleven composable tools with anop. A saved call that still uses a retired name runs only throughrouter.dispatch_legacy. Scenes, tours,/gev, the relay, and the pane keep bare action names such asfly_to_location.
Changed
- Pane branding: the panel header, loader, page title, status line and open button now say Eye Of Hermes (EOH) (gev/panel_brand.js, re-applied by a MutationObserver when the app re-renders); the header tooltip credits God's Eye View. Pane status messages and the pane loading text use the new name.
- Renamed the user-facing title to Eye Of Hermes (EOH) (pane title, plugin description,
/gevhelp, skill, README). Plugin idgodseye, tool names,/gev, routes and repo name are unchanged.
Added
- Time slider on the EOH pane, driven by
godseye_navop=timeline. The sub-action is an argument namedtimeline:set,play,step,stop,state,list_dates.mode=waybackscrubs Esri World Imagery Wayback release dates over the current view (swipe or fade).mode=eventsshows USGS quakes and NASA FIRMS fires, plus stored watch alerts, as pins that appear when the playhead reaches them.from/todefault to the last 7 days for events. The catalog is cached for six hours and not refetched inside two seconds. Tiles are for viewing only; photorealistic 3D tiles are hidden, not sampled. The slider is stored with the scene and with investigations, and it is restored on pane reopen and WebGL recovery. User scrubs persist through/live/timeline. - Composable tools, the rest of the catalog.
godseye_layers,godseye_feeds,godseye_annotate,godseye_nav,godseye_track,godseye_scene,godseye_watch,godseye_capture, andgodseye_adminjoingodseye_viewandgodseye_query. The camera read isgodseye_viewop=state(there is no separate state tool). Investigation export isgodseye_sceneop=export.godseye_viewalso gainsop=show, andgodseye_querygainsop=terrainandop=features. Every legacy name is unregistered.dispatch_legacystill runs one. Feed ops keep the person-tracking refusal and the CCTV/ALPR public-camera limit. The golden selection set covers every op. - Composable tools, phase A.
godseye_view(opfly, move, zoom, globe, home, share, panes) andgodseye_query(opfind_places, osm, context, what_is_here, brief, brief_and_show, analyst, military, poi, resolve_area, entity) call the existing handlers through one router. The 18 names those ops replaced are not registered.router.dispatch_legacystill runs a saved call that uses one of those names. Scenes, tours,/gev, the relay, and the pane keep their bare action names.flyacceptsstyle(nvgand night vision mean surveillance) and then callsset_visual_style.here=true, or a "near me" / "this area" phrase, reads the open pane's camera and then calls the original lookup. The map of every tool, including ones not routed yet, isdocs/COMPOSABLE-TOOLS.md. Selection checks live inevals/selection_golden.json(pytest, offline).evals/run_selection.pyscores that set with a live model only when an API key is set andCIis unset.evals/measure_schemas.pyprints schema bytes and token counts. - Automatic WebGL recovery. On
webglcontextlostthe pane preferswindow.__godsEyeView.recreateViewerwhen that hook is present (the hook ownsloseContext, destroy, and the new viewer, and rebinds the voice runner). Otherwise the pane callsWEBGL_lose_context.loseContext()beforeviewer.destroy()and creates a new viewer in the same container. Either path restores the saved scene with the existingrestore_commands(camera heading, pitch, and roll, pins and annotations, drawer, filters, layers, and the time slider). The click-to-reload card stays as the fallback.GODSEYE_GL_RECOVER=0, orglRecover: falseinplugin-data/godseye/config.json, turns recovery off (env wins). After 3 losses in 20 seconds, recovery stops and the card is shown. The relay reports{code:"CONTEXT_LOST", message, fix}when the context is lost and{code:"CONTEXT_RESTORED", message}when recovery succeeds; both are drained into the next turn. Intentional teardown still releases the context before destroy.scripts/gl_recover_harness.mjs(port 4233) forcesloseContext()and checks that the camera and pins come back. - Per-turn map state. When Hermes provides
pre_llm_call, the plugin injects one line (pane connected/busy/closed, camera center, range, pitch, heading, active layers, pin count, open drawer), under 300 bytes, from the relay cache. It does not call the pane. Ahermes_contextresult updates that cache fromcamera.center. The same callback also returns queued area-watch alerts, so both contexts reach the turn.GODSEYE_TURN_STATE=0turns the map line off; alerts still use the hook. Hosts withoutregister_hookskip both. - Concise tool results. Large-payload tools take
detail: concise|full(concise by default): ids and counts instead of full objects, and screenshots only whendetail=full. The same default covers live context, what-is-here, measure, isochrone, draw, compare, research pins, investigation list/load/report, pin filters, and watch create/list. A short distance, area, contour summary, or open/closed pin state stays intact; route lines, polygons, long catalogs, notes, and screenshots do not. The argument is removed before the MCP server or the pane sees it. - Fix-it errors. Failures the model sees include
code,messageandfix(pane closed or busy, relay down, timeout, set_map_stack key failures, missing keys, Overpass down or unconfigured, area too large, upstream app down, policy refusal, plusrouting_unavailable,wayback_unavailable,no_focus,no_drawing,unsupported_side,confirm_required/CONFIRM_REQUIRED,NOT_FOUND,BAD_AREA,BAD_FEEDS,no_pins). The originalerrorstring is unchanged. - Embed protocol matches the God's Eye View fork (
docs/EMBEDDING.md): the pane posts{type:'gev:visibility', visible}from page visibility and an intersection observer, and{type:'gev:config', ...keys, perf:'embed'}before the viewer starts (?waitForConfig=1). Repliesgev:visibility-appliedandgev:config-appliedare forwarded out of the inline frame.?perf=embedis on by default (GODSEYE_PERF=defaultturns it off). Client keys are written todist/panel/config.json(mode 0600) when the pane is served, so a current build does not need a rebuild. Older builds still use the baked bundle. Values are never logged.godseye_doctortreats a matchingconfig.jsonas fresh. - Pin clustering and filters (pane side,
gev/panel_pins.js+ vendored opening_hours subsetgev/panel_oh.js). Above ~2.5 km camera height, pins within 56 px merge into a count bubble; clicking one zooms to its members. A chip bar filters by category (amenity / shop / tourism / leisure / cuisine / category tags), rating >= 4 (rating or stars tags) and "Open now" (OSM opening_hours; unsupported syntax such as PH, months, sunrise is UNKNOWN, never guessed; unknown stays visible unlessinclude_unknown:false). New annotation fieldtags(filled bygodseye_find_places). New toolgodseye_live_filter_pins(set / state / expand). Filters, including chip clicks (new/live/filtersroute), persist in the scene and are re-applied after a restore. Pins stay grounded and the drawer shows rating and open state. - Area watches:
godseye_watch_create,godseye_watch_list(withcheck=<id>to run one now),godseye_watch_pause,godseye_watch_delete(needsconfirm:true). Area is a bbox, polygon, center + radius or the current view. Feeds: earthquakes (USGS, keyless), fires (NASA FIRMS,FIRMS_MAP_KEY), flights (OpenSky, keyless), ships (AISSTREAM_API_KEY+ the app'svessels_in_area), pois (OSM). Feeds without a key reportKEY_MISSING. The first run is a baseline by default. After that, only unseen ids alert; last-seen ids persist inplugin-data/godseye/watches.json. Each new item is pinned with drawer details. Alerts are queued and handed to the next chat turn through the samepre_llm_callhook as ...
v0.1.0
Rolls up 0.2.0 (never released separately) and 0.3.0.
Highlights
- Automatic pipeline:
dopplergeo detect|locateand the Hermes toolsdoppler_detect/doppler_locate. No hand-picked bands. Fetches adsb.lol ADS-B (ODbL), Copernicus DEM and Open-Meteo, with a cache (DOPPLER_GEO_CACHE) and--offline. - Track-based scoring: emission-time-correct curves from real ADS-B tracks, a joint likelihood with a silence penalty, a coarse-to-fine posterior with 68 / 95 % areas, and a
confidence: ok|lowflag. The areas are calibrated withtemper_extra=4. - Broadband (experimental,
--broadband/broadband: true): detects jet passes from the ground-reflection (Lloyd's mirror) multipath delay. Cepstrogram, Viterbi track, straight-pass fit, after Lo & Ferguson (IEEE TAES 2003). See docs/broadband.md. - New CLI flags
--broadbandand--temper-extra, plus matching tool parameters. - Eval harness
scripts/eval_batch.pyand docs/evaluation.md.
Honest results (real recordings with a known place and time; ±30 s; 15 km search)
- Tune, broadband on: Manchester field recordings went from 10.5 km to 0.19 km and from no events to 0.33 km. vny_0513 went from 15.4 to 2.95 km.
- Held-out (18 clips, one frozen run): 2 of 18 under 3 km (dfw 1.96, lgb 2.38), against 1 of 14 tonal-only. 11 solved against 8. The median of solved runs is 13.2 km (12.1 before). ads_0821b (7.9 → 17.2 km) and syd (11.0 → 18.6 km) regressed. Of the four
okresults, lgb (2.4 km) and dub (4.7 km) are roughly right, and osh (13.2 km) and muc_ap82011 (13.1 km) are wrong. The padded 95 % area holds the truth in 8 of 11. The Edinburgh, The Hague and Munich-north clips and most livestreams give no events. - The method works on clean multi-pass clips but does not yet generalise. Treat any output as a hypothesis to confirm.
Notes
- Network use is disclosed in SECURITY.md. Use only for forensics, research or your own recordings.
- Full changelog: CHANGELOG.md

