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 β€” Autonomous SRE Agent for Kubernetes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ + v0.3.0 — Built with Google ADK +
+

+ Your On-Call Engineer
+ Can Finally Sleep +

+

+ 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. +

+ +
+
+ + + + nightops +
+
+
+ $ nightops agent run --simple --incident "Pod OOMKilled in production" +
+
+
+
+
+ + + +
+
+ + +
+
+
+
+ < 5 + Min MTTR +
+
+ 6 + AI Agents +
+
+ 4 + MCP Servers +
+
+ 5 + Demo Scenarios +
+
+ 4 + Webhook Sources +
+
+
+
+ + +
+
+
+ +

Everything Your SRE Team Needs

+

Multi-agent AI orchestration that correlates logs, events, deployments, and metrics across your entire Kubernetes infrastructure.

+
+
+
+
πŸ”
+

Multi-Agent Investigation

+

6 specialized agents work in parallel — Log Analyst, Deployment Correlator, Runbook Retriever, Communication Drafter, Anomaly Detector, and Root Orchestrator.

+
+
+
πŸ“Š
+

Real-Time Dashboard

+

WebSocket-powered live investigation UI with phase progress tracking, severity-colored findings, and auto-generated RCA summaries.

+
+
+
🧠
+

Incident Memory

+

TF-IDF similarity matching learns from past incidents. Flags recurring patterns and accelerates diagnosis with historical context.

+
+
+
πŸ›‘οΈ
+

Graduated Remediation

+

4-level policy engine: auto-approve safe actions, require approval for risky ones, and block dangerous operations entirely.

+
+
+
πŸ”Œ
+

MCP Integration

+

Official Google Cloud MCP servers (GKE, Cloud Observability) plus custom servers for Kubernetes, Cloud Logging, Slack, and more.

+
+
+
πŸ“‘
+

Multi-Source Ingestion

+

Accept alerts from Grafana, Alertmanager, PagerDuty, or custom webhooks. K8s event watcher and proactive anomaly scheduler included.

+
+
+
πŸ€–
+

Dual-Mode Architecture

+

Plan A: Full multi-agent MCP mode for production. Plan B: Simple kubectl-based mode for quick demos and testing — zero MCP setup needed.

+
+
+
πŸ“ˆ
+

Metrics & Impact Tracking

+

Track MTTR, RCA consistency, auto-resolution rate, engineer hours saved, and recurring incident patterns across all investigations.

+
+
+
πŸ“’
+

Multi-Channel Notifications

+

Send RCA reports and incident updates via Slack, Email (SMTP), Telegram, or WhatsApp Business API automatically.

+
+
+
+
+ + +
+
+
+ +

Built for Production SRE

+

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  β”‚
+  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
+
+
+
+
+ Official Google Cloud MCP — IAM-authenticated access to GKE clusters and Cloud Observability +
+
+ Parallel Investigation — Sub-agents work simultaneously for faster diagnosis +
+
+ Full Reasoning Chain — Each agent contributes specialized analysis to the root cause +
+
+
+
+
+
+β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
+β”‚     Webhook Receiver  /  CLI  /  Event Watcher       β”‚
+β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
+                         β”‚
+              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
+              β”‚    Simple Agent     β”‚
+              β”‚  (ADK + Gemini)     β”‚
+              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
+                         β”‚
+          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
+          β–Ό              β–Ό              β–Ό
+   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
+   β”‚ kubectl    β”‚ β”‚ kubectl    β”‚ β”‚ kubectl    β”‚
+   β”‚ get pods   β”‚ β”‚ logs       β”‚ β”‚ top        β”‚
+   β”‚ get events β”‚ β”‚ describe   β”‚ β”‚ rollout    β”‚
+   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
+                         β”‚
+              (Any kubectl-configured cluster)
+
+
+
+
+ Zero MCP Setup — Works with any cluster where kubectl is configured +
+
+ Single Agent — Direct kubectl subprocess calls for maximum reliability +
+
+ Perfect for Demos — Get started in minutes, no GCP project required +
+
+
+
+
+
+ + +
+
+
+ +

4-Phase Autonomous Investigation

+

From alert to RCA in under 5 minutes, fully automated.

+
+
+
+
01
+
+

Triage

+

Incident received via webhook or CLI. Agent checks pod status, events, and namespace scope to understand the blast radius.

+
+
+
+
02
+
+

Deep Investigation

+

Sub-agents query logs, resource usage, deployment history, and YAML configs in parallel. Cloud Logging patterns are correlated with K8s events.

+
+
+
+
03
+
+

Synthesis

+

Findings from all agents are aggregated. Gemini correlates evidence across systems to identify the root cause with a confidence score.

+
+
+
+
04
+
+

RCA + Remediation

+

Structured RCA is generated. Remediation actions are evaluated against the policy engine. Safe actions auto-execute; risky ones await approval.

+
+
+
+
+
+ + +
+
+
+ +

5 Failure Modes, Fully Automated Recovery

+

Each scenario demonstrates a real-world incident pattern that TheNightOps can detect, diagnose, and resolve.

+
+
+
+
πŸ’Ύ
+
memory-leak
+

Memory Leak → OOMKill

+

Pod gradually consumes memory, gets OOMKilled, enters CrashLoopBackOff. Agent traces the leak, correlates with deployment version, recommends rollback.

+
+
+
πŸ”₯
+
cpu-spike
+

CPU Spike from Bad Query

+

Unoptimized endpoint causes CPU throttling and cascading latency. Agent identifies the hot endpoint, finds the code path, correlates with recent deploy.

+
+
+
🌊
+
cascading-failure
+

Cascading DB Failure

+

Database connection pool exhaustion triggers 504s across dependent services. Agent maps the cascade, identifies the root DB timeout, traces to config change.

+
+
+
βš™οΈ
+
config-drift
+

Config Drift → 5xx Errors

+

Misconfigured environment variable causes 50% failure rate. Agent detects the error spike, correlates with recent env var change, recommends revert.

+
+
+
πŸ’₯
+
oom-kill
+

Aggressive OOMKill

+

Instant memory allocation exhausts limits within seconds. Agent detects OOMKill events, compares limits vs usage, identifies the allocation bug.

+
+
+
+
+ + + + trigger a scenario +
+
+
$ nightops demo trigger -s memory-leak
+
$ nightops demo trigger -s cpu-spike
+
$ nightops demo trigger -s cascading-failure
+
+
+
+
+ + +
+
+
+ +

Graduated Remediation Policies

+

Four levels of autonomy ensure safe operations across all environments.

+
+
+
+
Level 0
+

Auto-Approve

+

Safe, read-only or notification actions that can't cause harm.

+
    +
  • Silence alerts
  • +
  • Create Grafana incidents
  • +
  • Post Slack updates
  • +
+
+
+
Level 1
+

Environment-Gated

+

Auto in dev/staging, require approval in production.

+
    +
  • Pod restarts
  • +
  • Scale-up replicas
  • +
+
+
+
Level 2
+

Always Approve

+

Potentially impactful actions that always need human sign-off.

+
    +
  • Rollbacks
  • +
  • Config reverts
  • +
  • Scale-down
  • +
+
+
+
Level 3
+

Blocked

+

Dangerous operations that are never allowed.

+
    +
  • Delete namespace
  • +
  • Delete PVC
  • +
  • Drain node
  • +
+
+
+
+
+ + +
+
+
+ +

Before vs After TheNightOps

+

Measured improvements across real incident investigation workflows.

+
+
+
+
+ MTTR (investigation) +
+
+
+ 45+ + min +
+
+
+ < 5 + min +
+
+
+
+
+ Context Assembly +
+
+
+ 20+ + min +
+
+
+ Seconds + (parallel) +
+
+
+
+
+ RCA Consistency +
+
+
+ Varies + by engineer +
+
+
+ 100% + standardized +
+
+
+
+
+ Post-Incident Toil +
+
+
+ 90+ + min +
+
+
+ < 10 + min +
+
+
+
+
+ On-Call Cognitive Load +
+
+
+ High + 5 dashboards +
+
+
+ Low + pre-diagnosed +
+
+
+
+
+ Recurring Incidents +
+
+
+ 60% + repeated +
+
+
+ Flagged + & learning +
+
+
+
+
+
+ + +
+
+
+ +

Built With

+
+
+
+
Google ADK
+
Agent orchestration framework
+
+
+
Gemini 3.1 Pro
+
LLM reasoning engine
+
+
+
MCP
+
Model Context Protocol
+
+
+
FastAPI
+
Webhooks & dashboard
+
+
+
Python 3.11+
+
Core language
+
+
+
Kubernetes
+
Target platform
+
+
+
GKE
+
Google Kubernetes Engine
+
+
+
Pydantic
+
Config & validation
+
+
+
+
+ + +
+
+
+ +

Development Milestones

+
+
+
+
+
+ v0.2.0 — Initial Release +

Foundation

+

Multi-agent architecture with custom MCP servers. Webhook receiver, policy engine, and CLI. 5 demo failure scenarios.

+
+
+
+
+
+ v0.3.0 — Major Upgrade +

Dual-Mode Architecture

+

Gemini 3.1 Pro upgrade. Official Google Cloud MCP support. Plan B Simple Mode for zero-setup demos. Real-time WebSocket dashboard.

+
+
+
+
+
+ Latest +

Intelligence & Polish

+

Incident Memory with TF-IDF similarity. ADK Web wrapper. Architecture deep-dive documentation. Commons Clause licensing.

+
+
+
+
+
+ Roadmap +

What's Next

+
    +
  • Multi-cluster support
  • +
  • Grafana MCP integration
  • +
  • Vector DB for incident memory
  • +
  • Auto-remediation execution
  • +
  • Cost impact analysis
  • +
+
+
+
+
+
+ + +
+
+
+ +

Up and Running in Minutes

+
+
+
+
1
+
+

Clone & Install

+
+
git clone https://github.com/nomadicmehul/TheNightOps.git
+cd TheNightOps
+python3 -m venv .venv && source .venv/bin/activate
+pip install -e ".[dev]"
+
+
+
+
+
2
+
+

Configure

+
+
cp config/.env.example config/.env
+# Edit config/.env with your GOOGLE_API_KEY
+nightops verify
+
+
+
+
+
3
+
+

Run Your First Investigation

+
+
# Simple Mode (no MCP setup needed)
+nightops agent run --simple \
+  --incident "Pod OOMKilled in production"
+
+# Or launch the dashboard
+nightops dashboard
+
+
+
+
+
+
+ + +
+
+

Ready to Let Your On-Call Sleep?

+

TheNightOps is open-source and ready for your Kubernetes clusters.

+ +
+
+ + + + + + + From bc681165aee78125c51bfcaf5194ef077d927182 Mon Sep 17 00:00:00 2001 From: Mehul Patel <11514627+nomadicmehul@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:18:46 +0100 Subject: [PATCH 2/3] Added BETA badge, Buy Me a Coffee button, and Sponsor section - BETA tag on hero version badge - Buy Me a Coffee CTA in navbar with orange gradient - Sponsor section with 3 cards: Buy Me a Coffee, GitHub Sponsors, Star the Repo - Updated repo URL to TheNightOps, removed Gemini from branding, removed broken Twitter link --- docs/assets/style.css | 121 ++++++++++++++++++++++++++++++++++++++++++ docs/index.html | 45 ++++++++++++++++ 2 files changed, 166 insertions(+) diff --git a/docs/assets/style.css b/docs/assets/style.css index d9b1a72..4feace5 100644 --- a/docs/assets/style.css +++ b/docs/assets/style.css @@ -136,6 +136,25 @@ img { max-width: 100%; height: auto; } color: var(--text-primary); } +.nav-coffee { + display: flex; + align-items: center; + gap: 6px; + background: linear-gradient(135deg, #ff813f, #ffdd00); + padding: 8px 16px; + border-radius: var(--radius-sm); + color: #1a1a1a !important; + font-weight: 700; + font-size: 0.85rem; + transition: all 0.25s ease; +} + +.nav-coffee:hover { + transform: translateY(-1px); + box-shadow: 0 6px 25px rgba(255, 129, 63, 0.35); + color: #1a1a1a !important; +} + .github-icon { flex-shrink: 0; } .nav-toggle { @@ -232,6 +251,18 @@ img { max-width: 100%; height: auto; } animation: pulse-dot 2s ease-in-out infinite; } +.badge-beta { + background: linear-gradient(135deg, var(--accent-purple), var(--accent-blue)); + color: white; + font-size: 0.65rem; + font-weight: 800; + padding: 2px 8px; + border-radius: 4px; + letter-spacing: 0.08em; + text-transform: uppercase; + margin-left: 4px; +} + @keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } @@ -840,6 +871,94 @@ img { max-width: 100%; height: auto; } flex-shrink: 0; } +/* ---- Sponsor Section ---- */ +.section-sponsor { + background: linear-gradient(135deg, rgba(139, 92, 246, 0.06), rgba(59, 130, 246, 0.06), rgba(6, 182, 212, 0.06)); + border-top: 1px solid var(--border); + border-bottom: 1px solid var(--border); +} + +.sponsor-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +.sponsor-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 36px 28px; + text-align: center; + transition: all 0.3s ease; +} + +.sponsor-card:hover { + transform: translateY(-4px); + border-color: var(--accent-purple); + box-shadow: 0 0 40px rgba(139, 92, 246, 0.15); +} + +.sponsor-featured { + border-color: var(--accent-yellow); + position: relative; + overflow: hidden; +} + +.sponsor-featured::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, #ff813f, #ffdd00); +} + +.sponsor-featured:hover { + border-color: var(--accent-yellow); + box-shadow: 0 0 40px rgba(255, 129, 63, 0.2); +} + +.sponsor-icon { + font-size: 2.5rem; + margin-bottom: 16px; +} + +.sponsor-card h3 { + font-size: 1.2rem; + font-weight: 700; + margin-bottom: 10px; +} + +.sponsor-card p { + font-size: 0.9rem; + color: var(--text-secondary); + line-height: 1.6; + margin-bottom: 24px; +} + +.btn-coffee { + display: inline-flex; + align-items: center; + gap: 8px; + background: linear-gradient(135deg, #ff813f, #ffdd00); + color: #1a1a1a; + padding: 12px 28px; + border-radius: var(--radius-md); + font-weight: 700; + font-size: 0.95rem; + transition: all 0.25s ease; + border: none; + cursor: pointer; +} + +.btn-coffee:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(255, 129, 63, 0.4); + color: #1a1a1a; +} + /* ---- Tech Stack ---- */ .tech-grid { display: grid; @@ -1130,6 +1249,7 @@ img { max-width: 100%; height: auto; } .tech-grid { grid-template-columns: repeat(4, 1fr); } .arch-features { grid-template-columns: 1fr; } .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; } + .sponsor-grid { grid-template-columns: repeat(3, 1fr); } } @media (max-width: 768px) { @@ -1154,6 +1274,7 @@ img { max-width: 100%; height: auto; } .metrics-grid { grid-template-columns: 1fr; } .policy-grid { grid-template-columns: 1fr; } .tech-grid { grid-template-columns: repeat(2, 1fr); } + .sponsor-grid { grid-template-columns: 1fr; } .stats-grid { gap: 24px; } .hero-title { font-size: 2.2rem; } diff --git a/docs/index.html b/docs/index.html index c25f905..d988577 100644 --- a/docs/index.html +++ b/docs/index.html @@ -46,6 +46,10 @@ Impact Timeline Quick Start + + + Buy Me a Coffee + GitHub @@ -67,6 +71,7 @@
v0.3.0 — Built with Google ADK + BETA

Your On-Call Engineer
@@ -542,6 +547,46 @@

Before vs After TheNightOps

+ +
+
From dfb66ab559cc1cf26bd802fb64c252b66f172cfc Mon Sep 17 00:00:00 2001 From: Mehul Patel <11514627+nomadicmehul@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:24:17 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Fix=20navbar=20layout=20=E2=80=94=20tighter?= =?UTF-8?q?=20spacing,=20earlier=20hamburger=20breakpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduced nav link gap and font sizes to fit all items at wide screens. Hamburger menu now triggers at 1024px instead of 768px to prevent cramped layout with Buy Me a Coffee and GitHub buttons. --- docs/assets/style.css | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/docs/assets/style.css b/docs/assets/style.css index 4feace5..710ddf7 100644 --- a/docs/assets/style.css +++ b/docs/assets/style.css @@ -87,7 +87,7 @@ img { max-width: 100%; height: auto; } } .nav-container { - max-width: 1200px; + max-width: 1280px; margin: 0 auto; padding: 0 24px; display: flex; @@ -102,6 +102,8 @@ img { max-width: 100%; height: auto; } font-weight: 700; font-size: 1.2rem; color: var(--text-primary); + flex-shrink: 0; + margin-right: 24px; } .logo-icon { font-size: 1.4rem; } @@ -109,14 +111,15 @@ img { max-width: 100%; height: auto; } .nav-links { display: flex; align-items: center; - gap: 28px; + gap: 20px; } .nav-link { color: var(--text-secondary); - font-size: 0.9rem; + font-size: 0.82rem; font-weight: 500; transition: color 0.2s; + white-space: nowrap; } .nav-link:hover { color: var(--text-primary); } @@ -124,11 +127,13 @@ img { max-width: 100%; height: auto; } .nav-cta { display: flex; align-items: center; - gap: 6px; + gap: 5px; background: var(--bg-card); - padding: 8px 16px; + padding: 6px 14px; border-radius: var(--radius-sm); border: 1px solid var(--border); + white-space: nowrap; + font-size: 0.8rem; } .nav-cta:hover { @@ -139,14 +144,15 @@ img { max-width: 100%; height: auto; } .nav-coffee { display: flex; align-items: center; - gap: 6px; + gap: 5px; background: linear-gradient(135deg, #ff813f, #ffdd00); - padding: 8px 16px; + padding: 6px 14px; border-radius: var(--radius-sm); color: #1a1a1a !important; font-weight: 700; - font-size: 0.85rem; + font-size: 0.8rem; transition: all 0.25s ease; + white-space: nowrap; } .nav-coffee:hover { @@ -1243,16 +1249,6 @@ img { max-width: 100%; height: auto; } /* ---- 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; } - .sponsor-grid { grid-template-columns: repeat(3, 1fr); } -} - -@media (max-width: 768px) { .nav-links { display: none; position: absolute; @@ -1270,6 +1266,17 @@ img { max-width: 100%; height: auto; } .nav-links.open { display: flex; } .nav-toggle { display: flex; } + .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; } + .sponsor-grid { grid-template-columns: repeat(3, 1fr); } +} + +@media (max-width: 768px) { + .features-grid { grid-template-columns: 1fr; } .metrics-grid { grid-template-columns: 1fr; } .policy-grid { grid-template-columns: 1fr; }