- Add twemoji as npm dependency instead of build download
- Package build assets with a Vite plugin instead of scripts
- Keep the eslint and prettier caches in one directory
Cloudflare's single-page-application fallback percent-encodes the
path on a fresh load or reload, so `rad:z4V1...` arrives as
`rad%3Az4V1...` and leaks into links and the seed command.
Only identifiers are decoded: revision and path segments stay
encoded, because branch and tag lookups are keyed on the encoded
name.
The seed command needs a second fix: the repo path segment is an
alias when one was used, and `rad seed <alias>` is not valid, the
`rad seed` command only supports RIDs and not aliases.
Co-Authored-By: Guillaume <guillaume.alabre@gmail.com>
The FAQ shipped here was a verbatim copy of the one on radicle.dev,
carrying a canonical tag that already pointed search engines at that
original. Drop the duplicate and redirect /faq to radicle.dev/faq so
existing links still reach the content.
The markdown sanitizer's allowlist did not include the <details> and
<summary> tags, so GitHub-style collapsible sections were stripped and
their contents rendered flat. Add both tags to ALLOWED_TAGS and the
"open" attribute to ALLOWED_ATTR, so collapsible sections render and
<details open> starts expanded.
Closes 390f3f2958
The installed-app home-screen label (short_name) in the web app
manifest was the full "Radicle Explorer". Shorten it to "Radicle" so
it reads well as an app label, while keeping name as "Radicle
Explorer", the project's full name.
Image URLs pointing at a GitHub "blob" page, such as
https://github.com/<owner>/<repo>/blob/<ref>/<path>, serve an HTML
page rather than the raw image bytes, so they render as broken images
in markdown.
Add a canonicalizeGithubImageUrl helper that appends ?raw=true to such
URLs, which makes GitHub redirect to the raw content. URLs already
pointing at the raw content, via ?raw=true or raw.githubusercontent.com,
are left unchanged, as are non-GitHub and non-URL sources.
Wire the helper into the markdown image loop so external image URLs are
canonicalized while relative paths keep resolving against the repo's raw
endpoint.
The pipelines are supposed to be a drop-in replacement for the current
github actions pipelines.
The github workflows have been restructured into 4 pipelines to take
advantage of the buildkite caching mechanism.
Listing remotes verifies signed refs for every peer and took seconds
on large repositories, blocking navigation.
Resolve revisions from the canonical refs already on the repo object,
fetching a single remote when the route names a peer, and load the
full listing after render. Tags living only on a remote no longer
resolve as bare revisions.
The cache only stored resolved values, so callers asking for the same
key while a request was still in flight each issued their own. The
peer selector makes this easy to hit: Source and History render their
own Header, so switching tabs while the remote listing loads fires a
second copy of a request that takes seconds.
Cache the promise instead, evicting it on rejection so failures still
retry.
So the badges stop fetching the full diff just for insertions and
deletions; the patch view did it on every load. Falls back to the
full diff when the backend doesn't serve the new endpoint.
The patch badge only needs insertions/deletions, but the full diff
endpoint builds every hunk and loads every changed blob.
This favours speed over exactness: `git diff --numstat` does not do
the rename/copy detection radicle-surf does, so on patches with copied
or renamed files the badge can diverge slightly from the full diff
view. In return it is roughly 6x faster on small diffs and 15x on
large ones.
So the header and history stop fetching full tree stats just for the
commit count. Falls back to the previous behaviour when the backend
doesn't serve the new endpoint.
The header and history only need a commit count, but /stats/tree walks
the full history and builds a contributor set to produce it.
Add /stats/commits, counting with `git rev-list --count`
(bitmap/commit-graph), falling back to a libgit2 revwalk.
surf's blob() walks the whole history to find the commit that last
touched a file, taking seconds to minutes on large repositories.
Read the blob directly and resolve its last commit with
`git rev-list -1`, which uses the commit-graph, falling back to surf.
Resolving a repo's signed refs opens a descriptor per packfile, and
radicle storage can hold thousands, so the default limit is exhausted
and reads fail with spurious "missing object" errors.
Copy:
- Sentence case for headlines, guide titles, and doc headings (proper
nouns kept capitalized).
- Removed em dashes from the home page.
- Tightened the "Programmable repos" line, clarified the explore CTA
("Explore the network"), rewrote the Claude skill card, simplified the
Install headline, and fixed the Garden nav description to describe
what Radicle Garden actually is (a hosted, always-on node).
Layout:
- Aligned the Garden promo on the Learn and landing pages (same copy and
dimensions).
- Balanced the page-header and hero headlines so they don't leave a
hanging word or widow.
- Line-break the Garden promo copy on desktop only.
- Animate the arrow on marketing buttons on hover, and drop the white
button's opacity hover.
Add sidebar sub-nav expand/collapse unfurl, now driven by the CSS View
Transitions API instead of JS tweening. Each nav section is a
view-transition group that clips into a top-to-bottom reveal as it opens
or closes, with a masked gradient soft edge.
A small JS flag (`sidebar-unfurling` on the document element) gates the
gradient to actual open/close, since CSS can't tell a within-section
navigation from a section toggle.
- Filter out jobs that have no runs in `jobs_by_commit` so empty
job COBs are not served to the frontend
- Add a unit test covering the filter via a stubbed `FindJobs`
This also upgrades dompurify to the latest version, outside our cooldown
window, for a security fix (verified safe with extra security checks).
Newer dompurify versions expose a bug where happy-dom renders one of our
custom elements incorrectly in tests, unlike real browsers. Switch the unit
test environment from happy-dom to jsdom to fix the failing tests.
The canonical radicle.network deployment serves the marketing landing
page at `/`, while self-hosted deployments keep the node view. Opt in
at build time without changing the default.
radicle-search now ships in the same release as radicle-httpd: one
tag, one changelog, one reproducible build, with per-binary artifacts
in sibling folders on files.radicle.dev.
meilisearch-sdk: use the pure-Rust JWT backend (jwt_rust_crypto) instead
of jwt_aws_lc_rs, dropping aws-lc-sys, which fails to cross-compile to
the Apple targets under cargo-zigbuild.