emrg: gui — tiptap rich-text composer (Stage 1) - #1062
Merged
Conversation
Replace the Composer textarea with @tiptap/react (StarterKit + Link + Placeholder + tiptap-markdown). Send path now serializes markdown via editor.storage.markdown.getMarkdown(); history.jsonl / protocol / TUI unchanged (storage stays a markdown string). Preserved: Enter-send, Shift+Enter newline, Ctrl+Enter send, / command menu (onUpdate + keydown), height cap, G143 requestId, P2 busy queue, G49 failure restore. TranscriptView now renders user/history messages through the markdown renderer (TUI parity) so rich text from tiptap displays correctly. Tests migrated to editor-command style; jsdom polyfills for prosemirror (getClientRects / elementFromPoint). Renderer 451/451, GUI 87+8, theme-guard 2/2.
argszero
commented
Aug 28, 2026
argszero
left a comment
OwnerAuthor
There was a problem hiding this comment.
✅ LGTM — cycle (1/3)
Reviewed the full diff (Composer.tsx tiptap migration, TranscriptView user-markdown render, layout.css, test migration + jsdom polyfills). Independent verification on this branch:
- Renderer:
npm test451/451 (44 files),npm run typecheckclean - GUI: theme-guard 2/2
- CI: test + test-windows both pass (run 33149595609), mergeable CLEAN
Acceptance mapping (rant 2026-08-28T14:07:29):
- Rich text send → markdown stored → transcript renders correctly: covered by markdown round-trip test + TranscriptView user-markdown render test
- Legacy plain-text messages survive setContent round-trip: round-trip test asserts plain text in/out
- / command menu keyboard nav preserved: menu nav tests + Shell wiring tests pass
No issues found. Stage 2 (format bar / shortcuts / paste sanitize) tracked in the rant.
argszero
commented
Aug 28, 2026
argszero
left a comment
OwnerAuthor
There was a problem hiding this comment.
✅ LGTM — cycle (2/3)
Re-verified PR #1062 (tiptap rich-text composer Stage 1):
- Head 1a936e2 unchanged since the (1/3) vote; no new commits
- CI: test + test-windows both pass (run 33149595609)
- mergeable: MERGEABLE / mergeStateStatus: CLEAN
- No ❌ or change requests in between; previous ✅ from cycle 150230 still valid
No issues found. Awaiting 1 more consecutive LGTM from a distinct cycle before merge.
argszero
commented
Aug 28, 2026
argszero
left a comment
OwnerAuthor
There was a problem hiding this comment.
✅ LGTM — cycle (3/3)
Final re-verification of PR #1062 (tiptap rich-text composer Stage 1):
- Head 1a936e2 unchanged since (1/3) and (2/3) votes; no new commits
- CI: test + test-windows both pass (run 33149595609)
- mergeable: MERGEABLE / mergeStateStatus: CLEAN
- Three consecutive ✅ from distinct cycles (150230 → 151203 → this cycle), no ❌ in between
Merging now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
tiptap rich-text composer — Stage 1 (editor core)
Addresses rant 2026-08-28T14:07:29 (GUI 输入框富文本化, design v1, plan A — pure WYSIWYG).
What changed
Composer.tsx: replaced the<textarea>with@tiptap/react(useEditor/EditorContent) using@tiptap/starter-kit+@tiptap/extension-link+@tiptap/extension-placeholder+tiptap-markdownfor serialization.editor.storage.markdown.getMarkdown()produces the markdown string and the existingsendMessagepath is unchanged —history.jsonl, protocol layer and TUI are untouched (storage stays a markdown string, both ends render markdown)./command menu (now driven byeditor.onUpdate+ keydown interception), height cap ≤150px, G143 pre-generatedrequestId, P2 busy-queue injection (emrg: queue messages sent while tool loop busy — inject at round boundary (P1, rant 2026-08-10T21:55:37) #655), G49 failure restore (markdown re-fill viasetContent).TranscriptView.tsx: user + history messages now render through the existing markdown renderer (TUIUserMarkdownparity) — previously plain text, so**bold**from tiptap would have shown literally.MarkdownTextgained astripMarkoption (the ✦ strip stays assistant-only).layout.css:.tiptap-inputcontenteditable rules share the textarea flex/scroll/padding; placeholder styling viap.is-editor-empty(theme-guard 2/2 — all colors via tokens.css vars).Composer.test.tsxswitched fromuserEvent.typeon a textarea to editor-command driven tests (editor.commands.insertContent/ direct send);Shell.test.tsxchat-wiring tests type into the contenteditable viauserEvent.type.test/setup.tsgained jsdom polyfills prosemirror needs (Text/Range.getClientRects,Range.getBoundingClientRect,document.elementFromPoint).Acceptance coverage (rant)
setContent(md)round-trip test (plain text in → plain text out)./命令菜单键盘导航不回归: menu navigation tests (↑↓ wrap, Enter select, Esc close) + Shell/help/rename/clearwiring tests.Verification
emrg/gui/renderer:npm run typecheckclean ·npm test451/451 (44 files) ·npm run buildOKemrg/gui:npm test87 pass / 8 skip · theme-guard 2/2uv run pytest tests/1147 passed + 1 skipped (matches Agent.md)Stage 2 (format bar / shortcuts / paste sanitize) lands in a follow-up cycle.