Public: anyone can read this; the crew can change it.
forked from trevato/cs · proposes · 4 behind
One page shell serves both games: the document, the style and the stage move to src/pages/shell.ts #21
Check · Review · Land · Live done — Landed and live in production.
`src/pages/shell.ts` is the document every game on this server is served inside, and it knows nothing about Counter-Strike: `page({ title, description, heading, env, pull, commit, script, ssh, terminalLead, stageHtml, sectionsHtml, footer, extraStyle })` renders the doctype, the head, the one `<style>` block, the header with its environment pill and short commit, `<main>`, the terminal line, the f…
shipped production is serving it deploy ae07c2d
Sign in to join this conversation.
new above
offline
src/pages/shell.tsis the document every game on this server is served inside, and it knows nothing about Counter-Strike:page({ title, description, heading, env, pull, commit, script, ssh, terminalLead, stageHtml, sectionsHtml, footer, extraStyle })renders the doctype, the head, the one<style>block, the header with its environment pill and short commit,<main>, the terminal line, the footer and the single<script type="module" src>, andstage({ overlays, touch })renders#stagewith#scene,#hud,#fpsand the#touchpads built from{ action, label }buttons.src/pages/game.tsis down to cs's own content — the three overlays, its touch buttons, the leaderboard, the prose andstatsHtml— plus the call to the shell; it still exportsescape, now re-exported from the shell so there is one implementation andsrc/server.tsis untouched.The escaping is stated in the parameter names: text is escaped by the shell, markup the caller already rendered says so (
stageHtml,sectionsHtml, an overlay'shtml) and is written through.src/pages/shell.test.tsputs</script><script>alert(1)</script>through the title, description, heading, env, commit, ssh, footer, script and a touch label, action and overlay id, and checks the page still holds exactly one<script>and one<style>; astatsHtml-shaped table with an&in it comes back unchanged. A rule only one game needs goes inextraStyle, appended to the shared block with<rewritten as CSS's\3cso it cannot close the block.What to look at in the preview:
/should be indistinguishable from production. The rendered HTML diff is two lines — the terminal sentence moved from the last paragraph of the "What this is" section to a<p class="terminal">at the end of<main>(same markup, one node later, so the gap above it goes from 16px to 24px; it lives in the shell now because every game needs that line and none should reinvent it), and the footer's apostrophe is', which renders identically. Everything else is byte-for-byte what it was, including the whitespace./answered in a median of 0.39 ms, p95 1.56 ms over 200 warm loopback requests.bun testis 176 passing, up from 166 — nine inshell.test.tsand one inserver.test.tsthat pinsscene,hud,fps,touch,menu,pause,buy,stats,name,length,side,sens,play,resume,quitand the six[data-action]buttons against the served page, because nothing type-checks them. No bundle was rebuilt:static/is not in the diff, no dependency was added, and the security floor stays insrc/server.ts— the shell only renders a body.🤖 Generated with Claude Code
Closes #17