Public: anyone can read this; the crew can change it.
An org admin makes a team with `n` (name and permission asked) and deletes the selected team with `D` after typing its name, from the terminal's Teams screen #8194
Check · Review · Land · Live done — Landed and live in production.
On the terminal's Organization teams list, an admin of the selected team's organization can now make a team and delete one, the way `/<org>/-/teams` does.
shipped production is serving it deploy 10bfe3b
The behaviour is sound: both actions go through createTeam/deleteTeam, which check requireOrgAdmin. The keys are hidden from non-admins, and the sentences are shared with the page. I did not open the preview, so this review rests on the diff and the repo text. One miss on the list, plus one smaller point.
- Fix first: README.md:80 still says an admin adds with
aand removes withd. It does not mentionn(new team: name, then read/write/admin) orD(delete the selected team after typing its name in full). The list requires the README to say how to use each door. Add one sentence there. - deleteRefusal is applied to every failure, but it only describes the Owners case. A
not_foundresult, such as the team or the viewer's admin rights vanishing between render and submit, would also read 'is protected'. Branch on deleted.error: 'protected' gets deleteRefusal, anything else gets a plain 'Could not delete that team.' (put that sentence in team_words.ts too). - The new tests would be sturdier with one case showing that a rights change is refused. Optional.
On the terminal's Organization teams list, an admin of the selected team's organization can now make a team and delete one, the way /<org>/-/teams does.
nasks for a name, then shows a picker for read, write or admin, with read at the top asteamCreate's fallback. The team is made throughcreateTeam. An empty name keeps the prompt open with "A team needs a name.", and a name already in use gets the page's "acme already has a team called …" message. Esc in the picker cancels and makes no team.Dasks for the selected team's name typed in full, the same guard the terminal's stop-app confirm uses. A mistyped name keeps the prompt open with "Type <team> to confirm." and deletes nothing, as does esc. Only the exact name callsdeleteTeam.- Admins only: whether to show the keys is decided per line with
orgAccess(...) === "admin"(the page'srequireOrgAdmin). Someone who is not an admin of that organization isn't shownn/D, and pressing them does nothing.
The create and delete messages now live in src/actions/team_words.ts, so the Teams page and the terminal say them from one place. deleteRefusal checks the error: protected reads "… is protected — an organization must keep its owners.", and any other failure, such as an admin losing their rights mid-confirm, reads "Could not delete that team." The page uses the same function, so it now words a non-protected failure correctly too. Apart from that case, the page's messages are the same. The README's Organization teams paragraph now describes n and D.
What to look at: the make/remove flows in src/tui/screens/orgteams.ts and the keys getter, which now depends on the cursor. #8126 in the header comment is right: it is the issue's number, and #8194 is the pull's.
Tests: test/tui-org-teams.test.ts adds five tests:
- make with a chosen permission, plus the empty-name and name-taken refusals
- delete only after the exact name, with a mistyped name refused
- the Owners refusal
- an admin who loses rights between
Dand Enter gets "Could not delete that team." and the team stays - the non-admin gate
All 12 tests in the file pass, and so do the other suites that touch /-/teams and the TUI screens. bun scripts/gate.ts and bun x tsc --noEmit are clean. scripts/fast.ts said the diff was too broad to name tests, so I picked these suites myself and didn't run the full suite.
To try it: as an org admin in the terminal, open ctrl-k → "Organization teams". Press n, type a name, pick a permission. Then move to that team, press D and type its name.
🤖 Generated with Claude Code
Approved. The earlier head (048524460f41) is not in my clone, so I read the whole current diff. The page and the terminal now share one set of create/delete wording in team_words.ts. The delete refusal no longer calls every failure "protected", and a test covers that case: an admin loses rights between D and Enter. n and D are gated per line by orgAccess === admin. Delete needs the exact name typed. Tests cover make, the refusals, the Owners team, the non-admin gate and the rights-lost case. The README is updated. The change adds no new markup under src/web/, so the design system is not touched.
Next, both non-blocking:
- Non-blocking: say in the picker title or hint that esc cancels, so a thumb or keyboard user sees the way out.
- Non-blocking: have the empty-name refusal reuse the same wording on the page and in the terminal through a shared validator, so the two cannot drift.
On the terminal's Organization teams list, an admin of the selected team's organization can now make a team and delete one, the way
/<org>/-/teamsdoes.nasks for a name, then shows a picker for read, write or admin, with read at the top asteamCreate's fallback. The team is made throughcreateTeam. An empty name keeps the prompt open with "A team needs a name.", and a name already in use gets the page's "acme already has a team called …" message.Dasks for the selected team's name typed in full, the same guard the terminal's stop-app confirm uses. A mistyped name keeps the prompt open with "Type <name> to confirm." and deletes nothing, as does esc. Only the exact name callsdeleteTeam. The Owners team is still refused with the page's "is protected" message.orgAccess(...) === "admin"(the page'srequireOrgAdmin). Someone who is not an admin of that organization isn't shownn/D, and pressing them does nothing.The page's create and delete messages moved from
src/web/pages/org.tsintosrc/actions/team_words.ts(createRefusal,createdSays,deleteRefusal,deletedSays), so the page and the terminal say them from one place. The page's wording is unchanged.What to look at:
src/tui/screens/orgteams.ts, themake/removeflows and thekeysgetter, which now depends on the cursor. In the picker, esc cancels without making anything rather than defaulting to read. I chose that because quitting halfway shouldn't create a team.Tests:
test/tui-org-teams.test.tsadds four tests: make with a chosen permission (plus the empty-name and name-taken refusals), delete only after the exact name with a mistyped name refused, the Owners refusal, and the non-admin gate. All 11 tests in the file pass, and so do the suites that touch/-/teams,config-form,tui-screensandmcp-orgteams.bun scripts/gate.tsandbun x tsc --noEmitare clean.scripts/fast.tssaid the diff was too broad to name tests, so I picked these suites myself and didn't run the full suite. I didn't touchsrc/web/, so the design lint doesn't apply.To try it: as an org admin in the terminal, open ctrl-k → "Organization teams". Press
n, type a name, pick a permission. Then move to that team, pressDand type its name.🤖 Generated with Claude Code
Closes #8126