Archived. This project is no longer maintained. For building sites, use lfm instead.
A lean static site builder where the fitness system is the product. Nineteen analyzers across four tiers, LLM-native tooling, and zero-config Schema.org — all driven by files on disk and zero runtime dependencies.
npx @ghostpaw/website init my-site
cd my-site
npm run devhttp://localhost:3000 is live. The fitness report runs automatically. Edit files in content/ and the browser reloads.
The website binary is the primary interface — for humans and agents alike. Every command runs from the project root (the directory containing site.json).
website init [dir] # scaffold + first build + package.json scripts
website dev # dev server with livereload, per-rebuild feedback
website build # full build to dist/, pre-compress assets, fitness summary
website check # 19-analyzer fitness report with actionable fixes
website new page <slug> # create a page with correct frontmatter
website new post <slug> # create a blog post with correct frontmatter
website config get [key] # read site.json or a specific dot-notation key
website config set <key> # update site.json safely
website deploy # generate GitHub Pages, Netlify, Cloudflare, or Docker config
website start # production HTTP server (security headers, gzip, ETag, clean URLs)--help works on every command. --json on check and build emits raw structured output for piping.
Local: http://localhost:3000
Project: My Site · 6 pages
Fitness: 84/100 — 3 issues (run `website check`)
Watching content/, templates/, data/, assets/
12:34:01 rebuilt 28ms · 6 pages
File watching is incremental — only changed pages re-render. Templates or site.json changes trigger a full rebuild.
website start serves dist/ over Node's built-in HTTP with no external dependencies:
- Security headers (
X-Content-Type-Options,X-Frame-Options,Referrer-Policy,Permissions-Policy) - Pre-compressed
.gzserving without runtime CPU cost (website buildwrites them) Cache-Control: no-cache+ETagfor HTML;immutablefor content-hashed assets- Clean URL redirects (
/about→/about/) matching CDN behaviour - Path traversal guard, dotfile protection, graceful
SIGTERM/SIGINTshutdown PORTenv var for containers;--trust-proxyfor reverse-proxy deployments
website deploy --github-pages # writes .github/workflows/pages.yml
website deploy --netlify # writes netlify.toml
website deploy --cloudflare # prints Cloudflare Pages setup
website deploy --docker # writes Dockerfile + .dockerignoreConfig generation only — no auth, no network calls.
Every project created by website init includes a SKILL.md that explains the full CLI to any agent with shell access. Drop a @ghostpaw/website project into Claude Code, Cursor, or any agent that can run commands and read files, and it knows how to:
- Audit the site and surface prioritised issues
- Write new content that passes fitness checks on the first build
- Fix cannibalization, schema gaps, and voice compliance issues
- Rebuild and verify the score improved
The --json flag on check and build returns the raw FitnessReport — ready to pipe directly into an LLM API call.
See docs/LLM.md for the full agent integration reference, including the library-level tools, skills, and soul namespaces for deeper harness integration.
For developers who need programmatic access:
npm install @ghostpaw/websiteimport { scaffold, buildSite, api } from '@ghostpaw/website';
await scaffold('./my-site', { name: 'Acme', url: 'https://acme.com' });
const result = await buildSite('./my-site');
console.log(result.pages.length); // 6
const report = await api.read.fitness('./my-site');
console.log(report.overall); // 84Three namespaces — every function takes dir: string as its first argument:
| Namespace | What it does |
|---|---|
api.read |
Inspect pages, templates, data, config, fitness — no side effects |
api.write |
Create, update, or delete content, templates, data, assets |
api.build |
Scaffold, build, preview, serve, clean |
See docs/HUMAN.md for the full API reference.
For agent builders wiring the library into an LLM harness:
import { tools, skills, soul } from '@ghostpaw/website';
// Inject into system prompt
const systemPrompt = soul.siteBuilderPersona.renderSoulPromptFoundation();
// Register with your harness
const toolDefs = tools.TOOLS; // JSON Schema + call(dir, input) → ToolResult
// Inject into reasoning steps
const skill = skills.SKILLS.find(s => s.name === 'create-page-well');Every tool returns a discriminated ToolResult:
{ status: 'success', data: T }
{ status: 'no_op', message: string }
{ status: 'needs_clarification', question: string }
{ status: 'error', code: string, message: string }The core agent loop:
site_read → site_plan → site_write → site_check → repeat
See docs/LLM.md for the full agent-builder reference.
| Tool | What it does |
|---|---|
site_read |
Inspect pages, templates, data, config, and fitness — no side effects |
site_write |
Create, update, or delete content, templates, data, and assets |
site_build |
Build, scaffold, preview, serve, or clean a site |
site_check |
Run the fitness system and return prioritised issues with fix suggestions |
site_plan |
Dry-run proposed changes and preview the fitness delta before writing |
The shared tool facade is available from the package root and the tools
namespace. Its five definitions preserve the existing names and input schemas:
site_read, site_write, site_build, site_check, and site_plan.
Each definition includes description, whenToUse, whenNotToUse, inputSchema,
readOnly, and sideEffects (none or writes_state).
Only site_plan is always read-only. Whole-site fitness actions in site_read
and site_check append score history, so their shared definitions declare writes.
import { getWebsiteToolByName, listWebsiteToolDefinitions, websiteTools } from '@ghostpaw/website';
const read = websiteTools[0];
const result = await read.handler('./my-site', { action: 'get_config' });
console.log(result.ok, result.outcome, result.summary, result.data);
console.log(listWebsiteToolDefinitions().map(tool => tool.name));
console.log(getWebsiteToolByName('site_read')?.name);Handlers return { ok, outcome, summary, next?, data? }. Outcomes are success,
no_op, needs_clarification, or error. Clarifications include a next-step
question; errors retain their original code and message in error.
The existing tools.TOOLS and individual tool objects remain available with
unchanged call() methods and status results, and are deprecated in favor of
these definitions.
| Skill | What it guides |
|---|---|
create-page-well |
End-to-end page creation with correct frontmatter and content structure |
seo-checklist |
Systematic on-page SEO review and remediation loop |
geo-optimization |
GEO signal optimisation: crawlability, interrogative headings, freshness |
template-composition |
Building and wiring reusable layout templates and data files |
site-launch-checklist |
Pre-launch fitness targets and configuration verification |
content-cannibalization |
Identifying and resolving keyword overlap across pages |
search-console-workflow |
Ingesting GSC data to drive Tier 4 fitness analysis |
| Tier | Analyzers |
|---|---|
| Tier 1 — always runs | seo_meta, seo_structure, content_quality, images, links, social, sitemap_robots, technical |
| Tier 2 — TF-IDF corpus | cannibalization, topical_clusters, content_tfidf |
| Tier 3 — schema-aware | schema_validation, geo, eeat, local_seo, multilingual, voice_compliance |
| Tier 4 — optional | search_console (requires GSC data) |
Score targets: ≥ 80 to publish, ≥ 90 for production excellence.
See docs/entities/FITNESS.md for the full analyzer reference.
- Fitness-first. Score and issues are first-class outputs. The HTML is the side effect.
- Dual-use CLI.
websiteis equally usable by humans and agents — same commands,--jsonfor machine output. - SKILL.md ships with every project. Any agent with shell access can operate the site immediately.
- LLM-native library. Soul for posture, tools for actions, skills for workflow — designed for agentic use from day one.
- Zero-config Schema.org.
faq.html,breadcrumb.html, andtable.htmlauto-inject correct JSON-LD. - Dry-run before write.
site_plansimulates any mutation and returns a fitness delta before a file is touched. - Everything is files.
content/,templates/,assets/,data/,site.json— no database, no admin UI. - Production-safe server.
website startis hardened: traversal guard, dotfile protection, security headers, gzip, graceful shutdown. - Zero runtime dependencies. Markdown rendering and CLI argument handling are implemented locally with Node.js built-ins.
| Document | Audience |
|---|---|
| docs/HUMAN.md | CLI usage and direct api.read / api.write / api.build reference |
| docs/LLM.md | Agent integration: CLI via SKILL.md, and library soul / tools / skills |
| docs/entities/CONTENT.md | Pages, frontmatter schema, collections, URL routing |
| docs/entities/TEMPLATES.md | Templates, layouts, partials, auto-injected Schema.org |
| docs/entities/FITNESS.md | 19 fitness analyzers, scoring, issue format, history |
npm install
npm test # node:test runner, no external framework
npm run typecheck # tsc --noEmit
npm run lint # biome check
npm run build # ESM + CJS + declarations + CLI binary via tsupIf this package helps your project, consider sponsoring its maintenance:
Part of the GhostPaw ecosystem.