fix(mindspace): ensure thumbnail sidecars for WeChat link card og:image
Memind CI / Test, build, and release guards (push) Failing after 2s

Generate SVG/PNG sidecars at HTML delivery and after share-preview repair so
forwarded service-account links get a raster og:image when only meta exists.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-02 13:47:09 +08:00
parent 3547cf8ef0
commit 55100f8945
3 changed files with 51 additions and 0 deletions
@@ -234,6 +234,24 @@ export function createMindSpaceWorkspacePublicationDeliveryService({
publishDir,
thumbnailRelativePath,
);
// WeChat link cards and forwards read og:image at serve time. Pages may
// already have share-preview meta without a raster sidecar (e.g. service
// account auto-repair); ensure the SVG exists before building fallbackImageUrl.
if (!existsSyncFn(thumbnailAbsolutePath)) {
try {
await ensureWorkspaceThumbnailFn(
publishDir,
relativePath,
html,
);
} catch (error) {
logger?.warn?.(
`[MindSpace] thumbnail sidecar ensure failed for ${relativePath}: ${
error?.message || error
}`,
);
}
}
return {
action: 'deliver',
kind: 'html',
@@ -198,6 +198,32 @@ test('enforces the page delivery contract inside MindSpace', async () => {
);
});
test('ensures a thumbnail sidecar before HTML delivery when share preview exists without one', async () => {
const calls = [];
const setup = createSetup({
existsSyncFn() {
return false;
},
async ensureWorkspaceThumbnailFn(publishDir, relativePath, html) {
calls.push([
'ensure-thumbnail',
publishDir,
relativePath,
html,
]);
},
});
const result =
await setup.service.resolveWorkspaceRequest({
requestPath: '/user-1/public/page.html',
});
assert.equal(result.thumbnailName, null);
assert.equal(
calls.some(([kind]) => kind === 'ensure-thumbnail'),
true,
);
});
test('materializes and returns thumbnail binaries through the logical contract', async () => {
const setup = createSetup({
async resolvePublicRequestFn() {
+7
View File
@@ -3,6 +3,7 @@ import path from 'node:path';
import { injectBeforeDocumentClosingHead } from '../../html-document-injection.mjs';
import { normalizeCoverMetaSuggestion, upsertMindspaceCoverMeta } from '../../mindspace-cover-meta.mjs';
import { preparePublishedPlatformBrand } from '../../mindspace-page-tag.mjs';
import { scheduleWorkspaceHtmlThumbnailSidecars } from '../../mindspace-workspace-thumbnails.mjs';
import {
artifactFileExists,
resolveArtifactLocalPath,
@@ -126,6 +127,12 @@ export function repairArtifactSharePreview(artifact, { topic = '', publishDir =
if (!verified.ok) {
return { ok: false, reason: verified.reason ?? 'repair_incomplete', changes };
}
if (publishDir && artifact?.relativePath) {
scheduleWorkspaceHtmlThumbnailSidecars(
publishDir,
String(artifact.relativePath).replace(/\\/g, '/'),
);
}
return { ok: true, reason: null, changes };
}