From a372f1c762d8fe4bb288a43ac763a4cd67599bcb Mon Sep 17 00:00:00 2001 From: Mehul Patel <11514627+nomadicmehul@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:07:53 +0100 Subject: [PATCH 1/3] Added static website for GitHub Pages Single-page site with dark theme covering project overview, features, architecture (Plan A/B tabs), investigation flow, demo scenarios, remediation policies, before/after metrics, tech stack, timeline, and quick start guide. Fully responsive with scroll animations and terminal typing effect. --- docs/assets/script.js | 185 +++++++ docs/assets/style.css | 1179 +++++++++++++++++++++++++++++++++++++++++ docs/index.html | 745 ++++++++++++++++++++++++++ 3 files changed, 2109 insertions(+) create mode 100644 docs/assets/script.js create mode 100644 docs/assets/style.css create mode 100644 docs/index.html diff --git a/docs/assets/script.js b/docs/assets/script.js new file mode 100644 index 0000000..4d2b39d --- /dev/null +++ b/docs/assets/script.js @@ -0,0 +1,185 @@ +/* ============================================ + TheNightOps β Website Interactivity + ============================================ */ + +(function () { + 'use strict'; + + // ---- Stars Background ---- + function createStars() { + const container = document.getElementById('stars'); + if (!container) return; + const count = Math.min(120, Math.floor(window.innerWidth / 10)); + for (let i = 0; i < count; i++) { + const star = document.createElement('div'); + star.className = 'star'; + star.style.left = Math.random() * 100 + '%'; + star.style.top = Math.random() * 100 + '%'; + star.style.setProperty('--duration', (2 + Math.random() * 4) + 's'); + star.style.setProperty('--max-opacity', (0.3 + Math.random() * 0.7).toString()); + star.style.animationDelay = Math.random() * 4 + 's'; + star.style.width = (1 + Math.random() * 2) + 'px'; + star.style.height = star.style.width; + container.appendChild(star); + } + } + + // ---- Navbar Scroll ---- + function initNavbar() { + const navbar = document.getElementById('navbar'); + if (!navbar) return; + let ticking = false; + window.addEventListener('scroll', function () { + if (!ticking) { + requestAnimationFrame(function () { + navbar.classList.toggle('scrolled', window.scrollY > 50); + ticking = false; + }); + ticking = true; + } + }); + } + + // ---- Mobile Nav Toggle ---- + function initMobileNav() { + const toggle = document.getElementById('navToggle'); + const links = document.getElementById('navLinks'); + if (!toggle || !links) return; + + toggle.addEventListener('click', function () { + links.classList.toggle('open'); + }); + + links.querySelectorAll('.nav-link').forEach(function (link) { + link.addEventListener('click', function () { + links.classList.remove('open'); + }); + }); + } + + // ---- Architecture Tabs ---- + function initArchTabs() { + var tabs = document.querySelectorAll('.arch-tab'); + tabs.forEach(function (tab) { + tab.addEventListener('click', function () { + var target = this.getAttribute('data-tab'); + tabs.forEach(function (t) { t.classList.remove('active'); }); + this.classList.add('active'); + document.querySelectorAll('.arch-panel').forEach(function (p) { + p.classList.remove('active'); + }); + var panel = document.getElementById(target); + if (panel) panel.classList.add('active'); + }); + }); + } + + // ---- Scroll Animations ---- + function initScrollAnimations() { + var elements = document.querySelectorAll('[data-aos]'); + if (!elements.length) return; + + var observer = new IntersectionObserver(function (entries) { + entries.forEach(function (entry) { + if (entry.isIntersecting) { + entry.target.classList.add('visible'); + observer.unobserve(entry.target); + } + }); + }, { + threshold: 0.1, + rootMargin: '0px 0px -40px 0px' + }); + + elements.forEach(function (el) { observer.observe(el); }); + } + + // ---- Terminal Typing Animation ---- + function initTerminalAnimation() { + var body = document.getElementById('terminalBody'); + if (!body) return; + + var lines = [ + { type: 'output', text: '' }, + { type: 'info', text: 'π TheNightOps v0.3.0 β Autonomous SRE Agent' }, + { type: 'output', text: '' }, + { type: 'output', text: '[Phase 1/4] Triage β checking pod status...' }, + { type: 'success', text: ' Found: pod/api-server-7d4f9 OOMKilled (exit 137)' }, + { type: 'output', text: '[Phase 2/4] Deep Investigation β querying logs & events...' }, + { type: 'warn', text: ' Memory spike: 128Mi -> 512Mi in 45s (limit: 256Mi)' }, + { type: 'output', text: '[Phase 3/4] Synthesis β correlating findings...' }, + { type: 'success', text: ' Root cause: memory leak in v2.1.3 (deployed 2h ago)' }, + { type: 'output', text: '[Phase 4/4] RCA + Remediation' }, + { type: 'success', text: ' β RCA generated (confidence: 92%)' }, + { type: 'info', text: ' β Recommended: rollback to v2.1.2' }, + { type: 'output', text: '' }, + { type: 'success', text: 'β Investigation complete β MTTR: 3m 12s' }, + ]; + + var delay = 1200; + var interval = 350; + + lines.forEach(function (line, i) { + setTimeout(function () { + var div = document.createElement('div'); + div.className = 'terminal-line ' + line.type; + div.textContent = line.text; + body.appendChild(div); + body.scrollTop = body.scrollHeight; + }, delay + i * interval); + }); + } + + // ---- Smooth Scroll for anchor links ---- + function initSmoothScroll() { + document.querySelectorAll('a[href^="#"]').forEach(function (link) { + link.addEventListener('click', function (e) { + var target = document.querySelector(this.getAttribute('href')); + if (target) { + e.preventDefault(); + var offset = 80; + var top = target.getBoundingClientRect().top + window.pageYOffset - offset; + window.scrollTo({ top: top, behavior: 'smooth' }); + } + }); + }); + } + + // ---- Active nav link highlight ---- + function initActiveNavHighlight() { + var sections = document.querySelectorAll('.section[id], .hero[id]'); + var navLinks = document.querySelectorAll('.nav-link[href^="#"]'); + if (!sections.length || !navLinks.length) return; + + var observer = new IntersectionObserver(function (entries) { + entries.forEach(function (entry) { + if (entry.isIntersecting) { + var id = entry.target.getAttribute('id'); + navLinks.forEach(function (link) { + link.style.color = ''; + if (link.getAttribute('href') === '#' + id) { + link.style.color = 'var(--accent-blue)'; + } + }); + } + }); + }, { + threshold: 0.2, + rootMargin: '-80px 0px -50% 0px' + }); + + sections.forEach(function (s) { observer.observe(s); }); + } + + // ---- Init Everything ---- + document.addEventListener('DOMContentLoaded', function () { + createStars(); + initNavbar(); + initMobileNav(); + initArchTabs(); + initScrollAnimations(); + initTerminalAnimation(); + initSmoothScroll(); + initActiveNavHighlight(); + }); +})(); diff --git a/docs/assets/style.css b/docs/assets/style.css new file mode 100644 index 0000000..d9b1a72 --- /dev/null +++ b/docs/assets/style.css @@ -0,0 +1,1179 @@ +/* ============================================ + TheNightOps β Static Website Styles + Dark theme with neon accents + ============================================ */ + +:root { + --bg-primary: #0a0e17; + --bg-secondary: #0f1420; + --bg-card: #141a2a; + --bg-card-hover: #1a2236; + --border: #1e293b; + --border-glow: #3b82f620; + + --text-primary: #e2e8f0; + --text-secondary: #94a3b8; + --text-muted: #64748b; + + --accent-blue: #3b82f6; + --accent-purple: #8b5cf6; + --accent-cyan: #06b6d4; + --accent-green: #10b981; + --accent-yellow: #f59e0b; + --accent-red: #ef4444; + --accent-orange: #f97316; + + --gradient-primary: linear-gradient(135deg, #3b82f6, #8b5cf6); + --gradient-hero: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 50%, #06b6d4 100%); + + --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', monospace; + + --radius-sm: 6px; + --radius-md: 10px; + --radius-lg: 16px; + --radius-xl: 24px; + + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5); + --shadow-glow: 0 0 40px rgba(59, 130, 246, 0.15); +} + +/* ---- Reset & Base ---- */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +html { + scroll-behavior: smooth; + -webkit-font-smoothing: antialiased; +} + +body { + font-family: var(--font-sans); + background: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; + overflow-x: hidden; +} + +a { color: var(--accent-blue); text-decoration: none; transition: color 0.2s; } +a:hover { color: var(--accent-cyan); } + +img { max-width: 100%; height: auto; } + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 24px; +} + +/* ---- Navbar ---- */ +.navbar { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + padding: 16px 0; + transition: all 0.3s ease; + background: transparent; +} + +.navbar.scrolled { + background: rgba(10, 14, 23, 0.9); + backdrop-filter: blur(20px); + border-bottom: 1px solid var(--border); + padding: 10px 0; +} + +.nav-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 24px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.nav-logo { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + font-size: 1.2rem; + color: var(--text-primary); +} + +.logo-icon { font-size: 1.4rem; } + +.nav-links { + display: flex; + align-items: center; + gap: 28px; +} + +.nav-link { + color: var(--text-secondary); + font-size: 0.9rem; + font-weight: 500; + transition: color 0.2s; +} + +.nav-link:hover { color: var(--text-primary); } + +.nav-cta { + display: flex; + align-items: center; + gap: 6px; + background: var(--bg-card); + padding: 8px 16px; + border-radius: var(--radius-sm); + border: 1px solid var(--border); +} + +.nav-cta:hover { + border-color: var(--accent-blue); + color: var(--text-primary); +} + +.github-icon { flex-shrink: 0; } + +.nav-toggle { + display: none; + flex-direction: column; + gap: 5px; + background: none; + border: none; + cursor: pointer; + padding: 4px; +} + +.nav-toggle span { + width: 24px; + height: 2px; + background: var(--text-primary); + border-radius: 2px; + transition: all 0.3s; +} + +/* ---- Hero ---- */ +.hero { + position: relative; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 120px 0 80px; + overflow: hidden; +} + +.hero-bg { + position: absolute; + inset: 0; + z-index: 0; +} + +.stars { + position: absolute; + inset: 0; +} + +.star { + position: absolute; + width: 2px; + height: 2px; + background: white; + border-radius: 50%; + animation: twinkle var(--duration) ease-in-out infinite; + opacity: 0; +} + +@keyframes twinkle { + 0%, 100% { opacity: 0; } + 50% { opacity: var(--max-opacity); } +} + +.grid-overlay { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(59, 130, 246, 0.03) 1px, transparent 1px), + linear-gradient(90deg, rgba(59, 130, 246, 0.03) 1px, transparent 1px); + background-size: 60px 60px; + mask-image: radial-gradient(ellipse at center, black 30%, transparent 70%); + -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 70%); +} + +.hero-content { + position: relative; + z-index: 1; + text-align: center; + max-width: 800px; +} + +.hero-badge { + display: inline-flex; + align-items: center; + gap: 8px; + background: var(--bg-card); + border: 1px solid var(--border); + padding: 8px 20px; + border-radius: 50px; + font-size: 0.85rem; + color: var(--text-secondary); + margin-bottom: 32px; +} + +.badge-dot { + width: 8px; + height: 8px; + background: var(--accent-green); + border-radius: 50%; + animation: pulse-dot 2s ease-in-out infinite; +} + +@keyframes pulse-dot { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.4; } +} + +.hero-title { + font-size: clamp(2.5rem, 6vw, 4.2rem); + font-weight: 800; + line-height: 1.1; + margin-bottom: 24px; + letter-spacing: -0.02em; +} + +.gradient-text { + background: var(--gradient-hero); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} + +.hero-subtitle { + font-size: 1.15rem; + color: var(--text-secondary); + max-width: 640px; + margin: 0 auto 40px; + line-height: 1.7; +} + +.hero-subtitle strong { + color: var(--text-primary); +} + +.hero-actions { + display: flex; + gap: 16px; + justify-content: center; + flex-wrap: wrap; + margin-bottom: 60px; +} + +/* Buttons */ +.btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 12px 28px; + border-radius: var(--radius-md); + font-weight: 600; + font-size: 0.95rem; + transition: all 0.25s ease; + cursor: pointer; + border: none; +} + +.btn-primary { + background: var(--gradient-primary); + color: white; + box-shadow: 0 4px 16px rgba(59, 130, 246, 0.3); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(59, 130, 246, 0.4); + color: white; +} + +.btn-secondary { + background: var(--bg-card); + color: var(--text-primary); + border: 1px solid var(--border); +} + +.btn-secondary:hover { + border-color: var(--accent-blue); + background: var(--bg-card-hover); + color: var(--text-primary); +} + +.btn-lg { + padding: 16px 36px; + font-size: 1.05rem; +} + +/* Terminal */ +.hero-terminal, .scenario-command { + background: #0d1117; + border: 1px solid #30363d; + border-radius: var(--radius-lg); + overflow: hidden; + text-align: left; + max-width: 700px; + margin: 0 auto; + box-shadow: var(--shadow-lg); +} + +.terminal-header { + display: flex; + align-items: center; + gap: 8px; + padding: 12px 16px; + background: #161b22; + border-bottom: 1px solid #30363d; +} + +.terminal-dot { + width: 12px; + height: 12px; + border-radius: 50%; +} + +.terminal-dot.red { background: #ff5f57; } +.terminal-dot.yellow { background: #febc2e; } +.terminal-dot.green { background: #28c840; } + +.terminal-title { + margin-left: 8px; + font-size: 0.8rem; + color: #8b949e; + font-family: var(--font-mono); +} + +.terminal-body { + padding: 20px; + font-family: var(--font-mono); + font-size: 0.85rem; + line-height: 1.8; +} + +.terminal-line { + color: #c9d1d9; + white-space: pre-wrap; + word-break: break-all; +} + +.terminal-line .prompt { + color: var(--accent-green); + margin-right: 8px; +} + +.terminal-line.output { + color: #8b949e; +} + +.terminal-line.success { + color: var(--accent-green); +} + +.terminal-line.info { + color: var(--accent-cyan); +} + +.terminal-line.warn { + color: var(--accent-yellow); +} + +.hero-scroll { + position: absolute; + bottom: 32px; + left: 50%; + transform: translateX(-50%); + z-index: 1; + animation: float 3s ease-in-out infinite; +} + +.hero-scroll a { color: var(--text-muted); } +.hero-scroll a:hover { color: var(--text-primary); } + +@keyframes float { + 0%, 100% { transform: translateX(-50%) translateY(0); } + 50% { transform: translateX(-50%) translateY(8px); } +} + +/* ---- Stats Bar ---- */ +.stats-bar { + background: var(--bg-secondary); + border-top: 1px solid var(--border); + border-bottom: 1px solid var(--border); + padding: 40px 0; +} + +.stats-grid { + display: flex; + justify-content: center; + gap: 48px; + flex-wrap: wrap; +} + +.stat-item { text-align: center; } + +.stat-number { + display: block; + font-size: 2rem; + font-weight: 800; + background: var(--gradient-primary); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} + +.stat-label { + font-size: 0.85rem; + color: var(--text-muted); + margin-top: 4px; +} + +/* ---- Sections ---- */ +.section { + padding: 100px 0; +} + +.section-dark { + background: var(--bg-secondary); +} + +.section-header { + text-align: center; + margin-bottom: 64px; +} + +.section-tag { + display: inline-block; + background: rgba(59, 130, 246, 0.1); + color: var(--accent-blue); + padding: 6px 16px; + border-radius: 50px; + font-size: 0.8rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 16px; +} + +.section-title { + font-size: clamp(1.8rem, 4vw, 2.8rem); + font-weight: 800; + letter-spacing: -0.02em; + margin-bottom: 16px; +} + +.section-subtitle { + font-size: 1.1rem; + color: var(--text-secondary); + max-width: 640px; + margin: 0 auto; +} + +/* ---- Features Grid ---- */ +.features-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +.feature-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 32px; + transition: all 0.3s ease; +} + +.feature-card:hover { + border-color: var(--accent-blue); + transform: translateY(-4px); + box-shadow: var(--shadow-glow); +} + +.feature-icon { + font-size: 2rem; + margin-bottom: 16px; +} + +.feature-card h3 { + font-size: 1.15rem; + font-weight: 700; + margin-bottom: 10px; +} + +.feature-card p { + font-size: 0.9rem; + color: var(--text-secondary); + line-height: 1.6; +} + +/* ---- Architecture ---- */ +.arch-tabs { + display: flex; + justify-content: center; + gap: 8px; + margin-bottom: 40px; +} + +.arch-tab { + padding: 10px 24px; + border-radius: var(--radius-sm); + background: var(--bg-card); + border: 1px solid var(--border); + color: var(--text-secondary); + font-weight: 600; + font-size: 0.9rem; + cursor: pointer; + transition: all 0.2s; + font-family: var(--font-sans); +} + +.arch-tab:hover { border-color: var(--accent-blue); color: var(--text-primary); } + +.arch-tab.active { + background: var(--gradient-primary); + border-color: transparent; + color: white; +} + +.arch-panel { display: none; } +.arch-panel.active { display: block; } + +.arch-diagram { + background: #0d1117; + border: 1px solid #30363d; + border-radius: var(--radius-lg); + padding: 32px; + overflow-x: auto; + margin-bottom: 32px; +} + +.arch-ascii { + font-family: var(--font-mono); + font-size: 0.78rem; + color: var(--accent-cyan); + line-height: 1.5; + white-space: pre; + margin: 0; +} + +.arch-features { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} + +.arch-feature { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-md); + padding: 20px; + font-size: 0.9rem; + color: var(--text-secondary); +} + +.arch-feature strong { + color: var(--text-primary); +} + +/* ---- Investigation Phases ---- */ +.phases-timeline { + max-width: 700px; + margin: 0 auto; + position: relative; +} + +.phases-timeline::before { + content: ''; + position: absolute; + left: 36px; + top: 0; + bottom: 0; + width: 2px; + background: linear-gradient(to bottom, var(--accent-blue), var(--accent-purple), var(--accent-cyan)); +} + +.phase-item { + display: flex; + gap: 28px; + margin-bottom: 48px; + position: relative; +} + +.phase-item:last-child { margin-bottom: 0; } + +.phase-number { + flex-shrink: 0; + width: 72px; + height: 72px; + display: flex; + align-items: center; + justify-content: center; + background: var(--bg-card); + border: 2px solid var(--accent-blue); + border-radius: 50%; + font-size: 1.2rem; + font-weight: 800; + color: var(--accent-blue); + z-index: 1; +} + +.phase-content h3 { + font-size: 1.3rem; + font-weight: 700; + margin-bottom: 8px; + margin-top: 8px; +} + +.phase-content p { + color: var(--text-secondary); + font-size: 0.95rem; + line-height: 1.7; +} + +/* ---- Demo Scenarios ---- */ +.scenarios-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 24px; + margin-bottom: 48px; +} + +.scenario-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 28px; + transition: all 0.3s ease; +} + +.scenario-card:hover { + border-color: var(--accent-purple); + transform: translateY(-4px); + box-shadow: 0 0 40px rgba(139, 92, 246, 0.15); +} + +.scenario-icon { + font-size: 2rem; + margin-bottom: 12px; +} + +.scenario-tag { + display: inline-block; + background: rgba(139, 92, 246, 0.1); + color: var(--accent-purple); + padding: 4px 12px; + border-radius: 50px; + font-family: var(--font-mono); + font-size: 0.75rem; + font-weight: 600; + margin-bottom: 12px; +} + +.scenario-card h3 { + font-size: 1.1rem; + font-weight: 700; + margin-bottom: 8px; +} + +.scenario-card p { + font-size: 0.88rem; + color: var(--text-secondary); + line-height: 1.6; +} + +.scenario-command { + max-width: 600px; + margin: 0 auto; +} + +/* ---- Remediation Policies ---- */ +.policy-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 24px; +} + +.policy-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 28px; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.policy-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; +} + +.policy-level-0::before { background: var(--accent-green); } +.policy-level-1::before { background: var(--accent-yellow); } +.policy-level-2::before { background: var(--accent-orange); } +.policy-level-3::before { background: var(--accent-red); } + +.policy-level { + font-family: var(--font-mono); + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 12px; +} + +.policy-level-0 .policy-level { color: var(--accent-green); } +.policy-level-1 .policy-level { color: var(--accent-yellow); } +.policy-level-2 .policy-level { color: var(--accent-orange); } +.policy-level-3 .policy-level { color: var(--accent-red); } + +.policy-card h3 { + font-size: 1.05rem; + font-weight: 700; + margin-bottom: 8px; +} + +.policy-card p { + font-size: 0.85rem; + color: var(--text-secondary); + margin-bottom: 16px; +} + +.policy-card ul { + list-style: none; + padding: 0; +} + +.policy-card li { + font-size: 0.82rem; + color: var(--text-muted); + padding: 4px 0; + padding-left: 16px; + position: relative; +} + +.policy-card li::before { + content: '>'; + position: absolute; + left: 0; + font-family: var(--font-mono); + color: var(--accent-blue); +} + +/* ---- Metrics ---- */ +.metrics-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +.metric-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 28px; + transition: all 0.3s ease; +} + +.metric-card:hover { + border-color: var(--accent-blue); + box-shadow: var(--shadow-glow); +} + +.metric-header { + margin-bottom: 20px; +} + +.metric-label { + font-size: 0.85rem; + color: var(--text-secondary); + font-weight: 600; +} + +.metric-comparison { + display: flex; + align-items: center; + gap: 16px; +} + +.metric-before, .metric-after { + flex: 1; + text-align: center; +} + +.metric-before .metric-value { + font-size: 1.6rem; + font-weight: 800; + color: var(--accent-red); + display: block; +} + +.metric-after .metric-value { + font-size: 1.6rem; + font-weight: 800; + color: var(--accent-green); + display: block; +} + +.metric-unit { + font-size: 0.75rem; + color: var(--text-muted); +} + +.metric-arrow { + font-size: 1.5rem; + color: var(--text-muted); + flex-shrink: 0; +} + +/* ---- Tech Stack ---- */ +.tech-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; +} + +.tech-item { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-md); + padding: 24px; + text-align: center; + transition: all 0.3s ease; +} + +.tech-item:hover { + border-color: var(--accent-blue); + transform: translateY(-2px); +} + +.tech-name { + font-weight: 700; + font-size: 1rem; + margin-bottom: 4px; +} + +.tech-desc { + font-size: 0.8rem; + color: var(--text-muted); +} + +/* ---- Timeline ---- */ +.timeline { + max-width: 700px; + margin: 0 auto; + position: relative; + padding-left: 40px; +} + +.timeline::before { + content: ''; + position: absolute; + left: 8px; + top: 0; + bottom: 0; + width: 2px; + background: linear-gradient(to bottom, var(--accent-blue), var(--accent-purple), var(--accent-cyan), var(--text-muted)); +} + +.timeline-item { + position: relative; + margin-bottom: 48px; +} + +.timeline-item:last-child { margin-bottom: 0; } + +.timeline-marker { + position: absolute; + left: -40px; + top: 6px; + width: 18px; + height: 18px; + border-radius: 50%; + background: var(--accent-blue); + border: 3px solid var(--bg-primary); + z-index: 1; +} + +.timeline-future .timeline-marker { + background: var(--text-muted); + border-style: dashed; + border-color: var(--text-muted); +} + +.section-dark .timeline-marker { + border-color: var(--bg-secondary); +} + +.timeline-date { + display: inline-block; + font-family: var(--font-mono); + font-size: 0.8rem; + color: var(--accent-blue); + margin-bottom: 8px; +} + +.timeline-future .timeline-date { + color: var(--text-muted); +} + +.timeline-content h3 { + font-size: 1.2rem; + font-weight: 700; + margin-bottom: 8px; +} + +.timeline-content p, +.timeline-content ul { + font-size: 0.9rem; + color: var(--text-secondary); + line-height: 1.7; +} + +.timeline-content ul { + list-style: none; + padding: 0; +} + +.timeline-content li { + padding-left: 16px; + position: relative; + margin-bottom: 4px; +} + +.timeline-content li::before { + content: '>'; + position: absolute; + left: 0; + color: var(--accent-purple); + font-family: var(--font-mono); +} + +/* ---- Quick Start ---- */ +.quickstart-steps { + max-width: 700px; + margin: 0 auto; +} + +.qs-step { + display: flex; + gap: 24px; + margin-bottom: 40px; +} + +.qs-step:last-child { margin-bottom: 0; } + +.qs-number { + flex-shrink: 0; + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + background: var(--gradient-primary); + border-radius: 50%; + font-weight: 800; + font-size: 1.1rem; + color: white; +} + +.qs-content { flex: 1; } + +.qs-content h3 { + font-size: 1.15rem; + font-weight: 700; + margin-bottom: 12px; +} + +.code-block { + background: #0d1117; + border: 1px solid #30363d; + border-radius: var(--radius-md); + overflow-x: auto; +} + +.code-block pre { + margin: 0; + padding: 20px; +} + +.code-block code { + font-family: var(--font-mono); + font-size: 0.82rem; + color: #c9d1d9; + line-height: 1.8; +} + +/* ---- CTA Section ---- */ +.section-cta { + text-align: center; + background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(139, 92, 246, 0.08)); + border-top: 1px solid var(--border); + border-bottom: 1px solid var(--border); +} + +.section-cta h2 { + font-size: clamp(1.8rem, 4vw, 2.5rem); + font-weight: 800; + margin-bottom: 16px; +} + +.section-cta p { + color: var(--text-secondary); + font-size: 1.1rem; + margin-bottom: 32px; +} + +.cta-actions { + display: flex; + gap: 16px; + justify-content: center; + flex-wrap: wrap; +} + +/* ---- Footer ---- */ +.footer { + background: var(--bg-secondary); + border-top: 1px solid var(--border); + padding: 64px 0 32px; +} + +.footer-grid { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr; + gap: 48px; + margin-bottom: 48px; +} + +.footer-logo { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + font-size: 1.1rem; + color: var(--text-primary); + margin-bottom: 12px; +} + +.footer-brand p { + color: var(--text-muted); + font-size: 0.9rem; + line-height: 1.6; +} + +.footer-links h4 { + font-size: 0.85rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--text-secondary); + margin-bottom: 16px; +} + +.footer-links a { + display: block; + color: var(--text-muted); + font-size: 0.9rem; + padding: 4px 0; + transition: color 0.2s; +} + +.footer-links a:hover { color: var(--text-primary); } + +.footer-bottom { + border-top: 1px solid var(--border); + padding-top: 24px; + text-align: center; +} + +.footer-bottom p { + font-size: 0.85rem; + color: var(--text-muted); +} + +.footer-tagline { + margin-top: 8px; + font-style: italic; +} + +/* ---- Animations ---- */ +[data-aos] { + opacity: 0; + transform: translateY(24px); + transition: opacity 0.6s ease, transform 0.6s ease; +} + +[data-aos].visible { + opacity: 1; + transform: translateY(0); +} + +/* ---- Responsive ---- */ +@media (max-width: 1024px) { + .features-grid { grid-template-columns: repeat(2, 1fr); } + .metrics-grid { grid-template-columns: repeat(2, 1fr); } + .policy-grid { grid-template-columns: repeat(2, 1fr); } + .tech-grid { grid-template-columns: repeat(4, 1fr); } + .arch-features { grid-template-columns: 1fr; } + .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; } +} + +@media (max-width: 768px) { + .nav-links { + display: none; + position: absolute; + top: 100%; + left: 0; + right: 0; + background: rgba(10, 14, 23, 0.98); + backdrop-filter: blur(20px); + flex-direction: column; + padding: 24px; + gap: 16px; + border-bottom: 1px solid var(--border); + } + + .nav-links.open { display: flex; } + .nav-toggle { display: flex; } + + .features-grid { grid-template-columns: 1fr; } + .metrics-grid { grid-template-columns: 1fr; } + .policy-grid { grid-template-columns: 1fr; } + .tech-grid { grid-template-columns: repeat(2, 1fr); } + .stats-grid { gap: 24px; } + + .hero-title { font-size: 2.2rem; } + + .phases-timeline::before { left: 28px; } + .phase-number { width: 56px; height: 56px; font-size: 1rem; } + + .footer-grid { grid-template-columns: 1fr; gap: 32px; } + + .arch-ascii { font-size: 0.6rem; } + + .qs-step { flex-direction: column; gap: 16px; } +} + +@media (max-width: 480px) { + .hero { padding: 100px 0 60px; } + .section { padding: 64px 0; } + .hero-terminal { margin: 0 -12px; border-radius: var(--radius-md); } + .scenario-command { margin: 0 -12px; border-radius: var(--radius-md); } + .stats-grid { flex-direction: column; gap: 16px; } + .stat-item { display: flex; align-items: center; gap: 12px; } + .stat-number { font-size: 1.5rem; } +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..c25f905 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,745 @@ + + +
+ + ++ TheNightOps is an autonomous SRE agent that investigates Kubernetes incidents, + generates root cause analyses, and recommends remediation — reducing MTTR + from 45+ minutes to under 5 minutes. +
+ +Multi-agent AI orchestration that correlates logs, events, deployments, and metrics across your entire Kubernetes infrastructure.
+6 specialized agents work in parallel — Log Analyst, Deployment Correlator, Runbook Retriever, Communication Drafter, Anomaly Detector, and Root Orchestrator.
+WebSocket-powered live investigation UI with phase progress tracking, severity-colored findings, and auto-generated RCA summaries.
+TF-IDF similarity matching learns from past incidents. Flags recurring patterns and accelerates diagnosis with historical context.
+4-level policy engine: auto-approve safe actions, require approval for risky ones, and block dangerous operations entirely.
+Official Google Cloud MCP servers (GKE, Cloud Observability) plus custom servers for Kubernetes, Cloud Logging, Slack, and more.
+Accept alerts from Grafana, Alertmanager, PagerDuty, or custom webhooks. K8s event watcher and proactive anomaly scheduler included.
+Plan A: Full multi-agent MCP mode for production. Plan B: Simple kubectl-based mode for quick demos and testing — zero MCP setup needed.
+Track MTTR, RCA consistency, auto-resolution rate, engineer hours saved, and recurring incident patterns across all investigations.
+Send RCA reports and incident updates via Slack, Email (SMTP), Telegram, or WhatsApp Business API automatically.
+Multi-agent orchestration powered by Google ADK, connected to your infrastructure via MCP.
++ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +β Webhook Receiver / CLI / Event Watcher / Scheduler β +βββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ + β + βββββββββββββββΌβββββββββββββββ + β Root Orchestrator β + β (ADK + Gemini 3.1 Pro) β + βββββββββββββββ¬βββββββββββββββ + β delegates + ββββββββββββ¬ββββββββββββΌββββββββββββ¬βββββββββββ + βΌ βΌ βΌ βΌ βΌ + βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ + β Log β β Deploy β β Runbook β β Comms β β Anomaly β + β Analyst β βCorrelatorβ βRetrieverβ β Drafter β βDetector β + ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ + β β β β β + βββββββ¬ββββββ β β β + βΌ βΌ βΌ βΌ + βββββββββββββββββββββ ββββββββββββ ββββββββββββ βββββββββββ + β GKE MCP Server β β Cloud β β Incident β β Policy β + β (Official GCP) β βObs. MCP β β Memory β β Engine β + βββββββββββββββββββββ ββββββββββββ ββββββββββββ βββββββββββ ++
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +β Webhook Receiver / CLI / Event Watcher β +ββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ + β + ββββββββββββΌβββββββββββ + β Simple Agent β + β (ADK + Gemini) β + ββββββββββββ¬βββββββββββ + β + ββββββββββββββββΌβββββββββββββββ + βΌ βΌ βΌ + ββββββββββββββ ββββββββββββββ ββββββββββββββ + β kubectl β β kubectl β β kubectl β + β get pods β β logs β β top β + β get events β β describe β β rollout β + ββββββββββββββ ββββββββββββββ ββββββββββββββ + β + (Any kubectl-configured cluster) ++
From alert to RCA in under 5 minutes, fully automated.
+Incident received via webhook or CLI. Agent checks pod status, events, and namespace scope to understand the blast radius.
+Sub-agents query logs, resource usage, deployment history, and YAML configs in parallel. Cloud Logging patterns are correlated with K8s events.
+Findings from all agents are aggregated. Gemini correlates evidence across systems to identify the root cause with a confidence score.
+Structured RCA is generated. Remediation actions are evaluated against the policy engine. Safe actions auto-execute; risky ones await approval.
+Each scenario demonstrates a real-world incident pattern that TheNightOps can detect, diagnose, and resolve.
+Pod gradually consumes memory, gets OOMKilled, enters CrashLoopBackOff. Agent traces the leak, correlates with deployment version, recommends rollback.
+Unoptimized endpoint causes CPU throttling and cascading latency. Agent identifies the hot endpoint, finds the code path, correlates with recent deploy.
+Database connection pool exhaustion triggers 504s across dependent services. Agent maps the cascade, identifies the root DB timeout, traces to config change.
+Misconfigured environment variable causes 50% failure rate. Agent detects the error spike, correlates with recent env var change, recommends revert.
+Instant memory allocation exhausts limits within seconds. Agent detects OOMKill events, compares limits vs usage, identifies the allocation bug.
+Four levels of autonomy ensure safe operations across all environments.
+Safe, read-only or notification actions that can't cause harm.
+Auto in dev/staging, require approval in production.
+Potentially impactful actions that always need human sign-off.
+Dangerous operations that are never allowed.
+Measured improvements across real incident investigation workflows.
+Multi-agent architecture with custom MCP servers. Webhook receiver, policy engine, and CLI. 5 demo failure scenarios.
+Gemini 3.1 Pro upgrade. Official Google Cloud MCP support. Plan B Simple Mode for zero-setup demos. Real-time WebSocket dashboard.
+Incident Memory with TF-IDF similarity. ADK Web wrapper. Architecture deep-dive documentation. Commons Clause licensing.
+git clone https://github.com/nomadicmehul/TheNightOps.git
+cd TheNightOps
+python3 -m venv .venv && source .venv/bin/activate
+pip install -e ".[dev]"
+ cp config/.env.example config/.env
+# Edit config/.env with your GOOGLE_API_KEY
+nightops verify
+ # Simple Mode (no MCP setup needed)
+nightops agent run --simple \
+ --incident "Pod OOMKilled in production"
+
+# Or launch the dashboard
+nightops dashboard
+ TheNightOps is open-source and ready for your Kubernetes clusters.
+ +Help keep this project alive and growing. Your support fuels late-night debugging sessions and new features.
+A one-time contribution to keep the caffeine flowing and the agents running.
+ + + Buy Me a Coffee + +Become a recurring sponsor and get your name in the project README and release notes.
+ + + Sponsor on GitHub + +Not ready to sponsor? A GitHub star helps with visibility and means a lot to the project.
+ + + Star on GitHub + +