- Detect presence of code blocks using regex
- Trigger display-based height measurement for both live IDE and permanent code blocks
- Measure display layer scrollHeight when code blocks are present
- Prevents code blocks from being cut off or drifting
- Ensures proper container height even after exiting code mode
- Fixes height sync for backtick code blocks
- When exiting code mode with double-Enter, convert to triple-backtick format
- Format: ```language\ncode\n```
- Code block remains visible and styled after exit
- User can continue typing in normal mode below the code block
- Preserves syntax highlighting in the final message
- Fixes issue where code block disappeared after exiting
- Detect when code content ends with double newline (\n\n)
- Exit code mode automatically when double newline detected
- Remove the #language trigger from the value
- Keep the code content as normal text
- Move cursor to end of text after exiting
- Allows user to continue typing in normal mode after code
- Press Enter twice in code mode to exit
- Calculate cursor position within code content
- Split code at cursor position for rendering
- Render code before cursor, cursor, then code after cursor
- Use inline span elements for proper cursor placement
- Cursor now appears at current typing position, not at end
- Fixes confusing cursor placement issue in code mode
- Changed regex from (\s|$) to (?![a-z]) negative lookahead
- Now matches #python immediately without requiring space
- Prevents #pythonprint from breaking the trigger
- Auto-inserts newline as soon as full language name is typed
- Updated both detection and rendering regex to match
- Fixes issue where typing continued on trigger line
- When #language is typed, automatically insert a newline after it
- Move cursor to the new line (inside the code block)
- Prevents typing from continuing on the trigger line
- Only inserts newline if one doesn't already exist
- Updates codeMode.startPos to account for the inserted newline
- Fixes issue where typing after #python would break the code box
- Add useEffect that triggers when codeMode changes
- Measure display layer's actual scrollHeight instead of textarea's
- Textarea doesn't know about styled code block height
- Use 50ms delay to ensure SyntaxHighlighter has rendered
- This fixes initial load where code block was below the fold
- Ensures containerHeight is properly set for code mode
- Changed regex from ^# to # (removed start-of-line anchor)
- Code mode now activates when #language appears anywhere
- Text before the trigger is preserved and displayed
- Example: 'Here is some code #python print(hello)' works!
- Maintains all existing functionality
- Type #python, #javascript, #typescript, etc. to activate code mode
- Live syntax highlighting as you type
- Enter key inserts newlines (doesn't send message)
- Cmd/Ctrl+Enter to send message
- Language badge displayed
- IDE-style visual appearance
- Supports 30+ programming languages
- Detect code blocks with triple backtick syntax ()
- Render using react-syntax-highlighter with VS Code dark theme
- Display language badge in top-right corner
- Support all common programming languages
- Maintain cursor positioning and height synchronization
- Code blocks excluded from spell checking
- Remove syncDisplayHeight and ensureStyleConsistency calls from resetHeight
- These were recalculating height based on scrollHeight, preventing shrinking
- Now resetHeight just sets to minHeight directly
- Add console logs for debugging
- Ensures syncDisplayHeight runs whenever value prop changes
- Fixes issue where height wasn't recalculating on text deletion
- Complements existing ResizeObserver with direct value monitoring
- Added value dependency to syncDisplayHeight callback
- Ensures height recalculation triggers when content changes
- Fixes issue where input stayed large after deleting text
Fixed the rendering layer having slightly larger line spacing than the input
layer by eliminating CSS class interference and enforcing exact line height:
1. Removed conflicting CSS classes:
- Removed 'leading-relaxed' class from content divs
- This class was applying Tailwind's line height that conflicted with computed values
- Removed 'min-h-[1.5em]' that could interfere with line height calculations
2. Enforced exact line height matching:
- Use setProperty() with '!important' to override any CSS inheritance
- Calculate minHeight using the same computed line height values
- Ensure display layer uses identical line height as textarea
3. Child element line height inheritance:
- Force all child elements to inherit the parent's exact line height
- Prevents individual spans/divs from having different line spacing
- Uses '!important' to override any Tailwind or other CSS classes
This should eliminate the line spacing discrepancy that was causing
highlights to gradually drift away from the text alignment.
Fixed the gradual highlight misalignment that gets worse with each line
by ensuring perfect style synchronization between layers:
1. Comprehensive style synchronization:
- Replaced simple line height sync with full style consistency
- Copies all computed styles that affect text layout from textarea
- Includes fontSize, fontFamily, letterSpacing, wordSpacing
- Ensures identical padding values to prevent cumulative drift
2. Box model consistency:
- Added explicit boxSizing: 'border-box' to display layer
- Matches textarea box model to prevent layout differences
- Eliminates padding/border calculation discrepancies
3. Rounded line height calculations:
- Uses Math.round() to prevent fractional pixel accumulation
- Eliminates subpixel differences that compound over multiple lines
- Ensures consistent line spacing throughout the text
4. Text rendering consistency:
- Copies textRendering, webkitFontSmoothing, mozOsxFontSmoothing
- Prevents browser-specific text rendering differences
- Eliminates subpixel positioning variations
This should eliminate the gradual 'walking away' of highlights and
fix the bottom text cutoff issue by ensuring perfect layer alignment.
Fixed the issue where highlights (spell check, selection) were offset from
text due to inconsistent line height calculations between layers:
1. Dynamic line height calculation:
- Replaced hardcoded 21px with computed line height from actual textarea
- Uses window.getComputedStyle() to get real rendered line height
- Handles both 'normal' and explicit line height values properly
2. Explicit line height synchronization:
- Sets both textarea and display layers to use identical pixel line heights
- Added ensureLineHeightConsistency() function for ongoing sync
- Called after every height sync to maintain consistency
3. Consistent cursor positioning:
- Updated resetHeight method to use calculated line height
- All line-based calculations now use the same computed value
- Eliminates discrepancies between layers
This ensures that spell check highlights, selection highlights, and cursor
positioning are perfectly aligned with the actual rendered text, regardless
of font size, browser differences, or CSS inheritance.
- Update built-in command badges to use grey styling matching ActionPopover
- Add blur effect to disabled edit/copy/delete buttons for built-in commands
- Position built-in pill as overlay on top of disabled action buttons
- Center align action buttons within their container space
- Add 8px left spacing to built-in pill overlay for better visual balance
Changed keyboard selection to use the same subtle gray background as mouse hover
instead of the bright blue. This creates a unified visual experience where:
- Mouse hover: Light gray background
- Keyboard selection: Same light gray background
- Both states look identical and use the system's natural hover styling
Removed the complex text color overrides since we're now using the same
background for both hover and selection states. This creates a more
subtle and consistent user experience.
Changed hover background from subtle 'hover:bg-background-muted' to more
visible 'hover:bg-gray-100 dark:hover:bg-gray-700' so users can clearly
see which item they're hovering over with their mouse.
Now both mouse and keyboard interactions have clear visual feedback:
- Mouse hover: Light gray background (gray-100/gray-700)
- Keyboard selection: Bright blue background (blue-500)
- Both provide clear indication of what will be selected
Updated both ActionPopover and MentionPopover to use more visible selection styling:
- Changed selected background from bgProminent to bright blue-500
- Added proper text color overrides for selected state
- Icon colors change to white when selected
- Description text uses blue-100 for better contrast on blue background
- Custom badge gets blue-400 background when parent is selected
This makes it crystal clear which item is selected when navigating with arrow keys.
Users can now easily see what they're about to select with both mouse hover
and keyboard navigation.
Fixed the issue where arrow up/down keys weren't working when the ActionPopover
was open after typing '/'. The problem was in the synthetic event creation in
RichChatInput's handleTextareaKeyDown function.
Changes:
- Properly preserve all keyboard event properties (key, code, keyCode, etc.)
- Bind event methods correctly to maintain proper context
- Ensure target/currentTarget reference the display div for positioning
- Maintain all event properties needed by ChatInput's handleKeyDown
This fixes the keyboard navigation for both ActionPopover (/) and MentionPopover (@)
when using the new RichChatInput component with pills and spell checking.
- Apply consistent hover styling from settings to both popovers
- Use hover:bg-background-muted for better visual feedback
- Change border-radius from rounded-md to rounded-lg for consistency
- Update transition from transition-colors to transition-all for smoother animations
- Maintain selected state styling with bg-bgProminent
This creates a consistent hover experience across the application where users
can clearly see what they're about to select in both @ and / popovers.
- Add search functionality to ActionPopover when typing / + text
- Show starred commands first, then all commands during search
- Add 'Create Command' button in empty states with modal integration
- Implement visual action pills in both input and user messages
- Hide expanded 'what AI sees' text from UI while sending full prompts to AI
- Add dynamic action mapping from localStorage for custom commands
- Implement action pill expansion in useMessageStream before API calls
- Add proper keyboard navigation and modal state management
- Include usage tracking for custom commands
Files modified:
- ChatInput.tsx: Query passing, modal integration, keyboard navigation
- ActionPopover.tsx: Search functionality and empty state enhancements
- RichChatInput.tsx: Dynamic action mapping from localStorage
- MessageContent.tsx: Dynamic action mapping from localStorage
- useMessageStream.ts: Action pill expansion before API calls
- Add CustomCommandsSettings component with row-based design matching Mode section
- Integrate AddCustomCommandModal using proper Dialog components for consistent styling
- Remove category filtering and inline editing for cleaner UX
- Update modal to use proper Dialog background instead of dark overlay
- Remove category field from modal form for simplified command creation
- Apply subtle text colors to form helper text for better visual hierarchy
- Remove preview section from modal to reduce height and improve usability
- Add proper header styling with CardTitle and CardDescription
- Update command icons to display without background circles
- Implement proper padding and spacing throughout the interface
- Connect modal functionality to Plus button and edit actions
- Preserve existing command categories while preventing new category assignment
- Remove header and description from Custom Commands card
- Convert card-style layout to row-based design matching mode section
- Update styling to use proper text-* and background-* classes
- Remove unused onClose parameter
- Make commands display as compact rows with inline actions
- Improve empty state styling and sizing
- Add comprehensive custom slash commands system
- Users can create /command shortcuts that expand to full prompts
- ActionPopover now only shows user-created custom commands
- Add custom commands management in Settings → Chat
- Implement pill rendering: users see [Command Label], AI gets full prompt
- Add localStorage-based storage with upgrade path to API
- Include example commands: document, review, explain, optimize, test
- Add complete type system with validation and categories
- Support usage tracking, favorites, and command management
- Fix pill expansion to use proper labels instead of IDs
Components added:
- CustomCommandsSettings: Full CRUD interface for command management
- AddCustomCommandModal: Modal for creating/editing commands
- useCustomCommands: Hook for command state management
- customCommands types: Complete type system with validation
Components modified:
- ActionPopover: Filtered to show only custom commands
- ChatInput: Fixed handleActionSelect for proper pill rendering
- ChatSettingsSection: Added custom commands card
- Added UI components: label, textarea for form inputs
- Force complete height reset to 0px before measuring scrollHeight
- Add reflow trigger to ensure accurate measurements
- Prevents input from staying large when content is removed
- Update SpellCheckTooltip styling to match commit 663c921 design
- Add numbered suggestions with hover highlighting and blue selection states
- Include keyboard hints and improved action buttons with icons
- Fix tooltip positioning to appear directly above words with minimal gap
- Remove translateY(-100%) transform that was pushing tooltip too far away
- Position tooltip 5px above word with only horizontal centering
- Maintain viewport boundary detection to prevent cutoff on edges
- Improve overall tooltip UX with professional styling and close proximity
- Add back SpellCheckTooltip component with custom styling and suggestions
- Restore custom spell checking logic in RichChatInput component
- Add back IPC spell-check and spell-suggestions handlers in main process
- Re-enable custom misspelled word highlighting with red background
- Restore hover/click popover tooltips with spell suggestions
- Disable native browser spell checking (spellCheck={false}) to use custom implementation
- Add back all spell checking state management and event handlers
This provides the custom spell checking UI with highlighting and popovers as requested.
- Remove custom spell checking logic from RichChatInput component
- Remove SpellCheckTooltip and SpellCheckContextMenu components
- Remove IPC spell-check and spell-suggestions handlers from main process
- Enable native browser spell checking with spellCheck={true} on textarea
- Simplify component by removing misspelled word highlighting and tooltip state
- Users now get familiar OS-native spell check with right-click context menus
This provides better UX with system dictionary integration and familiar behavior.
- Changed cursor transform from translateY(-0.1em) to translateY(0.1em)
- Cursor now appears properly centered with text instead of floating above
- Applied fix to all cursor instances throughout RichChatInput component
- Changed cursor top position from 0px to 0.125em
- Aligns cursor with text baseline instead of sitting below it
- Improves visual consistency with placeholder text
- Position placeholder text absolutely to prevent displacement
- Position cursor absolutely at start of empty input
- Maintains visual stability when focusing empty input
- Set cursor width to 1px for minimal visual footprint
- Removed left margin to prevent text from being pushed left/right
- Applied consistent styling across all cursor instances
- Cursor now appears as thin line without displacing text
- Changed selection background to #BBD6FB for softer, more pleasant highlighting
- Provides excellent visibility while being gentle on the eyes
- Custom blue tone as requested by user
- Changed selection background from #3b82f6 (blue-500) to #60a5fa (blue-400)
- Provides lighter, more subtle selection highlighting
- Maintains clear selection feedback while being easier on the eyes
- Changed selection text color from white to transparent
- Maintains blue selection background while eliminating white text artifacts
- Fixes holographic effect caused by visible selected text
- Changed from rgba(0,0,0,0) back to transparent for cleaner text hiding
- Added WebkitTextFillColor: transparent to eliminate text visibility artifacts
- Should maintain blue selection highlighting while removing ghost text effect
- Changed opacity from 0.01 to 1 to allow selection highlighting
- Used rgba(0,0,0,0) for transparent text while keeping element visible
- Added explicit user-select CSS properties
- Made selection text fully opaque white for better visibility