Commit Graph
144 Commits
Author SHA1 Message Date
nrobi144 fe22de0817 feat: shared index relays across Desktop and amy + settings UI
Unifies the "index relays" set (used for kind 0 profile metadata and
kind 3 follow list REQs) across the Desktop app and the `amy` CLI so
they always compute WoT scores against the same data source, and adds
a user-configurable settings section for the list.

Before this change:
- Desktop hard-coded `DefaultRelays.RELAYS` at coordinator
  construction; users could not override.
- `amy wot sync` used `outboxRelays().ifEmpty { inboxRelays() }` —
  NIP-65 write / DM inbox relays, which are semantically different
  from index relays. `amy wot get` after `amy wot sync` could return a
  different score than the Desktop UI would compute.

New `PreferencesIndexRelays` (commons/jvmMain) is a tiny class backed
by `java.util.prefs.Preferences.userRoot().node("com/vitorpamplona/amethyst/relays/index")` —
the same JVM-user-scoped shared-node trick `PreferencesHashtagSpamSettings`
already relies on. Both Desktop and amy running as the same OS user
observe the same value with zero extra plumbing. App-global (not
per-account); users typically have one preferred index-relay set
regardless of which account is logged in.

Behaviour changes for users who never open the settings UI: none.
`DEFAULT_INDEX_RELAYS` is byte-for-byte identical to the four URLs in
`DefaultRelays.RELAYS`.

Wiring:
- `DesktopRelayCategories` gains a straight-through `indexRelays`
  StateFlow (no combine — index relays are a curated user choice, not
  a NIP-65-derived set) plus `setIndexRelays(new)`.
- `Main.kt` instantiates `PreferencesIndexRelays` at App() root and
  passes it into both the subscriptions-coordinator constructor and
  `DesktopRelayCategories`. Coordinator snapshots the effective set
  at construction — changes take effect on next relaunch (documented
  in the settings section explainer).
- `Context.indexRelays()` reads the same preferences node so
  `WotCommand.sync` produces identical relay batches to Desktop.
- New `IndexRelaysSection` composable in
  `desktopApp/.../ui/settings/` — list + per-row remove + add-row
  with URL normalisation. Deletion of all entries falls back to
  defaults (delete-all is the reset — no separate "Reset" button).
  Placed between the Local Relay and Content Filters sections of the
  Relays settings screen.

Tests:
- `PreferencesIndexRelaysTest` — defaults fallback, round-trip
  persistence, blank-token skipping, non-empty defaults guardrail.
- Full existing test suites remain green.

Companion PR (search-result badges) landed on `feat/wot-search-badges`
and is this branch's parent. Both remain stacked on the WoT feature
branch pending upstream review.

Plan: docs/plans/2026-07-01-feat-wot-followups-search-badges-and-index-relays-plan.md
2026-07-06 09:31:02 +03:00
nrobi144 9284e12e86 feat(desktop): Web-of-Trust score badges + amy wot verbs
Adds a friends-of-friends trust score on every user avatar in Desktop
feeds, threads, profile headers, and repost overlays. For pubkey X the
score is the count of accounts in the active user's follow set who also
follow X — Gossip / Snort convention. v1 is display-only; no threshold
filtering.

Data flow
- `commons/wot/WoTService` — sparse `SnapshotStateMap<HexKey, Int>` +
  reverse index + per-follower snapshot for diff-based updates.
  Single-writer coroutine (Channel<Op> → `Snapshot.withMutableSnapshot`)
  serializes all mutations. Cap at 5000 follows/event blocks DoS via
  hostile kind-3s. Guardrail at 2000 follows/account skips WoT for
  mega-accounts.
- `DesktopIAccount.wotService` — per-account instance, matches
  `Kind3FollowListState` / `BookmarkListState` conventions.
- `Main.kt` binds `localCache.accountPubkey`, collects
  `localCache.contactListEvents` → `applyKind3`, collects
  `localCache.followedUsers` → `onFollowSetChange` +
  `subscriptionsCoordinator.loadKind3Batched(...)` with
  `onEose = markReadyOnce`. 2 s fallback timeout guarantees badge
  visibility even if index relays never EOSE.
- `FeedMetadataCoordinator.loadKind3Batched(pubkeys, onEose)` — chunks
  authors into ≤100 per Filter within one subscription. Matches
  nostr-rs-relay defaults.

UI
- `commons/ui/components/UserAvatar` gets an optional
  `badge: @Composable BoxScope.() -> Unit`. Android call sites pass
  null (no compile-time coupling to Desktop-only tooltip APIs).
- `desktopApp/.../ui/note/WoTBadge` — Material3 `TooltipBox` +
  `PlainTooltip` (multiplatform-ready, keyboard/screen-reader a11y).
  `rememberTooltipState(isPersistent = true)` fixes the
  vanish-too-fast desktop default.
- `desktopApp/.../ui/note/WoTBadgedAvatar` — drop-in replacement for
  `UserAvatar` that overlays the badge when
  `LocalWoTService != null && LocalWoTReady && pubkey !in LocalSpamExemptKeys`.
  Score read is a plain `service.scores[userHex] ?: 0` — snapshot
  system tracks per-key, so avatars only recompose when their own
  score changes.
- Call-site migration at 4 v1 surfaces: NoteCard header (covers feed /
  thread / bookmarks / search / QuotedNoteEmbed via NoteCard),
  FeedNoteCard repost header (2 avatars), UserProfileScreen header
  (2 sizes).

Amy verbs
- `amy wot get <pubkey|npub> [--json]` — hydrates a WoTService from the
  local FsEventStore, prints score for target pubkey.
- `amy wot list [--threshold N] [--limit K] [--json]` — sorted score
  list.
- `amy wot sync [--timeout N]` — batch-fetches kind-3 for the active
  follow set from outbox/inbox relays, persists to the event store.

Tests + docs
- 14 unit tests: `WoTServiceTest` covers happy path, sparse map,
  self/follower exclusion, kind-3 churn diff, guardrail, event cap,
  ready gate, clear.
- Manual testing sheet with 17 scenarios at
  `desktopApp/plans/2026-07-01-wot-score-manual-testing-sheet.md`.
- Plan at `docs/plans/2026-07-01-feat-desktop-wot-score-plan.md`.

Prerequisite `DesktopLocalCache.consumeContactList` scoping fix landed
as a separate commit.
2026-07-02 18:03:47 +03:00
vitorpamplonaandgithub-actions[bot] 73c9e2086a chore: sync Crowdin translations and seed translator npub placeholders 2026-07-01 21:19:15 +00:00
Vitor PamplonaandGitHub 3246f13044 Merge pull request #3431 from nrobi144/feat/desktop-hashtag-spam-filter
feat(desktop): hashtag-spam filter with collapse-with-reveal
2026-07-01 07:35:37 -04:00
davotoulaandgithub-actions[bot] dde6616451 chore: sync Crowdin translations and seed translator npub placeholders 2026-07-01 08:27:22 +00:00
nrobi144 d0646acf3c Merge upstream/main into feat/desktop-hashtag-spam-filter 2026-07-01 09:53:09 +03:00
nrobi144 7a18e30fc4 feat(desktop): hashtag-spam filter with collapse-with-reveal
Damus-inspired content filter that collapses notes abusing `t` hashtag
tags into a compact reveal-on-click placeholder. Ships default ON with a
threshold of 5 (adjustable 1–20 in Settings → Content Filters, or off).

Scope
- Pure check (`HashtagSpamCheck`) + settings interface
  (`HashtagSpamSettings`) live in `commons/moderation/`, callable by
  Desktop, `amy` CLI, and (future) Android.
- JVM-backed `PreferencesHashtagSpamSettings` writes to the shared
  `java.util.prefs` node `com/vitorpamplona/amethyst/filters`, so `amy`
  and Desktop observe the same value automatically.
- `CollapsedSpamNote` placeholder in `commons/ui/note/` takes only
  primitive scalars so Android can adopt it without touching commons.
- Desktop wraps every `NoteCard` call site (FeedNoteCard, QuotedNoteEmbed,
  BookmarksScreen, 5 SearchResultsList sites) with a shared
  `SpamCheckedNoteRender` helper. Thread root notes auto-expand via
  `forceReveal=true`; replies still respect the filter.

Exemptions
- Long-form articles (kind 30023)
- Authors in the follow list plus self
- Repost wrappers check the inner event's tags via precomputed
  `note.replyTo`, falling back to `containedPost()`

Search UX fixes bundled in
- Removed the `#hashtag` → "Direct lookup" card. `QueryParser` already
  extracts `#xxx` into the query's hashtag filter, so typing `#bitcoin`
  now goes straight to filtered results.
- Search-result rows now trigger metadata loading via
  `subscriptionsCoordinator.loadMetadataBatched(authors)` and observe
  each user's metadata flow via a new `rememberDisplayData` helper, so
  display names + avatars refresh when kind-0 arrives from index
  relays. Same helper reused in Bookmarks.

Tests + docs
- 19 unit tests (check × 10, displayed-event unwrap × 4, prefs × 5),
  all green.
- Manual testing sheet with 16 scenarios at
  `desktopApp/plans/2026-06-29-hashtag-spam-filter-manual-testing-sheet.md`.
- Plan at `docs/plans/2026-06-29-feat-desktop-hashtag-spam-filter-plan.md`.
- Cross-client desktop feature backlog reference at
  `desktopApp/plans/_desktop-feature-backlog.md`.
2026-07-01 09:46:43 +03:00
Claude 6579b5f656 docs: audit, status-stamp, and index all module plans
Audited all 143 plan files across the 10 plans/ folders. Each plan now
carries a Status header (shipped | in-progress | queued | abandoned)
backed by codebase evidence, and every folder has a README.md index
grouping plans by status.

Shipped plans were moved into a per-folder plans/archive/ (via git mv,
history preserved) so each plans/ folder surfaces only live work:

  shipped (archived): 122   in-progress: 8   queued: 7   abandoned: 4

docs/plans/ is the frozen legacy folder; its plans were stamped and
indexed in place (48 of 52 archived) but it remains closed to new plans.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hpUivtmq4pgzqRbY6MYrA
2026-06-30 15:35:38 +00:00
vitorpamplonaandgithub-actions[bot] a054215c4f chore: sync Crowdin translations and seed translator npub placeholders 2026-06-30 12:51:31 +00:00
vitorpamplonaandgithub-actions[bot] 4060bfac39 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-29 19:43:35 +00:00
vitorpamplonaandgithub-actions[bot] fc95f64458 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-27 16:40:09 +00:00
vitorpamplonaandgithub-actions[bot] cc72e8045a chore: sync Crowdin translations and seed translator npub placeholders 2026-06-27 00:14:28 +00:00
vitorpamplonaandgithub-actions[bot] f5bb04b643 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-26 01:34:37 +00:00
vitorpamplonaandgithub-actions[bot] d841277978 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-25 21:25:00 +00:00
vitorpamplonaandgithub-actions[bot] 49e56da1aa chore: sync Crowdin translations and seed translator npub placeholders 2026-06-25 16:01:36 +00:00
davotoulaandgithub-actions[bot] 8d036e0ac0 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-25 08:12:20 +00:00
vitorpamplonaandgithub-actions[bot] 443bfba65c chore: sync Crowdin translations and seed translator npub placeholders 2026-06-25 00:31:29 +00:00
vitorpamplonaandgithub-actions[bot] 7b890a0eff chore: sync Crowdin translations and seed translator npub placeholders 2026-06-24 14:01:39 +00:00
davotoulaandgithub-actions[bot] dd062861f3 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-23 16:14:26 +00:00
vitorpamplonaandgithub-actions[bot] 832951b90c chore: sync Crowdin translations and seed translator npub placeholders 2026-06-23 15:58:03 +00:00
vitorpamplonaandgithub-actions[bot] 82a20c012a chore: sync Crowdin translations and seed translator npub placeholders 2026-06-23 03:10:29 +00:00
vitorpamplonaandVitor Pamplona bd7c5c78cc chore: sync Crowdin translations and seed translator npub placeholders 2026-06-22 09:38:31 -04:00
vitorpamplonaandgithub-actions[bot] 4aa713e2db chore: sync Crowdin translations and seed translator npub placeholders 2026-06-21 15:36:45 +00:00
vitorpamplonaandgithub-actions[bot] eb04e09d26 chore: sync Crowdin translations and seed translator npub placeholders 2026-06-21 14:32:14 +00:00
vitorpamplonaandgithub-actions[bot] 3dcc46de2b chore: sync Crowdin translations and seed translator npub placeholders 2026-06-21 02:25:11 +00:00
vitorpamplonaandgithub-actions[bot] 67af8fc3bf chore: seed translator npub placeholders from Crowdin 2026-06-20 13:47:37 +00:00
vitorpamplonaandgithub-actions[bot] fcebff50cb chore: seed translator npub placeholders from Crowdin 2026-06-19 23:59:48 +00:00
Vitor PamplonaandClaude Opus 4.8 805f7e8e84 v.1.12.6
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 19:01:59 -04:00
Claude 39dc64ff3c fix: stop seeding a fresh timestamp into translators.json every run
The `sinceLastTag.updated` field was set to `date -u` on every
`scripts/translators.sh --seed` run, but nothing ever reads it. The
release-time credit generator only consumes `.mappings` and
`.sinceLastTag.translators`.

Because the field changed on every run, the seed-translators CI job
produced a diff (and therefore a new Crowdin/seed PR) on every push to
main even when the translator set was unchanged. Drop the field from the
seed write and from the committed JSON so the file only changes when a
contributor actually appears.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RSoN4DDC5F1ehwGeC33652
2026-06-19 20:02:21 +00:00
Vitor Pamplona f247f5a431 updating known mappings for translators and github 2026-06-19 15:53:53 -04:00
vitorpamplonaandgithub-actions[bot] 874503a2eb chore: seed translator npub placeholders from Crowdin 2026-06-19 17:21:55 +00:00
Vitor PamplonaandGitHub c37562dc51 Merge pull request #3280 from vitorpamplona/claude/epic-hamilton-m4xors
Add translator credit automation via Crowdin sync
2026-06-19 13:21:34 -04:00
Vitor PamplonaandClaude Opus 4.8 3d26a3d818 v.1.12.5
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 12:55:37 -04:00
Vitor PamplonaandClaude Opus 4.8 c006831f9c v.1.12.4
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 12:32:52 -04:00
Claude 765c1dfd7e feat: generate translator credits offline from the committed file
Makes docs/changelog/translators.json self-sufficient so a release no longer
needs to re-query Crowdin:

- sinceLastTag entries now carry each translator's languages ({user, languages}),
  recorded by the --seed run.
- Default mode (no flags) is offline: it generates the "## Translations" block
  straight from the committed file — reading sinceLastTag, grouping by the stored
  languages, and resolving npubs via the mappings registry. No token, no network.
- --seed/--raw remain the online paths (CI seeding / debugging). curl + git +
  credentials are only required there; the offline path needs just jq.

RELEASE_OPS now points at the tokenless `scripts/translators.sh` for the
changelog credits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWQWVdWLAwBUBX2gJ55y6b
2026-06-19 16:02:47 +00:00
Claude 6b30486667 feat: track a rolling "since last tag" translator list
Reworks docs/changelog/translators.json into two lists maintained by
scripts/translators.sh:

- mappings: a forever-growing Crowdin-username/id -> npub registry. --seed
  appends new contributors with a blank npub and never deletes or overwrites
  existing entries.
- sinceLastTag: a rolling snapshot of who has translated since the last v* tag,
  fully refreshed on every --seed run.

The contribution window now defaults to the most recent v* tag instead of a
fixed two months (falling back to two months ago when no tag is reachable). The
CI seed job fetches tags (fetch-depth: 0) so it can resolve that window.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWQWVdWLAwBUBX2gJ55y6b
2026-06-19 15:52:27 +00:00
Claude 41c686ebb3 feat: generate changelog translator credits from Crowdin
Adds tools/translators/translators.sh, which pulls a Crowdin "Top Members"
report for a release window (between two tags/dates) and prints the changelog
"## Translations" block grouped by language.

Crowdin contributors are joined against docs/changelog/translators.json, a
Crowdin-username/id -> npub mapping kept alongside the changelogs. Contributors
with no mapping are listed under UNMAPPED so they can be credited by hand and
backfilled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWQWVdWLAwBUBX2gJ55y6b
2026-06-19 15:34:05 +00:00
Vitor Pamplona 7096819f3b v.1.12.3 2026-06-19 11:13:00 -04:00
Vitor Pamplona b8312f023a v.1.12.2 2026-06-19 09:22:33 -04:00
David KasparandGitHub 29d6bc308e Merge pull request #3260 from nrobi144/worktree-fix-desktop-macos-keychain-proguard
fix(desktop): macOS forced re-login on cold boot — ProGuard strips java-keyring backend
2026-06-19 10:24:49 +01:00
nrobi144andClaude Opus 4.7 49929a4afa build(desktop): add osxkeychain.so regression guard task — fail release if stripped
The original "ProGuard strips the keychain backend" hypothesis turned out
to be wrong twice (PR 3260 comments document the binary PoW that refuted
both H1 strip-of-classes and H1b strip-of-native-resource). The full
117 KB osxkeychain.so resource ships intact in the proguarded
jkeychain-1.1.0-*.jar today, and Keyring.create() round-trips fine
against the proguarded classpath on macOS.

But the user-reported bug pattern (every cold boot, keychain key missing
→ forced re-login) maps so cleanly onto a hypothetical future
strip-of-native-resource that the guard is worth keeping. Cheap to run
(one unzip scan after proguardReleaseJars), wired onto every release
packaging task (DMG, MSI, DEB, RPM, current-OS distributable, runRelease)
so a regression can't slip past. Fails the build with a self-contained
explanation pointing at the next person who has to debug it.

The actual root cause of the reported bug remains unidentified after
three refuted hypotheses (see plan doc PoW table); needs the affected
user's Console.app logs + ~/.amethyst state to make further progress.
The LoginScreen "keychain-unavailable" diagnostic banner from the
earlier commit is unchanged and still earns its keep regardless of
which failure mode eventually turns out to be the cause.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-19 10:35:13 +03:00
nrobi144andClaude Opus 4.7 a1d7889be3 revert(desktop): drop ProGuard keep-rule swap — binary PoW refuted the strip hypothesis
Built ./gradlew :desktopApp:proguardReleaseJars on both main and this
branch and inspected the shrunk java-keyring-1.0.4-*.jar in
desktopApp/build/compose/tmp/main-release/proguard/. Both branches
contain byte-identical macOS Keychain backend bytecode:
OsxKeychainBackend, ModernOsxKeychainBackend,
pt/davidafsilva/apple/OSXKeychain, plus all _addGenericPassword /
_findGenericPassword / _deleteGenericPassword / loadSharedObject native
methods. ProGuard is NOT stripping the macOS backend.

The compose-rules.pro comment had misled me. pt.davidafsilva.apple IS a
real transitive runtime dep of com.github.javakeyring:java-keyring —
ModernOsxKeychainBackend has a private pt.davidafsilva.apple.OSXKeychain
field. The original keep rule was correct; restore it and clarify the
comment about the transitive relationship so the next person to read
this code doesn't repeat the same mistake.

The AccountManager keychain-unavailable diagnostic + LoginScreen banner
introduced earlier in this branch are kept — they're useful for any
future failure mode in this area, not just the (refuted) ProGuard one.

See https://github.com/vitorpamplona/amethyst/pull/3260#issuecomment-4740073787
for the full PoW jar inspection. Remaining hypotheses (H2 hardened-runtime
unsigned-dylib block, H4 jpackage stripping the bundled libosxkeychain.dylib,
H5 v1.11.0 migration gap) are documented in the plan doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-18 12:11:03 +03:00
nrobi144andClaude Opus 4.7 123c055828 fix(desktop): macOS forced re-login on cold boot — repair ProGuard keep rules for java-keyring
ProGuard in the release DMG (compose-rules.pro) was keeping
pt.davidafsilva.apple.** — a library no longer in the dependency graph.
The actual macOS-keychain dependency is com.github.javakeyring:java-keyring,
which reflection-loads its OS-specific backend (OSXKeychainBackend /
SecretServiceBackend / WinCredentialStoreBackend) at Keyring.create()
time. The shrinker stripped the backend classes, Keyring.create() threw
BackendNotSupportedException on every cold boot, SecureKeyStorage's
fallback silently returned null (no password prompt in a GUI cold-boot),
and every account whose key lived in the OS keychain (nsec, NIP-46
bunker ephemeral, NWC secret) was forced back to the login screen on
each launch of the release DMG. Dev/Gradle runs skip ProGuard, which is
why this never surfaced in development.

Primary fix:
- Replace dead pt.davidafsilva.apple.** keep rules with
  com.github.javakeyring.** and keep native methods + constructors on
  internal.** backends.

Defense in depth (so a future regression is visible, not silent):
- AccountManager._keychainUnavailable: StateFlow<Boolean> mirrors the
  existing _storageCorruption / _forceLogoutReason channels.
- loadInternalAccount / loadBunkerAccount raise the signal when
  accounts.json.enc points at a key the keychain cannot return.
- LoginScreen shows a one-line error banner when the signal is set;
  cleared on any successful login.

Tests:
- AccountManagerLoadAccountTest gains four cases: Internal-no-privkey
  signals, Bunker-no-ephemeral signals, clearKeychainUnavailable
  resets, happy path does NOT signal.

See docs/plans/2026-06-18-fix-desktop-macos-bunker-relogin-plan.md for
brainstorm + plan + deferred follow-ups (Linux/Windows DMG verification,
signed-DMG smoke test, ProGuard mapping regression guard).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-18 11:31:29 +03:00
Vitor Pamplona e1ec0b6823 Adds Bitcoin Sikho as a Designer to the contributors. 2026-06-17 20:51:08 -04:00
Vitor PamplonaandClaude Opus 4.8 02ee493502 chore(release): 1.12.1
Bump the app version to 1.12.1 (versionCode 449) in the catalog, which now
drives every module. Add the v1.12.01 changelog (Health Connect workouts,
share-as-image, immersive system bars, deterministic Tor Active fix) and index
it. Refresh the quartz-integration skill's artifact-version references.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 11:20:18 -04:00
Vitor PamplonaandClaude Opus 4.8 98204eb8ff docs(changelog): cover Tor reliability + other recent v1.12.0 work
Expand the Tor entry into the full reliability cluster (warm-cache speedup,
Active-but-dead watchtower, wedged-guard recovery, 60s bootstrap timeout, dial
gating, lifecycle serialization) and add the other user-facing changes from
recent commits that weren't captured yet: pre-loaded reply threads, richer
workout cards, relay recovery after device sleep, and not resetting relay
backoff on momentary connections.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:19:22 -04:00
Vitor Pamplona d475d041c8 Final version of change log 2026-06-15 15:25:25 -04:00
Claude dbe7a228a0 docs: tighten v1.12.0 highlights to flagship features
Drop three lower-impact items from the Highlights list (still documented
in the body): audio visualizer (author notes minimal visibility), LaTeX
math (niche), and pinned DMs (minor QoL). Keeps the headline payment,
privacy, and new-feed features front and center.

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-14 02:43:30 +00:00
Claude 5fa1d615bf docs: correct v1.12.0 descriptions against PR bodies + verify kinds/NIPs
Verified every event kind and NIP number against quartz code. Read the
feature PR descriptions and fixed inaccuracies:
- Audio visualizer styles (Classic/Spectrum Bars/Color Waves/Radial Ring/
  Aurora Glow/Static/Off; audio-only notes; FFT from decoded audio)
- Podcasts elevated to a new NIP-F4 feature (feeds, favorites, inline player)
- Workouts: create/publish + feed filters (RUNSTR dialect)
- NIP-14 group DMs: subjects + multi-recipient creation + read/mute tracking
- Share to DM reframed as the Android 'Send as DM' share-sheet target
- Cashu wallet: mint-from/melt-to Lightning, send/receive tokens
- CLINK acronym expanded

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-14 00:25:47 +00:00
Claude 344749c007 docs: reconcile v1.12.0 changelog against merged PRs
Reviewed all merged PRs since the v1.11.0 release. Fixed the misleading
'new money operations' Tor line (the toggle already existed; what changed
is relay sockets now honor it). Added gaps the PR titles surfaced: NIP-14
group DM subjects (#3163), removal of wallet reordering drag-and-drop
(#3114), and diagnosable relay failure logs (#3197).

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 23:22:09 +00:00