import re
# Read the RichChatInput file
with open('ui/desktop/src/components/RichChatInput.tsx', 'r') as f:
content = f.read()
print("Fixing RichChatInput processing loop to handle both actions and mentions...")
# Find the entire processing loop section and replace it
# Look for the section that starts with "Process all matches in order"
old_processing_section = ''' // Process all matches in order
for (const matchData of allMatches) {
const { type, match, index, length, content } = matchData;
console.log('✅ Found action match:', match);
const beforeAction = value.slice(lastIndex, match.index);
const actionLabel = match[1];
console.log('📝 Processing action:', { beforeAction, actionLabel, matchIndex: match.index });
// Add text before action with potential cursor
if (beforeAction) {
// Split text by cursor position to insert cursor at the right spot
let textWithCursor = [];
for (let i = 0; i < beforeAction.length; i++) {
if (isFocused && cursorPosition === currentPos) {
textWithCursor.push(
);
}
textWithCursor.push(beforeAction[i]);
currentPos++;
}
parts.push(
{textWithCursor}
);
}
// Find matching action
const actionEntry = Object.entries(ACTION_MAP).find(
([_, config]) => config.label === actionLabel
);
if (actionEntry) {
const [actionId, config] = actionEntry;
parts.push(
handleRemoveAction(actionLabel)}
/>
);
} else {
// If no matching action, render as text
parts.push(
{match[0]}
);
}
currentPos += match[0].length;
lastIndex = match.index + match[0].length;
}'''
new_processing_section = ''' // Process all matches in order
for (const matchData of allMatches) {
const { type, match, index, length, content } = matchData;
console.log('✅ Found match:', { type, content, index });
// Add text before this match with potential cursor
const beforeMatch = value.slice(lastIndex, index);
if (beforeMatch) {
let textWithCursor = [];
for (let i = 0; i < beforeMatch.length; i++) {
if (isFocused && cursorPosition === currentPos) {
textWithCursor.push(
);
}
textWithCursor.push(beforeMatch[i]);
currentPos++;
}
parts.push(
{textWithCursor}
);
}
// Add cursor before match if needed
if (isFocused && cursorPosition === currentPos) {
parts.push(
);
}
if (type === 'action') {
// Handle action pills
const actionLabel = content;
const actionEntry = Object.entries(ACTION_MAP).find(
([_, config]) => config.label === actionLabel
);
console.log('🏷️ Creating action pill:', { actionLabel, actionEntry });
if (actionEntry) {
const [actionId, config] = actionEntry;
parts.push(
handleRemoveAction(actionLabel)}
/>
);
} else {
// If no matching action, render as text
parts.push(
{match[0]}
);
}
} else if (type === 'mention') {
// Handle mention pills
const fileName = content; // filename without @
const filePath = `@${fileName}`; // full mention text
console.log('📁 Creating mention pill:', { fileName, filePath });
parts.push(
handleRemoveMention(fileName)}
/>
);
}
currentPos += length;
lastIndex = index + length;
}'''
content = content.replace(old_processing_section, new_processing_section)
# Write the modified content back
with open('ui/desktop/src/components/RichChatInput.tsx', 'w') as f:
f.write(content)
print("✅ Fixed RichChatInput processing loop:")
print(" - Updated to use new combined action/mention processing")
print(" - Added proper mention pill creation")
print(" - Added debugging logs for both types")
print(" - Should now render @filename as green pills")