Commit Graph

79 Commits

Author SHA1 Message Date
Elie Habib
6271fafd40 feat(live): custom channel management with review fixes (#282)
* feat(live): custom channel management — add/remove/reorder, standalone window, i18n

- Standalone channel management window (?live-channels=1) with list, add form, restore defaults
- LIVE panel: gear icon opens channel management; channel tabs reorderable via DnD
- Row click to edit; custom modal for delete confirmation (no window.confirm)
- i18n for all locales (manage, addChannel, youtubeHandle, displayName, etc.)
- UI: margin between channel list and add form in management window
- settings-window: panel display settings comment in English

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(tauri): channel management in desktop app, dev base_url fix

- Add live-channels.html and live-channels-main.ts for standalone window
- Tauri: open_live_channels_window_command, close_live_channels_window, open live-channels window (WebviewUrl::App or External from base_url)
- LiveNewsPanel: in desktop runtime invoke Tauri command with base_url (window.location.origin) so dev works when Vite runs on a different port than devUrl
- Vite: add liveChannels entry to build input
- capabilities: add live-channels window
- tauri.conf: devUrl 3000 to match vite server.port
- docs: PR_LIVE_CHANNEL_MANAGEMENT.md for PR #276

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: address review issues in live channel management PR

- Revert settings button to open modal (not window.open popup)
- Revert devUrl from localhost:3000 to localhost:5173
- Guard activeChannel against empty channels (fall back to defaults)
- Escape i18n strings in innerHTML with escapeHtml() to prevent XSS
- Only store displayNameOverrides for actually renamed channels
- Use URL constructor for live-channels window URL
- Add CSP meta tag to live-channels.html
- Remove unused i18n keys (edit, editMode, done) from all locales
- Remove unused CSS classes (live-news-manage-btn/panel/wrap)
- Delete PR instruction doc (PR_LIVE_CHANNEL_MANAGEMENT.md)

---------

Co-authored-by: Masaki <yukkurihakutaku@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 22:51:44 +00:00
Elie Habib
a37dced84e fix: circuit breaker persistent cache with safety fixes (#281)
* fix: persist circuit breaker cache to IndexedDB across page reloads

On page reload, all 28+ circuit breaker in-memory caches are lost,
triggering 20-30 simultaneous POST requests to Vercel edge functions.

Wire the existing persistent-cache.ts (IndexedDB + localStorage +
Tauri fallback) into CircuitBreaker so every breaker automatically:

- Hydrates from IndexedDB on first execute() call (~1-5ms read)
- Writes to IndexedDB fire-and-forget on every recordSuccess()
- Falls back to stale persistent data on network failure
- Auto-disables for breakers with cacheTtlMs=0 (live pricing)

Zero consumer code changes -- all 28+ breaker call sites untouched.
Reloads within the cache TTL (default 10min) serve instantly from
IndexedDB with zero network calls.

Also adds deletePersistentCache() to persistent-cache.ts for clean
cache invalidation via clearCache().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add Playwright e2e tests for circuit breaker persistent cache

7 tests covering: IndexedDB persistence on success, hydration on new
instance, TTL expiry forcing fresh fetch, 24h stale ceiling rejection,
clearCache cleanup, cacheTtlMs=0 auto-disable, and network failure
fallback to stale persistent data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: desktop cache deletion + clearCache race condition

P1: deletePersistentCache sent empty string to write_cache_entry,
which fails Rust's serde_json::from_str (not valid JSON). Add
dedicated delete_cache_entry Tauri command that removes the key
from the in-memory HashMap and flushes to disk.

P2: clearCache() set persistentLoaded=false, allowing a concurrent
execute() to re-hydrate stale data from IndexedDB before the async
delete completed. Remove the reset — after explicit clear there is
no reason to re-hydrate from persistent storage.

* fix: default persistCache to false, fix falsy data guard

P1b: 6 breakers store Date objects (weather, aviation, ACLED,
military-flights, military-vessels, GDACS) which become strings
after JSON round-trip. Callers like MapPopup.getTimeUntil() call
date.getTime() on hydrated strings → TypeError. Change default
to false (opt-in) so persistence requires explicit confirmation
that the payload is JSON-safe.

P2: `if (!entry?.data) return` drops valid falsy payloads (0,
false, empty string). Use explicit null/undefined check instead.

* fix: address blocking review issues on circuit breaker persistence

- clearCache() nulls persistentLoadPromise to orphan in-flight hydration
- delete_cache_entry defers disk flush to exit handler (avoids 14MB sync write)
- hydratePersistentCache checks TTL before setting lastDataState to 'cached'
- deletePersistentCache resets cacheDbPromise on IDB error + logs warning
- hydration catch logs warning instead of silently swallowing
- deletePersistentCache respects isStorageQuotaExceeded() for localStorage

---------

Co-authored-by: Elias El Khoury <efk@anghami.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 22:35:45 +00:00
Elie Habib
eafc4cb955 chore: bump version to 2.5.6 with changelog (#272) 2026-02-23 18:50:43 +00:00
Elie Habib
f06acd3c88 Fix GLib symbol mismatch when running as AppImage on newer distros (#263)
* fix: resolve AppImage crash on Ubuntu 25.10+ (GLib symbol mismatch)

The AppImage bundles GLib from the build system, but host GIO modules
(e.g. GVFS libgvfsdbus.so) compiled against a newer GLib reference
symbols like g_task_set_static_name that don't exist in the older
bundled copy, causing "undefined symbol" errors and WebKit crashes.

Set GIO_MODULE_DIR="" when running as AppImage to prevent host GIO
modules from loading against the incompatible bundled GLib. GVFS
features (network mounts, trash, MTP) are unused by this app.

Note: the CI should also be upgraded from ubuntu-22.04 to ubuntu-24.04
in .github/workflows/build-desktop.yml to ship GLib 2.80+ and extend
forward-compatibility. This requires workflows permission to push.

https://claude.ai/code/session_01J8HBrfb26GJm22MFCeGoAA

* fix(appimage): keep bundled GIO modules for Ubuntu 25.10

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 17:07:37 +00:00
Elie Habib
080f49b0b2 fix: allow http:// origin from tauri.localhost for Windows CORS (#262)
On Windows, Tauri webviews send requests with origin
`http://tauri.localhost` (HTTP), but the CORS allowlist only permitted
`https://tauri.localhost` (HTTPS). This caused every sidecar API
request to be blocked by CORS, making the app non-functional on
Windows with a "sidecar not reachable" error.

Change the regex from `^https:` to `^https?:` so both HTTP and HTTPS
origins from tauri.localhost are accepted.

https://claude.ai/code/session_016XMWtTPfE81bitu3QEoUwy

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 17:07:04 +00:00
Elie Habib
8504d5649a fix: layer help, SW ingest routing, toggle colors, v2.5.5 (#244)
* feat: make intelligence alert popup opt-in via dropdown toggle

Auto-popup was interrupting users every 10s refresh cycle. Badge still
counts and pulses silently. New toggle in dropdown (default OFF) lets
users explicitly opt in to auto-popup behavior.

* chore: bump version to 2.5.5

## Changelog

### Features
- Intelligence alert popup is now opt-in (default OFF) — badge counts silently, toggle in dropdown to enable auto-popup

### Bug Fixes
- Linux: disable DMA-BUF renderer on WebKitGTK to prevent blank white screen (NVIDIA/immutable distros)
- Linux: add DejaVu Sans Mono + Liberation Mono font fallbacks for monospace rendering
- Consolidate monospace font stacks into --font-mono CSS variable (fixes undefined var bug)
- Reduce dedup coordinate rounding from 0.5° to 0.1° (~10km precision)
- Vercel build: handle missing previous deploy SHA
- Panel base class: add missing showRetrying method
- Vercel ignoreCommand shortened to fit 256-char limit

### Infrastructure
- Upstash Redis shared caching for all RPC handlers + cache key contamination fix
- Format Rust code and fix Windows focus handling

### Docs
- Community guidelines: contributing, code of conduct, security policy
- Updated .env.example

* chore: track Cargo.lock for reproducible Rust builds

* fix: update layer help popup with all current map layers

Added missing layers to the ? help popup across all 3 variants:
- Full: UCDP Events, Displacement, Spaceports, Cyber Threats, Fires,
  Climate Anomalies, Critical Minerals; renamed Shipping→Ship Traffic
- Tech: Tech Events, Cyber Threats, Fires
- Finance: GCC Investments

* docs: update README with crypto prices, analytics, typography, and dedup grid fix

* fix: add /ingest to service worker NetworkOnly routes

The SW was intercepting PostHog /ingest/* requests and returning
no-response (404) because no cache match existed. Adding NetworkOnly
ensures analytics requests pass through to Vercel's rewrite proxy.

* chore: update Cargo.lock for v2.5.5

* fix: use explicit colors for findings toggle switch visibility
2026-02-23 08:01:46 +00:00
Elie Habib
d24d61f333 Fix Linux rendering issues and improve monospace font fallbacks (#243)
* fix: resolve AppImage blank white screen and font crash on Linux (#238)

Disable WebKitGTK DMA-BUF renderer by default on Linux to prevent blank
white screens caused by GPU buffer allocation failures (common with
NVIDIA drivers and immutable distros like Bazzite). Add Linux-native
monospace font fallbacks (DejaVu Sans Mono, Liberation Mono) to all font
stacks so WebKitGTK font resolution doesn't hit out-of-bounds vector
access when macOS-only fonts (SF Mono, Monaco) are unavailable.

https://claude.ai/code/session_01TF2NPgSSjgenmLT2XuR5b9

* fix: consolidate monospace font stacks into --font-mono variable

- Define --font-mono in :root (main.css) and .settings-shell (settings-window.css)
- Align font stack: SF Mono, Monaco, Cascadia Code, Fira Code, DejaVu Sans Mono, Liberation Mono
- Replace 3 hardcoded JetBrains Mono stacks with var(--font-mono)
- Replace 4 hardcoded settings-window stacks with var(--font-mono)
- Fix pre-existing bug: var(--font-mono) used in 4 places but never defined
- Match index.html skeleton font stack to --font-mono

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 07:16:48 +00:00
Elie Habib
63a4c9ab9c feat: Upstash Redis shared caching + cache key contamination fixes (#232)
* fix(sentry): add noise filters for 5 non-actionable error patterns

Filter dynamic import alt phrasing, script parse errors, maplibre
style/WebGL crashes, and CustomEvent promise rejections. Also fix
beforeSend to catch short Firefox null messages like "E is null".

* fix: cache write race, settings stale key status, yahoo gate concurrency

P1: Replace async background thread cache write with synchronous fs::write
to prevent out-of-order writes and dirty flag cleared before persistence.

P2: Add WorldMonitorTab.refresh() called after loadDesktopSecrets() so
the API key badge reflects actual keychain state.

P3: Replace timestamp-based Yahoo gate with promise queue to ensure
sequential execution under concurrent callers.

* feat: add Upstash Redis shared caching to all RPC handlers + fix cache key contamination

- Add Redis L2 cache (getCachedJson/setCachedJson) to 28 RPC handlers
  across all service domains (market, conflict, cyber, economic, etc.)
- Fix 10 P1 cache key contamination bugs where under-specified keys
  caused cross-request data pollution (e.g. filtered requests returning
  unfiltered cached data)
- Restructure list-internet-outages to cache-then-filter pattern so
  country/timeRange filters always apply after cache read
- Add write_lock mutex to PersistentCache in main.rs to prevent
  desktop cache write-race conditions
- Document FMP (Financial Modeling Prep) as Yahoo Finance fallback TODO
  in market/v1/_shared.ts

* fix: cache-key contamination and PizzINT/GDELT partial-failure regression

- tech-events: fetch with limit=0 and cache full result, apply limit
  slice after cache read to prevent low-limit requests poisoning cache
- pizzint: restore try-catch around PizzINT fetch so GDELT tension
  pairs are still returned when PizzINT API is down

* fix: remove extra closing brace in pizzint try-catch

* fix: recompute conferenceCount/mappableCount after limit slice

* fix: bypass WM API key gate for registration endpoint

/api/register-interest must reach cloud without a WorldMonitor API key,
otherwise desktop users can never register (circular dependency).
2026-02-23 10:09:12 +04:00
Elie Habib
8f8b0c843b Format Rust code and fix Windows focus handling (#242)
* chore: apply cargo fmt formatting to main.rs

Pure formatting normalization with no logic changes. Separated from
the behavioral fix to keep git blame clean.

https://claude.ai/code/session_01RPQ1PEqxTSEG6rB5XadzEz

* fix: restrict settings-window re-focus to macOS to avoid Windows focus churn

On Windows, the Focused(true) handler on the main window calls
show()+set_focus() on the settings window, which steals focus back,
retriggering the event in a tight loop and presenting as a UI hang.

Gate the match arm with #[cfg(target_os = "macos")] (compile-time
attribute) instead of cfg!() (runtime macro) to match the convention
used by the adjacent macOS-only handlers and eliminate dead code on
non-macOS builds entirely.

https://claude.ai/code/session_01RPQ1PEqxTSEG6rB5XadzEz

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 05:29:49 +00:00
Elie Habib
84f17e6c4c chore: bump version to 2.5.4
## Changelog

### Bug Fixes
- market: Fix price falsy bug (price of 0 treated as null)
- market: Per-symbol-set caching prevents stock/commodity data leakage
- market: Yahoo request gate (600ms) reduces IP-level rate limiting
- market: ETF panel 8s delayed fetch reduces Yahoo contention on startup
- ucdp: Clear circuit breaker cache on empty responses
- ucdp: Retry loop (3 attempts, 15s) for cold start resilience
- ucdp: Negative cache, version cache, stale-on-error fallback
- analytics: Proxy PostHog through own domain to bypass ad blockers
- settings: Skip API key re-verification when no keys changed
- csp: Allow PostHog scripts from us-assets.i.posthog.com
- api: Sanitize og-story level input
- api: Restore API-key gate on config import failure

### Features
- Cable health scoring via sebuf InfrastructureService
- PostHog analytics with privacy-first design

### i18n
- Cable health evidence key added to all locales
2026-02-22 09:17:18 +00:00
Elie Habib
e1b9e9e8a9 fix(csp): allow PostHog scripts from us-assets.i.posthog.com 2026-02-21 17:06:53 +00:00
Elie Habib
8699dae5e5 fix: registration via direct Convex call + compact WM tab layout
- Sidecar calls Convex HTTP API directly (Vercel Attack Challenge Mode
  blocks server-side proxy). CONVEX_URL read from env, not hardcoded.
- Rust injects CONVEX_URL into sidecar via option_env! (CI) / env var (dev)
- GitHub Actions passes CONVEX_URL secret to all 4 build steps
- Tighten WM tab CSS spacing so all content fits in one viewport
2026-02-21 11:36:03 +00:00
Elie Habib
1fc6dc2dbb fix: World Monitor tab first, registration proxy, empty key guard
- Move World Monitor tab to first position in settings.html
- Add registration proxy in sidecar to bypass Vercel bot protection
- Fix sidecar RSS/registration handlers to use response.text()
- Skip empty values in loadDesktopSecrets (NO LICENSE vs LICENSED)
- Add skip-setup text to desktop config alert panel
2026-02-21 11:09:18 +00:00
Elie Habib
68e6a367d6 feat: redesign settings World Monitor tab + sidecar RSS proxy + v2.5.3
Rebuild the World Monitor settings tab with hero banner, license key
input, waitlist registration, and BYOK footer. Only validate API key
panels that have pending changes on save. Add local RSS proxy handler
to sidecar so desktop fetches feeds directly without cloud fallback.
Bump version to 2.5.3.
2026-02-21 11:01:01 +00:00
Elie Habib
a388afe400 feat: API key gating for desktop cloud fallback + registration (#215)
* feat: API key gating for desktop cloud fallback + registration system

Gate desktop cloud fallback behind WORLDMONITOR_API_KEY — desktop users
need a valid key for cloud access, otherwise operate local-only (sidecar).
Add email registration system via Convex DB for future key distribution.

Client-side: installRuntimeFetchPatch() checks key presence before
allowing cloud fallback, with secretsReady promise + 2s timeout.
Server-side: origin-aware validation in sebuf gateway — desktop origins
require key, web origins pass through.

- Add WORLDMONITOR_API_KEY to 3-place secret system (Rust, TS, sidecar)
- New "World Monitor" settings tab with key input + registration form
- New api/_api-key.js server-side validation (origin-aware)
- New api/register-interest.js edge function with rate limiting
- Convex DB schema + mutation for email registration storage
- CORS headers updated for X-WorldMonitor-Key + Authorization
- E2E tests for key gate (blocked without key, allowed with key)
- Deployment docs (API_KEY_DEPLOYMENT.md) + updated desktop config docs

* fix: harden worldmonitor key + registration input handling

* fix: show invalid WorldMonitor API key status

* fix: simplify key validation, trim registration checks, add env example vars

- Inline getValidKeys() in _api-key.js
- Remove redundant type checks in register-interest.js
- Simplify WorldMonitorTab status to present/missing
- Add WORLDMONITOR_VALID_KEYS and CONVEX_URL to .env.example

* feat(sidecar): integrate proto gateway bundle into desktop build

The sidecar's buildRouteTable() only discovers .js files, so the proto
gateway at api/[domain]/v1/[rpc].ts was invisible — all 45 sebuf RPCs
returned 404 in the desktop app. Wire the existing build script into
Tauri's build commands and add esbuild as an explicit devDependency.
2026-02-21 10:36:23 +00:00
Lawyered
f082e09d55 fix(sidecar): preserve request body on cloud fallback (#209)
Cache inbound request body once so local handler dispatch and cloud fallback can both access the same payload. Adds regression coverage for POST fallback after a local non-OK response.
2026-02-21 04:10:53 +04:00
Lawyered
3bf4244cde fix(sidecar): preserve Request body semantics in ipv4 shim (#205)
* fix(sidecar): keep Request-body semantics in ipv4 fetch shim

* fix(sidecar): throw when Request body is already consumed
2026-02-21 04:09:26 +04:00
Elie Habib
48f8e24353 release: v2.5.2 — quota guard, map race fixes, Vercel build skip fix 2026-02-20 23:46:34 +00:00
Elie Habib
7440281d71 release: v2.5.1 — batch FRED, parallel UCDP, partial cache TTL, bot middleware 2026-02-20 15:07:11 +04:00
Elie Habib
6e9615f428 fix(sidecar): deduplicate Vary header tokens with appendVary helper
Replace naive string concatenation for Vary header with appendVary()
that parses existing tokens and deduplicates case-insensitively.
Prevents duplicate Vary tokens when both Origin and Accept-Encoding
are added.

Closes #170

Co-authored-by: Lawyered <4802498+lawyered0@users.noreply.github.com>
2026-02-20 09:21:36 +04:00
Elie Habib
2b7b35efd8 Add Brotli-first API compression for sidecar and nginx 2026-02-20 08:41:22 +04:00
Elie Habib
58389ba440 fix: sync Cargo.toml version to 2.5.0 (was missed in release commit) 2026-02-20 01:21:18 +04:00
Elie Habib
fce6c52970 release: v2.5.0 — Ollama/LM Studio local LLM support, settings tabs, keychain vault
- Ollama/LM Studio integration with auto model discovery and 4-tier fallback chain
- Settings window split into LLMs, API Keys, and Debug tabs
- Consolidated keychain vault (1 OS prompt instead of 20+)
- README expanded with privacy architecture, summarization chain docs
- CHANGELOG updated with full v2.5.0 release notes
- 5 new defense/intel RSS feeds, Koeberg nuclear plant added
2026-02-20 01:14:16 +04:00
Elie Habib
6c3d2770f7 feat: split settings into LLMs and API Keys tabs, fix keychain vault and Ollama UX
- Split settings window into 3 tabs: LLMs (Ollama/Groq/OpenRouter),
  API Keys (data feeds), and Debug & Logs
- Add featureFilter option to RuntimeConfigPanel for rendering subsets
- Consolidate keychain to single JSON vault entry (1 macOS prompt vs 20)
- Add Ollama model discovery with /api/tags + /v1/models fallback
- Strip <think> reasoning tokens from Ollama responses
- Suppress thinking with think:false in Ollama request body
- Parallel secret verification with 15s global timeout
- Fix manual model input overlapping dropdown (CSS grid-area + hidden-input class)
- Add loading spinners to settings tab panels
- Suppress notification popups when settings window is open
- Filter embed models from Ollama dropdown
- Fix settings window black screen flash with inline dark background
2026-02-20 00:02:48 +04:00
Elie Habib
1d1b1b209f fix: harden OpenAI-compatible endpoint flow for Ollama/LM Studio 2026-02-19 20:18:13 +04:00
Elie Habib
bb14f0e9a8 fix: resolve TS build errors and add missing Ollama keys to Rust keyring
- Use for...of entries() instead of index-based loops in summarization.ts
  to satisfy strict noUncheckedIndexedAccess (7 TS18048/TS2345 errors)
- Replace fragile API_PROVIDERS[1] with .find(p => p.name === groq)
- Add OLLAMA_API_URL and OLLAMA_MODEL to SUPPORTED_SECRET_KEYS in main.rs
  so keychain secrets are injected into sidecar on desktop startup
2026-02-19 19:33:40 +04:00
Claude
ba329e2a2a test: add Ollama provider tests across endpoint, sidecar, and chain layers
Three test files covering Ollama integration:

api/ollama-summarize.test.mjs (9 tests):
- Fallback signal when unconfigured, on API error, on empty response
- Success path with correct provider label and response shape
- Model selection via OLLAMA_MODEL env / default fallback
- Network error handling (ECONNREFUSED)
- Translate mode prompt verification

tests/summarization-chain.test.mjs (7 tests):
- Ollama success short-circuits chain (Groq never called)
- Ollama fail → Groq success fallback
- Full fallback when both unconfigured
- Provider label correctness for Ollama and Groq
- Uniform response shape across providers
- Identical fallback signal shapes

src-tauri/sidecar/local-api-server.test.mjs (8 new tests):
- OLLAMA_API_URL and OLLAMA_MODEL accepted via env-update allowlist
- Unknown keys rejected (403)
- Validation via /v1/models probe (reachable mock)
- Validation via /api/tags native fallback
- OLLAMA_MODEL pass-through validation
- Non-http protocol rejection (422)
- Auth-required behavior preserved with token

https://claude.ai/code/session_01AGg9fG6LZ8Y6XhvLszdfeY
2026-02-19 14:41:32 +00:00
Claude
3f5fa51f40 feat: add Ollama (OpenAI-compatible) local LLM summarization support
Add Ollama as the primary summarization provider for desktop builds,
sitting before Groq/OpenRouter in the fallback chain. This enables
fully local, unlimited LLM inference via Ollama's OpenAI-compatible
endpoint (/v1/chat/completions).

Changes across six layers:
- runtime-config: OLLAMA_API_URL + OLLAMA_MODEL secret keys, aiOllama
  feature toggle (default on), URL validation
- sidecar: allowlist + endpoint probe validation (tries /v1/models
  then /api/tags)
- api/ollama-summarize.js: new handler mirroring Groq/OpenRouter with
  shared Redis cache keys
- summarization.ts: tryOllama() + updated chain order in normal, beta,
  and translation paths (Ollama → Groq → OpenRouter → Browser T5)
- RuntimeConfigPanel: signup URLs + i18n help text for new keys
- desktop-readiness: aiOllama in key-backed features + readiness check

https://claude.ai/code/session_01AGg9fG6LZ8Y6XhvLszdfeY
2026-02-19 14:22:53 +00:00
Elie Habib
a851d5e8a1 release: v2.4.1 — README overhaul, sentry triage, ultra-wide layout
- Comprehensive README update: live webcams, ultra-wide layout, Linux
  AppImage, theme system, auto-updater, error tracking, responsive
  layout, virtual scrolling, 13 languages, and 8 new roadmap items
- Sentry triage: WORLDMONITOR-28 noise filter broadened for smart quotes
- Ultra-wide layout: CSS float L-shape for 2000px+ screens (#114)
- Version bump: 2.4.0 → 2.4.1
2026-02-19 08:31:35 +04:00
Elie Habib
f6e7bbbfbc chore: enforce desktop version sync 2026-02-19 07:53:15 +04:00
Elie Habib
179e9c1687 chore: bump version to 2.3.9 2026-02-18 08:16:36 +04:00
Elie Habib
a9f6909a20 fix(i18n): fix 5 P1/P2 bugs — timeAgo count, community widget, Linux AppImage, locale gaps, lang normalization
- Fix relative-time {{count}} placeholders in all 12 locales (5m ago, not m ago)
- Localize CommunityWidget: replace 3 hardcoded English strings with t() calls
- Add Linux AppImage to tech/finance Tauri configs, CI matrix (ubuntu-22.04), packaging scripts, and download-node.sh
- Fix language code normalization: add supportedLngs/nonExplicitSupportedLngs to i18next, normalize getCurrentLanguage()
- Translate ~240 untranslated English strings across 11 locale files (ru/ar/zh now 100% translated)
- Add components.community section to all 12 locales
- All 12 locales at 1130-key parity, 0 placeholder mismatches
2026-02-18 07:16:47 +04:00
Elie Habib
30be26e779 merge(main): update PR #86 and resolve merge conflicts 2026-02-17 20:58:31 +04:00
Elie Habib
fe3fe09c41 chore(release): bump version to 2.3.8 2026-02-17 20:14:16 +04:00
Elie Habib
116fc80fc7 Merge remote-tracking branch 'origin/main' into feature/finance-variant
# Conflicts:
#	index.html
#	src/components/DeckGLMap.ts
2026-02-17 09:37:47 +04:00
Elie Habib
65dea2e4f9 fix(desktop): batch keychain reads to reduce macOS password prompts
Add get_all_secrets command that reads all 18 keys in a single IPC call.
This triggers one Keychain prompt instead of 18 on fresh installs.
2026-02-17 00:24:44 +04:00
Elie Habib
88ad25cb93 release: v2.3.7
Full light mode theme, header dark/light toggle, desktop update checker,
bundled Node.js in installer, CORS fixes, and panel defaults update.
2026-02-16 23:56:28 +04:00
Elie Habib
c94ec0b4ad Adding Node in the Tauri Installer 2026-02-16 23:30:19 +04:00
Elie Habib
cccfdac0f9 feat(update): add desktop update check with architecture-aware download links 2026-02-16 23:13:10 +04:00
Elie Habib
60cec92a16 fix(windows): preserve UNC paths when sanitizing sidecar script path 2026-02-16 23:09:30 +04:00
Lib-LOCALE
95e51941dc fix(i18n): Replace remaining hardcoded strings with t() calls in 12 components
- StrategicPosturePanel: 25 strings (military units, tooltips, timer)
- App: 4 strings (GitHub link, pin map, filter, source counter)
- StatusPanel: 5 strings (system status, timestamps, storage)
- PizzIntIndicator: 3 strings + t() import (DEFCON, title, updated)
- PlaybackControl: 2 strings + t() import (toggle mode, LIVE)
- CountryBriefPage: 4 strings (share, print, export, source ref)
- DeckGLMap: 4 strings + t() import (zoom controls, layer guide)
- MonitorPanel: 2 strings (placeholder, no matches)
- TechEventsPanel: 4 strings (loading, empty, show on map, more info)
- TechReadinessPanel: 3 strings (internet, mobile, R&D tooltips)
- Removed deb from tauri.conf.json build targets
- Removed duplicate monitor key from en.json
2026-02-16 13:27:43 +01:00
Lib-LOCALE
00925011dc feat(i18n): Implement full internationalization support for 9 languages and add Linux AppImage config 2026-02-16 12:32:55 +01:00
Claude
01fb23df5c feat: add finance/trading variant with market-focused dashboard
Add a new 'finance' site variant (finance.worldmonitor.app) following the
same pattern as the existing tech variant. Includes:

- Finance-specific RSS feeds: markets, forex, bonds, commodities, crypto,
  central banks, economic data, IPOs/M&A, derivatives, fintech, regulation,
  institutional investors, and market analysis (all free/open RSS sources)
- Finance-focused panels with trading-themed labels (Market Headlines,
  Live Markets, Forex & Currencies, Fixed Income, etc.)
- Geographic data for stock exchanges (30+), financial centers (20+),
  central banks (14), and commodity hubs (10) worldwide
- Four new map layers: stockExchanges, financialCenters, centralBanks,
  commodityHubs with tier-based icons and zoom-dependent labels
- Map popup rendering for all finance marker types
- Variant switcher updated with FINANCE tab in header
- Search modal with finance-specific sources and icons
- Vite HTML variant plugin metadata for SEO
- Build scripts (dev:finance, build:finance, test:e2e:finance)
- Tauri desktop config for Finance Monitor app

https://claude.ai/code/session_01CCmkws2EYuUHjYDonzXEtY
2026-02-16 11:22:17 +01:00
Elie Habib
700132adad fix: hide node.exe console window on Windows & bump v2.3.6
Add CREATE_NO_WINDOW (0x08000000) creation flag to the sidecar
Command::new() spawn on Windows. Without this, node.exe inherits
a visible console window that overlays the Tauri GUI.
2026-02-16 09:00:16 +04:00
Elie Habib
46010c3911 feat: differentiated panel error messages & auto-hide desktop config (v2.3.5)
- Add Panel.showConfigError() with amber styling and desktop Settings link
- Propagate `skipped` flag from Finnhub and FIRMS API responses
- Show "API key not configured" on Markets/Heatmap/Commodities/FIRMS panels
  when sidecar returns skipped (missing API key)
- ETF, Stablecoin, MacroSignals panels detect upstream API unavailability
  and show retry message instead of generic "Failed to fetch"
- RuntimeConfigPanel auto-hides when all features are configured
- Bump version to 2.3.5
2026-02-16 08:51:47 +04:00
Elie Habib
7d3b600364 fix: strip UNC path prefix for Windows sidecar, set explicit CWD & bump v2.3.4
Tauri resource_dir() on Windows returns \\?\ extended-length paths that
Node.js module resolution cannot handle, causing EISDIR: lstat 'C:'.
Strip the prefix before passing to Node.js, set current_dir to the
sidecar directory, and add package.json with "type": "module" to prevent
ESM scope walk-up to drive root.
2026-02-16 00:47:02 +04:00
Elie Habib
f3581a5f9b fix: enable macOS Keychain backend for keyring crate & bump v2.3.3
keyring v3 ships with NO default platform backends — API keys were
stored in-memory only, lost on every app restart. Add apple-native
and windows-native features to use real OS credential stores.
2026-02-16 00:31:46 +04:00
Elie Habib
d3fb116e16 fix: harden settings key persistence with soft-pass verification & resilient keychain reads 2026-02-16 00:31:46 +04:00
Elie Habib
f3fddcb0e8 fix: settings UX — save verified keys, preserve inputs across renders, bump v2.3.2
- Save keys that pass verification even when others fail (was all-or-nothing)
- Capture un-blurred input values before render to prevent loss on checkbox toggle
- Fix missing isDisallowedOrigin import in PIZZINT endpoints
2026-02-15 23:33:19 +04:00
Elie Habib
a9b3582ae3 fix: harden sidecar verification, dedupe spikes, and bump v2.3.1 2026-02-15 22:57:09 +04:00