Add fleet groups, agent screenshots, deploy guards, and Crucible polish.

This commit is contained in:
AetherForge
2026-06-02 20:51:52 -07:00
parent 01d76b3730
commit 41b5ec7a88
66 changed files with 1773 additions and 388 deletions

View File

@@ -0,0 +1,42 @@
/** Strip whitespace and download a remote desktop capture as a JPEG file. */
export function sanitizeScreenshotBase64(raw: string): string {
const trimmed = raw.trim().replace(/^\uFEFF/, '');
let best = '';
for (const part of trimmed.split(/\s+/)) {
const cleaned = part.replace(/[^A-Za-z0-9+/=]/g, '');
if (cleaned.length > best.length && cleaned.length >= 100) {
best = cleaned;
}
}
if (best.length >= 100) return best;
return trimmed.replace(/[^A-Za-z0-9+/=]/g, '');
}
export function downloadScreenshotFromBase64(
base64: string,
agentLabel: string
): boolean {
const clean = sanitizeScreenshotBase64(base64);
if (clean.length < 100) return false;
const safeName = agentLabel.replace(/[^\w.-]+/g, '_').slice(0, 64) || 'agent';
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
const blob = base64ToBlob(clean, 'image/jpeg');
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `screenshot-${safeName}-${stamp}.jpg`;
a.rel = 'noopener';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
return true;
}
function base64ToBlob(b64: string, mime: string): Blob {
const binary = atob(b64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return new Blob([bytes], { type: mime });
}