Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/web/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@
"use-resize-observer": "^9.1.0",
"uuid": "^11.1.0",
"webfontloader": "^1.6.28",
"zod": "^3.24.3"
"zod": "^3.24.3",
"@mendable/firecrawl-js": "^1.29.1"
},
"devDependencies": {
"@eslint/eslintrc": "^3.3.1",
Expand Down
20 changes: 10 additions & 10 deletions apps/web/client/public/onlook-preload-script.js

Large diffs are not rendered by default.

23 changes: 20 additions & 3 deletions apps/web/client/src/app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { type NextRequest } from 'next/server';
const isProd = env.NODE_ENV === 'production';

const MainModelConfig: InitialModelPayload = isProd ? {
provider: LLMProvider.OPENROUTER,
model: OPENROUTER_MODELS.CLAUDE_4_SONNET,
provider: LLMProvider.ANTHROPIC,
model: CLAUDE_MODELS.SONNET_4,
} : {
provider: LLMProvider.ANTHROPIC,
model: CLAUDE_MODELS.SONNET_4,
Expand Down Expand Up @@ -102,7 +102,24 @@ export const getSupabaseUser = async (request: NextRequest) => {

export const streamResponse = async (req: NextRequest) => {
const { messages, maxSteps, chatType } = await req.json();
const { model, providerOptions, headers } = await initModel(MainModelConfig);

let model, providerOptions, headers;
try {
const modelConfig = await initModel(MainModelConfig);
model = modelConfig.model;
providerOptions = modelConfig.providerOptions;
headers = modelConfig.headers;
} catch (error) {
console.error('Error initializing model:', error);
return new Response(JSON.stringify({
error: 'Failed to initialize AI model. Please check your API key configuration.',
code: 500,
details: error instanceof Error ? error.message : String(error)
}), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}

// Updating the usage record and rate limit is done here to avoid
// abuse in the case where a single user sends many concurrent requests.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEditorEngine } from '@/components/store/editor';
import { RecentActivityTracker } from '@/components/store/editor/chat/at-menu/recent-activity';
import { transKeys } from '@/i18n/keys';
import { EditorMode, LeftPanelTabValue } from '@onlook/models';
import { Icons } from '@onlook/ui/icons';
Expand Down Expand Up @@ -95,6 +96,35 @@ export const LeftPanel = observer(() => {
} else {
editorEngine.state.leftPanelTab = tab;
editorEngine.state.leftPanelLocked = true;

// Track tab activity for recents
const tabInfo = tabs.find(t => t.value === tab);
if (tabInfo && !tabInfo.disabled) {
const tabName = t(tabInfo.label as any);
const tabPath = `/${tab.toLowerCase()}`;
const icon = getTabIcon(tab);
RecentActivityTracker.addTabActivity(tabName, tabPath, icon);
}
}
};

// Helper function to get icon for tab activity tracking
const getTabIcon = (tab: LeftPanelTabValue): string => {
switch (tab) {
case LeftPanelTabValue.LAYERS:
return 'layers';
case LeftPanelTabValue.BRAND:
return 'brand';
case LeftPanelTabValue.PAGES:
return 'file';
case LeftPanelTabValue.IMAGES:
return 'image';
case LeftPanelTabValue.APPS:
return 'viewGrid';
case LeftPanelTabValue.COMPONENTS:
return 'component';
default:
return 'file';
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# @ Menu Folder Navigation

This document describes the folder navigation feature in the @ menu component.

## Overview

When a user types an @-mention followed by a forward slash (`/`), the @ menu will show child files and folders within the specified folder. This allows users to navigate through the file structure and select specific files.

## Usage

### Basic Folder Navigation

1. Type `@` to open the @ menu
2. Type a folder name followed by `/` (e.g., `@src/`)
3. The menu will show child files and folders within that folder
4. Use arrow keys to navigate and Enter to select

### Examples

- `@src/` - Shows files and folders within the `src` directory
- `@app/` - Shows files and folders within the `app` directory
- `@components/` - Shows files and folders within the `components` directory

## Implementation Details

### Data Providers

The `AtMenuDataProviders` class includes new methods for folder navigation:

- `getChildFiles(folderPath: string)` - Returns files within a specific folder
- `getChildFolders(folderPath: string)` - Returns folders within a specific folder
- `getChildItems(folderPath: string)` - Returns all child items (files and folders) within a specific folder

### Menu State

The menu tracks folder context using the `currentFolderContext` state, which displays a breadcrumb showing the current folder being navigated.

### Input Handling

The chat input component detects folder navigation patterns using regex:
- Pattern: `/^([^\/]+)\/$/` - Matches folder names followed by `/`
- When detected, the search query is updated to trigger folder navigation mode

### Selection Handling

When a user selects a child file from folder navigation:
1. The entire folder mention (e.g., `@src/`) is replaced with the selected file (e.g., `@index.ts`)
2. A space is automatically added after the file name
3. The menu closes and returns to normal input mode

## UI Features

### Breadcrumb Display

When in folder navigation mode, a breadcrumb appears at the top of the menu showing:
- Folder icon
- Folder name with `/` suffix
- Monospace font styling

### Child Item Styling

Child items in folder navigation mode:
- Don't show the full path (since they're already in the context of the folder)
- Maintain the same selection and hover states
- Include appropriate icons for files and folders

## Testing

Use the test page at `/test-at-menu` to verify folder navigation functionality:

1. Type `@src/` to see child files in the src folder
2. Type `@app/` to see child files in the app folder
3. Navigate with arrow keys and select with Enter
4. Verify that the folder mention is replaced with the selected file

## Future Enhancements

- Support for nested folder navigation (e.g., `@src/components/`)
- Breadcrumb navigation to go back to parent folders
- Search within folder context
- Keyboard shortcuts for folder navigation
Loading