aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* feat(cast): photos on the TV, and a television chosen once for the sessionChristophe Besson14 hours31-56/+1203
| | | | | | | | | | | | | | A cast button in Videos' toolbar, at the top of Photos, in an album's bar and in the lightbox, in a group and in Search alike. A television chosen there is kept for the session: a film opened plays on it with the player as its remote from the start, and a photo opened in the lightbox is shown on it, scaled to 1920x1080, upright, as JPEG. The lightbox gains a slideshow. The relay serves one photo at /image behind the stream's token, on the desktop and on Android; the shell, not the page, decides that the receiver loads it as a picture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(hub): music keep-alive outlasts a skipped trackChristophe Besson16 hours1-7/+15
| | | | | | | | Held while a track plays or loads and released 5 s late, so skipping a bad file with the screen off no longer drops the Android foreground service, which cannot be taken back from the background. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): music keeps playing with the screen offChristophe Besson17 hours12-22/+84
| | | | | | | | While a track plays, the page asks the shell to stay awake (playback:keep-alive): on Android the cast's foreground service and visible WebView, with a notification; on desktop a power save blocker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(hub): music player retries a track lost to a screen-off disconnectChristophe Besson17 hours1-3/+60
| | | | | | | | A transport failure while the page is hidden, or within 30 s of waking, keeps the track and its spinner and retries once the page or the connection is back, instead of skipping it with an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(android): music player starts on its own and no longer shows autoplay ↵Christophe Besson17 hours2-2/+7
| | | | | | | | | refusals WebView now allows play() after the track fetch; a NotAllowedError leaves the track waiting for the play button instead of raising an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: bump version to 0.18.0Christophe Besson2 days9-9/+9
| | | | Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(packaging): node and hub stop and clear their bytecode on removalChristophe Besson2 days4-2/+83
| | | | | | | | A node left running after removal recompiled bytecode into the shared venv, and meshbay-common's cleanup ran too late for the node and hub directories: dpkg warned that they were not empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Player: redesigned cast remoteChristophe Besson2 days14-74/+254
| | | | | | | Skip buttons with circular arrows, filled scrubber, large play/pause, device header; the remote is its own component. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Player: remote control while castingChristophe Besson2 days16-10/+296
| | | | | | | Shows the receiver's position with play/pause, ±30 s and a scrubber; a seek restarts the relay where asked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Cast: receiver position and pause/play on both clientsChristophe Besson2 days7-0/+102
| | | | | | | The player's remote mode reads where the television is instead of the local playhead, which drifts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: the Android clientChristophe Besson2 days3-9/+128
| | | | | | | | Design §11.3/§11.4/§15 state what is built and what the phone found; the user guide drops 'no Android client'; CLAUDE.md gains the package's locators and the lessons casting from a phone taught. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(android): cast context created at launch, session found if its callback ↵Christophe Besson2 days2-2/+28
| | | | | | | | | is missed As the SDK recommends; and a connected session the listener did not hear of still counts, so a missed callback no longer fails the cast. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(android): the cast header is everything before the first moofChristophe Besson2 days3-3/+74
| | | | | | | | The node's first chunk can be the 28-byte ftyp alone, the moov in the next; served as the header, the receiver had no moov and gave up. A receiver early for the header now waits for all of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(android): release builds signed with the debug key for nowChristophe Besson2 days1-1/+7
| | | | | | | Not debuggable, no WebView devtools, no console forwarding; installs over a debug build and back. A stand-in until the release key (Stage D12). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(android): the cast relay spools a receiver's lead to diskChristophe Besson2 days4-44/+143
| | | | | | | | Fragments are 5-10 MB at a film's bitrate; dropped past 8 MB in memory, the TV froze for their length. Each receiver now reads from its own spool file, deleted with it; nothing is dropped short of a disk bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): log what a cast does downstream of the relayChristophe Besson2 days2-3/+57
| | | | | | | | Fragments dropped for a slow receiver, writes that block, a periodic per-client summary, and every receiver state change with its position — the only trace a freeze on the television leaves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): the MeshBay iconChristophe Besson2 days10-0/+46
| | | | | | | The desktop client's icon in the adaptive icon's safe zone, over its own edge colour, so no launcher mask crops the M. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): the local player is silent while castingChristophe Besson2 days2-0/+33
| | | | | | | It keeps playing to pace the relay, so it doubled the television's sound. The viewer's mute setting comes back when the cast ends. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(android): cast relay serves a clean header and restarts on its portsChristophe Besson2 days5-12/+159
| | | | | | | | The init is what precedes the first moof; ports are reused like Node's; the SDK is read on the main thread; a cast that fails says why on screen, and success waits until the receiver actually plays. Never a VPN's address. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): a seek's first segments are held while it lands, not droppedChristophe Besson2 days3-3/+106
| | | | | | | | They are the new stream, header first. Dropped, a cast relay restarted at the landing got no ftyp/moov and the receiver gave up; they are now replayed in order once reinitAt/resumeAt is done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): casting through a LAN relay and the platform cast SDKChristophe Besson2 days17-35/+1176
| | | | | | | | A port of cast-relay.js (backlog also bounded in bytes), discovery and control with the default media receiver, relay calls kept in order, and a foreground service plus a WebView kept visible so a cast survives the screen going off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): downloads to disk and uploads through the system pickerChristophe Besson2 days10-11/+624
| | | | | | | | Native save over the Storage Access Framework and MediaStore, chunks sent as binary bridge messages, a chosen folder that has gone asks rather than redirects, unfinished files removed on abort and after a killed process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): a download written to disk no longer holds the whole fileChristophe Besson2 days2-0/+57
| | | | | | | pipelinedDownload kept every chunk's resolved promise until the end; a 2 GB download held 2 GB in the page. Each is released once read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): device key, bundle key and node identities held nativelyChristophe Besson2 days18-8/+1327
| | | | | | | | Keystore-wrapped store, a Kotlin port of keyring.js and transcripts.js held to the shared vectors, the same keys/device/secrets bridge as the desktop, and a native confirmation before browser access is widened. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): the node setup welcome is for a build that has a nodeChristophe Besson2 days2-1/+15
| | | | | | | Gated on capabilities.nodeAdmin rather than on any bridge, so a phone with no groups sees its invitations and the join link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(android): client shell with the interface from the packageChristophe Besson2 days26-0/+1560
| | | | | | | | WebView over the packaged UI (copied from hub/static at build time), the desktop CSP as a header, a bridge answering our top-level document only, hub calls from native to the signed-in hub. Keys stay in the page for now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(hub): shared keyring and transcript vectorsChristophe Besson2 days3-0/+716
| | | | | | | One file every bundle/transcript implementation must reproduce, generated from the desktop keyring; checked against it and against the specification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(design): rewrite §2 trust model human-first; formal model to §13.9Christophe Besson2 days1-139/+117
| | | | | | | | - §2 now describes who you trust in plain terms: no adversary grid, no red crosses - adversary table, claim matrix and refused over-claims move to §13.9 for auditors - repoint cross-references and the concordance to match Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(design): restructure §2.2 security claims into reading + matrixChristophe Besson2 days1-2/+81
| | | | | | | | - split structural truths, guarantees and accepted risks into named parts - add a focused comparison; native "detectable" -> "publicly verifiable" - keep the full claim matrix as an auditor reference Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Merge branch 'main' of meshbay.org:meshbayChristophe Besson3 days49-6142/+598
|\
| * refactor(mnp): remove ten operator messages no client sent0.17Christophe Besson3 days23-4402/+183
| | | | | | | | | | | | | | | | | | node_status, node_settings_set, roster_read, denylist_read, denylist_clear, node_reload and the signed gek_rotate, member_unpin, transfer_limits, group_detach leave MNP 6.0; the Node page and the CLI do this work over loopback. Their ops keep their tests, moved to the ops level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| * fix(client): no confirmation dialog for adding a folder or its flagsChristophe Besson3 days18-68/+15
| | | | | | | | | | | | | | Removes confirmFolder (addRoot, attachGroup) and the writable confirmation added in e4f6177, with their two catalogue keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| * feat(mnp): sharing a folder is decided on the node's machine only (MNP 6.0)Christophe Besson3 days39-1729/+457
| | | | | | | | | | | | | | | | | | | | root_add, root_update and group_attach leave MNP: adding a directory and switching writable/removable go through the loopback API (native dialog in the desktop app) or the CLI. The operator's Settings tab still lists the roots from any browser, read-only. The desktop app refuses to sign those ops; a loopback flag change now reaches open pages (publish_roots). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* | test(node): node.toml fixtures use POSIX paths, and a Windows-impossible ↵Christophe Besson3 days2-8/+13
|/ | | | | | | | | | | folder is skipped The root fixtures wrote `path = C:\Users\...`, which is not valid TOML: node_toml now reads values with tomllib, so the four tests failed on Windows. The node and the app always write paths with `/`, as the other fixtures do. A folder named with a quote and a newline cannot exist on Windows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(client): list cast receivers as they answerChristophe Besson3 days8-47/+215
| | | | | | | | The scan still runs six seconds, but the picker polls what it has found and shows each receiver immediately. A rescan no longer has its timer cut short by the scan it replaced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(packaging): an upgrade reloads every user's systemd and restarts a ↵Christophe Besson4 days2-1/+54
| | | | | | | | | | | | running node The node runs as a user service; the system-wide daemon-reload did not reach the user managers, so systemctl warned that the unit had changed and the old code kept running until restarted by hand. The deb postinst and the rpm %posttrans reload each running user manager and try-restart the node there (and any meshbay-node@ instance) on an upgrade. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(packaging): meshbay-common clears its compiled bytecode before an upgradeChristophe Besson4 days3-0/+41
| | | | | | | | | The postinst compiles __pycache__ directories the package does not own; on the next upgrade they kept dpkg from removing directories the new version no longer ships, and it warned. preinst/prerm (deb) and %pre/%preun (rpm) remove them first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(hub): wrap a docstring ruff flaggedChristophe Besson4 days1-3/+3
| | | | Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): rotating a group key asks nothingChristophe Besson4 days14-30/+8
| | | | | | | Rotation narrows rather than widens: members still connected receive the new key, and nothing already shared changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): hosting a group asks nothing when its folder came from the pickerChristophe Besson4 days12-15/+4
| | | | | | | The folder chosen in the native picker is the consent; the dialog that followed on every group creation asked the same thing twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(hub): a username is unique whatever its caseChristophe Besson4 days3-5/+38
| | | | | | | | Registration refuses a name that differs from an existing one only by case; accounts that already do keep their names, and a pending retry needs the exact name (F-26). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(hub): what an offer or a node message costs the hub is boundedChristophe Besson4 days4-26/+114
| | | | | | | | | An offer's IP-log row (kept a year) was written before any check, for any string named as a node; it is written once the offer goes to a node. The ICE list is capped (64 candidates, 32 KiB). A node's update_groups, a database read each, is budgeted like chat_notify and claims at most 1000 groups (F-22). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): the audit export never hands a spreadsheet a formulaChristophe Besson4 days3-5/+48
| | | | | | | A cell starting with = + - @ (or a tab or carriage return) gets a leading apostrophe; the export carries text members chose (F-29). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: remove a spike page served in production and an unused derivationChristophe Besson4 days5-454/+2
| | | | | | | | static/webrtc-test.html posted a raw password to /login from the hub's own origin; meshbay_common/keyderive.py derived keys from a password and nothing called it (F-32). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(node): the clear fields beside a chat message are boundedChristophe Besson4 days2-2/+48
| | | | | | | | sender_name and thread_id travel in clear beside the sealed envelope and were stored and relayed whatever their type and size. A name longer than a username or a thread id that is not a short id is now dropped (F-27). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(node): a member is told a media tool failed, not what ffmpeg saidChristophe Besson4 days4-3/+30
| | | | | | | | Stream, transcode and subtitle failures sent the exception's text — operator paths, versions — to the member. Fixed messages now, the cause in the log (F-24). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(node): the reaper deletes only the .part files the node wroteChristophe Besson4 days3-12/+37
| | | | | | | | Any *.part older than a day in a writable root was deleted — a browser's download in progress in a shared folder included. Only names carrying the node's tag (name.<8 hex>.part) are reaped now (F-28). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(node): a revoked account is disconnected, not only refused next timeChristophe Besson4 days3-15/+87
| | | | | | | | A user revocation closed nothing: the denylist stopped the next connection and left the live ones streaming and chatting. Revocations now go through one method that closes the account's or the group's sessions (F-21). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: an MBK2 bundle is opened once and stored again as MBK3Christophe Besson4 days8-31/+252
| | | | | | | | | | | | Transitional. The Argon2 run that makes M makes A, the key MBK2 bundles were sealed under; a session keeps it as a decrypt-only key (IndexedDB in a browser, the key storage in the desktop app). A client meeting an MBK2 bundle opens it — or its recovery copy — and stores the same identity as MBK3 once connected; the desktop app reseals or withdraws it as browser access says. A session without A asks for the passphrase once. Older formats stay refused by name. Replaces the unpin-and-reinvite step the 0.17 flag day required on every node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: chat at rest is protected from a copy without the unlock key, not from ↵Christophe Besson4 days2-5/+20
| | | | | | | | | | | a disk unlock.key sits beside keystore.enc by default, so a whole disk, an image or a home-directory backup opens the stored chat. The claims table, §4.5 and the user guide say so and name what protects those: disk encryption, or the unlock key on other storage (F-20). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>