Files
john 1faba62f9b
Memind CI / Test, build, and release guards (push) Failing after 6s
fix(wechat): repair share preview on disk for sanitized delivery artifacts
Production WeChat delivery strips localPath from artifacts, so share-preview
auto-repair never wrote back to HTML. Resolve paths via publishDir +
relativePath, repair at materialize and delivery prep, and pass h5Root from
Portal so page.generate can patch missing meta before sending links.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 08:48:03 +08:00

126 lines
4.0 KiB
JavaScript

import { buildPagePublishFailureText } from '../prompts/page-generate.mjs';
import { selectSendableHtmlArtifacts, verifyPageArtifactContent } from '../verify/page-artifact.mjs';
import { repairArtifactSharePreview } from '../verify/share-preview-repair.mjs';
import { filterSharePreviewReadyArtifacts, verifyArtifactSharePreview } from '../verify/share-preview.mjs';
export function evaluatePageGenerateSendableArtifacts({
verifiedArtifacts = [],
confirmedArtifacts = [],
repairContext = {},
} = {}) {
const publishDir = String(repairContext.publishDir ?? '').trim();
const previewOptions = { publishDir };
const sendable = selectSendableHtmlArtifacts({
verifiedArtifacts,
confirmedArtifacts,
publishDir,
});
const verified = sendable.filter((artifact) =>
verifyPageArtifactContent(artifact, previewOptions).ok,
);
const candidates = verified.length > 0 ? verified : sendable;
const ready = filterSharePreviewReadyArtifacts(candidates, previewOptions);
if (ready.length > 0) return ready;
const repaired = [];
for (const artifact of candidates) {
if (!verifyPageArtifactContent(artifact, previewOptions).ok) continue;
const result = repairArtifactSharePreview(artifact, repairContext);
if (result.ok && verifyArtifactSharePreview(artifact, previewOptions).ok) {
repaired.push(artifact);
}
}
return repaired;
}
/**
* Decide whether a page.generate reply may be delivered to the user.
* Returns { action: 'send'|'fail'|'session_retry', failureText?, reason? }
*/
export function resolvePageGenerateOutcome({
reply,
confirmedArtifacts = [],
verifiedArtifacts = [],
suspiciousPublishClaim = false,
bareCompletionReply = false,
htmlGenerationNeedsRetry = false,
replyHasPublicLinks = false,
topic = '',
repairContext = {},
}) {
const context = {
topic: String(topic || repairContext.topic || '').trim(),
publishDir: String(repairContext.publishDir ?? '').trim(),
...repairContext,
};
const previewOptions = { publishDir: context.publishDir };
const sendable = evaluatePageGenerateSendableArtifacts({
verifiedArtifacts,
confirmedArtifacts,
repairContext: context,
});
if (sendable.length > 0) {
return { action: 'send', artifacts: sendable };
}
if (
suspiciousPublishClaim ||
bareCompletionReply ||
(htmlGenerationNeedsRetry && replyHasPublicLinks && confirmedArtifacts.length === 0)
) {
return { action: 'session_retry', reason: 'poisoned_or_fake_claim' };
}
if (htmlGenerationNeedsRetry || suspiciousPublishClaim) {
return {
action: 'fail',
failureText: buildPagePublishFailureText(),
reason: 'skill_or_stub',
};
}
const previewCandidates = filterSharePreviewReadyArtifacts(
selectSendableHtmlArtifacts({
verifiedArtifacts,
confirmedArtifacts,
publishDir: context.publishDir,
}),
previewOptions,
);
if (previewCandidates.length === 0 && confirmedArtifacts.length > 0) {
const previewIssue = verifyArtifactSharePreview(
selectSendableHtmlArtifacts({
verifiedArtifacts,
confirmedArtifacts,
publishDir: context.publishDir,
})[0] ?? confirmedArtifacts[0],
previewOptions,
);
return {
action: 'fail',
failureText: buildPagePublishFailureText({
missingPlatformBrand: previewIssue.reason === 'missing_platform_brand',
missingSharePreview: previewIssue.reason !== 'missing_platform_brand',
}),
reason: previewIssue.reason ?? 'missing_share_preview',
};
}
if (!String(reply?.text ?? '').trim() && sendable.length === 0) {
return {
action: 'fail',
failureText: buildPagePublishFailureText(),
reason: 'empty_reply',
};
}
// Fail closed: page.generate must deliver a verified public HTML artifact.
// Text-only planning replies ("我先搜索…") must not mark WeChat delivery done.
return {
action: 'fail',
failureText: buildPagePublishFailureText(),
reason: 'missing_page_artifact',
};
}