<feed xmlns='http://www.w3.org/2005/Atom'>
<title>cgithub.git/src/scraper.ts, branch main</title>
<subtitle>GitHub alternative frontend</subtitle>
<id>http://git.mou.fo/2026/cgithub.git/atom/src/scraper.ts?h=main</id>
<link rel='self' href='http://git.mou.fo/2026/cgithub.git/atom/src/scraper.ts?h=main'/>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/'/>
<updated>2026-09-25T06:15:25Z</updated>
<entry>
<title>Read the pull request list from embedded JSON</title>
<updated>2026-09-25T06:15:25Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-25T06:09:49Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=137831d6bcabcaa2851a09015b19d118cb054a38'/>
<id>urn:sha1:137831d6bcabcaa2851a09015b19d118cb054a38</id>
<content type='text'>
GitHub's pull request list no longer renders .js-issue-row rows server-side;
the rows come from the repoPullsDashboardContentRoute payload instead.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Show each repo nav item only if the GitHub page includes it</title>
<updated>2026-09-25T06:15:02Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-25T05:48:21Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=226984ad63b063c362e18260a591a3f9a035a8d3'/>
<id>urn:sha1:226984ad63b063c362e18260a591a3f9a035a8d3</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Show issue and pull request status and labels in their lists</title>
<updated>2026-09-25T05:43:53Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-22T02:15:24Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=1514865ec8911c26612e68048f84c6c8be92449d'/>
<id>urn:sha1:1514865ec8911c26612e68048f84c6c8be92449d</id>
<content type='text'>
Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add issue details</title>
<updated>2026-09-25T05:43:53Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-21T22:08:48Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=fd1c054c3c10dceb1a8a355c74a0d9e9077aae19'/>
<id>urn:sha1:fd1c054c3c10dceb1a8a355c74a0d9e9077aae19</id>
<content type='text'>
Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add discussions</title>
<updated>2026-09-25T05:43:53Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-21T21:55:06Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=499bba129c842c00c1a28d85bc044ab609aee44e'/>
<id>urn:sha1:499bba129c842c00c1a28d85bc044ab609aee44e</id>
<content type='text'>
Discussions are served from GitHub's older server-rendered HTML, with no
embeddedData JSON to read, so the scraper walks the DOM the way the pull
request and wiki code does. A discussion's timeline opens with its own
post and continues with its comments, each carrying its replies nested
inside it, which is where the recursion in _discussionComment.eta comes
from. Categories, upvotes, and the answer a Q&amp;A discussion is marked with
all come along.

Only what GitHub renders up front is shown: neither the next page of
discussions nor the replies it hides behind a "Show N previous replies"
button are fetched, so a comment says how many replies it is missing.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Handle route errors in middleware</title>
<updated>2026-09-04T03:28:52Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-04T03:08:08Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=ae000d743ef54368d21596d590e1acc0d90b370e'/>
<id>urn:sha1:ae000d743ef54368d21596d590e1acc0d90b370e</id>
<content type='text'>
Every page route wrapped its scrape in tryRender, which awaited the
promise, rendered the template on success, and turned a failure into a
redirect or an error page. Hono's onError does that mapping for all of
them at once, so handlers now await their scrape inline and both
wrappers are gone. Fragments under /api/ still fail as an empty body
rather than a page; onError checks for them first, since a fragment
turns a redirect into a 404 instead of following it.

RedirectError becomes an abstract base with InternalRedirectError and
ExternalRedirectError under it, so the handler dispatches on the type
instead of sniffing the location for an https:// prefix.

One behavior change: a thrown value that is not an Error no longer
renders error.eta, because Hono only routes Error instances to onError.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01QERwoRJhuqMhKzzCUW4Skv
</content>
</entry>
<entry>
<title>Render repository wikis</title>
<updated>2026-09-03T05:09:10Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-09-03T04:08:06Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=df2969f6ff3658d683ae1959a7e4dbdb25720e2e'/>
<id>urn:sha1:df2969f6ff3658d683ae1959a7e4dbdb25720e2e</id>
<content type='text'>
Wikis are one of the last parts of GitHub still served as plain Rails
HTML, with no embedded JSON to read, so this scrapes the markup: a page
and any older revision of it, the _Sidebar and _Footer a wiki can
define, and the page index. Every page is already in the sidebar of
every page, since the "Show N more pages" button only unhides the rest,
so linking the whole wiki costs no second request.

Routes mirror GitHub's and resolve in its order, so an underscore name
reserved for its own actions (_pages, _history, _new, _edit) can never
be mistaken for a page; the ones we don't serve fall through to the
usual redirect. A slug reaches us decoded and has to be encoded again
rather than interpolated the way a ref is, or a page named C# would
truncate at the fragment.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013rQG1io1i4GJQW5RFcXNGd
</content>
</entry>
<entry>
<title>Follow the commit history to its new home in the payload</title>
<updated>2026-08-27T19:02:20Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-08-27T19:02:13Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=61b47cf1bb42f2c1cda6d6183b472517072e4a37'/>
<id>urn:sha1:61b47cf1bb42f2c1cda6d6183b472517072e4a37</id>
<content type='text'>
GitHub moved commitGroups from the top of the embedded JSON into a
commitsRefRoute, alongside the code view's own routes, so every commits
page threw. The groups themselves are unchanged.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01BErPR92xppzGFXkPqXPYj2
</content>
</entry>
<entry>
<title>Display PDF blobs</title>
<updated>2026-08-27T18:53:38Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-08-27T18:08:06Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=4797a627f461204b289f95f61b64e3dab8bc00ff'/>
<id>urn:sha1:4797a627f461204b289f95f61b64e3dab8bc00ff</id>
<content type='text'>
GitHub renders a PDF with a viewer of its own and so ships no content for
one, leaving the blob view with nothing to show. Its raw bytes come as
application/octet-stream, which browsers download rather than display, so
serve them from a new embed route that retypes them and point an &lt;object&gt;
at that.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01BErPR92xppzGFXkPqXPYj2
</content>
</entry>
<entry>
<title>Read the About box and latest release from JSON</title>
<updated>2026-08-11T22:25:26Z</updated>
<author>
<name>Joe Mou</name>
<email>dev@mou.fo</email>
</author>
<published>2026-08-11T21:41:01Z</published>
<link rel='alternate' type='text/html' href='http://git.mou.fo/2026/cgithub.git/commit/?id=950d7e430b833f3e428f1af100f6fb74bdd76a2d'/>
<id>urn:sha1:950d7e430b833f3e428f1af100f6fb74bdd76a2d</id>
<content type='text'>
GitHub rebuilt the repository sidebar, so the selectors parseRepoInfo used
matched nothing and the About box rendered empty. Everything but the latest
release is in the page's embedded payload as sidebarAbout; the latest release
is only in the _sidebar JSON already fetched for languages, so it arrives with
that fragment and is moved beside the release count.
</content>
</entry>
</feed>
