From 0d09d11c339c5d4d1de24f6ba402fd3c21bb4c60 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 4 Apr 2026 14:19:24 -0700 Subject: [PATCH] improvement(mothership): docs --- apps/sim/app/api/function/execute/route.ts | 23 +++- .../components/file-viewer/file-viewer.tsx | 31 ++++- .../tools/handlers/function-execute.ts | 116 ++++++++++++++++++ apps/sim/lib/execution/doc-worker.cjs | 11 +- apps/sim/lib/execution/e2b.ts | 77 ++++++++++-- apps/sim/tools/function/execute.ts | 16 ++- apps/sim/tools/function/types.ts | 1 + 7 files changed, 254 insertions(+), 21 deletions(-) diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index e6698c328c..bd796105c6 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -593,6 +593,7 @@ async function maybeExportSandboxFileToWorkspace(args: { workspaceId?: string outputPath?: string outputFormat?: string + outputMimeType?: string outputSandboxPath?: string exportedFileContent?: string stdout: string @@ -604,6 +605,7 @@ async function maybeExportSandboxFileToWorkspace(args: { workspaceId, outputPath, outputFormat, + outputMimeType, outputSandboxPath, exportedFileContent, stdout, @@ -650,14 +652,23 @@ async function maybeExportSandboxFileToWorkspace(args: { } const fileName = normalizeOutputWorkspaceFileName(outputPath) - const format = resolveOutputFormat(fileName, outputFormat) - const contentType = FORMAT_TO_CONTENT_TYPE[format] + + const TEXT_MIMES = new Set(Object.values(FORMAT_TO_CONTENT_TYPE)) + const resolvedMimeType = + outputMimeType || + FORMAT_TO_CONTENT_TYPE[resolveOutputFormat(fileName, outputFormat)] || + 'application/octet-stream' + const isBinary = !TEXT_MIMES.has(resolvedMimeType) + const fileBuffer = isBinary + ? Buffer.from(exportedFileContent, 'base64') + : Buffer.from(exportedFileContent, 'utf-8') + const uploaded = await uploadWorkspaceFile( resolvedWorkspaceId, authUserId, - Buffer.from(exportedFileContent, 'utf-8'), + fileBuffer, fileName, - contentType + resolvedMimeType ) return NextResponse.json({ @@ -702,6 +713,7 @@ export async function POST(req: NextRequest) { language = DEFAULT_CODE_LANGUAGE, outputPath, outputFormat, + outputMimeType, outputSandboxPath, envVars = {}, blockData = {}, @@ -815,6 +827,7 @@ export async function POST(req: NextRequest) { workspaceId, outputPath, outputFormat, + outputMimeType, outputSandboxPath, exportedFileContent, stdout: shellStdout, @@ -938,6 +951,7 @@ export async function POST(req: NextRequest) { workspaceId, outputPath, outputFormat, + outputMimeType, outputSandboxPath, exportedFileContent, stdout, @@ -1019,6 +1033,7 @@ export async function POST(req: NextRequest) { workspaceId, outputPath, outputFormat, + outputMimeType, outputSandboxPath, exportedFileContent, stdout, diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx index fcca3eab13..6a90ebacbb 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx @@ -163,7 +163,7 @@ export function FileViewer({ } if (category === 'iframe-previewable') { - return + return } if (category === 'image-previewable') { @@ -454,13 +454,36 @@ function TextEditor({ ) } -const IframePreview = memo(function IframePreview({ file }: { file: WorkspaceFileRecord }) { - const serveUrl = `/api/files/serve/${encodeURIComponent(file.key)}?context=workspace` +const IframePreview = memo(function IframePreview({ + file, + workspaceId, +}: { + file: WorkspaceFileRecord + workspaceId: string +}) { + const { data: fileData, isLoading } = useWorkspaceFileBinary(workspaceId, file.id, file.key) + const [blobUrl, setBlobUrl] = useState(null) + + useEffect(() => { + if (!fileData) return + const blob = new Blob([fileData], { type: 'application/pdf' }) + const url = URL.createObjectURL(blob) + setBlobUrl(url) + return () => URL.revokeObjectURL(url) + }, [fileData]) + + if (isLoading || !blobUrl) { + return ( +
+ +
+ ) + } return (