291 Commits

Author SHA1 Message Date
Dorian
56e04a9df8 fix: netavark GLIBC mismatch in ISO, container adopt, app updates
ISO build no longer copies netavark from build host (Debian 13/GLIBC 2.41)
which broke container networking on Debian 12 targets. Rootfs already
installs netavark from Debian 12 repos — just configure the backend.

Install RPC now adopts existing containers (from first-boot) instead of
erroring on duplicates. Container scanner extracts real versions from
image tags and detects available updates against pinned versions.

Frontend shows update button with version info when updates are available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:47:35 +02:00
Dorian
5427d4ec5d feat: NostrVPN add-device guided wizard
Replace disconnected "Generate Invite" + "Add participant" with a 2-step
wizard: enter phone npub → get invite QR + mesh details. Backend vpn.invite
now accepts optional npub param to add participant in the same call. Modal
shows network ID, node npub, and relay URLs for manual app configuration.

Also includes nostr-vpn service hardening (rate-limit restarts, reset-failed
before enable).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 19:04:53 +02:00
Dorian
e977600471 feat: NostrVPN mesh + VPN card UI + nvpn v0.3.7
- VPN card: relay URLs, device management, invite QR, add participant
- Backend: vpn.invite, vpn.add-participant, vpn.peer-config RPCs
- nvpn v0.3.7 system service (fixes event processing bug in v0.3.4)
- First-boot: auto-configure nvpn with node identity and endpoint
- Service: AF_NETLINK for WireGuard, NoNewPrivileges=no for sudo wg
- TASK-50: networking stack reliability from first install

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:00:00 +02:00
Dorian
e9fb2f3939 fix: install/uninstall UI state, progress bar, auto-Tor hidden services
- Install progress bar replaces action buttons (no overlay)
- Hide status badge during install/uninstall
- Uninstall keeps progress state until container disappears from WebSocket
- Uninstall RPC timeout increased to 660s (Bitcoin UTXO flush)
- Installing apps appear in My Apps immediately as placeholders
- Auto-configure Tor hidden service for every app on install
- Widen Tor module visibility for install hooks
- Only clear stale install entries on error status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 09:20:18 +02:00
Dorian
37b6b376b2 fix: nostr-vpn service crash on reboot, detect activating state
- Remove ReadWritePaths sandbox (causes namespace error when /run/nostr-vpn
  doesn't exist after reboot — /run is tmpfs)
- Detect both 'active' and 'activating' states in VPN status check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 22:05:08 +01:00
Dorian
5ae60e83ae feat: VPN peer QR code UI, consolidate CI workflows
- Add vpn.create-peer, vpn.list-peers, vpn.remove-peer RPC methods
- Generate WireGuard config + QR code (SVG) for mobile device connection
- Add "Add Device" modal on Network page with QR scanner support
- Remove old build-iso.yml (replaced by build-iso-dev.yml)
- Remove container-tests.yml (tests run in dev workflow)
- Remove container orchestration tests from dev workflow (redundant)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 19:44:00 +01:00
Dorian
b58755b8ed fix: kiosk boot loop — redirect /kiosk to / for proper boot screen
Kiosk was redirecting /kiosk → /dashboard, bypassing RootRedirect
and BootScreen entirely. This caused the kiosk to land on Login.vue
showing "server is starting up" in a loop instead of the proper
terminal-style boot progression screen.

Now /kiosk → / → RootRedirect → BootScreen, matching what remote
browsers see.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:04:58 +01:00
Dorian
314497f94d fix: TS type error in VPN status, remove unused assignment warning
- Fix vpnStatus type mismatch (provider: string|undefined vs string|null)
- Remove redundant history_dirty assignment in health_monitor.rs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:23:17 +01:00
Dorian
23f17356df fix: implement Claude API key save RPC, VPN status on home page
- Add system.settings.get/set RPC methods for Claude API key management
- Save key to secrets/claude-api-key, restart claude-api-proxy service
- Home Network card now fetches VPN status via vpn.status RPC
- Shows provider name (nostr-vpn, tailscale) instead of just "Connected"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:18:35 +01:00
Dorian
362bbb451f fix: add v1.3.4 What's New, fix VPN TS error
- Add v1.3.4 release notes: NostrVPN, FIPS/Routstr, ISO boot fix, bootstrap
- Remove unused i18n import from VpnStatusSection.vue (TS6133)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:05:56 +01:00
Dorian
0aefacf3b9 fix: restore FIPS as installable container app
FIPS stays in the marketplace as an installable container app.
NostrVPN is the native system service; FIPS is a separate optional app.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:51:13 +01:00
Dorian
324405006d feat: NostrVPN as native system service, remove FIPS
- Convert NostrVPN from container app to native systemd service
- Auto-configure VPN with node's Nostr identity after onboarding
- Add nostr-vpn.service with proper capabilities (NET_ADMIN, NET_RAW)
- Remove FIPS from marketplace, container config, nginx, image-versions
  (consolidated into NostrVPN — same mesh VPN concept)
- Add AIUI inclusion step to dev CI workflow
- AIUI installed on VPS build server for ISO inclusion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:49:34 +01:00
Dorian
e97fee2d7e feat: NostrVPN as native system service, Claude API key input, fix duplicate password
- Add NostrVPN as a native systemd service (extracted from container)
- Add VPN status detection for nostr-vpn in backend vpn.rs
- ISO build extracts nvpn binary from container image
- First-boot auto-configures NostrVPN with node's Nostr identity
- Change Claude Auth from login iframe to API key input field
- Remove duplicate ChangePasswordSection from Settings.vue
- FIPS and Routstr remain as installable container apps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:40:33 +01:00
Dorian
1989014dd5 feat: add Nostr VPN, FIPS, Routstr apps with status UIs
Add three new marketplace apps:
- Routstr (v0.4.3): Decentralized AI inference proxy with Cashu payments
- Nostr VPN (v0.3.4): Mesh VPN with Nostr signaling + WireGuard tunnels
- FIPS (v0.1.0): Self-organizing encrypted mesh network

Includes status UI dashboards for headless apps (nostr-vpn-ui, fips-ui)
with usage instructions, node identity display, and container logs.
Nostr identity injected via env vars for all three apps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 05:06:45 +01:00
Dorian
449f47da49 fix: BUILD_VERSION from Cargo.toml, kiosk scaling, new apps, Rust warnings
Critical:
- BUILD_VERSION was hardcoded as "1.3.0-alpha" — now reads from Cargo.toml
  This caused ALL ISOs to show v1.3.0 regardless of actual binary version

Kiosk:
- Remove --disable-gpu flags (broke display scaling on some monitors)
- Add --start-fullscreen --window-size for reliable fullscreen

New apps:
- Nostr VPN, FIPS, Routstr, noStrudel, BotFights, NWNN, 484 Kitchen,
  Call the Operator, Arch Presentation, Syntropy Institute, T-0

Rust: suppress dead_code and unused_assignments warnings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:35:52 +01:00
Dorian
09474789fd fix: FileBrowser default dirs, login option on onboarding intro
- Pre-create Documents/Photos/Music/Downloads/Builds dirs for FileBrowser
- Add "Already set up? Log in" link on onboarding intro page
- Prevents users from getting stuck in onboarding loop

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:33:28 +01:00
Dorian
81b4db82d1 fix: onboarding persistence, clipboard, install UI, OnlyOffice removal, UI containers
Onboarding:
- Persist current step in localStorage — page refresh resumes where user was
- Router afterEach saves step; guard redirects to saved step, not always intro
- Show npub alongside DID on restore success screen

UI fixes:
- Clipboard polyfill for HTTP contexts (fixes Copy DID crash on non-HTTPS)
- AppCard installing overlay shows for pkg.state=installing (survives refresh)
- Hide uninstall button during installation
- Frontend version bumped to 1.3.2

App store:
- OnlyOffice fully removed from marketplace, curated apps, app config
- Replaced with CryptPad references throughout
- Remove OnlyOffice from ISO capture patterns

Container stability:
- UI containers (bitcoin-ui, lnd-ui, electrs-ui) pull from registry first
- Added --cap-add FOWNER for rootless Podman compatibility
- electrs-ui now included in first-boot loop alongside bitcoin-ui and lnd-ui

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:20:52 +01:00
Dorian
42707c4276 fix: move companion indicator into sidebar, inline design
Move CompanionIndicator from global App.vue overlay to DashboardSidebar
next to ControllerIndicator. Redesigned as inline sidebar element with
Tailwind classes — shows muted 'Relay' when idle, orange 'Companion'
with pulse dot when actively receiving input.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:41:54 +01:00
Dorian
ae4791d438 fix: companion indicator shows relay state, add node-profile script
CompanionIndicator: show muted icon when relay connected but idle,
orange when companion actively sending input. Removes Transition
wrapper for always-visible relay status.

Add scripts/node-profile.sh utility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:14:34 +01:00
Dorian
94524e150a feat: frontend remote relay, kiosk hardening, CSS compositor fix
Frontend:
- Add remote-relay.ts: receives companion input via /ws/remote-relay,
  dispatches keyboard/mouse/scroll events into browser DOM
- Add CompanionIndicator.vue: NES gamepad icon when companion connected
- Wire relay start/stop to auth state in App.vue

Kiosk:
- Move Chromium data dir to /var/lib/archipelago/chromium-kiosk (encrypted)
- Disable MetricsReporting, AutofillServerCommunication, PasswordManager
- Remove --metrics-recording-only (contradicts disable-metrics)

CSS:
- Fix Chromium ghost rectangles: only apply preserve-3d + backface-visibility
  during transitions, not always-on (causes Chromium to skip painting
  off-viewport cards)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:10:08 +01:00
Dorian
479fbe0d21 fix: show Bitcoin as Loading when container running but RPC unavailable
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 23:35:27 +01:00
Dorian
04d272d8e0 fix: restore outer glass container on seed phrase pages
The outer page wrapper needs path-glass-container for the glass effect.
Only the inner text field grid should be without it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:18:32 +01:00
Dorian
b05f72f50f fix: revert to direct port access for app iframes
Proxy paths (/app/name/) break iframes due to root-relative asset
paths. Direct IP:port access works correctly over Tailscale and LAN.
This has been confirmed working on .228 via Tailscale DNS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:08:11 +01:00
Dorian
6b90ab9eb0 fix: always use nginx proxy paths for app iframes
Direct port access (http://host:port) fails over Tailscale/VPN and
when ports aren't externally accessible. Now all apps use nginx proxy
paths (/app/name/) on both HTTP and HTTPS.

Also adds missing proxy paths for btcpay, nextcloud, penpot, grafana,
indeedhub. Bumps version to 1.3.1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:43:01 +01:00
Dorian
24cc941b72 fix: redirect /kiosk to /dashboard instead of app grid
The old Kiosk.vue app grid launcher was never intended as the kiosk
display. Redirect /kiosk to /dashboard so the kiosk shows the actual
Archipelago interface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:11:32 +01:00
Dorian
6d3704fff5 fix: container DNS, nginx chown, onboarding guard, seed UX, install flow
Backend:
- Add --add-host host.containers.internal:host-gateway to LND and Bitcoin
  Knots containers (fixes DNS resolution failure in rootless podman)
- Add --user 0:0 and DAC_OVERRIDE to nginx UI sidecar containers
  (fixes chown crash in rootless podman for bitcoin-ui, electrs-ui, lnd-ui)
- Add hostadd to Rust Podman API client for web UI container installs
- Add Chromium privacy flags to kiosk launcher (disable telemetry)

Frontend:
- Fix onboarding reset on raw IP visits (trust localStorage as first-class
  signal, skip boot screen when server is up but not onboarded)
- Fix seed regression: persist challenge indices in sessionStorage so going
  back from Verify doesn't change which words are asked
- Remove glass container from seed Generate/Verify/Restore screens
- Add Back button to Restore from Seed screen
- Replace Network card: Tor (purple), VPN status (orange), Bitcoin sync (orange)
- Add ElectrumX to curated app list with correct .webp icon
- Install flow: navigate to My Apps immediately with toast, hide
  installed/installing apps from marketplace and discover views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:06:57 +01:00
Dorian
22609abd64 fix: LND crash in rootless podman, improve container status labels
LND v0.18+ crashes with "netlinkrib: address family not supported"
because rootless podman blocks netlink access for TLS cert SAN
enumeration. Fix: add tlsextraip=0.0.0.0 and tlsextradomain=lnd
to lnd.conf so LND skips interface enumeration.

Also: fix status label to show "crashed" for both exited and
stopped containers with non-zero exit codes (previously only
caught "exited" state, but podman reports "stopped" for
restart-looping containers).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:01:51 +01:00
Dorian
2d5866d486 fix: disable boot reconciler, fix onboarding loop, UI polish
Critical flow fixes:
- Disable boot reconciliation that auto-created ALL containers on
  unbundled installs (only FileBrowser should exist on first boot)
- Fix onboarding loop: RootRedirect no longer clears the
  neode_onboarding_complete flag on boot screen completion
- Seed phrase persists when navigating back (no regeneration)

UI fixes:
- Boot screen: removed github and save icons from animation loop
- Seed screens: viewport height scaling with 100dvh
- Seed restore: removed outer card container from word input grid
- Seed screens use distinct background (bg-intro-1.jpg)
- Install progress simplified to "Installing" button style
- Uninstall state moved to global store (persists across navigation)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:00:01 +01:00
Dorian
843d778f90 fix: container security hardening, onboarding viewport scaling, boot screen cleanup
Container security:
- Add --cap-drop ALL + --security-opt no-new-privileges:true to 12 containers
  missing hardening in first-boot-containers.sh (mempool-db, electrumx,
  mempool-api, mempool-web, electrs-ui, btcpay-db, nbxplorer, nostr-rs-relay,
  strfry, tailscale, bitcoin-ui, lnd-ui)
- Mirror same hardening in deploy-to-target.sh for consistency
- Add --read-only + tmpfs to nostr-rs-relay
- Fix filebrowser deploy to include security flags
- Remove duplicate UI image definitions in image-versions.sh
- Separate Jellyfin capabilities (needs FOWNER, exec tmpfs for CoreCLR JIT)
- Harden archy-net creation with existence check and error handling

UI fixes:
- Fix onboarding viewport scaling: all 7 screens now use h-full + max-h-full
  pattern so containers never overflow viewport regardless of padding
- Remove path-option-card wrappers from seed verify inputs, left-justify labels
- Remove batteries/barbarian icons from boot screen (keep bitcoin, cloud, github, save)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:35:34 +01:00
Dorian
4b0e1cfbe3 fix: CSRF race condition, UI containers, Tor ordering, seed layout
- session.rs: use OnceCell for remember_secret to prevent concurrent
  requests on first boot from generating different HMAC secrets, which
  caused CSRF token mismatch on every state-changing RPC call (app
  install, start, stop all failed with "CSRF token missing or invalid")

- install.rs: write lnd.conf with Bitcoin RPC credentials before LND
  container starts (prevents "bitcoin.mainnet must be specified" crash);
  inject Bitcoin RPC auth into bitcoin-ui nginx.conf; add proper error
  logging to UI container build/run steps; fix UI containers to use
  --network=host (they proxy to localhost backend/bitcoin RPC)

- Tor: remove After=tor.service from archipelago-tor-helper.path to
  break systemd ordering cycle that prevented Tor from starting on boot

- Seed screen: compact grid layout (2 cols mobile, 4 cols sm+) with
  tighter padding to fit kiosk displays without scrolling

- Dockerfiles: remove nonexistent assets/ COPY from bitcoin-ui, fix
  electrs-ui to COPY qrcode.js and EXPOSE 50002 (matches nginx.conf)

- image-versions.sh: add UI container image variables for registry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:06:19 +01:00
Dorian
030015fce6 fix: add missing tracing::warn import, hide QuickActionsCard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 08:44:08 +01:00
Dorian
64b57dca7d fix: overhaul container lifecycle — recovery, health, uninstall, UI state
Container recovery:
- Health monitor: MAX_RESTART_ATTEMPTS 3→10, interval 60s→120s
- Dependency-aware restarts: won't restart services before their deps
- Reset dependent counters when a dependency recovers
- Handle "created" state containers (were invisible to health monitor)
- Added IndeedHub, mempool-api, mysql to tier system
- Crash recovery: podman start timeout 30s→120s with retry
- Podman client: socket timeout 5s→30s, added restart policy

UI state representation:
- Exit code 0 shows "stopped" (gray), not "crashed" (red)
- Exit code 137 shows "killed (OOM)"
- Non-zero exit shows "crashed" (red)
- Added exit_code field to PackageDataEntry

Install/uninstall fixes:
- Install returns error when container doesn't start (was silent success)
- Post-install hooks awaited instead of fire-and-forget tokio::spawn
- Uninstall: graceful rm before force, volume prune, network cleanup
- Uninstall returns error on partial failure (was 200 OK)

Config consistency:
- DB passwords read from /var/lib/archipelago/secrets/ (was hardcoded)
- Bitcoin: added ZMQ ports 28332/28333 for LND block notifications
- IndeedHub port 7777→8190 (was conflicting with strfry)
- Marketplace versions: LND 0.17.4→0.18.4, Mempool 2.5.0→3.0.0

Performance:
- Metrics collector interval 60s→300s (was duplicating health monitor)
- Podman client: proper error propagation instead of unwrap_or_default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 07:03:57 +01:00
Dorian
f8ffc7f0a8 fix: increase package start/stop/uninstall RPC timeouts
Uninstall was timing out at 15s default while podman stop takes 30-600s.
Now: uninstall 120s, stop 120s, restart 120s, start 60s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 03:21:16 +01:00
Dorian
f162ff85db fix: guard fleet containers iteration, prevent TypeError on null
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 03:05:52 +01:00
Dorian
6c5e50b4d5 chore: hide Fleet tab from sidebar for beta
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:52:22 +01:00
Dorian
92a429535a perf: reduce CPU — Chromium GPU flags, healthcheck 30s to 120s, app card fixed height
- Chromium kiosk: add --disable-gpu-compositing, --disable-gpu-rasterization,
  --disable-software-rasterizer, --renderer-process-limit=1
  drops GPU process from 64% to 12% CPU
- Container healthchecks: 30s to 120s interval in first-boot and reconcile
- AppCard: min-height on description so cards dont shift

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:42:44 +01:00
Dorian
e6fe00d61d fix: add missing BitcoinFaceAscii.vue (CI build fix)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:05:44 +01:00
Dorian
a8292ab622 feat: BIP-39 master seed for unified key derivation
Replace fragmented random key generation with a single 24-word BIP-39
mnemonic that deterministically derives all node keys: Ed25519 (DID),
secp256k1 (Nostr/Bitcoin), BIP-84 xprv (Bitcoin Core), and LND aezeed
entropy. New onboarding flow: seed generate → word verification → identity
naming. Restore path enabled via 24-word entry. Includes seed RPC handlers,
mock backend support, LND/Bitcoin Core wallet-from-seed integration, and
UI polish across settings and discover views.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 01:41:24 +01:00
Dorian
6bd515cb82 feat: mobile UI overhaul — iPhone-style app grid, icon-only tab bar, fullscreen app sessions
- Add AppIconGrid: 4-column swipeable icon grid with page dots for My Apps on mobile
- Tab bar: remove text labels, square icon-only buttons (w-14 h-14), doubled padding
- Hide tab bar and top context tabs when app session is open
- App session header hidden on mobile, replaced with floating glass close button
- App sessions now render fullscreen on mobile without nav chrome

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:03:00 +01:00
Dorian
6fecf081a4 fix: AI Assistant placeholder text unreadable on background
Added glass-card backdrop, increased text opacity for readability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:41:59 +01:00
Dorian
27c9d33329 fix: all curated apps pull from registry, not Docker Hub
Every app in curatedApps.ts was hardcoded to docker.io/* instead of
our registry (80.71.235.15:3000/archipelago/*). This caused Bitcoin
Knots and all Discover tab installs to fail with pull errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:34:06 +01:00
Dorian
031b3c34f4 fix: container installs, Tor, kiosk, GRUB, LUKS display, error messages
Critical:
- fix: container installs fail with "statfs: no such file or directory"
  Root cause: NoNewPrivileges=yes in systemd blocks sudo inside backend.
  Fix: use std::fs::create_dir_all + podman unshare chown (no sudo needed)
- fix: Tor services.json never written — \$ARCHY_TOR_DIR escaping bug
- fix: kiosk white screen — increase health wait to 60s, add --disable-gpu

Improvements:
- feat: LUKS encryption badge in Server disk stats (backend detects dm-crypt)
- fix: GRUB theme text scaling on 4:3 monitors — explicit fonts, wider menu
- fix: suppress default Debian MOTD (custom profile.d welcome is enough)
- fix: install error messages now show "Failed to pull/start" instead of
  generic "Operation failed" (middleware.rs allowlist expanded)
- fix: container-tests CI — source cargo env before running tests
- docs: interactive container architecture diagram (HTML)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:35:06 +01:00
Dorian
5bd3caf141 fix: auth, container resilience, ISO build, gamepad polish
- fix: login disconnect — verify session before WebSocket connect
- fix: 403 on app install — distinguish CSRF vs RBAC errors, only retry CSRF
- fix: health monitor now watches ALL containers (removed skip list for
  backend services like nbxplorer, databases, UI containers)
- fix: server.get-state added to CSRF-exempt list (read-only)
- fix: ISO build includes container-specs.sh and lib/common.sh in rootfs
  so reconcile actually works on fresh installs
- fix: gamepad nav — improved Server tab zone nav, focus styles, autofocus
- chore: move L484 web-only apps to Services tab
- chore: install store for cross-view install tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:35:02 +01:00
Dorian
377195f7e0 feat: gamepad navigation for Mesh tab — zone-based panel nav
- Peer rows: tabindex + role=button + Enter handler for D-pad selection
- Zone attributes: mesh-left, mesh-chat, mesh-tools for cross-panel nav
- Actions row: data-controller-container for Up from peers
- Right from peers → chat input, Right from chat → tools tabs (wide)
- Down from tabs → panel fields/buttons in grid fashion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:24:48 +01:00
Dorian
9ea8877d20 fix: onboarding gamepad — autofocus, click sounds, focus styles
All screens:
- playNavSound('action') on every button click
- path-action-button orange focus glow (removed from suppression list)

Per-screen autofocus:
- Intro: CTA button (after animation)
- Path: Continue button
- Identity: name input
- Backup: passphrase input, Continue after download
- Verify: Sign Challenge, then Finish after verification
- Done: Set Password button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:52:09 +01:00
Dorian
1c82b8285e fix: vertical nav prefers closest element over widest overlap
Down from Identity name input now lands on Personal button (closest)
instead of Continue (wider overlap but further away).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:50:50 +01:00
Dorian
b773ba610f fix: backup screen — autofocus passphrase, rename button, focus Continue after download
- Passphrase input autofocused on mount
- "Download Backup" renamed to "Backup to Continue"
- Continue button autofocused after successful backup download

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:42:26 +01:00
Dorian
ff85754aa2 fix: onboarding autofocus — Continue button + Identity name input
- Path screen: Continue autofocused after 500ms (was 400ms, missed transition)
- Identity screen: name input autofocused on mount
- path-action-button now shows orange focus glow (removed from suppression list)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:38:47 +01:00
Dorian
ccad4737de fix: Continue button focus visible on onboarding Path screen
- Remove path-action-button from focus-visible suppression list
- Orange glow now shows on Continue when autofocused
- Bump autofocus delay to 500ms to clear slide transition

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:38:06 +01:00
Dorian
b214b2f52f fix: onboarding gamepad focus styles + sounds
- glass-button gets orange glow on focus-visible (was suppressed)
- Input fields get orange border on focus-visible
- Restore link made focusable (tabindex, role, keydown.enter)
- Gamepad nav sounds play via existing fallback handler

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:36:18 +01:00