Skip to content

Integrate AI4U provider, add full vi locale parity, and AI4U maize/blue theme#117

Open
AI4Unow wants to merge 1004 commits intokoala73:mainfrom
AI4Unow:codex/ai4u-vi-theme
Open

Integrate AI4U provider, add full vi locale parity, and AI4U maize/blue theme#117
AI4Unow wants to merge 1004 commits intokoala73:mainfrom
AI4Unow:codex/ai4u-vi-theme

Conversation

@AI4Unow
Copy link

@AI4Unow AI4Unow commented Feb 19, 2026

This PR includes:\n- AI4U provider integration for chat/classification/country intel and embeddings\n- Runtime secret support for AI4U_API_KEY\n- Vietnamese locale added with full key parity against English\n- AI4U maize/blue theme updates\n\nBuild/typecheck validated locally and deployed to Vercel.

koala73 and others added 30 commits February 15, 2026 11:27
- Add negative country filter: headlines where another country is mentioned
  first in the title are excluded (fixes Venezuela brief showing for US)
- Filtered headlines used for both evidence section AND LLM context
- Add Top News section (5 items) between Intelligence Brief and Markets
- Limit prediction markets to max 3, tighter padding
…ine filter

- Add Brazil and UAE to TIER1_COUNTRIES, BASELINE_RISK, EVENT_MULTIPLIER,
  COUNTRY_KEYWORDS, COUNTRY_BOUNDS, COUNTRY_ALIASES, and Polymarket maps
- Use Intl.DisplayNames to resolve non-tier ISO codes in deep-link URLs
- Guard raw 2-letter codes from becoming overly broad search terms
- Fix military timeline to use same either/or logic as getCountrySignals
…ection

- Remove Evidence/Sources section (duplicate of Top News)
- Top News now shows 8 items with citation anchor IDs
- AI brief [N] citations link to Top News cards with scroll+highlight
- Move Prediction Markets to right column for balanced layout
- Left: Risk + Brief + Top News | Right: Signals + Timeline + Markets + Infra
GeoJSON uses "United States of America" but COUNTRY_TAG_MAP and
variant matching expect "United States". Normalize at entry point
so polymarket, search terms, and all downstream lookups work.
…ws dedup

- Full-page Country Brief replacing modal overlay
- Tightened headline relevance with negative country filter
- Top News section replacing redundant Evidence/Sources
- Shared country-geometry service for local-first detection
- BR/AE added to tier-1, deep-link name resolution
- Prediction Markets moved to right column for balanced layout
The runtime fetch patch previously returned local 4xx/5xx responses
as-is. Now falls back to worldmonitor.app cloud API on any non-OK
local response, matching the existing network-error fallback behavior.
- Add 60s startup cooldown to suppress pulse during initial data hydration
- Consolidate pulse lifecycle into syncPulseAnimation() across all setters
- Replace static predicates (h.level=high, c.maxSeverity=high) with dynamic-only
  checks: recent news, recent ACLED riots (<2h), breaking hotspots
- Exclude GDELT riots from pulse gating (noisy, not actionable)
- Reduce pulse interval from 250ms to 500ms (halves layer rebuild rate)
- Pause pulse when render is paused (country brief overlay)
- Add latestRiotEventTimeMs to MapProtestCluster with raw protest fallback
- Add Playwright tests for startup cooldown and lifecycle start/stop/GDELT exclusion
Side panel slides in 12s after initial load with macOS/Windows download
links. Dismissed per session. Skipped on Tauri desktop runtime.
…tion

Plot live botnet C2 servers, malware distribution nodes, and malicious IPs
on the globe using free abuse.ch APIs (Feodo Tracker + URLhaus).

- Vercel edge API with triple-layer caching (Redis → memory → stale fallback)
- IP geolocation via ipwho.is + ipapi.co (HTTPS-compatible with Edge runtime)
- Severity-based color coding (critical=red, high=orange, medium=amber, low=yellow)
- Feature-gated behind VITE_ENABLE_CYBER_LAYER=true env var
- Frontend circuit breaker, data sanitization, 10min auto-refresh
- Tauri desktop support: 3 new secret keys (URLHAUS, OTX, AbuseIPDB)
- Full test suite (6 unit tests), e2e harness updates, popup + tooltip rendering
Expands from 2 to 5 threat intel sources:
- C2IntelFeeds (free, no auth): ~500 active C2 server IPs (CobaltStrike, Metasploit)
- AlienVault OTX (optional API key): community-sourced IOCs with tags
- AbuseIPDB (optional API key): high-confidence abuse reports with geo
- Feodo: now includes recently-offline entries (still threat-relevant)

All sources fetched in parallel. Graceful degradation when API keys missing.
…nrichment

ipwho.is returns 403 from Node.js/Edge ("CORS not supported on Free plan")
and ipapi.co rate-limits aggressively (429). Both providers only work from
browser-side requests.

Switch to ipinfo.io (HTTPS, 50K/mo free, works from Edge runtime) as primary
with freeipapi.com as fallback.

Validated end-to-end: 20 C2 IPs geo-enriched in <1s with real coordinates.
…wnload banners

Addresses PR koala73#68 review comments:
- P1: hydrateThreatCoordinates now races workers against a 12s overall
  timeout so slow GeoIP providers can't block the entire request
- P2: DownloadBanner adds module-level guard preventing duplicate panels
- Tooltip: show "Cyber Threat" + severity + country instead of raw source names
- Popup header: "Cyber Threat" title instead of raw IP address
- Popup: show all 5 source labels and add malware family field
- Increase dot size for better visibility at global zoom level
Increase geo cap 100→250, concurrency 8→16, per-IP timeout 8→3s.
Add country centroid fallback with jitter for IPs with country codes.
Both WORLD_FEEDS and TECH_FEEDS were missing 'Cyber Threats', causing
updateFeed() calls to be silently rejected by the allowlist check.
Bring Climate Anomalies, Population Exposure, UCDP Conflict Events,
and UNHCR Displacement panels up to dashboard design standards
matching Fires/Markets/Stablecoins panels.

- Replace div-based layouts with proper <table> structures
- Add scoped <style> blocks (no inline style= attributes)
- CSS class-based severity badges, death colors, displacement badges
- tabular-nums on all numeric columns, right-aligned
- Row hover effects, text-overflow ellipsis for long text
- Stat grid for UNHCR global totals, total deaths summary for UCDP
- Custom tab styling for UCDP and Displacement panels
…la73#67)

**Description:** I fixed a visual bug where the cards were overlapping
the map when using the "Pin" option. Now the cards slide correctly
underneath the map when scrolling.

**Before:** 
<img width="1914" height="947" alt="error"
src="https://github.com/user-attachments/assets/add5b838-b15c-46d9-adea-aff063563af4"
/>

**and After:**
<img width="1919" height="929" alt="Correction"
src="https://github.com/user-attachments/assets/421fb4af-1851-4f8e-a422-3d095ddb9c48"
/>
…ation exposure, and entity index

Update README with 5 new How It Works sections and 10 inline updates
reflecting implemented features. Data layer count 29→30+, data sources
14→22, new Tech Stack and Roadmap entries.
PopulationExposure: replace truncated 4-column table with two-line
card layout (full event name + population/radius meta row).
UCDP: move deaths to column koala73#2 (Country → Deaths → Date → Actors).
… redesigns & docs (koala73#68)

## Summary
- **New map layer** plotting live botnet C2 servers, malware hosts, and
malicious IPs from **5 threat intel sources**
- **Vercel edge API** (`/api/cyber-threats`) with triple-layer caching
(Redis → memory → stale fallback), rate limiting, and graceful
degradation
- **IP geolocation** via ipinfo.io + freeipapi.com fallback —
HTTPS-compatible with Edge runtime, geo results cached in Redis (24h
TTL)
- **Feature-gated** behind `VITE_ENABLE_CYBER_LAYER=true` — entire layer
hidden when disabled
- **Severity color coding**: critical (red) → high (orange) → medium
(amber) → low (yellow)
- **Tauri desktop**: 3 new keychain secrets (URLHAUS_AUTH_KEY,
OTX_API_KEY, ABUSEIPDB_API_KEY) with runtime config UI
- **Geo enrichment timeout**: 12s overall cap prevents slow GeoIP
providers from blocking the request
- **Download banner**: idempotency guard prevents duplicate panels on
repeated calls

## Data Sources
| Source | Auth | What |
|--------|------|------|
| **Feodo Tracker** | None (free) | Botnet C2 server IPs with country |
| **C2IntelFeeds** | None (free) | ~500 C2 IPs from GitHub CSV
(CobaltStrike, Metasploit, Sliver, etc.) |
| **URLhaus** | `URLHAUS_AUTH_KEY` | Malicious URL distribution hosts |
| **AlienVault OTX** | `OTX_API_KEY` | Community threat indicators (APT,
ransomware, botnets) |
| **AbuseIPDB** | `ABUSEIPDB_API_KEY` | Reported malicious IPs with
abuse confidence scores |

Sources with missing API keys gracefully skip (no error, `partial:
false`). Sources that are configured but fail set `partial: true`.

## Test plan
- [x] 7 unit tests pass (`node --test api/cyber-threats.test.mjs`)
- [x] All 5 sources aggregated and deduplicated in API response
- [x] Graceful degradation when API keys missing (free sources only)
- [x] `partial: true` when configured sources fail
- [x] Memory cache hit on repeated requests
- [x] Stale fallback when upstream fails after cache TTL
- [x] Geo enrichment capped at 12s overall timeout
- [x] Set `VITE_ENABLE_CYBER_LAYER=true` → toggle appears in layer
controls
- [x] Enable layer → purple/red dots render on map at threat locations
- [x] Hover → tooltip shows indicator, severity, malware family, source
- [x] Click → popup with full details (type, tags, coordinates,
timestamps)
- [x] TypeScript build passes (`tsc --noEmit`)
- [ ] Without env var → layer toggle hidden, no fetches made
- [ ] `curl /api/cyber-threats` → returns JSON with `success: true`,
`data[]` has lat/lon
- [ ] Second request within 10min → `X-Cache: MEMORY-HIT`
…via Railway

Desktop Configuration panel was leaking to web due to being in
FULL_PANELS/TECH_PANELS configs. Removed from static configs (injected
programmatically for Tauri) and filtered from toggle UI on web.

World Bank API returns 403 to Vercel edge IPs. Added /worldbank proxy
route to Railway relay with full response transformation and 30-min cache.
Client tries Railway first, falls back to Vercel.

Polymarket gamma-api suffers Cloudflare JA3 blocking from Vercel.
Added /polymarket proxy route to Railway relay with 2-min cache.
Client fallback chain: browser-direct → Tauri → Railway → Vercel → production.
Replace Access-Control-Allow-Origin: * with an allowlist of our domains
(worldmonitor.app, tech.worldmonitor.app, localhost dev ports, Tauri,
and *.vercel.app previews). Prevents third parties from using the relay
as a free proxy.
Replace Access-Control-Allow-Origin: * with shared getCorsHeaders()
across 20 API edge functions to restrict access to worldmonitor.app,
tech.worldmonitor.app, and authorized Vercel preview URLs.

Version bump to 2.2.5 across package.json, tauri.conf.json, Cargo.toml.
koala73 and others added 23 commits February 19, 2026 00:01
Spaces inside HTML tags (e.g. `< span class= "trend-up" >`) caused
browsers to render raw markup text instead of elements. Fixed ~45
instances across CIIPanel, ServiceStatusPanel, and StrategicPosturePanel.
france24, euronews, lemonde, dw, africanews, lasillavacia,
channelnewsasia, thehindu were returning 403 in production.
CI already builds AppImage for Linux — this adds the missing UI:
- linux-appimage pattern in api/download.js
- Linux UA detection and button in DownloadBanner
- i18n key added to all 13 locale files
- ALL grid now picks one feed per region (was showing 4x mideast)
- Jerusalem & Tehran adjacent (conflict hotspots)
- Replace broken Berlin with Paris Eiffel Tower webcam
- Switch toolbar SVG icons from stroke to fill for dark mode clarity
- Idle handler now clears isIdle and re-renders on user activity
  (was permanently paused after 5min timeout)
- Add grid back button in single-view switcher row for mobile
  (view toggle hidden at <=768px left users stuck)
- Tokyo: DjdUEyjx8GM (maintenance) → 4pu9sF5Qssw (Tokyo Live Camera 4K)
- Reorder: Taipei → Shanghai → Tokyo → Seoul (strait hotspot first)
- Los Angeles Venice Beach (EO_1LWqsCNE) — confirmed live
- Miami Biscayne Bay (5YCajRjvWCg) — confirmed live
- Swap Dubai → Tel Aviv (live conflict coverage webcam)
- Swap Istanbul → Mecca (Kaaba 24/7 livestream)
- Fix margin-right → margin-inline-end on back button for RTL
…oks)

- Remove (pointer: coarse) from mobile detection so touch-capable
  desktops (e.g. ROG Flow X13) get desktop layout instead of mobile
- Define MOBILE_BREAKPOINT_PX (768) in utils and use in
  isMobileDevice(); CSS @media (max-width: 768px) kept in sync
- MobileWarningModal uses isMobileDevice() for consistent behavior

Ref: koala73#94
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary

<!-- A set of multiple live webcams to monitor the world live 😃  -->

## Type of change

- [ ] Bug fix
- [x] New feature
- [x] New data source / feed
- [ ] New map layer
- [ ] Refactor / code cleanup
- [ ] Documentation
- [ ] CI / Build / Infrastructure

## Affected areas

- [ ] Map / Globe
- [ ] News panels / RSS feeds
- [ ] AI Insights / World Brief
- [ ] Market Radar / Crypto
- [ ] Desktop app (Tauri)
- [ ] API endpoints (`/api/*`)
- [ ] Config / Settings
- [ ] Other: <!-- specify -->

## Checklist

- [x] Tested on [worldmonitor.app](https://worldmonitor.app) variant
- [ ] Tested on [tech.worldmonitor.app](https://tech.worldmonitor.app)
variant (if applicable)
- [ ] New RSS feed domains added to `api/rss-proxy.js` allowlist (if
adding feeds)
- [x] No API keys or secrets committed
- [x] TypeScript compiles without errors (`npm run typecheck`)

## Screenshots

<!-- If applicable, add screenshots or screen recordings -->
## Summary

<!-- Brief description of what this PR does -->

## Type of change

- [ ] Bug fix
- [x] New feature
- [ ] New data source / feed
- [ ] New map layer
- [ ] Refactor / code cleanup
- [ ] Documentation
- [ ] CI / Build / Infrastructure

## Affected areas

- [ ] Map / Globe
- [ ] News panels / RSS feeds
- [ ] AI Insights / World Brief
- [ ] Market Radar / Crypto
- [ ] Desktop app (Tauri)
- [ ] API endpoints (`/api/*`)
- [ ] Config / Settings
- [x] Other: Notifications

## Checklist

- [x] Tested on [worldmonitor.app](https://worldmonitor.app) variant
- [x] Tested on [tech.worldmonitor.app](https://tech.worldmonitor.app)
variant (if applicable)
- [ ] New RSS feed domains added to `api/rss-proxy.js` allowlist (if
adding feeds)
- [ ] No API keys or secrets committed
- [ ] TypeScript compiles without errors (`npm run typecheck`)

## Screenshots

<!-- If applicable, add screenshots or screen recordings -->
…t) (koala73#109)

## Summary

Improve mobile map popup usability for touch screen

## Type of change

- [ ] Bug fix
- [ ] New feature
- [ ] New data source / feed
- [ ] New map layer
- [x] Refactor / code cleanup
- [ ] Documentation
- [ ] CI / Build / Infrastructure

## Affected areas

- [x] Map / Globe
- [ ] News panels / RSS feeds
- [ ] AI Insights / World Brief
- [ ] Market Radar / Crypto
- [ ] Desktop app (Tauri)
- [ ] API endpoints (`/api/*`)
- [ ] Config / Settings
- [ ] Other: <!-- specify -->

## Checklist

- [ ] Tested on [worldmonitor.app](https://worldmonitor.app) variant
- [ ] Tested on [tech.worldmonitor.app](https://tech.worldmonitor.app)
variant (if applicable)
- [ ] New RSS feed domains added to `api/rss-proxy.js` allowlist (if
adding feeds)
- [ ] No API keys or secrets committed
- [ ] TypeScript compiles without errors (`npm run typecheck`)

## Screenshots

<!-- If applicable, add screenshots or screen recordings -->
- ml-worker: catch unload-model timeout instead of leaking unhandled rejection
- LiveNewsPanel: optional chaining on playVideo/pauseVideo for edge cases
  where YT IFrame API player object isn't fully initialized
- main.ts: add noise filter for Firefox i18next "too much recursion"
- main.ts: extend maplibre beforeSend filter for null 'id'/'type' crashes
# Conflicts:
#	src/styles/main.css
- Live Webcams Panel with region filters and grid/single view (koala73#111)
- Mobile detection: width-only, touch notebooks get desktop layout (koala73#113)
- Le Monde RSS URL fix, workbox precache HTML, panel ordering migration
- Sentry: ML timeout catch, YT player guards, maplibre noise filters
- Changelog for v2.4.0
- Replace MIT with AGPL-3.0-only to enforce attribution on derivatives
- Move hardcoded Sentry DSN to VITE_SENTRY_DSN env var
- Add null-coalesce guards for i18n legend keys and SVG viewBox
- Extend Sentry ignoreErrors with 7 additional noise patterns
## Summary

Fixes a css transparency issue when selecting languages.

Hi! First time contributing here. Found this app and thought it was
really cool. I realized it was a github repo and thought I'd try and
commit some fixes that I find. If y'all need me to update this PR in any
way let me know.

## Type of change

- [x] Bug fix
- [ ] New feature
- [ ] New data source / feed
- [ ] New map layer
- [ ] Refactor / code cleanup
- [ ] Documentation
- [ ] CI / Build / Infrastructure

## Affected areas

- [ ] Map / Globe
- [ ] News panels / RSS feeds
- [ ] AI Insights / World Brief
- [ ] Market Radar / Crypto
- [ ] Desktop app (Tauri)
- [ ] API endpoints (`/api/*`)
- [ ] Config / Settings
- [x] Other: <!-- Language dropdown-->

## Checklist

- [x] Tested on [worldmonitor.app](https://worldmonitor.app) variant
- [ ] Tested on [tech.worldmonitor.app](https://tech.worldmonitor.app)
variant (if applicable)
- [ ] New RSS feed domains added to `api/rss-proxy.js` allowlist (if
adding feeds)
- [x] No API keys or secrets committed
- [x] TypeScript compiles without errors (`npm run typecheck`)

## Screenshots
Before:

<img width="1470" height="803" alt="Screenshot 2026-02-18 at 7 00 25 PM"
src="https://github.com/user-attachments/assets/f0e2b8ce-58dc-42f0-a73f-76b7a539fecf"
/>

After:

<img width="1470" height="800" alt="Screenshot 2026-02-18 at 6 59 54 PM"
src="https://github.com/user-attachments/assets/a528fc36-45db-40d7-8463-49fb25d07438"
/>
…lick menus

macOS WKWebView shows native Lookup/Translate/Copy menu on right-click,
overriding the custom "Hide Intelligence Findings" context menu.
Prevents default contextmenu on non-input elements in Tauri only.
@vercel
Copy link

vercel bot commented Feb 19, 2026

@AI4Unow is attempting to deploy a commit to the eliehabib projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.