Every Lightning setup (Open a Shop, Accept Payments, Run a Lightning Node)
gains a guided path to a working channel:
- New "Fund Your Bitcoin Wallet" step, gated on the blockchain finishing
its initial sync: while syncing it shows a live progress bar with a
counting-down time-remaining estimate; once synced it shows the on-chain
balance and a "Fund Wallet" button that opens the receive modal with a
fresh address, QR, and the Zeus channel limits (min 150,000 / max
1,500,000 sats) noted.
- When the sync finishes while a Lightning setup is mid-flight, a toast
pops with a "Finish setup" link straight back to the wizard (toasts now
support action links). If several setups are in flight, one is chosen —
the shared steps complete the lightning part of any of them.
- Channel steps are Zeus-branded (logo + copy) and land on the Lightning
Channels screen, which now carries an "Open a channel with Zeus" card
that prefills the open-channel modal with the Olympus peer URI, 150k
sats, and private-channel checked. "Get Zeus" links to zeusln.com.
- Setup completion now actually requires walking the manual steps (fund,
open channel, configure) — previously any step whose app was installed
was silently auto-ticked and running apps marked the whole goal done.
- Completion CTAs now go to the app you just set up ("Go to my shop
(BTCPay)" etc.) instead of the generic services list; iframe apps open
in the on-top app overlay.
- On-chain send modal gains a "Send all funds" sweep toggle, backed by
LND's send_all on the backend (amount no longer required when sweeping).
- Demo/mock: bitcoin.getinfo now returns the block_height/sync_progress
contract the UI reads and simulates a ~90s IBD ramp per visitor so the
timer, toast, and fund flow can all be demoed live; channel list data
fixed (status/channel_point/liquidity totals — the panel previously
crashed on the missing status field); sendcoins supports send_all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
- 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>
Launching an app (or opening a tx in mempool from Home/wallet/channels) used
to router.push the app-session page in overlay/fullscreen modes, swapping the
page underneath — confusing and lossy. All display modes are now store-driven:
panel renders beside the page, overlay/fullscreen render above it (teleported
to body), and the route never changes. Deep-link paths (/tx/<hash>) ride along
via the launcher's panelPath instead of a route query; closing always returns
exactly where the user was. The app-session route stays for direct links.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixes from real fresh-install feedback (Framework node .81) + its log bundle:
Backend:
- websocket: subscribe before initial snapshot — broadcasts in the gap were
silently lost, stranding clients on stale state until a hard refresh
(the "everything needs ctrl-r" bug: My Apps stuck Loading, App Store
stuck Checking, containers-scanned never arriving)
- crash recovery: check the crash marker BEFORE writing our own PID —
recovery had never run on any node (always saw its own PID and skipped);
PID-reuse guard via /proc cmdline
- boot status: pending-boot-starts registry (recovery, stack recovery,
reconciler, adoption) — scanner overlays queued-but-down apps as
Restarting instead of Stopped after a reboot; scanner-authored
Restarting resolves immediately on a settled scan (no transitional wedge)
- install deps: bounded wait (36x5s) when a dependency is installed but
still starting ("Waiting for Bitcoin to start…") instead of instant
rejection; dependency-gate rejections remove the optimistic entry (no
phantom Stopped tile) and surface as a notification
- seed backup: auth.setup persists the onboarding mnemonic as the
encrypted seed backup (reveal previously failed on EVERY node — nothing
ever wrote master_seed.enc); seed.restore stashes too; error sanitizer
lets seed/2FA errors through instead of "Check server logs"
- lnd: bitcoind.rpchost resolved from the running Bitcoin variant
(hardcoded bitcoin-knots broke Core nodes); manifest uses derived_env
- bitcoin status: clean human message for connection-reset/startup; raw
URLs + os-error chains no longer reach the app card
- fedimint-clientd: chown /var/lib/archipelago/fmcd to 1000:1000 (root-
created dir crash-looped the rootless container, EACCES) — first-boot
script + pre-start self-heal
- log volume (>1GB/day on a day-old node): journald caps drop-in (ISO +
bootstrap self-heal), bitcoind -printtoconsole=0 everywhere (90% of the
journal was IBD UpdateTip spam), tracing default debug→info
Frontend:
- Login: Enter advances to confirm field then submits; submit always
clickable with inline errors (was silently disabled on mismatch);
Restart Onboarding needs a confirming second click (the mismatch →
"onboarding restarted" trap)
- sync store: 30s state reconciliation + refetch on re-entrant connect;
20s containers-scanned escape hatch so Checking can never show forever;
fresh empty node reaches the real "no apps yet" state
- intro video: CRF20 re-encode (SSIM 0.988) + faststart — moov was at EOF
so playback needed the full 15MB first (the intro lag)
- backgrounds: 10 heaviest JPEGs → WebP q90 (9.4MB→6.6MB); 7 stayed JPEG
(WebP larger on noisy sources)
- Web5ConnectedNodes: drop unused template ref that failed vue-tsc -b
ISO/kiosk:
- nginx: /assets/ 404s no longer cached immutable for a year; HTTPS block
gained the missing /assets/ location (served index.html as images)
- kiosk: launcher/service spliced from configs/ at ISO build (stale
heredoc force-disabled GPU); MemoryHigh/Max 1200/1500→2200/2800M (kiosk
rode the reclaim throttle = the lag); firmware-intel-graphics +
firmware-amd-graphics (trixie split DMC blobs out of misc-nonfree)
Verified: cargo test 898/898 green, npm run build green with dist
contents confirmed (webp refs, lnd.png, faststart video, new strings).
Handover for ISO build + deploy: docs/HANDOVER-2026-07-02-iso-feedback.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Classify databases/APIs/backends into Services (#10): add immich-postgres/redis
to SERVICE_NAMES; isServiceContainer matches -postgres/-redis/-valkey/-cache/-db
suffixes; isWebsitePackage final fallback now routes any no-UI, non-known package
to Services ("anything that isn't the frontend UI launcher").
- Services show their parent app's icon (#14): backends reuse the app logo
(immich-* → immich, archy-btcpay-db → btcpay, indeedhub-* → indeedhub, etc.)
via explicit APP_ICON_FALLBACKS + prefix map, instead of 404 → 📦.
- Categories sub-nav for Services (#12): getServiceCategory + buildServiceCategories
+ useServiceCategories; Services tab gets the same desktop/mobile category strips
(Databases/Caches/APIs/Backends), shown only for categories with items. Shared
selectedCategory resets to 'all' on tab switch.
- Mobile swipe (#11): the tab-swipe gesture is suppressed over .mobile-category-strip
so swiping the category chips scrolls them instead of changing tabs (covers both
My Apps and the new Services strip).
vue-tsc build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Apps tab: a horizontal swipe that starts on an app icon no longer flips the
top tab — it lets the app-page scroll / icon tap win (swipe empty space to
change tab). Fixes the swipe conflict with two pages of apps.
- Files: file cover tiles are forced square on mobile (aspect driven by CSS,
not a Tailwind arbitrary class) so the grid is uniform and tappable.
- Files: scroll container gets bottom safe-area + tab-bar padding so the last
row clears the mobile back button / bottom nav.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Companion app QR encoded a relative path (/packages/...apk.zip) which
can't resolve when scanned by a phone. Point it at the absolute 146
release-server URL so the download works from any device.
- Dashboard tab-swipe: guard tabs[next] (noUncheckedIndexedAccess) so the
frontend type-checks/builds.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
UI (this session):
- Global audio player now scales the whole interface into the space above it
on desktop (sidebar + main) and docks directly above the tab bar on mobile;
it stays visible while navigating.
- Mesh mobile redesign: floating Chat / BTC / Dead Man / AI / Map tab strip
with a single fixed, internally-scrolling pane (page no longer scrolls);
tabs hide while a conversation is open; floating back button; collapsible
Device panel (starts collapsed); keyboard-aware conversation sizing via
VisualViewport so the chat sits just above the keyboard.
- Cloud file grid: uniform 4/3 card heights (folders + images match).
- Swipe left/right switches tabs on the Apps and Web5 screens.
- Map tool fills its pane (no bottom gap); fix skewed Share Location toggle
on mobile (global min-height rule was deforming the switch).
- Trim redundant helper copy from the mesh AI tab.
Also bundles pre-existing in-progress work that was already in the tree:
mesh listener/session + wallet + container + bitcoin-status backend changes,
docker UI updates, and assorted other UI tweaks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- useOnboarding.ts: when the backend gives a definitive answer
(true/false, not a null retry failure), re-seed the
neode_onboarding_complete localStorage flag accordingly. Fixes the
case where a user clears site data on an already-onboarded node —
OnboardingWrapper's useVideoBackground computed reads localStorage
synchronously, so without this re-seed the intro video would fire
again on /login even though RootRedirect correctly sent them
straight to /login.
- OnboardingWrapper.vue: login background now rotates through
bg-intro-1..6 on each /login mount, with the current index
persisted to localStorage (neode_login_bg_idx) so subsequent
logouts advance rather than repeat the same image.
- Dashboard.vue: subsequent-login branch drops the 1.2s showZoomIn
entirely. Only the first dashboard entry after onboarding plays
the full zoom + glitch reveal; every re-login now just fades in
with the welcome typing (~300ms).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- useOnboarding.ts: prefer the backend over localStorage when checking
onboarding completion. The old order (localStorage first) meant any
browser that had ever onboarded a node would treat every new fresh
node as already-onboarded and skip the wizard, dumping the user
straight at the inline set-password form. Backend is now authoritative;
localStorage stays as the offline fallback.
- OnboardingWrapper.vue: skip the intro video on `/login` once
`neode_onboarding_complete` is set. Returning logged-out users now
get the static lock-screen background + glitch overlay instead of
replaying the full intro on every logout.
- RootRedirect.vue: when the health check fails, only show the full
BootScreen if the node was never onboarded. For already-onboarded
nodes (i.e. an OTA-update blip), keep the spinner and poll the
health endpoint every 2s for up to 60s before falling back to the
boot screen. Fixes the "fake boot loader" / "server starting up"
screens flashing on every successful update.
- loginTransition store: new `justCompletedOnboarding` flag distinct
from `justLoggedIn`. Set true only by the inline setup-password
flow (handleSetup). Dashboard.vue branches on it: full glitch+zoom
reveal for the post-onboarding entry, quick zoom + welcome typing
on every other login (no triple glitch flashes, ~1.2s vs 8s).
- vite.config.ts: bump assets cache from `assets-cache-v2` to
`assets-cache-v3` so service workers running the previous bundle
invalidate their cache and pick up the new UI cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cloud subpages (Music, Photos, etc.) now show bg-cloud.jpg instead
of falling through to bg-home.jpg.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dashboard.vue: move DashboardMobileNav outside <main> so position:fixed
isn't broken by will-change:transform on the perspective container
- Add container-specs.sh and reconcile-containers.sh utility scripts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- F29-F32: Split 4 views (Marketplace 1293→505, Server 1132→486, Home 1059→394, AppDetails 1036→386)
- F20: Add aria-current="page" to Dashboard nav links
- F21: Add 150ms search debounce in Marketplace and Apps views
- F22: Reduce backdrop-filter blur to 8px on mobile for GPU performance
- F23: Track and clear WebSocket connect check interval in all paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Federation page uses bg-web5.jpg background
- Invite code in full-screen modal with type label (Link/Peer)
- Join modal upgraded to full-screen with backdrop blur
- "Untrusted" renamed to "Blocked" in trust selector
- Your Nodes / Peers containers: max-h-[60vh] with inner scroll
- Server name from Settings shown on DID card + network map
- DID sync between Web5 and Federation on rotation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New Discover.vue (app store redesign)
- Fleet.vue dashboard for .228
- MeshMap.vue component
- Fixed Discover.vue type errors (unused var, type predicate)
- Various UI updates (Apps, Dashboard, Marketplace, Mesh, Web5)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New Discover.vue with hero banner, featured sovereignty stack apps,
principle cards, manifesto footer, and full app grid
- Featured apps (Bitcoin Knots, LND, BTCPay, Vaultwarden) with
expanded privacy/sovereignty descriptions
- Discover is first tab in categories bar on App Store pages
- Smart back navigation: detail pages return to Discover when navigated from there
- Category clicks from Discover navigate to Marketplace with category pre-selected
- Cypherpunk aesthetic: terminal tags, scanline overlays, gradient accents,
animated Bitcoin orange headings
- Global CSS classes: discover-hero, discover-terminal-tag, discover-featured-card,
discover-principle-card, discover-manifesto
- Route added: /dashboard/discover
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Simplify DHT encoding: use JSON instead of DNS packets (drop simple-dns)
- Fix mainline crate API: SigningKey takes 32 bytes, get_mutable returns Result
- Add missing dht_did field to IdentityRecord constructor
- Store DID Document as JSON in DHT (DNS encoding deferred)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added new dependencies: `adler2`, `crc32fast`, `flate2`, `miniz_oxide`, and `libredox`.
- Updated existing dependencies: `tokio-rustls` to version 0.26.4 and `filetime` to version 0.2.27.
- Removed the `backup.rs` file as it is no longer needed.
- Introduced tests for configuration and credential management.
- Enhanced the `identity` module to generate W3C compliant DID documents.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set up vue-i18n with English locale file containing 500+ keys organized
by view namespace. All 15 views converted to use t() calls instead of
hardcoded strings. Infrastructure ready for community translations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All modals now close with Escape key. Interactive card divs respond to
Enter key. Skip-to-content link added to Dashboard layout. All Web5 and
Settings modals get role=dialog, aria-modal, and escape handlers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Systematic accessibility pass: aria-label on icon-only buttons, role=dialog
and aria-modal on modals, role=tab/tablist on tab switchers, role=switch
on toggles, aria-live on dynamic status/error regions, aria-hidden on
decorative SVGs, aria-label on search inputs, and nav landmarks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The credential issuance and verification handlers used
Handle::block_on() directly inside the tokio runtime, causing a
deadlock. Wrapped with block_in_place() to properly yield the
runtime thread.
Also completed full feature verification across all 25 test groups
(~175 checks) on live server.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moves dynamic pt-20/pt-40 padding from perspective-container-wrapper (which
shrank the content area) to the inner scroll container via computed style.
Removes spacer divs in CloudFolder, AppDetails, MarketplaceAppDetails.
Reduces excessive bottom padding in Marketplace. Hides Cloud/Network tabs
in CloudFolder detail view. Teleports mobile back buttons to body to escape
CSS transform containing block.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --cap-drop=ALL, --security-opt=no-new-privileges:true to all
non-privileged containers. Per-app capability grants for apps needing
CHOWN/SETUID/SETGID. Read-only root filesystem with tmpfs for
compatible apps (searxng, grafana, uptime-kuma, filebrowser,
photoprism, vaultwarden). Add Fedimint "Create a Community" goal
with 4-step wizard. Fix deploy script cp -rf for audio directory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add native Cloud file browser with FileBrowser API integration
- Add cloud store, filebrowser-client, useAudioPlayer, useFileType composables
- Add Cloud components: FileGrid, FileCard, FileCardGrid, CloudToolbar
- Add Claude authentication section to Settings with OAuth status check
- Harden deploy script to preserve /aiui/ and claude-login.html
- Add nginx proxies for btcpay, homeassistant, filebrowser (HTTPS block)
- Add app configs for filebrowser, searxng, penpot in package.rs
- Update goal progress tracking with app aliases
- Improve mobile back button composable with ResizeObserver
- Update various views with cloud integration and UI refinements
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>