feat(desktop): add Projects as first-class top-level view#546
Merged
Conversation
Add Projects to the desktop sidebar with full routing, data fetching, and detail pages. Projects are sourced from kind:30617 (NIP-34 repo announcement) events via the relay. Navigation: - Projects sidebar entry between Pulse and Agents - /projects route with dense project list - /projects/$projectId route with targeted #d tag query Data layer: - useProjectsQuery() for list, useProjectQuery() for detail - Multi-value clone URL tag parsing (single tag with multiple values) - NIP-33 dedup by pubkey:kind:d-tag, composite IDs for uniqueness - KIND_REPO_ANNOUNCEMENT constant in shared/constants/kinds.ts UI: - Keyboard-accessible project cards (button overlay pattern) - Error/empty/loading states with retry buttons - Resolved display names via useUsersBatchQuery + resolveUserLabel - UserAvatar for contributors, isSafeUrl gate on web URLs - Shared isSafeUrl extracted to shared/lib/url.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collaborator
Author
This was referenced May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
/projectsroute with dense operational project list sourced from kind:30617 (NIP-34 repo announcements)/projects/$projectIdroute with detail page showing clone URLs, web link, resolved contributors with avatarsrelayClient.fetchEvents()with NIP-33 dedup and 60s stale timeDetails
Navigation & routing:
AppViewtype extended with"projects",deriveShellRoute()updatedgoProjects()andgoProject(id)navigation functionsData layer (
features/projects/hooks.ts):useProjectsQuery()— fetches kind:30617 events, deduplicates bypubkey:kind:d-taguseProjectQuery(id)— targeted#dtag filter query (not capped by list limit)tag.slice(1)for single["clone", url1, url2]tags)pubkey:dIDs for React key uniquenessKIND_REPO_ANNOUNCEMENTconstant inshared/constants/kinds.tsUI:
useUsersBatchQuery+resolveUserLabelUserAvatarfor contributor displayisSafeUrlgate on web URLs (extracted toshared/lib/url.ts, shared with DiffMessage)Notable NITs (not addressed)
isSafeUrl(desktop has no vitest/jest infra — e2e only)setTimeoutcleanup in CloneUrlRow copy buttonCardListLoadingBody(renamed fromWorkflowsLoadingBody)Test plan
/projects, shows project list/projects/$projectId, shows detail/projects/$projectIdworks (targeted query)javascript:scheme does not render as a link🤖 Generated with Claude Code