Deep chronicles of public GitHub repos for Guildhall, the browser
world that grows a repo into a voxel island. A chronicle is a repo's whole history, read once and
stored small (a few KB to a few dozen KB gzipped): its folders over time, its releases, its
contributors week by week. With one, an island grows from the first commit (?repo=owner/name&grow).
Without one, the hall sketches the history from about 20 live API calls.
This repo is the backend, and it is only GitHub:
| Piece | What does it |
|---|---|
| A request | An issue from the Chronicle a repo form |
| The builder | A GitHub Action (.github/workflows/build.yml) running builder/chronicle.js |
| Storage | This repo's main: chronicles/, og/, index.json, site/ |
| Delivery | jsDelivr mirroring main: https://cdn.jsdelivr.net/gh/Codestz/guildhall-chronicles@main/… |
| Previews | site/ on GitHub Pages: r/<owner>/<name>/ pages carrying each island's card for link unfurls |
The hall has no server and holds no token. It reads index.json and chronicles/*.json.gz from the
CDN, falling back to the few chronicles it ships with, then to the live sketch.
| Repo | About | Stars | Years | Files | Size | Island |
|---|---|---|---|---|---|---|
| react/react | The library for web and native user interfaces. | 252,435 | 2013–2026 | 7,300 | 39 MB | island |
| anomalyco/opencode | The open source coding agent. | 225,663 | 2025–2026 | 11,291 | 147 MB | island |
| microsoft/vscode | Visual Studio Code | 195,224 | 2015–2026 | 21,007 | 336 MB | island |
| Codestz/claude-hindsight | Claude Hindsight is a powerful observability tool for Claude Code that transforms raw JSONL transcripts into beautiful, interactive visualizations. Debug sessions, optimize costs, and understand Clau… | 22 | 2026 | 352 | 2 MB | island |
| Codestz/mcpx | MCP servers as CLI tools — built for AI agents | 13 | 2026 | 147 | 736 KB | island |
| Codestz/opencode-cockpit | OpenCode superpowers: background shells the agent can start, wait on and drive, with a docked TUI panel | 9 | 2026 | 791 | 9 MB | island |
| Codestz/guildhall | Events in. A living world out. Turn any event stream (coding agents, GitHub, a repo's history) into a living 3D island. | 0 | 2026 | 1,185 | 13 MB | island |
| Codestz/Mintroot | 0 | 2026 | 199 | 3 MB | island |
The table is written by scripts/catalog.ts from index.json in every publish commit; don't edit it by hand.
- Open a request (the hall's Deepen this island button opens it with the repo filled in).
- Give the repo as
owner/nameor its github.com link, and tick the public-repo box. - The Action checks it, builds it (minutes for most repos, longer for the biggest), commits it, and answers on the issue with the island's link and a README badge, then closes it.
What can stop a request:
- Not readable: the name must be
owner/nameor agithub.com/owner/namelink, nothing else. - Not public, or not on GitHub, or no commits yet.
- Already chronicled: you get its link. Popular chronicles are refreshed weekly.
- Too big: over 2 GB on GitHub (
CHRONICLE_MAX_SIZE_MB). - Waiting: requests from outside the maintainers can be held for an
approvedlabel (CHRONICLE_REQUIRE_APPROVAL), and builds are capped per day (CHRONICLE_DAILY_CAP, default 10). Held issues stay open with thequeuedlabel.
Only public repos, and only aggregate history. A chronicle holds:
- counts: files, bytes and commits per top-level folder (or workspace package) over time, weekly commit, PR and issue counts, lines added and removed per week;
- names: the repo's folder names, release tags and titles, and contributors' display names and
GitHub logins (the same names
git logshows anyone who clones the repo); - the repo's description, stars, forks, languages and creation date.
It holds no code, no file contents, no file paths below the top-level folders and workspace packages, and no email
addresses. The builder clones without file contents (--filter=blob:none) and fails rather than
download one. Everything in it is already public on GitHub; it is just counted.
To have a chronicle removed, open an issue (any kind) and say which one. Owners of the repo get it removed without question.
.github/ISSUE_TEMPLATE/chronicle.yml the request form (field ids: repo, public)
.github/workflows/build.yml a request → guards → build → publish → answer
.github/workflows/refresh.yml weekly: rebuild the top N by stars
.github/workflows/pages.yml site/ + og/ → GitHub Pages (off until enabled)
builder/chronicle.js the deep builder, vendored from Guildhall (see below)
chronicles/<owner>__<name>.json.gz the chronicles (lower case)
og/<owner>__<name>.png their 1200×630 preview cards
index.json the catalog: name, stars, languages, years, size, built date, and the builder
site/ the Pages site: index.html, r/<owner>/<name>/index.html
scripts/request.ts reads an issue and decides (pure rules in scripts/lib/request.ts)
scripts/og.ts a chronicle's card (scripts/lib/card.ts), rendered with resvg
scripts/catalog.ts index.json's `builder` stamp and the README's catalog table (scripts/lib/catalog.ts)
scripts/site.ts site/ from index.json (scripts/lib/page.ts)
scripts/publish.sh commit a build onto the latest main, retrying a lost race
scripts/refresh.ts, scripts/reply.ts the refresh list; the issue comments
assets/fonts/ Marcellus SC and Alegreya Sans (SIL OFL), for the cards
Needs Bun ≥ 1.3.5 and git.
bun install
GITHUB_TOKEN=$(gh auth token) bun builder/chronicle.js deep facebook/react --out chronicles/react__react.json.gz
bun scripts/og.ts chronicles/react__react.json.gz og/react__react.png
bun builder/chronicle.js index chronicles --out index.json
bun scripts/catalog.ts
bun scripts/site.ts
bun testA token is optional but strongly advised: without one GitHub allows 60 calls an hour, and a big repo's PR and issue counts alone take dozens.
builder/chronicle.js is Guildhall's scripts/chronicle.ts (and the chronicle format it writes)
bundled into one file, with no dependencies. It is vendored rather than fetched at run time so a
build never depends on another repo being reachable, and so every change to it is a reviewable diff
here. Its first lines name the Guildhall commit it came from. To update it, in a Guildhall checkout:
bun legacy/scripts/chronicle-build.ts --out ../guildhall-chronicles/builder/chronicle.js(V1 lives under legacy/ in Guildhall's v2 branch, so the paths there are legacy/scripts/chronicle.ts and
legacy/packages/hall/src/world/chronicle/….) Build from a clean, committed tree: the banner then names
a commit that reproduces the bundle, and index.json's builder field (commit, built, plus dirty
when it was built from uncommitted sources) records which builder wrote the catalog.
then commit it here. Rebuild it whenever the chronicle format or the deep builder changes in
Guildhall (world/chronicle/{deep,format,catalog}.ts, scripts/chronicle.ts).
Repository variables (Settings → Secrets and variables → Actions → Variables), all optional:
| Variable | Default | Meaning |
|---|---|---|
CHRONICLE_MAX_SIZE_MB |
2048 |
Largest repo built, by GitHub's reported size |
CHRONICLE_DAILY_CAP |
10 |
Outside requests built per UTC day |
CHRONICLE_REQUIRE_APPROVAL |
false |
true: outside requests wait for the approved label |
CHRONICLE_REFRESH_TOP |
12 |
How many chronicles the weekly refresh rebuilds |
PAGES_ENABLED |
unset | true once Pages is on: deploys site/ after each build |
No secrets: the workflows use the job's own GITHUB_TOKEN, scoped per job (contents and issues for
builds, contents for the refresh, Pages for the deploy).