From e4f61771131be635b9e81a19203a00707b4b19df Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 2 Oct 2026 10:20:09 +0200 Subject: feat(mnp): sharing a folder is decided on the node's machine only (MNP 6.0) 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 --- packages/meshbay-node/src/meshbay_node/ops/roots.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'packages/meshbay-node/src/meshbay_node/ops/roots.py') diff --git a/packages/meshbay-node/src/meshbay_node/ops/roots.py b/packages/meshbay-node/src/meshbay_node/ops/roots.py index 480fe63..9dbade4 100644 --- a/packages/meshbay-node/src/meshbay_node/ops/roots.py +++ b/packages/meshbay-node/src/meshbay_node/ops/roots.py @@ -174,11 +174,14 @@ async def update_root(state: dict, group_id: str, root_name: str, *, writable=match.writable, removable=match.removable) # Update the live RootSet so GET /api/groups returns correct data - # immediately, without waiting for the async reload to finish. + # immediately, without waiting for the async reload to finish — and the + # indexer's, which is normally the same object but need not be, since it + # is the one the table pushed to every peer is read from. live_roots: RootSet | None = state.get("groups_ctx", {}).get( group_id, {}).get("roots") - if live_roots: - for lr in live_roots.roots: + indexer = state.get("indexers", {}).get(group_id) + for rootset in {id(x): x for x in (live_roots, indexer and indexer.roots) if x}.values(): + for lr in rootset.roots: lr_name = lr.name or str(Path(lr.path).name) if fold(lr_name) == target: if writable is not None: @@ -187,6 +190,9 @@ async def update_root(state: dict, group_id: str, root_name: str, *, lr.removable = removable break + if indexer: + await indexer.publish_roots() + # Built from config when there is no live set, never returned empty: an # empty list is a *valid answer* meaning "this group has no directories", # and the client cannot tell it from "the node could not say". It would -- cgit v1.2.3