From 382fcc5f675f9942350013780335315757c245c5 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 15 Oct 2026 01:12:16 +0200 Subject: feat(cli): rm, and Delete in the interactive mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rm deletes files, resolved as get resolves paths and patterns, with the node's rule (design §5.4): the uploading account's devices, or the node's operator account. The whole run is checked against the index first (the entry's uploader_id, the role the join result gives this key): a file outside the rule, or a folder, refuses it before anything is asked or sent. Then one confirmation, or --yes. The node's challenge is checked against what was asked before it is signed. In the interactive mode, Delete on the right pane does the same, asked once per batch. Co-Authored-By: Claude Opus 5.5 --- packages/meshbay-cli/src/meshbay_cli/client/session.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'packages/meshbay-cli/src/meshbay_cli/client/session.py') diff --git a/packages/meshbay-cli/src/meshbay_cli/client/session.py b/packages/meshbay-cli/src/meshbay_cli/client/session.py index d5264a2..41bf0d6 100644 --- a/packages/meshbay-cli/src/meshbay_cli/client/session.py +++ b/packages/meshbay-cli/src/meshbay_cli/client/session.py @@ -197,7 +197,8 @@ class GroupSession: def __init__(self, pc: RTCPeerConnection, ch: Channel, group_id: str, node_id: str, node_pk: str, gek: bytes, ack: dict, - identity: Identity | None = None, nonce_node: bytes = b""): + identity: Identity | None = None, nonce_node: bytes = b"", + role: str = ""): self.pc = pc self.ch = ch self.group_id = group_id @@ -209,6 +210,10 @@ class GroupSession: # and the nonce that ties a signature to this connection. self.identity = identity self.nonce_node = nonce_node + # What the node's roster says this key is here: "operator" when it was + # paired with the node — the authority to delete anyone's file. Not the + # hub's word on who owns the group (docs/MESHBAY_DESIGN.md §3.3). + self.role = role async def index(self) -> dict: """`{version, entries, dirs, roots}`, opened under the group key.""" @@ -351,7 +356,7 @@ async def _handshake(account: Account, pc, ch: Channel, group_id: str, node_id: await _device_hello(account, ch, identity, node_pk, group_id, nonce_s) await _settle_bundle(account, ch, identity, node_pk, bundle) return GroupSession(pc, ch, group_id, node_id, node_pk, gek, config, - identity, nonce_s) + identity, nonce_s, str(joined.get("role") or "")) async def _fetch_bundle(ch: Channel) -> str: -- cgit v1.2.3