// ChatPane — mirrors ui/src/components/chat/* with user/ask/result/progress bubbles function Bubble({ role, children, footer }) { const isUser = role === 'user'; const style = { maxWidth: '85%', padding: '10px 14px', borderRadius: 16, fontSize: 13, lineHeight: 1.55, whiteSpace: 'pre-wrap', wordBreak: 'break-word', }; if (isUser) { Object.assign(style, { background: '#2563eb', color: '#fff', borderBottomRightRadius: 4, alignSelf: 'flex-end' }); } else if (role === 'ask') { Object.assign(style, { background: '#fef9c3', color: '#854d0e', border: '1px solid #fde68a', borderBottomLeftRadius: 4 }); } else if (role === 'result') { Object.assign(style, { background: '#ecfdf5', color: '#065f46', border: '1px solid #a7f3d0', borderBottomLeftRadius: 4 }); } else { Object.assign(style, { background: '#fff', color: '#0f172a', border: '1px solid #e2e8f0', borderBottomLeftRadius: 4 }); } return (
{children}
{footer &&
{footer}
}
); } function ProgressBubble({ text }) { return (
{text}
); } function ChatHeader({ task, onOpenDetail, detailOpen }) { return (
TASK #{task.id}
{task.title}
); } function Composer({ onSend }) { const [text, setText] = React.useState(''); const send = () => { if (!text.trim()) return; onSend(text.trim()); setText(''); }; return (