Source for https://aitofy.dev. A static site generator with zero dependencies — plain
TypeScript run by Node 22's built-in type stripping. No framework, no CSS framework, no build
tool. The only devDependency is wrangler, and only for deploying.
Node >= 22. Nothing to install to build or test.
node --run build # generate dist/
node --run test # node:test suite
node --run check # test, then buildnode --run is used everywhere so CI needs no package manager.
aitofy.dev is a Cloudflare Pages project named aitofy-dev, deployed by direct upload.
Build first, then upload dist/:
node --run build
wrangler pages deploy dist --project-name=aitofy-devwrangler pages deploy has no --dry-run, so there is no way to validate a Pages upload
without publishing it. Verify locally first instead:
node --run check # tests, then a clean build
wrangler pages dev dist # serve dist/ exactly as Pages wouldwrangler.jsonc holds the three keys a static Pages project needs (name,
pages_build_output_dir, compatibility_date), so wrangler pages deploy with no arguments
also works once the config is picked up. The explicit command above is what to paste.
aitofy.dev currently serves Cloudflare's managed robots.txt, which Cloudflare appends to
whatever we ship. Verified with curl https://aitofy.dev/robots.txt, it carries:
Content-Signal: search=yes,ai-train=no,use=reference
User-agent: ClaudeBot Disallow: /
User-agent: GPTBot Disallow: /
User-agent: CCBot Disallow: /
User-agent: Google-Extended Disallow: /
...plus Amazonbot, Applebot-Extended, Bytespider, meta-externalagent
While that is on, our llms.txt cannot be read by any AI crawler and the AI-native DX we are
aiming for does not happen. Our own robots.txt (Allow: / plus the sitemap) still works for
search engines either way.
To change it: Cloudflare dashboard → the aitofy.dev zone → Security → Settings → block AI
crawlers / managed robots.txt, turn it off, then re-verify:
curl https://aitofy.dev/robots.txtThis is a zone-level decision, not something this repo can set. Leave it on and keep llms.txt
for humans and direct fetches, or turn it off to let agents index the site.
src/products.ts Single source of truth for every product. Edit only this to change content.
src/html.ts Page shell: head, header, footer, escaping, path -> file mapping.
src/page-home.ts The home page: npm grid, Make.com panel, "what you get".
src/page-policy.ts /privacy, /terms, /affiliate-disclosure, /security and the 404.
src/discovery.ts sitemap.xml, robots.txt, llms.txt.
src/site.css Copied to dist/styles.css verbatim. The only stylesheet.
src/gen.ts Entry point. Wipes dist/ and writes everything.
Edit src/products.ts and rebuild. Version numbers, star counts, tags, URLs and install
commands all derive from that one array, so nothing needs updating in two places.
Refresh star counts from the source of truth before a release:
gh repo list aitofy-dev --visibility public --json name,stargazerCount
npm view @aitofy/<name> version- No JavaScript on any page, no analytics, no cookies, no third-party requests at runtime.
- System font stack only — no webfont is fetched, so
/privacycan honestly claim zero third-party requests. - No invented numbers. Versions and star counts are real and verified against npm and GitHub; download counts and testimonials are absent because we do not have credible ones.
- Every page's footer links
/privacy,/terms,/affiliate-disclosureand/security.