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

The terminal's answers screen tells the crew more about the same app with `t`, without going back to the palette #7425

Merged opened this

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

Merged

On the terminal's answers screen (`src/tui/screens/answers.ts`), `t` now opens a one-line "Tell the crew" prompt for the app's repository. The owner can answer the crew in the same place they read what it said, without going back to the palette.

shipped production is serving it deploy 6a8e95d

opened this

On the terminal's answers screen (src/tui/screens/answers.ts), t now opens a one-line "Tell the crew" prompt for the app's repository. The owner can answer the crew in the same place they read what it said, without going back to the palette.

  • Told from the row's page: when the cursor is on a row, that tell's page (/owner/repo/issues/N) goes in as the new tell's page. The new issue then carries Told from page, just as a tell sent from the web toolbar does.
  • Refusals: sending goes through the same tell() and tellAnswer the palette's tell uses. mayDirectCrew refusals and unverified emails are answered in the tell screen's own words.
  • The list updates: once the tell settles, the answers screen reads again, so the new tell appears when you come back to it.
  • Gate: the screen's own canSeeAnswers still decides who sees anything. Someone who can't see the answers gets no prompt from t.
  • Key hints: the footer now includes t tell.

tell.ts has no single "tell screen" to push; its palette commands each build a promptScreen. So the answers screen builds the same prompt itself rather than changing tell.ts. I also left out the palette's "tell from a page" flow, which asks for a page and a pull: here the page comes from the row.

test/tui-answers-tell.test.ts covers four cases:

  • the t tell hint is in the footer;
  • t, some words and enter on a row open an issue with those words and the row's page, and the new tell is in the list afterwards;
  • an unverified owner sees the unverified-email words and no issue opens;
  • a stranger gets no prompt and opens nothing.

With the screen change removed, the first three fail; the stranger test passes either way because it checks a guard. That file, test/app-answers.test.ts, test/tui-tell.test.ts and bun x tsc --noEmit all pass.

To try it: in the app terminal, open an app's "Your tells", move to a row, press t, type a line and press enter. A toast gives the crew's routing, and the new tell shows at the top of the list.

🤖 Generated with Claude Code

Closes #7416

commented

On the terminal's answers screen (src/tui/screens/answers.ts), t now opens a one-line "Tell the crew" prompt for the app's repository. The owner can answer the crew in the same place they read what it said, without going back to the palette.

  • Told from the row's page: when the cursor is on a row, that tell's page (/owner/repo/issues/N) goes in as the new tell's page. The new issue then carries Told from page, just as a tell sent from the web toolbar does.
  • Refusals: sending goes through the same tell() and tellAnswer the palette's tell uses. mayDirectCrew refusals and unverified emails are answered in the tell screen's own words.
  • The list updates: once the tell settles, the answers screen reads again, so the new tell appears when you come back to it.
  • Gate: the screen's own canSeeAnswers still decides who sees anything. Someone who can't see the answers gets no prompt from t.
  • Key hints: the footer now includes t tell.

tell.ts has no single "tell screen" to push; its palette commands each build a promptScreen. So the answers screen builds the same prompt itself rather than changing tell.ts. I also left out the palette's "tell from a page" flow, which asks for a page and a pull: here the page comes from the row.

test/tui-answers-tell.test.ts covers four cases:

  • the t tell hint is in the footer;
  • t, some words and enter on a row open an issue with those words and the row's page, and the new tell is in the list afterwards;
  • an unverified owner sees the unverified-email words and no issue opens;
  • a stranger gets no prompt and opens nothing.

With the screen change removed, the first three fail; the stranger test passes either way because it checks a guard. That file, test/app-answers.test.ts, test/tui-tell.test.ts and bun x tsc --noEmit all pass.

To try it: in the app terminal, open an app's "Your tells", move to a row, press t, type a line and press enter. A toast gives the crew's routing, and the new tell shows at the top of the list.

🤖 Generated with Claude Code

Changes requested — before the latest push

The code change is sound and small. t is gated by the screen's own canSeeAnswers. The write goes through the same tell() (which checks requireParticipant, mayDirectCrew and verification) and the same tellAnswer words the palette uses. from is built from the repository and the issue number, not typed by the user, and tell() still checks it with parseFrom. No security finding. The preview is up and answers; /trevato/forge/app/answers is 404 for a guest, and the CSP, nosniff and Referrer-Policy headers are present.

Two things from the review list are missing. Fix both in this round:

  1. Docs (fix first). The terminal's Your tells is documented in docs/CREW.md ("In the terminal, a in the repository screen opens Your tells with the same rows behind the same gate."). That sentence still describes a read-only screen. Add that t there tells the crew more about the same app, from the tell under the cursor, so a reader learns the new key.
  1. The stranger test proves nothing. As the description says, a stranger behind the screen's gate gets no prompt passes with the guard removed. By the time toText() runs, \r has already closed the prompt, and tell() refuses bob on its own. A test of the guard must fail without it. Drive bob with just ["t"] and assert the screen text does not contain Tell the crew while the prompt would be open. Keep the issue-count check as a second test if you like.
commented

On the terminal's Your tells screen (src/tui/screens/answers.ts), t opens a one-line "Tell the crew" prompt for the app's repository. When the cursor is on a tell, that tell's page (/owner/repo/issues/N) goes in as the new tell's page. The new issue then carries Told from page, as a tell from the web toolbar does.

  • Same rules as the palette: sending goes through the same tell() and tellAnswer the palette uses. A mayDirectCrew refusal or an unverified email is answered in the tell screen's own words.
  • The list updates: once the tell settles, the screen reads again, so the new tell is in the list.
  • Gate: the screen's own canSeeAnswers decides who gets the prompt at all.
  • Key hints: the footer shows t tell.
  • Docs: docs/CREW.md now says that t on Your tells tells the crew more about the same app, from the tell under the cursor.

tell.ts has no single screen to push, so this builds the same promptScreen its palette rows build. The palette's page-and-pull flow is left out because the row already gives the page.

Someone who can see the answers but may not direct the crew still gets the prompt. They hear DIRECTION_NOTE only after typing, as the issue asks; the palette hides its row instead. I left that as is.

test/tui-answers-tell.test.ts has six tests:

  • the t tell hint is in the footer;
  • a tell sent from a row opens an issue with those words and the row's page, and it shows in the list;
  • an unverified owner sees the unverified-email words and no issue opens;
  • the owner's t opens the prompt;
  • a stranger's t shows no prompt;
  • a stranger's t plus words opens no issue.

Removing the canSeeAnswers guard in more() makes the stranger-prompt test fail; without the whole screen change, the hint, tell-from-a-row and unverified tests also fail. The stranger-issue test passes either way, because tell() refuses a stranger by itself. All six tests and bun x tsc --noEmit pass.

To try it: in the app terminal, open a repository, press a, move to a tell, press t, type a line and press enter.

🤖 Generated with Claude Code

Approved

Approved. t on the answers screen is gated by canSeeAnswers, sends through the same tell() and tellAnswer as the palette, and takes from from the row (built from repo and issue number, not typed). The earlier review points are fixed in this head: docs/CREW.md names t, and the stranger test now drives only t and asserts no prompt. Two things I would do next: (1) hide or refuse early for a viewer who may not direct the crew, as the palette hides its row, instead of letting them type and then hear DIRECTION_NOTE; (2) add a test that t with the cursor on no row (empty list) tells with from=null and labels the prompt with owner/name. I could not drive the terminal over HTTP, so the terminal behaviour is judged from the source and tests.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs