const fs = require('fs'); const path = require('path'); const filePath = path.join(__dirname, '..', 'components', 'contextual-ai-chat.tsx'); let src = fs.readFileSync(filePath, 'utf8'); // ─── FIX 1: make inject buttons always visible on last assistant msg ────────── // Replace the hover-gated condition with always-visible for last msg const OLD_BUTTONS_CONDITION = ` {/* Hover-actions \u2014 visible only on assistant messages */}\r\n {isAssistant && onApplyToNote && (\r\n
`; const NEW_BUTTONS_CONDITION = ` {/* Inject buttons \u2014 always visible on last assistant msg */}\r\n {isAssistant && onApplyToNote && (() => {\r\n const lastAssistantId = messages.filter(m => m.role === 'assistant').at(-1)?.id\r\n const alwaysShow = msg.id === lastAssistantId\r\n return (\r\n
`; // Also need to close the IIFE const OLD_BUTTONS_CLOSE = `
\r\n )}\r\n
`; const NEW_BUTTONS_CLOSE = ` \r\n )\r\n })()}\r\n `; if (src.includes(OLD_BUTTONS_CONDITION)) { src = src.replace(OLD_BUTTONS_CONDITION, NEW_BUTTONS_CONDITION); console.log('Fix 1a: buttons condition updated'); } else { console.error('Fix 1a: OLD_BUTTONS_CONDITION not found!'); process.exit(1); } if (src.includes(OLD_BUTTONS_CLOSE)) { src = src.replace(OLD_BUTTONS_CLOSE, NEW_BUTTONS_CLOSE); console.log('Fix 1b: buttons IIFE close updated'); } else { console.error('Fix 1b: OLD_BUTTONS_CLOSE not found!'); process.exit(1); } // ─── FIX 2: Move preview panel OUTSIDE the scrollable div ──────────────────── // The scrollable div ends with: messagesEndRef then // We need to: // A) Remove the preview block from inside the scrollable area (already was removed in previous sessions since it was added after messagesEndRef) // B) Add preview as shrink-0 panel between the scroll div and controls // Find the closing of the scrollable area + start of controls const OLD_SCROLL_END = `
\r\n
\r\n\r\n {/* Scope & Tone Control Area */}`; const NEW_SCROLL_END = `
\r\n
\r\n\r\n {/* \u2550\u2550 Inject Preview Panel \u2014 fixed, always visible, NO scroll needed \u2550\u2550 */}\r\n {resourceEnriching && (\r\n
\r\n \r\n Traitement IA en cours...\r\n
\r\n )}\r\n {resourcePreview && !resourceEnriching && (\r\n
\r\n
\r\n \r\n {resourcePreview.source === 'complete' ? 'Compl\u00e9t\u00e9 par IA'\r\n : resourcePreview.source === 'merge' ? 'Fusionn\u00e9 par IA'\r\n : 'Aper\u00e7u'}\r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n setResourcePreview(null)}\r\n className="flex-1 text-[11px] py-1.5 rounded-lg border border-border/60 text-muted-foreground hover:bg-muted transition-colors"\r\n >\r\n Annuler\r\n \r\n {\r\n if (onApplyToNote && resourcePreview) {\r\n onApplyToNote(resourcePreview.text)\r\n setResourcePreview(null)\r\n setResourceText('')\r\n toast.success('Appliqu\u00e9 \u00e0 la note')\r\n }\r\n }}\r\n disabled={!onApplyToNote}\r\n className="flex-1 text-[11px] py-1.5 rounded-lg bg-primary text-primary-foreground font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 flex items-center justify-center gap-1"\r\n >\r\n \r\n Appliquer \u00e0 la note\r\n \r\n
\r\n
\r\n )}\r\n\r\n {/* Scope & Tone Control Area */}`; if (src.includes(OLD_SCROLL_END)) { src = src.replace(OLD_SCROLL_END, NEW_SCROLL_END); console.log('Fix 2: preview panel moved outside scroll'); } else { console.error('Fix 2: OLD_SCROLL_END not found!'); // Show what we're looking for context const idx = src.indexOf('messagesEndRef'); console.error('Context around messagesEndRef:', JSON.stringify(src.slice(idx-20, idx+200))); process.exit(1); } fs.writeFileSync(filePath, src); console.log('Done!');