Hi! Thanks for these reports, they are really useful.
Right now, to read a report you have to download the .html file and open it locally (as the README says). That is a bit awkward, especially when you just want to share a link to a finding with a maintainer.
The reports are fully self-contained: CSS and JS are inlined, with no external scripts or styles. So GitHub Pages can serve them as they are:
-
Minimal option: Settings → Pages → Deploy from a branch → master / (root). Every report then gets a URL such as
https://qarmin.github.io/ClaudeReports/wine_20260914.html.
The size is within Pages limits: about 185 MB without .git, against the 1 GB site limit. The largest file is 7.5 MB, against the 100 MB per-file limit.
-
Slightly nicer option: a small Actions workflow that publishes only the *.html reports (not Details/) and generates:
index.html: a searchable list of all projects with their report dates and links to older reports that are still kept;
latest/<Project>.html: a stable redirect to the newest report of each project. Links then keep working after a refresh renames the file to a new date, which would reduce the need for keep in projects.toml.
The published site is ~114 MB. After adding the two files below, enable it once in Settings → Pages → Source: GitHub Actions.
.github/workflows/pages.yml
name: Publish reports to GitHub Pages
on:
push:
branches: [master]
paths: ['*.html', 'scripts/build_site.py', '.github/workflows/pages.yml']
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- run: python3 scripts/build_site.py . _site
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: _site
- id: deployment
uses: actions/deploy-pages@v4
scripts/build_site.py
#!/usr/bin/env python3
"""Build the GitHub Pages site: copy reports, generate index and stable links."""
import html
import re
import shutil
import sys
from collections import defaultdict
from pathlib import Path
REPORT_RE = re.compile(r"^(?P<name>.+)_(?P<date>\d{8})\.html$")
def main(src: Path, out: Path) -> None:
out.mkdir(parents=True, exist_ok=True)
(out / "latest").mkdir(exist_ok=True)
(out / ".nojekyll").touch()
projects = defaultdict(list)
for f in src.glob("*.html"):
m = REPORT_RE.match(f.name)
if not m:
continue
shutil.copy2(f, out / f.name)
projects[m["name"]].append((m["date"], f.name, f.stat().st_size))
rows = []
for name in sorted(projects, key=str.lower):
reports = sorted(projects[name], reverse=True)
date, fname, size = reports[0]
# Stable URL that always points to the newest report of the project
(out / "latest" / f"{name}.html").write_text(
f'<!doctype html><meta charset="utf-8">'
f'<meta http-equiv="refresh" content="0; url=../{fname}">'
f'<link rel="canonical" href="../{fname}">'
f'<a href="../{fname}">{html.escape(fname)}</a>\n')
older = " ".join(
f'<a class="old" href="{f}">{d[:4]}-{d[4:6]}-{d[6:]}</a>'
for d, f, _ in reports[1:])
rows.append(
f'<tr><td><a href="{fname}">{html.escape(name)}</a></td>'
f'<td>{date[:4]}-{date[4:6]}-{date[6:]}</td>'
f'<td class="num">{size / 1024:.0f} KB</td><td>{older}</td></tr>')
(out / "index.html").write_text(INDEX.replace("{count}", str(len(rows)))
.replace("{rows}", "\n".join(rows)))
print(f"{len(rows)} projects written to {out}")
INDEX = """<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Claude Code audit reports</title>
<style>
:root{color-scheme:light dark;--fg:#1f2328;--bg:#fff;--muted:#656d76;--line:#d0d7de;--link:#0969da}
@media (prefers-color-scheme:dark){:root{--fg:#e6edf3;--bg:#0d1117;--muted:#8d96a0;--line:#30363d;--link:#4493f8}}
body{font:15px/1.5 system-ui,sans-serif;color:var(--fg);background:var(--bg);max-width:900px;margin:0 auto;padding:1.5rem 1rem}
a{color:var(--link);text-decoration:none}a:hover{text-decoration:underline}
input{width:100%;box-sizing:border-box;padding:.5rem .7rem;font:inherit;color:inherit;background:transparent;border:1px solid var(--line);border-radius:6px;margin:1rem 0}
table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:.35rem .5rem;border-bottom:1px solid var(--line)}
th{color:var(--muted);font-weight:600}.num{text-align:right;white-space:nowrap}.old{color:var(--muted);font-size:.9em;margin-right:.5em}
p{color:var(--muted)}
</style>
</head>
<body>
<h1>Claude Code audit reports</h1>
<p>{count} projects. Source: <a href="https://github.com/qarmin/ClaudeReports">qarmin/ClaudeReports</a>.
Stable link to the newest report of a project: <code>latest/<Project>.html</code>.</p>
<input id="q" type="search" placeholder="Filter projects..." autofocus>
<table>
<thead><tr><th>Project</th><th>Date</th><th class="num">Size</th><th>Older</th></tr></thead>
<tbody id="t">
{rows}
</tbody>
</table>
<script>
const q = document.getElementById('q'), rows = [...document.querySelectorAll('#t tr')];
q.addEventListener('input', () => {
const s = q.value.toLowerCase();
rows.forEach(r => r.hidden = !r.cells[0].textContent.toLowerCase().includes(s));
});
</script>
</body>
</html>
"""
if __name__ == "__main__":
main(Path(sys.argv[1] if len(sys.argv) > 1 else "."),
Path(sys.argv[2] if len(sys.argv) > 2 else "_site"))
I tested the generator locally on the current master: it produces 279 projects. I'm happy to open a PR with these files if you prefer.
Until then, a report can be viewed without downloading through raw.githack.com, e.g.
https://raw.githack.com/qarmin/ClaudeReports/master/ripgrep_20260909.html
Hi! Thanks for these reports, they are really useful.
Right now, to read a report you have to download the
.htmlfile and open it locally (as the README says). That is a bit awkward, especially when you just want to share a link to a finding with a maintainer.The reports are fully self-contained: CSS and JS are inlined, with no external scripts or styles. So GitHub Pages can serve them as they are:
Minimal option: Settings → Pages → Deploy from a branch →
master/(root). Every report then gets a URL such ashttps://qarmin.github.io/ClaudeReports/wine_20260914.html.The size is within Pages limits: about 185 MB without
.git, against the 1 GB site limit. The largest file is 7.5 MB, against the 100 MB per-file limit.Slightly nicer option: a small Actions workflow that publishes only the
*.htmlreports (notDetails/) and generates:index.html: a searchable list of all projects with their report dates and links to older reports that are still kept;latest/<Project>.html: a stable redirect to the newest report of each project. Links then keep working after a refresh renames the file to a new date, which would reduce the need forkeepinprojects.toml.The published site is ~114 MB. After adding the two files below, enable it once in Settings → Pages → Source: GitHub Actions.
.github/workflows/pages.ymlscripts/build_site.pyI tested the generator locally on the current
master: it produces 279 projects. I'm happy to open a PR with these files if you prefer.Until then, a report can be viewed without downloading through raw.githack.com, e.g.
https://raw.githack.com/qarmin/ClaudeReports/master/ripgrep_20260909.html