镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(composer): add opt-in setting to format messages with markup - #3259

Draft
damsonn wants to merge 1 commit into
block:mainfrom
damsonn:ddormal/format-messages-with-markup
Draft

damsonn wants to merge 1 commit into
block:mainfrom
damsonn:ddormal/format-messages-with-markup

Conversation

@damsonn

@damsonn damsonn commented Nov 11, 2026 •

Copy link
Copy Markdown

Why

Since #455, the composer converts Markdown as you type: **x** turns bold on the closing delimiter, three backticks open a code block, and - starts a list. Some people would rather see and edit the Markdown source, as Slack's Format messages with markup preference allows. This adds that as an opt-in device setting. Messages are still sent as the Markdown that was typed and still render formatted in the timeline.

What

  • New markup-preference.ts, which follows the autocorrect-preference.ts pattern: the buzz-message-markup.v1 localStorage key, a useMessageMarkupPreference hook, unsaved-choice recovery, and a markupSetting DeviceSetting (conversations.markup) registered in device-settings.ts, so agents can read and change it.
  • EditableInput skips the typed-delimiter conversion block when the setting is on. New messages and edits to sent messages both go through MessageComposer → RichComposerInput → EditableInput, so this one gate covers both. With the setting off, nothing changes.
  • Settings → Appearance → Format messages with markup switch. It sits next to the spelling-correction switch but shows on every platform, is off by default, and has the same retry toast when the choice can't be saved.
  • docs/buzz-help.md gets an entry for the setting and adds it to the list of settings agents can change.

Not changed: paste handling, the formatting toolbar and ⌘B, and the serializer. Toolbar formatting still applies when the setting is on.

Known limitation: with the setting on, if you bold foo with ⌘B and then type raw **bar** directly after it, with no space, the message is sent as **foo****bar** and the stars show. With the setting off, the typed span converts and merges into the bold, so this only affects people who opt in.

Tests

  • EditableInput.test.tsx adds 9 tests for the setting turned on. Typing **bold** and *it* _also_ ~~gone~~ `code`, a ``` fence, a ~~~ fence, - , * , 1. and > leaves raw text with no formatting nodes, and composerMarkdown returns exactly what was typed, so the serializer needs no change. Other tests cover typing into an existing draft (the edit case) and turning the setting off live, after which the next delimiter converts again.
  • With the !current.current.markup gate removed, all 9 fail. With the setting off, the existing conversion tests still pass.
  • AppearanceSettings.test.tsx checks that the switch is shown without Mac WebKit, starts off, persists, follows storage events, and retries an unsaved choice. device-settings.test.ts checks that the setting is listed and that its setter, event and unsaved states work.
  • vitest run src/features/messages src/app/AppearanceSettings.test.tsx src/app/device-settings.test.ts: 103 files and 3075 tests, all passing. tsc --noEmit and biome are clean, and the pre-commit and pre-push hooks passed.
  • CI has not run yet. This PR comes from a fork, so the CI workflow is waiting (action_required) for a maintainer to approve the run. Only DCO, Semgrep and zizmor have run so far. I'll post local results for what CI runs as a comment.

Not yet exercised in the running app (just desktop). Damien will try it before this is marked ready.

🤖 Generated with Claude Code

Add a device setting, Settings → Appearance → Format messages with
markup, that keeps typed Markdown delimiters as raw text instead of
converting them to formatting as you type. Messages are still sent as
the Markdown that was typed and render formatted. Off by default; when
off, the composer converts exactly as before.

Co-authored-by: Kamaji <076770de4ae8127da02d45adc3a2b673ef58f263632db16fdbfcc0c0db8c1a25@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Damien Dormal <ddormal@squareup.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant