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.
This prevents flakes in the visual test suite due to stack frame naming
mismatches in the command copy code box.
E.g.
```diff
-{"stack":"Error: Response error\n at Dx.fet
+{"stack":"Error: Response error\n at wx.fet
```
When mermaid.render fails, suppress mermaid's "Syntax error"
overlay and show our own small warning above the original code
block so the source stays visible. Subsequent diagrams in the
same document still render.
Changes which were needed after the upgrade:
- Replace vite-plugin-virtual (vite 8 incompatible) with vite's
built-in `define` for the buildTimeConfig injection
- tsconfig: drop deprecated `baseUrl` (TS 5+ resolves `paths`
relative to tsconfig)
- Vitest 4: import `defineConfig` from `vitest/config` so `test`
is valid in vite configs
- Zod 4: rename `.errors` to `.issues`, make `ZodSchema` a
type-only import, drop the removed `SafeParseReturnType`
- Tighten/loosen generic casts in localStore to match stricter
zod 4 inference
- ESLint 9 `no-useless-assignment`: remove redundant initializers
and dead reassignments; disable the rule where Svelte's reactive
blocks confuse the analyser
- Svelte/eslint `prefer-svelte-reactivity`: disable for legacy
Svelte usages of URL / Set
- Misc naming-convention and prefer-const fixes
Convert the vertical sidebar navigation (Source, Issues, Patches) into
a horizontal tab bar above the content area. The ContextRepo info moves
into a popover behind an info button in the tab bar.
Mobile footer navigation is preserved for small screens, with the tab
bar hidden on mobile.
When a saved node (e.g. localhost) is down, the app previously showed a
dead-end "Node not found" page with no way to navigate away.
Now the not-found page displays the seed selector inline with the error
title, showing which node failed and letting users switch to a different
one directly. The same treatment applies when navigating to a repo on an
unreachable node.
They were not run by the test suite at all, because they lacked the
.spec.ts suffix. This change makes sure they're run again and fixes a
all failing specs.
Allow radicle-explorer to connect to a locally running radicle-httpd via
https://app.radicle.xyz/nodes/localhost. This was previously disabled to
encourage use of Radicle Desktop, but is now useful for testing the new
always-on node in local development environments.
Remove support for /nodes/radicle.local, an undocumented and unused convention.
Fix remote node loading when Cloudflare URL-encodes port separator (: → %3A).
We don't really need the `clipboard` prop.
By switching between stats in patches and issue listings the clipboard
props aren't been recomputed.
Wrote a test that should make sure this doesn't break in the future.
The commit listing on each patch revision started to be flaky when using
browser navigation. It seems like the `Array.sort()` call started to
reverse the order of the commit listing back to HEAD on top which isn't
what we wanted.
`Array.toReversed()` returns a fresh copy of the reversed array which is
less error prone.
We where using `sinon` in the `playwright` tests to simulate a different
time, which since `playwright@1.45.0` can be done with the Clock API
calling `page.clock.setFixedTime`.
And to test the mutex executor we can use the vitest utils spy function
`vi.fn()` instead of `sinon.spy()`