Chat composer: Backspace at the prompt's start removes the last attached image
Summary
In the agent chat composer and on the New Tab page, Backspace with the caret at the very start of the prompt now removes the last staged attachment chip (a pasted or dropped image, a file, a pasted-text chip), one per press. Before, only the chip's × removed it.
- The check is shared:
backspacedAttachmentinwebviews/src/agent-session/acpmux/composer/attachmentIntake.tsx. - Holding Backspace: a held key's auto-repeat does not remove chips, so holding Backspace to clear the text stops at the start of the prompt.
- Formatting at the start: the chat composer asks the editor whether Backspace would do nothing there (new
MarkdownFieldHandle.atStart()): an empty caret at the start of a plain first paragraph. A heading, list item or quote at the start still takes Backspace to lift itself, and the chips stay. - Shell mode and IME composition are unchanged.
Testing
Regression tests were committed before the fix (035e6410b7c9b953e2c263844a170131afe0faad):
webviews/test/composer-paste-text.test.tsx(jsdom, the real Milkdown composer).- Backspace at the start removes chips one per press.
- Backspace with the caret after text, or as a key repeat, removes none.
- Backspace at the start of a heading leaves the chips.
webviews/test/new-tab-paste-attachments.test.ts(browser lane, real Chromium and WebKit key presses).- With two pasted images, Backspace deletes the typed text first, then one image per press.
Command: cmux-ci run --class light --script scripts/ci/run-webviews-tests.sh --env CMUX_WEB_TEST_FILES=<file> [--env CMUX_BROWSER_TESTS=1] --ref <sha>
| File | Base (tests only, 035e641) | Head (7552e7c) |
|---|---|---|
| composer-paste-text | FAIL, 1 fail: the chip stays (step d21a02e0306bb44c6f7eab68) | PASS (step 0b5b7ffdeb4ddfb057787d91) |
| new-tab-paste-attachments | FAIL, chromium and webkit: the image stays (step 3217df91f69a352148b26d8d) | PASS (step ecbaa60d31f5069b4fc6f562) |
Observed / Not run
- Ran: the two test files above on the AWS Macs, red and green.
scripts/web-lint.shandscripts/cmux-next/prepush-gate.pyboth pass. - Not run: a tagged app dogfood of the chat pane, and the full webviews suite (PR CI runs it).
No capture: a keyboard behavior change with no visual change.
Review
A correctness review subagent ran on the first version. It found that Backspace at the start of a heading or list item would remove a chip instead of lifting the block; fixed with atStart(), and covered by the heading test. It also flagged an unmounted-editor fallback that read as "at start" (atStart() returns false there) and racy negative checks in the browser test (a frame is now awaited before counting). A re-review on this head follows in a comment.
Changelog
- Fixed: Backspace at the start of the chat prompt removes the last attached image or file, like the chip's ×.
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Backspace with the caret at the very start of the prompt now removes the last staged attachment chip (a pasted or dropped image, a file, or pasted text) in the chat composer and on both New Tab templates, one per press. Previously only the chip's × removed it.
- Shared check lives in
backspacedAttachment; the chat composer uses a newMarkdownFieldHandle.atStart()so a heading, list item, or quote at the start still takes Backspace to lift itself and keeps the chips. - The Classic New Tab template first takes a Backspace that would undo a prefix switch (like
!to terminal), then removes the last image, which the default template removes directly. - A held key's auto-repeat does not remove chips, so holding Backspace to clear the prompt stops at its start.
- Shell mode and IME composition are unchanged; regression tests cover the composer (jsdom) and New Tab (real Chromium and WebKit presses).