618 Commits

Author SHA1 Message Date
archipelago
8e51164321 docs: v1.7.117-alpha changelog covers everything since 1.7.116 + What's New sync
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m4s
Rewrites the prepared 1.7.117 section to include the mesh flash flow,
first-class Reticulum fixes, radio-first routing, mesh chat polish, the
transactions-modal phone fixes, services-vs-apps classification, the
lightning slow-payment fix, cached-resource page loads, load-shedding,
FIPS uptime hardening, and companion 0.5.25. What's New modal block
regenerated from the new bullets (sync-whats-new --check passes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 05:49:45 -04:00
archipelago
da14c135e4 feat(apps): backend-only services classify as services with no Launch button
Some checks failed
Demo images / Build & push demo images (push) Has been cancelled
A published port no longer implies a web UI. The package scanner used to
synthesize interfaces.main.ui="true" for any container with a port or
onion address, so headless backends — including self-deployed compose
stacks like podsteadr — showed up as launchable apps. New ui_detection
module decides instead: a manifest interfaces declaration (catalog
overlay first, disk second) is definitive; undeclared apps get a short
HTTP probe of the launch port (HTML page, redirect, or browser auth
wall = UI; JSON APIs, raw TCP, dead ports = service), with cached
verdicts and probes gated on running containers. Frontend canLaunch
now refuses curated services outright and only treats a bare runtime
address as launchable for curated known apps.

Works identically for manifest apps and containers deployed by hand
outside the orchestrator. ui_detection tests 6/6, frontend suite
696/696.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 05:48:38 -04:00
archipelago
6ba39041d0 feat(ui): mesh header "Flash LoRa" button opens the in-app flash flow
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m9s
Replaces the external flasher.meshcore.co.uk link with a button that
opens the global device-setup modal directly at its flash step, via a
new manual entry point in the mesh store (flashFlowPath). Manual opens
target the connected radio (else the first detected stick), skip the
read-only probe — the port is held by the live session and a second tty
opener corrupts it; the backend flash job stops the listener itself —
and close the modal instead of stepping back to the detection screen.
Button is disabled with a hint when no radio is present.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 04:43:38 -04:00
archipelago
0aa3941c40 feat(ui): mesh chat polish — transport pills in image modal, hop-route modal, reaction dropdown, real read-tracking
Some checks failed
Demo images / Build & push demo images (push) Failing after 3m29s
- Image quality modal: 'Send via' pills (LoRa / FIPS / Tor) when the
  peer is federation-reachable — mesh.transport-advice now returns
  has_fips + last_transport alongside has_tor. Picking FIPS/Tor routes
  the image over the content-ref path instead of the radio.
- Attachment modals (transport chooser, image quality, new hop modal)
  Teleport to body so the backdrop dims the FULL viewport — rendered
  in-place they sat inside a transformed glass panel that trapped
  position:fixed to the right chat panel.
- Click a message's transport pill → route modal: radio hops + live
  SNR/RSSI quality for LoRa transports, overlay/circuit shape for
  FIPS/Tor, delivery + E2E state.
- Reactions move behind a compact 'React ▾' dropdown with a larger
  12-emoji palette.
- Unread badges now clear like a normal chat app: opening a contact
  clears ALL twins of the merged conversation (badge sums every
  contact_id — clearing just the clicked one left it stuck), and only
  once the chat has scrolled to the latest messages; scrolled up into
  history, new arrivals accumulate until you scroll back down.
- Refresh button shows only the spinner while refreshing (text+spinner
  overflowed the fixed button width).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 21:01:36 -04:00
archipelago
79c3cc5947 fix(mesh): radio-first transport policy + attachments to merged contacts route via the radio twin
Some checks failed
Demo images / Build & push demo images (push) Failing after 3m50s
Two halves of the same twin-resolution gap, found live while testing
images between archi-dev-box and archy-x250-dev:

- peer_dest_prefix resolved the given contact row's own pubkey. For the
  UI's merged conversation (the federation-synthetic id) that's the
  Archipelago ed25519 identity key, NOT a radio routing key — so every
  Reticulum resource send (images/files over LoRa) failed with 'Unknown
  Reticulum prefix' while the UI showed the message as sent. It now
  resolves through the radio twin (same arch identity, radio-range id).
- send_typed_wire sent EVERY federation-synthetic contact over the
  federation path (FIPS→Tor), even with the same node one LoRa hop away.
  Policy per operator: LoRa first when the payload fits and the radio
  twin is reachable, then FIPS, then Tor. Verified live: text to the
  merged contact now logs 'Radio-first routing' and lands with
  transport=reticulum on the peer.

Also restyles the mesh-chat attachment download controls: the pre-fetch
button was a bare .btn that squished to text width in the narrow mobile
bubble; now a full-width glass pill with a download icon and fetch
spinner, and the on-image overlay swaps the emoji glyph for a crisp SVG
in a properly-sized glass circle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 18:16:40 -04:00
archipelago
3f76b4960a feat(ui): mesh Refresh/Broadcast feedback, Set Recommended modal with probe progress bar, live list refresh
All checks were successful
Demo images / Build & push demo images (push) Successful in 3m43s
- Refresh button: real handler — calls the new mesh.refresh (radio
  re-query) plus contacts/federation/outbox re-reads, disabled with a
  spinner while running (was an unawaited cache repaint with no feedback
  that skipped half the list's data sources).
- Broadcast button: success ('Sent ✓') and failure states with the error
  in the tooltip; failures no longer vanish as unhandled rejections.
- The store's 5s status poll no longer wipes the error banner each tick.
- Contacts/aliases, federation nodes and the outbox badge refresh every
  ~30s (were mount-only and went permanently stale).
- Peer-list empty state keys on the merged list, so federation rows and
  the channel rows still render with no radio attached.
- Device setup modal: 'Set Recommended' naming, probe progress bar with
  stage labels instead of an anonymous spinner.
- Device panel: name save clears properly (empty = fall back to server
  name) and the confirmation reflects the new live apply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 16:37:16 -04:00
archipelago
537c52d11c feat(ui): FIPS network + seed-anchor cards render from cached resources (B4)
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m6s
The two FIPS containers on the Server page were the last network cards
still fetching-on-mount into local refs — every visit was a blank card
until fips.status / fips.list-seed-anchors answered. Both now ride the
cached-resource layer: FipsNetworkCard shares the server.fips-summary
key with the Local Network card's FIPS row (one fetch, never disagree),
seed anchors cache under server.fips-seed-anchors, and mutations
write the RPC's authoritative result straight into the cache. The 15s
status poll skips hidden tabs — revalidate-on-focus covers the return.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:48:34 -04:00
archipelago
8907cc47d9 feat(ui): Credentials + OpenWrtGateway render from cached resources — B4 complete
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m10s
- Credentials: identity.list + identity.list-credentials become
  useCachedResource entries; explicit reloads still toast on failure.
- OpenWrtGateway: openwrt.get-status caches in the shared store (revisits
  paint the last router state instantly); the connect flow's
  params/No-router-configured semantics are preserved on top of the entry.
- ContainerApps assessed and left as-is: its Pinia store already persists
  across navigation, keeps last data on error, and gates the spinner on
  empty — same class as Apps/Marketplace/Fleet.

This closes the B4 rollout list from docs/FIPS-UPTIME-AND-UI-STATE-PLAN.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 06:27:05 -04:00
archipelago
8fd72b947a test(ui): adapt SWR contract tests to the cached-resource layer — 692/692
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m9s
The keeps-data-visible-while-refreshing tests for PeerFiles, Server, and
LightningChannels mounted without Pinia (the converted components now
pull the resources store in setup) — add createPinia to the mounts.
LightningChannelsPanel: refresh the main channel list before the closed
history so the primary entry gets the first response, and null-guard
both fetchers' response shapes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 05:55:12 -04:00
archipelago
ea254f63af feat(ui): Server page renders from cached resources (B4)
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m9s
network summary (4-RPC allSettled aggregate), fips row, vpn peers,
interfaces, and tor services become useCachedResource entries — revisits
paint instantly, background refreshes keep content on screen. Mutations
write through the cache: DNS apply + the 15s vpn poll patch the network
aggregate via optimistic() instead of refetching all four RPCs; peer
removal filters the cached list. loading/refreshing flags derive from
entry loadState (drops the hand-rolled hasLoaded bookkeeping).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 05:45:17 -04:00
archipelago
1a306c7450 feat(ui): Federation adopts the cached-resource store (B4)
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m7s
federation nodes + dwn.status become useCachedResource entries: revisits
paint the node list instantly, `loading` fires on true first-load only
(the old showLoader semantics), the 5s poll refreshes silently like the
old surfaceErrors:false path, and explicit reloads after mutations still
surface failures in the error banner. Replaces the hand-rolled
loadNodesWithOptions SWR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 05:36:26 -04:00
archipelago
43e50e669e feat(ui): Monitoring renders from cached resources (B4)
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m7s
monitoring.current/history/alerts/alert-rules become useCachedResource
entries: revisiting the page paints the last snapshot, chart, and alert
list instantly and the 5s poll revalidates behind them (refreshes dedup
in the store; errors keep last-known values instead of blanking).
Alert-rule toggles and acknowledgements refresh their entries after the
mutation as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 05:22:06 -04:00
archipelago
529c7fe25d feat(ui): Web5 wallet/profits render from cached resources (B4)
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m2s
- lnd.getinfo and wallet.networking-profits become useCachedResource
  entries (web5.lnd-info / web5.networking-profits): revisits paint
  instantly from cache, errors keep last-known values, refreshes dedup.
- walletConnected is now derived from the lnd-info entry (with a manual
  disconnect override preserving the connect/disconnect toggle).
- Drop the eager wallet.ecash-balance + lnd.gettransactions loaders and
  their 30s polling — they fed only the hidden wallet card; the lnd-info
  poll remains for the connected pill until B5 moves it to WS-push.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 05:03:47 -04:00
archipelago
d605d0d544 feat(ui): PeerFiles renders from the shared peer-browse cache (B4)
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m11s
- PeerFiles.vue reads the SAME `cloud.peer-browse:<onion>` entry Cloud.vue's
  per-peer fan-in fills, so Cloud → peer files paints instantly from cache
  and revalidates behind it; catalog/error/loading/transport are now
  computed views over the store entry.
- preview-peer fan-out is capped at 3 concurrent with a queue (was one 30s
  RPC per media item, all at once, unbounded) and aborts on unmount.
- browse + preview RPCs drop to maxRetries:1 — retry×3 turned one slow
  peer into a 90s spinner.
- fix useCachedResource's interface types: `ReturnType<typeof computed<T>>`
  resolves to the writable overload (WritableComputedRef), which broke
  vue-tsc against the plain computed() returns; use ComputedRef<T>.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 04:46:26 -04:00
archipelago
c83bade022 feat(ui): Cloud page renders from cache — per-peer incremental fan-in, live FIPS/Tor badges, per-path folder cache
Some checks failed
Demo images / Build & push demo images (push) Failing after 3m24s
Part B3 of docs/FIPS-UPTIME-AND-UI-STATE-PLAN.md — the worst
fetch-on-every-navigation offender converted to the cached-resource layer:

- section counts / peer nodes / my files / paid items are cached resources:
  revisits paint instantly, refresh happens behind the content
  (sticky-ready), errors keep last-known data
- peer files: per-peer cached browse entries replace the all-or-nothing
  Promise.allSettled — each peer's rows render the moment it answers, with
  "still fetching from N peers" + unreachable counts; browse-peer runs
  with maxRetries:1 so one dead peer costs its timeout once, not ×3
- peer cards get a live transport badge (FIPS green / Tor amber, with
  measured latency) from the transport field the browse response already
  carried — the per-peer FIPS-uptime view, for free
- cloud store: per-path listing cache with stale-while-revalidate
  navigate() and a last-wins guard; CloudFolder no longer reset()s the
  store on every folder entry (that wipe forced a spinner each time)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 22:49:30 -04:00
Dorian
c598bb8796 fix(android): preserve top inset for fixed app headers 2026-07-27 20:11:02 +01:00
Dorian
70996203f9 fix: complete fips unit fallback coverage 2026-07-27 19:28:53 +01:00
Dorian
709922c293 fix: harden fips startup and app port relays 2026-07-27 19:18:39 +01:00
Dorian
24582128c5 fix(ui): re-pad mobile dashboard when Android injects safe-area top
The mobile nav sampled --safe-area-top once at mount, but the companion
WebView injects it asynchronously. An authenticated session mounts the
dashboard before the injection lands (fresh installs mount after login,
long after it), so the content padding baked in 0 while the fixed tab
bar grew by the real inset — content slid underneath by exactly the
status-bar height, the update-install-only overlap.

Re-read on the WebView's new archy-insets event, with a retry ladder as
fallback for APKs that predate the event.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 17:12:20 +01:00
archipelago
9cd507269c fix(lightning): never report a slow in-flight payment as failed
Slow multi-hop payments (>15s routing) surfaced as "Payment failed"
while LND settled them in the background: the shared LND REST client's
15s total timeout aborted the synchronous /v1/channels/transactions
wait, and every UI path treated that abort as a definitive failure. The
payment then succeeded anyway and only appeared in history on the next
background poll.

Backend: lnd.payinvoice now decodes the invoice up front for its payment
hash, pays on a dedicated 120s client, and answers status:"pending" with
the hash (never an error) when the wait elapses after the payment was
handed to LND — only a pre-connect failure is still a hard error. New
lnd.paymentstatus RPC reports succeeded/failed/in_flight (with humanized
failure reasons) from /v1/payments.

Frontend: new rpcClient.payLightningInvoice() pays then polls
lnd.paymentstatus to a real terminal state (3s interval, up to 2 min);
all five call sites (send modal, scan modal, web5 unified send, peer-file
purchase, app-launcher payments) migrated. Failure is only shown when LND
itself declares FAILED; a still-settling payment shows an in-flight state
and success fires the transaction refresh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 05:33:02 -04:00
Dorian
6dffd8e2e8 chore: bump version to 1.7.116-alpha + changelog/What's New
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m59s
Bundles all post-115 fixes into an OTA release: boot READY-before-recovery
+ Restart=always (no more 'server starting up'), and the app-install
daemon-kill fix (v6 relay only bridges live app ports; port-cleanup
excludes our own PID).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 07:59:48 +01:00
Dorian
9739bbb3db docs+fix: ship fips0 web-UI firewall allowance from core; changelog + What's New for v1.7.115-alpha
Some checks failed
Demo images / Build & push demo images (push) Has been cancelled
fips::config::install() now writes /etc/fips/fips.d/80-web-ui.nft
(tcp 80/8443 accept) and reloads the baseline on every install/upgrade —
the hardening firewall default-denies inbound on fips0 and the UI was
unreachable over the mesh without it (root-caused live 2026-07-26).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 22:03:25 +01:00
archipelago
0365cc0f9d docs: changelog + What's New for v1.7.114-alpha
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m52s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 12:24:36 -04:00
archipelago
0880824fb3 fix(ui): seed QRs use the SeedQR standard so hardware wallets can scan them
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m52s
Plain-text seed QRs didn't scan into Passport Prime — wallets that
import seeds by QR (Passport, SeedSigner, Keystone, Nunchuk, Sparrow)
expect the SeedQR standard: each BIP39 word as its zero-padded 4-digit
wordlist index, concatenated into a numeric QR.

- new utils/seedqr.ts encodes BIP39 words per the SeedSigner spec
  (@scure/bip39 wordlist; vector-checked abandon=0000, zoo=2047)
- new shared SeedRevealPanel (Words/QR tabs, tap-to-reveal blur) now
  backs the LND reveal AND the Settings→Backup recovery-phrase reveal,
  so every current and future seed reveal behaves the same
- onboarding seed + Settings reveal: QR defaults to SeedQR with a
  plain-text toggle
- LND seed stays plain-text-only with an explicit note: aezeed is not
  BIP39 and only restores into LND-based wallets (Zeus/Blixt/another
  node) — SeedQR-encoding it would just mislead

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 12:09:43 -04:00
archipelago
c8d0dda656 feat(ui): Words / QR code tabs on LND seed reveal + onboarding seed
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m54s
Both seed screens get the wallet-settings segmented tab style: words
stay the default first view; the QR tab renders the space-joined seed
words for wallets that support seed import by scan. The LND reveal QR
sits behind the same tap-to-reveal blur as the words, and both panes
warn that the code is equivalent to the words.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 07:34:19 -04:00
archipelago
0fadbb1d0f docs: sync What's New modal for v1.7.113-alpha
Some checks failed
Demo images / Build & push demo images (push) Failing after 48s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:29:48 -04:00
archipelago
0641ee85ef feat(wallet): total-bitcoin row at top of wallet card; on-chain gets a chain icon
The wallet card (Home + Web5 views) now leads with a Total Bitcoin row
summing all rails (on-chain + lightning + cashu + fedimint + ark), using
the orange ₿ mark. The on-chain row swaps ₿ for a link/chain icon.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 10:44:08 -04:00
Dorian
4343949005 perf(ui): app-launch-speed doctrine for data panels — parallel RPCs + instant last-known paint
Why apps feel instant over the mesh and data panels didn't: an app
launch is ONE streamed HTTP fetch on a warm session; the panels were
built from SERIALIZED RPC round-trips, each costing a full mesh RTT.

- Wallet card (Home): the 7 balance/history RPCs fired one-by-one
  (seconds by construction) — now all 7 in parallel, and the card paints
  a persisted last-known snapshot (balances + recent transactions)
  BEFORE any network round-trip. Refresh replaces it silently.
- Web5 connected nodes: listPeers + federationListNodes fetched
  together instead of stacked.
- Peer files: the cosmetic peer-name lookup no longer blocks the
  catalog/owned fetches it never depended on.

Rules going forward: never serialize independent RPCs; never show a
spinner where last-known data exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 11:22:46 +01:00
archipelago
408c605001 test: LightningChannels mounts with Pinia — panel setup now uses the tx-explorer store
All checks were successful
Demo images / Build & push demo images (push) Successful in 3m5s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 04:42:52 -04:00
Dorian
9fcb68816b perf(apps): launch never waits on the credentials RPC — 1.2s budget + memo
Apps-tab launches awaited package.credentials with a 5s timeout before
opening anything (home-card launches skip the gate — that's why they
always felt instant). The lookup now races a 1.2s budget: past it, the
app launches with the static fallback config while the RPC finishes
into a per-app memo, making every subsequent launch instant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 09:14:40 +01:00
archipelago
8af2ca4ac2 docs: complete the v1.7.112-alpha changelog — audio/TV-input/companion-mesh/paid-sharing batch + What's New re-sync
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m45s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:18:37 -04:00
Dorian
f0926ece94 feat(companion): mesh party + Flare, keep-warm mesh, restored fast-start, UI fixes — 0.5.7
Combined session state from both agents (shared checkout):

- Mesh Party / Flare (experimental): phone-to-phone FIPS via party QR,
  Flare chat/beam on :5680, optional fixed UDP listen (2121); party-only
  phones get the baked-in Archipelago anchor so two bare phones reach
  each other across the internet, not just on a hotspot.
- Keep-warm mesh: a running healthy node survives app opens (restart
  only when dead or peers changed — peersDirty); requestMeshRestart for
  config changes. Cold start measured on-device: session in ~3.1s.
- Restored after regression: startup LAN-vs-mesh race (the party work
  was based on a pre-#114 file copy) and same-node routing (BTCPay/
  Pine/HA had returned to opening in the external browser).
- UI: top status-bar scrim removed (bottom-only bars); web app-session
  mobile bar is solid black — app theme colour no longer bleeds through
  the bar and its safe-area strip.

Served APK: 0.5.7 (vc27).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:04:36 +01:00
archipelago
402183c0ae feat(appsession): mode switches never reload the iframe + strictly per-app display modes + TV focus
- The session subtree now ALWAYS lives under <body>; inline panel mode is
  emulated with a fixed-position rect synced from the layout placeholder
  (ResizeObserver + resize), so toggling panel/overlay/fullscreen no longer
  re-parents — and therefore no longer reloads — the app iframe.
- Display modes are strictly per-app: saved per-app pick → app default
  (IndeeHub: fullscreen) → panel. The global fallback is gone, so one app's
  mode can never change how another opens.
- The iframe takes focus when the app loads, so keyboard / the gamepad
  bridge work inside it immediately (TV).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:15:43 -04:00
archipelago
f72d4b92ac feat(content): seller-picked payment methods + music always in the bottom bar + video PiP
- Paid sharing: AccessControl::Paid gains an accepted-methods list
  (lightning/onchain/ecash/fedimint; empty = all, back-compat). Sellers pick
  methods in ShareModal, gated on what the node can actually receive (LND
  running/channel open, ecash wallet, fedimint joined) with an ⓘ that
  explains exactly how to enable a missing rail. Enforced server-side (the
  invoice/onchain mints refuse non-accepted methods; the serve gate only
  honors tokens/hashes for accepted rails) and the buyer's pay modal only
  offers what the seller accepts.
- Purchased music: the two remaining lightbox paths now use the bottom-bar
  player — the immediate post-ecash-purchase viewer and the Paid Files
  tab's window.open.
- Picture-in-picture buttons on the peer video player and the cloud media
  lightbox (utils/pip.ts; Chromium/Safari, no-op elsewhere).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:15:11 -04:00
archipelago
9f1daa0f8c feat(ui): per-app display-mode defaults (IndeeHub fullscreen) + gamepad plays media + node list scales
- Per-app default display mode: explicit user pick (remembered per app) ->
  app default -> last global -> panel; IndeeHub defaults to fullscreen.
- data-controller-primary: a media file card's gamepad-select clicks the
  card (audio -> bottom-bar player, video -> lightbox) instead of the
  card's download link.
- Discovered-nodes list scales with the viewport (max(14rem,45vh)) instead
  of cramming a long list into a fixed 224px box.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:31:02 -04:00
archipelago
960e41e164 fix(content): audio always plays in the bottom-bar player + ecash purchase is explicit two-step
- Owned/purchased and cloud audio never opens a lightbox: PeerFiles'
  owned-content viewer and the Cloud/CloudFolder preview route audio to the
  global bottom-bar player (video keeps the lightbox).
- Web5 shared-content 'Buy' no longer fires the node-ecash payment on
  click: it opens a confirmation with balance -> price -> balance-after,
  and pays only on explicit confirm.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:31:01 -04:00
archipelago
f339358109 fix(content): double-pay is now impossible + purchases auto-file + Paid Files tab
Some checks failed
Demo images / Build & push demo images (push) Failing after 32s
The double-share/double-pay chain (user hit it live, 2026-07-22):
ShareModal's already-shared lookup compared the slash-stripped stored
path against the leading-slash filepath — never matched — so every
re-share minted a NEW catalog entry with a new id, and the buyer's
owned-guard (keyed by id) saw the duplicate as unowned and paid again.
Three independent walls now: (1) ShareModal normalizes both sides so
re-shares reuse the entry; (2) content_server::add_item dedupes by
filename server-side (updates in place, keeps the id so buyers' owned
records stay valid); (3) the buyer REFUSES to pay for content it
already owns — matched by (onion, content_id) OR (onion, filename) —
and serves the cached copy instead, before any ecash is minted.

Purchases also auto-file into Photos/Music/Documents on the node (same
buckets as the Cloud view, collision-safe naming) so bought files show
up where files live on every device, and Cloud gains a Paid Files tab
listing every purchase (name, size, sats paid, date) with in-app view.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:10:48 -04:00
archipelago
e68fe071a7 docs: v1.7.112-alpha changelog + What's New sync + flasher integration point
Some checks failed
Demo images / Build & push demo images (push) Failing after 32s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:40:05 -04:00
archipelago
b193e64ffb fix(ui): kiosk dropdown flash + never inherit the OS light theme
Outside-close listeners move from click to pointerdown: pointerdown
fires before the open-toggle re-render, so the kiosk's slow software
compositing can no longer detach the click target mid-flight and close
the menu the instant it opens. color-scheme:dark (CSS + meta) pins every
native control — select popups, scrollbars, pickers — dark regardless of
the user's OS theme; explicit select/option colors cover Firefox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:44:32 -04:00
archipelago
770e3386f4 perf(nodes): Connected Nodes refresh — parallel probes, instant list, 12s health timeout
Reachability probes ran one at a time with a 30s Tor timeout each, so
Refresh sat disabled for N-offline-peers × 30s. Now the list renders and
the button re-enables immediately; probes run concurrently and fill the
dots in as they land.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:44:31 -04:00
archipelago
30a4343b83 fix(ui): kill console spam — pine/mempool icon 404s + filebrowser 401 loop
pine/mempool get explicit icon entries (their extensions aren't .png, so
the default guess 404'd on every render). filebrowser-client: central
authedFetch does ONE transparent re-login when the short-lived JWT
expires (an expired cookie previously kept _authenticated=true and every
Files-card poll 401'd forever), plus a 60s login cooldown so a missing
filebrowser doesn't spam either.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:08:31 -04:00
archipelago
c0aef2f03e feat(wallet): external tx-explorer fallback with consent + On-chain settings tab
Pruned nodes can't run the Mempool app, but tx links blindly opened it
anyway. Now: local app when running; otherwise an external explorer
(default tx1138.com) behind a one-time amber consent modal that spells
out what the other server's operator learns (tx of interest + IP) and
lets the user point at their own instance (placeholder mempool.guide).
Wallet Settings gains an On-chain tab (explorer URL + don't-warn toggle);
tabs renamed Cashu/Fedi so five fit in the row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:31:48 -04:00
archipelago
5e7e928650 feat(wallet): real-time tx push — 0-conf shows in seconds, not on poll
Backend streams LND /v1/transactions/subscribe (fires on mempool arrival
and each confirmation) and nudges the /ws/db revision per event; the Home
wallet card subscribes and refetches (debounced 800ms). An incoming
broadcast now appears while the 30s poll is still asleep. Reconnects
forever with capped backoff when LND is down/locked/absent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:31:47 -04:00
archipelago
7e7b6bd474 fix(neode-ui): instant payments no longer stuck as 'Incoming' forever
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m42s
The Home wallet card counted every incoming tx with num_confirmations < 3
in the pulsing 'Incoming N' badge. Lightning history hardcodes 1 conf and
ecash/fedimint/ark receives are normalized to 1 conf, so instant payments
qualified permanently — old receives showed as 'incoming' forever (seen
on .228 with week-old lightning orders).

- On-chain keeps confirmation-based logic (< 3 confs, expires naturally).
- Instant rails (lightning/cashu/fedimint/ark) now surface in the incoming
  panel only for 5 minutes after receipt — the nice arrival moment without
  the perpetual pending state.
- Panel rows: 'Unconfirmed / N conf' badge and mempool link are now
  on-chain-only; instant rows get a rail badge instead.
- Home now polls wallet balances+transactions every 30s (like Web5.vue),
  so pending on-chain receives actually flip to confirmed and the badge
  appears/expires without a manual wallet action.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:43:53 -04:00
archipelago
693f4bb947 docs: v1.7.111-alpha changelog + What's New sync
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m39s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 05:04:11 -04:00
archipelago
317a72aafe fix(federation): presence-sign modal scales and scrolls on small phones
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m37s
The info card above the action buttons now shrinks with the viewport and
scrolls internally (min-h-0 + overflow-y-auto in a max-h-full flex column),
keeping Cancel / Sign & Publish always visible. The hero disc and viz ring
scale down on narrow or short screens via a --seg-radius CSS variable so
the animation honors the smaller ring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 03:12:15 -04:00
archipelago
184257390d feat(pine): 1.3.0 manifests — openwakeword member + live node status on the launcher page
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m40s
pine-openwakeword manifest (wyoming-openwakeword 2.1.0, :10400, /custom model
dir for the future Yo Archy model). Pine 1.3.0: launcher page gains a live
node-status card fed by /api/pine/status via a same-origin nginx proxy, and
copy for the new intents / Claude fallback / mesh announcements. Catalogs,
app-session config, drift ids regenerated; release catalog embeds 56
manifests (unsigned until the ceremony). Framework PT test plan in docs/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 02:59:34 -04:00
archipelago
b288be314c feat(federation): presence-signing overlay on discovery enable
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m43s
Enabling Nostr discoverability now opens a signer overlay (same visual
language as the app NIP-07 identity picker) before anything is published:
a locked signer row fixed to the node's discovery key — deliberately not
pickable, personal identities are never used — plus the exact signed
content (DID, npub, software version, kind 30078/NIP-33 format) and a
Sign & Publish confirm. Disabling stays immediate. Also seeds the mock
with discovery OFF to match the production default, and defaults
dwnSyncLabel to 'Unknown' when the backend omits sync_status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 02:55:06 -04:00
archipelago
50d5d4d132 feat(federation): signing-details panel on the Nostr discoverability strip
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m41s
Adds a 'Signing details' disclosure showing who signs the presence event —
a locked identity row (styled like the NostrIdentityPicker overlay) fixed to
the node's own discovery key, deliberately not pickable so personal
identities can never be used for node discovery — plus a human-readable
breakdown of the signed content: DID, signing npub, software version, and
the event format (kind 30078, NIP-33 replaceable, d-tag archipelago-node),
with a note that every event carries a NIP-01 Schnorr signature.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 02:18:58 -04:00
archipelago
73923d0ffd feat(ui): mobile home — wallet card moves up under My Apps
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m40s
On single-column (mobile) the dashboard cards now order My Apps, Wallet,
Cloud, Network; desktop keeps its existing two-column layout via
lg:order-none resets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 02:11:39 -04:00