diff --git a/backend/main.py b/backend/main.py
index 88eb351..fd9c163 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -15,7 +15,7 @@ from dataclasses import dataclass, field
from typing import Any
from json import JSONDecodeError
-APP_VERSION = "0.9.81"
+APP_VERSION = "0.9.82"
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index 90f8244..c724510 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -7,7 +7,7 @@ py-modules = []
[project]
name = "backend"
-version = "0.9.81"
+version = "0.9.82"
requires-python = ">=3.10"
dependencies = [
"apscheduler==3.10.3",
@@ -55,7 +55,7 @@ dev = ["pytest>=9.0.3", "pytest-asyncio>=1.4.0", "ruff>=0.9.0", "black>=24.0.0"]
[tool.ruff.lint]
# The current backend carries historical style debt in large legacy modules.
-# Keep CI focused on actionable correctness checks for the v0.9.81 release.
+# Keep CI focused on actionable correctness checks for the v0.9.82 release.
ignore = ["E401", "E402", "E701", "E731", "E741", "F401", "F402", "F541", "F811", "F841"]
[tool.black]
diff --git a/backend/routers/ai_intel.py b/backend/routers/ai_intel.py
index c98087d..e380b6d 100644
--- a/backend/routers/ai_intel.py
+++ b/backend/routers/ai_intel.py
@@ -1590,7 +1590,7 @@ async def agent_tool_manifest(request: Request):
return {
"ok": True,
- "version": "0.9.81",
+ "version": "0.9.82",
"access_tier": access_tier,
"available_commands": available_commands,
"transport": {
@@ -2281,7 +2281,7 @@ async def api_capabilities(request: Request):
access_tier = str(get_settings().OPENCLAW_ACCESS_TIER or "restricted").strip().lower()
return {
"ok": True,
- "version": "0.9.81",
+ "version": "0.9.82",
"auth": {
"method": "HMAC-SHA256",
"headers": ["X-SB-Timestamp", "X-SB-Nonce", "X-SB-Signature"],
diff --git a/backend/routers/health.py b/backend/routers/health.py
index d11c983..c45e3e5 100644
--- a/backend/routers/health.py
+++ b/backend/routers/health.py
@@ -8,7 +8,7 @@ from services.data_fetcher import get_latest_data
from services.schemas import HealthResponse
import os
-APP_VERSION = os.environ.get("_HEALTH_APP_VERSION", "0.9.81")
+APP_VERSION = os.environ.get("_HEALTH_APP_VERSION", "0.9.82")
router = APIRouter()
diff --git a/backend/tests/test_per_operator_outbound_attribution.py b/backend/tests/test_per_operator_outbound_attribution.py
index d7285b3..36f0c0c 100644
--- a/backend/tests/test_per_operator_outbound_attribution.py
+++ b/backend/tests/test_per_operator_outbound_attribution.py
@@ -238,8 +238,8 @@ class TestNoMonsterUserAgentRemains:
"ShadowBroker/0.9.79 Finnhub connector",
"ShadowBroker/0.9.8 local Shodan connector",
"ShadowBroker/0.9.8 Finnhub connector",
- "ShadowBroker/0.9.81 local Shodan connector",
- "ShadowBroker/0.9.81 Finnhub connector",
+ "ShadowBroker/0.9.82 local Shodan connector",
+ "ShadowBroker/0.9.82 Finnhub connector",
"Mozilla/5.0 (compatible; ShadowBroker CCTV proxy)",
)
diff --git a/desktop-shell/package-lock.json b/desktop-shell/package-lock.json
index db194c5..ec57c3c 100644
--- a/desktop-shell/package-lock.json
+++ b/desktop-shell/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@shadowbroker/desktop-shell",
- "version": "0.9.81",
+ "version": "0.9.82",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@shadowbroker/desktop-shell",
- "version": "0.9.81",
+ "version": "0.9.82",
"devDependencies": {
"typescript": "^5.6.0"
}
diff --git a/desktop-shell/package.json b/desktop-shell/package.json
index 519e426..8bcc7b1 100644
--- a/desktop-shell/package.json
+++ b/desktop-shell/package.json
@@ -1,6 +1,6 @@
{
"name": "@shadowbroker/desktop-shell",
- "version": "0.9.81",
+ "version": "0.9.82",
"private": true,
"description": "ShadowBroker desktop shell packaging, runtime bridge, and release tooling",
"scripts": {
diff --git a/desktop-shell/tauri-skeleton/src-tauri/Cargo.lock b/desktop-shell/tauri-skeleton/src-tauri/Cargo.lock
index d37be8c..9e38612 100644
--- a/desktop-shell/tauri-skeleton/src-tauri/Cargo.lock
+++ b/desktop-shell/tauri-skeleton/src-tauri/Cargo.lock
@@ -4201,7 +4201,7 @@ dependencies = [
[[package]]
name = "shadowbroker-tauri-shell"
-version = "0.9.81"
+version = "0.9.82"
dependencies = [
"axum",
"base64 0.22.1",
diff --git a/desktop-shell/tauri-skeleton/src-tauri/Cargo.toml b/desktop-shell/tauri-skeleton/src-tauri/Cargo.toml
index dc18274..fe544a0 100644
--- a/desktop-shell/tauri-skeleton/src-tauri/Cargo.toml
+++ b/desktop-shell/tauri-skeleton/src-tauri/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "shadowbroker-tauri-shell"
-version = "0.9.81"
+version = "0.9.82"
edition = "2021"
[build-dependencies]
diff --git a/desktop-shell/tauri-skeleton/src-tauri/tauri.conf.json b/desktop-shell/tauri-skeleton/src-tauri/tauri.conf.json
index b2f0af8..3d6f83a 100644
--- a/desktop-shell/tauri-skeleton/src-tauri/tauri.conf.json
+++ b/desktop-shell/tauri-skeleton/src-tauri/tauri.conf.json
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "ShadowBroker",
- "version": "0.9.81",
+ "version": "0.9.82",
"identifier": "com.shadowbroker.desktop",
"build": {
"frontendDist": "../../../frontend/out",
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 20a4800..c11327d 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "frontend",
- "version": "0.9.81",
+ "version": "0.9.82",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "frontend",
- "version": "0.9.81",
+ "version": "0.9.82",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0",
"@tauri-apps/plugin-process": "^2.3.1",
diff --git a/frontend/package.json b/frontend/package.json
index 8905e99..0c4772f 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "frontend",
- "version": "0.9.81",
+ "version": "0.9.82",
"private": true,
"scripts": {
"dev": "node scripts/dev-all.cjs",
diff --git a/frontend/src/__tests__/desktop/updateRuntime.test.ts b/frontend/src/__tests__/desktop/updateRuntime.test.ts
index f0c5c05..5222d1f 100644
--- a/frontend/src/__tests__/desktop/updateRuntime.test.ts
+++ b/frontend/src/__tests__/desktop/updateRuntime.test.ts
@@ -9,12 +9,12 @@ import {
} from '@/lib/updateRuntime';
const RELEASE: GitHubLatestRelease = {
- html_url: 'https://github.com/BigBodyCobain/Shadowbroker/releases/tag/v0.9.81',
+ html_url: 'https://github.com/BigBodyCobain/Shadowbroker/releases/tag/v0.9.82',
assets: [
- { name: 'ShadowBroker_0.9.81_x64_en-US.msi', browser_download_url: 'https://example.test/windows.msi' },
- { name: 'ShadowBroker_0.9.81_x64-setup.exe', browser_download_url: 'https://example.test/windows-setup.exe' },
- { name: 'ShadowBroker_0.9.81_aarch64.dmg', browser_download_url: 'https://example.test/macos.dmg' },
- { name: 'ShadowBroker_0.9.81_amd64.AppImage', browser_download_url: 'https://example.test/linux.AppImage' },
+ { name: 'ShadowBroker_0.9.82_x64_en-US.msi', browser_download_url: 'https://example.test/windows.msi' },
+ { name: 'ShadowBroker_0.9.82_x64-setup.exe', browser_download_url: 'https://example.test/windows-setup.exe' },
+ { name: 'ShadowBroker_0.9.82_aarch64.dmg', browser_download_url: 'https://example.test/macos.dmg' },
+ { name: 'ShadowBroker_0.9.82_amd64.AppImage', browser_download_url: 'https://example.test/linux.AppImage' },
],
};
diff --git a/frontend/src/components/ChangelogModal.tsx b/frontend/src/components/ChangelogModal.tsx
index cfb3d5f..0f635d1 100644
--- a/frontend/src/components/ChangelogModal.tsx
+++ b/frontend/src/components/ChangelogModal.tsx
@@ -4,101 +4,108 @@ import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
X,
- Terminal,
Bot,
Network,
- Scale,
KeyRound,
- Cpu,
- Layers,
- GitBranch,
Shield,
Plane,
- Clock,
- Satellite,
Bug,
Heart,
+ MessageSquare,
+ Radar,
+ Factory,
+ Anchor,
+ Search,
} from 'lucide-react';
-const CURRENT_VERSION = '0.9.81';
+const CURRENT_VERSION = '0.9.82';
const STORAGE_KEY = `shadowbroker_changelog_v${CURRENT_VERSION}`;
-const RELEASE_TITLE = 'Signed Auto-Update + Update Button Race Fix';
+const RELEASE_TITLE = 'Telegram OSINT + Osiris Intel Ports + OpenClaw Recon';
const HEADLINE_FEATURES = [
{
- icon: ,
+ icon: ,
+ accent: 'cyan' as const,
+ title: 'Telegram OSINT Map Layer',
+ subtitle:
+ 'Public war/conflict Telegram channels scraped hourly, risk-scored, geoparsed to metro anchors, and plotted as clickable map pins with inline photo/video.',
+ details: [
+ 'Incremental merge — only new posts are fetched; known links stop the parser early so channels are not re-scraped redundantly.',
+ 'Metro-anchor geocoding (Tel Aviv, Kyiv, NYC, Beijing, etc.) keeps Telegram pins off news/threat-alert centroids so pins stay clickable above the threat intercept overlays.',
+ 'Threat-intercept styled popups with inline media via `/api/telegram/media` proxy. Configure channels via `TELEGRAM_OSINT_CHANNELS` (see `.env.example`).',
+ ],
+ callToAction: 'TOGGLE TELEGRAM OSINT IN DATA LAYERS',
+ },
+ {
+ icon: ,
accent: 'purple' as const,
- title: 'Signed Auto-Update Going Forward (one manual hop)',
- subtitle: 'After installing v0.9.81, the in-app Update button finally works end-to-end. This release establishes a fresh signing key — every release from here is a one-click upgrade.',
+ title: 'Osiris-Derived Intel Ports (Recon, SCM, Entity Graph)',
+ subtitle:
+ 'Server-side recon toolkit, supply-chain risk overlay, entity relationship graphs, malware/C2 hotspots, CISA KEV cyber feed, sanctions index, and submarine cable routes — all SSRF-guarded and local-operator proxied.',
details: [
- 'tauri.conf.json now carries a fresh minisign pubkey (the previous keypair was generated before v0.9.79 shipped but the matching private key was lost before any release was actually signed, so no release before v0.9.81 has working auto-update).',
- 'The v0.9.81 release artifacts ship with a signed latest.json + .sig files so every install on v0.9.81 or later can verify and apply the next release automatically via the Tauri updater plugin.',
- 'One-time cost: if you are upgrading from v0.9.79 or v0.9.8, the click-Update path falls back to a manual download because the new pubkey does not match the one baked into your install. Click the MANUAL DOWNLOAD button in the update dialog → grab the .msi from the release page → run it → from then on auto-update works in-app.',
+ 'Recon Toolkit panel: IP geolocation, DNS, WHOIS, certs, BGP/ASN, OFAC sanctions, CVE, MAC vendor, GitHub profile, breach checks, and InternetDB subnet sweeps.',
+ 'SCM panel cross-references Tier 1/2 fabs (TSMC, Samsung, CATL, etc.) against earthquakes, wildfires, and GDELT conflict proximity.',
+ 'Entity Graph expands aircraft, vessels, companies, persons, IPs, and countries via Wikidata + OFAC + live telemetry store. Attribution: `backend/third_party/osiris/NOTICE.md`.',
+ 'Malware C2 (abuse.ch Feodo + URLhaus) and Cyber Threats (CISA KEV) layers opt-in on the slow tier. Submarine cables overlay from static TeleGeography-derived GeoJSON.',
],
- callToAction: 'CLICK UPDATE → DOWNLOAD MSI ONCE → AUTO-UPDATE FOREVER',
+ callToAction: 'OPEN RECON • SCM • ENTITY GRAPH IN LEFT SIDEBAR',
},
{
- icon: ,
+ icon: ,
accent: 'cyan' as const,
- title: 'AIS Maritime Resilience — Outage Banner + AISHub Fallback',
- subtitle: 'When AISStream’s WebSocket goes offline (as happened upstream in May 2026), the ships layer no longer goes silently empty.',
+ title: 'OpenClaw Agent — Full Telemetry + Recon Parity',
+ subtitle:
+ 'AI agents on the HMAC command channel now search, slice, and investigate the same data the operator sees — including Telegram, malware, cyber, SCM, and the full recon toolkit.',
details: [
- 'AIS proxy health surfaces in /api/health: connected, last_msg_age_seconds, proxy_spawn_count. A dismissible amber banner explains the outage (“Ship data temporarily unavailable — AISStream upstream is offline”) instead of letting users assume their install is broken.',
- 'AISHub REST fallback (free tier at aishub.net/api). Polls every 20 minutes when the primary is disconnected and merges vessels into the same store with source: “aishub” so existing tooling attributes the provider.',
- 'Live data wins races: if the WebSocket reconnects mid-poll, fresh AISStream updates aren’t overwritten by stale REST records. Opt-in via AISHUB_USERNAME; cadence configurable via AISHUB_POLL_INTERVAL_MINUTES (clamped [1, 360]).',
+ '`search_telemetry` and `search_news` index Telegram OSINT posts alongside news, GDELT, and CrowdThreat. `get_slow_telemetry` and `get_layer_slice` include `telegram_osint`, `malware_threats`, `cyber_threats`, and `scm_suppliers`.',
+ 'New commands: `osint_lookup` (IP/DNS/WHOIS/sanctions/CVE/etc.), `entity_expand` (relationship graph), `osint_tools` (discovery), and `osint_sweep` (subnet scan — full access tier).',
+ 'Layer aliases: `telegram`, `malware`/`botnet`, `cyber`/`cisa`/`kev`, `scm`/`suppliers`, `gfw`/`fishing`. Skill package: `openclaw-skills/shadowbroker/SKILL.md`.',
],
- callToAction: 'SET AISHUB_USERNAME \u2192 RESTART BACKEND',
- },
- {
- icon: ,
- accent: 'cyan' as const,
- title: 'Data-Layer Repair \u2014 UAP Cutoff + GPS Jamming Detection',
- subtitle: 'Two long-broken layers fixed at the source. UFO sightings are actually recent now; GPS jamming zones actually fire.',
- details: [
- 'UAP sightings: the Hugging Face NUFORC mirror fallback had no date cutoff, so when the live nuforc.org scrape failed the layer served 3-year-old reports as \u201crecent\u201d. Now drops rows older than 60 days and logs loudly when the mirror is fully stale. Scheduler moved daily \u2192 weekly (Mondays 12:00 UTC).',
- 'GPS jamming: three stacked filters meant the layer almost never lit up. nac_p == 0 (\u201cGPS lock lost\u201d) was filtered out as if it were an old transponder \u2014 it\u2019s actually the strongest jamming signal. Now counted. MIN_AIRCRAFT lowered 5 \u2192 3 so sparser hotspots clear; MIN_RATIO lowered 0.30 \u2192 0.20.',
- 'Both layers now surface their own outages via assert_canary so operators see broken vs empty, not silently stale.',
- ],
- callToAction: 'TOGGLE UAP \u2022 GPS JAMMING LAYERS',
+ callToAction: 'AI INTEL PANEL → CONNECT AGENT → COPY HMAC SECRET',
},
];
const NEW_FEATURES = [
{
- icon: ,
- title: 'Cumulative Fuel & CO2 per Flight',
- desc: 'Aircraft tooltip now shows how much fuel each plane has actually burned in the air since first observation, not just the per-hour rate. 15-minute gap between sightings resets the session; 24-hour clamp protects against clock skew; per-icao prune every 5 minutes keeps memory bounded.',
+ icon: ,
+ title: 'Global Fishing Watch in Settings',
+ desc: 'GFW API token exposed in onboarding and Settings → Maritime. Fishing activity layer backed by GFW when `GFW_API_TOKEN` is configured.',
},
{
- icon: ,
- title: 'Per-Flight Source Attribution',
- desc: 'Every aircraft record now carries a source field (adsb.lol, OpenSky, airplanes.live, adsb.fi) so consumers can attribute the data provider. Pre-fix, adsb.lol records were unmarked while OpenSky records were explicitly tagged, making it look like adsb.lol was unused even though it is the primary source.',
+ icon: ,
+ title: 'Supply-Chain Risk Map Layer',
+ desc: 'SCM suppliers render as map markers with seismic, wildfire, and conflict proximity scoring. Panel alerts for CRITICAL/HIGH fabs.',
},
{
- icon: ,
- title: 'Cross-Node DM Mailbox Replication',
- desc: 'Direct messages now replicate across mesh nodes when one party is offline. Per-(sender, recipient) anti-spam cap enforced as a network rule (not client-side) so source-code tampering cannot bypass it.',
+ icon: ,
+ title: 'Malware C2 + CISA KEV Overlays',
+ desc: 'abuse.ch botnet C2 and URLhaus distribution URLs geolocated by country; CISA Known Exploited Vulnerabilities surfaced in cyber threats feed and slow-tier payload.',
},
{
- icon: ,
- title: 'Infonet Sync — HTTP 429 Honored',
- desc: 'When an upstream peer returns Retry-After, the node now waits exactly that long instead of retrying every 60 seconds and keeping the upstream rate-limit bucket permanently full. Exponential backoff on consecutive failures capped at 30 minutes.',
+ icon: ,
+ title: 'OpenClaw Compact Search Path',
+ desc: 'Agents prefer `get_summary` → SSE `layer_changed` → `get_layer_slice` with per-layer versions. `brief_area`, `correlate_entity`, and `entities_near` include Telegram and malware context.',
+ },
+ {
+ icon: ,
+ title: 'Submarine Cable Overlay',
+ desc: 'Opt-in undersea cable routes from static TeleGeography-derived GeoJSON for infrastructure context on the map.',
},
];
const BUG_FIXES = [
- 'Update button no longer throws "admin_session_required" on desktop installs. The initial updateAction now syncs to Tauri detection at React-init time (window.__TAURI__ is injected before mount), so a click before the async runtime probe completes opens the GitHub release page in a browser instead of POSTing to /api/system/update.',
- 'Desktop installer now bundles defusedxml + PySocks (declared in pyproject.toml but missing from the venv shipped with v0.9.79 and the initial v0.9.8 publish). Fixes the bundled-backend launch crash reported in #319 and #296 (managed_backend_exited_early:exit code: 103).',
- 'UAP layer no longer serves 3-year-old NUFORC sightings via the Hugging Face static-mirror fallback (60-day cutoff now applied to the fallback path too).',
- 'GPS jamming detection now counts nac_p == 0 (the actual GPS-lost signal) instead of filtering it out as an old-transponder artifact.',
- 'GPS jamming thresholds lowered (MIN_AIRCRAFT 5 → 3, MIN_RATIO 0.30 → 0.20) so sparser hotspots clear the bar without losing the 1-aircraft noise cushion.',
- 'AIS layer surfaces an outage banner when the AISStream WebSocket upstream is offline, instead of silently showing an empty ocean.',
- 'Flight emissions tooltip now shows cumulative fuel/CO2 since first observation, not just the per-hour rate.',
- 'Per-aircraft observation tracker (15-min reopen gap, 24-hour clamp) survives trail-rendering cache pruning so cumulative counters do not reset mid-flight.',
- 'UAP scheduler moved daily → weekly (Mondays 12:00 UTC) to match the layer’s rolling-window cadence and reduce upstream load.',
+ 'Telegram map pins are now HTML markers above threat-alert overlays — pins are clickable even when sharing a city grid with news intercept boxes.',
+ 'Telegram geocoding uses metro anchors (not national centroids) and a small NE offset only when news alerts share the same city cell — pins stay on land.',
+ 'Hourly Telegram scheduler with incremental post merge — no redundant full-channel re-scrape every cycle.',
+ 'OpenClaw `get_slow_telemetry` previously omitted telegram_osint, malware_threats, cyber_threats, and scm_suppliers — now included in slow-tier and universal search.',
+ 'OpenClaw agents can invoke the Recon panel backends via `osint_lookup` without raw `/api/osint/*` HTTP calls or local-operator browser auth.',
];
const CONTRIBUTORS = [
+ {
+ name: 'OSIRIS (simplifaisoul/osiris)',
+ desc: 'MIT-licensed recon stack — adapted for ShadowBroker proxy model (see backend/third_party/osiris/NOTICE.md)',
+ },
{
name: '@Alienmajik',
desc: 'Raspberry Pi 5 support — ARM64 packaging, headless deployment notes, and runtime tuning for Pi-class hardware',
@@ -135,53 +142,13 @@ const CONTRIBUTORS = [
},
{
name: '@suranyami',
- desc: 'Parallel multi-arch Docker builds (11min \u2192 3min) + runtime BACKEND_URL fix',
+ desc: 'Parallel multi-arch Docker builds (11min → 3min) + runtime BACKEND_URL fix',
pr: '#35, #44',
},
{
name: '@chr0n1x',
desc: 'Kubernetes / Helm chart architecture for high-availability deployments',
},
- {
- name: '@johan-martensson',
- desc: 'COSMO-SkyMed satellite classification fix + yfinance batch download optimization',
- pr: '#96, #98',
- },
- {
- name: '@singularfailure',
- desc: 'Spanish CCTV feeds + image loading fix',
- pr: '#93',
- },
- {
- name: '@smithbh',
- desc: 'Makefile-based taskrunner with LAN/local access options',
- pr: '#103',
- },
- {
- name: '@OrfeoTerkuci',
- desc: 'UV project management setup',
- pr: '#102',
- },
- {
- name: '@deuza',
- desc: 'dos2unix fix for Mac/Linux quick start',
- pr: '#101',
- },
- {
- name: '@tm-const',
- desc: 'CI/CD workflow updates',
- pr: '#108, #109',
- },
- {
- name: '@Elhard1',
- desc: 'start.sh shell script fix',
- pr: '#111',
- },
- {
- name: '@ttulttul',
- desc: 'Podman compose support + frontend production CSS fix',
- pr: '#23',
- },
];
export function useChangelog() {
@@ -252,7 +219,6 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
{/* Content */}
- {/* === HEADLINE PAIR: OpenClaw API + InfoNet === */}
{HEADLINE_FEATURES.map((h, idx) => {
const isPurple = h.accent === 'purple';
const cardClass = isPurple
@@ -292,23 +258,6 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
))}
- {!isPurple && (
-
-
!!
-
-
- EXPERIMENTAL TESTNET — NO PRIVACY GUARANTEE
-
-
- InfoNet messages are obfuscated but NOT encrypted end-to-end. The Mesh
- network (Meshtastic/APRS) is NOT private — radio transmissions are
- inherently public. The privacy primitive contracts are scaffolded but not
- yet wired. Treat all channels as open and public for now.
-
-
-
- )}
-
{h.callToAction}
@@ -316,7 +265,22 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
);
})}
- {/* === Required-config callout: OpenSky API === */}
+ {/* Auto-update note for v0.9.81+ installs */}
+
+
+
+
+ One-click update from v0.9.81
+
+
+ If you installed v0.9.81, the in-app Update button verifies this release via the
+ signed Tauri updater (`latest.json` + minisign). Desktop installs on v0.9.81 or
+ later should auto-apply v0.9.82 without a manual MSI hop.
+
+
+
+
+ {/* Required-config callout: OpenSky API */}
@@ -324,8 +288,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
Required: OpenSky API credentials for airplane telemetry
- Airplane telemetry now requires an OpenSky Network OAuth2 client. Set{' '}
-
OPENSKY_CLIENT_ID and{' '}
+ Set
OPENSKY_CLIENT_ID and{' '}
OPENSKY_CLIENT_SECRET in your{' '}
.env. Free registration:{' '}
opensky-network.org/register
- . Without these the flights layer falls back to ADS-B-only coverage with
- significant gaps in Africa, Asia, and Latin America, and the startup environment
- check will surface a critical warning.
+ .
- {/* === Other New Features === */}
+ {/* Other New Features */}
@@ -391,7 +352,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
- COMMUNITY CONTRIBUTORS
+ CREDITS & CONTRIBUTORS
{CONTRIBUTORS.map((c, i) => (
@@ -399,9 +360,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
key={i}
className="flex items-start gap-2 px-3 py-2 border border-pink-500/20 bg-pink-500/5"
>
-
- ♥
-
+
♥
{c.name}
diff --git a/frontend/src/components/StartupWarmupModal.tsx b/frontend/src/components/StartupWarmupModal.tsx
index c41faf8..4eecd1e 100644
--- a/frontend/src/components/StartupWarmupModal.tsx
+++ b/frontend/src/components/StartupWarmupModal.tsx
@@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Database, Clock, X } from 'lucide-react';
-const CURRENT_VERSION = '0.9.81';
+const CURRENT_VERSION = '0.9.82';
const STORAGE_KEY = `shadowbroker_startup_warmup_notice_v${CURRENT_VERSION}`;
interface StartupWarmupModalProps {
diff --git a/helm/chart/Chart.yaml b/helm/chart/Chart.yaml
index 1bffe2e..dee89bb 100644
--- a/helm/chart/Chart.yaml
+++ b/helm/chart/Chart.yaml
@@ -1,8 +1,8 @@
---
apiVersion: v2
name: shadowbroker
-version: 0.9.81
-appVersion: "0.9.81"
+version: 0.9.82
+appVersion: "0.9.82"
description: simple shadowbroker installation
type: application
diff --git a/pyproject.toml b/pyproject.toml
index 125908d..a6433fe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "shadowbroker"
-version = "0.9.81"
+version = "0.9.82"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
diff --git a/uv.lock b/uv.lock
index 6411efe..756a988 100644
--- a/uv.lock
+++ b/uv.lock
@@ -104,7 +104,7 @@ wheels = [
[[package]]
name = "backend"
-version = "0.9.81"
+version = "0.9.82"
source = { editable = "backend" }
dependencies = [
{ name = "apscheduler" },
@@ -3052,7 +3052,7 @@ wheels = [
[[package]]
name = "shadowbroker"
-version = "0.9.81"
+version = "0.9.82"
source = { virtual = "." }
[package.metadata]