From f4c938566177067e456eb780048da72e3eb7aaea Mon Sep 17 00:00:00 2001 From: Tyler Bradley Date: Tue, 2 Dec 2025 16:55:59 +0000 Subject: [PATCH] Fix: Add crypto.randomUUID fallback for browser compatibility The crypto.randomUUID() API requires a secure context (HTTPS or specific localhost conditions). When running CodeNomad Server on 0.0.0.0:9898 or accessing via LAN/VPN, some browsers don't provide this API, causing attachment creation to fail with TypeError. Added generateUUID() helper that uses crypto.randomUUID() when available, with a Math.random()-based UUID v4 fallback for compatibility. Fixes file and agent attachment creation in the @ mention picker when running in headless server mode. --- src/types/attachment.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/types/attachment.ts b/src/types/attachment.ts index 706fe928..10dbb0a5 100644 --- a/src/types/attachment.ts +++ b/src/types/attachment.ts @@ -47,6 +47,19 @@ export interface AgentSource { name: string } +// Generate UUID with fallback for browsers without crypto.randomUUID +function generateUUID(): string { + if (typeof crypto !== "undefined" && crypto.randomUUID) { + return crypto.randomUUID() + } + // Fallback: generate a simple UUID v4 + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0 + const v = c === "x" ? r : (r & 0x3) | 0x8 + return v.toString(16) + }) +} + export function createFileAttachment( path: string, filename: string, @@ -63,7 +76,7 @@ export function createFileAttachment( } return { - id: crypto.randomUUID(), + id: generateUUID(), type: "file", display: `@${filename}`, url: fileUrl, @@ -81,7 +94,7 @@ export function createFileAttachment( export function createTextAttachment(value: string, display: string, filename: string): Attachment { const base64 = encodeTextAsBase64(value) return { - id: crypto.randomUUID(), + id: generateUUID(), type: "text", display, url: `data:text/plain;base64,${base64}`, @@ -114,7 +127,7 @@ function encodeTextAsBase64(value: string): string { export function createAgentAttachment(agentName: string): Attachment { return { - id: crypto.randomUUID(), + id: generateUUID(), type: "agent", display: `@${agentName}`, url: "",