fix: MindSpace remote sync, thumbnail fallback, and Plaza URL guards

Ensure page sync runs via pageSyncService in remote mode, fall back to
workspace HTML when storage assets are missing, and prevent production
Portal from linking to loopback Plaza URLs baked in at build time.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-05 07:57:04 +08:00
parent 4781bbc156
commit d3239ff292
20 changed files with 646 additions and 58 deletions
+6 -30
View File
@@ -122,7 +122,6 @@ import {
normalizePublicHtmlRelativePath,
syncPublicHtmlAfterFinish,
} from './mindspace-public-finish-sync.mjs';
import { syncGeneratedPagesFromPublicAssets } from './mindspace-page-sync.mjs';
import { extractCoverSignals, generateHtmlThumbnail } from './mindspace-thumbnails.mjs';
import {
extractSharePreviewMeta,
@@ -299,6 +298,7 @@ let mindSpaceAudit = null;
let mindSpaceServiceFacade = null;
let mindSpaceConversationPackageRegistry = null;
let mindSpacePages = null;
let mindSpacePageSync = null;
let mindSpacePageLiveEdit = null;
let mindSpaceAssetAgent = null;
let mindSpacePageEditSession = null;
@@ -363,6 +363,7 @@ async function bootstrapUserAuth() {
resolveUserIdForAgentSession,
resolveSessionSnapshot: (sessionId) => sessionSnapshotService?.get?.(sessionId),
registerPublicHtmlArtifactsForConversation,
syncWorkspaceAssetsEnabled: WORKSPACE_MAINTENANCE_ENABLED,
remote: mindSpaceServerRuntime.remote,
logger: console,
}),
@@ -372,6 +373,7 @@ async function bootstrapUserAuth() {
mindSpaceConversationPackageRegistry = mindSpaceRuntimeAdapter.conversationPackageRegistry;
mindSpaceAssets = mindSpaceRuntimeAdapter.assetService;
mindSpacePages = mindSpaceRuntimeAdapter.pageService;
mindSpacePageSync = mindSpaceRuntimeAdapter.pageSyncService;
mindSpacePageLiveEdit = mindSpaceRuntimeAdapter.pageLiveEditService;
mindSpaceAssetAgent = mindSpaceRuntimeAdapter.assetAgentService;
mindSpacePublications = mindSpaceRuntimeAdapter.publicationService;
@@ -2942,36 +2944,10 @@ async function resolveExistingSavedPage(userId, { sessionId, messageId, relative
const SAVE_TARGET_CATEGORIES = new Set(['draft', 'oa', 'public']);
const pageSyncInFlight = new Map();
// REGRESSION GUARD: mindspace-page-sync-thumbnail — remote 也经 pageSyncService RPC 同步 public HTML
async function syncUserGeneratedPages(userId) {
if (!mindSpacePages || !authPool || !userId) return;
if (mindSpaceServerRuntime.adapterKind === 'remote') return;
let inFlight = pageSyncInFlight.get(userId);
if (!inFlight) {
inFlight = syncGeneratedPagesFromPublicAssets({
pool: authPool,
pageService: mindSpacePages,
assetService: mindSpaceAssets,
userId,
publishDir: resolveMindSpaceUserPublishDir(__dirname, { id: userId }),
syncWorkspaceAssets:
mindSpaceAssets && WORKSPACE_MAINTENANCE_ENABLED
? (targetUserId, options) => mindSpaceAssets.syncWorkspaceAssets(targetUserId, options)
: null,
})
.catch((error) => {
console.warn('[MindSpace] page sync failed:', error?.message ?? error);
})
.finally(() => {
if (pageSyncInFlight.get(userId) === inFlight) {
pageSyncInFlight.delete(userId);
}
});
pageSyncInFlight.set(userId, inFlight);
}
await inFlight;
if (!mindSpacePageSync || !userId) return;
await mindSpacePageSync.syncUserGeneratedPages(userId);
}
async function resolveChatSaveBundle(user, h5Root, input = {}) {