All checks were successful
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>
64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import * as fsp from 'fs/promises';
|
|
import * as path from 'path';
|
|
|
|
export type HighMemoryAlertReason = 'manual' | 'threshold';
|
|
|
|
export interface HighMemoryAlertRecord {
|
|
logFilePath: string;
|
|
detectedAt: number;
|
|
peakWorkingSetKb: number;
|
|
sessionId: string;
|
|
reason?: HighMemoryAlertReason;
|
|
}
|
|
|
|
export function resolveHighMemoryAlertPath(userDataPath: string): string {
|
|
return path.join(userDataPath, 'diagnostics', 'high-memory-pending.json');
|
|
}
|
|
|
|
export async function readHighMemoryAlert(userDataPath: string): Promise<HighMemoryAlertRecord | null> {
|
|
try {
|
|
const raw = await fsp.readFile(resolveHighMemoryAlertPath(userDataPath), 'utf8');
|
|
const parsed = JSON.parse(raw) as Partial<HighMemoryAlertRecord>;
|
|
|
|
if (
|
|
typeof parsed.logFilePath !== 'string'
|
|
|| !parsed.logFilePath.trim()
|
|
|| typeof parsed.detectedAt !== 'number'
|
|
|| typeof parsed.peakWorkingSetKb !== 'number'
|
|
|| typeof parsed.sessionId !== 'string'
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
logFilePath: parsed.logFilePath,
|
|
detectedAt: parsed.detectedAt,
|
|
peakWorkingSetKb: parsed.peakWorkingSetKb,
|
|
sessionId: parsed.sessionId,
|
|
...(parsed.reason === 'manual' || parsed.reason === 'threshold'
|
|
? { reason: parsed.reason }
|
|
: {})
|
|
};
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function writeHighMemoryAlert(
|
|
userDataPath: string,
|
|
record: HighMemoryAlertRecord
|
|
): Promise<void> {
|
|
const filePath = resolveHighMemoryAlertPath(userDataPath);
|
|
|
|
await fsp.mkdir(path.dirname(filePath), { recursive: true });
|
|
await fsp.writeFile(filePath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
|
|
}
|
|
|
|
export async function clearHighMemoryAlert(userDataPath: string): Promise<void> {
|
|
try {
|
|
await fsp.unlink(resolveHighMemoryAlertPath(userDataPath));
|
|
} catch {
|
|
// Missing pending alert is fine.
|
|
}
|
|
}
|