Commit Graph
15955 Commits
Author SHA1 Message Date
vitorpamplonaandgithub-actions[bot] d564dac0eb chore: sync Crowdin translations and seed translator npub placeholders 2026-06-30 01:25:28 +00:00
Vitor PamplonaandGitHub 1183ac7a00 Merge pull request #3421 from vitorpamplona/claude/nip07-permission-screen-bug-f501wz
Fix first-connect dialog suppression to allow retry after cooldown
2026-06-29 21:23:02 -04:00
Vitor PamplonaandGitHub 43a6dbaf44 Merge pull request #3420 from vitorpamplona/claude/browser-console-log-design-rq4x48
Console panel: add visibility toggle, elevation, and state sync
2026-06-29 20:31:07 -04:00
Claude 8b4f5e28f4 fix(napplet): let users re-trigger NIP-07 connect after cancelling
Pressing Back on the "Connect to Nostr" first-connect dialog resolves to
AppConnectResult.Cancelled, which added the app's coordinate to an in-memory
`sessionCancelled` set. That set suppressed every future connect prompt for the
entire broker lifetime, so a later request — e.g. the user re-clicking "login"
in the in-app browser — was silently denied and the dialog never reappeared.
Because a Cancel persists nothing, the app also never showed up in Connected
Apps, leaving the user with nothing to clear to recover.

Replace the permanent suppression with a short, self-clearing cooldown
(`cancelledUntil` map): a Cancel suppresses re-prompts only briefly so the
burst of requests a page/napplet fires on load doesn't relaunch the dialog per
request, while a deliberate retry seconds later prompts again. The clock is
injectable for deterministic tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HDcts4HzwSff4fy6oSVA6D
2026-06-30 00:16:31 +00:00
Claude 7d7789c8c9 fix(browser): console toggle + on-top pull tab in full-screen browser
The full-screen direct-WebView browser (NappletBrowserActivity, launched when
you type an address) and the sandbox host (NappletHostActivity) used an older
console design that diverged from the embedded tabs' Compose chrome:

- The Console row in NappletControlSheet was a plain action row and the bottom
  pull-up grabber was always visible. Make Console a Switch toggle (like the Tor
  row / the Compose TopControlSheet), and hide the whole NappletConsolePanel
  until the toggle is on — turning it on reveals the sheet already pulled up,
  mirroring BottomConsoleSheet.
- The console grabber/panel sat at elevation 0 while the top sheet's panel is at
  6dp, so an open top sheet drew over the console when they overlapped (e.g. in
  landscape). Elevate the console sheet above the top sheet so its pull tab and
  log render on top, matching the Compose layer where BottomConsoleSheet is
  composed after TopControlSheet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A9kfpNrBRB8WJNi67NHGGX
2026-06-30 00:14:19 +00:00
Vitor PamplonaandGitHub 4326d84887 Merge pull request #3415 from vitorpamplona/claude/git-repo-readme-code-tabs-e4uf6c
Add git smart-HTTP browser for NIP-34 repositories
2026-06-29 19:50:24 -04:00
Claude fdcfc05ba2 refactor(git): collapse status/PR-update indexes to map().stateIn
Now that observeEvents re-emits the whole matching list each time,
GitStatusIndex and GitPullRequestUpdateIndex no longer need the imperative
launch/collect-into-MutableStateFlow wrapper carried over from the old
newEventBundles version. Each is now a single observeEvents().map { reduce }
.stateIn(scope, Eagerly, null) — dropping startIfNeeded(), the AtomicBoolean
double-start guard, and the MutableStateFlow/asStateFlow pair.

Eagerly (not WhileSubscribed) is required: callers read .value synchronously
(isClosedOrResolved, the feed filters, the home open-count derivations) and
must not see a stale map when nobody is collecting. All startIfNeeded() call
sites removed; stateIn shares one upstream subscription across collectors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 23:43:25 +00:00
Claude 9a6c535cbd feat(git): bookmarked repositories as a standalone screen
Replace the third "Repositories" tab on the default bookmark screen with a
dedicated entry on the bookmark-lists screen, mirroring how Pinned Notes
works: a row in ListOfBookmarkGroupsFeedView that opens its own
BookmarkedRepositoriesScreen via the new Route.BookmarkedRepositories.

The row shows the bookmarked-repo count from
gitRepositoryListState.publicRepositoryAddressSet; the screen renders the
BookmarkRepositoriesFeedViewModel feed (moved to a repositories/ package),
invalidates on bookmark changes, and preloads any uncached repo
announcements via the EventFinder. Reverts the tab added to
BookmarkListScreen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 23:30:40 +00:00
Claude a2f918c1eb feat(git): bookmarked repos tab + observeEvents for GitStatusIndex
- GitStatusIndex now subscribes to a kind-1630..1633-filtered
  LocalCache.observeEvents instead of LocalCache.live.newEventBundles,
  matching the GitPullRequestUpdateIndex change: the indexed observable
  seeds from the cache index and re-emits the full list on each new status
  event, so the manual onStart full-cache scan and per-bundle type
  filtering are gone and the collector just reduces to latest-per-target.
- Bookmark screen gains a third "Repositories" tab listing the user's
  bookmarked (NIP-51 kind 10018) git repositories. New
  BookmarkRepositoriesFeedFilter resolves the public repository address set
  to addressable notes (newest first); the screen invalidates it on
  publicRepositoryAddressSet changes and preloads any uncached repo
  announcements via the EventFinder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 23:20:19 +00:00
Claude 0d8936e8d3 refactor(git): index PR updates via LocalCache.observeEvents
GitPullRequestUpdateIndex now subscribes to a kind-1619-filtered
LocalCache.observeEvents instead of LocalCache.live.newEventBundles. The
indexed observable seeds its matching set from the cache index (via init())
and re-emits the full list on each new PR update, so the manual onStart
full-cache scan and the per-bundle type filtering over every event of every
kind are both gone. The collector just reduces the list to the
latest-per-parent map. PR updates are rare, so recomputing the whole map per
emission is cheaper than scanning every bundle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 23:06:11 +00:00
Claude 2316e72573 fix(git): bookmark feedback, social divider, and disappearing-bar reset
- Top-bar repo bookmark toggle now switches between BookmarkAdd (with +)
  and Bookmark glyphs instead of two identical  glyphs, so the icon
  visibly changes shape (not just tint) when starred/unstarred.
- Add a thin HorizontalDivider after the ReactionsRow on the repo home.
- Code browser: opening/closing a file or changing folders swaps the
  scrollable in place, landing the new view at the top with no scroll
  delta, which left the disappearing top bar stranded at its hidden
  offset over a blank band. Expose the scaffold bar state via
  LocalDisappearingBarState and reset it to visible on each in-place view
  change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 23:01:16 +00:00
Claude f14ddd9e45 fix(git): import KMP Dispatchers.IO in GitRepositoryListState
The commonMain GitRepositoryListState used Dispatchers.IO without importing
the multiplatform kotlinx.coroutines.IO extension, so it resolved to the
JVM-only member and broke the iOS native compile
(:commons:compileKotlinIosSimulatorArm64). Matches BookmarkListState.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 22:44:14 +00:00
Claude 2f9162a96f feat(git): New Issue is a full screen; fix square FAB shape
- Converts the New Issue composer from an AlertDialog to a dedicated screen
  (new Route.GitRepositoryNewIssue + GitNewIssueScreen with its own top bar
  and a Create action). The Issues FAB now navigates to it.
- The extended FAB rendered square because the app theme sets shapes.large
  (the extended-FAB default shape) to 0.dp; pin an explicit RoundedCornerShape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 22:06:02 +00:00
Claude 3e0c688b8c feat(git): htree open-in-browser fallback; remove maintainers; tighten gaps
- Repos that can't be cloned over http(s) (e.g. Iris's htree://) now show a
  "Hosted externally" notice with an open-in-browser link instead of an empty
  dashboard — on the home, the Code screen, and the feed repo card.
- Removed the "Maintained by" row from the project home.
- Tighter home section spacing (12 → 8dp) and a smaller bottom padding on the
  feed repo card so the last-commit line sits closer to the reaction row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 21:06:24 +00:00
Claude a4bd541522 feat(git): snapshot cache, FAB, disappearing-bar fix, title subtitle, spacing
- Snapshot cache: a process-wide GitRepoSnapshotCache keyed by repo address.
  The browser ViewModel serves an already-fetched default-branch snapshot
  synchronously, so the stats render in share-to-image and don't re-fetch when
  switching screens.
- Issues/PR screens: filter chips now live inside the disappearing top bar
  (via the scaffold's belowBar slot) so they hide with it instead of leaving a
  static black band; the feed uses normal content padding.
- New issue is now an extended FAB on the Issues screen.
- Top bar shows the repo description as a single-line subtitle under the name;
  removed the duplicate description from the home body.
- Tighter spacing: home sections, code header rows (branch row / search /
  breadcrumb).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 20:50:07 +00:00
Claude 2378d70326 Merge remote-tracking branch 'origin/main' into claude/git-repo-readme-code-tabs-e4uf6c 2026-06-29 20:09:01 +00:00
Vitor PamplonaandGitHub 2152d5d5d6 Merge pull request #3416 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-06-29 15:47:30 -04:00
vitorpamplonaandgithub-actions[bot] 4060bfac39 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-29 19:43:35 +00:00
Vitor PamplonaandGitHub f5879ab107 Merge pull request #3418 from vitorpamplona/claude/cashu-wallet-wizard-0zr280
Add Cashu wallet find-or-create wizard with cross-relay discovery
2026-06-29 15:40:59 -04:00
Claude a687e03461 Merge remote-tracking branch 'origin/main' into claude/cashu-wallet-wizard-0zr280
# Conflicts:
#	amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt
2026-06-29 19:26:56 +00:00
Claude 124dcafdf9 fix(cashu): re-sign on adopt so a deleted wallet can't be re-deleted
The find-or-create wizard can surface a wallet the user previously
DELETED — a relay that missed the kind:5 still serves the kind:17375 to
the crawl. adoptDiscoveredWallet rebroadcast that event verbatim (same id,
same created_at), which loses to the prior NIP-09 deletion two ways:
DeletionEvent.build emits both an `e` tag (old id) and an `a` tag (the
replaceable 17375:pubkey: address), so relays reject the duplicate id and
re-delete every version with created_at <= the deletion's the moment the
kind:5 propagates back — on relays and in our own LocalCache. The
"reactivated" wallet would then silently vanish.

Adopt now re-signs a FRESH kind:17375 + kind:10019 (via publishWalletEvents)
with the discovered wallet's own mints and P2PK key. A new id escapes the
`e`-tag delete and created_at=now escapes the `a`-tag delete, while the
same key + mints preserve the nutzap address and all recoverable funds
(the NUT-13 seed derives from the key, not the event id). Falls back to a
verbatim rebroadcast only if the wallet can't be decrypted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EqmMR2QiULS5QGosSgSQAe
2026-06-29 18:18:38 +00:00
Claude 0bfe9d370e fix(cashu): return to the Wallet hub after deleting the wallet
Deleting the Cashu wallet popped back to CashuWalletScreen, which on an
empty wallet auto-launches the find-or-create wizard — so the user was
funneled straight back into creating the wallet they just deleted.

Navigate to the top-level Wallet hub (Route.Wallet) via newStack instead,
which pops the Cashu screens off the back stack so the wizard never
composes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EqmMR2QiULS5QGosSgSQAe
2026-06-29 18:13:18 +00:00
Claude d2dfd044cf feat(cashu): add "Wallet Created" celebration before the mint picker
In the find-or-create wizard, choosing "Create a new wallet" jumped
straight to the mint manager. Add a short celebratory interstitial first:
an animated check badge springs in (bouncy overshoot) behind an expanding
pulse ring, "Wallet Created" + "Now pick a few mints to host your sats"
fade up, a haptic fires, and a "Pick mints" button continues to the mint
selection.

The screen is purely presentational — the kind:17375 still isn't
published until the user adds a mint on the next screen — so "Pick mints"
uses popUpTo to replace the interstitial in the back stack, avoiding an
awkward return to the celebration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EqmMR2QiULS5QGosSgSQAe
2026-06-29 18:02:31 +00:00
Claude 29303b18c2 feat(git): make recent-activity rows and the last-commit line clickable
- Recent-activity rows navigate to the issue/PR they represent (routeFor).
- The last-commit strip is now tappable: on the home it opens the Code
  screen; on the feed repo card it opens the repository.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 17:50:03 +00:00
Claude 09633abae5 feat(git): home polish + repo-card dashboard in the feed
Home screen:
- Nav cards: tighter vertical spacing; badges now count only OPEN issues/PRs,
  derived from the live GitStatusIndex (started on the home so the split is
  correct without visiting the Issues screen first).
- Moved the reaction row to after the recent-activity pulse.
- Added the standard 3-dot note menu (MoreOptionsButton) to the top bar.

Feed card (RenderGitRepositoryEvent):
- Replaced the web/clone links with the same stat tiles + language bar +
  last-commit strip used on the home, loaded from a lazily-fetched shallow
  snapshot. (Factory made internal so the card can build the browser VM.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 17:45:18 +00:00
Claude 45f36a8159 refactor(git): use the standard ReactionsRow; tighten file rows
- Social bar now renders the app's canonical ReactionsRow (reply, boost,
  like, zap, zapraiser, reaction gallery) instead of a bespoke subset, so
  the repository announcement behaves exactly like any other note.
- Code browser file rows: replace the heavy 32dp boxed icon with a plain
  20dp icon and tighten spacing/padding, reducing the oversized horizontal
  gap before the file name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 16:56:24 +00:00
Claude f0100a35b3 refactor(git): move repo identity into the top bar title
The owner avatar + project name was duplicated as the home's first content
line and the top-bar title. Consolidates it into the top bar: a small owner
avatar (tappable to the profile) + project name. The home hero now carries
only the description and topic/fork chips.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 16:51:51 +00:00
Claude 52f830dd2e fix(git): make the "Mine" repo filter show the user's own repositories
The repositories feed never special-cased TopFilter.Mine, so it inherited
the shared Mine→all-follows fallback — "Mine" behaved identically to "All
Follows", making both selectors look unresponsive when toggled.

Mirrors the music/badges/communities/nsites pattern:
- GitRepositoriesFeedFilter: when the list is Mine, match repositories
  authored by the logged-in user (feed + applyFilter).
- GitRepositoriesSubAssembler: when the list is Mine, query the user's own
  repositories by author against their outbox relays (new
  filterGitRepositoriesMine), bypassing the follow-list machinery.

"All Follows" already routed through the standard follows filter; it now
visibly differs from "Mine".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 16:10:10 +00:00
Claude 39a8b7473e fix(cashu): populate mint suggestions in the create-wallet picker
The mint picker (CashuMintsScreen) already renders NIP-87 directory
suggestions, but in the find-or-create wizard's "create a new wallet"
path they showed up empty while the edit-mints screen had them.

Cause: openMintDirectory() subscribed the directory against a one-shot
snapshot of the account's outbox relays (acc.outboxRelays.flow.value). A
freshly-restored account reaching the create path often still has its
relay lists loading, so the snapshot was empty, hit
CashuMintDirectoryState's empty-relay early-out, and never retried.
Outbox-only relays also don't reliably carry the broad NIP-87 mint
announcements.

Fix: subscribe reactively to the union of the user's OUTBOX relays and
their INDEXER relays. The flow re-subscribes the moment relays arrive,
and indexer relays aggregate NIP-87 mint data and fall back to a curated
default set — so the picker is populated even for a brand-new user with
no wallet and no recommendations of their own yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EqmMR2QiULS5QGosSgSQAe
2026-06-29 16:01:55 +00:00
Claude b591984118 refactor(git): unify project home into one dashboard design
Removes the old boxed "Overview" section block (About/Links/Topics/
Maintainers cards) that was stacked on top of the new dashboard, which made
the home read as two designs. Its useful content now lives in the dashboard
language:

- New RepoHero: owner avatar + "name / project" title (GitHub-style), with
  description and topic chips.
- RepoMaintainersRow: a compact maintainer avatar cluster.
- Drops the Links card (clone/web URLs) as low-value.

Deletes GitRepositoryOverview.kt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 15:45:33 +00:00
Claude d270b6a69f feat(git): make the project-home social row interactive
Replaces the read-only zap/reaction/comment counts with the canonical
ZapReaction / LikeReaction / ReplyReaction actions, so the repository home
now supports one-tap zaps (with the amount dialog), reactions, and replying
to the repo announcement — each with its live counter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 15:38:37 +00:00
Claude 2ad4af2479 feat(git): rich project-home dashboard (stats, languages, social pulse)
Turns the repository home into a data-rich dashboard combining git facts
with the Nostr social layer:

- Social row: live zap / reaction / comment counts on the repo announcement
  (via observeNoteZaps/Reactions/ReplyCount).
- Stat tiles: branches, tags, file count, and last-updated relative time.
- Language breakdown bar: proportional colored segments computed from the
  snapshot's file tree by extension (new GitRepoSnapshot.walkFileNames()).
- Last-commit strip: tip commit summary, author, time and short SHA, exposed
  up-front via the new GitRepoSnapshot.tipCommit (no extra fetch).
- Nav cards now show open issue / PR counts.
- Recent-activity pulse: newest issues/patches merged from the feeds.

quartz: GitRepoSnapshot gains tipCommit (parsed in open()) and
walkFileNames() to enumerate blob paths for the language bar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 15:32:47 +00:00
Claude d2225c73cc feat(git): replace repo tab bar with project home + drill-in screens
Replaces the five-tab repository screen (Readme/Code/Overview/Issues/Patches)
with a scrollable Project Home and three dedicated screens:

- GitRepositoryScreen is now the home: repository facts (from the former
  Overview), Code / Issues / Pull Requests navigation cards, and the README
  rendered inline — all in one scroll.
- New GitRepositoryCode/Issues/Pulls screens, each owning its own
  disappearing top bar, reached via new addressable routes.

This removes tab overflow and the swipe-paging between heavy screens, and
fixes the per-tab header issues structurally: the Code browser's branch/tag
and file-search header now live inside the scroll list, so they track the
disappearing top bar instead of staying pinned below it.

README and Overview were refactored into embeddable, non-scrolling sections
(GitReadmeSection, GitRepositoryOverviewSections) so the home can compose
them in a single scroll container.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 00:15:51 +00:00
Claude 144f543014 fix(git): move browser ViewModel factory app-side for KMP lifecycle
The KMP lifecycle-viewmodel artifact used by commons doesn't expose the
create(Class<T>) ViewModelProvider.Factory override (only the desktop/JVM
target hit this), so the factory now lives in amethyst alongside the
viewModel() call, mirroring the NestViewModel pattern. The commons
ViewModel keeps only platform-agnostic state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-29 00:00:31 +00:00
Claude d6ec458117 fix(git): close Issues/PR feed top gap; add "Mine" repo feed filter
The status feed drew its filter-chip header at the top of the content area
(under the disappearing top bar) while the feed's LazyColumn separately
re-applied the full bar-height inset as content padding, leaving an empty
band above the first item. The header now consumes the scaffold top inset
itself and the inner feed renders with the top inset zeroed, matching the
Code tab's padding pattern.

Also adds a "Mine" option to the git repositories top-nav filter so the
feed can show only the logged-in user's own repositories. The feed side
already resolves TopFilter.Mine generically; this just exposes it via a
dedicated gitRepositoryRoutes catalog (kind3 + Around Me + Global + Mine).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 23:55:35 +00:00
Claude 714d202e7d refactor(git): move code-browser ViewModel + syntax highlighter to commons
Relocates the two app-agnostic pieces of the NIP-34 code browser into commons
so the desktop front end can reuse them verbatim:

- GitRepositoryBrowserViewModel (+ GitBrowseState) → commons jvmAndroid
  nip34Git package. Pure StateFlow ViewModel over quartz's GitHttpClient;
  no Android/AccountViewModel/INav dependency.
- CodeHighlighter → commons commonMain nip34Git/ui. Pulls the Apache-2.0
  dev.snipme:highlights dependency into commons commonMain.

Amethyst composables now import both from commons. The screen-level
composables stay app-side, matching the commons convention that shared UI
never takes AccountViewModel/INav.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 22:55:56 +00:00
Claude 5c29c277c8 Merge remote-tracking branch 'origin/main' into claude/git-repo-readme-code-tabs-e4uf6c 2026-06-28 22:29:16 +00:00
Claude 5aaaa90cd7 feat(git): bookmark repos + label filter & counts on status feed
Adds NIP-51 (kind 10018) repository bookmarking with a star toggle in the
git repository top bar, backed by a new GitRepositoryListState in commons.
Removal rebuilds the public tag set and re-signs so encrypted private
bookmarks are preserved without decryption.

Adds a label-filter chip row and open/closed item counts to the Issues and
Patches & PRs status feeds. The active feed's distinct labels drive the
chips; selecting one filters the rendered list, and a stale selection is
dropped when switching status.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 21:57:31 +00:00
Claude 402c2fd3b4 feat: commit history in the git repository code browser
Add a History action to the Code tab that shows a git-log-style list of the
branch's recent commits, and opens the diff a commit introduced (vs its first
parent) with the shared diff viewer.

quartz: GitCommit + a commit-object parser (skips multi-line headers like a
signed gpgsig), and GitHttpClient.loadHistory() — a shallow tree:0 fetch
(commits only) walked most-recent-first. The fetch filter is generalized from
a blob:none boolean to a filter spec so tree:0 can be requested. Unit-tested
against a real SSH-signed commit object.

amethyst: GitCommitLog (log list + per-commit diff), a History button on the
repo header, and ViewModel hooks (loadHistory / commitDiff).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 21:27:12 +00:00
Claude 9207209b0b feat: word-level intra-line highlighting in git diffs
Emphasize what changed inside a modified line, not just the whole line.
A new pure IntralineDiff helper pairs each delete with its corresponding
add within a hunk and trims the common prefix/suffix to the differing
middle; GitDiffView layers a stronger add/delete background over just that
character span, on top of the existing syntax highlighting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 21:14:57 +00:00
Claude a44ee6b312 feat: finish git PR/patch review — computed diffs and status actions
Pull requests reference a clone URL + commit rather than embedding a patch,
so their changes were invisible. Now the app computes and renders them.

- quartz: a pure Myers O(ND) line-diff (LineDiff) producing the same
  GitDiffHunk model the embedded-patch parser uses, unit-tested against git
  -U3 output and with a reconstruction property check.
- quartz: GitHttpClient.computeDiff(cloneUrl, head, base?) — fetches both
  commit trees, finds changed files by oid, batch-fetches the differing
  blobs and line-diffs each into a ParsedPatch (base = merge base, or HEAD).
- amethyst: a "View changes" section on the PR card that loads the diff over
  the git client and renders it with the shared GitDiffView.
- amethyst: GitStatusActions generalizes the issue open/close controls to
  issues, patches and PRs — patches/PRs additionally get "Mark merged"
  (GitStatusAppliedEvent). Visible to the author and repo owner/maintainers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 20:33:31 +00:00
Vitor PamplonaandGitHub 447d48bb83 Merge pull request #3395 from vitorpamplona/claude/keen-dijkstra-tzvqgd
Add Nostr signer permissions & relay auth management UI
2026-06-28 16:30:41 -04:00
Claude f25138fe7a feat: edit a NIP-34 repository announcement from the repo screen
Add an owner-only Edit action to the git repository screen's top bar that
opens a settings dialog. Because the repository event (kind 30617) is
addressable, saving republishes it under the same d-tag — preserving the
earliest-unique-commit, relays, maintainers and personal-fork flag — while
letting the owner edit the name, description, clone/web URLs and topics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 20:14:54 +00:00
Claude cd934fb0ea feat: git code browser branch/tag switch, file search, image preview; issue labels
Code browser:
- Branch & tag switching: the client now exposes all refs from ls-refs;
  a branch/tag picker on the repo header reloads the tree at the chosen
  ref (GitRepositoryBrowserViewModel.switchRef).
- In-tree filename search: a search field filters the whole tree
  (GitRepoSnapshot.searchFiles) and shows matching paths.
- Image preview: png/jpg/gif/webp/bmp blobs render via Coil instead of the
  binary notice.

Issues:
- Labels at creation: the new-issue composer takes a comma/space separated
  label list, written as NIP-34 `t` tags.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 20:12:00 +00:00
Claude 62f8cbe48a fix: resolve nsite icons and titles by trying both napplet and nsite manifest kinds
NSite manifests (kinds 15128/35128) were never found because all coordinate
construction hardcoded napplet kinds (15129/35129). The connected apps list
and detail screen therefore showed no icon or title for nsite entries.

- Add rememberManifestIconModel(author, identifier) in NappletFavoriteIcon.kt:
  tries napplet coord first, falls back to nsite coord. resolveIconBlob already
  handled all four event types — just needed the right coordinate.
- Replace rememberNappletManifest with rememberManifestEvent in
  ConnectedAppsScreen.kt: watches both napplet and nsite notes, returns
  whichever carries an event. NappletAppCard dispatches on the event type
  to extract title/icon from NappletManifest, RootSiteEvent, or NamedSiteEvent.
- ConnectedAppDetailScreen.AppIdentityHeader: swap hardcoded kind+
  rememberNappletIconModel call for rememberManifestIconModel(author, identifier).
- resolveNappletMeta in NappletManifestLookup.kt: widen the cache filter to
  include nsite kinds and dispatch title/icon extraction across all four types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hTFpoExYYLYEGGtXBx6ZT
2026-06-28 20:07:11 +00:00
Claude 7f583c3988 feat: surface git pull-request updates (kind 1619) in the repo screen
NIP-34 pull-request update events (kind 1619) revise a PR with a newer
commit / merge base, but the repository screen neither subscribed to them
nor reflected them, so updated PRs looked stale.

- Subscribe to GitPullRequestUpdateEvent.KIND in RepositoryContentKinds so
  updates reach the repo screen.
- Add GitPullRequestUpdateIndex (mirrors GitStatusIndex): tracks the latest
  update per parent PR id from LocalCache, exposed as a StateFlow.
- Fold the latest update into the parent PR card: the current commit, merge
  base and clone URLs now reflect the newest revision, with a "Revised"
  marker on both the PR card and the compact Patches-tab row.

Updates are folded into their parent PR rather than listed as separate rows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 19:44:05 +00:00
Claude c464c7cdba feat: replace capability toggle with dialog and fix napplet icon loading
- Capability rows now open a dialog with radio options (Ask each time /
  Always allow / Never allow) instead of the confusing Switch+revoke
  button combo; requiresPerUseConsent capabilities omit "Always allow"
- AppIdentityHeader now reactively loads napplet/nsite icons via
  rememberNappletIconModel using the full kind:pubkey:identifier coord

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hTFpoExYYLYEGGtXBx6ZT
2026-06-28 16:22:01 +00:00
Claude bee418fd17 fix: clarify capability toggle and revoke button semantics in ConnectedAppDetail
The toggle ON/OFF state was ambiguous (users couldn't tell if OFF meant
"ask me" or "permanently deny"). The revoke/Block icon looked like a deny
action but actually resets to "ask me each time".

- Add "Allow always" (primary) / "Never allow" (error) label above the
  Switch so the toggle's two states are explicit
- Swap MaterialSymbols.Block for MaterialSymbols.Refresh on the reset
  button — Refresh reads as "start over / go back to asking"
- Update its content description to "Ask me each time"
- Rename "Blocked" to "Requires per-use approval" for per-use-consent
  capabilities to explain why there's no toggle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hTFpoExYYLYEGGtXBx6ZT
2026-06-28 16:06:36 +00:00
Claude 39727d819e feat: flagship git review — diff viewer, issue management, polished Issues tab
Build out the repository screen into a project-review hub.

PR/patch diff viewer:
- quartz: UnifiedDiffParser turns a NIP-34 patch (kind 1617) `git
  format-patch` body into a commit message + structured per-file diffs,
  bounding each hunk by its header counts so the mbox "-- " signature is
  never miscounted. Unit-tested against a real git-generated patch.
- amethyst: GitDiffView renders a GitHub-style file-by-file diff —
  stat summary, collapsible file cards, +/- line coloring, old/new line
  numbers, and per-line syntax highlighting reused from the code browser
  (size-guarded). Wired into the patch card; feeds keep the compact preview.

Issue management:
- New-issue composer (subject + body) that builds, signs and broadcasts a
  GitIssueEvent via the account signer; reachable from the Issues tab.
- Author/maintainer Open/Close controls on the issue card, publishing
  GitStatusOpen/Closed events that flow back through GitStatusIndex.

Issues tab polish:
- Open/Closed filter chips, label (#topic) chips on each row.

Adds git_diff_files_changed plural and issue/diff strings. No new icons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DpNmN8CvP6HnEsdTGAjVUr
2026-06-28 16:00:35 +00:00
Claude f502b09b55 feat: rename See more/less to Show/Hide Event and make JSON scrollable
The raw event JSON toggle in the signer consent dialog is now labeled
"Show Event" / "Hide Event" instead of the generic "See more" / "See less".
The expanded JSON block also gains horizontal scroll (softWrap=false +
horizontalScroll) so wide event JSON doesn't get clipped on narrow screens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hTFpoExYYLYEGGtXBx6ZT
2026-06-28 15:57:52 +00:00