jaeswift-website/js/chat-cli.js

510 lines
21 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ===================================================
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; },
};
})();