From 15de6eb0c190da98f9271b7de0e24a643a93e9b1 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Aug 2026 00:41:34 +0000 Subject: [PATCH] Add Vercel static-site deployment for the landing page The full app needs a persistent server and local SQLite, so static hosts get only the self-contained landing page: scripts/build-site.mjs copies land.html (as index.html) and land.js into dist-site/, and vercel.json builds that directory with the same security headers the sovereign server sends. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01SAPZf6jJFm45TyBnvzdM6o --- .gitignore | 1 + scripts/build-site.mjs | 18 ++++++++++++++++++ vercel.json | 21 +++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 scripts/build-site.mjs create mode 100644 vercel.json diff --git a/.gitignore b/.gitignore index 6dcbbac..0c29b7b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ __pycache__/ # Build output dist/ +dist-site/ build/ out/ *.egg-info/ diff --git a/scripts/build-site.mjs b/scripts/build-site.mjs new file mode 100644 index 0000000..b4b7268 --- /dev/null +++ b/scripts/build-site.mjs @@ -0,0 +1,18 @@ +#!/usr/bin/env node +// Assemble the static landing site for static hosts (Vercel, Netlify, Pages). +// The full app needs a persistent Node server and a local SQLite database, so +// only the self-contained landing page ships to static hosting: land.html +// becomes index.html and brings its one script along. +import fs from 'node:fs'; +import path from 'node:path'; + +const root = path.resolve(import.meta.dirname, '..'); +const out = path.join(root, 'dist-site'); +const files = { 'land.html': 'index.html', 'land.js': 'land.js' }; + +fs.rmSync(out, { recursive: true, force: true }); +fs.mkdirSync(out, { recursive: true }); +for (const [src, dest] of Object.entries(files)) { + fs.copyFileSync(path.join(root, 'public', src), path.join(out, dest)); +} +console.log(`Static landing site written to ${out} (${Object.keys(files).length} files)`); diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..46fec7d --- /dev/null +++ b/vercel.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "installCommand": "", + "buildCommand": "node scripts/build-site.mjs", + "outputDirectory": "dist-site", + "headers": [ + { + "source": "/(.*)", + "headers": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'" + }, + { "key": "X-Content-Type-Options", "value": "nosniff" }, + { "key": "Referrer-Policy", "value": "no-referrer" }, + { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }, + { "key": "Cross-Origin-Resource-Policy", "value": "same-origin" } + ] + } + ] +}