510 lines
21 KiB
JavaScript
510 lines
21 KiB
JavaScript
/* ===================================================
|
||
JAESWIFT.XYZ — JAE-AI CLI Easter Egg
|
||
Local pseudo-shell handled in the JAE-AI chat panel.
|
||
Intercepts messages starting with '/'.
|
||
=================================================== */
|
||
(function () {
|
||
'use strict';
|
||
|
||
const MAX_HISTORY = 50;
|
||
const HIST_KEY = 'jaeCliHist';
|
||
let cmdHistory = [];
|
||
let devMode = false;
|
||
let matrixActive = false;
|
||
|
||
// Load history
|
||
try {
|
||
const raw = localStorage.getItem(HIST_KEY);
|
||
if (raw) cmdHistory = JSON.parse(raw) || [];
|
||
} catch (e) {}
|
||
|
||
function saveHistory() {
|
||
try {
|
||
localStorage.setItem(HIST_KEY, JSON.stringify(cmdHistory.slice(-MAX_HISTORY)));
|
||
} catch (e) {}
|
||
}
|
||
|
||
// ─── Virtual FS ──────────────────────────────────
|
||
const VFS = {
|
||
'about.md': [
|
||
'# JAESWIFT // OPERATOR FILE',
|
||
'',
|
||
'Codename: JAE',
|
||
'Location: Manchester, United Kingdom',
|
||
'Operator since: 2008',
|
||
'',
|
||
'Full-stack engineer, cyber-curious, builds things.',
|
||
'Specialisms: Node / Python / Linux / nginx / Solana',
|
||
'',
|
||
'This site is my HUD. Built by hand, deployed by git, watched by me.',
|
||
].join('\n'),
|
||
|
||
'projects.json': JSON.stringify({
|
||
'jaeswift.xyz': 'This site — military CRT HUD, Flask+vanilla',
|
||
'matty.lol': 'Crypto/Solana toolkit (Node/Express)',
|
||
'contraband-depot': 'FMHY mirror, 24 categories, 16k+ links',
|
||
'recon-awesomelist': '28 sectors / 135k items, weekly sync',
|
||
'unredacted-vault': '114+ declassified PDFs (MOD/CIA/etc)',
|
||
'radar': 'RSS aggregator (HN/Reddit/Lobsters)',
|
||
'sitrep': 'Daily AI briefing generator',
|
||
'telemetry': 'Live ops command centre'
|
||
}, null, 2),
|
||
|
||
'skills.md': [
|
||
'# FIELD LOADOUT',
|
||
'',
|
||
'## LANGS',
|
||
' - Python, JavaScript/Node, TypeScript, Rust, Bash, SQL',
|
||
'',
|
||
'## STACKS',
|
||
' - Flask, Express, React, Solana/Anchor, Docker, systemd',
|
||
'',
|
||
'## INFRA',
|
||
' - nginx, Debian, PostgreSQL, Redis, cron, fail2ban',
|
||
'',
|
||
'## OPS',
|
||
' - VPS ops, CI/CD via Gitea, observability, hardening'
|
||
].join('\n'),
|
||
|
||
'secrets.enc': [
|
||
'',
|
||
' ░█████╗░░█████╗░░█████╗░███████╗░██████╗░██████╗',
|
||
' ██╔══██╗██╔══██╗██╔══██╗██╔════╝██╔════╝██╔════╝',
|
||
' ███████║██║░░╚═╝██║░░╚═╝█████╗░░╚█████╗░╚█████╗░',
|
||
' ██╔══██║██║░░██╗██║░░██╗██╔══╝░░░╚═══██╗░╚═══██╗',
|
||
' ██║░░██║╚█████╔╝╚█████╔╝███████╗██████╔╝██████╔╝',
|
||
' ╚═╝░░╚═╝░╚════╝░░╚════╝░╚══════╝╚═════╝░╚═════╝░',
|
||
'',
|
||
' ▓▒░ ACCESS DENIED ░▒▓',
|
||
' File encrypted with AES-4096-QUANTUM-ROT13.',
|
||
' Authorisation required. >> /sudo',
|
||
].join('\n'),
|
||
|
||
'mascot.txt': [
|
||
' ___ ___',
|
||
' ,-" `. ," `-,',
|
||
' / _ \\_____/ _ \\',
|
||
' | (o) ` ` (o) |',
|
||
' \\ \\_._ _._/ /',
|
||
' `._ `----\' _.\'',
|
||
' `~---------~\'',
|
||
' // JAE MASCOT //',
|
||
' Black dragon, on duty.'
|
||
].join('\n'),
|
||
|
||
'whoami.txt': '$USER — check /whoami for your details.'
|
||
};
|
||
|
||
// ─── Helpers ─────────────────────────────────────
|
||
function fmt(lines) { return Array.isArray(lines) ? lines.join('\n') : lines; }
|
||
|
||
function pad(n, len) {
|
||
const s = String(n);
|
||
return s.length >= len ? s : ' '.repeat(len - s.length) + s;
|
||
}
|
||
|
||
async function fakeProgress(label, steps, delay) {
|
||
const out = [];
|
||
for (let i = 1; i <= steps; i++) {
|
||
const pct = Math.floor((i / steps) * 100);
|
||
const filled = '█'.repeat(Math.floor(pct / 5));
|
||
const empty = '░'.repeat(20 - filled.length);
|
||
out.push(`${label} [${filled}${empty}] ${pct}%`);
|
||
// intentionally not awaited — output comes as a block
|
||
}
|
||
return out;
|
||
}
|
||
|
||
// ─── Commands ────────────────────────────────────
|
||
const commands = {};
|
||
|
||
commands.help = function () {
|
||
const base = [
|
||
'JAE-AI TERMINAL — available commands:',
|
||
'',
|
||
' /help show this help',
|
||
' /ls list virtual files',
|
||
' /cat <file> print file contents',
|
||
' /whoami show your visitor fingerprint',
|
||
' /uptime show site uptime',
|
||
' /uname kernel/system info',
|
||
' /date current date/time',
|
||
' /ping <host> fake ping sweep',
|
||
' /sudo <cmd> attempt privilege escalation',
|
||
' /rm -rf / don\'t do it',
|
||
' /hack <target> hollywood hacking simulator',
|
||
' /matrix toggle matrix rain',
|
||
' /clear clear the chat',
|
||
' /exit try to leave',
|
||
' /fortune random sitrep quip',
|
||
' /history show last commands',
|
||
' /neofetch system summary ASCII',
|
||
];
|
||
if (devMode) {
|
||
base.push('');
|
||
base.push(' [DEVELOPER MODE ACTIVE]');
|
||
base.push(' /api list real API endpoints');
|
||
base.push(' /curl <url> actually fetch a URL');
|
||
base.push(' /geo show GEO INTEL from telemetry');
|
||
}
|
||
base.push('');
|
||
base.push('Anything not prefixed with / goes to JAE-AI.');
|
||
return fmt(base);
|
||
};
|
||
|
||
commands.ls = function () {
|
||
return fmt([
|
||
'total 6',
|
||
'-rw-r--r-- 1 jae jae 412 apr 20 01:24 about.md',
|
||
'-rw-r--r-- 1 jae jae 528 apr 20 01:24 projects.json',
|
||
'-rw-r--r-- 1 jae jae 394 apr 20 01:24 skills.md',
|
||
'-r-------- 1 jae jae 999 apr 20 01:24 secrets.enc',
|
||
'-rw-r--r-- 1 jae jae 210 apr 20 01:24 mascot.txt',
|
||
'-rw-r--r-- 1 jae jae 42 apr 20 01:24 whoami.txt'
|
||
]);
|
||
};
|
||
|
||
commands.cat = function (args) {
|
||
const name = args[0];
|
||
if (!name) return 'cat: missing operand — try /cat about.md';
|
||
if (VFS[name] != null) return VFS[name];
|
||
return `cat: ${name}: No such file or directory`;
|
||
};
|
||
|
||
commands.whoami = async function () {
|
||
try {
|
||
const r = await fetch('/api/visitor/scan');
|
||
if (!r.ok) throw new Error('scan unavailable');
|
||
const d = await r.json();
|
||
return fmt([
|
||
`operator: ${d.ip_masked}`,
|
||
`geolocation: ${d.city ? d.city + ', ' : ''}${d.country} ${d.country_flag || ''}`,
|
||
`network: ${d.isp}`,
|
||
`browser: ${d.browser} ${d.browser_version || ''}`,
|
||
`os: ${d.os} ${d.os_version || ''}`,
|
||
`device: ${d.device}`,
|
||
`threat: ${d.threat_level} — ${d.threat_reason}`,
|
||
'',
|
||
'you are a visitor. welcome.'
|
||
]);
|
||
} catch (e) {
|
||
return 'scan service unavailable. try again in a moment.';
|
||
}
|
||
};
|
||
|
||
commands.uptime = async function () {
|
||
try {
|
||
const r = await fetch('/api/telemetry/overview');
|
||
const d = await r.json();
|
||
const up = (d.system && d.system.uptime) || d.uptime || 'unknown';
|
||
const load = (d.system && d.system.load_1) || '—';
|
||
const users = 'many';
|
||
const now = new Date().toLocaleTimeString('en-GB');
|
||
return fmt([
|
||
` ${now} up ${up}, ${users} users, load average: ${load}`,
|
||
` HQ: Manchester // jaeswift-api.service ● ONLINE`
|
||
]);
|
||
} catch (e) {
|
||
return `up since boot — tired but operational`;
|
||
}
|
||
};
|
||
|
||
commands.uname = function (args) {
|
||
if (args[0] === '-a') {
|
||
return 'Linux jaeswift 6.1.0-jaeswift #1 SMP PREEMPT_DYNAMIC 2026-04-20 x86_64 GNU/Linux';
|
||
}
|
||
return 'Linux';
|
||
};
|
||
|
||
commands.date = function () {
|
||
return new Date().toUTCString();
|
||
};
|
||
|
||
commands.ping = function (args) {
|
||
const host = args[0] || 'jaeswift.xyz';
|
||
const out = [`PING ${host} (10.0.0.1) 56(84) bytes of data.`];
|
||
for (let i = 0; i < 4; i++) {
|
||
const t = (10 + Math.random() * 40).toFixed(2);
|
||
out.push(`64 bytes from ${host}: icmp_seq=${i+1} ttl=54 time=${t} ms`);
|
||
}
|
||
out.push('');
|
||
out.push(`--- ${host} ping statistics ---`);
|
||
out.push('4 packets transmitted, 4 received, 0% packet loss, time 3006ms');
|
||
return fmt(out);
|
||
};
|
||
|
||
commands.sudo = function (args) {
|
||
if (!args.length) return 'usage: /sudo <command>';
|
||
return fmt([
|
||
`[sudo] password for operator: ****`,
|
||
``,
|
||
`sudo: ACCESS DENIED — nice try.`,
|
||
`This incident will be reported... actually, no it won\'t.`
|
||
]);
|
||
};
|
||
|
||
commands.rm = function (args) {
|
||
if (args.join(' ') === '-rf /' || args.join(' ').startsWith('-rf /')) {
|
||
return fmt([
|
||
' __ __',
|
||
' / \\_/ \\ 💥 FORMATTING /dev/sda ...',
|
||
' \\_( • )_/ 💥 WIPING /home ...',
|
||
' //( )\\\\ 💥 DELETING /etc/passwd ...',
|
||
'',
|
||
' ERROR: The file system is screaming.',
|
||
' ███████████░░░░░░░░░ 58%',
|
||
'',
|
||
' ... just kidding.',
|
||
' SYSTEM RESTORED FROM BACKUP. Nice try, operator.'
|
||
]);
|
||
}
|
||
return `rm: refuse to do whatever that is`;
|
||
};
|
||
|
||
commands.hack = function (args) {
|
||
const target = args.join(' ') || 'the-gibson';
|
||
return fmt([
|
||
`>>> TARGETING ${target}...`,
|
||
`>>> BYPASSING FIREWALL... [████████████░░░░] 72%`,
|
||
`>>> CRACKING PASSWORD... [████████████████] 100%`,
|
||
`>>> INJECTING PAYLOAD... [████████████████] 100%`,
|
||
`>>> COVERING TRACKS... [████████████████] 100%`,
|
||
``,
|
||
`>>> CONNECTION ESTABLISHED.`,
|
||
`>>> ACCESS GRANTED TO ${target.toUpperCase()}.`,
|
||
``,
|
||
`... just kidding lol. nothing was hacked.`,
|
||
`If you came here looking for real offsec — go read /cat skills.md and touch grass.`
|
||
]);
|
||
};
|
||
|
||
commands.matrix = function () {
|
||
matrixActive = !matrixActive;
|
||
toggleMatrix(matrixActive);
|
||
return matrixActive
|
||
? 'Matrix rain enabled. Follow the white rabbit.'
|
||
: 'Matrix rain disabled. Back to the desert of the real.';
|
||
};
|
||
|
||
commands.clear = function () {
|
||
const cm = document.getElementById('chatMessages');
|
||
if (cm) cm.innerHTML = '';
|
||
return null; // nothing to print
|
||
};
|
||
|
||
commands.exit = function () {
|
||
return fmt([
|
||
'logout',
|
||
'',
|
||
'NICE TRY. You don\'t leave that easily.',
|
||
'JAE-AI resumes normal operation.'
|
||
]);
|
||
};
|
||
|
||
const FORTUNES = [
|
||
'SITREP: quiet on the wire. unusual.',
|
||
'SITREP: nothing is fine. everything is broken. proceed.',
|
||
'SITREP: coffee low. deploy anyway.',
|
||
'SITREP: the logs know. the logs always know.',
|
||
'SITREP: git status is a lifestyle.',
|
||
'SITREP: ship it friday. regret it monday.',
|
||
'SITREP: 99 bugs on the wall, patch one down, 117 on the wall.',
|
||
'SITREP: if it works on the VPS, the VPS is now production.',
|
||
'SITREP: the only safe deploy is no deploy.',
|
||
'SITREP: trust nothing. grep everything.',
|
||
];
|
||
|
||
commands.fortune = function () {
|
||
return FORTUNES[Math.floor(Math.random() * FORTUNES.length)];
|
||
};
|
||
|
||
commands.history = function () {
|
||
if (!cmdHistory.length) return '(no history yet)';
|
||
const recent = cmdHistory.slice(-10);
|
||
return recent.map((c, i) => ` ${pad(cmdHistory.length - recent.length + i + 1, 4)} ${c}`).join('\n');
|
||
};
|
||
|
||
commands.neofetch = function () {
|
||
const cc = (navigator.language || 'en').toUpperCase();
|
||
const ua = navigator.userAgent || '';
|
||
let browser = 'Unknown';
|
||
if (/firefox/i.test(ua)) browser = 'Firefox';
|
||
else if (/edg/i.test(ua)) browser = 'Edge';
|
||
else if (/chrome/i.test(ua)) browser = 'Chrome';
|
||
else if (/safari/i.test(ua)) browser = 'Safari';
|
||
return fmt([
|
||
' ▄███████▄ operator@jaeswift.xyz',
|
||
' ██░░░░░░░██ ----------------------',
|
||
' ██░░░░░░░██ OS: JAESWIFT/6.1.0 x86_64',
|
||
' ██░██░██░██ Host: Manchester HQ',
|
||
' ██░░░░░░░██ Kernel: CRT-tactical-v2',
|
||
' ██░░░░░██ Uptime: 24/7/365',
|
||
' ███████ Shell: /bin/jaesh',
|
||
' █ █ Resolution: ' + screen.width + 'x' + screen.height,
|
||
' ██ ██ Terminal: JAE-AI',
|
||
' ██ ██ Browser: ' + browser,
|
||
' Locale: ' + cc,
|
||
' CPU: 18-core @ spicy GHz',
|
||
' Memory: 96GB tactical',
|
||
' Theme: mil-green/CRT/cyberpunk',
|
||
]);
|
||
};
|
||
|
||
// ─── Dev-mode commands ──────────────────────────
|
||
commands.api = async function () {
|
||
if (!devMode) return 'command not found. try /help';
|
||
const endpoints = [
|
||
'/api/visitor/scan',
|
||
'/api/visitor/recent-arcs',
|
||
'/api/leaderboards',
|
||
'/api/telemetry/overview',
|
||
'/api/telemetry/history',
|
||
'/api/telemetry/geo',
|
||
'/api/telemetry/visitors',
|
||
'/api/telemetry/nginx-tail',
|
||
'/api/telemetry/alerts',
|
||
'/api/stats',
|
||
'/api/navigation',
|
||
'/api/changelog',
|
||
'/api/chat (POST)',
|
||
'/api/contraband',
|
||
'/api/sitrep/latest',
|
||
'/api/radar'
|
||
];
|
||
return 'JAESWIFT API endpoints (dev-mode):\n\n ' + endpoints.join('\n ');
|
||
};
|
||
|
||
commands.curl = async function (args) {
|
||
if (!devMode) return 'command not found. try /help';
|
||
const url = args[0];
|
||
if (!url) return 'usage: /curl <url>';
|
||
try {
|
||
const r = await fetch(url);
|
||
const text = (await r.text()).slice(0, 2000);
|
||
return `HTTP ${r.status} ${r.statusText}\ncontent-type: ${r.headers.get('content-type') || 'n/a'}\n\n${text}${text.length >= 2000 ? '\n...[truncated]' : ''}`;
|
||
} catch (e) {
|
||
return `curl: (6) ${e.message}`;
|
||
}
|
||
};
|
||
|
||
commands.geo = async function () {
|
||
if (!devMode) return 'command not found. try /help';
|
||
try {
|
||
const r = await fetch('/api/telemetry/geo');
|
||
const d = await r.json();
|
||
if (!Array.isArray(d) || !d.length) return 'GEO INTEL: no data.';
|
||
return 'GEO INTEL (24h):\n\n' + d.slice(0, 15).map((row, i) =>
|
||
` ${pad(i+1, 2)}. ${(row.country_code || 'XX').padEnd(3)} ${(row.country_name || 'Unknown').padEnd(22)} ${pad(row.count || 0, 5)}`
|
||
).join('\n');
|
||
} catch (e) {
|
||
return 'telemetry unavailable.';
|
||
}
|
||
};
|
||
|
||
// ─── Matrix rain overlay ─────────────────────────
|
||
let matrixCanvas = null;
|
||
let matrixRAF = null;
|
||
function toggleMatrix(on) {
|
||
if (on) {
|
||
matrixCanvas = document.createElement('canvas');
|
||
matrixCanvas.id = 'matrixRain';
|
||
Object.assign(matrixCanvas.style, {
|
||
position: 'fixed', inset: '0', width: '100%', height: '100%',
|
||
pointerEvents: 'none', zIndex: '7', opacity: '0.18',
|
||
});
|
||
document.body.appendChild(matrixCanvas);
|
||
const ctx = matrixCanvas.getContext('2d');
|
||
function resize() {
|
||
matrixCanvas.width = window.innerWidth;
|
||
matrixCanvas.height = window.innerHeight;
|
||
}
|
||
resize();
|
||
window.addEventListener('resize', resize);
|
||
const chars = 'アイウエオカキクケコサシスセソタチツテトナニヌネノ01JAESWIFT'.split('');
|
||
const size = 16;
|
||
const cols = Math.floor(matrixCanvas.width / size);
|
||
const drops = new Array(cols).fill(1);
|
||
function draw() {
|
||
ctx.fillStyle = 'rgba(0, 0, 0, 0.06)';
|
||
ctx.fillRect(0, 0, matrixCanvas.width, matrixCanvas.height);
|
||
ctx.fillStyle = '#00cc33';
|
||
ctx.font = size + 'px JetBrains Mono, monospace';
|
||
for (let i = 0; i < drops.length; i++) {
|
||
const ch = chars[Math.floor(Math.random() * chars.length)];
|
||
ctx.fillText(ch, i * size, drops[i] * size);
|
||
if (drops[i] * size > matrixCanvas.height && Math.random() > 0.975) drops[i] = 0;
|
||
drops[i]++;
|
||
}
|
||
matrixRAF = requestAnimationFrame(draw);
|
||
}
|
||
draw();
|
||
} else {
|
||
if (matrixRAF) cancelAnimationFrame(matrixRAF);
|
||
if (matrixCanvas) matrixCanvas.remove();
|
||
matrixCanvas = null;
|
||
}
|
||
}
|
||
|
||
// ─── Konami Code → Developer Mode ────────────────
|
||
const KONAMI = ['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||
let kBuf = [];
|
||
document.addEventListener('keydown', function (e) {
|
||
kBuf.push(e.key);
|
||
if (kBuf.length > KONAMI.length) kBuf.shift();
|
||
const match = kBuf.length === KONAMI.length && kBuf.every((k, i) => k.toLowerCase() === KONAMI[i].toLowerCase());
|
||
if (match && !devMode) {
|
||
devMode = true;
|
||
// Add a floating dev badge
|
||
const badge = document.createElement('div');
|
||
badge.id = 'devModeBadge';
|
||
Object.assign(badge.style, {
|
||
position: 'fixed', top: '68px', right: '16px', zIndex: '900',
|
||
background: 'var(--bg-panel)', border: '1px solid var(--warning)',
|
||
color: 'var(--warning)', padding: '6px 12px', fontFamily: 'var(--font-mono)',
|
||
fontSize: '11px', letterSpacing: '1.5px', cursor: 'pointer',
|
||
boxShadow: '0 0 14px rgba(201,162,39,0.4)',
|
||
});
|
||
badge.innerHTML = '⚡ DEVELOPER MODE // UNLOCKED';
|
||
badge.title = 'Click to disable';
|
||
badge.addEventListener('click', () => {
|
||
devMode = false; badge.remove();
|
||
});
|
||
document.body.appendChild(badge);
|
||
try { window.dispatchEvent(new CustomEvent('jae-dev-mode-on')); } catch (err) {}
|
||
}
|
||
});
|
||
|
||
// ─── Entry point — handle a /-command ───────────
|
||
async function handle(raw) {
|
||
const trimmed = raw.trim();
|
||
if (!trimmed.startsWith('/')) return { handled: false };
|
||
|
||
const parts = trimmed.slice(1).split(/\s+/);
|
||
const cmd = (parts[0] || '').toLowerCase();
|
||
const args = parts.slice(1);
|
||
|
||
cmdHistory.push(trimmed);
|
||
if (cmdHistory.length > MAX_HISTORY) cmdHistory = cmdHistory.slice(-MAX_HISTORY);
|
||
saveHistory();
|
||
|
||
if (!cmd) return { handled: true, output: '' };
|
||
|
||
const fn = commands[cmd];
|
||
if (!fn) {
|
||
return { handled: true, output: `command not found: /${cmd}. type /help for available commands.` };
|
||
}
|
||
|
||
try {
|
||
const result = await fn(args);
|
||
return { handled: true, output: (result == null ? '' : String(result)) };
|
||
} catch (e) {
|
||
return { handled: true, output: `error: ${e.message}` };
|
||
}
|
||
}
|
||
|
||
window.__jaeCLI = {
|
||
handle: handle,
|
||
commands: commands,
|
||
isDev: function () { return devMode; },
|
||
};
|
||
})();
|