156 labels named no field: no htmlFor and no control inside, so
clicking one did not focus the input and screen readers announced the
input without a name. Each now points at its field through a useId()
id. The change is additive only (ids and htmlFor), checked by comparing
tokens with the previous version.
The listing effect watched only the path. Switching to a remote agent
that advertises no allowed paths keeps the path, so the panel host's
files stayed on screen under the agent's header, and edits went to
the agent against the wrong host's entries.
Four inline dialogs kept their open flags, targets and input values as
ten separate useState calls on the page. One dialog state now says which
is open, and NamePromptModal / PermissionsModal own their inputs; the
browser test drives all three flows and passes on the old code too.
The create-file dialog had no way to open it and is removed with its
strings.
Six view preferences each had a lazy localStorage read plus a copied
mirroring effect. usePersistentState does both and tolerates storage
that throws, so the page no longer crashes on it; the panel as a whole
still needs storage for its auth tokens.
Opening a folder while the previous listing was still loading let the
slow answer land last and set the current path back, pulling the user
into the folder they had just left. Only the newest browse may now
write.