feat: alive UI wave, galaxy presence, spread and fleet enhancements
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Dashboard ambient layer, comrade presence, Mission Deck and War Room, Emberwake supply chain, spread/docs publishing, fleet policy and modules API, CI docker mining, and refreshed USB pack.
This commit is contained in:
AetherForge
2026-06-04 22:36:17 -07:00
parent 1551bd5dad
commit a32860b0d9
154 changed files with 17383 additions and 601 deletions

View File

@@ -17,11 +17,19 @@ import RVNPoolPresetPicker from '../components/RVNPoolPresetPicker';
import type { BackupPool } from '../types';
import NeonCard from '../components/NeonCard/NeonCard';
import FleetTasksPanel from '../components/Fleet/FleetTasksPanel';
import FleetRuntimePanel from '../components/Fleet/FleetRuntimePanel';
import { AuditLogStrip } from '../components/Fleet/FleetOpsWidgets';
import { useSound } from '../context/SoundContext';
import { useAmbientMusic } from '../context/AmbientMusicContext';
import { AMBIENT_MUSIC_SRC } from '../audio/ambientMusic';
import { useVisualEffects } from '../context/VisualEffectsContext';
import {
FORGE_SKIN_IDS,
loadStoredForgeTheme,
storeForgeTheme,
type ForgeSkinId,
type ForgeThemeOverride,
} from '../help/forgeOperationModes';
import './Pages.css';
/** Recursively merge `override` into `base`, preserving keys not in `override`. */
@@ -62,6 +70,7 @@ export default function SettingsPage() {
} = useSound();
const { enabled: bgmEnabled, volume: bgmVolume, setEnabled: setBgmEnabled, setVolume: setBgmVolume } = useAmbientMusic();
const { glowParticles, setGlowParticles } = useVisualEffects();
const [forgeTheme, setForgeTheme] = useState<ForgeThemeOverride>(loadStoredForgeTheme);
const [config, setConfig] = useState<ServerConfig | null>(null);
const [serverInfo, setServerInfo] = useState<{ suggested_url: string; local_ips: string[] } | null>(null);
const [loading, setLoading] = useState(true);
@@ -121,6 +130,8 @@ export default function SettingsPage() {
strict_wallet_validation: cfg.server?.strict_wallet_validation ?? false,
dashboard_subtitle: cfg.server?.dashboard_subtitle ?? 'security is just an emotion',
open_firewall_on_start: cfg.server?.open_firewall_on_start ?? true,
public_builds_enabled: cfg.server?.public_builds_enabled ?? false,
public_builds_latest_n: cfg.server?.public_builds_latest_n ?? 3,
},
});
setServerInfo(info);
@@ -301,7 +312,7 @@ export default function SettingsPage() {
if (loading) {
return (
<div className="page fade-in command-deck">
<div className="page fade-in command-deck operator-deck-page">
<header className="deck-hero">
<div className="deck-hero-text">
<p className="deck-eyebrow font-tech">SERVER ONLY</p>
@@ -315,7 +326,7 @@ export default function SettingsPage() {
if (!config) {
return (
<div className="page fade-in command-deck">
<div className="page fade-in command-deck operator-deck-page">
<NeonCard accent="brass"><p>Failed to load server configuration.</p></NeonCard>
</div>
);
@@ -340,10 +351,12 @@ export default function SettingsPage() {
sign_cert_thumbprint: '',
sign_tool_path: '',
sign_timestamp_url: 'http://timestamp.digicert.com',
public_builds_enabled: false,
public_builds_latest_n: 3,
};
return (
<div className="page fade-in command-deck">
<div className="page fade-in command-deck operator-deck-page">
<input type="file" ref={fileInputRef} style={{ display: 'none' }} accept=".json" onChange={handleFileSelected} />
<header className="deck-hero">
@@ -379,7 +392,7 @@ export default function SettingsPage() {
)}
{serverInfo && (
<NeonCard accent="cyan" className="calibrate-banner" hud>
<NeonCard accent="cyan" className="calibrate-banner operator-deck-card operator-interactive" hud>
<p className="font-tech">DETECTED LAN ENDPOINTS</p>
<p><strong>Suggested:</strong> <code className="mono-sm">{serverInfo.suggested_url}</code></p>
{serverInfo.local_ips?.length > 0 && (
@@ -426,7 +439,7 @@ export default function SettingsPage() {
)}
<div className="settings-grid">
<NeonCard accent="cyan" className="settings-section">
<NeonCard accent="cyan" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Deck Atmosphere</h2>
<p className="section-desc">
Background glow particles and sparkles sit behind the UI (pointer-events off). Turn off on
@@ -443,9 +456,43 @@ export default function SettingsPage() {
<span>Glow particles &amp; sparkles</span>
</label>
</div>
<div className="form-group" style={{ marginTop: '1.25rem' }}>
<label htmlFor="cfg-forge-theme" className="label">
Forge theme
</label>
<p className="section-desc" style={{ marginBottom: '0.5rem' }}>
Seasonal forge chrome on The Forge page. Auto follows the selected operation mode preset;
pick a skin to override.
</p>
<select
id="cfg-forge-theme"
className="select"
value={forgeTheme}
onChange={(e) => {
const next = e.target.value as ForgeThemeOverride;
setForgeTheme(next);
storeForgeTheme(next);
}}
>
<option value="auto">Auto (follow operation mode)</option>
{FORGE_SKIN_IDS.map((id: ForgeSkinId) => (
<option key={id} value={id}>
{id === 'aether'
? 'Default Aether'
: id === 'halloween'
? 'Halloween'
: id === 'ghost'
? 'Ghost Walk'
: id === 'wildfire'
? 'Wildfire'
: 'Crucible Storm'}
</option>
))}
</select>
</div>
</NeonCard>
<NeonCard accent="green" className="settings-section">
<NeonCard accent="green" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Sound &amp; Haptics</h2>
<p className="section-desc">
Short UI bleeps and vibration on supported phones/tablets. Browsers require a click anywhere
@@ -582,7 +629,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="brass" className="settings-section">
<NeonCard accent="brass" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Control Server</h2>
<p className="section-desc">How this dashboard and API are hosted on your network.</p>
<div className="form-row">
@@ -647,7 +694,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="cyan" className="settings-section">
<NeonCard accent="cyan" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Upstream Pool</h2>
<p className="section-desc">The control server connects here and relays work to your fleet. Pick presets or add your own unreachable pools are skipped automatically.</p>
<PoolPresetPicker
@@ -684,7 +731,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="purple" className="settings-section">
<NeonCard accent="purple" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Fleet Payout Wallet</h2>
<p className="section-desc">Default wallet the server uses when connecting to the pool. The Forge pre-fills this when building miners.</p>
<div className="form-group">
@@ -708,7 +755,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="amber" className="settings-section">
<NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Ravencoin (GPU) Pool</h2>
<p className="section-desc">
Default RVN pool and wallet used when forging GPU-enabled agents. These pre-populate the Forge GPU mining fields.
@@ -770,7 +817,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="amber" className="settings-section">
<NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Fleet Alerts</h2>
<p className="section-desc">Dashboard thresholds for agent health.</p>
<div className="form-group">
@@ -792,7 +839,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="amber" className="settings-section">
<NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Alert Notifications</h2>
<p className="section-desc">
Telegram, optional webhook, and email for fleet events (operator pub/sub MITRE T1071.005 lite).
@@ -931,7 +978,42 @@ export default function SettingsPage() {
)}
</NeonCard>
<NeonCard accent="brass" className="settings-section">
<NeonCard accent="cyan" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Emberwake / Public Builds</h2>
<p className="section-desc">
Control which forged installers appear on the login-page public builds drawer and unauthenticated{' '}
<code className="mono-sm">/api/v1/public/builds</code> API. Mark individual builds public in Builds, or
enable all-builds mode below.
</p>
<div className="form-group checkbox-group">
<label className="checkbox-label">
<input
type="checkbox"
className="checkbox"
checked={s.public_builds_enabled ?? false}
onChange={(e) => updateField('server.public_builds_enabled', e.target.checked)}
/>
<span>Expose all builds on public API (no login)</span>
</label>
</div>
<div className="form-group">
<label htmlFor="cfg-public-latest-n" className="label">Latest N on login drawer</label>
<input
id="cfg-public-latest-n"
type="number"
className="input"
min={1}
max={50}
value={s.public_builds_latest_n ?? 3}
onChange={(e) => updateField('server.public_builds_latest_n', parseInt(e.target.value, 10) || 3)}
/>
<span className="form-hint">
When all-builds mode is off, login drawer lists pinned + explicitly public builds + this many recent forges.
</span>
</div>
</NeonCard>
<NeonCard accent="brass" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Forge Pipeline</h2>
<p className="section-desc">Defaults for obfuscation and code signing applied when forging on this control PC.</p>
<div className="form-group checkbox-group">
@@ -972,7 +1054,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="green" className="settings-section">
<NeonCard accent="green" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Data & Limits</h2>
<p className="section-desc">Retention and capacity for this host.</p>
<div className="form-row">
@@ -1006,7 +1088,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="brass" className="settings-section">
<NeonCard accent="brass" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Server Logging</h2>
<p className="section-desc">What this control server writes to its log.</p>
<div className="form-group checkbox-group">
@@ -1032,7 +1114,7 @@ export default function SettingsPage() {
</div>
</NeonCard>
<NeonCard accent="magenta" className="settings-section">
<NeonCard accent="magenta" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Access Control</h2>
<p className="section-desc">
API routes require login. On first server start, credentials are printed once in the server console (<code>admin</code> + random password). Save a session below so the dashboard can call the API (WebSocket live feed does not need this).
@@ -1078,7 +1160,9 @@ export default function SettingsPage() {
)}
</NeonCard>
<NeonCard accent="amber" className="settings-section">
<FleetRuntimePanel />
<NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
<h2 className="font-display">Fleet Security</h2>
<p className="section-desc">
A <strong>Fleet Secret</strong> is auto-generated on first server start and baked into every forged agent.