Agent-First UI v0.9.0: Trust Belongs to One Checkout
Trusting a workspace frontend now trusts that directory and no other, so two checkouts no longer revoke each other. A remote Provider can take as long to answer as the viewer is willing to wait, a minimised macOS window no longer ends its question, and the remote view and ask page speak Traditional Chinese.
A workspace frontend is code that runs in the person’s browser with the session’s credential, so AFUI renders one only after someone has said, once, that they trust it. Until now that trust had one key per provider. Two checkouts of the same project shared it: enabling the frontend in one replaced the trust of the other, and disabling either revoked both. This release keys trust by the frontend’s resolved directory, and fixes a set of places where a session ended, or failed, for a reason that had nothing to do with the person.
Trust per directory
afui frontend enable records trust for the directory it resolved, and
afui frontend disable removes only that record. Another checkout keeps its
own, and deleting a frontend directory no longer leaves a trust record that
disable cannot reach. Both commands update trust.json under a lock and
through a uniquely named temporary file, so two of them run at once no longer
lose one write.
Trust recorded by earlier versions is keyed the old way and is not read. Run
afui frontend enable once in each workspace you use.
A remote Provider can be slow
The remote view’s proxy gave a Provider five seconds to start answering. The
same five seconds bounded connecting, which is right: a Provider that cannot be
reached should be reported quickly. Answering is different. A route that
renders a report or waits on a database worked in a local window and answered
502 remotely.
Only reaching the Provider is bounded now. Once a request is delivered, the proxy waits for as long as the viewer does. A viewer that gives up still closes the request’s connection to the Provider, so an abandoned request does not hold anything open. Ending a session keeps a five-second budget of its own.
Sessions that ended for the wrong reason
- A minimised window. On macOS, minimising the window or hiding the browser ended the question as closed, as if the person had dismissed it. Only closing the window ends it now.
- A slow host. The session registry deleted an entry whose host did not answer a liveness probe in time, even while the process that announced it was still running. An entry is now removed only when its owner process is gone; an unreachable host is hidden from one listing and shown again in the next.
- A late completion. A completion handle kept after its
ActiveUiSessionwas dropped could still record an answer nobody would read. Dropping the session closes its slot, and a latecomplete()reportsfalse. - A killed collector.
afui ask waitclaims a result before reading it. A collector killed after the claim left a marker that kept every laterask waitfrom collecting. The next one takes the claim over. The claim itself is now a file created withcreate_new, which has one winner on every platform; the rename it replaces could move a result out from under a collector on Windows.
Traditional Chinese
The remote view and the ask page already spoke English and Simplified Chinese.
A browser asking for zh-TW, zh-HK, zh-MO, or any Hant tag now gets
Traditional Chinese controls in Taiwan usage. zh-Hans-HK and other Chinese
tags stay Simplified, and Accept-Language weights are read case-insensitively,
so zh;Q=0 really excludes Chinese.
Smaller fixes
- The
tojsontemplate filter is gone, assafealready was. Its output was not escaped, so a value placed in an attribute could add attributes. requires_elementsandrequires_element_mapadd to a decision contract instead of replacing it.- A redirect from a Provider to its own address — relative, or absolute with
the upstream’s host — keeps its target and loses only the announced query.
The proxy also drops response headers that
Connectionnames. - Mount and advertised authorities are lowercased, matching what browsers send.
- Decision declaration, route, and attribute errors carry the rule they broke,
as
Error::InvalidDecision, instead of the provider-id grammar. afui.autosaverecovers whensave()throws synchronously.
Breaking changes
- Frontend trust is per workspace directory. Trust recorded by earlier versions is ignored; enable each workspace again.
afui frontend diffno longer accepts--scope, which it ignored.Error::InvalidDecisionis a new variant, so an exhaustivematchonErrorneeds an arm for it.test_support::FrontendOnDisk::attakes the frontend root alone.- The
tojsonfilter is removed from page templates.
Also in this release: AFUI moves to agent-first-data 0.36.1 and
agent-first-slug 0.9.0.
Getting it
$ brew install agentfirstkit/tap/afui
$ cargo install agent-first-ui