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

The terminal's Passkeys screen removes the passkey under the cursor with `d` after a confirm #8117

Merged opened this

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

Merged

The terminal's Passkeys screen can now remove a passkey: `d` on the one under the cursor, then `y` to confirm. It follows the same rule as Settings › Passkeys and MCP `whoami_can`, and shows the same words.

shipped production is serving it deploy 5431a5f

opened this

The terminal's Passkeys screen can now remove a passkey: d on the one under the cursor, then y to confirm. It follows the same rule as Settings › Passkeys and MCP whoami_can, and shows the same words.

What changed

  • src/tui/screens/passkeys.ts: d opens confirmScreen asking "remove passkey <name>? y/n", with Cancel selected by default. y calls removeOwnPasskey and nothing else; n, esc and Cancel change nothing.
  • The screen's top line then reads "Passkey removed.", or the action's refusal word for word: LAST_WAY_IN for an account's last way to sign in, or "No such passkey." — the same text the web page shows.
  • The d remove binding shows in the screen's keys. The top line now reads "Passkeys that sign in as you. d removes one; add one on the web, Settings › Passkeys." Adding a passkey still needs the browser.
  • test/tui-passkeys-remove.test.ts (new) covers:

- the binding shows in the screen's keys; - d then n keeps the passkey; - d then y removes it and says "Passkey removed."; - a passkey-only account pressing d then y on its only passkey keeps it and sees LAST_WAY_IN.

  • test/tui-asks-first.test.ts: removeOwnPasskey is added to its list of destructive actions, so a future call that skips the confirm fails the scan.
  • test/tui-passkeys.test.ts: the test was wrong once the behaviour changed, because it checked for the old "Read only: add or remove one on the web" line. Only that expected string is updated.

What I chose not to do: no MCP change. The MCP already removes passkeys through whoami_can, and test/mcp-size.test.ts passes. No src/web/ files changed, so the design lint does not apply.

Checks: bun scripts/gate.ts and bun x tsc --noEmit are clean. bun scripts/fast.ts named 228 files (about 18 minutes, over its 5-minute budget), so I didn't run that list. Instead I ran the 11 files that cover this change: the three passkeys tests, tui-asks-first, passkeys, tui-screens, tui-size, tui-words, tui-render, tui-sshkeys, palette-roster and mcp-size. All 103 tests pass.

Try it: connect to the preview's terminal, open the palette with ctrl-k, type "Passkeys" and press Enter. Move to a passkey, press d, then y or n. On an account with no password and one passkey, y keeps the passkey and shows the last-way-in refusal.

🤖 Generated with Claude Code

Closes #8045

commented

The terminal's Passkeys screen can now remove a passkey: d on the one under the cursor, then y to confirm. It follows the same rule as Settings › Passkeys and MCP whoami_can, and shows the same words.

What changed

  • src/tui/screens/passkeys.ts: d opens confirmScreen asking "remove passkey <name>? y/n", with Cancel selected by default. y calls removeOwnPasskey and nothing else; n, esc and Cancel change nothing.
  • The screen's top line then reads "Passkey removed.", or the action's refusal word for word: LAST_WAY_IN for an account's last way to sign in, or "No such passkey." — the same text the web page shows.
  • The d remove binding shows in the screen's keys. The top line now reads "Passkeys that sign in as you. d removes one; add one on the web, Settings › Passkeys." Adding a passkey still needs the browser.
  • test/tui-passkeys-remove.test.ts (new) covers:

- the binding shows in the screen's keys; - d then n keeps the passkey; - d then y removes it and says "Passkey removed."; - a passkey-only account pressing d then y on its only passkey keeps it and sees LAST_WAY_IN.

  • test/tui-asks-first.test.ts: removeOwnPasskey is added to its list of destructive actions, so a future call that skips the confirm fails the scan.
  • test/tui-passkeys.test.ts: the test was wrong once the behaviour changed, because it checked for the old "Read only: add or remove one on the web" line. Only that expected string is updated.

What I chose not to do: no MCP change. The MCP already removes passkeys through whoami_can, and test/mcp-size.test.ts passes. No src/web/ files changed, so the design lint does not apply.

Checks: bun scripts/gate.ts and bun x tsc --noEmit are clean. bun scripts/fast.ts named 228 files (about 18 minutes, over its 5-minute budget), so I didn't run that list. Instead I ran the 11 files that cover this change: the three passkeys tests, tui-asks-first, passkeys, tui-screens, tui-size, tui-words, tui-render, tui-sshkeys, palette-roster and mcp-size. All 103 tests pass.

Try it: connect to the preview's terminal, open the palette with ctrl-k, type "Passkeys" and press Enter. Move to a passkey, press d, then y or n. On an account with no password and one passkey, y keeps the passkey and shows the last-way-in refusal.

🤖 Generated with Claude Code

Approved

Approved. d asks y/n with Cancel preselected, removal goes through the shared removeOwnPasskey (own passkeys only, last-way-in rule and words shared with web/MCP), and tests cover the binding, n, y and the last-way-in refusal. removeOwnPasskey is added to the asks-first scan. Scope is tight, no new dependency. The terminal itself is not reachable from curl, so I judged it from source and tests. Two things I would do next: (1) the note ("Passkey removed." or the refusal) never clears, so the usual hint line stays hidden until you leave the screen; clear it on the next keypress. (2) Confirm the cursor clamps when the last row is removed, and add a test for it.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs