<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-hub/tests/harness, branch 0.18</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.18</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.18'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-10-05T11:13:54Z</updated>
<entry>
<title>feat(hub): say "N groups unreachable" on Search for a few seconds, not for good</title>
<updated>2026-10-05T11:13:54Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-05T11:13:54Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=92b7afcb186d7aaf475939d58a0385f408425eeb'/>
<id>urn:sha1:92b7afcb186d7aaf475939d58a0385f408425eeb</id>
<content type='text'>
The line sat above the results for as long as the page was open. It is now
said once a cross-group pass is over, for five seconds, in the same passing
note as "Link copied" — moved out of copy-link.js into note.js (`say(text,
ms)`), one note at a time for the whole page. The `.search-unreachable` rule
goes with the line it styled.

The copy-link probe now also checks in Chrome that the note goes by itself.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>test(hub): join from an invitation link and land under the group's handle</title>
<updated>2026-10-05T10:53:48Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-05T10:53:48Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=97fa4cf78a826050b9d1df0b484a7794861cda80'/>
<id>urn:sha1:97fa4cf78a826050b9d1df0b484a7794861cda80</id>
<content type='text'>
The invitation probe listed no groups, so after Join the address stayed the
#/group/&lt;id&gt; the button navigated to and the group links' rewrite to
#/name@owner was never exercised on that path. A third case has the hub list
the group once joined, as it does: the group page opens, the address shows
the handle without a history entry of its own, and the code still never
reaches the hub.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: copy a file's or folder's #/name@owner link from Files, Music, Photos and Search</title>
<updated>2026-10-05T10:23:18Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-05T10:23:18Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=1d94a92936abb3d37a8f9bfb36c8850246fee15d'/>
<id>urn:sha1:1d94a92936abb3d37a8f9bfb36c8850246fee15d</id>
<content type='text'>
"Copy link" puts the address group-link.js resolves on the clipboard, on the
hub's origin rather than the page's, so a link copied in the desktop
application is not app://meshbay. Files offers it for one row, from the
right-click menu or the toolbar with one row ticked (a phone's way in);
Music on one track's menu, whose dots a phone has; Photos on a right-clicked
tile and in the lightbox's bar. The video player and the file preview carry
a link button next to Download.

Applications get a `linkFor(entry | folderPath)` prop (MESHBAY_DESIGN.md
§9.2) and offer the action only when it names a link. The group page builds
it from the hub's row; Search from each result's own group and its path
before the merged views prefixed it, and names no link for a folder of the
merged tree, which a group name alone does not identify.

harness/copy_link_probe.py mounts the three applications in Chrome and reads
what reached the clipboard.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: open a group, a folder or a file from a #/name@owner link</title>
<updated>2026-10-05T09:53:57Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-05T09:53:57Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=8f25294b0f6bc3f292442edd69a2e149f0717b52'/>
<id>urn:sha1:8f25294b0f6bc3f292442edd69a2e149f0717b52</id>
<content type='text'>
A group can now be reached by the handle shown under its name, and a path
after it points inside the group: #/name@owner/root/dir/file downloads the
file and opens Files on its folder; a folder opens Files there. The handle
is resolved in the client against the account's own /v1/groups/mine, so no
hub route answers for a name and nobody can probe for one. While a group is
open the address shows the handle (replace, no history entry); a linked path
is taken out of the address once acted on, so a reload does not download
twice.

Signing in no longer sends everyone home: the form stood in for the page the
address named, and that is where a link opened signed out was going.

group-link.js holds the parsing and lookups, executed whole by
test_group_link.py; harness/group_link_probe.py drives the router in Chrome.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(cast): music on the TV, the music bar as its remote</title>
<updated>2026-10-05T00:29:27Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-05T00:29:27Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=ee9798fe3b88face2fa34f14874770f509c788a5'/>
<id>urn:sha1:ee9798fe3b88face2fa34f14874770f509c788a5</id>
<content type='text'>
A cast button in Music's toolbar and in the music bar. With a television
chosen, each decrypted track goes to the relay with its cover — found as the
album card finds it — and plays there as music with its title, artist and
album; the bar's play, pause, seek, previous and next drive the receiver, its
clock is the receiver's, and the end of a track there moves the queue on.
A film or a photo taking the television pauses the bar; stopping the cast
carries the track on locally.

Photos and tracks now share one path: a whole file sent to the relay in
pieces (binary frames on Android, written to disk there), served at /file
with byte ranges and its cover at /cover, and loaded as what the relay says
it is. cast:image is gone; cast:chromecast:seek is new.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(cast): photos on the TV, and a television chosen once for the session</title>
<updated>2026-10-04T23:16:12Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-04T23:16:12Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=243bcf017b4957237b3ddf556bd0a37296eb8798'/>
<id>urn:sha1:243bcf017b4957237b3ddf556bd0a37296eb8798</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(client): a seek's first segments are held while it lands, not dropped</title>
<updated>2026-10-03T12:24:54Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-03T08:29:59Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=f73476d71f9b7268650c257db0eed3ab49b94849'/>
<id>urn:sha1:f73476d71f9b7268650c257db0eed3ab49b94849</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix: an identity signs a named kind, and a device approval answers a request</title>
<updated>2026-09-30T19:04:39Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T19:04:39Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=0378e8e0912a1a7e6cea4424e69d524e7afecbf8'/>
<id>urn:sha1:0378e8e0912a1a7e6cea4424e69d524e7afecbf8</id>
<content type='text'>
The desktop main process builds every transcript itself from fields
(transcripts.js) and signs no raw bytes; the page's identity has the same
contract (crypto.js transcriptFor). The keyring seals no bundle while browser
access is off. On the node, device_add must redeem a pending request filed by
the same keys, and device_revoke is signed under its own prefix
(meshbay:device_revoke:v1), so a retirement signature admits nothing.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(client): the desktop application keeps M and every node identity in its main process</title>
<updated>2026-09-30T14:58:31Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T14:58:31Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=6d167392f6f8ede37e2794a68a3738f8ba03131d'/>
<id>urn:sha1:6d167392f6f8ede37e2794a68a3738f8ba03131d</id>
<content type='text'>
keyring.js derives, opens, mints, seals, signs and agrees there; the page gets
public keys and a handle. Argon2 comes from the page's own WebAssembly build
(Electron's crypto has none). Without OS key storage the page keeps its keys as
a browser does. A node's bundle is settled after connecting, re-sealed when the
key changed.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor(hub): the transport holds an identity, never a private key</title>
<updated>2026-09-30T13:48:51Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T13:48:51Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=8926f163dad9d32dc06c3a142658a4e11d9c12c1'/>
<id>urn:sha1:8926f163dad9d32dc06c3a142658a4e11d9c12c1</id>
<content type='text'>
Two public keys, sign() and shared(); the apps take transport.signFn. What
holds the keys (this page, or the desktop main process) is the identity's
business alone.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
