From 84e45b5c402c2d309a3e0f7a12749652e76f359c Mon Sep 17 00:00:00 2001 From: teknium1 Date: Mon, 2 Mar 2026 22:03:43 -0800 Subject: [PATCH] feat: tabbed platform installer on landing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an interactive OS selector widget to the hero section and install steps, inspired by OpenClaw's install UI: - macOS-style window chrome with red/yellow/green dots - Three clickable tabs: Linux/macOS, PowerShell, CMD - Command text, shell prompt, and note update on tab click - Auto-detects visitor's OS and selects the right tab on page load - Install steps section also gets synced platform tabs - Simplified Windows note section (tabs above now cover all platforms) - Fully responsive — icons hidden on mobile, tabs wrap properly --- landingpage/index.html | 59 +++++++++++------ landingpage/script.js | 74 ++++++++++++++++++++- landingpage/style.css | 141 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 242 insertions(+), 32 deletions(-) diff --git a/landingpage/index.html b/landingpage/index.html index bc1aa859e..2d1f99972 100644 --- a/landingpage/index.html +++ b/landingpage/index.html @@ -69,14 +69,38 @@

-
- curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash - +
+
+
+ + + +
+
+ + + +
+
+
+ $ + curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash + +
-

Works on Linux & macOS · No Python prerequisite · Installs everything automatically

+

Works on Linux, macOS & WSL · No prerequisites · Installs everything automatically

@@ -394,14 +422,7 @@ hermes gateway install
-

Windows? Use WSL or PowerShell:

-
-
- powershell - -
-
irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex
-
+

🪟 Windows requires Git for Windows — Hermes uses Git Bash internally for shell commands.

diff --git a/landingpage/script.js b/landingpage/script.js index 6f1c6c105..422ba3bea 100644 --- a/landingpage/script.js +++ b/landingpage/script.js @@ -2,11 +2,79 @@ // Hermes Agent Landing Page — Interactions // ========================================================================= +// --- Platform install commands --- +const PLATFORMS = { + linux: { + command: 'curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash', + prompt: '$', + note: 'Works on Linux, macOS & WSL · No prerequisites · Installs everything automatically', + stepNote: 'Installs uv, Python 3.11, clones the repo, sets up everything. No sudo needed.', + }, + powershell: { + command: 'irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex', + prompt: 'PS>', + note: 'Windows PowerShell · Requires Git for Windows · Installs everything automatically', + stepNote: 'Requires Git for Windows. Installs uv, Python 3.11, sets up everything.', + }, + cmd: { + command: 'curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.cmd -o install.cmd && install.cmd && del install.cmd', + prompt: '>', + note: 'Windows CMD · Requires Git for Windows · Installs everything automatically', + stepNote: 'Requires Git for Windows. Downloads and runs the installer, then cleans up.', + }, +}; + +function detectPlatform() { + const ua = navigator.userAgent.toLowerCase(); + if (ua.includes('win')) return 'powershell'; + return 'linux'; +} + +function switchPlatform(platform) { + const cfg = PLATFORMS[platform]; + if (!cfg) return; + + // Update hero install widget + const commandEl = document.getElementById('install-command'); + const promptEl = document.getElementById('install-prompt'); + const noteEl = document.getElementById('install-note'); + + if (commandEl) commandEl.textContent = cfg.command; + if (promptEl) promptEl.textContent = cfg.prompt; + if (noteEl) noteEl.textContent = cfg.note; + + // Update active tab in hero + document.querySelectorAll('.install-tab').forEach(tab => { + tab.classList.toggle('active', tab.dataset.platform === platform); + }); + + // Sync the step section tabs too + switchStepPlatform(platform); +} + +function switchStepPlatform(platform) { + const cfg = PLATFORMS[platform]; + if (!cfg) return; + + const commandEl = document.getElementById('step1-command'); + const copyBtn = document.getElementById('step1-copy'); + const noteEl = document.getElementById('step1-note'); + + if (commandEl) commandEl.textContent = cfg.command; + if (copyBtn) copyBtn.setAttribute('data-text', cfg.command); + if (noteEl) noteEl.textContent = cfg.stepNote; + + // Update active tab in step section + document.querySelectorAll('.code-tab').forEach(tab => { + tab.classList.toggle('active', tab.dataset.platform === platform); + }); +} + // --- Copy to clipboard --- function copyInstall() { const text = document.getElementById('install-command').textContent; navigator.clipboard.writeText(text).then(() => { - const btn = document.querySelector('.hero-install .copy-btn'); + const btn = document.querySelector('.install-widget-body .copy-btn'); const original = btn.querySelector('.copy-text').textContent; btn.querySelector('.copy-text').textContent = 'Copied!'; btn.style.color = 'var(--gold)'; @@ -243,6 +311,10 @@ class TerminalDemo { // --- Initialize --- document.addEventListener('DOMContentLoaded', () => { + // Auto-detect platform and set the right install command + const detectedPlatform = detectPlatform(); + switchPlatform(detectedPlatform); + initScrollAnimations(); // Terminal demo - start when visible diff --git a/landingpage/style.css b/landingpage/style.css index f75057d62..cf05a7a8b 100644 --- a/landingpage/style.css +++ b/landingpage/style.css @@ -245,33 +245,132 @@ strong { margin-bottom: 32px; } -.install-box { - display: flex; - align-items: center; - gap: 0; +/* --- Install Widget (hero tabbed installer) --- */ +.install-widget { + max-width: 740px; + margin: 0 auto; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); + overflow: hidden; + transition: border-color 0.3s; +} + +.install-widget:hover { + border-color: var(--border-hover); +} + +.install-widget-header { + display: flex; + align-items: center; + gap: 16px; + padding: 10px 16px; + background: rgba(255, 255, 255, 0.02); + border-bottom: 1px solid var(--border); +} + +.install-dots { + display: flex; + gap: 6px; + flex-shrink: 0; +} + +.install-dots .dot { + width: 10px; + height: 10px; + border-radius: 50%; +} + +.install-tabs { + display: flex; + gap: 4px; + flex-wrap: wrap; +} + +.install-tab { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 5px 14px; + border: none; + border-radius: 6px; + font-family: var(--font-sans); + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; + background: transparent; + color: var(--text-muted); +} + +.install-tab:hover { + color: var(--text-dim); + background: rgba(255, 255, 255, 0.04); +} + +.install-tab.active { + background: rgba(255, 215, 0, 0.12); + color: var(--gold); +} + +.install-tab svg { + flex-shrink: 0; +} + +.install-widget-body { + display: flex; + align-items: center; + gap: 10px; padding: 14px 16px; - max-width: 680px; - margin: 0 auto; font-family: var(--font-mono); font-size: 13px; color: var(--text); overflow-x: auto; - transition: border-color 0.3s; } -.install-box:hover { - border-color: var(--border-hover); +.install-prompt { + color: var(--gold); + font-weight: 600; + flex-shrink: 0; + opacity: 0.7; } -.install-box code { +.install-widget-body code { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left; + transition: opacity 0.15s; +} + +/* --- Code block tabs (install step section) --- */ +.code-tabs { + display: flex; + gap: 2px; +} + +.code-tab { + padding: 3px 10px; + border: none; + border-radius: 4px; + font-family: var(--font-mono); + font-size: 11px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; + background: transparent; + color: var(--text-muted); +} + +.code-tab:hover { + color: var(--text-dim); + background: rgba(255, 255, 255, 0.04); +} + +.code-tab.active { + background: rgba(255, 215, 0, 0.1); + color: var(--gold); } .copy-btn { @@ -948,17 +1047,35 @@ strong { margin: 0 auto 28px; } - .install-box { + .install-widget-body { font-size: 10px; padding: 10px 12px; } - .install-box code { + .install-widget-body code { overflow: hidden; text-overflow: ellipsis; display: block; } + .install-widget-header { + padding: 8px 12px; + gap: 10px; + } + + .install-tabs { + gap: 2px; + } + + .install-tab { + padding: 4px 10px; + font-size: 11px; + } + + .install-tab svg { + display: none; + } + .copy-btn { padding: 3px 6px; }