worldmonitor-intelligence-dashboard

安装量: 65
排名: #11587

安装

npx skills add https://github.com/aradotso/trending-skills --skill worldmonitor-intelligence-dashboard

World Monitor Intelligence Dashboard Skill by ara.so — Daily 2026 Skills collection. World Monitor is a real-time global intelligence dashboard combining AI-powered news aggregation (435+ feeds, 15 categories), dual map engine (3D globe + WebGL flat map with 45 data layers), geopolitical risk scoring, finance radar (92 exchanges), and cross-stream signal correlation — all from a single TypeScript/Vite codebase deployable as web, PWA, or native desktop (Tauri 2). Installation & Quick Start git clone https://github.com/koala73/worldmonitor.git cd worldmonitor npm install npm run dev

Opens http://localhost:5173

No environment variables required for basic operation. All features work with local Ollama by default. Site Variants npm run dev:tech

tech.worldmonitor.app variant

npm run dev:finance

finance.worldmonitor.app variant

npm run dev:commodity

commodity.worldmonitor.app variant

npm run dev:happy

happy.worldmonitor.app variant

Production Build npm run typecheck

TypeScript validation

npm run build:full

Build all variants

npm run build

Build default (world) variant

Project Structure worldmonitor/ ├── src/ │ ├── components/ # UI components (TypeScript) │ ├── feeds/ # 435+ RSS/API feed definitions │ ├── layers/ # Map data layers (deck.gl) │ ├── ai/ # AI synthesis pipeline │ ├── signals/ # Cross-stream correlation engine │ ├── finance/ # Market data (92 exchanges) │ ├── variants/ # Site variant configs (world/tech/finance/commodity/happy) │ └── protos/ # Protocol Buffer definitions (92 protos, 22 services) ├── api/ # Vercel Edge Functions (60+) ├── src-tauri/ # Tauri 2 desktop app (Rust) ├── docs/ # Documentation source └── vite.config.ts Environment Variables Create a .env.local file (never commit secrets):

AI Providers (all optional — Ollama works with no keys)

VITE_OLLAMA_BASE_URL

http://localhost:11434

Local Ollama instance

VITE_GROQ_API_KEY

$GROQ_API_KEY

Groq cloud inference

VITE_OPENROUTER_API_KEY

$OPENROUTER_API_KEY

OpenRouter multi-model

Caching (optional, improves performance)

UPSTASH_REDIS_REST_URL

$UPSTASH_REDIS_REST_URL UPSTASH_REDIS_REST_TOKEN = $UPSTASH_REDIS_REST_TOKEN

Map tiles (optional, MapLibre GL)

VITE_MAPTILER_API_KEY

$MAPTILER_API_KEY

Variant selection

VITE_SITE_VARIANT

world

world | tech | finance | commodity | happy

Core Concepts Feed Categories World Monitor aggregates 435+ feeds across 15 categories: // src/feeds/categories.ts pattern import type { FeedCategory } from './types' ; const FEED_CATEGORIES : FeedCategory [ ] = [ 'geopolitics' , 'military' , 'economics' , 'technology' , 'climate' , 'energy' , 'health' , 'finance' , 'commodities' , 'infrastructure' , 'cyber' , 'space' , 'diplomacy' , 'disasters' , 'society' , ] ; Country Intelligence Index Composite risk scoring across 12 signal categories per country: // Example: accessing country risk scores import { CountryIntelligence } from './signals/country-intelligence' ; const intel = new CountryIntelligence ( ) ; // Get composite risk score for a country const score = await intel . getCountryScore ( 'UA' ) ; console . log ( score ) ; // { // composite: 0.82, // signals: { // military: 0.91, // economic: 0.74, // political: 0.88, // humanitarian: 0.79, // ... // }, // trend: 'escalating', // updatedAt: '2026-03-17T08:00:00Z' // } // Subscribe to real-time updates intel . subscribe ( 'UA' , ( update ) => { console . log ( 'Risk update:' , update ) ; } ) ; AI Synthesis Pipeline // src/ai/synthesize.ts pattern import { AISynthesizer } from './ai/synthesizer' ; const synth = new AISynthesizer ( { provider : 'ollama' , // 'ollama' | 'groq' | 'openrouter' model : 'llama3.2' , // any Ollama-compatible model baseUrl : process . env . VITE_OLLAMA_BASE_URL , } ) ; // Synthesize a news brief from multiple feed items const brief = await synth . synthesize ( { items : feedItems , // FeedItem[] category : 'geopolitics' , region : 'Europe' , maxTokens : 500 , language : 'en' , } ) ; console . log ( brief . summary ) ; // AI-generated synthesis console . log ( brief . signals ) ; // Extracted signals array console . log ( brief . confidence ) ; // 0-1 confidence score Cross-Stream Signal Correlation // src/signals/correlator.ts pattern import { SignalCorrelator } from './signals/correlator' ; const correlator = new SignalCorrelator ( ) ; // Detect convergence across military, economic, disaster signals const convergence = await correlator . detectConvergence ( { streams : [ 'military' , 'economic' , 'disaster' , 'escalation' ] , timeWindow : '6h' , threshold : 0.7 , region : 'Middle East' , } ) ; if ( convergence . detected ) { console . log ( 'Convergence signals:' , convergence . signals ) ; console . log ( 'Escalation probability:' , convergence . probability ) ; console . log ( 'Contributing events:' , convergence . events ) ; } Map Engine Integration 3D Globe (globe.gl) // src/components/globe/GlobeView.ts import Globe from 'globe.gl' ; import { getCountryRiskData } from '../signals/country-intelligence' ; export function initGlobe ( container : HTMLElement ) { const globe = Globe ( ) ( container ) . globeImageUrl ( '//unpkg.com/three-globe/example/img/earth-dark.jpg' ) . backgroundImageUrl ( '//unpkg.com/three-globe/example/img/night-sky.png' ) ; // Load country risk layer const riskData = await getCountryRiskData ( ) ; globe . polygonsData ( riskData . features ) . polygonCapColor ( feat => riskToColor ( feat . properties . riskScore ) ) . polygonSideColor ( ( ) => 'rgba(0, 100, 0, 0.15)' ) . polygonLabel ( ( { properties : d } ) => <b> ${ d . name } </b><br/>Risk: ${ ( d . riskScore * 100 ) . toFixed ( 0 ) } % ) ; return globe ; } function riskToColor ( score : number ) : string { if ( score

0.8 ) return 'rgba(220, 38, 38, 0.8)' ; // critical if ( score

0.6 ) return 'rgba(234, 88, 12, 0.7)' ; // high if ( score

0.4 ) return 'rgba(202, 138, 4, 0.6)' ; // elevated if ( score

0.2 ) return 'rgba(22, 163, 74, 0.5)' ; // low return 'rgba(15, 118, 110, 0.4)' ; // minimal } WebGL Flat Map (deck.gl + MapLibre GL) // src/components/map/DeckMap.ts import { Deck } from '@deck.gl/core' ; import { ScatterplotLayer , ArcLayer , HeatmapLayer } from '@deck.gl/layers' ; import maplibregl from 'maplibre-gl' ; export function initDeckMap ( container : HTMLElement ) { const map = new maplibregl . Map ( { container , style : 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json' , center : [ 0 , 20 ] , zoom : 2 , } ) ; const deck = new Deck ( { canvas : 'deck-canvas' , initialViewState : { longitude : 0 , latitude : 20 , zoom : 2 } , controller : true , layers : [ // Event scatter layer new ScatterplotLayer ( { id : 'events' , data : getActiveEvents ( ) , getPosition : d => [ d . lng , d . lat ] , getRadius : d => d . severity * 50000 , getFillColor : d => severityToRGBA ( d . severity ) , pickable : true , } ) , // Supply chain arc layer new ArcLayer ( { id : 'supply-chains' , data : getSupplyChainData ( ) , getSourcePosition : d => d . source , getTargetPosition : d => d . target , getSourceColor : [ 0 , 128 , 200 ] , getTargetColor : [ 200 , 0 , 80 ] , getWidth : 2 , } ) , ] , } ) ; return { map , deck } ; } Finance Radar // src/finance/radar.ts pattern import { FinanceRadar } from './finance/radar' ; const radar = new FinanceRadar ( ) ; // Get market composite (7-signal) const composite = await radar . getMarketComposite ( ) ; console . log ( composite ) ; // { // score: 0.62, // signals: { // volatility: 0.71, // momentum: 0.58, // sentiment: 0.65, // liquidity: 0.44, // correlation: 0.78, // macro: 0.61, // geopolitical: 0.82 // }, // exchanges: 92, // timestamp: '2026-03-17T08:00:00Z' // } // Watch specific exchange const exchange = await radar . getExchange ( 'NYSE' ) ; const crypto = await radar . getCrypto ( [ 'BTC' , 'ETH' , 'SOL' ] ) ; const commodities = await radar . getCommodities ( [ 'GOLD' , 'OIL' , 'WHEAT' ] ) ; Language & RTL Support World Monitor supports 21 languages with native-language feeds: // src/i18n/config.ts pattern import { setLanguage , getAvailableLanguages } from './i18n' ; const languages = getAvailableLanguages ( ) ; // ['en', 'ar', 'zh', 'ru', 'fr', 'es', 'de', 'ja', 'ko', 'pt', // 'hi', 'fa', 'tr', 'pl', 'uk', 'nl', 'sv', 'he', 'it', 'vi', 'id'] // Switch language (handles RTL automatically) await setLanguage ( 'ar' ) ; // Arabic — triggers RTL layout await setLanguage ( 'he' ) ; // Hebrew — triggers RTL layout await setLanguage ( 'fa' ) ; // Farsi — triggers RTL layout // Configure feed language filtering import { FeedManager } from './feeds/manager' ; const feeds = new FeedManager ( { language : 'ar' , includeEnglish : true } ) ; Protocol Buffers (API Contracts) // src/protos — 92 proto definitions, 22 services // Example generated client usage: import { IntelligenceServiceClient } from './protos/generated/intelligence_grpc_web_pb' ; import { CountryRequest } from './protos/generated/intelligence_pb' ; const client = new IntelligenceServiceClient ( process . env . VITE_API_BASE_URL || 'http://localhost:8080' ) ; const request = new CountryRequest ( ) ; request . setCountryCode ( 'DE' ) ; request . setTimeRange ( '24h' ) ; request . setSignalTypes ( [ 'military' , 'economic' , 'political' ] ) ; client . getCountryIntelligence ( request , { } , ( err , response ) => { if ( err ) console . error ( err ) ; else console . log ( response . toObject ( ) ) ; } ) ; Vercel Edge Function Pattern // api/feeds/aggregate.ts — Edge Function example import type { VercelRequest , VercelResponse } from '@vercel/node' ; import { aggregateFeeds } from '../../src/feeds/aggregator' ; import { getCachedData , setCachedData } from '../../src/cache/redis' ; export const config = { runtime : 'edge' } ; export default async function handler ( req : VercelRequest , res : VercelResponse ) { const { category , region , limit = '20' } = req . query as Record < string , string

; const cacheKey = feeds: ${ category } : ${ region } : ${ limit } ; const cached = await getCachedData ( cacheKey ) ; if ( cached ) return res . json ( cached ) ; const items = await aggregateFeeds ( { categories : category ? [ category ] : undefined , region , limit : parseInt ( limit ) , } ) ; await setCachedData ( cacheKey , items , { ttl : 300 } ) ; // 5 min TTL return res . json ( items ) ; } Desktop App (Tauri 2)

Install Tauri CLI

cargo install tauri-cli

Development

npm run tauri:dev

Build native app

npm run tauri:build

Outputs: .exe (Windows), .dmg/.app (macOS), .AppImage (Linux)

// src-tauri/src/main.rs — IPC command example

[tauri::command]

async fn fetch_intelligence ( country : String ) -> Result < CountryData , String

{ // Sidecar Node.js process handles feed aggregation // Tauri handles secure IPC between renderer and backend Ok ( CountryData :: default ( ) ) } fn main ( ) { tauri :: Builder :: default ( ) . invoke_handler ( tauri :: generate_handler! [ fetch_intelligence ] ) . run ( tauri :: generate_context! ( ) ) . expect ( "error while running tauri application" ) ; } Docker / Self-Hosting

Docker single-container

docker build -t worldmonitor . docker run -p 3000 :3000 \ -e VITE_SITE_VARIANT = world \ -e UPSTASH_REDIS_REST_URL = $UPSTASH_REDIS_REST_URL \ -e UPSTASH_REDIS_REST_TOKEN = $UPSTASH_REDIS_REST_TOKEN \ worldmonitor

Docker Compose with Redis

docker compose up -d

docker-compose.yml

version : '3.9' services : app : build : . ports : [ '3000:3000' ] environment : - VITE_SITE_VARIANT=world - REDIS_URL=redis : //redis : 6379 depends_on : [ redis ] redis : image : redis : 7 - alpine volumes : [ 'redis_data:/data' ] volumes : redis_data : Vercel Deployment npm i -g vercel vercel --prod

Set env vars in Vercel dashboard or via CLI:

vercel env add GROQ_API_KEY production vercel env add UPSTASH_REDIS_REST_URL production vercel env add UPSTASH_REDIS_REST_TOKEN production Common Patterns Custom Feed Integration // Add a custom RSS feed to the aggregation pipeline import { FeedRegistry } from './src/feeds/registry' ; FeedRegistry . register ( { id : 'my-custom-feed' , name : 'My Intelligence Source' , url : 'https://example.com/feed.xml' , category : 'geopolitics' , region : 'Asia' , language : 'en' , weight : 0.8 , // 0-1, affects signal weighting refreshInterval : 300 , // seconds parser : 'rss2' , // 'rss2' | 'atom' | 'json' } ) ; Custom Map Layer // Register a custom deck.gl layer in the 45-layer system import { LayerRegistry } from './src/layers/registry' ; import { IconLayer } from '@deck.gl/layers' ; LayerRegistry . register ( { id : 'my-custom-layer' , name : 'Custom Events' , category : 'infrastructure' , defaultVisible : false , factory : ( data ) => new IconLayer ( { id : 'my-custom-layer-deck' , data , getPosition : d => [ d . lng , d . lat ] , getIcon : d => 'marker' , getSize : 32 , pickable : true , } ) , } ) ; Site Variant Configuration // src/variants/my-variant.ts import type { SiteVariant } from './types' ; export const myVariant : SiteVariant = { id : 'my-variant' , name : 'My Monitor' , title : 'My Custom Monitor' , defaultCategories : [ 'geopolitics' , 'economics' , 'military' ] , defaultRegion : 'Europe' , defaultLanguage : 'en' , mapStyle : 'dark' , enabledLayers : [ 'country-risk' , 'events' , 'supply-chains' ] , aiProvider : 'ollama' , theme : { primary : '#0891b2' , background : '#0f172a' , surface : '#1e293b' , } , } ; Troubleshooting Problem Solution Map not rendering Check VITE_MAPTILER_API_KEY or use free CartoBasemap style AI synthesis slow/failing Ensure Ollama is running: ollama serve && ollama pull llama3.2 Feeds returning 429 errors Enable Redis caching via UPSTASH_REDIS_REST_* env vars Desktop app won't build Ensure Rust + cargo install tauri-cli + platform build tools RTL layout broken Confirm lang attribute set on

<html> by setLanguage() TypeScript errors on build Run npm run typecheck — proto generated files must exist Redis connection refused Check REDIS_URL or use Upstash REST API instead of TCP npm run build:full fails mid-variant Build individually: npm run build -- --mode finance Ollama Setup for Local AI # Install Ollama curl -fsSL https://ollama.ai/install.sh | sh # Pull recommended model ollama pull llama3.2 # Fast, good quality ollama pull mistral # Alternative ollama pull gemma2:9b # Larger, higher quality # Verify Ollama is accessible curl http://localhost:11434/api/tags Verify Installation npm run typecheck # Should exit 0 npm run dev # Should open localhost:5173 # Navigate to /api/health for API status curl http://localhost:5173/api/health Resources Live App : worldmonitor.app Documentation : docs.worldmonitor.app Architecture : docs.worldmonitor.app/architecture Self-Hosting Guide : docs.worldmonitor.app/getting-started Contributing : docs.worldmonitor.app/contributing Security Policy : SECURITY.md License : AGPL-3.0 (non-commercial); commercial license required for SaaS/rebranding
返回排行榜