From 593ad125ff6c94f2608d6646973c15ba066f6662 Mon Sep 17 00:00:00 2001 From: Theo Browne Date: Fri, 20 Feb 2026 04:26:14 -0800 Subject: [PATCH] Pause --- bulk-test.ts | 4 ++-- frontend.tsx | 2 +- game.ts | 5 +++++ quipslop-logo-black.svg | 9 +++++++++ quipslop.tsx | 1 + server.ts | 19 +++++++++++++++++++ 6 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 quipslop-logo-black.svg diff --git a/bulk-test.ts b/bulk-test.ts index b222f59..47a4d2a 100644 --- a/bulk-test.ts +++ b/bulk-test.ts @@ -2,7 +2,7 @@ import { appendFileSync } from "node:fs"; import { join } from "node:path"; import { MODELS, - Model, + type Model, shuffle, withRetry, callGeneratePrompt, @@ -141,7 +141,7 @@ async function worker() { } else { completedRounds++; if (result.winner) { - scores[result.winner.name]++; + scores[result.winner.name] = (scores[result.winner.name] ?? 0) + 1; } let roundLog = `\n=== ROUND ${roundNum} ===\n`; diff --git a/frontend.tsx b/frontend.tsx index 4182236..59c21b1 100644 --- a/frontend.tsx +++ b/frontend.tsx @@ -415,7 +415,7 @@ function App() { } if (!state.active && !state.done && state.completed.length > 0) { - return ; + return ; } if (!state.active && !state.done && state.completed.length === 0) { diff --git a/game.ts b/game.ts index f13bca0..ff77ce2 100644 --- a/game.ts +++ b/game.ts @@ -71,6 +71,7 @@ export type GameState = { active: RoundState | null; scores: Record; done: boolean; + isPaused: boolean; }; // ── OpenRouter ────────────────────────────────────────────────────────────── @@ -261,6 +262,10 @@ export async function runGame( rerender: () => void, ) { for (let r = 1; r <= runs; r++) { + while (state.isPaused) { + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + const shuffled = shuffle([...MODELS]); const prompter = shuffled[0]!; const contA = shuffled[1]!; diff --git a/quipslop-logo-black.svg b/quipslop-logo-black.svg new file mode 100644 index 0000000..bbceafe --- /dev/null +++ b/quipslop-logo-black.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/quipslop.tsx b/quipslop.tsx index 21bf1aa..1a002fe 100644 --- a/quipslop.tsx +++ b/quipslop.tsx @@ -223,6 +223,7 @@ function Game({ runs }: { runs: number }) { active: null, scores: Object.fromEntries(MODELS.map((m) => [m.name, 0])), done: false, + isPaused: false, }); const [, setTick] = useState(0); const rerender = useCallback(() => setTick((t) => t + 1), []); diff --git a/server.ts b/server.ts index 25c4eca..5af8792 100644 --- a/server.ts +++ b/server.ts @@ -26,6 +26,7 @@ const gameState: GameState = { active: null, scores: Object.fromEntries(MODELS.map((m) => [m.name, 0])), done: false, + isPaused: false, }; // ── WebSocket clients ─────────────────────────────────────────────────────── @@ -56,6 +57,24 @@ const server = Bun.serve({ const file = Bun.file(path); return new Response(file); } + if (url.pathname === "/api/pause") { + const secret = url.searchParams.get("secret"); + if (process.env.ADMIN_SECRET && secret === process.env.ADMIN_SECRET) { + gameState.isPaused = true; + broadcast(); + return new Response("Paused", { status: 200 }); + } + return new Response("Unauthorized", { status: 401 }); + } + if (url.pathname === "/api/resume") { + const secret = url.searchParams.get("secret"); + if (process.env.ADMIN_SECRET && secret === process.env.ADMIN_SECRET) { + gameState.isPaused = false; + broadcast(); + return new Response("Resumed", { status: 200 }); + } + return new Response("Unauthorized", { status: 401 }); + } if (url.pathname === "/api/history") { const page = parseInt(url.searchParams.get("page") || "1", 10); return new Response(JSON.stringify(getRounds(page)), {