mirror of
https://github.com/hanzo-apps/world.git
synced 2026-10-30 14:53:09 +00:00
The WebSocket/RSS relay is deployment-target-agnostic in code and docs; drop the platform brand from identifiers, comments, and prose describing it. The industry status-board entry and the Gulf FDI "railways" transport sector (unrelated meaning) are untouched. Co-authored-by: Hanzo Dev <[email protected]> Claude-Session: https://claude.ai/code/session_011i2AG9nwpiKUCVxAdDzYuU
20 KiB
20 KiB
Changelog
All notable changes to World Monitor are documented here.
[2.4.43]
Added
- Finance-terminal alt-asset feeds are live (
?variant=finance). The "Art & Collectibles — Auctions" and "Luxury Real Estate" panels now render REAL data instead of "live feed pending":GET /v1/world/auctions— Christie's public auction results (realized sale totals: title, inferred category, price + currency, sale date, location, image, link). Sotheby's gates realized prices behind a login (its sale-results API returns401 Not signed in), so the honest public major house is the source.GET /v1/world/luxury-realestate— LuxuryEstate.com luxury listings (title, location, price + currency, type, image, link). JamesEdition sits behind a Cloudflare JS challenge that blocks datacenter egress, so it cannot be fetched from the pod.- Both are scraped server-side (
internal/world/handlers_altassets.go) at most once an hour and served from cache to every caller (respectful). On a source failure the last-good copy is served; with no cache yet, an honest empty{items:[]}(the panel shows "live feed pending") — never fabricated data. The payload attributes its source per feed.
[2.4.19]
Fixed
- Moving/resizing a panel no longer shifts the others (the "when I shift the 3D map it shifts all other components" report). The dashboard now DEFAULTS to the free layout: every panel owns its own {x,y,w,h}, so a drag or resize leaves every sibling exactly where it was — no more grid reflow. The switch is invisible: the current grid arrangement is frozen as the starting geometry (
grid-config.applyDefaultLayout), and Grid stays one dropdown-click away for anyone who wants snap-to-grid back. - Panels resize granularly — pixel-exact width AND height from any edge or corner, instead of jumping between coarse column/row spans.
- Panels can be made much narrower/smaller ("constrained on min width"): the free-mode floors drop to 96×40px (map 140px), and the grid widget-size slider now reaches a 120px column track (was 140).
Changed
- A panel shown from the Panels menu / "+ Add widget" while in free mode seeds a tidy default slot below the placed panels (never a full-width block under its absolute siblings). Hidden panels no longer persist 0×0 geometry.
[2.4.13]
Fixed
- Globe overlays now sit ON the sphere with correct occlusion (the "map spazzes" report). On the native deck.gl GlobeView, data layers (shared with the 2D map) carried no depth parameters, so the far hemisphere showed through and count badges floated above the limb. GlobeNative now seats every data layer against the depth-writing ocean sphere (test, don't write — no inter-marker z-fight), and the far-side billboard cull (
occludeFarSide) faces the globe's OWN live camera instead of the parked (frozen) mapbox center — extended toTextLayerso a back-side "36" count badge disappears instead of hovering over the planet. - Terrain striping on the globe: the draped ESRI imagery tiles each wrote depth, so coplanar neighbours z-fought at the tile seams (horizontal stripes / partial render). Tiles now depth-TEST only; the ocean sphere owns the depth buffer.
- Live request-geo dots kept polling on the 3D globe: the
/v1/world/cloud/*poll was gated onrenderPaused, which the native GlobeView sets on activation — so the realtime dots froze the moment you entered the default 3D view. It now gates on tab visibility, so the dots stay live (and fade) on the globe.
Changed
- Request-origin → serving-region arcs on by default in the Cloud view: the
/cloud/trafficarcs derive from the same real native request-geo points as the dots (origin country → nearest Hanzo region) and degrade to empty — never demo.
[2.4.6]
Added
- Enso Flywheel panel (AI variant): the router self-improvement loop made visible. New
/v1/world/enso-trainingfolds the routing-decision ledger tail + reward tail (export-routing-ledger/export-routing-rewards, super-admin) into ledger growth, engine-vs-heuristic mix, a routing-confidence histogram, and task/model distributions, alongside the latest enso-bench eval scores (an embeddedresults/summary.jsonsnapshot, overridable live viaENSO_BENCH_URL). The response is event-typed so future retrain/deploy milestones slot into the same timeline. Eval scores render even signed-out;state(live/partial/demo) says which live sources resolved.
[2.4.5]
Added
- AI Compute panel (AI variant): live Hanzo inference-plane telemetry over SSE — tokens/s, requests/s, 24h spend, top models by real spend, and the serving fleet (GPUs, machines online, models served). New
/v1/world/ai-pulsepushes typedusage/fleet/statusframes (EventSource) and answers a plain GET with one JSON snapshot as the poll fallback. Honest "connecting"/"unavailable" states — never a zero dressed up as live; the service bearer stays server-side.
[2.4.4]
Changed
- Cloud Pulse is real when a service token is wired:
/v1/world/cloud-pulsenow folds MEASURED platform-wide 24h request/token volume from the ClickHouse-backed usage ledger (get-cloud-usages ?org=all, super-admin) on top of the live model/node/GPU/region counts — dropping bothdemo:trueandvolumeModeled:true. Top models come from real ledger spend. Without a token, or with a non-admin token, it stays honestly demo/modeled — platform numbers are never faked silently. The service bearer stays server-side (never sent to the browser).
[2.4.2]
Added
- Streaming analyst: answers flow in live over SSE — reasoning shows as dim thinking text, tool calls appear as chips the moment they run, the reply types itself in; the final render and command dispatch are unchanged (done event = the old JSON contract)
- Model menu: the composer pill opens a grouped popover (Auto / Zen / GPT / Llama / Claude / Agents) with per-family marks and an active check
Fixed
- Model identity: the Zen ring appears only on zen* models — gpt-oss/llama/claude get their own marks on the pill, menu rows, avatars, and the thinking row
- Dev server:
npm run devproxies /v1 to production by default (VITE_DEV_API_PROXY overrides)
[2.4.1]
Added
- Western Pacific cyclones: cross-agency tropical-cyclone attribution (GDACS + HKO warnings via new
/v1/world/hko-warningsproxy) with per-agency wind observations, canonical dedup, and map popup detail rows - China macro snapshot:
/v1/world/china-macro— CPI/CLI (OECD), policy rate, USD/CNY (FRED), HKMA context, NBS release calendar + PBoC LPR dates, surfaced with staleness-honest indicator tiles - Model roster:
Best (auto)leads the analyst model picker — the gateway routing alias that always resolves
Changed
- AI default model:
zen5→best; a pinned family id goes dark when the inference plane's claim catalog shifts, the routing alias never does - Server cache is now stale-while-revalidate:
cachedJSON/passthroughserve stale instantly and refresh in the background (single-flight); GDELT/theater-posture no longer stall requests ~10s on TTL expiry - GDELT cache warmers: hot keys (analyst grounding, protests layer) refreshed every ~4min so no user ever eats a cold miss
- Sparkline payloads: close arrays rounded to 7 significant digits (float32-widening noise stripped, ~40% smaller; scalars untouched)
Fixed
- News first paint: panels no longer gate their first DOM write on a 65MB ML sentiment model download — headlines paint immediately, sentiment refines in place
- Analyst grounding snapshot: context fetches bounded at 2.5s so a cold endpoint can't hold the chat send hostage
- AI errors are honest: upstream error codes (
insufficient_balance,spend_cap_exceeded, …) surface in the chat instead of a barestatus 402
[2.4.0] - 2026-02-19
Added
- Live Webcams Panel: 2x2 grid of live YouTube webcam feeds from global hotspots with region filters (Middle East, Europe, Asia-Pacific, Americas), grid/single view toggle, idle detection, and full i18n support (#111)
- Linux download: added
.AppImageoption to download banner
Changed
- Mobile detection: use viewport width only for mobile detection; touch-capable notebooks (e.g. ROG Flow X13) now get desktop layout (#113)
- Webcam feeds: curated Tel Aviv, Mecca, LA, Miami; replaced dead Tokyo feed; diverse ALL grid with Jerusalem, Tehran, Kyiv, Washington
Fixed
- Le Monde RSS: English feed URL updated (
/en/rss/full.xml→/en/rss/une.xml) to fix 404 - Workbox precache: added
htmltoglobPatternssonavigateFallbackworks for offline PWA - Panel ordering: one-time migration ensures Live Webcams follows Live News for existing users
- Mobile popups: improved sheet/touch/controls layout (#109)
- Intelligence alerts: disabled on mobile to reduce noise (#110)
- RSS proxy: added 8 missing domains to allowlist
- HTML tags: repaired malformed tags in panel template literals
- ML worker: wrapped
unloadModel()in try/catch to prevent unhandled timeout rejections - YouTube player: optional chaining on
playVideo?.()/pauseVideo?.()for initialization race - Panel drag: guarded
.closest()on non-Element event targets - Beta mode: resolved race condition and timeout failures
- Sentry noise: added filters for Firefox
too much recursion, maplibre_layers/id/typenull crashes
[2.3.9] - 2026-02-18
Added
- Full internationalization (14 locales): English, French, German, Spanish, Italian, Polish, Portuguese, Dutch, Swedish, Russian, Arabic, Chinese Simplified, Japanese — each with 1100+ translated keys
- RTL support: Arabic locale with
dir="rtl", dedicated RTL CSS overrides, regional language code normalization (e.g.ar-SAcorrectly triggers RTL) - Language switcher: in-app locale picker with flag icons, persists to localStorage
- i18n infrastructure: i18next with browser language detection and English fallback
- Community discussion widget: floating pill linking to GitHub Discussions with delayed appearance and permanent dismiss
- Linux AppImage: added
ubuntu-22.04to CI build matrix with webkit2gtk/appindicator dependencies - NHK World and Nikkei Asia: added RSS feeds for Japan news coverage
- Intelligence Findings badge toggle: option to disable the findings badge in the UI
Changed
- Zero hardcoded English: all UI text routed through
t()— panels, modals, tooltips, popups, map legends, alert templates, signal descriptions - Trending proper-noun detection: improved mid-sentence capitalization heuristic with all-caps fallback when ML classifier is unavailable
- Stopword suppression: added missing English stopwords to trending keyword filter
Fixed
- Dead UTC clock: removed
#timeDisplayelement that permanently displayed--:--:-- UTC - Community widget duplicates: added DOM idempotency guard preventing duplicate widgets on repeated news refresh cycles
- Settings help text: suppressed raw i18n key paths rendering when translation is missing
- Intelligence Findings badge: fixed toggle state and listener lifecycle
- Context menu styles: restored intel-findings context menu styles
- CSS theme variables: defined missing
--panel-bgand--panel-bordervariables
[2.3.8] - 2026-02-17
Added
- Finance variant: Added a dedicated market-first variant (
world.hanzo.ai) with finance/trading-focused feeds, panels, and map defaults - Finance desktop profile: Added finance-specific desktop config and build profile for Tauri packaging
Changed
- Variant feed loading:
loadNewsnow enumerates categories dynamically and stages category fetches with bounded concurrency across variants - Feed resilience: Replaced direct MarketWatch RSS usage in finance/full/tech paths with Google News-backed fallback queries
- Classification pressure controls: Tightened AI classification budgets for tech/full and tuned per-feed caps to reduce startup burst pressure
- Timeline behavior: Wired timeline filtering consistently across map and news panels
- AI summarization defaults: Switched OpenRouter summarization to auto-routed free-tier model selection
Fixed
- Finance panel parity: Kept data-rich panels while adding news panels for finance instead of removing core data surfaces
- Desktop finance map parity: Finance variant now runs first-class Deck.GL map/layer behavior on desktop runtime
- Polymarket fallback: Added one-time direct connectivity probe and memoized fallback to prevent repeated
ERR_CONNECTION_RESETstorms - FRED fallback behavior: Missing
FRED_API_KEYnow returns graceful empty payloads instead of repeated hard 500s - Preview CSP tooling: Allowed
https://vercel.livescript in CSP so Vercel preview feedback injection is not blocked - Trending quality: Suppressed noisy generic finance terms in keyword spike detection
- Mobile UX: Hidden desktop download prompt on mobile devices
[2.3.7] - 2026-02-16
Added
- Full light mode theme: Complete light/dark theme system with CSS custom properties, ThemeManager module, FOUC prevention, and
getCSSColor()utility for theme-aware inline styles - Theme-aware maps and charts: Deck.GL basemap, overlay layers, and CountryTimeline charts respond to theme changes in real time
- Dark/light mode header toggle: Sun/moon icon in the header bar for quick theme switching, replacing the duplicate UTC clock
- Desktop update checker: Architecture-aware download links for macOS (ARM/Intel) and Windows
- Node.js bundled in Tauri installer: Sidecar no longer requires system Node.js
- Markdown linting: Added markdownlint config and CI workflow
Changed
- Panels modal: Reverted from "Settings" back to "Panels" — removed redundant Appearance section now that header has theme toggle
- Default panels: Enabled UCDP Conflict Events, UNHCR Displacement, Climate Anomalies, and Population Exposure panels by default
Fixed
- CORS for Tauri desktop: Fixed CORS issues for desktop app requests
- Markets panel: Keep Yahoo-backed data visible when Finnhub API key is skipped
- Windows UNC paths: Preserve extended-length path prefix when sanitizing sidecar script path
- Light mode readability: Darkened neon semantic colors and overlay backgrounds for light mode contrast
[2.3.6] - 2026-02-16
Fixed
- Windows console window: Hide the
node.execonsole window that appeared alongside the desktop app on Windows
[2.3.5] - 2026-02-16
Changed
- Panel error messages: Differentiated error messages per panel so users see context-specific guidance instead of generic failures
- Desktop config auto-hide: Desktop configuration panel automatically hides on web deployments where it is not relevant
[2.3.4] - 2026-02-16
Fixed
- Windows sidecar crash: Strip
\\?\UNC extended-length prefix from paths before passing to Node.js — Tauriresource_dir()on Windows returns UNC-prefixed paths that causeEISDIR: lstat 'C:'in Node.js module resolution - Windows sidecar CWD: Set explicit
current_diron the Node.js Command to prevent bare drive-letter working directory issues from NSIS shortcut launcher - Sidecar package scope: Add
package.jsonwith"type": "module"to sidecar directory, preventing Node.js from walking up the entire directory tree during ESM scope resolution
[2.3.3] - 2026-02-16
Fixed
- Keychain persistence: Enable
apple-native(macOS) andwindows-native(Windows) features for thekeyringcrate — v3 ships with no default platform backends, so API keys were stored in-memory only and lost on restart - Settings key verification: Soft-pass network errors during API key verification so transient sidecar failures don't block saving
- Resilient keychain reads: Use
Promise.allSettledinloadDesktopSecretsso a single key failure doesn't discard all loaded secrets - Settings window capabilities: Add
"settings"to Tauri capabilities window list for core plugin permissions - Input preservation: Capture unsaved input values before DOM re-render in settings panel
[2.3.0] - 2026-02-15
Security
- CORS hardening: Tighten Vercel preview deployment regex to block origin spoofing (
worldmonitorEVIL.vercel.app) - Sidecar auth bypass: Move
/api/local-env-updatebehindLOCAL_API_TOKENauth check - Env key allowlist: Restrict sidecar env mutations to 18 known secret keys (matching
SUPPORTED_SECRET_KEYS) - postMessage validation: Add
originandsourcechecks on incoming messages in LiveNewsPanel - postMessage targetOrigin: Replace wildcard
'*'with specific embed origin - CORS enforcement: Add
isDisallowedOrigin()check to 25+ API endpoints that were missing it - Custom CORS migration: Migrate
gdelt-geoandeiafrom custom CORS to shared_cors.jsmodule - New CORS coverage: Add CORS headers + origin check to
firms-fires,stock-index,youtube/live - YouTube embed origins: Tighten
ALLOWED_ORIGINSregex inyoutube/embed.js - CSP hardening: Remove
'unsafe-inline'fromscript-srcin bothindex.htmlandtauri.conf.json - iframe sandbox: Add
sandbox="allow-scripts allow-same-origin allow-presentation"to YouTube embed iframe - Meta tag validation: Validate URL query params with regex allowlist in
parseStoryParams()
Fixed
- Service worker stale assets: Add
skipWaiting,clientsClaim, andcleanupOutdatedCachesto workbox config — fixesNS_ERROR_CORRUPTED_CONTENT/ MIME type errors when users have a cached SW serving old HTML after redeployment
[2.2.6] - 2026-02-14
Fixed
- Filter trending noise and fix sidecar auth
- Restore tech variant panels
- Remove Market Radar and Economic Data panels from tech variant
Docs
- Add developer X/Twitter link to Support section
- Add cyber threat API keys to
.env.example
[2.2.5] - 2026-02-13
Security
- Migrate all Vercel edge functions to CORS allowlist
- Restrict relay CORS to allowed origins only
Fixed
- Hide desktop config panel on web
- Route World Bank & Polymarket via relay
[2.2.3] - 2026-02-12
Added
- Cyber threat intelligence map layer (Feodo Tracker, URLhaus, C2IntelFeeds, OTX, AbuseIPDB)
- Trending keyword spike detection with end-to-end flow
- Download desktop app slide-in banner for web visitors
- Country briefs in Cmd+K search
Changed
- Redesign 4 panels with table layouts and scoped styles
- Redesign population exposure panel and reorder UCDP columns
- Dramatically increase cyber threat map density
Fixed
- Resolve z-index conflict between pinned map and panels grid
- Cap geo enrichment at 12s timeout, prevent duplicate download banners
- Replace ipwho.is/ipapi.co with ipinfo.io/freeipapi.com for geo enrichment
- Harden trending spike processing and optimize hot paths
- Improve cyber threat tooltip/popup UX and dot visibility
[2.2.2] - 2026-02-10
Added
- Full-page Country Brief Page replacing modal overlay
- Download redirect API for platform-specific installers
Fixed
- Normalize country name from GeoJSON to canonical TIER1 name
- Tighten headline relevance, add Top News section, compact markets
- Hide desktop config panel on web, fix irrelevant prediction markets
- Tone down climate anomalies heatmap to stop obscuring other layers
- macOS: hide window on close instead of quitting
Performance
- Reduce idle CPU from pulse animation loop
- Harden regression guardrails in CI, cache, and map clustering
[2.2.1] - 2026-02-08
Fixed
- Consolidate variant naming and fix PWA tile caching
- Windows settings window: async command, no menu bar, no white flash
- Constrain layers menu height in DeckGLMap
- Allow Cloudflare Insights script in CSP
- macOS build failures when Apple signing secrets are missing
[2.2.0] - 2026-02-07
Initial v2.2 release with multi-variant support (World + Tech), desktop app (Tauri), and comprehensive geopolitical intelligence features.