diff --git a/backend/data/release_digests.json b/backend/data/release_digests.json
index 89dcf60..d5261e2 100644
--- a/backend/data/release_digests.json
+++ b/backend/data/release_digests.json
@@ -56,5 +56,10 @@
"ShadowBroker_v0.9.83.zip": "53f56631731ad3cdc7be68df09bedd6570ed91ecda6fa57c39651098e15666c7",
"ShadowBroker_0.9.83_x64-setup.exe": "d62170af4b9df0b190832b7bb3ad6bfe8a7ac01472f2c7b39cf2a1b61edc7492",
"ShadowBroker_0.9.83_x64_en-US.msi": "b664cc0003a29f7ce88b04c2b425643dbe7ed897342fc6e9a2378bc1910c6850"
+ },
+ "v0.9.84": {
+ "ShadowBroker_v0.9.84.zip": "b9cf09754949febb85c9ea967e53c867627b85343b9391af1ff67eb8f129d479",
+ "ShadowBroker_0.9.84_x64-setup.exe": "37d5bcb087b7a669668b2eb85a37413242b4579efb4444a36df8f8515be4a5e4",
+ "ShadowBroker_0.9.84_x64_en-US.msi": "83edd9074469f034660d0ab81197c9a0bf3ba92b101693101217b2cd39444223"
}
}
diff --git a/backend/main.py b/backend/main.py
index 4166dbf..320e934 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.83"
+APP_VERSION = "0.9.84"
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index b280d6d..ec6be79 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -7,7 +7,7 @@ py-modules = []
[project]
name = "backend"
-version = "0.9.83"
+version = "0.9.84"
requires-python = ">=3.10"
dependencies = [
"apscheduler==3.10.3",
@@ -57,7 +57,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.83 release.
+# Keep CI focused on actionable correctness checks for the v0.9.84 release.
ignore = ["E401", "E402", "E701", "E731", "E741", "F401", "F402", "F541", "F811", "F841"]
[tool.black]
diff --git a/desktop-shell/package-lock.json b/desktop-shell/package-lock.json
index 51b26c6..38f03dd 100644
--- a/desktop-shell/package-lock.json
+++ b/desktop-shell/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@shadowbroker/desktop-shell",
- "version": "0.9.83",
+ "version": "0.9.84",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@shadowbroker/desktop-shell",
- "version": "0.9.83",
+ "version": "0.9.84",
"devDependencies": {
"typescript": "^5.6.0"
}
diff --git a/desktop-shell/package.json b/desktop-shell/package.json
index e9eea01..47a9fbd 100644
--- a/desktop-shell/package.json
+++ b/desktop-shell/package.json
@@ -1,6 +1,6 @@
{
"name": "@shadowbroker/desktop-shell",
- "version": "0.9.83",
+ "version": "0.9.84",
"private": true,
"description": "ShadowBroker desktop shell packaging, runtime bridge, and release tooling",
"scripts": {
diff --git a/desktop-shell/tauri-skeleton/scripts/write-release-manifest.cjs b/desktop-shell/tauri-skeleton/scripts/write-release-manifest.cjs
index 52c443e..105aac9 100644
--- a/desktop-shell/tauri-skeleton/scripts/write-release-manifest.cjs
+++ b/desktop-shell/tauri-skeleton/scripts/write-release-manifest.cjs
@@ -94,6 +94,11 @@ function writeUpdaterManifest(files) {
};
})
.filter(Boolean)
+ .filter((artifact) => {
+ const version = readReleaseVersion();
+ const versionToken = `_${version}_`;
+ return artifact.relativePath.includes(versionToken) || artifact.relativePath.includes(`_${version}.`);
+ })
.sort((a, b) => updaterArtifactPriority(a.relativePath) - updaterArtifactPriority(b.relativePath));
const platforms = {};
diff --git a/desktop-shell/tauri-skeleton/src-tauri/Cargo.lock b/desktop-shell/tauri-skeleton/src-tauri/Cargo.lock
index e3bf681..2ab2a83 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.83"
+version = "0.9.84"
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 c973467..fab6721 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.83"
+version = "0.9.84"
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 4ac09d5..d651fe8 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.83",
+ "version": "0.9.84",
"identifier": "com.shadowbroker.desktop",
"build": {
"frontendDist": "../../../frontend/out",
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 0468763..d707540 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "frontend",
- "version": "0.9.83",
+ "version": "0.9.84",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "frontend",
- "version": "0.9.83",
+ "version": "0.9.84",
"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 2be0acb..222b08c 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "frontend",
- "version": "0.9.83",
+ "version": "0.9.84",
"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 7858d63..fa14a9b 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.83',
+ html_url: 'https://github.com/BigBodyCobain/Shadowbroker/releases/tag/v0.9.84',
assets: [
- { name: 'ShadowBroker_0.9.83_x64_en-US.msi', browser_download_url: 'https://example.test/windows.msi' },
- { name: 'ShadowBroker_0.9.83_x64-setup.exe', browser_download_url: 'https://example.test/windows-setup.exe' },
- { name: 'ShadowBroker_0.9.83_aarch64.dmg', browser_download_url: 'https://example.test/macos.dmg' },
- { name: 'ShadowBroker_0.9.83_amd64.AppImage', browser_download_url: 'https://example.test/linux.AppImage' },
+ { name: 'ShadowBroker_0.9.84_x64_en-US.msi', browser_download_url: 'https://example.test/windows.msi' },
+ { name: 'ShadowBroker_0.9.84_x64-setup.exe', browser_download_url: 'https://example.test/windows-setup.exe' },
+ { name: 'ShadowBroker_0.9.84_aarch64.dmg', browser_download_url: 'https://example.test/macos.dmg' },
+ { name: 'ShadowBroker_0.9.84_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 c1eda38..6ddd21a 100644
--- a/frontend/src/components/ChangelogModal.tsx
+++ b/frontend/src/components/ChangelogModal.tsx
@@ -10,86 +10,100 @@ import {
Bug,
Heart,
MessageSquare,
- Lock,
- Users,
Radio,
+ Radar,
+ Plane,
+ Languages,
+ Layers,
+ Bot,
} from 'lucide-react';
-const CURRENT_VERSION = '0.9.83';
+const CURRENT_VERSION = '0.9.84';
const STORAGE_KEY = `shadowbroker_changelog_v${CURRENT_VERSION}`;
-const RELEASE_TITLE = 'Infonet Gate Messaging + DM Protocols Live';
+const RELEASE_TITLE = 'GT Analytics + Telegram Translate + Full Telemetry + Saved Layout';
const HEADLINE_FEATURES = [
{
- icon: ,
+ icon: ,
accent: 'purple' as const,
- title: 'Gate Messaging — End-to-End on the Hashchain',
+ title: 'GT Analytics & Strategic Risk Layer',
subtitle:
- 'Encrypted MLS gate rooms now carry live chat over your private Infonet hashchain. Messages replicate across participant nodes via swarm push/pull — only gate members can decrypt.',
+ 'OpenClaw-driven geopolitical analytics now power a Strategic Risk map layer — risk scoring, signal triage, and overlays wired into the dashboard (#392).',
details: [
- 'Gate messages append as signed `gate_message` events on each participant\'s private chain; peers sync ciphertext through the mesh without exposing room keys to outsiders.',
- 'Swarm replication keeps late joiners and offline nodes convergent — pull missing blocks, push new envelopes to known gate peers.',
- 'MLS group crypto (privacy-core) handles forward secrecy and membership changes; the UI surfaces delivery, key rotation, and compat approval when room epochs advance.',
+ 'GT analytics pipeline feeds live risk indicators onto the worldview map so operators can correlate OSINT feeds with strategic posture.',
+ 'OpenClaw integration exposes entity profile and trail views for agent-assisted analysis without leaving the command surface.',
+ 'Layer toggles, scoring thresholds, and panel state persist across refreshes via the new dashboard preferences store.',
],
- callToAction: 'MESH CHAT → GATES → CREATE OR JOIN A ROOM',
+ callToAction: 'LEFT PANEL → LAYERS → STRATEGIC RISK',
},
{
icon: ,
accent: 'cyan' as const,
- title: 'Direct Messages — Short Address, Request, Encrypt',
+ title: 'Telegram OSINT Auto-Translate',
subtitle:
- 'DMs are fully operational over the wormhole/Tor lane: share your short wormhole address out-of-band, accept a contact request, then exchange ratchet-encrypted messages.',
+ 'Telegram posts in map popups now auto-translate with source-language labels — Persian (fa) joins English, French, and Chinese.',
details: [
- 'Contact flow: outbound request → peer approve/deny → mutual DM session with double-ratchet bundles and mailbox claim keys.',
- 'No public phonebook — addresses are intentionally short and meant to be exchanged like a phone number or email, not discovered from a directory.',
- 'Fleet-tested across multiple onion participants: request, accept, decrypt, and reply paths verified on live Tor hidden services.',
+ 'Backend translate service detects source language and returns localized text for popup rendering without manual copy-paste.',
+ 'Persian locale pack (#472) ships full RTL layout support across the dashboard, not just Telegram labels.',
+ 'Source badges in popups show the detected language so analysts know when a machine translation is in play.',
],
- callToAction: 'MESH CHAT → DIRECT → SHARE SHORT ADDRESS',
+ callToAction: 'MAP → TELEGRAM MARKER → VIEW TRANSLATED POST',
},
{
- icon: ,
+ icon: ,
accent: 'cyan' as const,
- title: 'Infonet Transport Hardening',
+ title: 'ACARS Datalink + Full-World Telemetry',
subtitle:
- 'Tor/Arti warmup, SOCKS readiness, and terminal session lifecycle fixes so sovereign nodes actually join the mesh instead of sitting on NODE ARTI WARMING.',
+ 'Plane dossiers now surface Airframes ACARS datalink with summarizer support, and world telemetry caps are removed so dense regions render completely.',
details: [
- 'Tor hidden service config always exposes SOCKS; readiness probes cache and recover wedged transports instead of blocking wormhole sync indefinitely.',
- 'Leaving the Infonet terminal now tears down wormhole prep, leaves the session, and stops Tor when the UI enabled it — no ghost connections after close.',
- 'Network stats distinguish real transport warmup from stale sync backoff so operators see actionable status instead of a permanent warming spinner.',
+ 'ACARS messages attach to aircraft profiles with optional LLM summarization for long datalink bursts.',
+ 'Telemetry truncation limits lifted — high-density air and surface tracks no longer silently drop contacts at the map edge.',
+ 'Incremental live-data deltas and map render tuning reduce flicker when feeds update at high frequency.',
],
- callToAction: 'TOP RIGHT → ENTER INFONET → CHECK NODE STATUS',
+ callToAction: 'MAP → AIRCRAFT → OPEN DOSSIER → ACARS TAB',
},
];
const NEW_FEATURES = [
{
- icon: ,
- title: 'Gate Swarm Replication',
- desc: 'Participant nodes push and pull gate hashchain segments so encrypted room history converges across the fleet without a central relay.',
+ icon: ,
+ title: 'Persian (fa) Locale + RTL',
+ desc: 'Full Persian translation pack with right-to-left layout across the dashboard (#472).',
},
{
- icon: ,
- title: 'DM Contact Requests',
- desc: 'Pending inbound/outbound access requests with approve, deny, and scoped per-node DM state — no cross-identity leakage in local storage.',
+ icon: ,
+ title: 'Saved Dashboard Layout',
+ desc: 'Layer toggles, filter panel, map style, and section expand/collapse persist in localStorage across refreshes.',
},
{
- icon: ,
- title: 'Wormhole Session Teardown',
- desc: 'Closing the Infonet terminal aborts in-flight wormhole prep, leaves the lane, and resets launcher busy state for clean re-entry.',
+ icon: ,
+ title: 'OpenClaw Agent Hardening',
+ desc: 'Fetch-health endpoint (#470), Docker HMAC bootstrap, entity profile/trail, and agent-shell WebSocket token auth (#409).',
},
{
- icon: ,
- title: 'Fail-Closed Tor Proof',
- desc: 'Onion sync waits for a working SOCKS handshake before declaring transport ready — prevents silent half-open mesh joins.',
+ icon: ,
+ title: 'SAR UI + Mesh Bootstrap',
+ desc: 'SAR layer polish, mesh private outbox bootstrap, and live-data delta streaming for smoother map updates.',
+ },
+ {
+ icon: ,
+ title: 'Infonet Tab Fix',
+ desc: 'Infonet routing regression resolved (#404); README collapsible sections (#393) and contributor map docs (#435).',
+ },
+ {
+ icon: ,
+ title: 'Security & Stability',
+ desc: 'Agent-shell WS tokens, GDELT thread safety (#388), and store/SIGINT snapshot hardening (#389).',
},
];
const BUG_FIXES = [
- 'Arti/Tor transport no longer omits SocksPort when MESH_ARTI_ENABLED — SOCKS probes succeed and wormhole sync can start.',
- 'Concurrent Arti readiness checks no longer wedge Tor under load; single-flight probes with auto-recycle when SOCKS stalls.',
- 'Infonet terminal exit no longer leaves background wormhole prep or terminalLaunchBusy stuck after close.',
- 'Stale onion sync backoff clears when transport recovers so NODE ARTI WARMING does not persist after Tor is healthy.',
- 'DM decrypt timeouts on multi-participant fleets addressed via improved peer push timing and mailbox claim sequencing.',
+ 'GDELT mutation race under concurrent fetches (#388).',
+ 'Store/SIGINT snapshot consistency under load (#389).',
+ 'Spain DGT CCTV endpoint routing (#413).',
+ 'Python 3.13 feedparser compatibility for RSS ingestion.',
+ 'Layer preference hydration overwriting saved state on page load.',
+ 'Infonet tab routing regression (#404).',
];
type ChangelogContributor = {
@@ -100,8 +114,29 @@ type ChangelogContributor = {
const CONTRIBUTORS: ChangelogContributor[] = [
{
- name: 'privacy-core (MLS)',
- desc: 'Rust MLS gate crypto — WASM/FFI path for browser and Tauri sovereign shells',
+ name: 'esmaeelE',
+ desc: 'Persian (fa) locale + RTL, README collapsible sections',
+ pr: '#472, #393',
+ },
+ {
+ name: 'nzinci',
+ desc: 'Agent fetch health endpoint for OpenClaw monitoring',
+ pr: '#470',
+ },
+ {
+ name: 'Javier Andreo Zapata',
+ desc: 'Spain DGT CCTV endpoint fix',
+ pr: '#413',
+ },
+ {
+ name: 'TheYellowBeanieGuy',
+ desc: 'GDELT thread safety and store/SIGINT snapshot hardening',
+ pr: '#388, #389',
+ },
+ {
+ name: 'anntr1k3',
+ desc: 'Contributor map and frontend README documentation',
+ pr: '#435',
},
];
@@ -219,17 +254,17 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
);
})}
- {/* Auto-update note for v0.9.82+ installs */}
+ {/* Auto-update note for v0.9.83+ installs */}
- One-click update from v0.9.82
+ One-click update from v0.9.83
- If you installed v0.9.82, the in-app Update button verifies this release via the
- signed Tauri updater (`latest.json` + minisign). Desktop installs on v0.9.82 or
- later should auto-apply v0.9.83 without a manual MSI hop once the release is
+ If you installed v0.9.83, the in-app Update button verifies this release via the
+ signed Tauri updater (`latest.json` + minisign). Desktop installs on v0.9.83 or
+ later should auto-apply v0.9.84 without a manual MSI hop once the release is
published.
diff --git a/frontend/src/components/StartupWarmupModal.tsx b/frontend/src/components/StartupWarmupModal.tsx
index 66e1fa9..01d8d90 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 '@/lib/motion';
import { Database, Clock, X } from 'lucide-react';
-const CURRENT_VERSION = '0.9.83';
+const CURRENT_VERSION = '0.9.84';
const STORAGE_KEY = `shadowbroker_startup_warmup_notice_v${CURRENT_VERSION}`;
interface StartupWarmupModalProps {
diff --git a/pyproject.toml b/pyproject.toml
index 3a2416b..fcf3510 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "shadowbroker"
-version = "0.9.83"
+version = "0.9.84"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
diff --git a/uv.lock b/uv.lock
index c8f30c3..a56f3c1 100644
--- a/uv.lock
+++ b/uv.lock
@@ -104,7 +104,7 @@ wheels = [
[[package]]
name = "backend"
-version = "0.9.83"
+version = "0.9.84"
source = { editable = "backend" }
dependencies = [
{ name = "apscheduler" },
@@ -3058,7 +3058,7 @@ wheels = [
[[package]]
name = "shadowbroker"
-version = "0.9.83"
+version = "0.9.84"
source = { virtual = "." }
[package.metadata]