Skip to content

Polish desktop typing and agents UI - #92

Merged
wesbillman merged 1 commit into
mainfrom
desktop-typing-and-agents-polish
Mar 17, 2026
Merged

wesbillman merged 1 commit into
mainfrom
desktop-typing-and-agents-polish

Conversation

@wesbillman

Copy link
Copy Markdown
Collaborator

Summary

  • add desktop typing indicators for active channel bots, including the typing row UI and mock/e2e coverage
  • show the total managed-agent count in the sidebar and compact the relay directory into a table while keeping the Agents view stacked
  • polish chat spacing and related desktop UI details around reactions and typing presentation

Testing

  • source ./bin/activate-hermit && cd desktop && pnpm typecheck
  • source ./bin/activate-hermit && cd desktop && pnpm build
  • source ./bin/activate-hermit && cd desktop && pnpm test:e2e:smoke
  • pre-push: cargo fmt --all -- --check
  • pre-push: cd desktop && pnpm check
  • pre-push: cargo check --manifest-path desktop/src-tauri/Cargo.toml
  • pre-push: cargo clippy --workspace --all-targets -- -D warnings
  • pre-push: ./scripts/run-tests.sh unit

@wesbillman
wesbillman merged commit 6ecd048 into main Mar 17, 2026
8 checks passed
@wesbillman
wesbillman deleted the desktop-typing-and-agents-polish branch March 17, 2026 19:09
BradGroux pushed a commit to BradGroux/buzz that referenced this pull request Aug 23, 2026
brow pushed a commit that referenced this pull request Nov 2, 2026
Treat `~~~` fences as code when shielding escapes, as bubble segments
already do, so their backslashes stay literal. Encode backslashes in an
`<url>` autolink as `&#92;` in its label and `%5C` in its destination,
so none escapes the synthesized `]` or `)`.

Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Tom Brow <[email protected]>
brow added a commit that referenced this pull request Nov 13, 2026
Message Markdown on mobile moves from gpt_markdown 1.2.1's legacy regex
pipeline to the CommonMark parser that 1.3 added ("plusparse"). Before
this, passing `inlineComponents` (now deprecated, removed in 2.0.0) kept
every message on the legacy pipeline.

### What changes for users

Rendering moves closer to desktop (react-markdown + remark-gfm):

- `_italic_` and `__bold__` work, backslash escapes and HTML entities
decode, and `[a [b] c](url)` labels are correct.
- Inline code follows CommonMark pairing: `"```npm install```"` in a
sentence is inline code, and four-backtick fences work.
- Setext headings, reference links, footnotes, `~~~` fences, `1)` lists
and CommonMark list/quote continuation render.
- HTML comments are hidden, as on desktop.
- `\[`, `\]`, `\(` and `\)` stay literal, as on desktop. Plusparse
hard-codes them as LaTeX delimiters, so they're written as entities
before rendering.
- Side effect: an unfenced `__init__` now renders as bold "init", and a
line over `---` becomes a heading, same as desktop.

Device benchmark (iPhone SE, profile build, 600 synthetic messages, 3
launches per build): scrolling spends 9% less time building, and frames
with more than 8 ms of build drop from 63 to 22. Jumping onto unbuilt
messages is 11% cheaper, and raster time is unchanged.

App size: the release app grows about 4.6 MB uncompressed (80.6 to 85.2
MB), mostly Dart code from the new math and highlighting packages.

### Before and after

Synthetic messages that reproduce differences found in real channel
history, rendered through `MessageContent` on main and on this branch:


![01-escaped-brackets-in-code](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--01-escaped-brackets-in-code.png)


![02-inline-triple-backticks](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--02-inline-triple-backticks.png)


![03-four-backtick-fence](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--03-four-backtick-fence.png)


![04-entities](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--04-entities.png)


![05-stars-and-underscores](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--05-stars-and-underscores.png)


![06-ordered-list-paren](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--06-ordered-list-paren.png)


![07-setext-heading](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--07-setext-heading.png)


![08-dunder](https://raw.githubusercontent.com/block/buzz/49600d2f9b87c2c41fd1bcac450efd345de0d0db/pr-8945--08-dunder.png)

### Demo

A scroll through synthetic messages covering common formatting
(headings, lists, quotes, links, highlighted code, a table, a task list,
escapes), recorded on an iPhone 17 Pro simulator running this branch:


https://github.com/user-attachments/assets/bdc9680c-d20b-41ec-8e1a-a5b51c602f9d

### How

- Mentions, custom emoji and `#channel` tokens are `InlinePattern`s.
Links go through `inlineLinkBuilder` into the existing `_buildLink`, so
chips, media links and taps are unchanged.
- Removed workarounds the parser makes unnecessary:
  - the render-path escape shielding from #8925
- the `_MarkdownEscapeMd`, `_MarkdownLabelEntityMd` and `_MessageLinkMd`
components
  - the zero-width prefix before a leading `#channel`

Plain-text previews and gallery helpers keep their own escape handling.
`normalizeBareLinks` stays because attachment and gallery detection
depend on its output. Bubble segmentation unescapes a link destination
itself before its imeta lookup, since content no longer arrives
shielded.
- Kept desktop parity where plusparse differs from GFM:
- a table typed directly under a caption line gets a blank line inserted
before it, since plusparse can't start a table mid-paragraph
- `> [!NOTE]` quotes render as quotes (`alertBuilder` returns
`asBlockQuote()`), since desktop has no alerts
- `mapMarkdownProse` now ends an unclosed backtick run at its paragraph.
Before, it could pair with a run in a later block and flip code and
prose for the rest of the message.
- Synthesized autolink labels escape backslashes instead of using
`&#92;`, which the parser leaves undecoded in a URL-shaped label.
- Repo/PR/issue chips keep their own semantics node.
- Forum card previews clip at their 120 px cap instead of overflowing:
blocks now lay out as a column.
- Pinned to exactly 1.3.4. 1.4.0 renders HTML by default and themes
through the separate `material_ui` package, which would need a theme
bridge.

### Validation

- Full mobile suite passes and analyze is clean at 78b9c1a.
- All of #8925's and #8940's backslash-escape cases pass on the new
parser, including the strike-across-lines case that used to be a known
limitation.
- Real-message diff: 2,259 recent messages from 13 busy channels,
rendered through `MessageContent` on main and on this branch. 29
differed in text or styling. On inline and fenced code, the branch
matched desktop's parser (remark-gfm) in 23 of them and main in 7. The
review found the three parity gaps above, now fixed. The rest are
CommonMark behavior that desktop shares.
- Added tests, each confirmed to fail without its fix:
  - a leading `#channel` renders as a link, not a heading
  - a table under its caption renders as a table
  - an alert-marker quote stays a quote
  - an unclosed backtick run doesn't flip later code
- the transcript tests detect a rendered link by its style; the old
`LinkButton` check passed even with autolink on
- Automated simulator run (iPhone 17 Pro, iOS 27, debug build, signed in
to a Builderlab community): channel list, two channels with history
scrolled back several pages (mentions, link previews, thread summaries,
images), an agent Solo chat with long agent messages, and the inbox. No
rendering errors or layout breaks; the Solo chat screen also matched
main's build side by side.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Tom Brow <[email protected]>
Co-authored-by: Tom Brow <[email protected]>
Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
Co-authored-by: Claude Opus 5.5 <[email protected]>
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