Skip to content

feat: perfkit render --config writes a site with no runs, and data/site.json - #22

Merged
psanders merged 2 commits into
mainfrom
feat/render-without-report
Nov 5, 2026
Merged

psanders merged 2 commits into
mainfrom
feat/render-without-report

Conversation

@psanders

@psanders psanders commented Nov 5, 2026

Copy link
Copy Markdown
Member

Why

perfkit render required --report, and the app learned the live URL only from the latest report. A project could not publish its benchmarks site before its first published run, and the site could not show a run in progress until then. Routr wants to clear its old site now and have routr.io/benchmarks show live runs right away.

What

  • perfkit render --config <perfkit.yaml> --out <dir> [--history <file|url>], with no --report: writes app/<version>/app.js, data/runs.json (empty without --history, else the history as it is; runs.json v1 already allows zero runs), the new data/site.json and the shells (index.html, plus one per run in a given history). --report and --config together, or neither, is a usage error (exit 1).
  • data/site.json, schema: perfkit/site/v1 (Zod siteSchema, JSON Schema schemas/site-v1.schema.json): { schema, project }, where project is report.json's project shape: name, repo, siteUrl, accent, logoSvg/faviconSvg (inlined from the config's files), title, lead, live.url. The live URL resolves as it does for reports (project.live.url, else live.url, else https://<live.domain>/live.json). That logic now lives in projectFromConfig, which toReportProject uses too.
  • render --report also writes data/site.json from the report's project on every render.
  • App: when data/runs.json is empty, the latest page is drawn from data/site.json. It shows the nav brand, eyebrow, title, lead, "No published runs yet. When a run is in progress it appears here live." and the footer, in the existing page styles. The live URL is ?live=, then data/site.json, then the latest report. The page polls it from the site root as before.
  • The render line list now includes data/site.json (...). The Contract test was updated for that line.
  • Version 0.1.12.

Compatibility

  • Additive. Existing flags, exit codes and runs.json/report.json are unchanged. --report is no longer a required option at the commander level, but a render without it (and without --config) still exits 1.
  • Older sites without data/site.json keep working: the app falls back to the latest report's live URL.

Verify

  • npm test: 660 passing. npm run typecheck and npm run lint are clean. New tests: config-only render (lines, empty runs.json, site.json, history kept, invalid config, both/neither flags), the no-runs draw (from site.json, and an invalid site.json), siteSchema, projectFromConfig live URL order, the resolveLiveUrl order, createReadSiteLiveUrl, and a jsdom run of the real bundle on a config-only site.
  • Headless Chromium (Playwright): rendered examples/minimal/perfkit.yaml with --config and served it with perfkit serve. The no-runs page drew with no console errors and no horizontal scroll at 375px. With a live.url in the config, the page fetched data/site.json and then polled that live.json.

🤖 Generated with Claude Code

…te.json

perfkit render --config <perfkit.yaml> --out <dir> (no --report) writes the
app, an empty data/runs.json (or the --history as it is), a new
data/site.json (schema perfkit/site/v1: the project with its inlined logo,
favicon and live URL) and the shells. Every render with --report also
writes data/site.json from the report's project.

The app draws a no-runs page from data/site.json when data/runs.json is
empty, and resolves the live URL as ?live=, then data/site.json, then the
latest report, so a project can publish its site and show a run in progress
live before its first published run.
@psanders
psanders merged commit 79cf626 into main Nov 5, 2026
2 checks passed
@psanders
psanders deleted the feat/render-without-report branch November 5, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant