nexus/server/src
馨冉 728fbdd199
Fix markdown paste handling in document editor (#2572)
Supersedes #2499.

## Thinking Path

1. **Project context**: Paperclip uses a markdown editor
(`MarkdownEditor`) for document editing. Users expect to paste
markdown-formatted text from external sources (like code editors, other
documents) and have it render correctly.

2. **Problem identification**: When users paste plain text containing
markdown syntax (e.g., `# Heading`, `- list item`), the editor was
treating it as plain text, resulting in raw markdown syntax being
displayed rather than formatted content.

3. **Root cause**: The default browser paste behavior doesn't recognize
markdown syntax in plain text. The editor needed to intercept paste
events and detect when the clipboard content looks like markdown.

4. **Solution design**: 
- Create a utility (`markdownPaste.ts`) to detect markdown patterns in
plain text
- Add a paste capture handler in `MarkdownEditor` that intercepts paste
events
- When markdown is detected, prevent default paste and use
`insertMarkdown` instead
   - Handle edge cases (code blocks, file pastes, HTML content)

## What

- Added `ui/src/lib/markdownPaste.ts`: Utility to detect markdown
patterns and normalize line endings
- Added `ui/src/lib/markdownPaste.test.ts`: Test coverage for markdown
detection
- Modified `ui/src/components/MarkdownEditor.tsx`: Added paste capture
handler to intercept and handle markdown paste

## Why

Users frequently copy markdown content from various sources (GitHub,
documentation, notes) and expect it to render correctly when pasted into
the editor. Without this fix, users see raw markdown syntax (e.g., `#
Title` instead of a formatted heading), which degrades the editing
experience.

## How to Verify

1. Open any document in Paperclip
2. Copy markdown text from an external source (e.g., `# Heading\n\n-
Item 1\n- Item 2`)
3. Paste into the editor
4. **Expected**: The content should render as formatted markdown
(heading + bullet list), not as plain text with markdown syntax

### Test Coverage

```bash
cd ui
npm test -- markdownPaste.test.ts
```

All tests should pass, including:
- Windows line ending normalization (`\r\n` → `\n`)
- Old-Mac line ending normalization (`\r` → `\n`)
- Markdown block detection (headings, lists, code fences, etc.)
- Plain text rejection (non-markdown content)

## Risks

1. **False positives**: Plain text containing markdown-like characters
(e.g., a paragraph starting with `#` as a hashtag) may be incorrectly
treated as markdown. The detection uses a heuristic that requires
block-level markdown patterns, which reduces but doesn't eliminate this
risk.

2. **Removed focus guard**: The previous implementation used
`isFocusedRef` to prevent `onChange` from firing during programmatic
`setMarkdown` calls. This guard was removed as part of refactoring. The
assumption is that MDXEditor does not fire `onChange` during
`setMarkdown`, but this should be monitored for unexpected parent update
loops.

3. **Clipboard compatibility**: The paste handler specifically looks for
`text/plain` content and ignores `text/html` (to preserve existing HTML
paste behavior). This means pasting from rich text editors that provide
both HTML and plain text will continue to use the HTML path, which may
or may not be the desired behavior.

---------

Co-authored-by: 馨冉 <xinxincui239@gmail.com>
2026-04-03 08:50:48 -07:00
..
__tests__ Fix markdown paste handling in document editor (#2572) 2026-04-03 08:50:48 -07:00
adapters Merge branch 'master' into add-gpt-5-4-xhigh-effort 2026-03-31 06:19:26 -05:00
auth fix: disable secure cookies for HTTP deployments 2026-03-08 22:00:51 -05:00
middleware fix: align telemetry client payload and dimensions with backend schema 2026-04-02 10:47:29 -05:00
onboarding-assets Preserve workspaces for follow-up issues 2026-03-30 14:10:36 -05:00
realtime update typing to node v24 from v20 2026-03-05 14:36:00 -03:00
routes fix(inbox): address Greptile review findings 2026-04-02 12:16:34 -05:00
secrets refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
services fix: use sh instead of /bin/sh as shell fallback on Windows (#891) 2026-04-02 17:34:26 -07:00
storage refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
types Add browser-based board CLI auth flow 2026-03-23 08:46:05 -05:00
agent-auth-jwt.ts Implement local agent JWT authentication for adapters 2026-02-18 16:46:45 -06:00
app.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
attachment-types.ts feat(issues): add issue documents and inline editing 2026-03-13 21:30:48 -05:00
board-claim.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
config-file.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
config.ts feat: implement app-side telemetry sender 2026-04-02 10:47:29 -05:00
dev-server-status.ts Add guarded dev restart handling 2026-03-20 08:50:00 -05:00
dev-watch-ignore.ts Harden dev-watch excludes for nested UI outputs 2026-03-26 12:35:19 -05:00
errors.ts Add server routes for companies, approvals, costs, and dashboard 2026-02-17 09:07:27 -06:00
home-paths.ts Redesign project codebase configuration 2026-03-16 15:56:37 -05:00
index.ts fix: add periodic flush and graceful shutdown for server-side telemetry 2026-04-02 10:47:29 -05:00
log-redaction.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
paths.ts feat(cli): add client commands and home-based local runtime defaults 2026-02-20 07:10:58 -06:00
redaction.ts Implement secrets service with local encryption, redaction, and runtime resolution 2026-02-19 15:43:52 -06:00
startup-banner.ts Add configurable automatic database backup scheduling 2026-03-04 18:03:23 -06:00
telemetry.ts fix: add periodic flush and graceful shutdown for server-side telemetry 2026-04-02 10:47:29 -05:00
ui-branding.ts Add worktree UI branding 2026-03-13 11:12:43 -05:00
version.ts add app version label 2026-03-17 09:40:07 +05:30
worktree-config.ts Avoid sibling worktree port collisions 2026-03-26 11:12:39 -05:00