- Remove unused _restartApp in Apps.vue
- Remove unused version computed in Home.vue
- Remove unused filteredCommunityApps in Marketplace.vue
- All metrics clean: 0 type errors, 0 build warnings, 515/515 tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
515 tests across 38 files. Branch coverage 88%, function coverage 83%
on testable logic (stores, composables, api, utils, services, router).
New test files: websocket, useLoginSounds, useMobileBackButton,
useControllerNav, routes. Extended: rpc-client (99.5%), container store
(100%). Fixed: useNavSounds AudioContext mock, type errors across tests.
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>
Webhook module with HTTP delivery, HMAC-SHA256 signing, and event
filtering. RPC handlers for get-config, configure, and test endpoints.
Settings page gains webhook configuration section with URL, secret,
event toggles, and test button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Server.vue: Add loading/disabled state to WiFi connect button,
success toast on WiFi connection
- Credentials.vue: Disable verify button when input empty, add
disabled styles
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Server.vue: Add user feedback for disk cleanup and restart operations
- Credentials.vue: Add clipboard fallback, better identity load error handling
- Federation.vue: Add clipboard fallback for invite code copy
- ContainerApps.vue: Wrap polling intervals in try-catch to prevent
unhandled promise rejections from background refresh
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All 30 UX audit findings verified resolved. Added the last missing
loading indicator for Cloud.vue file count fetching. All P0, P1, and P2
items from docs/ux-audit-2026-03.md are now addressed across Login,
Home, Apps, Server, Chat, Federation, Credentials, Settings, Marketplace,
Web5, SystemUpdate, and Cloud views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Every empty/comment-only catch block now logs a descriptive warning
in dev mode via `if (import.meta.env.DEV) console.warn(...)`. Covers
15 files across views, stores, components, and utils. Zero silent
catches remaining.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Double-submit cookie pattern: backend generates csrf_token cookie on login
(non-HttpOnly so JS can read it), validates X-CSRF-Token header matches
cookie on all authenticated RPC calls. Returns 403 if missing/mismatched.
Frontend reads cookie and sends header automatically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows detected physical interfaces (ethernet/wifi) with IP, MAC, and
status. WiFi scan button opens a modal with signal strength bars and
password-protected connection flow. Uses network.list-interfaces and
network.scan-wifi RPC endpoints.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full-width card with color-coded progress bars (green <70%, orange
70-90%, red >90%) and uptime display. Calls system.stats RPC on
mount and refreshes every 30s. Deployed and verified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Web3 card showed hardcoded values (3 active, Valid, 2.4 GB, 1
configured) for features that don't exist yet. Replace with subtle
"Coming Soon" pill badges to avoid misleading users.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded values with live data from network.diagnostics and
router.list-forwards RPC calls. Add skeleton loading states and
graceful N/A fallbacks when endpoints are unavailable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
express.json() middleware was consuming the binary file body before the
upload handler could drain it, causing 404/parse errors on file uploads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The entrypoint now injects client_max_body_size 0 at runtime if missing,
as a safety net against Docker layer caching of the nginx config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Location-level override wasn't sufficient. Setting at http block
disables the body size limit globally for the demo.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Onboarding:
- Fixed viewport to use dvh units with position:fixed container
- All views use scrollable glass containers that fit within viewport
- Responsive typography and spacing (mobile-first breakpoints)
- Tighter padding/margins on small screens
- RootRedirect checks localStorage first for instant redirect
- Spinner only appears after 500ms delay to avoid flash
Filebrowser:
- Fix CloudFolder null initialPath crash (watch both useNativeUI + section)
- Remove unused `host` computed (was causing TS error)
- Add mock GET /app/filebrowser/ landing page
- Increase express.json limit to 50mb
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mock backend lan-address now uses localhost so hostname replacement works
correctly. CloudFolder external URLs use origin-relative proxy paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The My Apps page went blank after installing apps because pkg['static-files'].icon
was accessed without optional chaining on dynamically installed packages that lack
the static-files property.
- Make static-files optional in PackageDataEntry type
- Add defensive ?.icon access with fallback in Apps.vue and AppDetails.vue
- Add filebrowser to mock backend staticDevApps (enables Cloud page in demo)
- Expand portMappings and marketplaceMetadata for all marketplace apps
- installPackage now uses staticApp() format for consistent data shape
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes "Method not found: identity.create" on demo onboarding. Adds handlers
for all identity, nostr, content, network, router, and peer RPC methods so
no method-not-found errors occur anywhere in the demo. Expands marketplace
from 2 to 12 apps, adds 5 static dashboard apps, randomizes metrics, and
populates peer/message data for a richer demo experience.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set http1_keep_alive(false) on hyper server to prevent connection
reuse issues with nginx reverse proxy
- Clean up nginx proxy config: remove upstream block, use direct
proxy_pass to 127.0.0.1:5678
- Update AppLauncherOverlay and appLauncher store with UI fixes
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>
Apps with absolute-path redirects (Jellyfin, Portainer, PhotoPrism,
OnlyOffice, Uptime Kuma, Fedimint) now correctly open in new tab on
HTTPS where subpath proxy breaks their redirects, but still use iframe
on HTTP where direct port access works fine.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added searxng, onlyoffice, filebrowser, nginx-proxy-manager, portainer,
and tailscale to first-boot-containers.sh so fresh ISO installs have all
marketplace apps ready. Fixed penpot icon path in Marketplace.vue to use
the correct app-icons directory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add electrs to marketplace as standalone installable app
- Add dependency check: refuse install if no bitcoin node is running
- Use container DNS (bitcoin-knots:8332) on archy-net instead of host IP
- Auto-create bitcoin.conf with txindex + RPC on bitcoin-knots install
- Auto-build and start electrs-ui container post-install
- Show index size and estimated progress during initial sync
- Add /electrs-status and /health nginx proxy routes
- Remove Tailwind CDN from electrs-ui, use inline styles
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create Ollama provider plugin in AIUI (ollama-provider.ts)
- Register Ollama alongside Claude in plugin system
- Auto-detect installed models via /api/tags endpoint
- Add Ollama proxy in mock backend (forwards to localhost:11434)
- Add nginx proxy rules for /aiui/api/ollama/ (both HTTP and HTTPS)
- Rebuild AIUI dist with Ollama provider included
- Qwen 2.5 Coder 3B installed on dev server via Ollama
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove webSearch, webResults, context fields before forwarding to
Anthropic API — these are AIUI-internal and cause 400 errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Exclude assets/icon/** from workbox globPatterns (already in includeAssets)
- Remove duplicate /api/* and /aiui/api/web-search routes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add /api/web-search stub returning empty results in demo mode
- Add /aiui/api/* catch-all returning JSON 404 instead of HTML fallback
- Fix nginx proxy to catch all /api/ routes (not just /aiui/api/web-search)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Inject max_tokens: 4096 in Claude API proxy when AIUI omits it
- Add /aiui/api/web-search stub returning empty results (no search backend in demo)
- Add nginx proxy rule for web-search endpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Claude API proxy in mock-backend.js (reads ANTHROPIC_API_KEY from env)
- Supports SSE streaming via pipe
- Move ANTHROPIC_API_KEY to backend service in docker-compose.demo.yml
- Remove envsubst from entrypoint (no longer needed)
- nginx-demo.conf proxies /aiui/api/claude/ to backend
This fixes the 401 error when Portainer doesn't pass env vars to
nginx correctly — the Node.js backend reads process.env directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>