summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-09-18Merge commit 'FILTERED_HEAD'HEADmainJoe Mou
2026-09-10Trust LizardByte/homebrewJoe Mou
Only trusting the sunshine formula would fail operations with: Error: Refusing to load formula lizardbyte/homebrew/sunshine-beta from untrusted tap lizardbyte/homebrew. Note trust is not removed if we remove it from the Nix config.
2026-09-10Render the error page in the shared page shellJoe Mou
error.eta carried its own copy of the HTML shell, so error pages missed the viewport meta tag, the build-commit footer, and the link to the original GitHub page. The renderer already passes githubUrl and buildCommit to every template, so the layout needs nothing new from app.ts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JZAT3YzYP85DihSvQbDKB6
2026-09-10Redirect /notifications instead of scraping it as an ownerJoe Mou
A signed-out request for github.com/notifications is bounced to a login page, so the owner route followed that redirect and left the visitor on /login. Hand the path over to GitHub before it reaches the route.
2026-09-09make upgradeJoe Mou
2026-09-09claude.sb: allow write access to ~/Library/pnpm/storeJoe Mou
2026-09-09Upgrade mojo to NixOS 26.05Joe Mou
2026-09-09Add feature list to README.mdJoe Mou
2026-09-09Serve GitHub's global search when it names one repositoryJoe Mou
/search?q=repo:owner/name+...&type=code matched the /:owner route and rendered a profile page for an owner named "search", which GitHub 404s. It is the URL GitHub's own search box produces, so it arrives whenever a search is redirected here. A /search route now takes it: when the query carries a repo: qualifier and a type, it strips the qualifier and redirects to that repository's search route, which already maps issues and pull requests to pages we render and hands the rest to GitHub. Searches that name no single repository -- bare queries, org:/user: scopes, a missing type -- keep redirecting to github.com/search as they did before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GkGX6puS45xD5KzdV9tHEA
2026-09-05Add screenshotJoe Mou
2026-09-04Split the page shell out of the repository layoutJoe Mou
layout.eta was two things at once: the HTML shell every page needs and the repository chrome around it. owner.eta, being the one page that is not about a repository, could use neither and carried its own copy of the shell, which had drifted -- its footer named no build commit and did not link to the original page on GitHub. The shell moves to views/layouts/base.eta, taking its title and any deferred scripts as layout data, and the chrome to views/layouts/repo.eta, a layout over it that adds the clone commands, nav, search box, and the "/" shortcut that focuses it. Repository pages point at repo.eta and render as before; owner.eta uses base.eta directly and so gains the footer it was missing. Templates now live in more than one directory, so scripts/build.ts walks views/ recursively and keys each template by its path underneath it. Names crossing a directory are written from the views root ("/layouts/base.eta"), the one form both Eta's filesystem resolver and the precompiled resolver in worker.ts agree on; siblings stay relative. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ba5p88cWtCq42vf3uweweL
2026-09-03Handle route errors in middlewareJoe Mou
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QERwoRJhuqMhKzzCUW4Skv
2026-09-03Clean up renderer, redirects, and build commitJoe Mou
2026-09-03Link blobs to their history and backJoe Mou
Nothing in a commits payload says whether the path it lists is a file or a directory: currentBlobPath, despite the name, is only the path filter, and is set for a directory just the same. GitHub's own UI cannot tell either, and points its browse button at /blob/<oid>/<path> so that the redirect resolves a file to its blob. We do the same, and the blob route already turns that redirect into one of our own tree URLs. Breadcrumbs now stay in the view they were clicked from, so walking up from a history lands in the history of each parent directory rather than in its listing. The last crumb remains the page you are already on. A path with no commits now says so rather than rendering an empty page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R7pRKdmTvNDgT4ZXrwkbH8
2026-09-03Anchor blob lines so #L fragments workJoe Mou
Wrap each rendered line in a <span id="Ln">, for both syntax-highlighted and plain-text blobs, and shade the line a fragment targets.
2026-09-03Fix drifted testsJoe Mou
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NWDWkWbj5oZCGQEYoybMrV
2026-09-03Render repository wikisJoe Mou
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rQG1io1i4GJQW5RFcXNGd
2026-08-27Move the workerd build allowance out of package.jsonJoe Mou
pnpm 11 no longer reads the "pnpm" field in package.json and warns that it ignored onlyBuiltDependencies, which would leave workerd's build script unapproved and unrun on a fresh install. Its new home is pnpm-workspace.yaml, which pnpm accepts without a packages key for a single-package repo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PbJ1wy2dNdjk7LpME4ud3J
2026-08-27Follow the commit history to its new home in the payloadJoe Mou
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BErPR92xppzGFXkPqXPYj2
2026-08-27Display PDF blobsJoe Mou
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 <object> at that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BErPR92xppzGFXkPqXPYj2
2026-08-26cal: run on Node 26 via socket activationJoe Mou
Swap Deno for nodejs-slim_26, which runs server.ts directly. Drops DENO_DIR and CacheDirectory, which only existed to give Deno's module cache a writable home under DynamicUser. Listen on a unix socket like clippersnip rather than a TCP port.
2026-08-26make upgradeJoe Mou
2026-08-26cal.elmo.mou.fo serviceJoe Mou
2026-08-26ytdl-sub & pinchflat permissionsJoe Mou
2026-08-26Add pinchflatJoe Mou
Coexists with ytdl-sub rather than replacing it, downloading into its own tree under /srv/media/incoming so the two never manage the same files. Podcast clients cannot authenticate, so the feed, cover art, episode art and media stream routes bypass oauth2-proxy with auth_request off. Those are exactly the routes pinchflat serves unauthenticated itself, each addressed by an unguessable UUID. The OPML endpoint is exposed as well but stays token-protected by the app. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26Convert miniflux to systemd socket activationJoe Mou
Fixes socket permission issue. Drop the RuntimeDirectoryMode workaround: nginx no longer traverses /run/miniflux. Also drop the now-redundant explicit socket dependencies from bjj-booker and clippersnip; systemd adds those implicitly.
2026-08-26Redirect fluffy-kitten to Cloudflare cgithubJoe Mou
2026-08-13Scroll on / search shortcutJoe Mou
2026-08-12Handle blobs GitHub cannot previewJoe Mou
Binary files with no preview (a .ttf, say) have no rawLines, no colorizedLines and no richText, so the blob view's final branch threw on a null textLines and the page 500ed. Offer the raw file instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12Use an HTTP redirect for same-origin requestsJoe Mou
The meta refresh page renders as a broken image when the request came from an <img> on one of our own pages. Such requests are already past the redirect-loop hazard the refresh works around, so send them a real redirect instead.
2026-08-11Read the About box and latest release from JSONJoe Mou
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.
2026-08-11Keep the ref picker on the current view and pathJoe Mou
2026-08-11Mitigate placeholder layout shiftJoe Mou
2026-08-11Redirect to GitHub with a meta refreshJoe Mou
A browser extension redirects github.com to cgithub with declarative net requests. Its rules match our HTTP redirects back to github.com too, so those bounce straight back here and loop forever. A meta refresh makes cgithub the initiator origin instead, which the extension's rules can exclude, and its delay leaves a page the user can stop on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11Show the build's commit in the page footerJoe Mou
Workers can't shell out at request time, so the commit has to be baked in before wrangler bundles the sources. compile-views.ts grows a second job and becomes scripts/build.ts: alongside the precompiled views it writes src/commit.generated.ts with `git describe --tags --always --dirty`, which yields a bare short hash until the repo is tagged and marks builds made from an unclean working copy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11Deploy only to Cloudflare WorkersJoe Mou
The Node server entry, esbuild bundle, and Makefile rsync/systemd deploy are gone; wrangler dev and wrangler deploy are the only paths now, so the dev:cf/deploy:cf scripts take over the plain dev/deploy names. @hono/ node-server and esbuild drop out with src/index.ts, and the README's systemd socket and nginx snippets go with them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11Abbreviate commit hashes in branch pickerJoe Mou
2026-08-11Link repo header and add a "View original" linkJoe Mou
The owner/name header in the layout now links to the owner page and the repository root. tryRender passes the request's path and query through as githubUrl — our URLs mirror GitHub's, so the same path is the page we scraped — and the footer links there with rel="noreferrer", matching the no-referrer policy used on redirects to github.com. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11Add language percentages to repo pagesJoe Mou
GitHub no longer server-renders the repository sidebar; its React UI lazily fetches /:owner/:repo/_sidebar as JSON, which carries the language breakdown (name, percentage, color). getGitHubLanguages() uses that endpoint, and a new /api/:owner/:repo/languages fragment route renders the bar and legend the same way refs and latest-commit already work, so repo page loads still cost a single scrape. The latest-commit placeholder loader in refs.js is generalized over .placeholder[data-src] so both placeholders share it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11make upgradeJoe Mou
2026-08-11Remove redlib and nitter for public instancesJoe Mou
2026-08-11ClippersnipJoe Mou
2026-08-11TypeTypeJoe Mou
Requires /var/secrets/typetype to be populated by hand: - env with DATABASE_PASSWORD and POSTGRES_PASSWORD (set the same value) - youtube_remote_login_internal_token - youtube_session_encryption_key Postgres data lives at /var/lib/typetype/postgres as a bind mount rather than a Docker volume. Downloads (typetype-downloader + Garage) and SSO are not set up yet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11make upgradeJoe Mou
2026-08-11BJJ BookerJoe Mou
2026-08-11HA: Check for rainJoe Mou
2026-08-11HA: Legacy switch template deprecationJoe Mou
2026-08-11HA: Add entity and automation idsJoe Mou
See https://community.home-assistant.io/t/all-automations-show-no-traces-found/389304 and https://www.home-assistant.io/faq/unique_id
2026-08-11HA: Leave AC onJoe Mou
2026-08-11Upgrade to NixOS 26.05Joe Mou