- Replace single ' handler with generic numeric/hex entity decoder
so ' and other unpadded entities are properly converted
- Dedup urgent OSINT posts against all hot memory runs (last 3 sweeps)
instead of only the previous sweep, preventing posts that drop out
of one sweep from reappearing as "new" in the next
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
P1-1: Permission instructions now correctly reference Account →
Account Analytics → Read, matching Cloudflare's Radar API docs.
P1-2: Layer 3 DDoS endpoint fixed to use /summary/{dimension}
(protocol, vector) and parse summary_0 response format per API
contract. Returns protocol breakdown and attack vector percentages.
CISA Known Exploited Vulnerabilities catalog — tracks CVEs actively
exploited in the wild. No auth required. Provides vendor breakdown,
ransomware linkage, recent additions, and actionable signals.
Cloudflare Radar — internet outages, traffic anomalies, and DDoS attack
trends. Requires a free API token (CLOUDFLARE_API_TOKEN). Monitors
watchlist countries (RU, UA, CN, IR, KP, etc.) for internet shutdowns
and sustained disruptions.
Both sources slot into Tier 6: Cyber & Infrastructure. Source count
updated from 27 to 29.
Posts were being cut to 300 chars (source ingestion) and 150 chars
(alert evaluation), losing valuable OSINT context. The sendMessage
chunker already handles the 4096-char Telegram API limit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Al Jazeera RSS URL (feeds.aljazeera.com is dead, moved to www.aljazeera.com)
- Add 8 new RSS sources: DW, France 24, Euronews, DW Africa, RFI, Africa News,
NYT Africa, NPR — covering Germany, Europe, Africa, Cameroon region, and USA
- Filter WHO outbreak news and ticker feed to last 30 days (drops stale alerts
like 733-day-old WHO DONs)
- Fix ticker causing Chrome to crash: add will-change:transform and
contain:layout style for GPU compositing, reduce DOM nodes from 80 to 40
- Add badge styles for new source categories (DW, EU, Africa)
* Add zoom-aware symbology, fix globe popovers, expand geo coverage
Map rendering improvements based on user feedback:
- Globe markers now scale with camera altitude (onZoom hook)
- Priority-based visibility culls low-priority markers at world view
- Globe popovers use getScreenCoords for accurate positioning
- Flat map labels hidden at low zoom, revealed progressively
- Default globe altitude lowered from 2.5 to 1.8 for better fill
- Americas region zoom tightened to CONUS focus
Geographic coverage expansion:
- 4 new OpenSky air theaters: Caribbean, Gulf of Guinea, Cape Route, Horn of Africa
- Flight corridors now span Americas and Africa
- NOAA alerts extract centroid lat/lon from GeoJSON geometry
- EPA RadNet stations geocoded with hardcoded coords for 10 US cities
- ISS + Tiangong positions estimated from TLE orbital elements
- GDELT geoEvents() now called in briefing for mapped event points
- New legend entries: Weather Alert, EPA RadNet, Space Station, GDELT Event
* Fix null-safe coordinate checks and remove injected data blob
- Use `!= null` instead of truthy checks for lat/lon in noaa.mjs
and inject.mjs so valid 0-coordinates (equator/prime meridian)
are not silently dropped
- Reset jarvis.html `let D` back to null placeholder so generated
runtime data is not part of the PR diff
* Remove re-injected data blob from jarvis.html
Reset let D back to null — previous commit was correct but
inject.mjs build verification re-injected the payload.
The dashboard would hang indefinitely on the loading screen because:
1. `bls.mjs` used a raw `fetch()` without any timeout/AbortSignal —
if the BLS API was slow or unresponsive, it would block forever.
2. `runSource()` in `briefing.mjs` had no per-source timeout, so a
single hanging API could stall the entire sweep indefinitely.
3. `server.mjs` loaded cached `latest.json` via a fire-and-forget
promise (`.then()`) instead of `await`, meaning the dashboard
never received the cached data before the sweep started.
4. `loading.html` relied solely on SSE for redirect — if the SSE
connection missed the update event, the page would never redirect.
Changes:
- Add 15s AbortController timeout to BLS `getSeries()` fetch call
- Add 30s per-source timeout via `Promise.race()` in `runSource()`
- Await `synthesize()` when loading cached data so the dashboard
serves instantly on restart when `runs/latest.json` exists
- Add 5s fallback polling to loading page alongside SSE
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New source: apis/sources/space.mjs (no API key required)
- Tracks: recent launches, ISS, military sats, Starlink/OneWeb constellations
- Wired into briefing.mjs (27 sources), inject.mjs synthesis, and dashboard
- New Space Watch panel in left rail with military breakdown and signals
- New Satellites layer in Sensor Grid
26-source OSINT intelligence engine with live Jarvis dashboard,
auto-refresh via SSE, optional LLM layer (4 providers), delta/memory
system, and Telegram breaking news alerts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>