Skip to content

Commit 48323bd

Browse files
committed
Configure Vercel static site deployment
1 parent 065bf57 commit 48323bd

7 files changed

Lines changed: 371 additions & 24 deletions

File tree

site/assets/app.js

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(function () {
1+
(function () {
22
"use strict";
33

44
/* ---------------------------------------------------------------------
@@ -18,22 +18,38 @@
1818
var root = document.documentElement;
1919
var THEME_KEY = "ghostrun-theme";
2020

21+
function getStoredTheme() {
22+
try {
23+
return localStorage.getItem(THEME_KEY);
24+
} catch (e) {
25+
return null;
26+
}
27+
}
28+
29+
function setStoredTheme(theme) {
30+
try {
31+
localStorage.setItem(THEME_KEY, theme);
32+
} catch (e) {
33+
/* Theme still applies for this page view when storage is unavailable. */
34+
}
35+
}
36+
2137
function applyTheme(theme) {
2238
root.setAttribute("data-theme", theme);
2339
var btn = document.getElementById("theme-toggle");
2440
if (btn) btn.setAttribute("aria-label", "Switch to " + (theme === "dark" ? "light" : "dark") + " mode");
2541
}
2642

2743
function initTheme() {
28-
var stored = localStorage.getItem(THEME_KEY);
44+
var stored = getStoredTheme();
2945
var theme = stored || (window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark");
3046
applyTheme(theme);
3147
}
3248

3349
function toggleTheme() {
3450
var current = root.getAttribute("data-theme") === "light" ? "light" : "dark";
3551
var next = current === "light" ? "dark" : "light";
36-
localStorage.setItem(THEME_KEY, next);
52+
setStoredTheme(next);
3753
applyTheme(next);
3854
}
3955

@@ -77,14 +93,28 @@
7793
btn.addEventListener("click", function () {
7894
var code = pre.querySelector("code");
7995
var text = code ? code.textContent : pre.textContent;
80-
navigator.clipboard.writeText(text).then(function () {
81-
btn.textContent = "Copied";
82-
btn.classList.add("copied");
96+
if (!navigator.clipboard || !navigator.clipboard.writeText) {
97+
btn.textContent = "Unavailable";
8398
setTimeout(function () {
8499
btn.textContent = "Copy";
85-
btn.classList.remove("copied");
86100
}, 1500);
87-
});
101+
return;
102+
}
103+
navigator.clipboard.writeText(text)
104+
.then(function () {
105+
btn.textContent = "Copied";
106+
btn.classList.add("copied");
107+
setTimeout(function () {
108+
btn.textContent = "Copy";
109+
btn.classList.remove("copied");
110+
}, 1500);
111+
})
112+
.catch(function () {
113+
btn.textContent = "Failed";
114+
setTimeout(function () {
115+
btn.textContent = "Copy";
116+
}, 1500);
117+
});
88118
});
89119
pre.appendChild(btn);
90120
});
@@ -166,15 +196,21 @@
166196
a.href = SITE_BASE + m.url;
167197
a.className = "search-result";
168198
if (i === 0) a.classList.add("active");
169-
a.innerHTML =
170-
'<span class="result-title">' +
171-
m.title +
172-
' <span class="result-crumb">' +
173-
m.section +
174-
"</span></span>" +
175-
'<span class="result-excerpt">' +
176-
m.excerpt +
177-
"</span>";
199+
var title = document.createElement("span");
200+
title.className = "result-title";
201+
title.appendChild(document.createTextNode(m.title + " "));
202+
203+
var crumb = document.createElement("span");
204+
crumb.className = "result-crumb";
205+
crumb.textContent = m.section;
206+
title.appendChild(crumb);
207+
208+
var excerpt = document.createElement("span");
209+
excerpt.className = "result-excerpt";
210+
excerpt.textContent = m.excerpt;
211+
212+
a.appendChild(title);
213+
a.appendChild(excerpt);
178214
results.appendChild(a);
179215
});
180216
results.classList.add("open");
266 KB
Loading

site/assets/ghostrun-hero.webm

Whitespace-only changes.

site/index.html

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<!doctype html>
1+
<!doctype html>
22
<html lang="en">
33
<head>
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1">
6-
<title>ghostrun pytest for LLMs</title>
6+
<title>ghostrun — pytest for LLMs</title>
77
<meta name="description" content="Deterministic HTTP record/replay, local LLM-as-judge semantic assertions, and prompt regression diffing for testing GenAI applications in Python.">
88
<link rel="icon" href="assets/ghost-icon.svg">
99
<link rel="stylesheet" href="assets/style.css">
@@ -57,9 +57,12 @@
5757
<div class="article" style="max-width:960px">
5858

5959
<div class="home-hero">
60-
<img class="hero-gif" src="assets/ghostrun-hero.gif" alt="A ghost travels to the LLM API once, then instantly reappears with the result on every run after">
60+
<video class="hero-gif" autoplay loop muted playsinline poster="assets/ghostrun-hero-poster.jpg" aria-label="A ghost travels to the LLM API once, then instantly reappears with the result on every run after">
61+
<source src="assets/ghostrun-hero.webm" type="video/webm">
62+
<img src="assets/ghostrun-hero.gif" width="560" height="315" alt="A ghost travels to the LLM API once, then instantly reappears with the result on every run after">
63+
</video>
6164
<h1>pytest for LLMs</h1>
62-
<p class="tagline">Deterministic record/replay and semantic assertions for GenAI apps local-first, privacy-first, zero SaaS lock-in.</p>
65+
<p class="tagline">Deterministic record/replay and semantic assertions for GenAI apps — local-first, privacy-first, zero SaaS lock-in.</p>
6366
<div class="home-cta">
6467
<a class="btn btn-primary" href="guide/getting-started.html">Get started</a>
6568
<a class="btn btn-ghost" href="https://github.com/parthmax2/ghostrun" target="_blank" rel="noopener">View on GitHub</a>
@@ -80,15 +83,15 @@ <h3>Deterministic replay</h3>
8083
</div>
8184
<div class="home-card">
8285
<h3>Semantic assertions</h3>
83-
<p>Assert on <em>meaning</em> (<code>contains_intent</code>, <code>tone_is</code>, ), graded by a local Ollama model by default. Your prompts and data never leave your machine.</p>
86+
<p>Assert on <em>meaning</em> (<code>contains_intent</code>, <code>tone_is</code>, …), graded by a local Ollama model by default. Your prompts and data never leave your machine.</p>
8487
</div>
8588
<div class="home-card">
8689
<h3>Regression tracking</h3>
8790
<p>Snapshot runs and diff them: classify every assertion as regression / fix / stable / added / removed, plus output-drift similarity.</p>
8891
</div>
8992
<div class="home-card">
9093
<h3>Native to pytest</h3>
91-
<p>No cloud dashboard, no custom CLI to learn, no dataset to author by hand. Auto-registered as a pytest plugin just <code>pytest</code>.</p>
94+
<p>No cloud dashboard, no custom CLI to learn, no dataset to author by hand. Auto-registered as a pytest plugin — just <code>pytest</code>.</p>
9295
</div>
9396
</div>
9497

@@ -116,7 +119,7 @@ <h2>Research</h2>
116119
</div>
117120

118121
<footer class="site-footer">
119-
<a href="https://github.com/parthmax2/ghostrun" target="_blank" rel="noopener">parthmax2/ghostrun</a> · MIT License
122+
<a href="https://github.com/parthmax2/ghostrun" target="_blank" rel="noopener">parthmax2/ghostrun</a> · MIT License
120123
</footer>
121124

122125
<script src="assets/search-index.js"></script>

0 commit comments

Comments
 (0)