Translate one tournament alert locally with QVAC, then deliver the bilingual update directly to joined peers through PearRuntime and Hyperswarm—without an application server.
Touchline Relay is a desktop matchday tool for grassroots football tournaments. An organizer writes a short operational update, translates it on-device with QVAC Bergamot (English → Spanish, French, German, or Portuguese), previews both versions, and publishes a structured announcement to a shared room. A second app instance receives it over Hyperswarm and keeps it in local history.
Tournament updates often get lost across WhatsApp, email, and team apps. When a pitch changes or check-in moves, late or fragmented messages cost volunteers and teams real time. Touchline Relay keeps one critical action: compose → translate locally → publish to reachable peers.
| Layer | Technology | Role |
|---|---|---|
| Local AI | QVAC SDK + Bergamot EN→ES/FR/DE/PT | On-device translation on the organizer’s machine |
| Desktop shell | Electron (Forge package) | UI + main-process QVAC lifecycle |
| P2P runtime | PearRuntime / Bare worker | Owns Hyperswarm membership and relay |
| Networking | Hyperswarm | Direct peer delivery of structured announcements |
There is no cloud translation API, application server, account system, wallet, or general chat feed.
- Translation runs locally after the Bergamot model is cached.
- Messages travel directly between reachable peers.
- Peer discovery still requires network reachability (Hyperswarm bootstrap / DHT). This is not claimed as fully offline LAN messaging.
- 3-minute voiceover + shot list:
docs/demo-script.md - Submission paste pack:
docs/submission-draft.md - What we cut:
docs/roadmap.md
- Launch two instances with separate
--storagepaths. - Join the same room name on both.
- Wait until each shows 1 peer.
- On the organizer: set venue + priority, write an English alert, click Translate locally.
- Confirm Spanish preview and Publish to room.
- On the receiver: the bilingual structured announcement appears in Announcements.
- Linux x64 recommended for the verified package path (this repo also carries macOS/Windows packaging config from the Pear Electron starter).
- Node.js 20+ and npm.
- Network access for first-time dependency install and QVAC model download/cache.
- A display (or Xvfb) to run the Electron UI.
git clone https://github.com/ShalyX/touchline-relay.git
cd touchline-relay
npm installIf Electron fails to install:
rm -rf node_modules/electron
npm rebuild electronIf you see:
Error: Cannot find addon '.' ... rocksdb-native
that almost always means a broken/partial npm install (e.g. earlier ENOSPC) or native modules not rebuilt for Electron.
# 1) Free disk first (need ~10GB free)
Get-PSDrive C
# 2) Clean install
cd C:\Users\USER\touchline-relay
git pull
Remove-Item -Recurse -Force node_modules -ErrorAction SilentlyContinue
Remove-Item -Force package-lock.json -ErrorAction SilentlyContinue
npm cache clean --force
npm install
# 3) Rebuild natives for this Electron version
npx --yes @electron/rebuild -f
# 4) Confirm the Windows prebuild exists and is non-empty
Get-Item .\node_modules\rocksdb-native\prebuilds\win32-x64\*.node | Format-Table Name,Length
# 5) Start two peers
npm start -- --storage .\demo-a
# second terminal:
npm start -- --storage .\demo-bIf rebuild fails, install Visual C++ Redistributable x64 and retry npx @electron/rebuild -f.
Development:
npm start -- --storage /tmp/touchline-aSecond peer (required for the demo; custom storage bypasses the single-instance lock):
npm start -- --storage /tmp/touchline-bRoot / hermesbox (this machine runs as root):
# always pass --no-sandbox as root (also baked into npm start)
npm start -- --storage /tmp/touchline-a
# no display / SSH headless:
xvfb-run -a npm start -- --storage /tmp/touchline-aDemo helpers:
npm run start:demo-a
npm run start:demo-bOptional Chromium remote debugging (used by automated QA):
npm start -- --storage /tmp/touchline-a --remote-debugging-port 9222This is a desktop app, not a website. Users install/run it on their machine (organizer laptop, ops desk, second peer device).
git clone https://github.com/ShalyX/touchline-relay.git
cd touchline-relay
npm install
npm start -- --storage ./data-organizerAnother peer (second machine or second terminal):
npm start -- --storage ./data-peerJoin the same room key on both. Translate on the organizer. The peer receives the bilingual alert.
npm run package
# Linux:
# out/Touchline Relay-linux-x64/Touchline RelayZip that folder (or build installers later) and hand it to users. No account, no cloud API key, no app server.
- Not “terminal only forever” — Electron is a normal desktop UI.
- Not “offline guaranteed” — peer discovery still needs network reachability.
- Not multi-tenant SaaS — there is no hosted production URL in this MVP.
Static design preview (populated mock, not live network): open renderer/index.html?demo=1 in a browser.
npm test
npm run lint
npm run qvac:smoke
npm run packageThis repository's pilot task is dkt-8eaed55e224940e4ae9edbe1 on the Docket Studio Devnet contract 0x729C8B0451Cc42Cc4abdF9b5ba468ce14eF79057. The agreement and its weighted acceptance criteria are frozen in the root docket.yml; changing that file after registration invalidates the evidence hash.
Every public pull request runs .github/workflows/docket-evidence.yml. The workflow checks out the immutable PR head, runs the vendored dependency-free action in .docket/github-action, and writes two JSON objects to the successful run's job summary:
- Open the pull request's successful Docket evidence workflow run.
- Open its job summary and copy both the Manifest and Proof JSON objects.
- Open the matching case in Docket. Connect the assigned worker wallet, paste both objects into Submit delivery, and sign the transaction.
- The browser checks the proof against the onchain task and submits only the compact public manifest. Docket independently fetches the public PR, commit, workflow run, and frozen
docket.ymlif adjudication is needed.
The workflow uses a read-only checkout token and does not post comments, upload artifacts, call an external API, or submit an onchain transaction. Keep credentials, private issue data, customer data, and raw logs out of the public Docket configuration and evidence.
What those mean:
npm test— protocol, renderer state, instance policy, QVAC translator unit tests, and a two-peer Hyperswarm structured-announcement integration test.npm run qvac:smoke— real local Bergamot EN→ES translation via@qvac/sdk.npm run package— Electron Forge package plus a postPackage hook that restores the unstripped QVAC native prebuild (Forge otherwise truncates the Vulkan shared library).
Packaged Linux app:
out/Touchline Relay-linux-x64/Touchline Relay
┌──────────────────────────────┐
│ Renderer (vanilla HTML/CSS/JS)│
│ room · compose · preview · UI │
└──────────────┬───────────────┘
│ preload bridge
┌──────────────▼───────────────┐
│ Electron main │
│ QVAC load/translate/unload │
│ PearRuntime.run(worker) │
└──────────────┬───────────────┘
│ framed IPC
┌──────────────▼───────────────┐
│ Bare worker (PearRuntime) │
│ Hyperswarm room join/publish │
│ structured NDJSON wire msgs │
└──────────────────────────────┘
Key source:
electron/main.js— window, QVAC IPC, Pear worker lifecycle, multi-instance policylib/qvac-translator.js— official Bergamot EN→ES pathlib/protocol.js— room key, validation, wire format, duplicate filterworkers/main.js+workers/relay-node.js— Pear/Bare relayrenderer/— editorial desktop UI (“Crossing the line” mark, proof drawer)
Independently verified on Linux x64:
- 16/16 automated tests pass.
- Lint exits 0 (existing
require-awaitwarnings only). - QVAC smoke produces real Spanish output.
- Packaging preserves QVAC native library byte-for-byte vs
node_modules. - Two Electron instances with separate storage:
- join the same room and see 1 peer each
- organizer translates with local QVAC Bergamot
- receiver history shows English + Spanish structured announcement
- publisher records local relay acceptance only (not universal delivery)
Example translated line from live UI QA:
Kickoff se traslada a Pitch 2 a las 14:30. Reúnase en la puerta norte.
Bergamot quality is operational, not human-editor grade. Venue tags stay structured so names remain unambiguous.
- Leave room without restarting the app
- Peer receipt ACKs (connected peers only — not universal delivery)
- Target languages: Spanish, French, German, Portuguese (QVAC Bergamot EN→*)
- Installer notes:
scripts/make-release-notes.mdanddocs/roadmap.md
- English → Spanish only in MVP.
- No leave-room beyond process restart in MVP.
- No end-to-end delivery receipts from every peer—only local relay acceptance + observed peer receive.
- First model download can take time; keep the demo script ready for a cached model.
- Packaging fix is especially important on Linux x64 for
@qvac/translation-nmtcpp.
MIT. Bootstrapped from the official holepunchto/hello-pear-electron starter architecture, then rebuilt for Touchline Relay.
docs/decision.md— concept selectiondocs/design-brief.md— UI specificationdocs/submission-draft.md— DoraHacks paste-ready copy