fix(web): a dash added in front of a composer line now makes it a bullet#22994

closed3
main
GitHub fork: fix/composer-dash-lines-become-lists
opened21d agobyOOnkarj012
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

In the composer, a line gets a bullet only if you type -, a space, and the first letter in one go. If the dash or the space is added in front of text that is already there, the line stays plain text. The composer still saves and sends it as a Markdown list item, so the editor shows something different from what the agent gets. Anything that rebuilds the editor from the saved draft, such as attaching an image, then shows the bullet out of nowhere.

Fixes #22989.

Change

A small ProseMirror plugin on the list item extension (apps/web/src/composer-rich-text-doc.ts). When the caret leaves a top-level paragraph the user just edited, and its text reads as a list line under the same grammar the draft parser uses (parseListPrefix), the plugin turns that paragraph into a list item:

  • It waits for the caret to leave the line, so typing - [ ] still makes a task.
  • It joins the new item with a list right before or after it when the markers match, because the saved draft reads those lines as one list.
  • It skips lines that the parser reads as a horizontal rule (- - -).
  • It skips lines brought back by undo, so leaving such a line doesn't clear the redo stack.

Plain-text mode has no list nodes and is unchanged. Nothing changes on the server or in contracts. Mobile has its own composer and isn't affected.

Scope and approval

One bug, reported in #22989. It qualifies as a small, focused fix for an obvious bug: the editor shows plain text while the composer sends a list, and the fix only makes the view match what already gets sent.

Verification

  • New browser tests in ComposerPromptEditorTiptap.input.browser.test.tsx cover: a space typed after the dash, - typed in front of text, joining with the lists on either side, a - - - line staying a paragraph, redo surviving after undo, and - [ ] still making a task. The first four fail on main and the undo/rule cases fail on the first version of this fix; all pass now.
  • All composer unit and browser tests pass: vp test run --project unit --project browser src/composer src/components/ComposerPromptEditor (12 files, 465 tests).
  • Lint, format, and tsc --noEmit are clean for the changed files.
  • Not checked: a manual pass in the desktop or web app. The screenshots below come from the composer rendered in the browser test runner with the app stylesheet.
Before (main)After
beforeafter

Both shots: the line -get md formatting right gets a space after its dash, then the caret moves to the first line.

Steps to check by hand: type -get md, press Shift+Enter, move the caret back, type a space after the dash, then click another line.

Model and harness: Claude Opus 5.5 in T3 Code (Claude Code), with a review pass from GPT-6.1-Sol.

🤖 Generated with Claude Code

Checks

20 successful · 16 skipped · 1 neutral
All checks passed
9faf589

Added 3 commits

  • fix(web): join a line-turned bullet with the lists beside it3ec4435
  • fix(web): skip rule lines and undone lines when turning lines into bullets9faf589
  • fix(web): composer lines with a dash added later become bulletse6c8d17
Synced from GitHub

Approvability

Verdict: Would Approve

Macroscope's review found this PR approvable — This is a focused composer bug fix that aligns edited list-like lines with the existing Markdown representation. The production change is isolated to bounded editor behavior, with targeted tests covering list conversion, task lists, horizontal rules, neighboring lists, and undo/redo.

Needs human approval because:

  • Macroscope's correctness review did not reach a verdict

Notes:

  • The correctness review was unavailable. Eligibility was assessed without its result.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4d7821f0-a284-4b20-9d6d-7101ed44f1bb
📥 Commits

Reviewing files that changed from the base of the PR and between 680152e27b2a961686389ca69a1557cbb2c55f08 and 9faf58986020a1ea35cdeac0bbb195310c843ceb.

📒 Files selected for processing: 2
  • apps/web/src/components/ComposerPromptEditorTiptap.input.browser.test.tsx
  • apps/web/src/composer-rich-text-doc.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The composer now converts eligible Markdown bullet and ordered-list lines into lists when the caret leaves them. The change also adds browser tests for conversion, adjacent lists, horizontal-rule-like text, undo and redo, and task-list input.

Changes: Composer list conversion

Layer / File(s)Summary
Deferred list conversion and regression coverage
apps/web/src/composer-rich-text-doc.ts, apps/web/src/components/ComposerPromptEditorTiptap.input.browser.test.tsx
The list-item extension registers a plugin that converts eligible top-level Markdown list lines when the caret leaves them. It joins compatible adjacent lists and excludes tasks, indented or styled lines, empty items, horizontal-rule-like text, and history changes. Browser tests cover conversion, adjacent lists, exclusions, undo and redo, and task-list input.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: chrisdeeming, juliusmarminge

Merge Risk: ⚪ Minimal · up to 9faf5

The reported list-formatting behavior is covered by the change and its regression test. No identified issue prevents merging after normal checks.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly summarizes the main change: adding a dash before existing composer text now converts the line into a bullet.
Description checkPassedThe description covers the problem, implementation, scope and approval rationale, focused verification, test results, limitations, and UI screenshots. It is complete and aligned with the template.
Linked Issues checkPassedIssue #22989 requires rich-text conversion when a dash or - is added before existing text. The plugin in apps/web/src/composer-rich-text-doc.ts tracks edited top-level paragraphs, parses them wit…
Out of Scope Changes checkPassedThe diff changes only the composer document behavior and its browser regression tests. The horizontal-rule regex is shared with the existing draft parser path. Adjacent-list joining, undo handling, ta…
Full details: Linked Issues check

Explanation

Issue #22989 requires rich-text conversion when a dash or - is added before existing text. The plugin in apps/web/src/composer-rich-text-doc.ts tracks edited top-level paragraphs, parses them with parseListPrefix, converts matching lines after the caret leaves, and joins compatible adjacent lists. It excludes horizontal-rule lines and task prefixes. The browser tests in ComposerPromptEditorTiptap.input.browser.test.tsx cover the reported reproduction and related regression cases.

Full details: Out of Scope Changes check

Explanation

The diff changes only the composer document behavior and its browser regression tests. The horizontal-rule regex is shared with the existing draft parser path. Adjacent-list joining, undo handling, task-list protection, and ordered-list parsing support the same draft/editor consistency fix. No server, contract, mobile, or unrelated product changes are present.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Thanks @Onkarj012 for the earlier work and regression coverage. #23000 by @juliusmarminge addresses the same composer mismatch with broader marker coverage and additional test and runtime evidence. This PR now conflicts with main and has had no author activity for over a week, so I’m closing it as a duplicate.