import fs from 'node:fs'; import { prepareWechatHtmlDeliveryAtWorkspace } from './mindspace-wechat-html-delivery.mjs'; import { resolveArtifactLocalPath } from './wechat/verify/page-artifact.mjs'; import { extractPageTitle, repairArtifactSharePreview, repairSharePreviewHtml, } from './wechat/verify/share-preview-repair.mjs'; const MIN_CURSOR_PAGE_BYTES = 512; export function isWechatCursorChannelReply(reply) { return reply?.wechatCursorChannel === true; } function padHtmlToMinBytes(html, minBytes = MIN_CURSOR_PAGE_BYTES) { let next = String(html ?? ''); if (Buffer.byteLength(next, 'utf8') >= minBytes) return next; const deficit = minBytes - Buffer.byteLength(next, 'utf8') + 32; const pad = `${' '.repeat(Math.max(0, deficit))}`; if (/<\/body>/i.test(next)) { return next.replace(/<\/body>/i, `${pad}`); } if (/<\/html>/i.test(next)) { return next.replace(/<\/html>/i, `${pad}`); } return `${next}${pad}`; } function normalizeCursorArtifactForWechatDelivery(artifact, { publishDir, topic }) { const localPath = resolveArtifactLocalPath(artifact, publishDir); if (!localPath) return artifact; try { if (!fs.existsSync(localPath)) return artifact; const title = extractPageTitle(fs.readFileSync(localPath, 'utf8')); let content = fs.readFileSync(localPath, 'utf8'); content = padHtmlToMinBytes(content); content = repairSharePreviewHtml(content, { title, topic }); fs.writeFileSync(localPath, content, 'utf8'); repairArtifactSharePreview( { ...artifact, localPath }, { topic, publishDir }, ); } catch { // Best-effort repair; delivery validation will fail closed if still unusable. } return artifact; } export function prepareWechatCursorPageDelivery({ reply, intent, publishDir, requestStartedAt, buildCanonicalUrl, topic = '', }) { const baseReply = { ...reply, wechatCursorChannel: true, }; if (!String(publishDir ?? '').trim()) { return baseReply; } const prepared = prepareWechatHtmlDeliveryAtWorkspace({ reply: baseReply, intent, publishDir, requestStartedAt, allowRecentArtifacts: true, buildCanonicalUrl, }); const candidateArtifacts = [ ...(prepared.recentArtifacts ?? []), ...(prepared.confirmedArtifacts ?? []), ...(prepared.publishedArtifacts ?? []), ]; for (const artifact of candidateArtifacts) { normalizeCursorArtifactForWechatDelivery(artifact, { publishDir, topic }); } const reprepared = prepareWechatHtmlDeliveryAtWorkspace({ reply: baseReply, intent, publishDir, requestStartedAt, allowRecentArtifacts: true, buildCanonicalUrl, }); const confirmedArtifacts = reprepared.confirmedArtifacts ?? []; const urls = confirmedArtifacts .map((artifact) => String(artifact?.url ?? '').trim()) .filter(Boolean); const uniqueUrls = [...new Set(urls)]; return { ...baseReply, text: uniqueUrls.length > 0 ? [String(baseReply.text ?? '').trim(), ...uniqueUrls].filter(Boolean).join('\n') : String(baseReply.text ?? '').trim(), cursorPreparedArtifacts: confirmedArtifacts, }; }