1993 Commits

Author SHA1 Message Date
archipelago
1a3170f1c3 fix(ui): companion popup waits for sustained calm; connection banner stops crying wolf
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m36s
Two "unpolished" moments, worst on the demo:

- CompanionIntroOverlay gated on a point-in-time check of the reveal
  cinematic flag. On a cold cache the entrance video can start buffering
  after the 5s base delay, so the flag was still false when sampled and
  the popup cut into the cinematic anyway. It now shows only after the
  scene has been continuously calm for the full grace window.

- ConnectionBanner's flat 2.5s debounce fired on every tab-return and on
  first dashboard paint: a dead WebSocket is the NORMAL state right then
  (browsers kill background-tab sockets; first paint races the initial
  connect), and reconnects routinely exceed 2.5s over real links. Those
  moments now get a 10s runway (15s window after load/resume); genuine
  mid-session drops keep the 2.5s response. On the demo the blip banner
  is suppressed entirely — it runs against a local mock, so "Connection
  lost" there is pure noise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:42:57 -04:00
archipelago
547f674ac8 fix(pwa): defer update reloads until the intro cinematic finishes
All checks were successful
Demo images / Build & push demo images (push) Successful in 3m23s
A genuine service-worker update still reloaded the page the instant the
new worker claimed it. The kiosk and the public demo replay the intro on
every boot/visit, so an update landing mid-sequence restarted the whole
cinematic — the "typing intro resets to the start after several seconds"
report. Hold the reload until the splash is complete and the
dashboard-reveal cinematic is over, then apply it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 16:48:56 -04:00
archipelago
92d221bbf1 fix(ui): show the controller focus ring only during actual arrow/gamepad navigation
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m42s
The orange "gamepad selection" lift+glow was plain CSS :focus styling on
[data-controller-container] — any tap on a tabindex card lit it up (worst
on mobile), and useControllerNav's autoFocusMain programmatically focused
the first card on mount and every route change, painting the ring with no
controller input at all.

Gate it behind html.controller-nav, toggled by actual input modality:
arrow-key navigation and gamepad connection turn it on, any pointerdown
turns it off. autoFocusMain now no-ops outside directional-nav mode (a
first arrow press focuses the first container instead of spatially
navigating from <body>), so pointer users never get surprise rings while
keyboard/gamepad users keep the exact same navigation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 15:38:46 -04:00
archipelago
e9cfc234cd fix(kiosk): flatten the onboarding/login background too + roomier renderer heap
The 454c4bb2 kiosk flattening only covered the Dashboard's background
stack, but the kiosk boots into the login/onboarding screen —
OnboardingWrapper.vue — whose scoped 3D stack (perspective +
preserve-3d bg layers + mix-blend-mode glitch overlays) has the exact
compositing pattern that fails to repaint under the kiosk's software
compositor, leaving the black body fill visible. Extend the same
html.kiosk-mode flattening to this screen via :global() rules: 2D
opacity crossfades stay, 3D transforms / blur filters / blend-mode
glitch layers go.

Also raise the kiosk chromium JS heap cap 128→256MB: the intro
cinematic (video + audio + app) inside a 128MB V8 old-space risks
renderer OOM, and a crashed kiosk tab auto-reloads — indistinguishable
from the reported "flickers and refreshes".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 15:38:22 -04:00
archipelago
06186ab30c fix(intro): restore the typing intro on fresh kiosk installs + seamless splash-to-onboarding handoff
Three regressions of the fresh-install cinematic, all in App.vue:

1. The kiosk chromium opens /kiosk (a marker route that stamps
   localStorage.kiosk and redirects to /). The deep-route splash
   suppression added in PR #91 reads window.location.pathname, so the
   kiosk boot was classified as a deep route and the typing intro →
   "Welcome Noderunner" → onboarding sequence never played. Normalize
   /kiosk to / for the splash decision.

2. The pre-splash onboarding-status check runs a ~30s retry ladder;
   against a still-booting backend it held the black !isReady screen the
   whole time. Bound it with a 2.5s race — unknown means "play the
   intro" (a fresh install IS the slow-backend case; onboarded nodes
   answer in milliseconds so their suppression is unaffected).

3. handleSplashComplete revealed RouterView before routing, flashing
   RootRedirect's spinner at '/' between the intro's final frame and the
   onboarding screen. Commit the destination route first, then reveal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 15:35:47 -04:00
archipelago
e5c7210663 fix(install): stall-aware, retried image pulls in the orchestrator runtime
PodmanClient::pull_image had a single attempt with a hard 600s wall
clock — on a fresh node, any image that legitimately takes >10 min to
download got killed mid-pull and failed the install. Podman keeps the
completed layers, so the user's retry started half-done and succeeded:
the exact "first install fails, second works" pattern reported for
btcpay and indeedhub (and earlier for LND, whose fix in 72d7fa07 only
covered the legacy install path — this is the same cure ported to the
orchestrator path both fresh installs and upgrades use).

A pull is now only killed when nothing is observably happening — no
stderr output AND no staged-byte growth in TMPDIR for 180s — or at a
1800s absolute ceiling, with 3 attempts and backoff on top. Dead
registries still fail fast (no bytes ever land). Failures now surface
podman's actual stderr tail instead of a bare exit status, and the
pull stages via the user's containers tmp like every other pull path
(rootless /var/tmp is read-only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:02:53 -04:00
archipelago
500472944c fix(install): stream per-member progress for orchestrator stack installs
Orchestrator-installed stacks (indeedhub, btcpay, netbird, immich,
mempool) sat at "Preparing… 5%" for the entire install — the
install_stack_via_orchestrator path never called set_install_phase /
set_install_progress after the initial Preparing, so a 7-image,
multi-gigabyte indeedhub pull gave the user zero feedback ("just says
preparing for ages"). The legacy installers already report phases and
the frontend already interpolates X-of-N across the PullingImage band;
the new path simply never fed it.

Now: PullingImage phase up front, an X-of-N counter plus a per-member
"Installing postgres (2 of 7)…" message as each member installs, and
the legacy installers' truthful PostInstall→Done settle at the end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:02:05 -04:00
archipelago
a687df9bd9 feat(backup): include secrets (LND seed key) in backups + Download button
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m32s
The full backup carried identity/lnd_aezeed.enc but NOT the per-node
wallet secret that encrypts it (secrets/lnd-wallet-password), so a
restored node could never decrypt its Lightning seed. The secrets dir
now rides the backup (archive v3; the .bak itself is
passphrase-encrypted). Restore gains a staging-presence guard so
restoring an older archive without a secrets dir can no longer displace
and delete the node's live secrets — covered by two new tests.

Backups can now also be downloaded through the browser: a session-gated
GET /api/blob/backup/<id> endpoint (under the existing nginx /api/blob
prefix, so no fleet nginx changes) plus a Download button next to
Verify / USB / Restore / Delete in Settings → Backup & Restore.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:49:37 -04:00
archipelago
0aa9463b36 feat(iso): append auto-incrementing _RCn suffix to ISO filenames
Rebuilds of the same version overwrote the previous ISO under an
identical filename, making a flashed stick indistinguishable from a
newer build. The builder now keeps a per-version RC counter (next to
the build counter) and names outputs like
archipelago-installer-1.7.101-alpha-unbundled-x86_64_RC2.iso.
Override with RC=n env when re-cutting a specific candidate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:17:11 -04:00
archipelago
5cb53ade66 fix(health): stop raw-probing ports of containers with own healthchecks
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m34s
The health monitor opened a bare TCP connection to every published host
port each cycle. Against TLS listeners that connect+close logs noise on
the app side — LND printed 'http: TLS handshake error … EOF' endlessly.
Containers that define a podman healthcheck (LND uses lncli getinfo)
now rely on it alone; bare containers keep the port probe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:06:03 -04:00
archipelago
47dea8cd55 fix(lnd): make the seed-backup notification actually open the backup flow
Clicking 'Back up now' on the Lightning seed banner only navigated to
the LND app page — and the backup card there hid itself permanently if
its single status fetch failed (common right after a fresh install),
so the click appeared to do nothing.

The banner now deep-links with ?seed-backup=1, which the LND page uses
to open the reveal flow directly, and the card retries its status fetch
with backoff instead of giving up after one failed RPC.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:06:03 -04:00
archipelago
72d7fa07ff fix(install): never fail a first-time LND install over transient conditions
Two confirmed fresh-node failure modes made 'install LND' fail on the
first try and succeed on the second:

- The dependency gate failed fast when Bitcoin was still mid-install
  (image pulling, container not created yet): DepProbe.existing only
  covered 'podman ps -a', so an in-flight dependency looked identical to
  'not installed at all'. The probe now also reports packages in
  Installing/Updating state, and the gate waits up to 30 minutes for an
  in-flight dependency install to finish (surfacing 'Waiting for X to
  finish installing…' on the card) before its normal 3-minute
  started-but-not-running window.

- Image pulls had a hard 300s per-URL wall clock, which killed
  slow-but-progressing pulls of large images (LND on fresh-node WiFi);
  the retry then succeeded off the warm layer cache. Pulls are now
  stall-aware: killed only after 3 minutes with no podman output AND no
  byte movement in the staging dir, with a 30-minute absolute ceiling.
  Dead registries still fail in ~3 minutes.

Adds dep-gate unit tests for the in-flight-install wait and the
neither-installed-nor-installing fail-fast.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 08:42:06 -04:00
archipelago
6dcdada371 fix(iso): make baseline apps work on a fresh install with no internet
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m36s
Fresh offline installs came up without fedimint-clientd and filebrowser
(they only appeared after connecting internet). Three root causes:

- archipelago-load-images.service ran 'podman load' as root, but every
  container runs rootless as archipelago — bundled images landed in
  root's storage where the rootless runtime can't see them, so all
  container creation silently depended on registry pulls. The loader now
  loads into the archipelago user's storage (with linger + runtime-dir
  wait + system migrate).
- The unbundled ISO bundled only filebrowser.tar; fmcd (fedimint-clientd)
  is a baseline first-boot app too and is now part of the unbundled core
  bundle.
- first-boot's pull_with_fallback always hit the network; it now uses an
  already-loaded local image first and skips the pull entirely.

Also: fedimint-clientd added to the UI's hardcoded curated-app fallback
list (it was missing when all catalog fetches fail offline), plus its
INSTALLED_ALIASES entry, and the stale fmcd bundling comment in
image-versions.sh corrected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 07:31:28 -04:00
archipelago
454c4bb25c fix(kiosk): flatten background compositing so backgrounds don't go black
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m40s
On kiosk, chromium runs software-composited (--in-process-gpu or
--disable-gpu, one raster thread). The dashboard's 3D-transformed
will-change background layers and the infinite mix-blend-mode:multiply
fixed overlays routinely fail to repaint there after the first
interaction/route change, leaving the container's black fill (or a stuck
multiply layer) covering the screen.

A kiosk-mode class is now set on <html> (localStorage kiosk flag, ?kiosk
param, or the /kiosk boot path) and gates CSS overrides: background
layers become plain 2D opacity crossfades (no preserve-3d/translateZ/
will-change) and the animated multiply overlays are disabled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 07:06:12 -04:00
archipelago
66fd121748 fix(kiosk): no reload on first service-worker claim + patient boot health check
Two causes of the fresh-install 'loads, refreshes, loads again' jank:

- The PWA autoUpdate service worker claims the page right after the very
  first load, firing controllerchange, which unconditionally reloaded the
  page. Now only a *replaced* controller (a real update) triggers reload.
- A single 2s RPC echo decided server-down on first boot, flashing the
  BootScreen and then hard-reloading seconds later. A second, 6s attempt
  now runs before concluding the backend is down.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 07:05:56 -04:00
archipelago
fa91faa67c fix(intro): hold companion popup until dashboard reveal cinematic ends
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m42s
The remote-companion popup fired on a blind 5s timer while the
first-visit dashboard entrance cinematic runs for 8s, so on a fresh
install it appeared mid-reveal and broke the intro. The cinematic now
publishes an introCinematicPlaying flag via the loginTransition store,
and the popup waits for it to clear (plus a 2s grace) before showing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 06:57:42 -04:00
archipelago
e9c3311eff chore: sign v1.7.101-alpha OTA manifest
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m37s
Also folds the Cargo.lock version bump the release commit missed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
v1.7.101-alpha
2026-07-15 11:18:46 -04:00
archipelago
338ae9a6de chore: release v1.7.101-alpha 2026-07-15 11:11:08 -04:00
archipelago
8f397b03f9 docs(release): fold PR #91 (audible entrance, no splash hijack on deep routes) into v1.7.101-alpha notes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:07:57 -04:00
48d5fd0045 Merge pull request 'fix(intro): reliable first-visit cinematic — audible oomph, no splash hijack on deep routes, e2e suite' (#91) from intro-reliability-video-perf into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m34s
2026-07-15 14:29:23 +00:00
Dorian
a44cbe478a fix(intro): audible entrance oomph, splash off deep routes, finale on intro shortcuts — with e2e cinematic suite
Three first-visit-experience bugs, all caught by the new e2e suite
(e2e/intro-experience.spec.ts — 5 tests against the demo stack on real
Chrome, instrumenting HTMLMediaElement/WebAudio/MutationObserver since
headless can't hear or see the cinematic):

- playDashboardLoadOomph was always silent: the login→dashboard route
  change closes the AudioContext (stopAllAudio), and the oomph only
  fetched the dead context. It now recreates one, riding the login
  click's sticky user activation.
- A direct /login load in the demo hijacked into the splash: App.vue
  read route.path before the router resolved the initial navigation, so
  every deep-route boot looked like a root boot. The splash decision now
  reads window.location.pathname.
- Replayed intros ran mute (enableCinematicSounds override) and the
  intro's shortcut exits skipped the dashboard finale (flag now armed on
  both demo and login exits).

Verified: 5/5 e2e, 673/673 unit, vue-tsc clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:13:39 +01:00
archipelago
519b4b209a docs(release): fold PR #90 (splash reliability + lighter intro video) into v1.7.101-alpha notes
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m39s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 06:58:55 -04:00
ai
2c82b498f0 Merge pull request 'fix(intro): splash reliability on fresh visits + 3x lighter video' (#90) from intro-reliability-video-perf into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m33s
2026-07-15 10:54:21 +00:00
Dorian
efd1ae41de fix(intro): splash always honors App's decision + video streams 3x lighter
- SplashScreen no longer re-checks neode_intro_seen itself: it silently
  skipped the whole logo-tap/typing sequence for any browser that had
  seen the intro before, even when App.vue explicitly requested it (demo
  fresh visits, Replay Intro). App.vue is the single decision point.
- Intro video re-encoded 12.7MB/12.6Mbps → 4.3MB/4.2Mbps (1920x1080 CRF23
  faststart, muted track dropped) — visually identical on this
  illustrated content; cache-buster bumped to v=8.
- Video is <link rel=preload>ed the moment the splash is scheduled (the
  <video> element only mounts ~20s in, so cold caches used to start the
  download mid-sequence and stutter).
- nginx demo cache regex now covers mp4/webm/mp3/webp/woff2 so repeat
  visits play from browser cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:53:14 +01:00
archipelago
0c591a997e docs(release): fold PRs #87-#89 into the v1.7.101-alpha notes
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m34s
Login video continuity, cloud bottom-bar music player, demo intro on
every visit — regenerated the What's New block to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 06:37:17 -04:00
ai
91e1059f56 Merge pull request 'fix(ui): login video/background continuity — video until first login, rotation after' (#89) from login-bg-continuity into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m31s
2026-07-15 10:34:40 +00:00
Dorian
3d986b81a0 fix(ui): login keeps the intro video until the first login; rotation after
The login page sometimes swapped to a random bg-intro-N still on load,
breaking the seamless handoff from the intro video. Now: until anyone
has logged in / set a password (neode_first_login_done, stamped by every
Login success path incl. TOTP and setup), /login keeps the VIDEO
background — one continuous shot from the splash. From the second login
onward the lock screen rotates through the static backgrounds as
designed, and if the static path is ever hit pre-first-login it pins to
bg-intro.jpg (the video's end frame) instead of rotating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:34:06 +01:00
ai
2efed23afd Merge pull request 'fix(cloud): music opens the bottom-bar player, never the lightbox' (#88) from audio-bottom-bar into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m36s
2026-07-15 10:24:19 +00:00
Dorian
df403c5a69 fix(cloud): music opens the bottom-bar player, never the lightbox
FileCard audio clicks now emit play (global GlobalAudioPlayer bar) —
wired through the FileGrid list view, the Cloud My Files list and own
search results. Peer Files already used the bottom bar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:23:57 +01:00
ai
a34634e00f Merge pull request 'feat(demo): intro on every fresh visit + neutral desktop Cloud tabs' (#87) from demo-intro-every-visit into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m35s
2026-07-15 10:13:30 +00:00
Dorian
c13ee58edf feat(demo): typing splash + intro on every fresh visit; neutral desktop Cloud tabs
- Demo boots at '/' (first visit or a browser refresh) always start with
  the typing splash into the onboarding intro — the per-calendar-day
  gate is gone. In-session SPA navigation never replays it, and
  deep-route refreshes keep the visitor's place.
- Cloud top-level tabs return to the standard mode-switcher style on
  desktop; the orange full-width switcher stays mobile-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:12:49 +01:00
archipelago
6e5a99ef71 fix(tests): CloudPeersRefresh mounts Cloud with Pinia (useCloudStore in setup)
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m33s
The cloud tabs rework added useCloudStore() to Cloud.vue's setup; this
older test mounted without a Pinia instance and failed the release gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 06:05:53 -04:00
archipelago
749c351e5e docs(release): v1.7.101-alpha notes + What's New sync
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 05:59:53 -04:00
archipelago
dc897064cd fix(iso): derive ARCHIPELAGO_HOST_IP from the default route, not hostname -I
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m39s
The unit's ExecStartPre baked the first hostname -I token into
host-ip.env, which config.rs prefers over its own detection — once a
VPN/bridge interface existed (netbird's wg tunnel), every host_ip
consumer (install configs, VPN, mint URLs) got the tunnel IP. Read the
main-table default route's src address instead, falling back to
hostname -I on routeless hosts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 05:56:22 -04:00
archipelago
178ba85c5c fix(system): hostname rename updates /etc/hosts and re-announces mDNS
server.set-name ran hostnamectl but left Debian's 127.0.1.1 line on the
old name (breaking sudo's 'unable to resolve host' and hostname -f) and
waited on avahi to notice the change by itself. Sync /etc/hosts and
avahi-set-host-name (fallback: try-restart avahi-daemon) right after a
successful rename, so http(s)://<hostname>.local works immediately —
best-effort, never blocks the rename.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 05:56:22 -04:00
archipelago
0f5ea9ae15 fix(tor): resolve app ports dynamically + auto-create hidden service on install
'Add Service' only worked for the 19 apps in the hardcoded
known_service_port map — everything else failed with 'Unknown app'.
tor.create-service and tor.toggle-app now fall back to the app's live
launch address from the scanner state, so any manifest-driven app gets
a .onion without a per-app entry (the static map still wins for
protocol services like bitcoin, which must expose 8333, not a UI port).
toggle-app also no longer writes a broken port-0 HiddenServicePort for
unknown apps.

Every successful package.install now auto-creates the app's hidden
service (detached, best-effort, retries while the scanner derives the
port; skips protocol services and existing entries).

The demo mock gains stateful tor.create-service/tor.delete-service so
the demo round-trips instead of erroring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 05:56:22 -04:00
archipelago
5d4d40e9e8 style: cargo fmt the Ark wallet merge (release-gate fmt guard)
Formatting only — no logic changes to PR #78.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 05:56:22 -04:00
ai
8caa4c7d07 Merge pull request 'fix(ui): restore first-login dashboard entrance + working Replay Intro' (#86) from intro-entrance-fixes into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m36s
2026-07-15 09:49:14 +00:00
Dorian
4983ba4e20 fix(ui): first-login dashboard entrance restored + working Replay Intro
- playDashboardLoadOomph gated itself silent on the one entry that
  should be loud: onboarding is already flagged complete by the time the
  post-wizard dashboard mounts. force flag restores the full oomph there
  while keeping ordinary re-logins quiet (the intentional limit).
- OnboardingDone now hands Login a one-shot finale flag, so the login
  right after the wizard gets the full zoom + oomph even as a regular
  password login — which is exactly the demo flow (and TOTP logins).
- 'Replay intro' on the login screen actually replays: App.vue was
  instantly re-marking the intro as seen on onboarded nodes; an explicit
  one-shot replay flag now overrides every suppression rule (unit
  tested).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:48:39 +01:00
ai
994795e4d2 Merge pull request 'feat(cloud): tab/list feedback + rich demo peer content' (#85) from cloud-feedback-demo-content into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m33s
2026-07-15 09:36:33 +00:00
Dorian
4226b5ec0a feat(demo): rich peer content library with never-broken previews
24-item catalog across films/series/books/music/photography/documents/
software with full metadata; deterministic per-peer subsets so every
node shares a different mix. Posters/covers/photos are committed JPEGs
(demo/peer-media, sourced via picsum.photos); previews always serve real
image bytes, and free music/photos/documents stream the actual committed
files so playback genuinely works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:35:42 +01:00
Dorian
8f6312fe7b feat(cloud): Folders/My Files/Peer Files polish + readable file rows
- Top-level Cloud tabs get their own orange-tinted switcher (clearly
  distinct from the category pills); full-width thirds on mobile
- 'All Files' tab renamed Folders; categories only show on the file-list
  tabs (My Files / Peer Files / search)
- My Files is now a flat list of every own file rendered with FileCard —
  real actions (share/download/delete) and clicking opens the FILE
  (media lightbox incl. audio, downloads for documents), never a folder;
  own search results get the same treatment
- Folder list rows get card backgrounds (readable over the wallpaper),
  same info as before

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:35:42 +01:00
ai
bdf283fcff Merge pull request 'feat(cloud): Apps-style tabs, categories and federated file search' (#84) from cloud-tabs-search into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m37s
2026-07-15 09:02:56 +00:00
Dorian
df90cdaac9 fix(cloud): satisfy noUncheckedIndexedAccess in categoryMeta fallback
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:02:35 +01:00
Dorian
0cf91136f9 feat(cloud): Apps-style tabs, categories and federated file search
Cloud gets the same header layout as Apps: All Files / My Files / Peer
Files tabs, Photos & Video / Music / Documents category filter, and a
search bar that queries your own FileBrowser sections (depth-limited
walk) plus every federation peer's shared catalog (content.browse-peer
fan-out, cached), with a loader while it runs. Peer Files lists the
actual files from all peers with attribution. Mobile uses the Apps
category-pill strips (which already opt out of the page-switch swipe)
with search below — no fixed top tabs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:01:36 +01:00
ai
6d7b39578e Merge pull request 'feat(wallet-ui): Ark send/receive/pay-with + mobile tx modal height' (#83) from ark-wallet-ui-demo into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m32s
2026-07-15 08:54:24 +00:00
Dorian
13909e28bf fix(ui): cap transactions modal at 60% of the live viewport on mobile
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 09:53:53 +01:00
Dorian
97488c83f7 feat(wallet-ui): Ark send/receive tabs + Ark pay-with option on peer files
Send modal gains an Ark tab (address/invoice/lightning-address via
wallet.ark-send), Receive gains an Ark address + QR tab, and the peer
file purchase confirm offers Ark alongside Cashu/Fedimint. Demo mock
exposes ark_sats in wallet.ecash-balance and deducts the chosen rail on
paid downloads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 09:53:53 +01:00
ai
eaf8b7b63e Merge pull request 'fix(demo): nginx cache regex was 404ing all /app/ shell assets' (#82) from demo-nginx-app-assets into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m35s
2026-07-15 08:45:44 +00:00
Dorian
46f7ac3fcf fix(demo): stop the static-cache regex from swallowing /app/ assets
nginx regex locations outrank prefix locations, so app-shell assets like
/app/bitcoin-core/tailwind.css and /app/lnd/qrcode.js hit the .css/.js
cache block and 404'd from the web root instead of proxying to the mock
backend — the actual cause of the unstyled Bitcoin UI (and the shabby
lnd-ui) on the demo. ^~ on the /app/ prefixes disables regex matching
for those paths. Config validated with nginx -t.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 09:44:56 +01:00