TODO:
- Upgrade radicle-artifact once released
Rebase on rad/main
cherry pick changes from dependency upgrades branch
Rebase on rad/main
Big update with lots of UI/UX improvements and bug fixes
Add creator, tag name, commit summary to Release DTO
- enrich the Release DTO so list views can render at-a-glance metadata without N+1 backend round-trips
- resolve tag refnames once per call via a small OID→name index
- pull commit summary from radicle-surf at DTO construction time
Rework releases list with teaser, filter, prominent CTA
- show creator avatar, commit OID (copyable), tag pill, and the commit summary so the list answers "what is this release" at a glance
- hide releases that have no artifacts since they're empty placeholders
- add fuzzy filter and align the New release button styling with patches
Pick seed source by artifact kind, not by fallthrough
The seed flow used to show the folder picker first and then the file picker if the user cancelled it, which surfaced two prompts in a row and limited the first one to directories regardless of the artifact type. Branch on artifact.kind so the user sees exactly one picker that matches what they're seeding.
Rework release detail view with breadcrumb, commit panel, redact
- add a breadcrumb back to the releases list to match the issue/patch views; users were stuck with browser-back as the only escape hatch
- always render the full CID via the Id copy-to-clipboard component so the value can be verified or shared without truncation guesswork
- pull the commit and show its summary plus body so the page reads as release notes instead of a bare OID
- disable the download button when no peer has advertised a location; it would have failed anyway and now the title explains why
- add a green "Local" pill driven by is_seeding so users can see at a glance whether the bytes are on disk
- add a Redact action gated to delegates/authors with a reason prompt
Add commit picker to the new-release form
Replaces the plain text input + datalist with a fuzzy-searchable dropdown that previews the commit summary and short OID. Users were typically resorting to copy/paste from another window because the datalist label only showed up after typing matched a prefix.
Add seeded-artifacts modal with disk usage and unseed
- new list_seeded_artifacts command walks every repo and emits the release artifacts whose CIDs match the iroh store's seeded tags
- artifact_size sums blob bytes (or collection child bytes) so the UI can show how much disk each entry occupies and a running total
- expose a Manage modal from Settings; users can unseed individual entries when they want to reclaim disk space
Show full CID in new-release artifact rows
The truncated form hid exactly the bit users need to verify against external tools; restack each row vertically so the full CID can wrap underneath the name/path without crowding the action.
Surface release id in breadcrumb and list rows
- breadcrumb now points at release.id so the value matches the COB id used elsewhere (URL, refresh calls); the commit OID stays on the page header where it still belongs
- list rows show both the release id and the commit OID so users can tell two releases of the same commit apart at a glance
Match release header to the list-row id pattern
Show both the release id and the originating commit OID with their own copy-to-clipboard chips, so the detail page reads the same way as the list row that brought the user here.
Sort releases newest first
Order list_releases by timestamp descending so the most recent release lands at the top of the list. Sorting explicitly rather than reversing the iterator since the underlying order is not part of the API.
Surface artifact peer details and blur trusted redactions
- expandable per-artifact panels list every attestation, location, and third-party redaction with a NodeId chip so users can see who is vouching for or hosting what
- role badges (author / delegate) flag entries whose peer matches the artifact author or a repo delegate, ranking trustworthy claims above arbitrary network noise
- when the artifact author or a delegate has redacted the entry, blur the body and surface the redaction reason in a red banner; other redactions remain visible in a regular peer list
Hide releases whose artifacts are all author/delegate-redacted
The detail view already blurs trusted-redacted artifacts; surface the same trust filter on the list so a release whose every artifact has been withdrawn by its author or a delegate drops out of discovery. The release is still reachable by direct URL since release_by_id is unfiltered.
Use a save-as dialog for blob artifact downloads
The previous flow reused pick_artifact_files (an existing-files picker) as a stand-in for a save dialog, which prompted users to select a file on disk that the download would then overwrite — confusing UX and a footgun. Add pick_artifact_save_path that opens the OS Save as dialog seeded with the artifact name, mirroring the save_embed_to_disk pattern; the frontend uses it for Blob destinations while collections keep using the folder picker.
Try HTTP before iroh for blob downloads with web URLs
When a blob artifact carries an http/https location, the iroh path could stall waiting on an unreachable provider and never fall back, even though the HTTP URL would have served the bytes in seconds.
- ureq-based fetch_http_blob writes to a .partial sibling, verifies the CID against the file, then renames into place
- the Tauri command now tries every HTTP URL first for blobs, then falls back to the iroh persistent-store path on failure
- collections still go through iroh (radicle-artifact has no HTTP collection fetch)
- aggregate the per-attempt errors via AllTransportsFailed so users see why each transport failed
Filter releases list to delegate-authored by default
Add Delegates / All toggle to the releases topbar with counts, modelled on the patches filter. Default lands on Delegates so peer-published releases from non-delegates don't appear in the discovery list unless the user opts in. Filter is local state — keeps the URL clean since this is a viewing preference, not a deep link concern.
Surface artifact action errors and rename Download when local
- inline an error banner under the artifact row when seed / download / attest / redact fails so the user sees what went wrong instead of just the dialog disappearing
- friendlier message for ArtifactError.CidMismatch (the seeding case where the user picks a file that does not match the recorded CID)
- when the artifact bytes are already in the local iroh store, the button now reads "Save to disk" and download_artifact skips the network entirely, going straight from store to the chosen path
Inline redact form and hide Attest from authors
- window.prompt is a no-op in Tauri's WebKit webview, so the redact flow silently returned null without ever invoking the backend. Replace with an inline form: red banner, required reason textarea, Cancel / Redact buttons. Empty reason is now rejected client-side before sending the request.
- Attest is a vouching signal from someone other than the author, so hide the button when the current user authored the artifact. A self-attestation would just be noise in the COB.
Use relative time with absolute hover on release page
Drop the inline formatTimestamp helper that printed a raw toLocaleString and reuse the shared utils: relative time in the meta line, full locale-formatted date in the hover title. Matches the commit page so the time stamping reads consistently across the app.
Preserve releases filter through navigation
- promote the Delegates / All toggle from local component state into a route param (filter=all in the URL, delegate stays implicit)
- pass the active filter through repo.release so the breadcrumb knows which list to return to; the link now reads "Delegate releases" or "All releases" accordingly
- ReleaseTeaser carries the current filter when navigating into a release, so clicking a row from the All view returns to All
Distinguish "shared from here" from "shared from another device"
The shared_by_us flag was per-DID, so an artifact you seeded from the CLI on a server looked identical to one you're seeding right now from the desktop. That tripped both UI signals on the release detail page:
- the Local pill flickered on before is_seeding returned false, and
- the Seed/Unseed button defaulted to Unseed, even though clicking it on this machine was a silent no-op (the unseed URL is built from this process's iroh endpoint, which doesn't match the CLI URL).
Replace shared_by_us with two flags driven by the running iroh endpoint:
- shared_from_here — at least one of our DID's iroh URLs has this process's endpoint id as its host
- shared_from_other — at least one is an iroh URL pointing somewhere else (typically the CLI on another machine)
The trait now leaves both flags at false (no iroh state in scope) and the Tauri commands fill them in via set_endpoint_flags after fetching. isAvailableLocally / isShared on the frontend are now strict about this device's state, and an amber "Other device" pill explains the edge case to the user with a tooltip about the remote peer needing to be online.
Rebase on rad/main