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

The terminal's "What I can do" screen says when your email is unverified, and `v` sends a new verification email, as MCP `email_verify` does #7314

Merged opened this

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

Merged

The terminal's "What I can do" screen (`src/tui/screens/can.ts`) now tells a person when their email is unverified, and `v` sends a new verification email.

shipped production is serving it deploy 97ab7b8

opened this

The terminal's "What I can do" screen (src/tui/screens/can.ts) now tells a person when their email is unverified, and v sends a new verification email.

  • The line: while the email is unverified, one line under the role says so, using the account page's wording: until the email is verified you can read and talk, but not make repositories, apps or runs. A verified account sees no line.
  • v: sends the email through resendVerification, the same action the account page and MCP email_verify use. The outcome is shown in the same words MCP and the API use (VERIFY_WORDS for too_soon, no_mail and failed, and CAPPED_WORDS). The link only ever goes into the email, never onto the screen. The v key appears in the screen's key list only while the account can actually use it.
  • Agents: never offered v and never shown the line. emailVerified already counts every agent as verified, and the screen also checks that the account is not an agent.
  • Placeholder addresses: an account still on a placeholder (.invalid) address isn't offered v either, because there is nowhere to send the email. Its line says to add an email from account settings in a browser instead.

The new test/tui-verify.test.ts checks four things. An unverified account sees the line, and v sends exactly one email, to that account's address, with no link on the screen. A second v inside the resend window sends nothing and shows VERIFY_WORDS.too_soon. Once verified, there is no line and v sends nothing. An agent is never offered v.

bun x tsc --noEmit is clean. test/tui-verify.test.ts, test/tui-can.test.ts and test/mcp-size.test.ts pass, and so do the 129 files scripts/fast.ts named (1000 pass, 24 skipped in the sandbox). The MCP is unchanged, so no ceiling moved.

To try it, open "What I can do" from the palette (Ctrl+K) as an unverified account and press v twice: the first press sends the email, the second shows the "try again in a few minutes" refusal.

🤖 Generated with Claude Code

Closes #7301

commented

The terminal's "What I can do" screen (src/tui/screens/can.ts) now tells a person when their email is unverified, and v sends a new verification email.

  • The line: while the email is unverified, one line under the role says so, using the account page's wording: until the email is verified you can read and talk, but not make repositories, apps or runs. A verified account sees no line.
  • v: sends the email through resendVerification, the same action the account page and MCP email_verify use. The outcome is shown in the same words MCP and the API use (VERIFY_WORDS for too_soon, no_mail and failed, and CAPPED_WORDS). The link only ever goes into the email, never onto the screen. The v key appears in the screen's key list only while the account can actually use it.
  • Agents: never offered v and never shown the line. emailVerified already counts every agent as verified, and the screen also checks that the account is not an agent.
  • Placeholder addresses: an account still on a placeholder (.invalid) address isn't offered v either, because there is nowhere to send the email. Its line says to add an email from account settings in a browser instead.

The new test/tui-verify.test.ts checks four things. An unverified account sees the line, and v sends exactly one email, to that account's address, with no link on the screen. A second v inside the resend window sends nothing and shows VERIFY_WORDS.too_soon. Once verified, there is no line and v sends nothing. An agent is never offered v.

bun x tsc --noEmit is clean. test/tui-verify.test.ts, test/tui-can.test.ts and test/mcp-size.test.ts pass, and so do the 129 files scripts/fast.ts named (1000 pass, 24 skipped in the sandbox). The MCP is unchanged, so no ceiling moved.

To try it, open "What I can do" from the palette (Ctrl+K) as an unverified account and press v twice: the first press sends the email, the second shows the "try again in a few minutes" refusal.

🤖 Generated with Claude Code

Changes requested — before the latest push

Reviewed the pull's real head, 95db0856 (src/tui/screens/can.ts and test/tui-verify.test.ts). The diff handed to me for this review was #7313's asked-screen change, not this one.

Security is fine. Identity is the SSH session's f.user. v goes through resendVerification, so the resend window and the mail caps are the same per-account ones the page, the API and MCP use. The link never reaches the screen. Agents and placeholder addresses are kept away from v. The preview answers 200, but SSH is not reachable from here, so I could not try v live.

Two things to fix, in this order:

  1. Docs (fix first). The pull adds a key and says nowhere how to use it. docs/CREW.md:304 still describes the terminal's What I can do command as "(read only, agents included)", and neither the README nor docs/TOUR.md mentions v. Add one sentence where that command is described: when the email is unverified the screen says so, and v sends a new verification email, as the account page and MCP email_verify do. Remove "read only" while you are there.
  1. Test for the placeholder branch. An unverified account on a .invalid address gets a different line ("add your email from account settings in a browser") and no v. No test covers that, so the isStandInEmail guard could be deleted and every test would still pass. Add a case: an unverified account on a placeholder address sees that line, the key list does not offer v, and pressing v sends no mail.

Not blocking: the chain that maps the outcome to words (lines 54–66) repeats email_verify.ts line for line. A small verifyWords(result) in actions/verify_words.ts, used by both, would keep the two doors from drifting apart.

commented

The terminal's What I can do screen now says when your email is unverified, and v sends a new verification email through resendVerification. It uses the same per-account resend window and mail caps as the account page, the API and MCP email_verify, and reports the outcome in the API's words; the link never appears on screen. Agents are always counted as verified, so they are never offered v. An account on a placeholder .invalid address is told to add an email from account settings in a browser, and gets no v either.

This push answers the review:

  • Docs: docs/CREW.md no longer calls What I can do "read only". It now says the screen shows an unverified email, that v sends a new verification email as the account page and MCP email_verify do, and what a placeholder-address account is told instead.
  • Placeholder test: test/tui-verify.test.ts adds an unverified account on a .invalid address. The test checks that the screen tells it to add an email in a browser, does not offer v, and sends no mail when v is pressed. With the isStandInEmail guard removed, this test fails.
  • Shared words: verifyWords(outcome) in src/actions/verify_words.ts maps each resendVerification outcome to its sentence. src/tui/screens/can.ts and src/http/mcp/tools/email_verify.ts both use it, so the two can't drift apart. The MCP tool's error codes and sentences are unchanged.

To try it, ssh with the preview's FORGE_APP_SSH command as an unverified account, open What I can do (ctrl-k), press v, then press v again to see the "a link was sent a moment ago" refusal.

tsc --noEmit passes, as do test/tui-verify.test.ts, test/mcp-email-verify.test.ts, test/verify-words.test.ts, test/mcp.test.ts and test/settings-email-verify.test.ts. I didn't run the full set scripts/fast.ts named: 1104 test files, an estimated 95 minutes.

🤖 Generated with Claude Code

Approved — before the latest push

Round 2: every earlier ask is met.

  • Placeholder-address test (blocking last round): met. test/tui-verify.test.ts now creates an unverified .invalid account, presses v, and expects the "add your email from account settings in a browser" line, no v offer and no mail sent. The test would fail without the isStandInEmail guard.
  • Shared words (non-blocking last round): met. verifyWords in src/actions/verify_words.ts takes exactly the outcome union resendVerification returns (sent|already / unauthorized|too_soon|no_mail|capped|failed), so tsc fails if a new outcome is added and not worded. MCP email_verify still answers with the same codes and sentences.
  • Docs: docs/CREW.md no longer calls the screen read only, and it describes v and the placeholder case.

No new findings on the changed lines. The write still goes through resendVerification with the session's verified user, keeping the per-account limit and mail caps. The link never reaches the screen. Agents and placeholder addresses get no v. The mail.ts import adds no cycle. The preview answers 200.

commented

The terminal's What I can do screen now says when your email is unverified, and v sends a new verification email through resendVerification. It uses the same per-account resend window and mail caps as the account page, the API and MCP email_verify, and reports the outcome in the API's words; the link never appears on screen. Agents are always counted as verified, so they are never offered v. An unverified account on a placeholder .invalid address is told to add an email from account settings in a browser, and gets no v either.

  • Shared words: verifyWords(outcome) in src/actions/verify_words.ts maps each resendVerification outcome to its sentence. src/tui/screens/can.ts and src/http/mcp/tools/email_verify.ts both use it, so the terminal and MCP can't drift apart. The MCP tool's error codes and sentences are unchanged.
  • Docs: docs/CREW.md no longer calls What I can do "read only". It now says how the screen shows an unverified email and what v does, and what a placeholder-address account is told instead.
  • Tests: test/tui-verify.test.ts covers four cases:

- An unverified account sees the line, and v sends exactly one mail. - A second v inside the resend window sends nothing and is refused in the API's words. - A verified account and an agent see no line, and v sends nothing. - A placeholder-address account is told to add an email in a browser, is not offered v, and sends nothing when it presses v. This last case fails if the isStandInEmail guard is removed.

  • Merge: main changed the same Roles paragraph in docs/CREW.md. I took main's version, keeping the People command's new s (suspend) key and the new "Where you are signed in" paragraph, and reapplied the What I can do sentence to it.

To try it, connect with the preview's FORGE_APP_SSH command as an unverified account and open What I can do with ctrl-k. Press v to get a new link, then press v again to see the "a link was sent a moment ago" refusal.

After the merge, tsc --noEmit passes, as do test/tui-verify.test.ts, test/mcp-email-verify.test.ts, test/verify-words.test.ts, test/mcp.test.ts and test/settings-email-verify.test.ts. I didn't run the full set scripts/fast.ts named, because it was too broad: 1104 test files, an estimated 95 minutes.

🤖 Generated with Claude Code

Approved

Round 3, head b77387e0. Since 8e5bb69f the only change is a merge of main. The pull's own diff in src/ and test/tui-verify.test.ts is byte-identical to the one I approved on 8e5bb69f. The merge resolution in docs/CREW.md keeps main's People s (suspend) wording and the new "Where you are signed in" paragraph, and puts the What I can do sentence back without "read only".

Earlier asks:

  • Docs: met. docs/CREW.md says how the unverified line, v and the placeholder-address case work.
  • Placeholder-address test: met. The test fails without the isStandInEmail guard.
  • Shared words: met. verifyWords is typed on resendVerification's outcome union and used by both the terminal and MCP email_verify.

No new findings: no lines changed that I have not already read. The write goes through resendVerification with the session's user, under the same per-account window and mail caps as the other doors, and the link never reaches the screen. The preview answers 200.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs