Frontend store (mesh.ts):
- Add typed message interfaces: InvoiceData, AlertData, CoordinateData,
SessionStatus, AlertStatus, MeshMessageTypeLabel
- New actions: sendInvoice, sendCoordinate, sendAlert, getSessionStatus,
rotatePrekeys
Mesh.vue UI:
- Typed message rendering in chat bubbles:
- Invoice: orange card with sats amount, memo, bolt11 preview, paid badge
- Alert: red card (emergency/dead_man) or blue (status), signed badge,
GPS link to OpenStreetMap
- Coordinate: blue card with lat/lng, label, OSM map link
- Block header: purple inline with chain icon
- Session badge in chat header: green shield (Double Ratchet),
yellow (static encryption), gray (none)
- Session status fetched on peer selection via mesh.session-status RPC
Mock backend:
- Messages now include message_type and typed_payload fields
- Mix of text, invoice (paid + unpaid), alert (emergency + status),
coordinate, and block_header messages for testing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bitcoin relay (mesh/bitcoin_relay.rs):
- BlockHeaderCache: stores latest block headers from internet peers for SPV
- RelayTracker: tracks in-flight TX and Lightning relay requests
- Builder functions: block header announcements (Ed25519 signed),
TX relay request/response, Lightning invoice relay/response
- All amounts as u64 sats, never float
- 4 unit tests
Emergency alerts (mesh/alerts.rs):
- AlertConfig: dead man switch settings, GPS, emergency contacts
- DeadManSwitch: background timer, auto-trigger after configurable interval
(default 6h), signed alert broadcast with GPS coordinates
- check_in() resets timer, is_triggered() checks elapsed time
- GPS as integer microdegrees (Coordinate type from message_types)
- Disk persistence for config
- 4 unit tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend (6 new RPC endpoints):
- mesh.send-invoice: create Lightning invoice, send bolt11 to mesh peer
- mesh.send-coordinate: send GPS coordinates (integer microdegrees)
- mesh.send-alert: send signed emergency alert (with optional GPS)
- mesh.outbox: list pending store-and-forward messages
- mesh.session-status: get Double Ratchet session info per peer
- mesh.rotate-prekeys: force X3DH prekey rotation
Mock backend: matching dev mode responses for all 6 new endpoints
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create mesh/session.rs: SessionManager for Double Ratchet state lifecycle
- Lazy-loads sessions from disk on first message
- Saves after every encrypt/decrypt (chain key advancement)
- Per-DID storage at {data_dir}/ratchet/{sha256(did)}.json
- Session info API for RPC status reporting
- Zeroize on drop for all key material
- Tests: store+load roundtrip, encrypt/decrypt through manager, session removal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Federation: 3 federated nodes with full state snapshots (apps, CPU, disk, uptime)
- Federation invite/join/sync/set-trust/remove/deploy-app mock handlers
- DWN status with 3 protocols, message counts, sync state
- Enables testing Federation.vue and Web5.vue in local dev mode
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add off-grid (mesh only) toggle to Mesh.vue with orange OFF-GRID banner
- Add per-peer transport indicator in Federation.vue (mesh/lan/tor icons)
- Add sync_with_peer_via_transport() for CBOR delta sync via transport router
- Fetch transport store on mount in both Mesh and Federation views
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve stash conflicts in Cargo.toml, rpc/mod.rs, AppDetails.vue, Apps.vue
- Fix ScopedIp conversion in LAN transport (mdns-sd compatibility)
- Fix String vs &str in transport RPC send handler
- Remove duplicate mod transport declaration
- Remove stale mesh.discover route (replaced by mesh.peers/messages/send)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Private repo needs auth — pass GITEA_TOKEN as env var in Portainer,
never hardcoded. Or make the repo public to skip auth entirely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
No submodule needed — the Dockerfile clones the IndeedHub repo
directly during build. Works with Portainer without any manual steps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
IndeedHub source included as git submodule at ./indeedhub/.
Demo compose builds all services from source — no registry needed.
Stack: app, api, postgres, redis, minio, relay.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Just pull git.tx1138.com/lfg2025/indeedhub:latest directly.
No source build, no backend stack needed for demo.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full 8-service IndeedHub stack: app (frontend), api (NestJS), postgres,
redis, minio (S3), minio-init, ffmpeg-worker, nostr-relay.
All env vars have sensible defaults for demo — override in Portainer
env vars for production. IndeedHub builds from ../Indeedhub Prototype
source. Frontend on port 7777 with NIP-07 nostr-provider.js for
signing via Archipelago's identity system.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The toggle handler only tried `podman restart archy-tor` which fails
on servers running Tor as a systemd service. Now tries
`systemctl restart tor` first (like the rotation handler already does),
falling back to container restart.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Every enabled Tor service now shows a Rotate button that instantly
creates a new .onion address and decommissions the old one. Previously
only the main 'archipelago' service had this button.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix .onion address overflow: add min-width:0 to flex children
- Reduce field font size for long addresses
- Auto-select Local Network mode when Tor unavailable
- Fix Tor hidden service paths on Arch 1/3 (was /var/lib/tor/,
backend reads /var/lib/archipelago/tor/)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When tor_onion is null in the connect info response, automatically
switch dropdown to "REST (Local Network)" and show a helpful message
instead of "Tor not configured for LND" error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- fetchConnectInfo: use window.location.protocol instead of hardcoded http://
- getBackendUrl: default to current origin when no ?backend= param
- Fixes mixed content errors on HTTPS Tailscale servers
- Also fixed: nginx needed reload on Tailscale servers, Arch 2 missing
/lnd-connect-info nginx location
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- LND UI: replace cdn.tailwindcss.com with local tailwind.css (CSP fix)
- LND UI: make asset paths relative for nginx proxy compatibility
- Web5 wallet: add QR code for on-chain receive addresses (qrcode npm)
- Web5 wallet: hide incoming transactions after 3 confirmations
- Apps: add "Services" tab to separate backend containers from user apps
- Home: null guard on packages.value to prevent TypeError on load
- First-boot: auto-create Bitcoin Knots wallet (no longer auto-created)
- AppSession: add mempool-electrs to port mapping
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added YAML frontmatter to all 8 polish-* skills and sweep skill
so Claude can auto-invoke them
- New bitcoin-conventions skill with PROUX UX methodology, sats display,
address validation, Tor preferences, Lightning patterns
- Path-specific rules for containers (security hardening) and frontend
(Vue/glassmorphism conventions)
- Gitea Actions: nightly security review and weekly dependency audit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All code changes deployed and verified. Frontend type-check passes
(0 errors), all 515 tests pass, backend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- system.factory-reset RPC: wipes user data, preserves images/node_key
- Factory Reset button in Settings with confirmation modal
- backup.restore-identity RPC: decrypts and restores DID key
- Restore from Backup panel in OnboardingIntro first screen
- Auto-create default identity with Nostr key on boot if none exist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Unmatched URLs now show a glass-card 404 page with a link back
to the dashboard instead of a blank page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated appLauncher tests to match current session-based routing.
Fixed settings test to use h2 instead of h1. Fixed RPC client test
to expect 'Session expired' on 401.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rate limiters correctly use monotonic Instant. Session TTL uses
SystemTime for wall-clock accuracy across sleep/hibernate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed unused sync podman_command/docker_command methods.
Removed dead_code annotations from User and AuthManager (now actively used).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Check user role against method permissions before dispatch.
All current users default to Admin, laying groundwork for multi-user.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instant is monotonic but drifts on sleep/hibernate common on NUC
hardware. SystemTime gives proper wall-clock expiry for sessions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
IndeedHub running on port 7777, nostr-provider.js injected,
NIP-07 identity flow wired, NIP-04/NIP-44 RPC handlers in place.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>