Improve attachment memory safety, downloads, and high-memory alert UX.
Queue Release Build / prepare (push) Successful in 20s
Deploy Web Apps / deploy (push) Successful in 9m2s
Queue Release Build / build-windows (push) Successful in 28m8s
Queue Release Build / build-linux (push) Successful in 47m26s
Queue Release Build / build-android (push) Successful in 19m52s
Queue Release Build / finalize (push) Successful in 4m42s

Stream large receives to disk with chunk acks to cap renderer RAM, evict
off-screen display blobs, and route exports through a disk-aware download
service. Fix the high-memory dialog (backdrop dismiss, copy, log actions),
allow diagnostics paths in the path jail, and restore persisted image
hydration after reload.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-14 00:25:22 +02:00
co-authored by Cursor
parent f0d79aa627
commit bb0ac930ad
69 changed files with 2306 additions and 430 deletions
@@ -11,6 +11,7 @@ import {
decodeBase64ToUint8Array,
yieldToAttachmentHydrationLoop
} from '../../domain/logic/attachment-blob.rules';
import { canRevokeAttachmentDisplayBlob } from '../../domain/logic/attachment-blob-eviction.rules';
import { isBlobObjectUrl, needsBlobObjectUrlForInlineDisplay } from '../../domain/logic/attachment-display-url.rules';
import { mergeAttachmentLocalPaths } from '../../domain/logic/attachment-persistence.rules';
import { isAttachmentMedia } from '../../domain/logic/attachment.logic';
@@ -119,7 +120,7 @@ export class AttachmentPersistenceService {
}
async tryRestoreAttachmentFromLocal(attachment: Attachment): Promise<boolean> {
const restored = await this.ensurePersistedUploadHost(attachment);
const restored = await this.ensurePersistedUploadHost(attachment, { hydrateMediaForDisplay: true });
if (restored) {
attachment.requestError = undefined;
@@ -128,11 +129,30 @@ export class AttachmentPersistenceService {
return restored;
}
async ensurePersistedUploadHost(attachment: Attachment): Promise<boolean> {
async tryRestoreAttachmentHostOnly(attachment: Attachment): Promise<boolean> {
return this.ensurePersistedUploadHost(attachment, { hydrateMediaForDisplay: false });
}
revokeAttachmentDisplayBlob(attachment: Attachment): boolean {
if (!canRevokeAttachmentDisplayBlob(attachment)) {
return false;
}
this.revokeAttachmentObjectUrl(attachment);
attachment.objectUrl = undefined;
return true;
}
async ensurePersistedUploadHost(
attachment: Attachment,
options: { hydrateMediaForDisplay?: boolean } = {}
): Promise<boolean> {
const hydrateMediaForDisplay = options.hydrateMediaForDisplay !== false;
const existingPath = await this.attachmentStorage.resolveExistingPath(attachment);
if (existingPath) {
return this.hydrateAttachmentFromStoredPath(attachment, existingPath);
return this.hydrateAttachmentFromStoredPath(attachment, existingPath, hydrateMediaForDisplay);
}
if (!attachment.filePath?.trim() || !this.attachmentStorage.canCopyFiles()) {
@@ -147,13 +167,22 @@ export class AttachmentPersistenceService {
return false;
}
return this.hydrateAttachmentFromStoredPath(attachment, savedPath);
return this.hydrateAttachmentFromStoredPath(attachment, savedPath, hydrateMediaForDisplay);
}
private async hydrateAttachmentFromStoredPath(attachment: Attachment, diskPath: string): Promise<boolean> {
private async hydrateAttachmentFromStoredPath(
attachment: Attachment,
diskPath: string,
hydrateMediaForDisplay = true
): Promise<boolean> {
attachment.savedPath = diskPath;
if (isAttachmentMedia(attachment)) {
if (!hydrateMediaForDisplay) {
void this.persistAttachmentMeta(attachment);
return true;
}
return this.ensureInlineDisplayObjectUrl(attachment);
}
@@ -192,6 +221,7 @@ export class AttachmentPersistenceService {
this.revokeAttachmentObjectUrl(attachment);
attachment.objectUrl = nativeUrl;
attachment.available = true;
this.runtimeStore.touch();
return true;
}
}
@@ -366,6 +396,8 @@ export class AttachmentPersistenceService {
`${attachment.messageId}:${attachment.id}`,
new File([blob], attachment.filename, { type: attachment.mime })
);
this.runtimeStore.touch();
}
private revokeAttachmentObjectUrl(attachment: Attachment): void {