refactor(desktop): feedback is a standard dialog, not the notch-era slot composer
Settings ▸ General's Send feedback and Suggest a feature (and the new Help-menu items) now open a standard centred dialog, instead of the notch-era slot composer that dropped a half-clipped shape from the top of the window.



The dialog
renderer/feedback-dialog.tsx: a modal onConfirmDialog's pattern and classes (dimmed backdrop, card, Tab kept in the card via the now-sharedtrappedTab, focus back to whatever opened it,role="dialog", motion and spacing tokens), 520px wide.- The title follows the kind: "Send feedback" / "Suggest a feature". That second name is user-facing copy only; the wire's
FEEDBACK_KIND.PROMPTis unchanged. - One auto-growing textarea (
field-sizing: content) with the kind's placeholder, focused on open. - Screenshots come in three ways: the "Attach screenshot" icon button, paste into the field, or a drop anywhere over the dialog. They show as small removable thumbnails.
FEEDBACK_LIMITSand the old refusal wording stay; the button disables once 3 are attached. - The signature is one quiet line: an Include my name and email checkbox (on by default) and "Sending as Name · email". Signed out there is no line, and the note goes unsigned.
- The submission keeps the same shape:
{ kind, message, name?, email?, images }. Name and email are sent only while the box is ticked. The only account data that goes is the signed-in name and email; no credential is included. - Buttons use only #1929's shared classes: attach is
icon-button, Cancel istoolbar-button, Send isprimary-button, and the Settings offers aretoolbar-button. - Footer: Cancel, then Send (primary, ⌘↩). Send stays disabled until there are words. While sending, the button reads "Sending…" and the controls are disabled. A refused send keeps the dialog open and shows the reason inline.
- When a send is delivered, the dialog closes and a small "Thanks — sent" toast shows at the bottom of the window for 3s. Its timer is an
Effect.sleepatom on the renderer runtime, so there's no rawsetTimeout. The Luke swoop/landing is gone.
Draft rule: each kind keeps its own draft. Cancel and a delivered send discard it. Escape or a click on the dimmed window just closes the dialog and keeps the words and screenshots for the next opening of that kind. If there are no words yet, it discards instead. A screenshot still being read when its draft is discarded or sent lands nowhere.
Entry points
- The two buttons in Settings' Feedback section.
- Help ▸ Send Feedback… and Help ▸ Suggest a Feature…. These are two menu-only commands in the shortcut table (
MENU_COMMAND_LABELS), with no new key. To keep that type-safe,APP_SHORTCUTSis now typed overKeyedCommand, i.e. every command except the menu-only ones.
Deleted (notch-era)
feedback-slot.tsx,use-feedback-composer.ts,feedback-entry.ts,feedback-confirmation.tsand their tests.PANEL_PRESENTATION.FEEDBACKanduse-panel-entry.ts(only the composer used them after #1926 and #1927).- App's presentation is now a constant
PANEL. The final notch purge, which the sign-in workspace is landing after this PR, removes it along withdata-presentationand the notch CSS. SURFACE_PROPERTY.FEEDBACK_HEIGHTand the now-unusedSurfacePropertytype,STILL_MS/parseMilliseconds, about 450 lines of slot/landing CSS, and tworawAsyncPrimitivesallowlist rows.- I coordinated with the sign-in redesign workspace, which owns
sign-in-slotand the rest of the presentation plumbing.
Privacy
The whole dialog card is ph-no-capture, so the screen recording leaves out the words, the thumbnails and the signature. session-replay.ts, PRIVACY.md, packages/feedback's doc and docs/DESIGN.md are updated to match.
Tests
feedback-dialog.test.ts drives the public components (Settings + dialog, wired as the app wires them). It covers:
- opening from each Settings button and from the Help menu;
- Send disabled until there are words;
- ⌘↩ sends the signed payload, closes the dialog, shows the toast and returns focus;
- unticking the box omits name and email, and a signed-out send is unsigned;
- attach, remove and the 3-image limit refusal;
- paste and drop;
- Escape keeps the draft and never reaches the window, a backdrop click does the same, and Cancel discards;
- a refused send shows its reason inline;
- each kind keeps its own draft;
- a screenshot still encoding when its draft is cancelled lands in no draft.
app-menu.test.ts covers the Help items.
Verification
./scripts/check.shexits 0 (Linux).- CI could not verify the Mac UI, and
./scripts/verify.shwas not run. This was built on a Linux cloud VM; LUKE-159 is the manual Mac pass. - The screenshots above are headless Chrome renders of the real
DesktopSettingspage andFeedbackDialogover the app's real stylesheet. They are not the Electron window.
🤖 Generated with Claude Code