OpenPeon is an open standard (CESP v1.0) for coding event sounds. Any agentic IDE or terminal editor can implement CESP to give developers audio feedback when tasks complete, errors occur, or input is needed.
spec/-- CESP v1.0 specification, JSON schemas (openpeon.schema.jsonfor pack manifests,registry-entry.schema.jsonfor registry entries)examples/-- Example sound packs (peon, glados) that validate against the schemassite/-- Next.js site deployed to openpeon.com via Vercelscripts/-- Cross-repo utility scripts (update-pack-counts.shfor syncing pack counts)docs/-- Architecture documents (registry-design.md,download-tracking-plan.md,plans/)tests/-- Schema validation tests
npm run dev-- Start dev servernpm run build-- Production buildnpm run lint-- ESLint
npm test-- Run all tests (schema validation)npm run test:schema-- Run schema validation tests only
- Pack data is fetched at request time with ISR, not at build time.
site/src/lib/registry.tsfetches the registry index frompeonping.github.io/registry/index.json, then each pack'sopenpeon.jsonmanifest from GitHub raw URLs, with bounded concurrency and retries. Fetches are cached withrevalidate: 86400(24h) underREGISTRY_TAG. - A malformed community manifest is dropped with a
[registry] dropping pack ...console warning rather than failing the render. If the live site shows far fewer packs than the registry, check the deploy logs for these warnings. site/src/app/api/revalidate/route.tsaccepts a POST with anx-revalidate-secretheader and busts the registry cache tag. It only works onceREVALIDATE_SECRETis set in the Vercel project env; until then a freshvercel --proddeploy is the way to reset the ISR cache.- Audio files are served directly from GitHub raw URLs (no local copies).
- The site is deployed to Vercel; the Vercel project's root directory is
site/, so runvercelfrom the REPO ROOT, not fromsite/. - Schemas use JSON Schema Draft 7.
- CI (
.github/workflows/ci.yml) runs root schema tests plus site lint and build on every push/PR to main.
- Site-wide OG card lives in
site/src/app/layout.tsx. Per-pagegenerateMetadatamust set its ownopenGraph/twitterblocks; Next.js does not cascade the page title/description into them (pack pages do this, seesite/src/app/packs/[name]/page.tsx).