Commit Graph
15076 Commits
Author SHA1 Message Date
Vitor PamplonaandGitHub ff2de15b20 Merge pull request #3223 from vitorpamplona/fix/gate-tor-relays-until-ready
Gate Tor-routed relay dials until Tor is ready
2026-06-16 09:44:53 -04:00
Vitor PamplonaandClaude Opus 4.8 be5cfc1501 fix(commons): stop RelayHealthStoreCloseTest livelocking the test suite
recordIncoming_after_close_does_not_schedule_persist called advanceUntilIdle()
while RelayHealthStore's init ticker (`while(true){ reclassify(); delay(60s) }`)
was still live on the shared StandardTestDispatcher scheduler. advanceUntilIdle()
chases that periodic delay forever, so the test spun at 100% CPU and never
returned — wedging :commons:jvmTest at "373 tests completed" and hanging the
pre-push hook (and leaving orphaned, CPU-pegging Gradle test workers behind).

Advance just past PERSIST_DEBOUNCE_MS and runCurrent() instead, so init's
debounced save fires for the baseline while the 60s ticker stays parked. The
post-close advanceUntilIdle() calls are fine — close() cancels the ticker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 09:37:55 -04:00
Vitor PamplonaandClaude Opus 4.8 7b34438b04 fix: gate Tor-routed relay dials until Tor's SOCKS port is ready
Before Tor finishes bootstrapping, the relay pool dialed every Tor-routed
relay against the not-yet-listening SOCKS proxy. On a cold start this was
~580 doomed dials (all "SOCKS: Connection refused") concentrated in the
seconds before Tor went Active, churning sockets/CPU and inflating each
relay's backoff. The cost scaled with bootstrap latency, and the same
storm recurred on every network switch (which resets and re-bootstraps Arti).

Add an optional WebsocketBuilder.canConnect(url) gate (defaults to true,
so other implementors are untouched), checked at the top of
BasicRelayClient.connect() before the mutex/onConnecting/build — so a
gated relay opens no socket, fires no listener events, and grows no
backoff. The Android builder gates Tor-routed relays on
torManager.isSocksReady(); RelayProxyClientConnector already reconnects
them with ignoreRetryDelays=true the instant Tor flips to Active, so they
dial as soon as the transport is usable.

Measured on-device: pre-ready doomed Tor dials 581 -> 0 across cold starts
and WiFi<->Mobile switches; clearnet connections stay untouched and Tor
relays self-heal once Tor is Active.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 08:41:06 -04:00
Vitor PamplonaandGitHub 085e2466e6 Merge pull request #3221 from nrobi144/fix/relay-health-threading-and-sleep-resume
fix: RelayHealthStore threading + sleep-resume socket recovery (follow-up to #3186)
2026-06-16 08:40:37 -04:00
nrobi144 552540e77d fix(desktopApp): move sleep/resume detection out of Quartz
Per Vitor's review of #3221: wake-detection is platform-specific UX, not
NostrClient's job. Quartz already exposes `reconnect(onlyIfChanged = false,
ignoreRetryDelays = true)` which does the full disconnect + connect — the
app layer just needs to call it when it detects a wake.

- Revert the keep-alive heuristic in NostrClient.kt; the loop is back to the
  conservative `reconnectIfNeedsTo` path it had before.
- Add `runSleepResumeMonitor` (desktopApp/network/SleepResumeMonitor.kt): a
  60s tick that watches for wall-clock overshoot and calls the supplied
  `onWake` lambda. No native deps.
- Wire it in `Main.kt` next to the metrics LaunchedEffect: on >5x overshoot
  call `relayManager.client.reconnect(onlyIfChanged = false,
  ignoreRetryDelays = true)`.

Real OS sleep events (NSWorkspace on macOS, D-Bus PrepareForSleep on Linux,
WM_POWERBROADCAST on Windows) can be layered in later as platform improvements
without touching Quartz again.
2026-06-16 09:59:31 +03:00
Vitor Pamplona 72c0558bb9 Merge branch 'main' of https://github.com/vitorpamplona/amethyst 2026-06-15 16:11:10 -04:00
Vitor Pamplona d475d041c8 Final version of change log 2026-06-15 15:25:25 -04:00
David KasparandGitHub 23bdd952b4 Merge pull request #3222 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-06-15 17:59:39 +02:00
Crowdin Bot 17e8e1c8b2 New Crowdin translations by GitHub Action 2026-06-15 15:50:36 +00:00
Vitor Pamplona 3b233924ce Merge branch 'main' of https://github.com/vitorpamplona/amethyst 2026-06-15 11:46:10 -04:00
Vitor PamplonaandGitHub fcaa7ba67c Merge branch 'main' into fix/relay-health-threading-and-sleep-resume 2026-06-15 11:41:28 -04:00
Vitor PamplonaandGitHub c3f82359db Merge pull request #3219 from davotoula/fix/relay-reconnect-backoff
Don't reset relay reconnect backoff on momentary connections
2026-06-15 11:41:06 -04:00
Vitor Pamplona 7b0e8b7117 Merge branch 'main' of https://github.com/vitorpamplona/amethyst 2026-06-15 10:46:15 -04:00
Vitor Pamplona 0cfc324d87 Removes Threading checks on Commons since Main Threads don't exist over there.
Remove warnings
2026-06-15 10:41:40 -04:00
nrobi144 b91519157e fix(commons,quartz): RelayHealthStore threading + sleep-resume socket recovery
Follow-up to #3186, addressing the unresolved review feedback:

- RelayHealthStore.schedulePersist() wrapped the blocking save() in withContext(ioDispatcher)
  so prefs.flush() no longer sits on the Compose composition thread on Desktop.
- close() now fires the final save on a detached IO-bound scope instead of blocking
  the composition thread for ~50ms during account switch / app exit.
- @Volatile on persistJob/tickJob and a closed-flag guard so the relay-network thread
  and composition thread no longer race on plain vars (and post-close work is dropped).
- desktopApp/Main.kt passes Dispatchers.IO to RelayHealthStore so persistence flushes
  land on the IO dispatcher instead of Dispatchers.Default.

Plus a separate-but-related fix to the offline-banner-stuck-after-Mac-sleep issue:
NostrClient.keepAliveJob now tracks wall-clock overshoot of its scheduled tick.
If the OS suspended us (laptop lid closed, system sleep), delay() returns far
past its deadline and the OkHttp websockets we held are dead even though
BasicRelayClient.isConnected() still reads true until the next ping fails.
On a >5x interval overshoot, force relayPool.disconnect() + connect() instead
of trusting needsToReconnect(), so feeds resume without an app restart.
2026-06-15 13:21:32 +03:00
davotoula 33a7ef3be5 Code review:
- harden relay backoff fields for cross-thread access
- reuse EmptyConnectionListener in backoff test
- extract shared relay-client test fakes
2026-06-14 20:36:59 +02:00
Vitor PamplonaandGitHub 4552928360 Merge pull request #3216 from davotoula/fix/ios-test-uikit-prebuilt-cache
Restore iOS test native-cache workaround dropped in dependency bump
2026-06-14 12:33:26 -04:00
davotoula 312f64dcc3 fix: don't reset relay reconnect backoff on momentary connections
A relay that accepts the WebSocket handshake and then immediately resets
the connection (e.g. essayist.decentnewsroom.com) defeated the exponential
reconnect backoff.
2026-06-14 18:25:26 +02:00
Vitor PamplonaandGitHub c146b97a3f Merge pull request #3217 from vitorpamplona/claude/ipv6-url-parsing-xy4mvg
fix: parse IPv6-literal URLs in post content
2026-06-14 12:23:38 -04:00
Claude b565c37277 fix: parse IPv6-literal URLs in post content
UrlParser.parseValidUrls filtered every detected URL through
isValidTopLevelDomain(), which requires the TLD's first character to be
an ASCII letter. IPv6 literal hosts are bracketed (e.g. [2001:db8::1])
and have no dotted TLD, so the whole bracketed host became the candidate
"TLD", starting with '[' and failing the check. As a result, valid
IPv6 URLs like http://[302:68d0:f0d5:b88d::bdb]/<hash> were dropped and
rendered as plain text instead of links.

The UrlDetector already validates the bracketed address as syntactically
correct IPv6, so accept bracketed hosts directly in isValidTopLevelDomain.
2026-06-14 15:59:32 +00:00
davotoula 0459f29be2 fix(commons): restore iOS test native-cache workaround dropped in dep bump
The "Updates all dependencies" commit (ece719445) bumped Kotlin to 2.4.0,
which removed the `DisableCacheInKotlinVersion.2_3_21` enum value. Rather
than bumping the guard, the whole `disableUiKitPrebuiltCache()` workaround
was deleted — which reintroduced the iOS test link failure on CI
2026-06-14 17:48:03 +02:00
David KasparandGitHub 2458a59e07 Merge pull request #3215 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-06-14 17:38:01 +02:00
Crowdin Bot 2fa393cfb6 New Crowdin translations by GitHub Action 2026-06-14 15:37:10 +00:00
David KasparandGitHub 4ae9d967f5 Merge pull request #3212 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-06-14 17:35:07 +02:00
Crowdin Bot fe08e79c68 New Crowdin translations by GitHub Action 2026-06-14 15:01:18 +00:00
Vitor PamplonaandGitHub 6cc62f13d8 Merge pull request #3214 from vitorpamplona/claude/changelog-v1-11-at3e12
docs: Add v1.12.0 release notes
2026-06-14 10:59:25 -04:00
davotoula cddaaec445 update cz, se, pt, de 2026-06-14 14:49:16 +02: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
Claude 5cdc21a7c0 docs: fully itemize v1.12.0 changelog for phone reading
Break every multi-clause bullet into short sub-items so each line is one
idea, optimized for mobile reading.

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 23:13:39 +00:00
Claude b98c226e19 docs: complete v1.12.0 changelog after full commit-by-commit audit
Read all 352 non-merge commits since v1.11.0 and added the remaining
gaps: GPLv3 TarsosDSP -> in-house pitch shifter (licensing/voice
anonymizer), live-stream chat relay fallback, DM history-loading fixes,
legacy NIP-71 video d-tag, media-server reset, account cache cleanup,
poll option text, and the Material Symbols Cashu icon.

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 23:06:42 +00:00
Claude a6868a1083 docs: add Cashu wallet, Music, Software Apps, audio visualizer to v1.12.0
A file-level audit (not just commit subjects) surfaced major features hidden
under misleading commit messages: the new NIP-60 Cashu ecash wallet, music
tracks/playlists, the NIP-82 Software Apps directory, the live audio
visualizer, and multi-wallet management (NWC/CLINK-debit/Cashu).

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 23:02:44 +00:00
Claude 4be9cfc687 docs: add missing features to v1.12.0 changelog
Adds Hidden Words unblock, Share to DM, reply-to-zaps from notifications,
the Selected/Global notification split, the podcasts subsystem, desktop
unhealthy-relay review, the live zap-popup rails, and the commons KMP
migration scope.

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 22:57:03 +00:00
Claude 26eea1d183 docs: split remaining multi-sentence items into sub-lists in v1.12.0 changelog
https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 22:54:43 +00:00
Claude eb4524ec58 docs: use template Translations section (Crowdin credits) in v1.12.0 changelog
https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 22:51:28 +00:00
Claude 7695fe6ee9 docs: shorten sentences and add sub-lists in v1.12.0 changelog
https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 22:45:50 +00:00
Claude a2f331eb65 docs: add v1.12.0 changelog covering work since v1.11.0
Summarizes the 506 commits / 131 PRs merged since the v1.11.0 release:
CLINK payments, private posts/reactions via NIP-17, NIP-101e workouts,
LaTeX math rendering, NIP-89 app recommendations, pinned DMs, activity
cards, desktop image compression + new media player, and the Quartz
relay-server toolkit. User-facing sections are written for end users;
build/quartz/cli sections keep developer-level language.

https://claude.ai/code/session_01Y8cDkDRV48GYdQd3CR4kuV
2026-06-13 22:40:03 +00:00
Vitor Pamplona c7e25c5a9e Merge branch 'main' of https://github.com/vitorpamplona/amethyst 2026-06-13 18:18:35 -04:00
Vitor PamplonaandClaude Opus 4.8 a75b60135a fix: adapt Blossom interceptor test to OkHttp 5 Interceptor.Chain
OkHttp 5.4.0 expanded Interceptor.Chain from ~10 to ~40 members, breaking
the test's hand-rolled `object : Interceptor.Chain` fake. Replace it with a
java.lang.reflect.Proxy that implements only request()/proceed() and throws
for the rest, so it survives future interface growth without dozens of empty
stubs. A real OkHttpClient can't be used here because Platform init fails
outside Robolectric (android.util.Log.isLoggable is unavailable).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 18:17:42 -04:00
Vitor Pamplona ece7194456 Updates all dependencies 2026-06-13 18:10:13 -04:00
Vitor PamplonaandGitHub 8dc24d6574 Merge pull request #3211 from mstrofnone/feat/desktop-namecoin-diagnostics
desktop(namecoin): port DiagnosticCard from Android settings
2026-06-13 18:08:46 -04:00
mstrofnone 96943fb0d1 desktop(namecoin): port DiagnosticCard from Android settings
Adds the Namecoin diagnostics card that Android renders below the
per-server test results to the desktop settings panel, so support
requests carry the same information on both platforms.

- last test timestamp + pass/fail tally
- host OS (name/version/arch) — desktop equivalent of Android's
  Build.MANUFACTURER/MODEL row
- JVM name + version — desktop equivalent of Android's API level row
- distinct TLS versions observed during the test run

Also adds a 'Testing next server...' inline progress row matching the
Android section's behaviour when the test loop is mid-run.

Pure UI addition; no model, preference, or callback changes.
2026-06-14 08:01:59 +10:00
Vitor Pamplona f2a48f87ca Finish up the template 2026-06-13 17:50:51 -04:00
Vitor PamplonaandGitHub a47f952f6e Merge pull request #3210 from vitorpamplona/claude/exciting-pascal-1yw9mv
Reorganize changelog into versioned files
2026-06-13 15:39:17 -04:00
Claude 81128ba74a docs: split CHANGELOG into per-version files under docs/changelog
The single CHANGELOG.md had grown to ~7.9k lines. Move it to
docs/changelog/ with one file per release, named with zero-padded
minor/patch versions (e.g. v1.11.00.md) so plain file browsers sort
them correctly. Add a README.md index (newest first) and a TEMPLATE.md
for cutting new releases. The root CHANGELOG.md now points to the new
location.
2026-06-13 18:24:10 +00:00
Vitor PamplonaandGitHub 48a9ad8897 Merge pull request #3209 from davotoula/fix/media-server-default-reset
Stop media-server default from resetting on every launch
2026-06-13 14:10:56 -04:00
Vitor PamplonaandGitHub 60d9917bd3 Merge pull request #3208 from davotoula/fix/relaystat-deadcode-3186
Remove write-only RelayStat liveness fields
2026-06-13 14:09:19 -04:00
davotoula 5551f990a5 fix(quartz): remove write-only RelayStat liveness fields
The RelayStat.lastConnectAt / lastIncomingAt fields added in #3186 were
written on every connect and every incoming relay message (a TimeUtils.now()
call plus a volatile store on the Android hot path) but never read.
2026-06-13 19:43:02 +02:00
davotoula 0f1b4c9597 fix: stop media-server default from resetting on every launch 2026-06-13 19:20:08 +02:00