Skip to content

Use tiptap editor for prompt file#559

Merged
elie222 merged 9 commits intomainfrom
feat/tiptap-prompt-file
Jul 12, 2025
Merged

Use tiptap editor for prompt file#559
elie222 merged 9 commits intomainfrom
feat/tiptap-prompt-file

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Jul 11, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a rich text editor for editing rules prompts, allowing enhanced formatting and a more user-friendly experience.
    • Updated placeholder text in the prompt editor to a clear bullet-point format with improved examples.
  • Chores

    • Added new dependencies to support rich text editing capabilities.
  • Style

    • Added new styles for syntax highlighting and code formatting within the rich text editor, including dark mode support.

@vercel
Copy link

vercel bot commented Jul 11, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
inbox-zero ✅ Ready (Inspect) Visit Preview Jul 12, 2025 10:45pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 11, 2025

Caution

Review failed

The pull request is closed.

"""

Walkthrough

A new SimpleRichTextEditor component utilizing TipTap is introduced and integrated into the RulesPromptForm to replace the previous plain text area for editing rules prompts. The editor supports markdown, exposes imperative methods, and updates the UI for richer text editing. A related TipTap extension dependency is added. CSS styles for the editor’s syntax highlighting and code formatting are also introduced.

Changes

File(s) Change Summary
apps/web/components/editor/SimpleRichTextEditor.tsx Added a new rich text editor component using TipTap, with markdown support, placeholder extension, and imperative methods.
apps/web/components/editor/SimpleRichTextEditor.css Added CSS styles for syntax highlighting and code formatting in the SimpleRichTextEditor component.
apps/web/app/(app)/[emailAccountId]/assistant/RulesPrompt.tsx Replaced plain text area with SimpleRichTextEditor for editing rules prompt; updated placeholder to markdown bullet points with examples.
apps/web/package.json Added @tiptap/extension-placeholder dependency for the new editor and updated TipTap packages to version 2.26.1.
version.txt Updated version from v1.8.8 to v1.9.0

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RulesPromptForm
    participant SimpleRichTextEditor

    User->>RulesPromptForm: Open/Edit Rules Prompt
    RulesPromptForm->>SimpleRichTextEditor: Render editor with props (value, placeholder, etc.)
    User->>SimpleRichTextEditor: Edit content (rich text/markdown)
    SimpleRichTextEditor->>RulesPromptForm: Propagate markdown content on change
    RulesPromptForm->>RulesPromptForm: Handle form validation and submission
Loading

Possibly related PRs

  • Select persona examples in chat #451: Refactors persona definitions including personas.other.promptArray, which is used in the updated placeholder examples in the new rich text editor.

Suggested reviewers

  • edulelis

Poem

In the garden of prompts, a new tool appears,
A rich text delight for your editing cheers.
Markdown and lists now hop into view,
With TipTap’s magic, formatting grew.
The bunny leaps high, in code it delights—
"Try the new editor, it’s richer than bytes!"
🐇✨
"""


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 094acb9 and 1cc6ff4.

📒 Files selected for processing (1)
  • version.txt (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@claude
Copy link

claude bot commented Jul 11, 2025

Claude finished @elie222's task —— View job


Pull Request Review

I'll review this PR that introduces Tiptap editor for prompt files. Here's my analysis plan:

Review Checklist:

  • Read repository guidelines (CLAUDE.md)
  • Analyze the modified RulesPrompt.tsx
  • Review the new SimpleRichTextEditor.tsx component
  • Check package.json dependencies
  • Assess code quality and best practices
  • Identify potential bugs or issues
  • Review performance considerations
  • Check security concerns
  • Evaluate test coverage

Initial Analysis

Files Changed:

  • RulesPrompt.tsx - Modified to use new rich text editor
  • SimpleRichTextEditor.tsx - New Tiptap-based editor component
  • package.json - Added Tiptap dependencies
  • pnpm-lock.yaml - Lockfile updates

Dependencies Added:

  • @tiptap/extension-placeholder@2.26.0
  • @tiptap/pm@2.12.0
  • @tiptap/react@2.12.0
  • @tiptap/starter-kit@2.12.0
  • tiptap-markdown@0.8.10

Detailed Review

Code Quality & Best Practices

  • Good TypeScript usage: Well-defined interfaces and proper typing
  • Clean component structure: Clear separation of concerns in both files
  • Proper React patterns: Good use of hooks (useCallback, useEffect, useEditor)
  • Consistent styling: Uses the project's design system (cn utility, proper CSS classes)
  • Accessible: Includes proper ARIA attributes and error handling

⚠️ Potential Bugs & Issues

High Priority:

  1. Form synchronization issue in SimpleRichTextEditor.tsx:130:

    value={editor?.storage.markdown.getMarkdown() || ""}

    This could cause the form to be out of sync if the editor isn't ready. Consider using state to track the current value.

  2. Missing dependency in useEffect at line 104-111:

    useEffect(() => {
      if (editor && (defaultValue || "") !== editor.storage.markdown.getMarkdown()) {
        editor.commands.setContent(defaultValue || "");
      }
    }, [defaultValue, editor]);

    This comparison might not work correctly since getMarkdown() returns formatted markdown while defaultValue might be plain text.

Medium Priority:
3. Potential infinite loop in form registration: The onUpdate callback triggers registerProps.onChange, which might cause re-renders and affect the editor state.

  1. Missing null check in RulesPrompt.tsx:251: The component assumes rulesPrompt exists when passing to defaultValue.

🔄 Performance Considerations

Room for improvement:

  • The editor instance is created on every render. Consider memoizing the editor configuration
  • The onUpdate callback recreates on every render due to dependencies. This is acceptable but could be optimized
  • The markdown conversion happens on every update, which might be expensive for long content

Acceptable:

  • The useEditor hook handles most performance optimizations internally
  • The component properly handles disabled states

🔒 Security Concerns

Low Risk:

  • Tiptap with StarterKit is generally safe as it limits HTML output
  • The markdown extension doesn't appear to allow arbitrary HTML
  • The component only enables basic formatting (bold, headings, lists)

Recommendations:

  • Consider adding input sanitization for the markdown output
  • Review if the markdown content needs additional validation before saving

🧪 Test Coverage

Missing:

  • No tests for the new SimpleRichTextEditor component
  • No tests for the updated RulesPrompt component functionality
  • No integration tests for the editor-form integration

Recommendations:

  • Add unit tests for the editor component
  • Test form integration scenarios
  • Test edge cases (empty content, markdown formatting, etc.)

Summary

This is a solid implementation that replaces a simple text input with a rich text editor. The code quality is good and follows React best practices. However, there are some potential synchronization issues between the editor and form state that should be addressed.

Priority Actions:

  1. Fix the form synchronization logic in SimpleRichTextEditor
  2. Add proper error handling for edge cases
  3. Consider adding tests for the new functionality

Nice to have:

  • Performance optimizations for large content
  • Additional validation for markdown content
  • Better handling of editor state transitions

Overall, this is a well-implemented feature that enhances the user experience while maintaining code quality standards.

@claude
Copy link

claude bot commented Jul 11, 2025

Claude finished @elie222's task —— View job


PR Review: Use tiptap editor for prompt file

Review Checklist:

  • Read and analyze all changed files
  • Review code quality and best practices
  • Check for potential bugs or issues
  • Assess performance considerations
  • Evaluate security concerns
  • Review test coverage
  • Provide comprehensive feedback

🔍 Review Summary

This PR successfully replaces a plain text input with a TipTap-based rich text editor for the rules prompt. The implementation is well-structured with good TypeScript integration, though there are some areas for improvement.

✅ Strengths

Code Quality

  • Clean Architecture: The SimpleRichTextEditor component follows React best practices with proper separation of concerns
  • Strong TypeScript Usage: Well-defined interfaces and proper typing throughout
  • Proper React Hook Form Integration: Uses useImperativeHandle and forwardRef correctly for form integration
  • Configurability: Good prop interface allowing customization of placeholder, styling, and behavior

Implementation Details

  • Appropriate TipTap Configuration: Minimal feature set configured (bold, headings, lists, blockquotes) suitable for prompt editing
  • Markdown Support: Proper markdown input/output handling with tiptap-markdown extension
  • Accessibility: Proper ARIA attributes and focus management

⚠️ Issues & Recommendations

1. Potential Memory Leak (Medium Priority)

File: apps/web/components/editor/SimpleRichTextEditor.tsx:48-120

The editor instance may not be properly cleaned up. Consider adding:

useEffect(() => {
  return () => {
    editor?.destroy();
  };
}, [editor]);

2. Form Synchronization Issue (Medium Priority)

File: apps/web/components/editor/SimpleRichTextEditor.tsx:147-156

The useEffect for syncing external value changes could cause infinite loops if value and editor content differ slightly (whitespace, formatting). Consider:

useEffect(() => {
  if (
    editor &&
    value !== undefined &&
    value.trim() !== editor.storage.markdown.getMarkdown().trim()
  ) {
    editor.commands.setContent(value);
  }
}, [value, editor]);

3. Hidden Input State Sync (Low Priority)

File: apps/web/components/editor/SimpleRichTextEditor.tsx:172-176

The hidden input value isn't updated when the editor content changes outside of the onUpdate callback. Consider using a state variable:

const [currentValue, setCurrentValue] = useState('');
// Update in onUpdate callback and use in hidden input

4. Performance Optimization (Low Priority)

File: apps/web/components/editor/SimpleRichTextEditor.tsx:86-97

The onUpdate callback is recreated on every render due to dependencies. Consider using useCallback with stable dependencies:

const onUpdate = useCallback(
  ({ editor }: { editor: Editor }) => {
    const markdown = editor.storage.markdown.getMarkdown();
    if (registerProps?.onChange) {
      registerProps.onChange({
        target: { name: name || registerProps.name, value: markdown },
      });
    }
  },
  [registerProps?.onChange, registerProps?.name, name],
);

5. Error Handling (Low Priority)

File: apps/web/components/editor/SimpleRichTextEditor.tsx:126-143

The ref methods don't handle cases where the editor might be null or destroyed:

insertText: (text: string) => {
  if (editor && !editor.isDestroyed) {
    editor.chain().focus().insertContent(text).run();
  }
},

🔒 Security Considerations

XSS Prevention

  • Good: The html: false configuration in the Markdown extension prevents HTML injection
  • Good: Content is properly sanitized through TipTap's markdown processing

Content Validation

  • Consider: Adding input length limits to prevent excessively large prompts
  • Consider: Validating markdown content for malicious patterns

🚀 Performance Considerations

Bundle Size Impact

  • Impact: TipTap adds ~150KB to the bundle, but this is reasonable for a rich text editor
  • Good: The minimal extension configuration keeps the bundle size manageable

Runtime Performance

  • Good: Editor lazy-loads and only renders when needed
  • Consider: For very large prompts, consider implementing virtual scrolling

🧪 Test Coverage

Missing Tests

  • Critical: No unit tests for the new SimpleRichTextEditor component
  • Important: No integration tests for the form integration
  • Consider: Add tests for:
    • Form synchronization
    • Markdown input/output
    • Error handling
    • Accessibility

Recommended Test Structure

// __tests__/components/editor/SimpleRichTextEditor.test.tsx
describe('SimpleRichTextEditor', () => {
  it('should render with placeholder', () => {});
  it('should sync with form values', () => {});
  it('should handle markdown input/output', () => {});
  it('should handle ref methods', () => {});
});

📦 Dependencies

New Dependency Analysis

  • Added: tiptap-markdown@0.8.10 - Well-maintained, actively developed
  • Good: Uses existing TipTap ecosystem already in the project
  • Low Risk: No known security vulnerabilities

🎯 Final Recommendations

  1. Fix the potential memory leak with proper cleanup
  2. Improve form synchronization logic to prevent edge cases
  3. Add comprehensive tests for the new component
  4. Consider performance optimizations for the callback functions
  5. Add input validation for very large content

🏆 Overall Assessment

This is a solid implementation that successfully replaces the plain text input with a rich text editor. The code quality is good, TypeScript usage is excellent, and the integration is clean. The main concerns are around proper cleanup, form synchronization edge cases, and the lack of tests.

Rating: ⭐⭐⭐⭐ (4/5) - Good implementation with minor improvements needed


@socket-security
Copy link

socket-security bot commented Jul 11, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​tiptap/​extension-placeholder@​2.26.11001007199100
Updated@​tiptap/​pm@​2.12.0 ⏵ 2.26.1991007299 +1100
Updated@​tiptap/​starter-kit@​2.12.0 ⏵ 2.26.1991007299 +1100
Updated@​tiptap/​react@​2.12.0 ⏵ 2.26.199 +110076 +199 +1100

View full report

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
apps/web/components/editor/SimpleRichTextEditor.tsx (1)

182-183: Add display name for better debugging experience.

Consider adding a display name to the forwardRef component for better React DevTools experience.

Add after line 182:

   },
 );
+
+SimpleRichTextEditor.displayName = "SimpleRichTextEditor";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 168b1da and 1968be8.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • apps/web/app/(app)/[emailAccountId]/assistant/RulesPrompt.tsx (2 hunks)
  • apps/web/components/editor/SimpleRichTextEditor.tsx (1 hunks)
  • apps/web/package.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
apps/web/**/*.{ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • apps/web/CLAUDE.md
apps/web/app/**/*

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • apps/web/CLAUDE.md
apps/web/**/*.tsx

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • apps/web/CLAUDE.md
**/*.tsx

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/data-fetching.mdc
  • .cursor/rules/form-handling.mdc
**/*.{ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/form-handling.mdc
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-06-23T12:27:33.499Z
Learning: For multi-line text input, use the `Input` component with `type="text"`, `autosizeTextarea`, and `rows` props to create an autosizing textarea, and handle validation and errors similarly to single-line inputs.
apps/web/package.json (1)
Learnt from: CR
PR: elie222/inbox-zero#0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:02:16.137Z
Learning: Applies to apps/web/**/{.env.example,env.ts,turbo.json} : Add environment variables to `.env.example`, `env.ts`, and `turbo.json`
apps/web/app/(app)/[emailAccountId]/assistant/RulesPrompt.tsx (7)
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-06-23T12:27:33.499Z
Learning: For multi-line text input, use the `Input` component with `type="text"`, `autosizeTextarea`, and `rows` props to create an autosizing textarea, and handle validation and errors similarly to single-line inputs.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.tsx : Show validation errors inline next to form fields
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.tsx : Validate form inputs before submission
Learnt from: CR
PR: elie222/inbox-zero#0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:02:16.137Z
Learning: Applies to apps/web/**/*.tsx : Follow consistent naming conventions (PascalCase for components)
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.{ts,tsx} : Use descriptive error messages
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-06-23T12:26:36.694Z
Learning: Structure data in LLM prompts using XML-like tags, remove excessive whitespace, truncate long inputs, and format data consistently across similar functions.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-06-23T12:27:33.499Z
Learning: For form text inputs in React using Shadcn UI, use the `Input` component with `registerProps` from a form library (such as react-hook-form) and pass any validation errors to the `error` prop.
apps/web/components/editor/SimpleRichTextEditor.tsx (5)
Learnt from: CR
PR: elie222/inbox-zero#0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:02:16.137Z
Learning: Applies to apps/web/**/*.tsx : Prefer functional components with hooks
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.tsx : Validate form inputs before submission
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.tsx : Show validation errors inline next to form fields
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-06-23T12:27:33.499Z
Learning: For multi-line text input, use the `Input` component with `type="text"`, `autosizeTextarea`, and `rows` props to create an autosizing textarea, and handle validation and errors similarly to single-line inputs.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-06-23T12:27:33.499Z
Learning: For form text inputs in React using Shadcn UI, use the `Input` component with `registerProps` from a form library (such as react-hook-form) and pass any validation errors to the `error` prop.
🧬 Code Graph Analysis (1)
apps/web/components/editor/SimpleRichTextEditor.tsx (2)
apps/web/components/assistant-chat/markdown.tsx (1)
  • Markdown (103-106)
apps/web/utils/index.ts (1)
  • cn (4-6)
🔇 Additional comments (2)
apps/web/app/(app)/[emailAccountId]/assistant/RulesPrompt.tsx (1)

253-259: Great improvement to the placeholder text!

The markdown-formatted placeholder with bullet points and examples provides clear guidance to users on how to structure their prompts. This enhances the user experience significantly.

apps/web/components/editor/SimpleRichTextEditor.tsx (1)

48-120: Well-implemented rich text editor component!

The component is properly structured with:

  • Clean TypeScript types and interfaces
  • Proper integration with react-hook-form
  • Minimal but sufficient TipTap extensions
  • Good use of forwardRef for imperative methods
  • Responsive styling with Tailwind CSS
  • Proper error handling

The minimal feature set (bold, headings, lists, blockquote) is appropriate for a prompt editor.

@claude
Copy link

claude bot commented Jul 11, 2025

Claude encountered an error —— View job


I'll analyze this and get back to you.

@claude
Copy link

claude bot commented Jul 12, 2025

Claude encountered an error —— View job


I'll analyze this and get back to you.

@claude
Copy link

claude bot commented Jul 12, 2025

Claude encountered an error —— View job


I'll analyze this and get back to you.

@elie222 elie222 merged commit 3007124 into main Jul 12, 2025
7 of 10 checks passed
@claude
Copy link

claude bot commented Jul 12, 2025

Claude encountered an error —— View job


I'll analyze this and get back to you.

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

Comments