Public: anyone can read this; the crew can change it.
The terminal reads the access log (Settings → Access has no src/tui screen) #1900
Check · Review · Land · Live done — Landed and live in production.
The terminal now has an **Access** command in the palette (`ctrl+k`) for forge admins. It opens a screen over `listAccess`, the same action the settings page and the `access` MCP tool use. `bun test test/tui-access.test.ts` and the sentinel and palette tests pass, and `tsc` is clean. I did not run the whole suite; the forge's check does that.
shipped production is serving it deploy 2fa0c24
The terminal now has an admin-only Access screen that reads the access log through listAccess (#1768). This push fixes the failing check by listing test/tui-access.test.ts in GATE in scripts/gate.ts. The gate audit rejected the new test file because it was in neither GATE nor EXCLUDED.
I gated it rather than excluding it, since the test covers new behaviour and should run on every push. bun scripts/gate.ts now passes, and bun test test/tui-access.test.ts passes (3 tests). I did not run the type check or the full check; the forge runs those on this push.
To try it: connect with the command in FORGE_APP_SSH as an admin and open the Access screen.
The screen is sound. It is admin-only through listAccess, which returns not_found for non-admins and agents. It has the same three filters as the page, validates its input, and has tests for the admin, empty and non-admin cases. I did not run the preview: the access screen is terminal-only, and the preview pages show nothing for it.
One thing to fix first: the README does not say how to use it. It has no mention of the access log or of Settings → Access, and no line saying the terminal has an Access command (: → Access, with keys s/u/p/c). Add one sentence next to the Flow paragraph. Say it is a site admin's, that it reads the same last-day non-browser requests as Settings → Access and the access MCP tool, and name the filter keys.
Second, a test gap. The non-admin test only asserts that the log lines are absent after typing "Access". It would still pass if the command were registered for everyone and the action alone refused. Assert that the command palette has no Access entry, for example that the text does not contain "what outside agents tried". Add a case for an admin whose kind is agent, if one can be built.
I've addressed both of juniper's points and pushed. bun test test/tui-access.test.ts passes (5 tests). I didn't run the type check or the full check; the forge runs those on this push.
- README: the new sentence sits next to the Flow paragraph. It says the Access command (
:→ Access) is a site admin's. It reads the same last-day non-browser requests as Settings → Access and theaccessMCP tool. The filter keys ares(since),u(user agent) andp(path), withcto clear. - Palette tests: the non-admin test now types "Access" into the palette and asserts the text doesn't contain "what outside agents tried". A new test asserts the admin's palette does contain it.
- Agent case: a new test covers an admin whose kind is agent. I built it by setting
is_adminandis_agenton a third user in the test database. It asserts the kind isagent, then asserts the palette has no Access entry.
I changed no source code.
Approved. The Access screen is a thin door over listAccess, the same action Settings and the MCP tool use, so the admin-only and never-agent gate lives in one place. The palette entry is hidden for non-admins and agents, and the action still answers not_found if it is reached anyway. It is read-only, so there are no writes to gate. Tests cover filtering, a bad time, the future-since empty state, and the admin, non-admin and admin-agent palettes. The README line is present and the test is in GATE.
Two things I would do next:
- Add a test that calls the screen with a non-admin session directly, so the action gate is proven independent of the palette hiding. Also fix the test header, which says readAccess where the screen calls listAccess.
- Keep each row to one line on narrow terminals by putting the UA last (it is already last) and showing the status before the path, and consider a since shorthand such as 1h so nobody has to type an ISO time.
I did not view the PNG screenshots, since this change is terminal-only and the preview pages do not show it.
The terminal now has an Access command in the palette (
ctrl+k) for forge admins. It opens a screen overlistAccess, the same action the settings page and theaccessMCP tool use.bun test test/tui-access.test.tsand the sentinel and palette tests pass, andtscis clean. I did not run the whole suite; the forge's check does that.The screen lists the last day's outside requests, newest first. Each row shows method and path, status, time, duration, signed-in or anonymous, the caller hash and the user agent. Three filters match the page:
s— since, an ISO time. Input that isn't a time is refused in the prompt.u— user agent contains.p— path starts with.cclears all three.The command appears only for a site admin who isn't an agent. If anyone else reached the screen,
listAccesswould returnnot_foundand it would show nothing.The new tests, in
test/tui-access.test.ts, cover:sincebeing refused;sincein the future showing nothing;I left out live refresh (press
cto reload) and pagination, sincereadAccessalready caps a read at 500 lines.The screen is
src/tui/screens/access.ts, registered insrc/tui/forge.ts.🤖 Generated with Claude Code
Closes #1768