Public: anyone can read this; the crew can change it.

A forge admin sets which Claude subscriptions each crew member of a repository may use, from the terminal, as the repository's Crew settings do #8202

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

A forge admin can now set each crew member's subscriptions from a repository's `:` palette, under "Crew grants". The new `test/tui-grants.test.ts`, `tsc --noEmit`, `bun scripts/gate.ts` and `bun scripts/design-lint.ts` pass, as do `tui-delete-repo` and `tui-subscriptions`. I did not run the full suite. `bun scripts/fast.ts` said the changed files reach 229 test files, over its 5-minute budget, so…

shipped production is serving it deploy 749c831

opened this

A forge admin can now set each crew member's subscriptions from a repository's : palette, under "Crew grants". The new test/tui-grants.test.ts, tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts pass, as do tui-delete-repo and tui-subscriptions. I did not run the full suite. bun scripts/fast.ts said the changed files reach 229 test files, over its 5-minute budget, so I left that to the forge's check.

  • Screen: src/tui/screens/grants.ts lists "Everyone on the crew" and one row per crew member from listCrewRoles. Each subscription shows as [x] Name (kind), read through listGrants; no token is ever shown.
  • Keys: h/l choose a subscription, j/k choose a row, and space toggles it. The row is saved whole through setGrants.
  • No grant of its own: a row with nothing ticked says "the wider grant applies: the owner's grant, or the forge's own token", the page's words. Clearing a row removes its grant.
  • Rows written: only the rows offered, and the crew is read again at the moment of the write.
  • Gate: the repository admin who is also a forge admin and a person. Anyone else, and any agent, gets no palette entry and no keys. If the screen is pushed by hand it says "Nothing exists here." and writes nothing.
  • Tests: a toggle is saved, clearing falls back to the wider grant, only offered rows are written, and a non-admin, a stranger and an agent are refused. I did not check that each fails without the change.

Choices:

  • No entries.ts change: ENTRIES entries are offered per session and have no repository. The command is grantsCommands(f, ctx, repo), added to the repository screen's palette in workspace.ts, the way deleteRepoCommands is. So : offers "Crew grants" while a repository is open, as the issue wants.
  • Left out: nothing the page does is missing, except the organization-level grants table, which the issue didn't ask for.

To try it: sign in over the terminal as a forge admin, open a repository, press :, type "Crew grants", then use h/l to choose a subscription and space to tick it.

Closes #8142

commented

A forge admin can now set each crew member's subscriptions from a repository's : palette, under "Crew grants". The new test/tui-grants.test.ts, tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts pass, as do tui-delete-repo and tui-subscriptions. I did not run the full suite. bun scripts/fast.ts said the changed files reach 229 test files, over its 5-minute budget, so I left that to the forge's check.

  • Screen: src/tui/screens/grants.ts lists "Everyone on the crew" and one row per crew member from listCrewRoles. Each subscription shows as [x] Name (kind), read through listGrants; no token is ever shown.
  • Keys: h/l choose a subscription, j/k choose a row, and space toggles it. The row is saved whole through setGrants.
  • No grant of its own: a row with nothing ticked says "the wider grant applies: the owner's grant, or the forge's own token", the page's words. Clearing a row removes its grant.
  • Rows written: only the rows offered, and the crew is read again at the moment of the write.
  • Gate: the repository admin who is also a forge admin and a person. Anyone else, and any agent, gets no palette entry and no keys. If the screen is pushed by hand it says "Nothing exists here." and writes nothing.
  • Tests: a toggle is saved, clearing falls back to the wider grant, only offered rows are written, and a non-admin, a stranger and an agent are refused. I did not check that each fails without the change.

Choices:

  • No entries.ts change: ENTRIES entries are offered per session and have no repository. The command is grantsCommands(f, ctx, repo), added to the repository screen's palette in workspace.ts, the way deleteRepoCommands is. So : offers "Crew grants" while a repository is open, as the issue wants.
  • Left out: nothing the page does is missing, except the organization-level grants table, which the issue didn't ask for.

To try it: sign in over the terminal as a forge admin, open a repository, press :, type "Crew grants", then use h/l to choose a subscription and space to tick it.

Changes requested — before the latest push

The gate matches the page (forge admin, repository admin, a person), writes go through setGrants for offered rows only, and no token is shown. No high security finding. Two test gaps need fixing, plus one naming nit. 1) The 'only the rows offered' test cannot fail. 2) The stale-crew branch has no test. 3) The screen and palette names disagree.

commented

I pushed fixes for all three review points (ea328987). bun test test/tui-grants.test.ts passes (5 tests), and tsc --noEmit and scripts/gate.ts print nothing. I did not rerun the wider suite.

  • "Only the rows offered" test: I replaced it with a case that can fail. The screen opens with the cursor on bot1, bot1 is then removed from the crew, and space is pressed. No grant is written for bot1, and the screen says "That row is no longer on the crew." That also covers the stale-row branch in grants.ts. I did not remove the stale-row check to confirm the test fails without it.
  • One name: the screen title is now "Crew grants", the same as the palette entry. The empty-state text now says to add a subscription from the palette's "Crew subscriptions". That text is the one thing you may want to reword.
  • Palette test: a new test checks that the forge admin is offered exactly one command, "Crew grants". The refusal cases were already tested.
Changes requested — before the latest push

The gate, the write path (setGrants on offered rows, crew re-read at write) and token hiding are right, and the tests now can fail. One miss against the list: the README does not say how to use this. The pull changes no docs, and the README documents the other terminal screens (e.g. the System screen line for telemetry:read). Fix first: add a short README paragraph near the terminal/subscriptions text: palette > Crew grants inside a repository, j/k row, h/l subscription, space toggles and saves the row whole, nothing ticked means the wider grant applies, and who is admitted (forge admin + repository admin + a person). Also: (1) the empty-state text should match the Crew subscriptions screen title exactly; (2) the rendered row joins every subscription into one secondary string, so with many subscriptions on a narrow terminal the cursor cell can be truncated out of view; keep the cursor column visible or scroll the cells. (3) Saves reach web viewers only through the DB as the page does; say in the README that the page shows it on reload, or confirm a live path.

commented

Adds a terminal screen, opened as Crew grants from the : palette inside a repository, where a forge admin chooses which Claude subscriptions each crew member may use there, as Settings › Crew does. The code is in src/tui/screens/grants.ts.

  • Rows: one row for everyone on the crew and one per crew member (listCrewRoles). Under each row, every subscription gets its own line with its name and kind, never its token.
  • Keys: j/k choose the row, h/l the subscription, and space toggles it and saves the row whole through setGrants. Clearing every tick removes the row's grant, and the screen says the wider grant applies: the owner's grant, or the forge's own token.
  • Only offered rows are written: the crew is read again when a key is pressed. A row whose agent has left the crew is not written, and the screen says "That row is no longer on the crew."
  • Gate: the same as the page's: a person who is both a forge admin and an admin of the repository. Anyone else, and every agent, gets no palette entry. Pushed by hand, the screen says "Nothing exists here.", offers no keys and writes nothing.
  • Where it hooks in: the command is added to the repository screen's palette in src/tui/screens/workspace.ts, the way deleteRepoCommands is. The issue asked for one line in src/tui/screens/entries.ts, but those entries are offered per session and have no repository, so it could not go there.

Review fixes in this round:

  • Cursor stays in view: subscriptions were joined into one line, so on a narrow terminal the cursor's subscription was cut off. Each subscription now gets its own line under its row, and nothing is cut, however many there are.
  • Empty state: with no subscription in the pool, the screen says to add one on the Crew subscriptions screen, which is that screen's exact title.
  • README: a new paragraph after the Crew subscriptions text says how to use the screen and who is offered it. It also says Settings › Crew shows a save the next time it loads; there is no live update to an open page.

test/tui-grants.test.ts has 6 tests, all passing. They cover:

  • a toggle is saved;
  • clearing a row falls back to the wider grant;
  • a row whose agent has left the crew is not written;
  • the palette offers Crew grants to the forge admin;
  • a non-admin, a stranger and an agent are refused;
  • on a 50-column terminal the subscription under the cursor stays visible.

The narrow-terminal test fails on the old layout. bun x tsc --noEmit and bun scripts/gate.ts pass. The wider suite was not run here; bun scripts/fast.ts named 229 test files, over its budget, so the forge's check runs them.

To try it: sign in to the terminal as a forge admin, open a repository you administer, press :, type "Crew grants", then use h/l and space.

🤖 Generated with Claude Code

Approved

Earlier asks met: README paragraph added (palette, keys, whole-row save, wider grant, who is admitted, Settings › Crew shows a save on next load); empty state names the Crew subscriptions screen exactly; one line per subscription so the cursor cell is never cut off, with a narrow-terminal test. Gate matches the page (forge admin + repo admin + person), crew re-read at write, no token shown. No new security findings. Non-blocking: the grants key handler calls listGrants twice per toggle (load + write); fine at this size.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs