Skip to content

Conversation

@Kitenite
Copy link
Contributor

@Kitenite Kitenite commented Aug 13, 2025

Description

Related Issues

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Release
  • Refactor
  • Other (please describe):

Testing

Screenshots (if applicable)

Additional Notes


Important

Improves file upload handling in upload-modal.tsx with smarter directory selection, binary vs text file distinction, and enhanced error handling.

  • Behavior:
    • upload-modal.tsx: Smarter directory selection for uploads; images default to public or assets, non-images use active file's directory.
    • upload-modal.tsx: Distinguishes binary vs text files; uses writeBinaryFile for binary and writeFile for text.
  • Error Handling:
    • upload-modal.tsx: Prevents errors when no file is selected; improved error notifications and resets upload state after attempts.
  • Imports:
    • image/index.ts: Consolidates imports from @onlook/utility.
    • upload-modal.tsx: Adds isBinaryFile import from @onlook/utility.

This description was created by Ellipsis for 27c6baf. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • Smarter upload destinations: images saved to the most appropriate public/assets directory; non-image uploads prefer the active file's directory when available.
    • Correct handling of file types: uploads now distinguish binary vs. text and write using the appropriate method for each file.
  • Bug Fixes

    • Prevents errors when no file is selected.
    • Improved error handling with failure notifications and ensures upload loading state resets after attempts.

@vercel
Copy link

vercel bot commented Aug 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Project Deployment Preview Comments Updated (UTC)
web Ready Preview Comment Aug 14, 2025 1:00am
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
docs ⬜️ Skipped Aug 14, 2025 1:00am

@supabase
Copy link

supabase bot commented Aug 13, 2025

This pull request has been ignored for the connected project wowaemfasoptxrdjhilu because there are no changes detected in apps/backend/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

Upload handling updated to detect binary vs text files, choose smarter target directories (images: public → src/assets → assets; non-images: active file directory or root), write binaries with writeBinaryFile and texts with writeFile, add safer file selection checks, improved error handling, and reset uploading state.

Changes

Cohort / File(s) Summary
Upload modal enhancements
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx
- Added isBinaryFile import and per-file type branching
- getSmartDirectory: image path preference publicsrc/assetsassets, else fallback; non-images derive from editorEngine.ide.activeFile.path if valid, else root
- Guarded file selection (fileArray[0]) before directory computation
- Use writeBinaryFile(path, Uint8Array) for binaries; writeFile(path, file.text()) for non-binaries
- Call listAllFiles() after writes; added catch (log + failure toast) and finally to reset isUploading
- Minor formatting/whitespace edits
Image store import consolidation
apps/web/client/src/components/store/editor/image/index.ts
- Switched some type imports to @onlook/models (type-only)
- Consolidated utility imports to @onlook/utility (moved from mixed sources)
- No runtime logic changes

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant M as UploadModal
  participant FS as FileSystem

  U->>M: Select file(s)
  M->>M: Ensure fileArray[0] exists
  M->>M: getSmartDirectory(file)
  alt isBinaryFile(file.name)
    M->>FS: writeBinaryFile(path, Uint8Array)
  else
    M->>FS: writeFile(path, file.text())
  end
  M->>FS: listAllFiles()
  M->>U: Show success toast
  alt Error
    M->>U: Show failure toast
  end
  M->>M: set isUploading = false
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • Feat/editor improvements #2601 — Modifies the same UploadModal areas (getSmartDirectory, file selection, and upload/write logic); likely directly related.

Poem

A rabbit hops through folders bright,
Public first, then assets in sight.
Bytes for pictures, text for prose,
Checks and toasts where upload goes.
Done and tidy — hop, compose! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/file-upload

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (1)

53-68: Potential logic issue in image directory fallback

Line 67 contains redundant logic - it checks for 'public' again after already checking it on line 58. The fallback should likely default to 'root' for images when no standard directories exist.

-            return availableDirectories.includes('public') ? 'public' : 'root';
+            return 'root';
🧹 Nitpick comments (1)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (1)

110-116: Consider adding MIME type validation for safer file handling

While checking file.type.startsWith('image/') works for most cases, some files might have incorrect or missing MIME types. Consider adding a fallback check based on file extension.

-                if (file.type.startsWith('image/')) {
+                const extension = file.name.toLowerCase().split('.').pop();
+                const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'ico'];
+                const isImage = file.type.startsWith('image/') || 
+                               (extension && imageExtensions.includes(extension));
+                if (isImage) {
                     const content = await file.arrayBuffer();
                     await editorEngine.sandbox.writeBinaryFile(finalPath, new Uint8Array(content));
                 } else {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a21e67 and d42cc90.

📒 Files selected for processing (1)
  • apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (6 hunks)
🔇 Additional comments (3)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (3)

93-96: Good defensive programming with the file existence check

The added check fileArray[0] prevents potential undefined access when computing the smart directory, improving robustness against edge cases.


110-116: Correct file handling approach for different content types

The differentiation between binary (images) and text files is appropriate. Using writeBinaryFile for images with Uint8Array and writeFile for text content ensures proper handling of different file types and prevents potential encoding issues.


127-132: Excellent error handling improvements

The addition of try-catch-finally ensures proper error handling with user feedback via toast notifications and guarantees the loading state is reset even on failure. This prevents the UI from getting stuck in a loading state.

Comment on lines 110 to 116
if (file.type.startsWith('image/')) {
const content = await file.arrayBuffer();
await editorEngine.sandbox.writeBinaryFile(finalPath, new Uint8Array(content));
} else {
const content = await file.text();
await editorEngine.sandbox.writeFile(finalPath, content);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding file size validation

For large files, loading the entire content into memory via arrayBuffer() or text() could cause performance issues or browser crashes. Consider adding file size validation before processing.

Add size validation before the upload loop:

const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit
const oversizedFiles = selectedFiles.filter(file => file.size > MAX_FILE_SIZE);
if (oversizedFiles.length > 0) {
    toast('Files too large', { 
        description: `The following files exceed the 10MB limit: ${oversizedFiles.map(f => f.name).join(', ')}` 
    });
    return;
}
🤖 Prompt for AI Agents
In
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx
around lines 110-116, add file size validation before calling file.arrayBuffer()
or file.text(): define a MAX_FILE_SIZE (e.g. 10 * 1024 * 1024), check
selectedFiles for any file.size > MAX_FILE_SIZE, and if any are oversized show a
toast listing their names and stop the upload (or skip oversized files) so you
never load large files fully into memory; ensure the check runs before the
upload loop and that the UI informs the user which files exceeded the limit.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (1)

100-107: Add file size validation before reading file contents into memory

Reading large files with file.arrayBuffer() or file.text() can blow memory or freeze the UI. Add a size cap and notify the user before the upload loop.

   const handleUpload = async () => {
     if (selectedFiles.length === 0) {
       return;
     }
 
+    // Prevent loading very large files into memory
+    const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
+    const oversized = selectedFiles.filter(f => f.size > MAX_FILE_SIZE);
+    if (oversized.length > 0) {
+      toast('Files too large', {
+        description: `The following files exceed the 10MB limit: ${oversized.map(f => f.name).join(', ')}`
+      });
+      return;
+    }
+
     setIsUploading(true);
🧹 Nitpick comments (3)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (3)

54-69: Broaden image extension coverage and remove redundant fallback

  • The image extension list misses common types (avif, tif/tiff, bmp, apng, heic/heif). This can misclassify image files and degrade the “smart” directory selection.
  • The final return in the image branch repeats the 'public' check and is effectively equivalent to returning 'root' at that point.

Consider this focused tweak:

-        const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'ico'];
+        const imageExtensions = [
+            'jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'ico',
+            'avif', 'tif', 'tiff', 'bmp', 'apng', 'heic', 'heif'
+        ];
@@
-            return availableDirectories.includes('public') ? 'public' : 'root';
+            return 'root';

71-81: Prefer the nearest existing parent directory over falling back to root

If the active file’s directory isn’t in availableDirectories, you immediately return 'root'. Often a parent directory exists (e.g., active dir "src/pages" while only "src" is present). Select the deepest existing parent to improve UX.

-        if (editorEngine.ide.activeFile?.path) {
+        if (editorEngine.ide.activeFile?.path) {
             const path = editorEngine.ide.activeFile.path;
             const lastSlash = path.lastIndexOf('/');
             const dir = lastSlash > 0 ? path.substring(0, lastSlash) : 'root';
-            if (dir === 'root' || availableDirectories.includes(dir)) {
-                return dir;
-            }
+            if (dir === 'root' || availableDirectories.includes(dir)) {
+                return dir;
+            }
+            // Try nearest existing parent of the active file's directory
+            const parts = dir.split('/');
+            for (let i = parts.length - 1; i > 0; i--) {
+                const candidate = parts.slice(0, i).join('/');
+                if (availableDirectories.includes(candidate)) {
+                    return candidate;
+                }
+            }
         }

128-133: Consider per-file error handling to avoid failing the whole batch

A single failing file aborts the entire upload. If that’s not desired, wrap the body of the for-of loop in its own try/catch, collect errors, and present a summary toast while still uploading the rest.

-        try {
-            for (const file of selectedFiles) {
+        try {
+            const failures: string[] = [];
+            for (const file of selectedFiles) {
+                try {
                   const directory = targetDirectory === 'root' ? '' : targetDirectory;
                   const finalPath = directory ? `${directory}/${file.name}` : file.name;
 
                   if (isBinaryFile(file.name)) {
                     const content = await file.arrayBuffer();
                     await editorEngine.sandbox.writeBinaryFile(finalPath, new Uint8Array(content));
                   } else {
                     const content = await file.text();
                     await editorEngine.sandbox.writeFile(finalPath, content);
                   }
+                } catch (e) {
+                    console.error('Error uploading file:', file.name, e);
+                    failures.push(file.name);
+                }
             }
 
             await editorEngine.sandbox.listAllFiles();
 
-            const fileCount = selectedFiles.length;
-            const fileText = fileCount === 1 ? selectedFiles[0]?.name ?? 'file' : `${fileCount} files`;
-            toast(`Successfully uploaded ${fileText}!`);
+            const fileCount = selectedFiles.length;
+            if (failures.length === 0) {
+                const fileText = fileCount === 1 ? selectedFiles[0]?.name ?? 'file' : `${fileCount} files`;
+                toast(`Successfully uploaded ${fileText}!`);
+            } else if (failures.length < fileCount) {
+                toast('Partial upload completed', {
+                    description: `Failed: ${failures.join(', ')}`
+                });
+            } else {
+                throw new Error('All uploads failed');
+            }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d42cc90 and dc6db3a.

📒 Files selected for processing (1)
  • apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (7 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (2)
packages/utility/src/file.ts (1)
  • isBinaryFile (9-12)
packages/ui/src/components/sonner.tsx (1)
  • toast (12-12)
🔇 Additional comments (1)
apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (1)

94-97: Good null guard on first selected file

Thanks for guarding against an empty selection before computing the smart directory.

@vercel vercel bot temporarily deployed to Preview – docs August 14, 2025 00:58 Inactive
@Kitenite Kitenite merged commit 3e8dc10 into main Aug 14, 2025
5 of 7 checks passed
@Kitenite Kitenite deleted the fix/file-upload branch August 14, 2025 01:00
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
apps/web/client/src/components/store/editor/image/index.ts (1)

264-266: Type narrowing bug: filter(Boolean) does not narrow to ImageContentData[]

results is (ImageContentData | null)[]; filter((r) => !!r) produces (ImageContentData | null)[], which does not match the declared return Promise<ImageContentData[]> under strict typing. Use a type predicate to narrow:

-            const validImages = results.filter((result) => !!result);
-            return validImages;
+            const validImages = results.filter(
+                (result): result is ImageContentData => !!result
+            );
+            return validImages;
🧹 Nitpick comments (1)
apps/web/client/src/components/store/editor/image/index.ts (1)

193-196: Avoid stale state when image folder yields no results

If files is falsy, _imagePaths remains unchanged, potentially leaving stale entries. Clear it in this branch as done for the empty-array case.

-            if (!files) {
-                console.error('No files found in image folder');
-                return;
-            }
+            if (!files) {
+                console.error('No files found in image folder');
+                this._imagePaths = [];
+                return;
+            }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc6db3a and 27c6baf.

📒 Files selected for processing (2)
  • apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx (7 hunks)
  • apps/web/client/src/components/store/editor/image/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/client/src/app/project/[id]/_components/right-panel/dev-tab/upload-modal.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/client/src/components/store/editor/image/index.ts (1)
packages/models/src/actions/index.ts (1)
  • ActionTarget (8-12)
🔇 Additional comments (1)
apps/web/client/src/components/store/editor/image/index.ts (1)

173-179: No ActionTarget mismatch—code is correct

The ActionTarget interface in packages/models/src/actions/target.ts is defined as:

export interface ActionTarget {
    domId: string;
    oid: string | null;
    frameId: string;
}

Your code already constructs exactly that shape (frameId, domId, oid). No remapping or renaming is needed. Feel free to ignore the original suggestion.

Likely an incorrect or invalid review comment.

Comment on lines +2 to +3
import type { ActionTarget, ImageContentData, InsertImageAction } from '@onlook/models';
import { convertToBase64, generateNewFolderPath, getBaseName, getMimeType, isImageFile, stripImageFolderPrefix } from '@onlook/utility';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Import source consolidation looks fine; verify re-exports and type shapes to prevent breakages

Centralizing imports to @onlook/models and @onlook/utility is good. Please verify that:

  • @onlook/models re-exports ActionTarget, ImageContentData, InsertImageAction with the same shapes used here.
  • @onlook/utility re-exports convertToBase64, generateNewFolderPath, getBaseName, getMimeType, isImageFile, stripImageFolderPrefix.

Run this script to confirm presence and shapes of the re-exports:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Checking type re-exports in @onlook/models…"
rg -n --no-heading $'export( type)? \\{?\\s*ActionTarget\\b' -A 2 -B 2
rg -n --no-heading $'export( type)? \\{?\\s*ImageContentData\\b' -A 2 -B 2
rg -n --no-heading $'export( type)? \\{?\\s*InsertImageAction\\b' -A 2 -B 2

echo
echo "Enumerating ActionTarget shape(s)…"
rg -n --no-heading $'interface ActionTarget\\b' -A 20 -B 2
rg -n --no-heading $'type ActionTarget\\b' -A 20 -B 2

echo
echo "Checking utility exports in @onlook/utility…"
for sym in convertToBase64 generateNewFolderPath getBaseName getMimeType isImageFile stripImageFolderPrefix; do
  echo "Symbol: $sym"
  rg -n --no-heading $'export( const| function| type| interface)?\\s+'$sym -A 2 -B 2 || true
  rg -n --no-heading $'export \\{[^}]*\\b'$sym'\\b' -A 0 -B 0 || true
  echo
done

Length of output: 185


I didn’t see any output because the script aborted on the first missing match. Let’s rerun with a more resilient search across the entire repo (won’t stop on no‐matches) to locate both the re-exports and the actual definitions:


🏁 Script executed:

#!/bin/bash
# Continue even if patterns aren’t found
set -uo pipefail

echo "🔍 Checking @onlook/models for exported types…"
rg -n 'export( type)?[[:space:]]*\{[^}]*\b(ActionTarget|ImageContentData|InsertImageAction)\b[^}]*\}' -A2 -B2 || true

echo
echo "🔍 Locating type definitions in models…"
rg -n 'export (interface|type) (ActionTarget|ImageContentData|InsertImageAction)\b' -A20 -B2 || true

echo
echo "🔍 Checking @onlook/utility for named exports…"
rg -n 'export (const|function|type|interface)[[:space:]]+(convertToBase64|generateNewFolderPath|getBaseName|getMimeType|isImageFile|stripImageFolderPrefix)\b' -A2 -B2 || true

echo
echo "🔍 Checking utility index for grouped exports…"
rg -n 'export\s*\{[^}]*\b(convertToBase64|generateNewFolderPath|getBaseName|getMimeType|isImageFile|stripImageFolderPrefix)\b[^}]*\}' -A0 -B0 || true

Length of output: 5463


Let’s locate and inspect each package’s entry point to confirm the actual re-exports:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "🔍 Locating @onlook/models index file…"
MODELS_INDEX=$(fd index.ts packages/models/src -t f -1) || MODELS_INDEX=""
echo "models index: $MODELS_INDEX"
[ -n "$MODELS_INDEX" ] && sed -n '1,200p' "$MODELS_INDEX" || echo "No index.ts found for models"

echo
echo "🔍 Locating @onlook/utility index file…"
UTILITY_INDEX=$(fd index.ts packages/utility/src -t f -1) || UTILITY_INDEX=""
echo "utility index: $UTILITY_INDEX"
[ -n "$UTILITY_INDEX" ] && sed -n '1,200p' "$UTILITY_INDEX" || echo "No index.ts found for utility"

Length of output: 1474


To confirm each package’s published entrypoint and re-export strategy, let’s inspect their package.json files:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== @onlook/models package.json =="
sed -n '1,200p' packages/models/package.json || echo "Cannot read models package.json"

echo
echo "== @onlook/utility package.json =="
sed -n '1,200p' packages/utility/package.json || echo "Cannot read utility package.json"

Length of output: 2563


Confirm re-exports in @onlook/models and @onlook/utility

✅ The utility functions you’re importing are all exported through packages/utility/src/index.ts (via export * from './image', ./folder, and ./file'), so convertToBase64, generateNewFolderPath, getBaseName, getMimeType, isImageFile, and stripImageFolderPrefix will resolve correctly.

⚠️ The model types you need live here:
packages/models/src/actions/target.tsexport interface ActionTarget
packages/models/src/actions/action.tsexport interface ImageContentData and export interface InsertImageAction

However, I didn’t find a top-level packages/models/src/index.ts to re-export those interfaces (even though package.json points "." at src/index.ts). Please ensure that your models package’s entrypoint actually exports the action types—either by adding a barrel in src/index.ts or by adjusting the import paths (e.g. from @onlook/models/actions/...).

Tagging as fix required so we don’t accidentally ship broken type imports.

@coderabbitai coderabbitai bot mentioned this pull request Aug 14, 2025
8 tasks
Kitenite added a commit that referenced this pull request Aug 14, 2025
zongkelong pushed a commit to zongkelong/ulook that referenced this pull request Aug 15, 2025
* 'main' of https://github.com/onlook-dev/onlook: (41 commits)
  feat: fix delete project (onlook-dev#2683)
  feat: reduce search latency (onlook-dev#2682)
  feat: revamp projects ux (onlook-dev#2672)
  Upload fix (onlook-dev#2677)
  feat: using firecrawl to screenshot (onlook-dev#2665)
  fix: file upload build error (onlook-dev#2674)
  feat: new project frames (onlook-dev#2673)
  feat: self hosting docs (onlook-dev#2671)
  fix: docs layout + troubleshoot section (onlook-dev#2670)
  fix(template): suppress hydration mismatch
  Feat/editor improvements (onlook-dev#2601)
  fix: make message content selectable (onlook-dev#2664)
  bugs: transient stream error (onlook-dev#2663)
  feat: update migration files (onlook-dev#2659)
  Start from Blank + Import buttons on the home page (onlook-dev#2653)
  fix: snapshot type conflict and mastra can't view image (onlook-dev#2656)
  fix: typecheck snapshot (onlook-dev#2655)
  feat: clean up mastra branch (onlook-dev#2654)
  feat: mastra no storage (onlook-dev#2650)
  feat: update ai packages (onlook-dev#2648)
  ...
@coderabbitai coderabbitai bot mentioned this pull request Oct 14, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants