import assert from 'node:assert/strict' import { renderToStaticMarkup } from 'react-dom/server' import { normalizeUserContent, trimUserContent } from '../src/shared/user-content' import type { UserContentBlock } from '../src/shared/conversation' import { userContentToSlate, slateToUserContent } from '../src/renderer/src/workbuddy/references/ReferenceContentEditor' import { MessageQuoteTag } from '../src/renderer/src/workbuddy/conversation/MessageQuoteTag' import { UserInlineContent } from '../src/renderer/src/workbuddy/references/UserInlineContent' import { ReferenceIcon } from '../src/renderer/src/workbuddy/references/ContentReferenceTag' const collections = { quotes: [{ id: 'q' }], attachments: [{ id: 'a' }], resources: ['C:/资料/说明.md'], skills: [{ id: 's' }] } const blocks: UserContentBlock[] = [{ type: 'text', text: '前😀' }, { type: 'quote', id: 'q' }, { type: 'text', text: '\n中\n' }, { type: 'attachment', id: 'a' }, { type: 'resource', id: collections.resources[0] }, { type: 'skill', id: 's' }, { type: 'text', text: '后' }] const normalized = normalizeUserContent(blocks, '前😀\n中\n后', collections) assert.deepEqual(normalized, blocks, 'mixed order must survive validation') assert.deepEqual(normalizeUserContent(slateToUserContent(userContentToSlate(blocks)), '前😀\n中\n后', collections), blocks, 'paragraphs, inline voids, adjacent references and Unicode must round trip without changing the prompt') assert.deepEqual(normalizeUserContent([{ type: 'text', text: 'safe' }, { type: 'attachment', id: 'forged' }, { type: 'quote', id: 'q' }, { type: 'quote', id: 'q' }], 'safe', { quotes: [{ id: 'q' }] }), [{ type: 'text', text: 'safe' }, { type: 'quote', id: 'q' }], 'layout cannot introduce payloads or duplicate reference identities') assert.deepEqual(normalizeUserContent([{ type: 'text', text: 'changed' }], 'trusted', {}), [{ type: 'text', text: 'trusted' }], 'view metadata cannot replace model text') assert.deepEqual(trimUserContent([{ type: 'text', text: ' 前' }, { type: 'quote', id: 'q' }, { type: 'text', text: '后 ' }]), [{ type: 'text', text: '前' }, { type: 'quote', id: 'q' }, { type: 'text', text: '后' }], 'trimming cannot flatten the inline reference order') const quote = { id: 'q', sourceId: 'm:table:t', kind: 'table' as const, markdown: '| sensitive snapshot |', preview: '| sensitive snapshot |' } const tag = renderToStaticMarkup() assert.ok(tag.includes('会话表格') && !tag.includes('sensitive snapshot'), 'legacy table previews cannot leak raw Markdown into the label or tooltip') assert.ok(tag.includes('viewBox="0 0 14 14"') && tag.includes('_fileTag_1krka_111'), 'table must use its actual SVG and pill variant') assert.ok(!tag.includes(') assert.ok(message.indexOf('前') < message.indexOf('会话表格') && message.indexOf('会话表格') < message.indexOf('报告.pdf') && message.indexOf('报告.pdf') < message.lastIndexOf('后'), 'read-only projection must keep the original inline order') for (const name of ['说明.md','表格.csv','报告.pdf','文档.docx','代码.ts','页面.html','图片.png','压缩.zip','音频.wav','视频.mp4','other.unknown']) { const icon = renderToStaticMarkup() assert.ok(icon.includes('