Public: anyone can read this; the crew can change it.
The terminal's About screen shows whether outsiders may direct the crew, and `o` turns it on or off after a plan, as MCP `outsiders` does #7263
Check · Review · Land · Live done — Landed and live in production.
The terminal's About card now shows who may direct the crew, and an admin can switch outsiders on or off with `o`. The new test file, `test/tui-flow-only.test.ts` and `test/mcp-size.test.ts` pass, and `tsc` and `design-lint` are clean. I did not run the full suite; the forge's check does that on the push.
shipped production is serving it deploy 3b6d43c
The terminal's About card now shows who may direct the crew, and an admin can switch outsiders on or off with o. The new test file, test/tui-flow-only.test.ts and test/mcp-size.test.ts pass, and tsc and design-lint are clean. I did not run the full suite; the forge's check does that on the push.
- The line: every reader sees it as a "Crew" row. It uses
directionNote(repo), so it readsDIRECTION_NOTEwhen outsiders are off andOUTSIDERS_NOTEwhen they are on. It wraps at 50 columns like the check-cell row. o: it is offered only to a repository admin who is a person, the same gate asw(FLOW ONLY). Pressing it runssetCrewOutsidersas a dry run and pushes a confirm dialog with one line saying what changes. Enter calls the action for real, then refreshes the repository and the row. Esc or Cancel changes nothing.- Writers and agents: a writer who is not an admin, or an agent, is never offered
o, and pressing it does nothing. - Tests:
test/tui-about-outsiders.test.tscovers the line reading off,o+ enter turning it on and the row saying so, esc leaving it, and a writer and an agent having noo. - MCP: no new tool.
Key clash: o was already the fork's "offer commits upstream" key. While that offer is showing (a fork ahead of its parent), the upstream offer keeps o and the outsiders switch is not offered. The settings page and MCP outsiders still reach it. The alternative is to give the switch another key; I held back because o was specified.
I did not touch setCrewOutsiders or add anything new to the MCP.
The behaviour is sound: the About row, an admin-only o, a dry-run plan, then a confirm, all through setCrewOutsiders, so the gate matches MCP. Three things to fix in one round:
- README: it does not mention the terminal's About
okey or the Crew row. The checklist requires the README to say how to use it. Add a line next to thewflow-only key. - Test gap: the key clash with the fork upstream offer is a behaviour this change adds, and nothing pins it. Add a test where
offered !== nulland assertodoes not offer outsiders, and that it still opens the upstream offer. - Door gap: a fork that is ahead of its parent cannot reach outsiders in the terminal at all, while the page can. Give the switch a key that never clashes, or show the outsiders key whenever it is free. Say in the README which one you chose.
Smaller: this_ is an odd name, so use screen. The ctx.toast(...) line in the confirm handler is over-long, so wrap it like the surrounding code.
I moved the outsiders switch from o to d, so a fork ahead of its parent can reach it. tsc, design-lint and the tests I ran pass (tui-about-outsiders, mcp-size, tui-flow-only, offer-upstream). I did not run the full suite; the forge's check does that on the push.
- Key (item 3): the switch is on
d(for "direct"), offered to the same people as before: a repository admin who is a person.ogoes back to being only the fork's upstream offer. The issue namedo; I changed it because that clash left a fork ahead of its parent with no way to reach the switch. - README (item 1): a line next to the
wflow-only key covers the Crew row andd(plan, then enter to confirm, esc changes nothing). It says why the key isdand noto, and that writers who are not admins and agents are not offeredd. - Fork test (item 2): a new test in
test/tui-about-outsiders.test.tsbuilds a fork ahead of its parent. On that cardois still the upstream offer and opens the pull form, anddopens the "Outsiders" plan without changing anything. The earlier tests now usedtoo. - Smaller:
this_is renamedscreen, and the long toast line is wrapped.
The change itself is right. The Crew row uses directionNote, so the terminal and the page use the same words. d uses the same person-and-admin gate as the page and as w, and it goes through setCrewOutsiders, as MCP outsiders does: dry-run plan first, then the confirm dialog, then the real call. updateRepoSettings appends to app.bus, so web viewers see the change live. Writers and agents are refused in the action as well as on the card. d clashes with no other key on About. The README explains the key choice. The four tests pass at this head (bun test test/tui-about-outsiders.test.ts: 4 pass), and the preview answers /.
One thing to fix first. The direction is "fast tests that never flake", and the fork test waits for forkDrift, which is git work, with a fixed setTimeout(r, 500). On a loaded check machine that can run late, and then has("o") fails. On a fast machine it wastes half a second. Replace it with a wait on the condition: loop await Bun.sleep(10) until screen.keys.some(b => b.keys.includes("o")), with a deadline of about 5 s and a clear failure when the deadline passes. The 20 ms settle after d and after enter guesses in the same way. Await the condition instead (a screen pushed, or crewOutsiders changed), or poll for it the same way.
Smaller, same round: the pull title still says o. Retitle it to d so the log matches the key that shipped.
The About screen now shows a "Crew" row saying whether people who cannot write may direct the crew. A repository admin who is a person can switch that with d, not o. d shows the plan, asks to confirm, and only then calls setCrewOutsiders. Esc changes nothing, and writers and agents are never offered it. bun x tsc --noEmit and test/tui-about-outsiders.test.ts pass (4 tests).
- Key choice:
oalready opens the fork's upstream offer on the same card, so the switch moved tod; otherwise a fork ahead of its parent could not reach it. The README explains this. - Test timing (this round): the tests no longer use fixed sleeps. A small
until(what, condition)helper polls every 10 ms with a 5 s deadline and fails with "timed out waiting for …". The 500 ms wait for the fork's git check, and the 20 ms waits afterdand after enter, now poll for what each test checks (the offer key, a pushed screen, or the stored setting). - Not awaited: the esc and writer/agent cases have nothing asynchronous to wait for, because the key handler refuses them before any async work starts. A comment in the writer test says so.
- Title: the pull title still says
o. I can't edit it from here, so please retitle it tod.
Left out: nothing new on the MCP side. outsiders already covers the switch, and the terminal calls the same action.
Try it: open a repository's About card (I) as its admin and press d, then enter. Run bun test test/tui-about-outsiders.test.ts.
Round 3, read against 05c82cd36ff6. Since then only test/tui-about-outsiders.test.ts changed; src/tui/screens/about.ts and the README are the same as the code I passed last round.
Earlier asks:
- Fixed sleeps in the test (
settle()at 20 ms and the 500 ms wait for the fork's git check): met.until(what, done)polls every 10 ms, gives up after 5 s, and names what it was waiting for. Every wait now checks the state the test asserts: the pushed plan, the storedcrewOutsiders, or theooffer key. The esc and writer/agent cases have nothing to wait for, because the handler refuses before any async work starts, and a comment says so. That is right. - README line, the fork-clash test, and the move to
dso a fork ahead of its parent can reach the switch: all met last round and unchanged.
Security, unchanged and still sound: the write goes through setCrewOutsiders(f.app, f.user, …) with the session's identity, first as a dry run and then for real. The action keeps its own person-and-admin gate behind the terminal's mayFlow() offer gate. The row shows directionNote(repo), the same public words the page uses. No new input is parsed.
The preview at this head answers / with 200. The terminal itself is not reachable from my sandbox, so the tests are what show the key working.
Non-blocking: the pull title still says o; a person merging should retitle it to d. The fork test builds its own ctx/Session mock instead of reusing card(); it would be shorter if card() took the repository.
The terminal's About card now shows who may direct the crew, and an admin can switch outsiders on or off with
o. The new test file,test/tui-flow-only.test.tsandtest/mcp-size.test.tspass, andtscanddesign-lintare clean. I did not run the full suite; the forge's check does that on the push.directionNote(repo), so it readsDIRECTION_NOTEwhen outsiders are off andOUTSIDERS_NOTEwhen they are on. It wraps at 50 columns like the check-cell row.o: it is offered only to a repository admin who is a person, the same gate asw(FLOW ONLY). Pressing it runssetCrewOutsidersas a dry run and pushes a confirm dialog with one line saying what changes. Enter calls the action for real, then refreshes the repository and the row. Esc or Cancel changes nothing.o, and pressing it does nothing.test/tui-about-outsiders.test.tscovers the line reading off,o+ enter turning it on and the row saying so, esc leaving it, and a writer and an agent having noo.Key clash:
owas already the fork's "offer commits upstream" key. While that offer is showing (a fork ahead of its parent), the upstream offer keepsoand the outsiders switch is not offered. The settings page and MCPoutsidersstill reach it. The alternative is to give the switch another key; I held back becauseowas specified.I did not touch
setCrewOutsidersor add anything new to the MCP.Closes #7256