My Gatsby Deployment pipeline / build-and-deploy (push) Successful in 1m4s
Replace the single Gatsby page with a dark, terminal-style agent that answers questions about Dennis's work from one curated knowledge base. There is no model and no network call, so answers cannot be invented. A plain "Classic view" and an optional light theme sit one click away. Site - Terminal UI (React island): typed answers, tool-call lines, slash commands, autocomplete, history, deep links, a short /oncall game - Content focused on what recruiters scan for; personal and employer-internal details are left out - No profile photo anywhere, including the new link-preview card and icons - Corrected facts from the old page (dates, titles, tenses, skill tiers) Tooling - Migrate Gatsby 5 to Astro 7 (Node 22.23+); builds in about 1 second - Self-host fonts, so visitors make no request to third parties - Link-preview card, favicon set, web manifest and a service-worker clean-up for returning visitors - Deploy workflow builds with npm ci on Node 22 and uploads dist/ - Track package-lock.json Quality - Tests for routing and for markup injection from visitor input - A content guard scans every reachable answer; the list of things that must never be published lives in a git-ignored local file Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
28 lines
893 B
JavaScript
28 lines
893 B
JavaScript
// Loads the git-ignored list of specifics that must never reach the site. Without the file
|
|
// (a fresh clone, CI) the generic rules in the tests still run, and a note says what was skipped.
|
|
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
const FILE = new URL('./banned.private.json', import.meta.url)
|
|
|
|
let loaded = { patterns: [], questions: [], answerPattern: null }
|
|
let present = false
|
|
try {
|
|
loaded = { ...loaded, ...JSON.parse(readFileSync(FILE, 'utf8')) }
|
|
present = true
|
|
} catch (e) {
|
|
console.warn(
|
|
'note: test/banned.private.json not found; private content checks skipped'
|
|
)
|
|
}
|
|
|
|
export const privatePresent = present
|
|
export const privatePatterns = loaded.patterns.map(([source, why]) => [
|
|
new RegExp(source, 'i'),
|
|
why,
|
|
])
|
|
export const privateQuestions = loaded.questions
|
|
export const privateAnswerPattern = loaded.answerPattern
|
|
? new RegExp(loaded.answerPattern, 'i')
|
|
: null
|