Showing preview only (8,647K chars total). Download the full file or copy to clipboard to get everything.
Repository: onlook-dev/onlook
Branch: main
Commit: a242be584fa9
Files: 1600
Total size: 7.9 MB
Directory structure:
gitextract_tfg2fxbz/
├── .dockerignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── help_wanted.md
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── chromatic.yml
│ ├── ci.yml
│ └── supabase-push-staging.yml
├── .gitignore
├── .gitmodules
├── .prettierignore
├── .vscode/
│ ├── .debug.script.mjs
│ ├── extensions.json
│ ├── launch.json
│ └── tasks.json
├── AGENTS.md
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.md
├── README.md
├── SECURITY.md
├── apps/
│ ├── backend/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── supabase/
│ │ │ ├── .gitignore
│ │ │ ├── config.toml
│ │ │ └── migrations/
│ │ │ ├── 0000_same_human_robot.sql
│ │ │ ├── 0001_graceful_exodus.sql
│ │ │ ├── 0002_red_crusher_hogan.sql
│ │ │ ├── 0003_loud_ozymandias.sql
│ │ │ ├── 0004_pink_expediter.sql
│ │ │ ├── 0005_short_lila_cheney.sql
│ │ │ ├── 0006_rls.sql
│ │ │ ├── 0007_realtime_rls.sql
│ │ │ ├── 0008_preview-img-storage.sql
│ │ │ ├── 0009_project_img_path.sql
│ │ │ ├── 0010_bent_edwin_jarvis.sql
│ │ │ ├── 0011_typical_clea.sql
│ │ │ ├── 0012_file-transfer-bucket.sql
│ │ │ ├── 0013_aspiring_kabuki.sql
│ │ │ ├── 0014_military_marrow.sql
│ │ │ ├── 0015_same_leo.sql
│ │ │ ├── 0016_pretty_dust.sql
│ │ │ ├── 0017_small_xavin.sql
│ │ │ ├── 0018_lush_thanos.sql
│ │ │ ├── 0019_abandoned_psylocke.sql
│ │ │ └── meta/
│ │ │ ├── 0000_snapshot.json
│ │ │ ├── 0001_snapshot.json
│ │ │ ├── 0002_snapshot.json
│ │ │ ├── 0003_snapshot.json
│ │ │ ├── 0004_snapshot.json
│ │ │ ├── 0005_snapshot.json
│ │ │ ├── 0006_snapshot.json
│ │ │ ├── 0007_snapshot.json
│ │ │ ├── 0008_snapshot.json
│ │ │ ├── 0009_snapshot.json
│ │ │ ├── 0010_snapshot.json
│ │ │ ├── 0011_snapshot.json
│ │ │ ├── 0012_snapshot.json
│ │ │ ├── 0013_snapshot.json
│ │ │ ├── 0014_snapshot.json
│ │ │ ├── 0015_snapshot.json
│ │ │ ├── 0016_snapshot.json
│ │ │ ├── 0017_snapshot.json
│ │ │ ├── 0018_snapshot.json
│ │ │ ├── 0019_snapshot.json
│ │ │ └── _journal.json
│ │ └── tsconfig.json
│ └── web/
│ ├── .gitignore
│ ├── README.md
│ ├── client/
│ │ ├── .gitignore
│ │ ├── .storybook/
│ │ │ ├── main.ts
│ │ │ ├── mocks/
│ │ │ │ ├── supabase-client.ts
│ │ │ │ └── trpc-react.tsx
│ │ │ ├── preview-head.html
│ │ │ ├── preview.tsx
│ │ │ └── vitest.setup.ts
│ │ ├── README.md
│ │ ├── chromatic.config.json
│ │ ├── components.json
│ │ ├── eslint.config.js
│ │ ├── messages/
│ │ │ ├── en.d.json.ts
│ │ │ ├── en.json
│ │ │ ├── es.json
│ │ │ ├── ja.json
│ │ │ ├── ko.json
│ │ │ └── zh.json
│ │ ├── next.config.ts
│ │ ├── package.json
│ │ ├── postcss.config.js
│ │ ├── public/
│ │ │ ├── onlook-preload-script.js
│ │ │ └── scenes/
│ │ │ └── flow-background.json
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── _components/
│ │ │ │ │ ├── auth-modal.tsx
│ │ │ │ │ ├── button-link.tsx
│ │ │ │ │ ├── hero/
│ │ │ │ │ │ ├── ai-features-hero.tsx
│ │ │ │ │ │ ├── ai-frontend-hero.tsx
│ │ │ │ │ │ ├── builder-features-hero.tsx
│ │ │ │ │ │ ├── claude-code-hero.tsx
│ │ │ │ │ │ ├── create-error.tsx
│ │ │ │ │ │ ├── create.tsx
│ │ │ │ │ │ ├── features-hero.tsx
│ │ │ │ │ │ ├── high-demand.tsx
│ │ │ │ │ │ ├── import.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── mobile-email-capture.tsx
│ │ │ │ │ │ ├── start-blank.tsx
│ │ │ │ │ │ └── unicorn-background.tsx
│ │ │ │ │ ├── landing-page/
│ │ │ │ │ │ ├── ai-benefits-section.tsx
│ │ │ │ │ │ ├── ai-features-grid-section.tsx
│ │ │ │ │ │ ├── ai-features-intro-section.tsx
│ │ │ │ │ │ ├── benefits-section.tsx
│ │ │ │ │ │ ├── builder-benefits-section.tsx
│ │ │ │ │ │ ├── builder-features-grid-section.tsx
│ │ │ │ │ │ ├── builder-features-intro-section.tsx
│ │ │ │ │ │ ├── code-one-to-one-section.tsx
│ │ │ │ │ │ ├── color-swatch-group.tsx
│ │ │ │ │ │ ├── contributor-section.tsx
│ │ │ │ │ │ ├── contributor.css
│ │ │ │ │ │ ├── cta-section.tsx
│ │ │ │ │ │ ├── design-mockup/
│ │ │ │ │ │ │ ├── design-mockup-icons.tsx
│ │ │ │ │ │ │ └── design-mockup.tsx
│ │ │ │ │ │ ├── faq-dropdown.tsx
│ │ │ │ │ │ ├── faq-section.tsx
│ │ │ │ │ │ ├── feature-blocks/
│ │ │ │ │ │ │ ├── ai-chat-preview-block.tsx
│ │ │ │ │ │ │ ├── brand-compliance.tsx
│ │ │ │ │ │ │ ├── components.tsx
│ │ │ │ │ │ │ ├── direct-editing.tsx
│ │ │ │ │ │ │ ├── layers.tsx
│ │ │ │ │ │ │ ├── responsive-website.tsx
│ │ │ │ │ │ │ └── revision-history.tsx
│ │ │ │ │ │ ├── features-grid-section.tsx
│ │ │ │ │ │ ├── features-intro-section.tsx
│ │ │ │ │ │ ├── illustrations.tsx
│ │ │ │ │ │ ├── obsess-for-hours-section.tsx
│ │ │ │ │ │ ├── onlook-interface-mockup.tsx
│ │ │ │ │ │ ├── page-footer.tsx
│ │ │ │ │ │ ├── responsive-mockup-section.tsx
│ │ │ │ │ │ ├── social-proof-section.tsx
│ │ │ │ │ │ ├── testimonials-section.tsx
│ │ │ │ │ │ └── what-can-onlook-do-section.tsx
│ │ │ │ │ ├── login-button.tsx
│ │ │ │ │ ├── shared/
│ │ │ │ │ │ └── mockups/
│ │ │ │ │ │ ├── ai-chat-interactive.tsx
│ │ │ │ │ │ ├── components-mockup.tsx
│ │ │ │ │ │ ├── direct-editing-interactive.tsx
│ │ │ │ │ │ └── tailwind-color-editor.tsx
│ │ │ │ │ ├── theme.tsx
│ │ │ │ │ ├── top-bar/
│ │ │ │ │ │ ├── github.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── mega-menu.tsx
│ │ │ │ │ │ ├── mobile-menu.tsx
│ │ │ │ │ │ └── user.tsx
│ │ │ │ │ └── website-layout.tsx
│ │ │ │ ├── about/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── api/
│ │ │ │ │ ├── chat/
│ │ │ │ │ │ ├── helpers/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── stream.ts
│ │ │ │ │ │ │ └── usage.ts
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── email-capture/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── trpc/
│ │ │ │ │ └── [trpc]/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── auth/
│ │ │ │ │ ├── auth-context.tsx
│ │ │ │ │ ├── callback/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── redirect/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── callback/
│ │ │ │ │ ├── github/
│ │ │ │ │ │ └── install/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── stripe/
│ │ │ │ │ ├── cancel/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── message-screen.tsx
│ │ │ │ │ └── success/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── faq/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── features/
│ │ │ │ │ ├── ai/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── ai-for-frontend/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── builder/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── prototype/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── fonts.ts
│ │ │ │ ├── invitation/
│ │ │ │ │ └── [id]/
│ │ │ │ │ ├── _components/
│ │ │ │ │ │ ├── auth.tsx
│ │ │ │ │ │ └── main.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── login/
│ │ │ │ │ ├── actions.tsx
│ │ │ │ │ ├── error.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── not-found.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── pricing/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── privacy-policy/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── project/
│ │ │ │ │ ├── [id]/
│ │ │ │ │ │ ├── _components/
│ │ │ │ │ │ │ ├── bottom-bar/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── restart-sandbox-button.tsx
│ │ │ │ │ │ │ │ ├── terminal-area.tsx
│ │ │ │ │ │ │ │ └── terminal.tsx
│ │ │ │ │ │ │ ├── branch/
│ │ │ │ │ │ │ │ ├── branch-controls.tsx
│ │ │ │ │ │ │ │ └── branch-list.tsx
│ │ │ │ │ │ │ ├── canvas/
│ │ │ │ │ │ │ │ ├── frame/
│ │ │ │ │ │ │ │ │ ├── gesture.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── resize-handles.tsx
│ │ │ │ │ │ │ │ │ ├── top-bar/
│ │ │ │ │ │ │ │ │ │ ├── branch.tsx
│ │ │ │ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── page-selector.tsx
│ │ │ │ │ │ │ │ │ ├── use-frame-reload.ts
│ │ │ │ │ │ │ │ │ ├── use-sandbox-timeout.ts
│ │ │ │ │ │ │ │ │ └── view.tsx
│ │ │ │ │ │ │ │ ├── frames.tsx
│ │ │ │ │ │ │ │ ├── hotkeys/
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── overlay/
│ │ │ │ │ │ │ │ │ ├── drag-select.tsx
│ │ │ │ │ │ │ │ │ ├── elements/
│ │ │ │ │ │ │ │ │ │ ├── buttons/
│ │ │ │ │ │ │ │ │ │ │ ├── chat.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── code.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── measurement.tsx
│ │ │ │ │ │ │ │ │ │ ├── rect/
│ │ │ │ │ │ │ │ │ │ │ ├── base.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── click.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── hover.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── insert.tsx
│ │ │ │ │ │ │ │ │ │ │ └── resize.tsx
│ │ │ │ │ │ │ │ │ │ ├── snap-guidelines.tsx
│ │ │ │ │ │ │ │ │ │ └── text.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ └── pan.tsx
│ │ │ │ │ │ │ │ ├── recenter-canvas-button.tsx
│ │ │ │ │ │ │ │ └── selection-utils.ts
│ │ │ │ │ │ │ ├── clone-project-dialog.tsx
│ │ │ │ │ │ │ ├── editor-bar/
│ │ │ │ │ │ │ │ ├── div-selected.tsx
│ │ │ │ │ │ │ │ ├── dropdowns/
│ │ │ │ │ │ │ │ │ ├── border-color.tsx
│ │ │ │ │ │ │ │ │ ├── border.tsx
│ │ │ │ │ │ │ │ │ ├── color-background.tsx
│ │ │ │ │ │ │ │ │ ├── display/
│ │ │ │ │ │ │ │ │ │ ├── direction.tsx
│ │ │ │ │ │ │ │ │ │ ├── gap.tsx
│ │ │ │ │ │ │ │ │ │ ├── horizontal-align.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── type.tsx
│ │ │ │ │ │ │ │ │ │ └── vertical-align.tsx
│ │ │ │ │ │ │ │ │ ├── height.tsx
│ │ │ │ │ │ │ │ │ ├── img-background.tsx
│ │ │ │ │ │ │ │ │ ├── img-fit.tsx
│ │ │ │ │ │ │ │ │ ├── margin.tsx
│ │ │ │ │ │ │ │ │ ├── opacity.tsx
│ │ │ │ │ │ │ │ │ ├── padding.tsx
│ │ │ │ │ │ │ │ │ ├── radius.tsx
│ │ │ │ │ │ │ │ │ ├── state-dropdown.tsx
│ │ │ │ │ │ │ │ │ └── width.tsx
│ │ │ │ │ │ │ │ ├── frame-selected/
│ │ │ │ │ │ │ │ │ ├── device-selector.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── rotate-group.tsx
│ │ │ │ │ │ │ │ │ ├── theme-group.tsx
│ │ │ │ │ │ │ │ │ └── window-actions-group.tsx
│ │ │ │ │ │ │ │ ├── hooks/
│ │ │ │ │ │ │ │ │ ├── use-background-image-update.ts
│ │ │ │ │ │ │ │ │ ├── use-box-control.ts
│ │ │ │ │ │ │ │ │ ├── use-color-update.ts
│ │ │ │ │ │ │ │ │ ├── use-dimension-control.ts
│ │ │ │ │ │ │ │ │ ├── use-dropdown-manager.tsx
│ │ │ │ │ │ │ │ │ ├── use-gradient-update.ts
│ │ │ │ │ │ │ │ │ ├── use-input-control.ts
│ │ │ │ │ │ │ │ │ ├── use-measure-group.ts
│ │ │ │ │ │ │ │ │ └── use-text-control.ts
│ │ │ │ │ │ │ │ ├── hover-tooltip.tsx
│ │ │ │ │ │ │ │ ├── img-selected.tsx
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── inputs/
│ │ │ │ │ │ │ │ │ ├── color-picker.tsx
│ │ │ │ │ │ │ │ │ ├── input-color.tsx
│ │ │ │ │ │ │ │ │ ├── input-dropdown.tsx
│ │ │ │ │ │ │ │ │ ├── input-icon.tsx
│ │ │ │ │ │ │ │ │ ├── input-image.tsx
│ │ │ │ │ │ │ │ │ ├── input-radio.tsx
│ │ │ │ │ │ │ │ │ ├── input-range.tsx
│ │ │ │ │ │ │ │ │ └── spacing-inputs.tsx
│ │ │ │ │ │ │ │ ├── overflow-menu.tsx
│ │ │ │ │ │ │ │ ├── separator.tsx
│ │ │ │ │ │ │ │ ├── text-inputs/
│ │ │ │ │ │ │ │ │ ├── advanced-typography.tsx
│ │ │ │ │ │ │ │ │ ├── font/
│ │ │ │ │ │ │ │ │ │ ├── font-family-selector.tsx
│ │ │ │ │ │ │ │ │ │ ├── font-family.tsx
│ │ │ │ │ │ │ │ │ │ ├── font-size.tsx
│ │ │ │ │ │ │ │ │ │ └── font-weight.tsx
│ │ │ │ │ │ │ │ │ ├── text-align.tsx
│ │ │ │ │ │ │ │ │ └── text-color.tsx
│ │ │ │ │ │ │ │ ├── text-selected.tsx
│ │ │ │ │ │ │ │ ├── toolbar-button.tsx
│ │ │ │ │ │ │ │ └── utils/
│ │ │ │ │ │ │ │ └── gradient.ts
│ │ │ │ │ │ │ ├── left-panel/
│ │ │ │ │ │ │ │ ├── code-panel/
│ │ │ │ │ │ │ │ │ ├── code-tab/
│ │ │ │ │ │ │ │ │ │ ├── file-content/
│ │ │ │ │ │ │ │ │ │ │ ├── code-editor.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── code-mirror-config.ts
│ │ │ │ │ │ │ │ │ │ │ ├── floating-add-to-chat-button.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ │ └── unsaved-changes-dialog.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tabs/
│ │ │ │ │ │ │ │ │ │ │ ├── file-tab.tsx
│ │ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── header-controls.tsx
│ │ │ │ │ │ │ │ │ │ ├── hooks/
│ │ │ │ │ │ │ │ │ │ │ └── use-code-navigation.ts
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── modals/
│ │ │ │ │ │ │ │ │ │ │ ├── file-modal.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── folder-modal.tsx
│ │ │ │ │ │ │ │ │ │ │ └── upload-modal.tsx
│ │ │ │ │ │ │ │ │ │ ├── shared/
│ │ │ │ │ │ │ │ │ │ │ ├── file-operations.ts
│ │ │ │ │ │ │ │ │ │ │ ├── file-templates.ts
│ │ │ │ │ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ │ │ │ │ └── sidebar/
│ │ │ │ │ │ │ │ │ │ ├── file-icon.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tree-node.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tree-row.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tree-search.tsx
│ │ │ │ │ │ │ │ │ │ └── file-tree.tsx
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── design-panel/
│ │ │ │ │ │ │ │ │ ├── branches-tab/
│ │ │ │ │ │ │ │ │ │ ├── branch-management.tsx
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── brand-tab/
│ │ │ │ │ │ │ │ │ │ ├── color-panel/
│ │ │ │ │ │ │ │ │ │ │ ├── color-name-input.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── color-pallet-group.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── color-popover.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── color-row.tsx
│ │ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── font-panel/
│ │ │ │ │ │ │ │ │ │ │ ├── font-family.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── font-files.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── system-font.tsx
│ │ │ │ │ │ │ │ │ │ │ └── upload-modal.tsx
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── help-button/
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── image-tab/
│ │ │ │ │ │ │ │ │ │ ├── breadcrumb-navigation.tsx
│ │ │ │ │ │ │ │ │ │ ├── folder-list.tsx
│ │ │ │ │ │ │ │ │ │ ├── hooks/
│ │ │ │ │ │ │ │ │ │ │ ├── use-image-drag-drop.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── use-image-operations.tsx
│ │ │ │ │ │ │ │ │ │ │ └── use-navigation.tsx
│ │ │ │ │ │ │ │ │ │ ├── image-grid.tsx
│ │ │ │ │ │ │ │ │ │ ├── image-item.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── search-upload-bar.tsx
│ │ │ │ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ │ │ │ └── utils/
│ │ │ │ │ │ │ │ │ │ ├── image-references.test.ts
│ │ │ │ │ │ │ │ │ │ └── image-references.ts
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── layers-tab/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── tree/
│ │ │ │ │ │ │ │ │ │ ├── page-tree-node.tsx
│ │ │ │ │ │ │ │ │ │ ├── page-tree-row.tsx
│ │ │ │ │ │ │ │ │ │ ├── tree-node.tsx
│ │ │ │ │ │ │ │ │ │ └── tree-row.tsx
│ │ │ │ │ │ │ │ │ ├── page-tab/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── page-modal.tsx
│ │ │ │ │ │ │ │ │ ├── windows-tab/
│ │ │ │ │ │ │ │ │ │ ├── device-settings.tsx
│ │ │ │ │ │ │ │ │ │ ├── frame-dimensions.tsx
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ └── zoom-controls/
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── main.tsx
│ │ │ │ │ │ │ ├── members/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── invitation-row.tsx
│ │ │ │ │ │ │ │ ├── invite-member-input.tsx
│ │ │ │ │ │ │ │ ├── member-row.tsx
│ │ │ │ │ │ │ │ ├── members-content.tsx
│ │ │ │ │ │ │ │ └── suggested-teammates.tsx
│ │ │ │ │ │ │ ├── right-click-menu/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── right-panel/
│ │ │ │ │ │ │ │ ├── chat-tab/
│ │ │ │ │ │ │ │ │ ├── chat-input/
│ │ │ │ │ │ │ │ │ │ ├── action-buttons.tsx
│ │ │ │ │ │ │ │ │ │ ├── chat-context.tsx
│ │ │ │ │ │ │ │ │ │ ├── chat-mode-toggle.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── queue-items/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── queue-item.tsx
│ │ │ │ │ │ │ │ │ ├── chat-messages/
│ │ │ │ │ │ │ │ │ │ ├── assistant-message.tsx
│ │ │ │ │ │ │ │ │ │ ├── error-message.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── message-content/
│ │ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── tool-call-display.tsx
│ │ │ │ │ │ │ │ │ │ │ └── tool-call-simple.tsx
│ │ │ │ │ │ │ │ │ │ ├── multi-branch-revert-modal.tsx
│ │ │ │ │ │ │ │ │ │ ├── stream-message.tsx
│ │ │ │ │ │ │ │ │ │ └── user-message.tsx
│ │ │ │ │ │ │ │ │ ├── chat-tab-content/
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── code-display/
│ │ │ │ │ │ │ │ │ │ ├── bash-code-display.tsx
│ │ │ │ │ │ │ │ │ │ ├── code-block.tsx
│ │ │ │ │ │ │ │ │ │ ├── code-diff.tsx
│ │ │ │ │ │ │ │ │ │ ├── collapsible-code-block.tsx
│ │ │ │ │ │ │ │ │ │ └── search-sources-display.tsx
│ │ │ │ │ │ │ │ │ ├── context-pills/
│ │ │ │ │ │ │ │ │ │ ├── draft-context-pill.tsx
│ │ │ │ │ │ │ │ │ │ ├── helpers.tsx
│ │ │ │ │ │ │ │ │ │ ├── image-pill.tsx
│ │ │ │ │ │ │ │ │ │ ├── input-context-pills.tsx
│ │ │ │ │ │ │ │ │ │ └── sent-context-pill.tsx
│ │ │ │ │ │ │ │ │ ├── controls.tsx
│ │ │ │ │ │ │ │ │ ├── error.tsx
│ │ │ │ │ │ │ │ │ ├── history.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── panel-dropdown.tsx
│ │ │ │ │ │ │ │ │ └── suggestions.tsx
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ └── top-bar/
│ │ │ │ │ │ │ ├── branch.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── mode-toggle.tsx
│ │ │ │ │ │ │ ├── new-project-menu.tsx
│ │ │ │ │ │ │ ├── project-breadcrumb.tsx
│ │ │ │ │ │ │ ├── publish/
│ │ │ │ │ │ │ │ ├── dropdown/
│ │ │ │ │ │ │ │ │ ├── advanced-settings.tsx
│ │ │ │ │ │ │ │ │ ├── custom-domain/
│ │ │ │ │ │ │ │ │ │ ├── action.tsx
│ │ │ │ │ │ │ │ │ │ ├── domain.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── no-domain.tsx
│ │ │ │ │ │ │ │ │ │ └── provider.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── loading.tsx
│ │ │ │ │ │ │ │ │ ├── preview-domain-section.tsx
│ │ │ │ │ │ │ │ │ └── url.tsx
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ └── trigger-button.tsx
│ │ │ │ │ │ │ └── recent-projects.tsx
│ │ │ │ │ │ ├── _hooks/
│ │ │ │ │ │ │ ├── use-chat/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ │ ├── use-panel-measure.tsx
│ │ │ │ │ │ │ ├── use-start-project.tsx
│ │ │ │ │ │ │ └── use-tab-active.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── providers.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── projects/
│ │ │ │ │ ├── _components/
│ │ │ │ │ │ ├── carousel/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── edit-app.tsx
│ │ │ │ │ │ ├── select/
│ │ │ │ │ │ │ ├── highlight-text.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── masonry-layout.tsx
│ │ │ │ │ │ │ ├── project-card-presentation.tsx
│ │ │ │ │ │ │ ├── project-card.tsx
│ │ │ │ │ │ │ ├── square-project-card-presentation.tsx
│ │ │ │ │ │ │ └── square-project-card.tsx
│ │ │ │ │ │ ├── select-presentation.tsx
│ │ │ │ │ │ ├── settings/
│ │ │ │ │ │ │ ├── clone-project.tsx
│ │ │ │ │ │ │ ├── create-template.tsx
│ │ │ │ │ │ │ ├── delete-project.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── rename-project.tsx
│ │ │ │ │ │ ├── templates/
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── lazy-image.tsx
│ │ │ │ │ │ │ ├── template-card.tsx
│ │ │ │ │ │ │ ├── template-modal-presentation.tsx
│ │ │ │ │ │ │ └── template-modal.tsx
│ │ │ │ │ │ ├── top-bar-presentation.tsx
│ │ │ │ │ │ └── top-bar.tsx
│ │ │ │ │ ├── import/
│ │ │ │ │ │ ├── cancel-button.tsx
│ │ │ │ │ │ ├── github/
│ │ │ │ │ │ │ ├── _components/
│ │ │ │ │ │ │ │ ├── connect.tsx
│ │ │ │ │ │ │ │ ├── finalizing.tsx
│ │ │ │ │ │ │ │ └── setup.tsx
│ │ │ │ │ │ │ ├── _context/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── _hooks/
│ │ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ │ ├── use-data.ts
│ │ │ │ │ │ │ │ ├── use-installation.ts
│ │ │ │ │ │ │ │ ├── use-repo-import.ts
│ │ │ │ │ │ │ │ └── use-repo-validation.ts
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── local/
│ │ │ │ │ │ │ ├── _components/
│ │ │ │ │ │ │ │ ├── finalizing-project.tsx
│ │ │ │ │ │ │ │ ├── import-local-project.tsx
│ │ │ │ │ │ │ │ ├── select-folder.tsx
│ │ │ │ │ │ │ │ └── verify-project.tsx
│ │ │ │ │ │ │ ├── _context/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── steps.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── types.ts
│ │ │ │ ├── see-a-demo/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── seo.ts
│ │ │ │ ├── site-map/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── sitemap.ts
│ │ │ │ ├── terms-of-service/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── webhook/
│ │ │ │ │ └── stripe/
│ │ │ │ │ ├── route.ts
│ │ │ │ │ └── subscription/
│ │ │ │ │ ├── create.ts
│ │ │ │ │ ├── delete.ts
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── update.ts
│ │ │ │ └── workflows/
│ │ │ │ ├── claude-code/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── vibe-coding/
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── components/
│ │ │ │ ├── hotkey.ts
│ │ │ │ ├── ide.ts
│ │ │ │ ├── rb2b-loader.tsx
│ │ │ │ ├── store/
│ │ │ │ │ ├── create/
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── manager.ts
│ │ │ │ │ ├── editor/
│ │ │ │ │ │ ├── action/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── api/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── ast/
│ │ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── layers.ts
│ │ │ │ │ │ ├── branch/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── manager.ts
│ │ │ │ │ │ ├── cache/
│ │ │ │ │ │ │ ├── file-cache.ts
│ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ └── unified-cache.ts
│ │ │ │ │ │ ├── canvas/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── chat/
│ │ │ │ │ │ │ ├── context.ts
│ │ │ │ │ │ │ ├── conversation.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── code/
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── insert.ts
│ │ │ │ │ │ │ ├── requests.ts
│ │ │ │ │ │ │ └── tailwind.ts
│ │ │ │ │ │ ├── copy/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── element/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── engine.ts
│ │ │ │ │ │ ├── error/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── font/
│ │ │ │ │ │ │ ├── font-config.ts
│ │ │ │ │ │ │ ├── font-search-manager.ts
│ │ │ │ │ │ │ ├── font-upload-manager.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── layout-manager.ts
│ │ │ │ │ │ │ └── tailwind-config.ts
│ │ │ │ │ │ ├── frame-events/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ │ ├── frames/
│ │ │ │ │ │ │ ├── dimension.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── manager.ts
│ │ │ │ │ │ │ └── navigation.ts
│ │ │ │ │ │ ├── git/
│ │ │ │ │ │ │ ├── git.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── group/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── history/
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── ide/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── image/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── insert/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── move/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── overlay/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── prosemirror/
│ │ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ │ ├── state.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── pages/
│ │ │ │ │ │ │ ├── helper.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── sandbox/
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── preload-script.ts
│ │ │ │ │ │ │ ├── session.ts
│ │ │ │ │ │ │ └── terminal.ts
│ │ │ │ │ │ ├── screenshot/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── snap/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ │ ├── state/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── style/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── text/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── theme/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── util.ts
│ │ │ │ │ ├── hosting/
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── provider.tsx
│ │ │ │ │ │ └── type.tsx
│ │ │ │ │ └── state/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── manager.ts
│ │ │ │ ├── telemetry-provider.tsx
│ │ │ │ ├── tools/
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── tools.ts
│ │ │ │ └── ui/
│ │ │ │ ├── auth-redirect.tsx
│ │ │ │ ├── avatar-dropdown/
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── plans.tsx
│ │ │ │ ├── pricing-modal/
│ │ │ │ │ ├── enterprise-card.tsx
│ │ │ │ │ ├── free-card.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── legacy-promotion.tsx
│ │ │ │ │ ├── pro-card.tsx
│ │ │ │ │ └── use-subscription.tsx
│ │ │ │ ├── pricing-table/
│ │ │ │ │ └── index.tsx
│ │ │ │ └── settings-modal/
│ │ │ │ ├── domain/
│ │ │ │ │ ├── custom/
│ │ │ │ │ │ ├── headers.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── no-domain-input.tsx
│ │ │ │ │ │ ├── record-field.tsx
│ │ │ │ │ │ ├── use-domain-verification.tsx
│ │ │ │ │ │ ├── verification.tsx
│ │ │ │ │ │ └── verified.tsx
│ │ │ │ │ ├── danger-zone.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── preview.tsx
│ │ │ │ │ └── upgrade-prompt.tsx
│ │ │ │ ├── helpers.tsx
│ │ │ │ ├── non-project.tsx
│ │ │ │ ├── preferences-tab.tsx
│ │ │ │ ├── project/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── site/
│ │ │ │ │ ├── favicon.tsx
│ │ │ │ │ ├── image.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── metadata-form.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── use-metadata-form.ts
│ │ │ │ ├── subscription-cancel-modal.tsx
│ │ │ │ ├── subscription-tab.tsx
│ │ │ │ ├── user-delete-section.tsx
│ │ │ │ ├── versions/
│ │ │ │ │ ├── empty-state/
│ │ │ │ │ │ └── version.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── version-row.tsx
│ │ │ │ │ └── versions.tsx
│ │ │ │ └── with-project.tsx
│ │ │ ├── env.ts
│ │ │ ├── global.ts
│ │ │ ├── hooks/
│ │ │ │ ├── use-create-blank-project.ts
│ │ │ │ ├── use-debounce-input.tsx
│ │ │ │ ├── use-feature-flags.tsx
│ │ │ │ ├── use-font-loader.tsx
│ │ │ │ ├── use-get-background.tsx
│ │ │ │ └── use-parallax-cursor.ts
│ │ │ ├── i18n/
│ │ │ │ ├── keys.ts
│ │ │ │ └── request.ts
│ │ │ ├── instrumentation.ts
│ │ │ ├── proxy.ts
│ │ │ ├── server/
│ │ │ │ └── api/
│ │ │ │ ├── root.ts
│ │ │ │ ├── routers/
│ │ │ │ │ ├── chat/
│ │ │ │ │ │ ├── conversation.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── message.ts
│ │ │ │ │ │ └── suggestion.ts
│ │ │ │ │ ├── code.ts
│ │ │ │ │ ├── domain/
│ │ │ │ │ │ ├── adapters/
│ │ │ │ │ │ │ └── freestyle.ts
│ │ │ │ │ │ ├── custom.ts
│ │ │ │ │ │ ├── freestyle.ts
│ │ │ │ │ │ ├── hosting-factory.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── preview.ts
│ │ │ │ │ │ └── verify/
│ │ │ │ │ │ ├── helpers/
│ │ │ │ │ │ │ ├── freestyle.ts
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── records.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── forward/
│ │ │ │ │ │ ├── editor.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── github.ts
│ │ │ │ │ ├── image.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── project/
│ │ │ │ │ │ ├── branch.ts
│ │ │ │ │ │ ├── createRequest.ts
│ │ │ │ │ │ ├── fork.ts
│ │ │ │ │ │ ├── frame.ts
│ │ │ │ │ │ ├── helper.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── invitation.ts
│ │ │ │ │ │ ├── member.ts
│ │ │ │ │ │ ├── project.ts
│ │ │ │ │ │ ├── sandbox.ts
│ │ │ │ │ │ └── settings.ts
│ │ │ │ │ ├── publish/
│ │ │ │ │ │ ├── deployment.ts
│ │ │ │ │ │ ├── helpers/
│ │ │ │ │ │ │ ├── deploy.ts
│ │ │ │ │ │ │ ├── env.ts
│ │ │ │ │ │ │ ├── fork.ts
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── publish.ts
│ │ │ │ │ │ │ └── unpublish.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── manager.ts
│ │ │ │ │ ├── subscription/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── subscription.ts
│ │ │ │ │ ├── usage/
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── user/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── user-canvas.ts
│ │ │ │ │ ├── user-settings.ts
│ │ │ │ │ └── user.ts
│ │ │ │ └── trpc.ts
│ │ │ ├── services/
│ │ │ │ └── sync-engine/
│ │ │ │ ├── index.ts
│ │ │ │ └── sync-engine.ts
│ │ │ ├── stories/
│ │ │ │ ├── Button.stories.tsx
│ │ │ │ ├── ProjectCard.stories.tsx
│ │ │ │ ├── ProjectsPage.stories.tsx
│ │ │ │ ├── SelectProject.stories.tsx
│ │ │ │ ├── TopBar.stories.tsx
│ │ │ │ └── assets/
│ │ │ │ └── avif-test-image.avif
│ │ │ ├── styles/
│ │ │ │ └── globals.css
│ │ │ ├── trpc/
│ │ │ │ ├── client.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── query-client.ts
│ │ │ │ ├── react.tsx
│ │ │ │ ├── request-server.ts
│ │ │ │ └── server.ts
│ │ │ └── utils/
│ │ │ ├── analytics/
│ │ │ │ └── server.ts
│ │ │ ├── constants/
│ │ │ │ ├── index.ts
│ │ │ │ └── navigation.ts
│ │ │ ├── git/
│ │ │ │ ├── index.test.ts
│ │ │ │ └── index.ts
│ │ │ ├── n8n/
│ │ │ │ └── webhook.ts
│ │ │ ├── subscription.ts
│ │ │ ├── supabase/
│ │ │ │ ├── admin.ts
│ │ │ │ ├── client/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── middleware.ts
│ │ │ │ ├── request-server.ts
│ │ │ │ └── server.ts
│ │ │ ├── telemetry/
│ │ │ │ └── index.ts
│ │ │ ├── upload/
│ │ │ │ └── image-compression.ts
│ │ │ └── url/
│ │ │ └── index.ts
│ │ ├── test/
│ │ │ ├── cache/
│ │ │ │ ├── file-cache.test.ts
│ │ │ │ └── unified-cache.test.ts
│ │ │ ├── frame/
│ │ │ │ └── navigation.test.ts
│ │ │ ├── messages.test.ts
│ │ │ ├── pages/
│ │ │ │ └── helper.test.ts
│ │ │ ├── sandbox/
│ │ │ │ ├── env.test.ts
│ │ │ │ ├── helpers.test.ts
│ │ │ │ ├── port.test.ts
│ │ │ │ └── subdirectory.test.ts
│ │ │ └── setup.ts
│ │ ├── tsconfig.json
│ │ ├── vercel.json
│ │ ├── vitest.config.ts
│ │ └── vitest.shims.d.ts
│ ├── package.json
│ ├── preload/
│ │ ├── .gitignore
│ │ ├── Dockerfile
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── script/
│ │ │ ├── api/
│ │ │ │ ├── dom.ts
│ │ │ │ ├── elements/
│ │ │ │ │ ├── dom/
│ │ │ │ │ │ ├── group.ts
│ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ ├── image.ts
│ │ │ │ │ │ ├── insert.ts
│ │ │ │ │ │ └── remove.ts
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── move/
│ │ │ │ │ │ ├── drag.ts
│ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── stub.ts
│ │ │ │ │ ├── style.ts
│ │ │ │ │ └── text.ts
│ │ │ │ ├── events/
│ │ │ │ │ ├── dom.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── publish.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── ready.ts
│ │ │ │ ├── screenshot.ts
│ │ │ │ ├── state.ts
│ │ │ │ ├── style/
│ │ │ │ │ ├── css-manager.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── update.ts
│ │ │ │ └── theme/
│ │ │ │ └── index.ts
│ │ │ ├── helpers/
│ │ │ │ ├── assert.ts
│ │ │ │ ├── clone.ts
│ │ │ │ ├── dom.ts
│ │ │ │ ├── ids.ts
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ ├── server/
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ └── server/
│ ├── .gitignore
│ ├── Dockerfile
│ ├── README.md
│ ├── eslint.config.js
│ ├── package.json
│ ├── src/
│ │ ├── index.ts
│ │ ├── router/
│ │ │ ├── context.ts
│ │ │ ├── index.ts
│ │ │ ├── routes/
│ │ │ │ └── sandbox.ts
│ │ │ └── trpc.ts
│ │ ├── sandbox/
│ │ │ └── index.ts
│ │ └── server.ts
│ └── tsconfig.json
├── bunfig.toml
├── docker-compose.yml
├── docs/
│ ├── .gitignore
│ ├── README.md
│ ├── content/
│ │ └── docs/
│ │ ├── developers/
│ │ │ ├── appendix.mdx
│ │ │ ├── architecture.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── running-locally.mdx
│ │ │ └── troubleshooting.mdx
│ │ ├── enterprise.mdx
│ │ ├── faq.mdx
│ │ ├── getting-started/
│ │ │ ├── core-features.mdx
│ │ │ ├── first-project.mdx
│ │ │ ├── meta.json
│ │ │ └── ui-overview.mdx
│ │ ├── index.mdx
│ │ ├── meta.json
│ │ ├── migrations/
│ │ │ └── electron-to-web-migration.mdx
│ │ ├── self-hosting/
│ │ │ ├── admin-dashboard.mdx
│ │ │ ├── cloud-deployment.mdx
│ │ │ ├── docker-compose.mdx
│ │ │ ├── external-services.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── oauth-setup.mdx
│ │ │ └── single-machine.mdx
│ │ └── tutorials/
│ │ ├── figma-to-onlook.mdx
│ │ └── importing-templates.mdx
│ ├── eslint.config.js
│ ├── next-sitemap.config.js
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public/
│ │ ├── sitemap-0.xml
│ │ └── sitemap.xml
│ ├── source.config.ts
│ ├── src/
│ │ ├── app/
│ │ │ ├── [[...slug]]/
│ │ │ │ ├── edit-button.tsx
│ │ │ │ ├── edit-gh.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── api/
│ │ │ │ └── search/
│ │ │ │ └── route.ts
│ │ │ ├── global.css
│ │ │ ├── layout.config.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── not-found.tsx
│ │ │ └── robots.txt/
│ │ │ └── route.ts
│ │ ├── components/
│ │ │ ├── card.tsx
│ │ │ ├── cards.tsx
│ │ │ └── rb2b-loader.tsx
│ │ ├── lib/
│ │ │ └── source.ts
│ │ └── mdx-components.tsx
│ └── tsconfig.json
├── eslint.config.js
├── package.json
├── packages/
│ ├── ai/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agents/
│ │ │ │ ├── index.ts
│ │ │ │ ├── root.ts
│ │ │ │ └── tool-lookup.ts
│ │ │ ├── apply/
│ │ │ │ ├── client.ts
│ │ │ │ └── index.ts
│ │ │ ├── chat/
│ │ │ │ ├── index.ts
│ │ │ │ └── providers.ts
│ │ │ ├── contexts/
│ │ │ │ ├── classes/
│ │ │ │ │ ├── agent-rule.ts
│ │ │ │ │ ├── branch.ts
│ │ │ │ │ ├── error.ts
│ │ │ │ │ ├── file.ts
│ │ │ │ │ ├── highlight.ts
│ │ │ │ │ ├── image.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── models/
│ │ │ │ ├── base.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── prompt/
│ │ │ │ ├── constants/
│ │ │ │ │ ├── ask.ts
│ │ │ │ │ ├── base.ts
│ │ │ │ │ ├── create.ts
│ │ │ │ │ ├── format.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── onlook.ts
│ │ │ │ │ ├── shell.ts
│ │ │ │ │ ├── signatures.ts
│ │ │ │ │ ├── suggest.ts
│ │ │ │ │ ├── summary.ts
│ │ │ │ │ └── system.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── provider.ts
│ │ │ ├── stream/
│ │ │ │ ├── converter.ts
│ │ │ │ └── index.ts
│ │ │ ├── tokens/
│ │ │ │ └── index.ts
│ │ │ └── tools/
│ │ │ ├── classes/
│ │ │ │ ├── bash-edit.ts
│ │ │ │ ├── bash-read.ts
│ │ │ │ ├── check-errors.ts
│ │ │ │ ├── fuzzy-edit-file.ts
│ │ │ │ ├── glob.ts
│ │ │ │ ├── grep.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── list-branches.ts
│ │ │ │ ├── list-files.ts
│ │ │ │ ├── onlook-instructions.ts
│ │ │ │ ├── read-file.ts
│ │ │ │ ├── read-style-guide.ts
│ │ │ │ ├── sandbox.ts
│ │ │ │ ├── scrape-url.ts
│ │ │ │ ├── search-replace-edit.ts
│ │ │ │ ├── search-replace-multi-edit.ts
│ │ │ │ ├── terminal-command.ts
│ │ │ │ ├── typecheck.ts
│ │ │ │ ├── upload-image.ts
│ │ │ │ ├── web-search.ts
│ │ │ │ └── write-file.ts
│ │ │ ├── index.ts
│ │ │ ├── models/
│ │ │ │ ├── base.ts
│ │ │ │ ├── client.ts
│ │ │ │ └── index.ts
│ │ │ ├── shared/
│ │ │ │ ├── helpers/
│ │ │ │ │ ├── cli.ts
│ │ │ │ │ └── files.ts
│ │ │ │ └── type.ts
│ │ │ └── toolset.ts
│ │ ├── test/
│ │ │ ├── apply.test.ts
│ │ │ ├── contexts/
│ │ │ │ ├── agent-rule-context.test.ts
│ │ │ │ ├── branch-context.test.ts
│ │ │ │ ├── error-context.test.ts
│ │ │ │ ├── file-context.test.ts
│ │ │ │ ├── highlight-context.test.ts
│ │ │ │ ├── image-context.test.ts
│ │ │ │ └── index.test.ts
│ │ │ ├── prompt/
│ │ │ │ ├── data/
│ │ │ │ │ ├── create-page-system.txt
│ │ │ │ │ ├── examples.txt
│ │ │ │ │ ├── file.txt
│ │ │ │ │ ├── highlights.txt
│ │ │ │ │ ├── summary.txt
│ │ │ │ │ ├── system.txt
│ │ │ │ │ ├── user-empty.txt
│ │ │ │ │ └── user.txt
│ │ │ │ └── prompt.test.ts
│ │ │ ├── stream/
│ │ │ │ └── convert.test.ts
│ │ │ ├── tokens.test.ts
│ │ │ └── tools/
│ │ │ ├── edit.test.ts
│ │ │ ├── helpers.test.ts
│ │ │ └── read.test.ts
│ │ └── tsconfig.json
│ ├── code-provider/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── providers/
│ │ │ │ ├── codesandbox/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── utils/
│ │ │ │ │ ├── list-files.ts
│ │ │ │ │ ├── read-file.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ ├── utils.ts
│ │ │ │ │ └── write-file.ts
│ │ │ │ └── nodefs/
│ │ │ │ └── index.ts
│ │ │ ├── providers.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── constants/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── colors.ts
│ │ │ ├── contact.ts
│ │ │ ├── csb.ts
│ │ │ ├── dom.ts
│ │ │ ├── editor.ts
│ │ │ ├── files.ts
│ │ │ ├── frame.ts
│ │ │ ├── freestyle.ts
│ │ │ ├── index.ts
│ │ │ ├── language.ts
│ │ │ ├── links.ts
│ │ │ ├── storage.ts
│ │ │ ├── style.ts
│ │ │ └── tags.ts
│ │ └── tsconfig.json
│ ├── db/
│ │ ├── drizzle.config.ts
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── client.ts
│ │ │ ├── defaults/
│ │ │ │ ├── branch.ts
│ │ │ │ ├── canvas.ts
│ │ │ │ ├── conversation.ts
│ │ │ │ ├── frame.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project-settings.ts
│ │ │ │ ├── project.ts
│ │ │ │ ├── user-canvas.ts
│ │ │ │ └── user-settings.ts
│ │ │ ├── index.ts
│ │ │ ├── mappers/
│ │ │ │ ├── chat/
│ │ │ │ │ ├── conversation.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── message.ts
│ │ │ │ ├── domain.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project/
│ │ │ │ │ ├── branch.ts
│ │ │ │ │ ├── canvas.ts
│ │ │ │ │ ├── frame.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── project.ts
│ │ │ │ │ └── settings.ts
│ │ │ │ ├── subscription.ts
│ │ │ │ └── user/
│ │ │ │ ├── index.ts
│ │ │ │ ├── settings.ts
│ │ │ │ └── user.ts
│ │ │ ├── migration-scripts/
│ │ │ │ ├── README.md
│ │ │ │ └── migrate-to-branching.ts
│ │ │ ├── schema/
│ │ │ │ ├── canvas/
│ │ │ │ │ ├── canvas.ts
│ │ │ │ │ ├── frame.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── chat/
│ │ │ │ │ ├── conversation.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── message.ts
│ │ │ │ ├── domain/
│ │ │ │ │ ├── custom/
│ │ │ │ │ │ ├── domain.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── project-custom-domain.ts
│ │ │ │ │ │ └── verification.ts
│ │ │ │ │ ├── deployment.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── preview.ts
│ │ │ │ ├── feedback/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project/
│ │ │ │ │ ├── branch.ts
│ │ │ │ │ ├── create.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── invitation.ts
│ │ │ │ │ ├── project.ts
│ │ │ │ │ └── settings.ts
│ │ │ │ ├── subscription/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── legacy.ts
│ │ │ │ │ ├── price.ts
│ │ │ │ │ ├── product.ts
│ │ │ │ │ ├── rate-limits.ts
│ │ │ │ │ ├── subscription.ts
│ │ │ │ │ └── usage.ts
│ │ │ │ ├── supabase/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── user.ts
│ │ │ │ └── user/
│ │ │ │ ├── index.ts
│ │ │ │ ├── settings.ts
│ │ │ │ ├── user-canvas.ts
│ │ │ │ ├── user-project.ts
│ │ │ │ └── user.ts
│ │ │ └── seed/
│ │ │ ├── constants.ts
│ │ │ ├── db.ts
│ │ │ ├── reset.ts
│ │ │ ├── seed.ts
│ │ │ ├── stripe/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── backfill-subscriptions.ts
│ │ │ │ ├── legacy-subscription.ts
│ │ │ │ └── stripe.ts
│ │ │ └── supabase.ts
│ │ └── tsconfig.json
│ ├── email/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── client.ts
│ │ │ ├── index.ts
│ │ │ ├── invitation.ts
│ │ │ ├── templates/
│ │ │ │ ├── index.ts
│ │ │ │ └── invite-user.tsx
│ │ │ └── types/
│ │ │ └── send-email.ts
│ │ └── tsconfig.json
│ ├── file-system/
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── code-fs.ts
│ │ │ ├── config.ts
│ │ │ ├── fs.ts
│ │ │ ├── hooks/
│ │ │ │ ├── index.ts
│ │ │ │ ├── use-dir.ts
│ │ │ │ ├── use-file.ts
│ │ │ │ └── use-fs.tsx
│ │ │ ├── index-cache.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── fonts/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── default.ts
│ │ │ ├── family.ts
│ │ │ ├── helpers/
│ │ │ │ ├── ast-generators.ts
│ │ │ │ ├── ast-manipulators.ts
│ │ │ │ ├── class-utils.ts
│ │ │ │ ├── font-extractors.ts
│ │ │ │ ├── import-export-manager.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── validators.ts
│ │ │ ├── index.ts
│ │ │ ├── utils.ts
│ │ │ └── variants.ts
│ │ ├── test/
│ │ │ ├── ast-generators.test.ts
│ │ │ ├── ast-manipulators.test.ts
│ │ │ ├── class-utils.test.ts
│ │ │ ├── data/
│ │ │ │ ├── ast-manipulators/
│ │ │ │ │ ├── add-font-to-tailwind-theme/
│ │ │ │ │ │ ├── existing-fontfamily/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── font-already-exists/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── new-fontfamily/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── add-google-font-specifier/
│ │ │ │ │ │ ├── existing-import/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── no-import/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── merge-local-font-sources/
│ │ │ │ │ │ ├── array-to-array/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── empty-array/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── no-src-property/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── single-to-array/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── remove-font-declaration/
│ │ │ │ │ │ ├── google-font/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── last-google-font/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── local-font/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── multiple-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── remove-font-from-tailwind-theme/
│ │ │ │ │ ├── multiple-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── non-existent-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── single-font/
│ │ │ │ │ ├── config.json
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── create-font-src-objects/
│ │ │ │ │ ├── basic-sources/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── multiple-formats/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ └── optional-properties/
│ │ │ │ │ ├── config.json
│ │ │ │ │ └── expected.ts
│ │ │ │ ├── create-local-font-config/
│ │ │ │ │ ├── basic-local-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ └── complex-font-name/
│ │ │ │ │ ├── config.json
│ │ │ │ │ └── expected.ts
│ │ │ │ ├── create-template-literal-with-font/
│ │ │ │ │ ├── conditional-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── empty-string/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── function-call-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── identifier-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── member-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── string-literal/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── font-extractors/
│ │ │ │ │ ├── migrate-fonts-from-layout/
│ │ │ │ │ │ ├── complex-layout/
│ │ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── layout-with-classnames/
│ │ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── simple-layout/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── parse-font-declarations/
│ │ │ │ │ ├── google-fonts/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── local-fonts/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── mixed-fonts/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── no-fonts/
│ │ │ │ │ ├── expected.json
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── generate-font-variable-export/
│ │ │ │ │ ├── basic-google-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── local-font-type/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── missing-optional-props/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── multiple-weights-styles/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ └── special-characters/
│ │ │ │ │ ├── config.json
│ │ │ │ │ └── expected.ts
│ │ │ │ ├── remove-fonts-classname/
│ │ │ │ │ ├── font-weight-preservation/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── member-expression-remove-all/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── member-expression-remove-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-empty/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-no-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-remove-all/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-specific-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-complex-expressions/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-multiple-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-remove-all/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-specific-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── template-literal-static-only/
│ │ │ │ │ ├── config.json
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── update-classname-with-font-var/
│ │ │ │ │ ├── jsx-expression-classname/
│ │ │ │ │ │ ├── already-has-font/
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── identifier-expression/
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── template-literal-existing/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── string-literal-classname/
│ │ │ │ │ ├── empty-string/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── with-existing-classes/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── with-font-classes/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ └── update-template-literal-with-font-class/
│ │ │ │ ├── complex-template/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── empty-template/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── font-weight-preservation/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── multiple-expressions/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── multiple-font-classes/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── replace-existing-font/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── with-existing-classes/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ └── with-leading-space/
│ │ │ │ ├── expected.tsx
│ │ │ │ └── input.tsx
│ │ │ ├── font-extractors.test.ts
│ │ │ ├── import-export-manager.test.ts
│ │ │ ├── test-utils.ts
│ │ │ └── validators.test.ts
│ │ └── tsconfig.json
│ ├── git/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── git.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── github/
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── auth.ts
│ │ │ ├── config.ts
│ │ │ ├── index.ts
│ │ │ ├── installation.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── growth/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── helpers.ts
│ │ │ ├── index.ts
│ │ │ ├── inject.ts
│ │ │ ├── remove.ts
│ │ │ └── script.ts
│ │ ├── tests/
│ │ │ └── inject.test.ts
│ │ └── tsconfig.json
│ ├── image-server/
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── compress.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── test/
│ │ │ └── image.test.ts
│ │ └── tsconfig.json
│ ├── models/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── actions/
│ │ │ │ ├── action.ts
│ │ │ │ ├── code.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── location.ts
│ │ │ │ └── target.ts
│ │ │ ├── assets/
│ │ │ │ └── index.ts
│ │ │ ├── auth/
│ │ │ │ └── index.ts
│ │ │ ├── chat/
│ │ │ │ ├── conversation/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── message/
│ │ │ │ │ ├── checkpoint.ts
│ │ │ │ │ ├── code.ts
│ │ │ │ │ ├── context.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── message.ts
│ │ │ │ │ └── queue.ts
│ │ │ │ ├── request.ts
│ │ │ │ ├── response.ts
│ │ │ │ ├── suggestion.ts
│ │ │ │ ├── summary.ts
│ │ │ │ └── type.ts
│ │ │ ├── code/
│ │ │ │ └── index.ts
│ │ │ ├── create/
│ │ │ │ └── index.ts
│ │ │ ├── domain/
│ │ │ │ └── index.ts
│ │ │ ├── editor/
│ │ │ │ └── index.ts
│ │ │ ├── element/
│ │ │ │ ├── classes.ts
│ │ │ │ ├── element.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── layers.ts
│ │ │ │ ├── props.ts
│ │ │ │ └── templateNode.ts
│ │ │ ├── font/
│ │ │ │ └── index.ts
│ │ │ ├── hosting/
│ │ │ │ └── index.ts
│ │ │ ├── ide/
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── llm/
│ │ │ │ └── index.ts
│ │ │ ├── next/
│ │ │ │ └── index.ts
│ │ │ ├── pages/
│ │ │ │ ├── index.ts
│ │ │ │ └── opengraph.ts
│ │ │ ├── project/
│ │ │ │ ├── branch.ts
│ │ │ │ ├── canvas.ts
│ │ │ │ ├── command.ts
│ │ │ │ ├── create.ts
│ │ │ │ ├── frame.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project.ts
│ │ │ │ ├── rect.ts
│ │ │ │ ├── role.ts
│ │ │ │ └── settings.ts
│ │ │ ├── run/
│ │ │ │ └── index.ts
│ │ │ ├── sandbox/
│ │ │ │ ├── files.ts
│ │ │ │ ├── folder.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── template.ts
│ │ │ ├── style/
│ │ │ │ └── index.ts
│ │ │ ├── supabase/
│ │ │ │ └── db.ts
│ │ │ ├── tools/
│ │ │ │ └── index.ts
│ │ │ ├── usage/
│ │ │ │ └── index.ts
│ │ │ └── user/
│ │ │ ├── index.ts
│ │ │ ├── settings.ts
│ │ │ └── user.ts
│ │ └── tsconfig.json
│ ├── parser/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── code-edit/
│ │ │ │ ├── group.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── image.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── insert.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── move.ts
│ │ │ │ ├── next-config.ts
│ │ │ │ ├── remove.ts
│ │ │ │ ├── style.ts
│ │ │ │ ├── text.ts
│ │ │ │ └── transform.ts
│ │ │ ├── helpers.ts
│ │ │ ├── ids.ts
│ │ │ ├── index.ts
│ │ │ ├── packages.ts
│ │ │ ├── parse.ts
│ │ │ ├── prettier/
│ │ │ │ └── index.ts
│ │ │ └── template-node/
│ │ │ ├── helpers.ts
│ │ │ ├── index.ts
│ │ │ └── map.ts
│ │ ├── test/
│ │ │ ├── data/
│ │ │ │ ├── ids/
│ │ │ │ │ ├── adds-ids-to-jsx/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── does-not-add-ids-if-exist/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── layout/
│ │ │ │ │ ├── adds-script-if-missing/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── creates-body/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── does-not-duplicate/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── handles-self-closing-body/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── handles-self-closing-html-head/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── injects-at-bottom/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── injects-in-first-body/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── injects-with-existing-head-script/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── preserves-body-props/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── removes-deprecated-script/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── removes-deprecated-script-multiple/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── wraps-conditional-ternary/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── wraps-fragment-only/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── wraps-plain-children/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── next-config/
│ │ │ │ │ ├── add-basic-js/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── add-basic-mjs/
│ │ │ │ │ │ ├── expected.mjs
│ │ │ │ │ │ └── input.mjs
│ │ │ │ │ ├── add-basic-ts/
│ │ │ │ │ │ ├── expected.ts
│ │ │ │ │ │ └── input.ts
│ │ │ │ │ ├── alternative-name-config/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── complex-nested-objects/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── direct-return-from-function/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── empty-config/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── exported-as-function/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── iife-wrapped-config/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── merge-typescript-props/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── no-duplicate-props/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── with-mdx/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── with-mdx-alt-name-order/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── with-mdx-alt-order/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ └── with-plugin/
│ │ │ │ │ ├── expected.js
│ │ │ │ │ └── input.js
│ │ │ │ └── parse/
│ │ │ │ └── simple/
│ │ │ │ ├── expected.js
│ │ │ │ └── input.js
│ │ │ ├── helpers.test.ts
│ │ │ ├── ids.test.ts
│ │ │ ├── layout.test.ts
│ │ │ ├── next-config.test.ts
│ │ │ ├── parse.test.ts
│ │ │ ├── preload.test.ts
│ │ │ └── template.test.ts
│ │ └── tsconfig.json
│ ├── penpal/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── child.ts
│ │ │ ├── index.ts
│ │ │ └── parent.ts
│ │ └── tsconfig.json
│ ├── rpc/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ └── trpc/
│ │ │ ├── config.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── scripts/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── api-keys.ts
│ │ │ ├── backend.ts
│ │ │ ├── helpers.ts
│ │ │ └── index.ts
│ │ ├── test/
│ │ │ ├── comprehensive.test.ts
│ │ │ ├── integration.test.ts
│ │ │ └── simple.test.ts
│ │ └── tsconfig.json
│ ├── stripe/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── client.ts
│ │ │ ├── constants.ts
│ │ │ ├── functions.ts
│ │ │ ├── index.ts
│ │ │ ├── scripts/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── customer.ts
│ │ │ │ │ ├── product.ts
│ │ │ │ │ ├── reset.ts
│ │ │ │ │ └── setup.ts
│ │ │ │ └── production/
│ │ │ │ ├── coupon.ts
│ │ │ │ └── product-price.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── types/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── adapters/
│ │ │ │ ├── index.ts
│ │ │ │ └── props.ts
│ │ │ ├── design-tokens/
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── ui/
│ │ ├── README.md
│ │ ├── components.json
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── postcss.config.js
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── accordion.tsx
│ │ │ │ ├── ai-elements/
│ │ │ │ │ ├── code-block.tsx
│ │ │ │ │ ├── context.tsx
│ │ │ │ │ ├── conversation.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── reasoning.tsx
│ │ │ │ │ ├── response.tsx
│ │ │ │ │ ├── tool.tsx
│ │ │ │ │ └── web-preview.tsx
│ │ │ │ ├── alert-dialog.tsx
│ │ │ │ ├── alert.tsx
│ │ │ │ ├── aspect-ratio.tsx
│ │ │ │ ├── avatar.tsx
│ │ │ │ ├── badge.tsx
│ │ │ │ ├── breadcrumb.tsx
│ │ │ │ ├── button.tsx
│ │ │ │ ├── calendar.tsx
│ │ │ │ ├── card.tsx
│ │ │ │ ├── chart.tsx
│ │ │ │ ├── checkbox.tsx
│ │ │ │ ├── collapsible.tsx
│ │ │ │ ├── color-picker/
│ │ │ │ │ ├── ColorPicker.tsx
│ │ │ │ │ ├── ColorSlider.tsx
│ │ │ │ │ ├── EyeDropperButton.tsx
│ │ │ │ │ ├── Gradient.tsx
│ │ │ │ │ ├── SVPicker.tsx
│ │ │ │ │ ├── checkPattern.ts
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── command.tsx
│ │ │ │ ├── context-menu.tsx
│ │ │ │ ├── dialog.tsx
│ │ │ │ ├── draftable-input.tsx
│ │ │ │ ├── drawer.tsx
│ │ │ │ ├── dropdown-menu.tsx
│ │ │ │ ├── form.tsx
│ │ │ │ ├── hotkey-label.tsx
│ │ │ │ ├── hover-card.tsx
│ │ │ │ ├── icons/
│ │ │ │ │ ├── header-level-icons/
│ │ │ │ │ │ ├── h1Icon.tsx
│ │ │ │ │ │ ├── h2Icon.tsx
│ │ │ │ │ │ ├── h3Icon.tsx
│ │ │ │ │ │ ├── h4Icon.tsx
│ │ │ │ │ │ ├── h5Icon.tsx
│ │ │ │ │ │ └── h6Icon.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── input-group.tsx
│ │ │ │ ├── input-otp.tsx
│ │ │ │ ├── input.tsx
│ │ │ │ ├── kbd.tsx
│ │ │ │ ├── label.tsx
│ │ │ │ ├── menubar.tsx
│ │ │ │ ├── motion-card.tsx
│ │ │ │ ├── navigation-menu.tsx
│ │ │ │ ├── node-icon.tsx
│ │ │ │ ├── pagination.tsx
│ │ │ │ ├── popover.tsx
│ │ │ │ ├── progress-with-interval.tsx
│ │ │ │ ├── progress.tsx
│ │ │ │ ├── radio-group.tsx
│ │ │ │ ├── resizable.tsx
│ │ │ │ ├── scroll-area.tsx
│ │ │ │ ├── select.tsx
│ │ │ │ ├── separator.tsx
│ │ │ │ ├── sheet.tsx
│ │ │ │ ├── shine-border.tsx
│ │ │ │ ├── sidebar.tsx
│ │ │ │ ├── skeleton.tsx
│ │ │ │ ├── slider.tsx
│ │ │ │ ├── sonner.tsx
│ │ │ │ ├── switch.tsx
│ │ │ │ ├── table.tsx
│ │ │ │ ├── tabs.tsx
│ │ │ │ ├── textarea.tsx
│ │ │ │ ├── toggle-group.tsx
│ │ │ │ ├── toggle.tsx
│ │ │ │ └── tooltip.tsx
│ │ │ ├── globals.css
│ │ │ ├── hooks/
│ │ │ │ ├── index.ts
│ │ │ │ ├── use-enter-submit.ts
│ │ │ │ ├── use-media-query.ts
│ │ │ │ ├── use-mobile.ts
│ │ │ │ ├── use-pointer-stroke.tsx
│ │ │ │ ├── use-reduced-motion.ts
│ │ │ │ └── use-resize-observer.ts
│ │ │ ├── index.ts
│ │ │ └── utils/
│ │ │ ├── cn.ts
│ │ │ ├── index.ts
│ │ │ └── truncate.ts
│ │ ├── tailwind.config.ts
│ │ ├── test/
│ │ │ └── Gradient.test.ts
│ │ ├── tokens.ts
│ │ └── tsconfig.json
│ └── utility/
│ ├── eslint.config.js
│ ├── package.json
│ ├── src/
│ │ ├── assert.ts
│ │ ├── autolayout.ts
│ │ ├── clone.ts
│ │ ├── color.ts
│ │ ├── domain.test.ts
│ │ ├── domain.ts
│ │ ├── email.ts
│ │ ├── errors.ts
│ │ ├── file.ts
│ │ ├── folder.ts
│ │ ├── font.ts
│ │ ├── frame.ts
│ │ ├── id.ts
│ │ ├── image.ts
│ │ ├── index.ts
│ │ ├── initials.ts
│ │ ├── math.ts
│ │ ├── name.ts
│ │ ├── null.ts
│ │ ├── path.ts
│ │ ├── screenshot.ts
│ │ ├── string.ts
│ │ ├── tailwind.ts
│ │ ├── time.ts
│ │ ├── tw-merge.ts
│ │ ├── unit.ts
│ │ ├── urls.ts
│ │ └── window-metadata.ts
│ ├── test/
│ │ ├── colors.test.ts
│ │ ├── domain.test.ts
│ │ ├── errors.test.ts
│ │ ├── file.test.ts
│ │ ├── frame.ts
│ │ ├── id.test.ts
│ │ ├── image.test.ts
│ │ ├── name.test.ts
│ │ ├── path.test.ts
│ │ ├── tailwind.test.ts
│ │ ├── tw-merge.test.ts
│ │ └── urls.test.ts
│ └── tsconfig.json
└── tooling/
├── eslint/
│ ├── base.js
│ ├── nextjs.js
│ ├── package.json
│ ├── react.js
│ └── tsconfig.json
├── prettier/
│ ├── index.js
│ ├── package.json
│ └── tsconfig.json
└── typescript/
├── base.json
├── next-react.json
├── package.json
├── react-library.json
└── vite-react.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
node_modules
.git
.gitignore
README.md
.env
.env.local
.env.*.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.next
.vercel
*.tsbuildinfo
.DS_Store
coverage
.nyc_output
dist
build
.vscode
.idea
*.log
.next
# Parts of the app that does not need to be deployed
apps/web/backend
assets
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: 🐞 Bug report
about: Create a report to help us improve
title: "[bug] the title of bug report"
labels: bug
assignees: ''
---
#### Describe the bug
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: ✨ Feature request
about: Create a feature request
title: "[feat] the title of the request"
labels: enhancement
assignees: ''
---
#### Describe the feature
================================================
FILE: .github/ISSUE_TEMPLATE/help_wanted.md
================================================
---
name: 🥺 Help wanted
about: Confuse about the use of Onlook
title: "[Help] the title of help wanted report"
labels: help wanted
assignees: ''
---
#### Describe the problem you confuse
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"
================================================
FILE: .github/pull_request_template.md
================================================
## Description
<!-- Provide a clear and concise description of your changes -->
## Related Issues
<!-- Link any related issues using GitHub keywords (e.g., "closes #123", "fixes #456", "related to #789") -->
## Type of Change
<!-- Put an `x` in the boxes that apply -->
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation
- [ ] Refactor
- [ ] Other (please describe):
## Testing
<!-- Describe the tests you ran or the steps to verify your changes -->
## Screenshots (if applicable)
<!-- Add screenshots to help explain your changes -->
## Additional Notes
<!-- Add any other context about the PR here -->
================================================
FILE: .github/workflows/chromatic.yml
================================================
name: Chromatic
on: push
jobs:
chromatic:
name: Run Chromatic
runs-on: ubuntu-latest
env:
SKIP_ENV_VALIDATION: true
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.1
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Run Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
workingDir: apps/web/client
buildScriptName: build-storybook
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
# TODO: Enable lint job after applying lint fixes and setting appropriate warning limits
# Will be handled in follow-up PR to avoid blocking CI setup / bloating this PR
# lint:
# name: Lint
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: oven-sh/setup-bun@v1
# with:
# bun-version: 1.3.1
# - name: Cache dependencies
# uses: actions/cache@v4
# with:
# path: |
# ~/.bun/install/cache
# key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
# - name: Install dependencies
# run: bun install --frozen
# - name: Run linter
# run: bun lint
typecheck:
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
with:
bun-version: 1.3.1
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
- name: Install dependencies
run: bun install --frozen
- name: Run type checking
run: bun typecheck
test:
name: Unit Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
with:
bun-version: 1.3.1
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
- name: Install dependencies
run: bun install --frozen
- name: Run tests
run: bun test --timeout 30000 --coverage
================================================
FILE: .github/workflows/supabase-push-staging.yml
================================================
name: Push Supabase Drizzle Schema to Staging Environment
on:
workflow_dispatch:
jobs:
migrate:
runs-on: ubuntu-latest
env:
SUPABASE_DATABASE_URL: ${{ secrets.STAGING_SUPABASE_DATABASE_URL }}
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Run migrations
run: bun run db:push
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
dist-electron
release
*.local
# Editor directories and files
.vscode/.debug.env
.vscode/settings.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
#lockfile
package-lock.json
pnpm-lock.yaml
yarn.lock
/test-results/
/playwright-report/
/playwright/.cache/
# Env variables
.env
.env.production
.env.development
.env.test
.env.local
.env.development.local
.env.test.local
.env.production.local
mise.toml
# Temporary files
.tmp/
================================================
FILE: .gitmodules
================================================
[submodule "apps/admin"]
path = apps/admin
url = https://github.com/onlook-dev/admin.git
================================================
FILE: .prettierignore
================================================
dist-electron
dist
node_modules
release
demos
test/data
================================================
FILE: .vscode/.debug.script.mjs
================================================
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { createRequire } from 'node:module'
import { spawn } from 'node:child_process'
const pkg = createRequire(import.meta.url)('../apps/studio/package.json')
const __dirname = path.dirname(fileURLToPath(import.meta.url))
// write .debug.env
const envContent = Object.entries(pkg.debug.env).map(([key, val]) => `${key}=${val}`)
fs.writeFileSync(path.join(__dirname, '.debug.env'), envContent.join('\n'))
// bootstrap
spawn(
process.platform === 'win32' ? 'npm.cmd' : 'npm',
['run', 'dev'],
{
stdio: 'inherit',
env: Object.assign(process.env, { VSCODE_DEBUG: 'true' }),
},
)
================================================
FILE: .vscode/extensions.json
================================================
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": ["mrmlnc.vscode-json5", "dbaeumer.vscode-eslint"]
}
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"compounds": [
{
"name": "Debug App",
"preLaunchTask": "Before Debug",
"configurations": [
"Debug Main Process",
"Debug Renderer Process"
],
"presentation": {
"hidden": false,
"group": "",
"order": 1
},
"stopAll": true
}
],
"configurations": [
{
"name": "Debug Main Process",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
},
"runtimeArgs": [
"--no-sandbox",
"--remote-debugging-port=9229",
"."
],
"envFile": "${workspaceFolder}/.vscode/.debug.env",
"console": "integratedTerminal"
},
{
"name": "Debug Renderer Process",
"port": 9229,
"request": "attach",
"type": "chrome",
"timeout": 60000,
"skipFiles": [
"<node_internals>/**",
"${workspaceRoot}/node_modules/**",
"${workspaceRoot}/dist-electron/**",
// Skip files in host(VITE_DEV_SERVER_URL)
"http://127.0.0.1:7777/**"
]
},
]
}
================================================
FILE: .vscode/tasks.json
================================================
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Before Debug",
"type": "shell",
"command": "node .vscode/.debug.script.mjs",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"fileLocation": "relative",
"pattern": {
"regexp": "^([a-zA-Z]\\:\/?([\\w\\-]\/?)+\\.\\w+):(\\d+):(\\d+): (ERROR|WARNING)\\: (.*)$",
"file": 1,
"line": 3,
"column": 4,
"code": 5,
"message": 6
},
"background": {
"activeOnStart": true,
"beginsPattern": "^.*VITE v.* ready in \\d* ms.*$",
"endsPattern": "^.*\\[startup\\] Electron App.*$"
}
}
}
]
}
================================================
FILE: AGENTS.md
================================================
## Onlook Agents Guide
Actionable rules for repo agents—keep diffs minimal, safe, token‑efficient.
### Purpose & Scope
- Audience: automated coding agents working within this repository.
- Goal: small, correct diffs aligned with the project’s architecture.
- Non-goals: editing generated artifacts, lockfiles, or `node_modules`.
### Repo Map
- Monorepo managed by Bun workspaces (see root `package.json`).
- App: `apps/web/client` (Next.js App Router + TailwindCSS).
- API routes: `apps/web/client/src/server/api/routers/*`, aggregated in
`apps/web/client/src/server/api/root.ts`.
- Shared utilities: `packages/*` (e.g., `packages/utility`).
### Stack & Runtimes
- UI: Next.js App Router, TailwindCSS.
- API: tRPC + Zod (`apps/web/client/src/server/api/*`).
- Package manager: Bun only — use Bun for all installs and scripts; do not use
npm, yarn, or pnpm.
### Agent Priorities
- Correctness first: minimal scope and targeted edits.
- Respect client/server boundaries in App Router.
- Prefer local patterns and existing abstractions; avoid one-off frameworks.
- Do not modify build outputs, generated files, or lockfiles.
- Use Bun for all scripts; do not introduce npm/yarn.
- Avoid running the local dev server in automation contexts.
- Respect type safety and
### Next.js App Router
- Default to Server Components. Add `use client` when using events,
state/effects, browser APIs, or client-only libs.
- App structure: `apps/web/client/src/app/**` (`page.tsx`, `layout.tsx`,
`route.ts`).
- Client providers live behind a client boundary (e.g.,
`apps/web/client/src/trpc/react.tsx`).
- Example roots: `apps/web/client/src/app/layout.tsx` (RSC shell, providers
wired, scripts gated by env).
- Components using `mobx-react-lite`'s `observer` must be client components
(include `use client`).
### tRPC API
- Routers live in `apps/web/client/src/server/api/routers/**` and must be
exported from `apps/web/client/src/server/api/root.ts`.
- Use `publicProcedure`/`protectedProcedure` from
`apps/web/client/src/server/api/trpc.ts`; validate inputs with Zod.
- Serialization handled by SuperJSON; return plain objects/arrays.
- Client usage via `apps/web/client/src/trpc/react.tsx` (React Query + tRPC
links).
### Auth & Supabase
- Server-side client: `apps/web/client/src/utils/supabase/server.ts` (uses Next
headers/cookies). Use in server components, actions, and routes.
- Browser client: `apps/web/client/src/utils/supabase/client/index.ts` for
client components.
- Never pass server-only clients into client code.
### Env & Config
- Define/validate env vars in `apps/web/client/src/env.ts` via
`@t3-oss/env-nextjs`.
- Expose browser vars with `NEXT_PUBLIC_*` and declare in the `client` schema.
- Prefer `env` from `@/env`. In server-only helpers (e.g., base URL in
`src/trpc/helpers.ts`), read `process.env` only for deployment vars like
`VERCEL_URL`/`PORT`. Never use `process.env` in client code; in shared
modules, guard with `typeof window === 'undefined'`.
- Import `./src/env` in `apps/web/client/next.config.ts` to enforce validation.
### Imports & Paths
- Use path aliases: `@/*` and `~/*` map to `apps/web/client/src/*` (see
`apps/web/client/tsconfig.json`).
- Do not import server-only modules into client components. Limited exception:
editor modules that already use `path`; reuse only there. Never import
`process` in client code.
- Split code by environment if needed (server file vs client file).
### MobX + React Stores
- Create store instances with `useState(() => new Store())` for stability across
renders.
- Keep active store in `useRef`; clean up async with
`setTimeout(() => storeRef.current?.clear(), 0)` to avoid route-change races.
- Avoid `useMemo` for store instances; React may drop memoized values leading to
data loss.
- Avoid putting the store instance in effect deps if it loops; split concerns
(e.g., project vs branch).
- `observer` components are client-only. Place one client boundary at the
feature entry; child observers need not include `use client` (e.g.,
`apps/web/client/src/app/project/[id]/_components/main.tsx`).
- Example store: `apps/web/client/src/components/store/editor/engine.ts:1` (uses
`makeAutoObservable`).
### Styling & UI
- TailwindCSS-first styling; global styles are already imported in
`apps/web/client/src/app/layout.tsx`.
- Prefer existing UI components from `@onlook/ui` and local patterns.
- Preserve dark theme defaults via `ThemeProvider` usage in layout.
### Internationalization
- `next-intl` is configured; provider lives in
`apps/web/client/src/app/layout.tsx`.
- Strings live in `apps/web/client/messages/*`. Add/modify keys there; avoid
hardcoded user-facing text.
- Keep keys stable; prefer additions over breaking renames.
### Common Pitfalls
- Missing `use client` where needed (events/browser APIs) causes unbound events;
a single boundary at the feature root is sufficient.
- New tRPC routers not exported in `src/server/api/root.ts` (endpoints
unreachable).
- Env vars not typed/exposed in `src/env.ts` cause runtime/edge failures. Prefer
`env`; avoid new `process.env` reads in client code.
- Importing server-only code into client components (bundling/runtime errors).
Note: `path` is already used in specific client code-editor modules; avoid
expanding Node API usage beyond those areas.
- Bypassing i18n by hardcoding strings instead of using message files/hooks.
- Avoid `useMemo` to create MobX stores (risk of lost references); avoid
synchronous cleanup on route change (race conditions).
### Context Discipline (for Agents)
- Search narrowly with ripgrep; open only files you need.
- Read small sections; avoid `node_modules`, `.next`, large assets.
- Propose minimal diffs aligned with existing conventions; avoid wide refactors.
### Notes
- Unit tests can be run with `bun test`
- Run type checking with `bun run typecheck`
- Apply database updates to local dev with `bun run db:push`
- Refrain from running the dev server
- DO NOT run `db:gen`. This is reserved for the maintainer.
- DO NOT use any type unless necessary
================================================
FILE: CLAUDE.md
================================================
## Onlook Agents Guide
Actionable rules for repo agents—keep diffs minimal, safe, token‑efficient.
### Purpose & Scope
- Audience: automated coding agents working within this repository.
- Goal: small, correct diffs aligned with the project’s architecture.
- Non-goals: editing generated artifacts, lockfiles, or `node_modules`.
### Repo Map
- Monorepo managed by Bun workspaces (see root `package.json`).
- App: `apps/web/client` (Next.js App Router + TailwindCSS).
- API routes: `apps/web/client/src/server/api/routers/*`, aggregated in
`apps/web/client/src/server/api/root.ts`.
- Shared utilities: `packages/*` (e.g., `packages/utility`).
### Stack & Runtimes
- UI: Next.js App Router, TailwindCSS.
- API: tRPC + Zod (`apps/web/client/src/server/api/*`).
- Package manager: Bun only — use Bun for all installs and scripts; do not use
npm, yarn, or pnpm.
### Agent Priorities
- Correctness first: minimal scope and targeted edits.
- Respect client/server boundaries in App Router.
- Prefer local patterns and existing abstractions; avoid one-off frameworks.
- Do not modify build outputs, generated files, or lockfiles.
- Use Bun for all scripts; do not introduce npm/yarn.
- Avoid running the local dev server in automation contexts.
- Respect type safety and
### Next.js App Router
- Default to Server Components. Add `use client` when using events,
state/effects, browser APIs, or client-only libs.
- App structure: `apps/web/client/src/app/**` (`page.tsx`, `layout.tsx`,
`route.ts`).
- Client providers live behind a client boundary (e.g.,
`apps/web/client/src/trpc/react.tsx`).
- Example roots: `apps/web/client/src/app/layout.tsx` (RSC shell, providers
wired, scripts gated by env).
- Components using `mobx-react-lite`'s `observer` must be client components
(include `use client`).
### tRPC API
- Routers live in `apps/web/client/src/server/api/routers/**` and must be
exported from `apps/web/client/src/server/api/root.ts`.
- Use `publicProcedure`/`protectedProcedure` from
`apps/web/client/src/server/api/trpc.ts`; validate inputs with Zod.
- Serialization handled by SuperJSON; return plain objects/arrays.
- Client usage via `apps/web/client/src/trpc/react.tsx` (React Query + tRPC
links).
### Auth & Supabase
- Server-side client: `apps/web/client/src/utils/supabase/server.ts` (uses Next
headers/cookies). Use in server components, actions, and routes.
- Browser client: `apps/web/client/src/utils/supabase/client/index.ts` for
client components.
- Never pass server-only clients into client code.
### Env & Config
- Define/validate env vars in `apps/web/client/src/env.ts` via
`@t3-oss/env-nextjs`.
- Expose browser vars with `NEXT_PUBLIC_*` and declare in the `client` schema.
- Prefer `env` from `@/env`. In server-only helpers (e.g., base URL in
`src/trpc/helpers.ts`), read `process.env` only for deployment vars like
`VERCEL_URL`/`PORT`. Never use `process.env` in client code; in shared
modules, guard with `typeof window === 'undefined'`.
- Import `./src/env` in `apps/web/client/next.config.ts` to enforce validation.
### Imports & Paths
- Use path aliases: `@/*` and `~/*` map to `apps/web/client/src/*` (see
`apps/web/client/tsconfig.json`).
- Do not import server-only modules into client components. Limited exception:
editor modules that already use `path`; reuse only there. Never import
`process` in client code.
- Split code by environment if needed (server file vs client file).
### MobX + React Stores
- Create store instances with `useState(() => new Store())` for stability across
renders.
- Keep active store in `useRef`; clean up async with
`setTimeout(() => storeRef.current?.clear(), 0)` to avoid route-change races.
- Avoid `useMemo` for store instances; React may drop memoized values leading to
data loss.
- Avoid putting the store instance in effect deps if it loops; split concerns
(e.g., project vs branch).
- `observer` components are client-only. Place one client boundary at the
feature entry; child observers need not include `use client` (e.g.,
`apps/web/client/src/app/project/[id]/_components/main.tsx`).
- Example store: `apps/web/client/src/components/store/editor/engine.ts:1` (uses
`makeAutoObservable`).
### Styling & UI
- TailwindCSS-first styling; global styles are already imported in
`apps/web/client/src/app/layout.tsx`.
- Prefer existing UI components from `@onlook/ui` and local patterns.
- Preserve dark theme defaults via `ThemeProvider` usage in layout.
### Internationalization
- `next-intl` is configured; provider lives in
`apps/web/client/src/app/layout.tsx`.
- Strings live in `apps/web/client/messages/*`. Add/modify keys there; avoid
hardcoded user-facing text.
- Keep keys stable; prefer additions over breaking renames.
### Common Pitfalls
- Missing `use client` where needed (events/browser APIs) causes unbound events;
a single boundary at the feature root is sufficient.
- New tRPC routers not exported in `src/server/api/root.ts` (endpoints
unreachable).
- Env vars not typed/exposed in `src/env.ts` cause runtime/edge failures. Prefer
`env`; avoid new `process.env` reads in client code.
- Importing server-only code into client components (bundling/runtime errors).
Note: `path` is already used in specific client code-editor modules; avoid
expanding Node API usage beyond those areas.
- Bypassing i18n by hardcoding strings instead of using message files/hooks.
- Avoid `useMemo` to create MobX stores (risk of lost references); avoid
synchronous cleanup on route change (race conditions).
### Context Discipline (for Agents)
- Search narrowly with ripgrep; open only files you need.
- Read small sections; avoid `node_modules`, `.next`, large assets.
- Propose minimal diffs aligned with existing conventions; avoid wide refactors.
### Notes
- Unit tests can be run with `bun test`
- Run type checking with `bun run typecheck`
- Apply database updates to local dev with `bun run db:push`
- Refrain from running the dev server
- DO NOT run `db:gen`. This is reserved for the maintainer.
- DO NOT use any type unless necessary
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement by emailing
[contact@onlook.com](mailto:contact@onlook.com).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
To keep all docs in one place, we've moved the contributing guide here:
https://docs.onlook.com/developers
### Running locally
To get set up and run Onlook locally, see here:
https://docs.onlook.com/developers/running-locally
================================================
FILE: Dockerfile
================================================
# Build Onlook web client
FROM oven/bun:1
WORKDIR /app
# Set build and production environment
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV STANDALONE_BUILD=true
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
# Copy everything (monorepo structure)
COPY . .
# Install dependencies and build
RUN bun install --frozen-lockfile
RUN cd apps/web/client && bun run build:standalone
# Expose the application port
EXPOSE 3000
# Health check to ensure the application is running
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD bun -e "fetch('http://localhost:3000').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))"
# Start the Next.js server
CMD ["bun", "apps/web/client/server.js"]
================================================
FILE: LICENSE.md
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2024 On Off, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 -->
<div align="center">
<img width="800" alt="header image" src="assets/web-preview.png">
<h3 align="center">Onlook</h3>
<p align="center">
Cursor for Designers
<br />
<a href="https://docs.onlook.com"><strong>Explore the docs »</strong></a>
<br />
</p>
<p align="center">
👨💻👩💻👨💻
<a href="https://www.ycombinator.com/companies/onlook/jobs/e4gHv1n-founding-engineer-fullstack">We're hiring engineers in SF!</a>
👩💻👨💻👩💻
</p>
<br />
<a href="https://youtu.be/RSX_3EaO5eU?feature=shared">View Demo</a>
·
<a href="https://github.com/onlook-dev/onlook/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
·
<a href="https://github.com/onlook-dev/onlook/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
</p>
<!-- PROJECT SHIELDS -->
<!--
*** I'm using markdown "reference style" links for readability.
*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
*** See the bottom of this document for the declaration of the reference variables
*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
-->
<!-- [![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![Apache License][license-shield]][license-url] -->
[![Discord][discord-shield]][discord-url]
[![LinkedIn][linkedin-shield]][linkedin-url]
[![Twitter][twitter-shield]][twitter-url]
[中文](https://www.readme-i18n.com/onlook-dev/onlook?lang=zh) |
[Español](https://www.readme-i18n.com/onlook-dev/onlook?lang=es) |
[Deutsch](https://www.readme-i18n.com/onlook-dev/onlook?lang=de) |
[français](https://www.readme-i18n.com/onlook-dev/onlook?lang=fr) |
[Português](https://www.readme-i18n.com/onlook-dev/onlook?lang=pt) |
[Русский](https://www.readme-i18n.com/onlook-dev/onlook?lang=ru) |
[日本語](https://www.readme-i18n.com/onlook-dev/onlook?lang=ja) |
[한국어](https://www.readme-i18n.com/onlook-dev/onlook?lang=ko)
</div>
# An Open-Source, Visual-First Code Editor
Craft websites, prototypes, and designs with AI in Next.js + TailwindCSS. Make
edits directly in the browser DOM with a visual editor. Design in realtime with
code. An open-source alternative to Bolt.new, Lovable, V0, Replit Agent, Figma
Make, Webflow, etc.
### 🚧 🚧 🚧 Onlook is still under development 🚧 🚧 🚧
We're actively looking for contributors to help make Onlook for Web an
incredible prompt-to-build experience. Check the
[open issues](https://github.com/onlook-dev/onlook/issues) for a full list of
proposed features (and known issues), and join our
[Discord](https://discord.gg/hERDfFZCsH) to collaborate with hundreds of other
builders.
## What you can do with Onlook:
- [x] Create Next.js app in seconds
- [x] Start from text or image
- [x] Use prebuilt templates
- [ ] Import from Figma
- [ ] Import from GitHub repo
- [ ] Make a PR to a GitHub repo
- [x] Visually edit your app
- [x] Use Figma-like UI
- [x] Preview your app in real-time
- [x] Manage brand assets and tokens
- [x] Create and navigate to Pages
- [x] Browse layers
- [x] Manage project Images
- [x] Detect and use Components – _Previously in
[Onlook Desktop](https://github.com/onlook-dev/desktop)_
- [ ] Drag-and-drop Components Panel
- [x] Use Branching to experiment with designs
- [x] Development Tools
- [x] Real-time code editor
- [x] Save and restore from checkpoints
- [x] Run commands via CLI
- [x] Connect with app marketplace
- [x] Deploy your app in seconds
- [x] Generate sharable links
- [x] Link your custom domain
- [ ] Collaborate with your team
- [x] Real-time editing
- [ ] Leave comments
- [ ] Advanced AI capabilities
- [x] Queue multiple messages at once
- [ ] Use Images as references and as assets in a project
- [ ] Setup and use MCPs in projects
- [ ] Allow Onlook to use itself as a toolcall for branch creation and iteration
- [ ] Advanced project support
- [ ] Support non-NextJS projects
- [ ] Support non-Tailwind projects

## Getting Started
Use our [hosted app](https://onlook.com) or
[run locally](https://docs.onlook.com/developers/running-locally).
### Usage
Onlook will run on any Next.js + TailwindCSS project, import your project into
Onlook or start from scratch within the editor.
Use the AI chat to create or edit a project you're working on. At any time, you
can always right-click an element to open up the exact location of the element
in code.
<img width="600" alt="image" src="https://github.com/user-attachments/assets/4ad9f411-b172-4430-81ef-650f4f314666" />
<br>
Draw-in new divs and re-arrange them within their parent containers by
dragging-and-dropping.
<img width="600" alt="image" src="assets/insert-div.png">
<br>
Preview the code side-by-side with your site design.
<img width="600" alt="image" src="assets/code-connect.png">
<br>
Use Onlook's editor toolbar to adjust Tailwind styles, directly manipulate
objects, and experiment with layouts.
<img width="600" alt="image" src="assets/text-styling.png" />
## Documentation
For full documentation, visit [docs.onlook.com](https://docs.onlook.com)
To see how to Contribute, visit
[Contributing to Onlook](https://docs.onlook.com/developers) in our docs.
## How it works
<img width="676" alt="architecture" src="assets/architecture.png">
1. When you create an app, we load the code into a web container
2. The container runs and serves the code
3. Our editor receives the preview link and displays it in an iFrame
4. Our editor reads and indexes the code from the container
5. We instrument the code in order to map elements to their place in code
6. When the element is edited, we edit the element in our iFrame, then in code
7. Our AI chat also has code access and tools to understand and edit the code
This architecture can theoretically scale to any language or framework that
displays DOM elements declaratively (e.g. jsx/tsx/html). We are focused on
making it work well with Next.js and TailwindCSS for now.
For a full walkthrough, check out our
[Architecture Docs](https://docs.onlook.com/developers/architecture).
### Our Tech Stack
#### Front-end
- [Next.js](https://nextjs.org/) - Full stack
- [TailwindCSS](https://tailwindcss.com/) - Styling
- [tRPC](https://trpc.io/) - Server interface
#### Database
- [Supabase](https://supabase.com/) - Auth, Database, Storage
- [Drizzle](https://orm.drizzle.team/) - ORM
#### AI
- [AI SDK](https://ai-sdk.dev/) - LLM client
- [OpenRouter](https://openrouter.ai/) - LLM model provider
- [Morph Fast Apply](https://morphllm.com) - Fast apply model provider
- [Relace](https://relace.ai) - Fast apply model provider
#### Sandbox and hosting
- [CodeSandboxSDK](https://codesandbox.io/docs/sdk) - Dev sandbox
- [Freestyle](https://www.freestyle.sh/) - Hosting
#### Runtime
- [Bun](https://bun.sh/) - Monorepo, runtime, bundler
- [Docker](https://www.docker.com/) - Container management
## Contributing

If you have a suggestion that would make this better, please fork the repo and
create a pull request. You can also
[open issues](https://github.com/onlook-dev/onlook/issues).
See the [CONTRIBUTING.md](CONTRIBUTING.md) for instructions and code of conduct.
#### Contributors
<a href="https://github.com/onlook-dev/onlook/graphs/contributors">
<img src="https://contrib.rocks/image?repo=onlook-dev/onlook" />
</a>
## Contact

- Team: [Discord](https://discord.gg/hERDfFZCsH) -
[Twitter](https://twitter.com/onlookdev) -
[LinkedIn](https://www.linkedin.com/company/onlook-dev/) -
[Email](mailto:contact@onlook.com)
- Project:
[https://github.com/onlook-dev/onlook](https://github.com/onlook-dev/onlook)
- Website: [https://onlook.com](https://onlook.com)
## License
Distributed under the Apache 2.0 License. See [LICENSE.md](LICENSE.md) for more
information.
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
[contributors-shield]: https://img.shields.io/github/contributors/onlook-dev/studio.svg?style=for-the-badge
[contributors-url]: https://github.com/onlook-dev/onlook/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/onlook-dev/studio.svg?style=for-the-badge
[forks-url]: https://github.com/onlook-dev/onlook/network/members
[stars-shield]: https://img.shields.io/github/stars/onlook-dev/studio.svg?style=for-the-badge
[stars-url]: https://github.com/onlook-dev/onlook/stargazers
[issues-shield]: https://img.shields.io/github/issues/onlook-dev/studio.svg?style=for-the-badge
[issues-url]: https://github.com/onlook-dev/onlook/issues
[license-shield]: https://img.shields.io/github/license/onlook-dev/studio.svg?style=for-the-badge
[license-url]: https://github.com/onlook-dev/onlook/blob/master/LICENSE.txt
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?logo=linkedin&colorB=555
[linkedin-url]: https://www.linkedin.com/company/onlook-dev
[twitter-shield]: https://img.shields.io/badge/-Twitter-black?logo=x&colorB=555
[twitter-url]: https://x.com/onlookdev
[discord-shield]: https://img.shields.io/badge/-Discord-black?logo=discord&colorB=555
[discord-url]: https://discord.gg/hERDfFZCsH
[React.js]: https://img.shields.io/badge/react-%2320232a.svg?logo=react&logoColor=%2361DAFB
[React-url]: https://reactjs.org/
[TailwindCSS]: https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?logo=tailwind-css&logoColor=white
[Tailwind-url]: https://tailwindcss.com/
[Electron.js]: https://img.shields.io/badge/Electron-191970?logo=Electron&logoColor=white
[Electron-url]: https://www.electronjs.org/
[Vite.js]: https://img.shields.io/badge/vite-%23646CFF.svg?logo=vite&logoColor=white
[Vite-url]: https://vitejs.dev/
[product-screenshot]: assets/brand.png
[weave-shield]: https://img.shields.io/endpoint?url=https%3A%2F%2Fapp.workweave.ai%2Fapi%2Frepository%2Fbadge%2Forg_pWcXBHJo3Li2Te2Y4WkCPA33%2F820087727&cacheSeconds=3600&labelColor=#131313
[weave-url]: https://app.workweave.ai/reports/repository/org_pWcXBHJo3Li2Te2Y4WkCPA33/820087727
================================================
FILE: SECURITY.md
================================================
# Security Policy
Please contact us at [contact@onlook.com](mailto:contact@onlook.com) with any security issues.
================================================
FILE: apps/backend/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
dist-electron
release
*.local
# Editor directories and files
.vscode/.debug.env
.vscode/settings.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
#lockfile
package-lock.json
pnpm-lock.yaml
yarn.lock
/test-results/
/playwright-report/
/playwright/.cache/
# Env variables
.env
================================================
FILE: apps/backend/README.md
================================================
## Why a backend stack?
This is our server stack built in Supabase which you can also run locally or
self-host.
Used to enable online capabilities such as managing users, collaborating,
persisting data, etc.
We will offer this as a hosted instance at some point. Ideally, the product
should still work offline with no backend connection.
## Usage
### Running locally
1. Make sure you have [Docker] installed
2. Install necessary packages
```bash
bun install
```
3. Run the supabase instance locally
```bash
bun run start
```
4. Set up the latest snapshot of the database
```bash
bun run reset
```
================================================
FILE: apps/backend/package.json
================================================
{
"name": "@onlook/backend",
"private": true,
"scripts": {
"start": "supabase start",
"stop": "supabase stop",
"push": "supabase db push",
"reset": "supabase db reset",
"db:gen": "supabase gen types --lang=typescript --local --schema public > ../../packages/supabase/src/types/db.ts",
"test": "cd supabase/functions/api && deno test",
"status": "supabase status -o json"
},
"dependencies": {},
"devDependencies": {
"@onlook/typescript": "*",
"@types/bun": "latest",
"supabase": "^2.45.5"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
}
================================================
FILE: apps/backend/supabase/.gitignore
================================================
# Supabase
.branches
.temp
.env
================================================
FILE: apps/backend/supabase/config.toml
================================================
project_id = "onlook-web"
[api]
enabled = true
port = 54321
schemas = ["public", "storage"]
extra_search_path = ["public"]
max_rows = 100
[auth]
site_url = "https://onlook.com"
additional_redirect_urls = [
"http://localhost:3000",
"http://localhost:3000/auth/callback",
]
jwt_expiry = 36000
[db]
port = 54322
[studio]
port = 54323
[auth.external.github]
enabled = true
client_id = "env(GITHUB_CLIENT_ID)"
secret = "env(GITHUB_SECRET)"
redirect_uri = "http://127.0.0.1:54321/auth/v1/callback"
[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_SECRET)"
redirect_uri = "http://127.0.0.1:54321/auth/v1/callback"
[analytics]
enabled = true
port = 54327
vector_port = 54328
backend = "postgres"
[functions.stripe-webhook]
verify_jwt = false
[storage.buckets.preview_images]
public = true
file_size_limit = "10MiB"
================================================
FILE: apps/backend/supabase/migrations/0000_same_human_robot.sql
================================================
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'frame_type') THEN
CREATE TYPE "public"."frame_type" AS ENUM('web');
END IF;
END $$;--> statement-breakpoint
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'role') THEN
CREATE TYPE "public"."message_role" AS ENUM('user', 'assistant');
END IF;
END $$;--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "canvas" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"project_id" uuid NOT NULL,
"scale" numeric NOT NULL,
"x" numeric NOT NULL,
"y" numeric NOT NULL
);
--> statement-breakpoint
ALTER TABLE "canvas" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "frames" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"canvas_id" uuid NOT NULL,
"type" "frame_type" NOT NULL,
"url" varchar NOT NULL,
"x" numeric NOT NULL,
"y" numeric NOT NULL,
"width" numeric NOT NULL,
"height" numeric NOT NULL
);
--> statement-breakpoint
ALTER TABLE "frames" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "conversations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"project_id" uuid NOT NULL,
"display_name" varchar,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "messages" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"conversation_id" uuid NOT NULL,
"content" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"role" "message_role" NOT NULL,
"applied" boolean DEFAULT false NOT NULL,
"snapshots" jsonb DEFAULT '{}'::jsonb NOT NULL,
"context" jsonb DEFAULT '[]'::jsonb NOT NULL,
"parts" jsonb DEFAULT '[]'::jsonb NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "projects" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" varchar NOT NULL,
"sandbox_id" varchar NOT NULL,
"sandbox_url" varchar NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"preview_img" varchar,
"description" text
);
--> statement-breakpoint
ALTER TABLE "projects" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "users" (
"id" uuid PRIMARY KEY NOT NULL
);
--> statement-breakpoint
ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "user_projects" (
"user_id" uuid NOT NULL,
"project_id" uuid NOT NULL,
"created_at" timestamp with time zone DEFAULT now(),
CONSTRAINT "user_projects_user_id_project_id_pk" PRIMARY KEY("user_id","project_id")
);
--> statement-breakpoint
ALTER TABLE "user_projects" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "canvas" DROP CONSTRAINT IF EXISTS "canvas_project_id_projects_id_fk";--> statement-breakpoint
ALTER TABLE "canvas" ADD CONSTRAINT "canvas_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "frames" DROP CONSTRAINT IF EXISTS "frames_canvas_id_canvas_id_fk";--> statement-breakpoint
ALTER TABLE "frames" ADD CONSTRAINT "frames_canvas_id_canvas_id_fk" FOREIGN KEY ("canvas_id") REFERENCES "public"."canvas"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "conversations" DROP CONSTRAINT IF EXISTS "conversations_project_id_projects_id_fk";--> statement-breakpoint
ALTER TABLE "conversations" ADD CONSTRAINT "conversations_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "messages" DROP CONSTRAINT IF EXISTS "messages_conversation_id_conversations_id_fk";--> statement-breakpoint
ALTER TABLE "messages" ADD CONSTRAINT "messages_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "users_id_users_id_fk";--> statement-breakpoint
ALTER TABLE "users" ADD CONSTRAINT "users_id_users_id_fk" FOREIGN KEY ("id") REFERENCES "auth"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "user_projects" DROP CONSTRAINT IF EXISTS "user_projects_user_id_users_id_fk";--> statement-breakpoint
ALTER TABLE "user_projects" ADD CONSTRAINT "user_projects_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "user_projects" DROP CONSTRAINT IF EXISTS "user_projects_project_id_projects_id_fk";--> statement-breakpoint
ALTER TABLE "user_projects" ADD CONSTRAINT "user_projects_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;
================================================
FILE: apps/backend/supabase/migrations/0001_graceful_exodus.sql
================================================
ALTER TABLE "conversations" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "messages" ENABLE ROW LEVEL SECURITY;
================================================
FILE: apps/backend/supabase/migrations/0002_red_crusher_hogan.sql
================================================
CREATE TABLE IF NOT EXISTS "user_settings" (
"id" uuid PRIMARY KEY NOT NULL,
"user_id" uuid NOT NULL,
"auto_apply_code" boolean DEFAULT true NOT NULL,
"expand_code_blocks" boolean DEFAULT true NOT NULL,
"show_suggestions" boolean DEFAULT true NOT NULL,
"show_mini_chat" boolean DEFAULT true NOT NULL,
CONSTRAINT "user_settings_user_id_unique" UNIQUE("user_id")
);
--> statement-breakpoint
ALTER TABLE "user_settings" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "user_settings" DROP CONSTRAINT IF EXISTS "user_settings_user_id_users_id_fk";
--> statement-breakpoint
ALTER TABLE "user_settings" ADD CONSTRAINT "user_settings_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;
================================================
FILE: apps/backend/supabase/migrations/0003_loud_ozymandias.sql
================================================
CREATE TABLE IF NOT EXISTS "user_canvases" (
"user_id" uuid NOT NULL,
"canvas_id" uuid NOT NULL,
"scale" numeric NOT NULL,
"x" numeric NOT NULL,
"y" numeric NOT NULL,
CONSTRAINT "user_canvases_user_id_canvas_id_pk" PRIMARY KEY("user_id","canvas_id")
);
--> statement-breakpoint
ALTER TABLE "user_canvases" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "user_canvases" DROP CONSTRAINT IF EXISTS user_canvases_user_id_users_id_fk;
ALTER TABLE "user_canvases" ADD CONSTRAINT "user_canvases_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "user_canvases" DROP CONSTRAINT IF EXISTS user_canvases_canvas_id_canvas_id_fk;
ALTER TABLE "user_canvases" ADD CONSTRAINT "user_canvases_canvas_id_canvas_id_fk" FOREIGN KEY ("canvas_id") REFERENCES "public"."canvas"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
-- Copy over the scale, x, and y values from the canvas table to the user_canvases table (if columns exist)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'canvas' AND column_name = 'scale') THEN
INSERT INTO "user_canvases" ("user_id", "canvas_id", "scale", "x", "y")
SELECT
up.user_id,
c.id as canvas_id,
c.scale,
c.x,
c.y
FROM "canvas" c
INNER JOIN "user_projects" up ON c.project_id = up.project_id
ON CONFLICT (user_id, canvas_id) DO NOTHING;
END IF;
END $$;
ALTER TABLE "canvas" DROP COLUMN IF EXISTS "scale";--> statement-breakpoint
ALTER TABLE "canvas" DROP COLUMN IF EXISTS "x";--> statement-breakpoint
ALTER TABLE "canvas" DROP COLUMN IF EXISTS "y";
================================================
FILE: apps/backend/supabase/migrations/0004_pink_expediter.sql
================================================
-- Create ENUMs only if they don't exist
DO $$ BEGIN
CREATE TYPE "public"."invitation_status" AS ENUM('pending', 'accepted', 'expired');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "public"."project_role" AS ENUM('owner', 'admin');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;--> statement-breakpoint
-- Create table only if it doesn't exist
CREATE TABLE IF NOT EXISTS "project_invitations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"project_id" uuid NOT NULL,
"inviter_id" uuid NOT NULL,
"invitee_email" varchar NOT NULL,
"status" "invitation_status" DEFAULT 'pending' NOT NULL,
"token" varchar NOT NULL,
"role" "project_role" NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "project_invitations_token_unique" UNIQUE("token")
);
--> statement-breakpoint
ALTER TABLE "project_invitations" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "user_projects" ADD COLUMN IF NOT EXISTS "role" "project_role";--> statement-breakpoint
-- Set all existing records to 'owner' role (assuming existing users should be owners)
UPDATE "user_projects" SET "role" = 'owner' WHERE "role" IS NULL;
-- Make the role column NOT NULL after setting default values
ALTER TABLE "user_projects" ALTER COLUMN "role" SET NOT NULL;
ALTER TABLE "project_invitations" DROP CONSTRAINT IF EXISTS "project_invitations_project_id_projects_id_fk";
ALTER TABLE "project_invitations" ADD CONSTRAINT "project_invitations_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "project_invitations" DROP CONSTRAINT IF EXISTS "project_invitations_inviter_id_users_id_fk";
ALTER TABLE "project_invitations" ADD CONSTRAINT "project_invitations_inviter_id_users_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;
================================================
FILE: apps/backend/supabase/migrations/0005_short_lila_cheney.sql
================================================
ALTER TABLE "project_invitations" DROP COLUMN IF EXISTS "status";--> statement-breakpoint
ALTER TABLE "project_invitations" DROP CONSTRAINT IF EXISTS "project_invitations_invitee_email_project_id_unique";
ALTER TABLE "project_invitations" ADD CONSTRAINT "project_invitations_invitee_email_project_id_unique" UNIQUE("invitee_email","project_id");--> statement-breakpoint
DROP TYPE IF EXISTS "public"."invitation_status";
================================================
FILE: apps/backend/supabase/migrations/0006_rls.sql
================================================
-- Helper function to check if user has specific roles for a project
CREATE OR REPLACE FUNCTION user_has_project_access(
project_id_param UUID,
required_roles TEXT[]
) RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (
SELECT 1 FROM user_projects
WHERE user_projects.project_id = project_id_param
AND user_projects.user_id = auth.uid()
AND user_projects.role = ANY(required_roles)
);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Helper function to check if user has project access via canvas
CREATE OR REPLACE FUNCTION user_has_canvas_access(
canvas_id_param UUID,
required_roles TEXT[]
) RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (
SELECT 1 FROM canvas c
JOIN user_projects up ON c.project_id = up.project_id
WHERE c.id = canvas_id_param
AND up.user_id = auth.uid()
AND up.role = ANY(required_roles)
);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- PROJECTS POLICIES
DROP POLICY IF EXISTS "projects_insert_policy" ON projects;
-- 1. INSERT: Allow only authenticated users to create projects
CREATE POLICY "projects_insert_policy" ON projects
FOR INSERT
TO authenticated
WITH CHECK (true);
DROP POLICY IF EXISTS "projects_select_policy" ON projects;
-- 2. SELECT: Allow users who have an entry in user_projects for that project
CREATE POLICY "projects_select_policy" ON projects
FOR SELECT
TO authenticated
USING (user_has_project_access(projects.id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "projects_update_policy" ON projects;
-- 3. UPDATE: Allow users with 'owner' or 'admin' role in user_projects
CREATE POLICY "projects_update_policy" ON projects
FOR UPDATE
TO authenticated
USING (user_has_project_access(projects.id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "projects_delete_policy" ON projects;
-- 4. DELETE: Allow only users with 'owner' role
CREATE POLICY "projects_delete_policy" ON projects
FOR DELETE
TO authenticated
USING (user_has_project_access(projects.id, ARRAY['owner']));
-- CANVAS POLICIES
DROP POLICY IF EXISTS "canvas_insert_policy" ON canvas;
-- 1. INSERT: Allow only users with 'owner' role to create canvas entries
CREATE POLICY "canvas_insert_policy" ON canvas
FOR INSERT
TO authenticated
WITH CHECK (user_has_project_access(canvas.project_id, ARRAY['owner']));
DROP POLICY IF EXISTS "canvas_select_policy" ON canvas;
-- 2. SELECT: Allow users who have an entry in user_projects for the canvas's project
CREATE POLICY "canvas_select_policy" ON canvas
FOR SELECT
TO authenticated
USING (user_has_project_access(canvas.project_id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "canvas_update_policy" ON canvas;
-- 3. UPDATE: Allow users with 'owner' or 'admin' role in user_projects for the canvas's project
CREATE POLICY "canvas_update_policy" ON canvas
FOR UPDATE
TO authenticated
USING (user_has_project_access(canvas.project_id, ARRAY['owner', 'admin']))
WITH CHECK (user_has_project_access(canvas.project_id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "canvas_delete_policy" ON canvas;
-- 4. DELETE: Allow only users with 'owner' role for the canvas's project
CREATE POLICY "canvas_delete_policy" ON canvas
FOR DELETE
TO authenticated
USING (user_has_project_access(canvas.project_id, ARRAY['owner']));
-- USER_PROJECTS POLICIES
DROP POLICY IF EXISTS "user_projects_select_policy" ON user_projects;
-- 1. SELECT: Allow users to see their own entries or project owners/admins to see all entries
CREATE POLICY "user_projects_select_policy" ON user_projects
FOR SELECT
TO authenticated
USING (
auth.uid() = user_projects.user_id OR
user_has_project_access(user_projects.project_id, ARRAY['owner', 'admin'])
);
DROP POLICY IF EXISTS "user_projects_update_policy" ON user_projects;
-- 2. UPDATE: Allow only project owners/admins to update user roles
CREATE POLICY "user_projects_update_policy" ON user_projects
FOR UPDATE
TO authenticated
USING (user_has_project_access(user_projects.project_id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "user_projects_delete_policy" ON user_projects;
-- 3. DELETE: Allow users to remove themselves or project owners to remove anyone
CREATE POLICY "user_projects_delete_policy" ON user_projects
FOR DELETE
TO authenticated
USING (
auth.uid() = user_projects.user_id OR
user_has_project_access(user_projects.project_id, ARRAY['owner'])
);
-- USER_CANVASES POLICIES
DROP POLICY IF EXISTS "user_canvases_insert_policy" ON user_canvases;
-- 1. INSERT: Allow users to create their own canvas associations
CREATE POLICY "user_canvases_insert_policy" ON user_canvases
FOR INSERT
TO authenticated
WITH CHECK (
auth.uid() = user_canvases.user_id
);
DROP POLICY IF EXISTS "user_canvases_select_policy" ON user_canvases;
-- 2. SELECT: Allow users to see only their own canvas associations
CREATE POLICY "user_canvases_select_policy" ON user_canvases
FOR SELECT
TO authenticated
USING (
auth.uid() = user_canvases.user_id
);
DROP POLICY IF EXISTS "user_canvases_update_policy" ON user_canvases;
-- 3. UPDATE: Allow users to update only their own canvas associations
CREATE POLICY "user_canvases_update_policy" ON user_canvases
FOR UPDATE
TO authenticated
USING (auth.uid() = user_canvases.user_id)
WITH CHECK (auth.uid() = user_canvases.user_id);
DROP POLICY IF EXISTS "user_canvases_delete_policy" ON user_canvases;
-- 4. DELETE: Allow users to delete only their own canvas associations
CREATE POLICY "user_canvases_delete_policy" ON user_canvases
FOR DELETE
TO authenticated
USING (auth.uid() = user_canvases.user_id);
-- FRAMES POLICIES
DROP POLICY IF EXISTS "frames_insert_policy" ON frames;
-- 1. INSERT: Allow project owners/admins to create frames
CREATE POLICY "frames_insert_policy" ON frames
FOR INSERT
TO authenticated
WITH CHECK (user_has_canvas_access(frames.canvas_id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "frames_select_policy" ON frames;
-- 2. SELECT: Allow project owners/admins to view frames
CREATE POLICY "frames_select_policy" ON frames
FOR SELECT
TO authenticated
USING (user_has_canvas_access(frames.canvas_id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "frames_update_policy" ON frames;
-- 3. UPDATE: Allow project owners/admins to update frames
CREATE POLICY "frames_update_policy" ON frames
FOR UPDATE
TO authenticated
USING (user_has_canvas_access(frames.canvas_id, ARRAY['owner', 'admin']))
WITH CHECK (user_has_canvas_access(frames.canvas_id, ARRAY['owner', 'admin']));
DROP POLICY IF EXISTS "frames_delete_policy" ON frames;
-- 4. DELETE: Allow project owners/admins to delete frames
CREATE POLICY "frames_delete_policy" ON frames
FOR DELETE
TO authenticated
USING (user_has_canvas_access(frames.canvas_id, ARRAY['owner', 'admin']));
-- USERS POLICIES
DROP POLICY IF EXISTS "users_insert_policy" ON users;
-- 1. INSERT: Allow users to create their own user record
CREATE POLICY "users_insert_policy" ON users
FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = users.id);
DROP POLICY IF EXISTS "users_select_policy" ON users;
-- 2. SELECT: Allow users to view only their own user record
CREATE POLICY "users_select_policy" ON users
FOR SELECT
TO authenticated
USING (auth.uid() = users.id);
DROP POLICY IF EXISTS "users_update_policy" ON users;
-- 3. UPDATE: Allow users to update only their own user record
CREATE POLICY "users_update_policy" ON users
FOR UPDATE
TO authenticated
USING (auth.uid() = users.id)
WITH CHECK (auth.uid() = users.id);
DROP POLICY IF EXISTS "users_delete_policy" ON users;
-- 4. DELETE: Allow users to delete only their own user record
CREATE POLICY "users_delete_policy" ON users
FOR DELETE
TO authenticated
USING (auth.uid() = users.id);
-- USER_SETTINGS POLICIES
DROP POLICY IF EXISTS "user_settings_insert_policy" ON user_settings;
-- 1. INSERT: Allow users to create their own settings
CREATE POLICY "user_settings_insert_policy" ON user_settings
FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_settings.user_id);
DROP POLICY IF EXISTS "user_settings_select_policy" ON user_settings;
-- 2. SELECT: Allow users to view only their own settings
CREATE POLICY "user_settings_select_policy" ON user_settings
FOR SELECT
TO authenticated
USING (auth.uid() = user_settings.user_id);
DROP POLICY IF EXISTS "user_settings_update_policy" ON user_settings;
-- 3. UPDATE: Allow users to update only their own settings
CREATE POLICY "user_settings_update_policy" ON user_settings
FOR UPDATE
TO authenticated
USING (auth.uid() = user_settings.user_id)
WITH CHECK (auth.uid() = user_settings.user_id);
DROP POLICY IF EXISTS "user_settings_delete_policy" ON user_settings;
-- 4. DELETE: Allow users to delete only their own settings
CREATE POLICY "user_settings_delete_policy" ON user_settings
FOR DELETE
TO authenticated
USING (auth.uid() = user_settings.user_id);
-- PROJECT_INVITATIONS POLICIES
DROP POLICY IF EXISTS "project_invitations_insert_policy" ON project_invitations;
-- 1. INSERT: Allow project owners/admins to send invitations
CREATE POLICY "project_invitations_insert_policy" ON project_invitations
FOR INSERT
TO authenticated
WITH CHECK (
auth.uid() = project_invitations.inviter_id AND
user_has_project_access(project_invitations.project_id, ARRAY['owner', 'admin'])
);
DROP POLICY IF EXISTS "project_invitations_select_policy" ON project_invitations;
-- 2. SELECT: Allow project owners/admins and invitees to view invitations
CREATE POLICY "project_invitations_select_policy" ON project_invitations
FOR SELECT
TO authenticated
USING (
user_has_project_access(project_invitations.project_id, ARRAY['owner', 'admin']) OR
EXISTS (
SELECT 1 FROM auth.users
WHERE auth.users.id = auth.uid()
AND auth.users.email = project_invitations.invitee_email
)
);
DROP POLICY IF EXISTS "project_invitations_update_policy" ON project_invitations;
-- 3. UPDATE: Allow project owners/admins and invitees to update invitations
CREATE POLICY "project_invitations_update_policy" ON project_invitations
FOR UPDATE
TO authenticated
USING (
user_has_project_access(project_invitations.project_id, ARRAY['owner', 'admin']) OR
EXISTS (
SELECT 1 FROM auth.users
WHERE auth.users.id = auth.uid()
AND auth.users.email = project_invitations.invitee_email
)
)
WITH CHECK (
user_has_project_access(project_invitations.project_id, ARRAY['owner', 'admin']) OR
EXISTS (
SELECT 1 FROM auth.users
WHERE auth.users.id = auth.uid()
AND auth.users.email = project_invitations.invitee_email
)
);
DROP POLICY IF EXISTS "project_invitations_delete_policy" ON project_invitations;
-- 4. DELETE: Allow inviters, project owners/admins, and invitees to delete invitations
CREATE POLICY "project_invitations_delete_policy" ON project_invitations
FOR DELETE
TO authenticated
USING (
auth.uid() = project_invitations.inviter_id OR
user_has_project_access(project_invitations.project_id, ARRAY['owner', 'admin']) OR
EXISTS (
SELECT 1 FROM auth.users
WHERE auth.users.id = auth.uid()
AND auth.users.email = project_invitations.invitee_email
)
);
================================================
FILE: apps/backend/supabase/migrations/0007_realtime_rls.sql
================================================
CREATE OR REPLACE FUNCTION public.project_changes()
RETURNS TRIGGER
SECURITY DEFINER
LANGUAGE plpgsql
AS $$
DECLARE
topic_project_id uuid;
BEGIN
IF TG_TABLE_NAME = 'conversations' THEN
SELECT c.project_id INTO topic_project_id
FROM "conversations" c WHERE c.id = COALESCE(NEW.id, OLD.id);
ELSIF TG_TABLE_NAME = 'messages' THEN
SELECT c.project_id INTO topic_project_id
FROM "messages" m INNER JOIN "conversations" c ON m.conversation_id = c.id
WHERE m.id = COALESCE(NEW.id, OLD.id);
END IF;
-- Only broadcast if we found a valid project_id (i.e., not for projects table)
IF topic_project_id IS NOT NULL THEN
PERFORM realtime.broadcast_changes(
'topic:' || topic_project_id::text, -- topic - the topic to which we're broadcasting
TG_OP, -- event - the event that triggered the function
TG_OP, -- operation - the operation that triggered the function
TG_TABLE_NAME, -- table - the table that caused the trigger
TG_TABLE_SCHEMA, -- schema - the schema of the table that caused the trigger
NEW, -- new record - the record after the change
OLD -- old record - the record before the change
);
END IF;
RETURN NULL;
END;
$$;
DROP TRIGGER IF EXISTS handle_conversations_changes ON public.conversations;
CREATE TRIGGER handle_conversations_changes
AFTER INSERT OR UPDATE OR DELETE
ON public.conversations
FOR EACH ROW
EXECUTE FUNCTION project_changes ();
DROP TRIGGER IF EXISTS handle_messages_changes ON public.messages;
CREATE TRIGGER handle_messages_changes
AFTER INSERT OR UPDATE OR DELETE
ON public.messages
FOR EACH ROW
EXECUTE FUNCTION project_changes ();
DROP POLICY IF EXISTS "Authenticated users can receive broadcasts" ON "realtime"."messages";
CREATE POLICY "Authenticated users can receive broadcasts"
ON "realtime"."messages"
FOR SELECT
TO authenticated
USING ( TRUE );
================================================
FILE: apps/backend/supabase/migrations/0008_preview-img-storage.sql
================================================
delete from storage.objects where bucket_id = 'preview_images';
delete from storage.buckets where id = 'preview_images';
insert into storage.buckets
(id, name, public)
values
('preview_images', 'preview_images', true);
-- Allow any users to select from preview_images files
drop policy if exists "preview_images_select_policy" on storage.objects;
create policy "preview_images_select_policy"
on storage.objects for select to public using (
bucket_id = 'preview_images'
);
-- Allow any users to insert into preview_images files
drop policy if exists "preview_images_insert_policy" on storage.objects;
create policy "preview_images_insert_policy"
on storage.objects for insert to public with check (
bucket_id = 'preview_images'
);
================================================
FILE: apps/backend/supabase/migrations/0009_project_img_path.sql
================================================
ALTER TABLE "projects" DROP COLUMN IF EXISTS "preview_img_url";--> statement-breakpoint
ALTER TABLE "projects" DROP COLUMN IF EXISTS "preview_img_path";--> statement-breakpoint
ALTER TABLE "projects" DROP COLUMN IF EXISTS "preview_img_bucket";--> statement-breakpoint
ALTER TABLE "projects" ADD COLUMN "preview_img_url" varchar;--> statement-breakpoint
ALTER TABLE "projects" ADD COLUMN "preview_img_path" varchar;--> statement-breakpoint
ALTER TABLE "projects" ADD COLUMN "preview_img_bucket" varchar;--> statement-breakpoint
================================================
FILE: apps/backend/supabase/migrations/0010_bent_edwin_jarvis.sql
================================================
-- Create new type
CREATE TYPE "public"."verification_request_status" AS ENUM('active', 'expired', 'used');--> statement-breakpoint
CREATE TABLE "custom_domains" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"apex_domain" text NOT NULL,
"verified" boolean DEFAULT false NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "custom_domains_apex_domain_unique" UNIQUE("apex_domain")
);
--> statement-breakpoint
CREATE TABLE "preview_domains" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"full_domain" text NOT NULL,
"project_id" uuid,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "preview_domains_full_domain_unique" UNIQUE("full_domain")
);
--> statement-breakpoint
CREATE TABLE "published_domains" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"domain_id" uuid,
"project_id" uuid,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"full_domain" text NOT NULL,
CONSTRAINT "published_domains_domain_id_unique" UNIQUE("domain_id"),
CONSTRAINT "published_domains_full_domain_unique" UNIQUE("full_domain")
);
--> statement-breakpoint
CREATE TABLE "custom_domain_verification" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"domain_id" uuid NOT NULL,
"project_id" uuid NOT NULL,
"verification_id" text NOT NULL,
"verification_code" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"status" "verification_request_status" DEFAULT 'active' NOT NULL
);
--> statement-breakpoint
ALTER TABLE "preview_domains" ADD CONSTRAINT "preview_domains_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "published_domains" ADD CONSTRAINT "published_domains_domain_id_custom_domains_id_fk" FOREIGN KEY ("domain_id") REFERENCES "public"."custom_domains"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "published_domains" ADD CONSTRAINT "published_domains_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD CONSTRAINT "custom_domain_verification_domain_id_custom_domains_id_fk" FOREIGN KEY ("domain_id") REFERENCES "public"."custom_domains"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD CONSTRAINT "custom_domain_verification_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "projects" DROP COLUMN IF EXISTS "preview_img";
================================================
FILE: apps/backend/supabase/migrations/0011_typical_clea.sql
================================================
;--> statement-breakpoint
CREATE TYPE "public"."price_keys" AS ENUM('PRO_MONTHLY_TIER_1', 'PRO_MONTHLY_TIER_2', 'PRO_MONTHLY_TIER_3', 'PRO_MONTHLY_TIER_4', 'PRO_MONTHLY_TIER_5', 'PRO_MONTHLY_TIER_6', 'PRO_MONTHLY_TIER_7', 'PRO_MONTHLY_TIER_8', 'PRO_MONTHLY_TIER_9', 'PRO_MONTHLY_TIER_10', 'PRO_MONTHLY_TIER_11');--> statement-breakpoint
CREATE TYPE "public"."product_type" AS ENUM('free', 'pro');--> statement-breakpoint
CREATE TYPE "public"."scheduled_subscription_action" AS ENUM('price_change', 'cancellation');--> statement-breakpoint
CREATE TYPE "public"."usage_types" AS ENUM('message', 'deployment');--> statement-breakpoint
CREATE TYPE "public"."subscription_status" AS ENUM('active', 'canceled');--> statement-breakpoint
CREATE TABLE "project_settings" (
"project_id" uuid NOT NULL,
"run_command" text DEFAULT '' NOT NULL,
"build_command" text DEFAULT '' NOT NULL,
"install_command" text DEFAULT '' NOT NULL,
CONSTRAINT "project_settings_project_id_unique" UNIQUE("project_id")
);
--> statement-breakpoint
ALTER TABLE "project_settings" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE "prices" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"product_id" uuid NOT NULL,
"price_key" "price_keys" NOT NULL,
"monthly_message_limit" integer NOT NULL,
"stripe_price_id" text NOT NULL,
CONSTRAINT "prices_stripe_price_id_unique" UNIQUE("stripe_price_id")
);
--> statement-breakpoint
ALTER TABLE "prices" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE "products" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text NOT NULL,
"type" "product_type" NOT NULL,
"stripe_product_id" text NOT NULL,
CONSTRAINT "products_stripe_product_id_unique" UNIQUE("stripe_product_id")
);
--> statement-breakpoint
ALTER TABLE "products" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE "subscriptions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"product_id" uuid NOT NULL,
"price_id" uuid NOT NULL,
"started_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"ended_at" timestamp with time zone,
"status" "subscription_status" DEFAULT 'active' NOT NULL,
"stripe_customer_id" text NOT NULL,
"stripe_subscription_id" text NOT NULL,
"stripe_subscription_item_id" text NOT NULL,
"scheduled_action" "scheduled_subscription_action",
"scheduled_price_id" uuid,
"scheduled_change_at" timestamp with time zone,
"stripe_subscription_schedule_id" text,
CONSTRAINT "subscriptions_stripe_subscription_id_unique" UNIQUE("stripe_subscription_id"),
CONSTRAINT "subscriptions_stripe_subscription_item_id_unique" UNIQUE("stripe_subscription_item_id")
);
--> statement-breakpoint
ALTER TABLE "subscriptions" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE "usage_records" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"type" "usage_types" DEFAULT 'message' NOT NULL,
"timestamp" timestamp with time zone NOT NULL
);
--> statement-breakpoint
ALTER TABLE "usage_records" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "custom_domains" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "preview_domains" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "published_domains" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ALTER COLUMN "status" SET DATA TYPE "public"."verification_request_status";--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ALTER COLUMN "status" SET DEFAULT 'active';--> statement-breakpoint
ALTER TABLE "messages" ADD COLUMN "commit_oid" text;--> statement-breakpoint
ALTER TABLE "user_settings" ADD COLUMN "should_warn_delete" boolean DEFAULT true NOT NULL;--> statement-breakpoint
ALTER TABLE "project_settings" ADD CONSTRAINT "project_settings_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "prices" ADD CONSTRAINT "prices_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_price_id_prices_id_fk" FOREIGN KEY ("price_id") REFERENCES "public"."prices"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_scheduled_price_id_prices_id_fk" FOREIGN KEY ("scheduled_price_id") REFERENCES "public"."prices"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "usage_records" ADD CONSTRAINT "usage_records_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
DROP TYPE IF EXISTS "public"."status";
================================================
FILE: apps/backend/supabase/migrations/0012_file-transfer-bucket.sql
================================================
delete from storage.objects where bucket_id = 'file_transfer';
delete from storage.buckets where id = 'file_transfer';
insert into storage.buckets
(id, name, public)
values
('file_transfer', 'file_transfer', false);
-- Allow authenticated users to select only their own files from file_transfer
drop policy if exists "file_transfer_select_policy" on storage.objects;
create policy "file_transfer_select_policy"
on storage.objects for select to authenticated using (
bucket_id = 'file_transfer' AND auth.uid() = owner
);
-- Allow authenticated users to insert into file_transfer with their user ID as owner
drop policy if exists "file_transfer_insert_policy" on storage.objects;
create policy "file_transfer_insert_policy"
on storage.objects for insert to authenticated with check (
bucket_id = 'file_transfer' AND auth.uid() = owner
);
-- Allow authenticated users to delete only their own files
drop policy if exists "file_transfer_delete_policy" on storage.objects;
create policy "file_transfer_delete_policy"
on storage.objects for delete to authenticated using (
bucket_id = 'file_transfer' AND auth.uid() = owner
);
================================================
FILE: apps/backend/supabase/migrations/0013_aspiring_kabuki.sql
================================================
CREATE TYPE "public"."project_create_status" AS ENUM('pending', 'completed', 'failed');--> statement-breakpoint
CREATE TYPE "public"."deployment_status" AS ENUM('in_progress', 'completed', 'failed');--> statement-breakpoint
CREATE TYPE "public"."deployment_type" AS ENUM('preview', 'custom', 'unpublish_preview', 'unpublish_custom');--> statement-breakpoint
CREATE TABLE "project_create_requests" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"project_id" uuid NOT NULL,
"context" jsonb NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"status" "project_create_status" DEFAULT 'pending' NOT NULL,
CONSTRAINT "project_create_requests_project_id_unique" UNIQUE("project_id")
);
--> statement-breakpoint
ALTER TABLE "project_create_requests" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
CREATE TABLE "deployments" (
"id" uuid PRIMARY KEY NOT NULL,
"requested_by" uuid NOT NULL,
"project_id" uuid NOT NULL,
"sandbox_id" text,
"urls" text[],
"type" "deployment_type" NOT NULL,
"status" "deployment_status" NOT NULL,
"message" text,
"build_log" text,
"error" text,
"progress" integer,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "deployments" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "first_name" text;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "last_name" text;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "display_name" text;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "avatar_url" text;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "email" text;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "created_at" timestamp with time zone DEFAULT now() NOT NULL;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "updated_at" timestamp with time zone DEFAULT now() NOT NULL;--> statement-breakpoint
ALTER TABLE "project_create_requests" ADD CONSTRAINT "project_create_requests_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "deployments" ADD CONSTRAINT "deployments_requested_by_users_id_fk" FOREIGN KEY ("requested_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "deployments" ADD CONSTRAINT "deployments_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE no action ON UPDATE no action;
================================================
FILE: apps/backend/supabase/migrations/0014_military_marrow.sql
================================================
CREATE TYPE "public"."project_custom_domain_status" AS ENUM('active', 'cancelled');--> statement-breakpoint
CREATE TABLE "project_custom_domains" (
"full_domain" text NOT NULL,
"custom_domain_id" uuid NOT NULL,
"project_id" uuid NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"status" "project_custom_domain_status" DEFAULT 'active' NOT NULL,
CONSTRAINT "project_custom_domains_custom_domain_id_project_id_pk" PRIMARY KEY("custom_domain_id","project_id")
);
--> statement-breakpoint
ALTER TABLE "project_custom_domains" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
DROP TABLE "published_domains" CASCADE;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" RENAME COLUMN "domain_id" TO "custom_domain_id";--> statement-breakpoint
ALTER TABLE "custom_domain_verification" RENAME COLUMN "verification_id" TO "freestyle_verification_id";--> statement-breakpoint
ALTER TABLE "custom_domain_verification" DROP CONSTRAINT "custom_domain_verification_domain_id_custom_domains_id_fk";
--> statement-breakpoint
ALTER TABLE "custom_domain_verification" DROP COLUMN "status";--> statement-breakpoint
DROP TYPE IF EXISTS "public"."verification_request_status";--> statement-breakpoint
CREATE TYPE "public"."verification_request_status" AS ENUM('pending', 'verified', 'cancelled');--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD COLUMN "status" "verification_request_status" NOT NULL DEFAULT 'pending';--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD COLUMN "full_domain" text NOT NULL;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD COLUMN "txt_record" jsonb NOT NULL;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD COLUMN "a_records" jsonb DEFAULT '[]'::jsonb NOT NULL;--> statement-breakpoint
ALTER TABLE "project_custom_domains" ADD CONSTRAINT "project_custom_domains_custom_domain_id_custom_domains_id_fk" FOREIGN KEY ("custom_domain_id") REFERENCES "public"."custom_domains"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "project_custom_domains" ADD CONSTRAINT "project_custom_domains_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD CONSTRAINT "custom_domain_verification_custom_domain_id_custom_domains_id_fk" FOREIGN KEY ("custom_domain_id") REFERENCES "public"."custom_domains"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" DROP COLUMN "verification_code";
================================================
FILE: apps/backend/supabase/migrations/0015_same_leo.sql
================================================
--> statement-breakpoint
ALTER TYPE "public"."deployment_status" ADD VALUE 'pending' BEFORE 'in_progress';--> statement-breakpoint
ALTER TYPE "public"."deployment_status" ADD VALUE 'cancelled';--> statement-breakpoint
CREATE TABLE "legacy_subscriptions" (
"email" text PRIMARY KEY NOT NULL,
"stripe_coupon_id" text NOT NULL,
"stripe_promotion_code_id" text NOT NULL,
"stripe_promotion_code" text NOT NULL,
"redeem_at" timestamp with time zone,
"redeem_by" timestamp with time zone
);
--> statement-breakpoint
ALTER TABLE "legacy_subscriptions" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "deployments" ADD COLUMN "build_script" text;--> statement-breakpoint
ALTER TABLE "deployments" ADD COLUMN "build_flags" text;--> statement-breakpoint
ALTER TABLE "deployments" ADD COLUMN "env_vars" jsonb;
================================================
FILE: apps/backend/supabase/migrations/0016_pretty_dust.sql
================================================
CREATE TABLE "rate_limits" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"subscription_id" uuid NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"started_at" timestamp with time zone NOT NULL,
"ended_at" timestamp with time zone NOT NULL,
"max" integer NOT NULL,
"left" integer DEFAULT 0 NOT NULL,
"carry_over_key" uuid NOT NULL,
"carry_over_total" integer DEFAULT 0 NOT NULL,
"stripe_subscription_item_id" text NOT NULL
);
--> statement-breakpoint
ALTER TABLE "rate_limits" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "messages" ALTER COLUMN "applied" DROP DEFAULT;--> statement-breakpoint
ALTER TABLE "messages" ALTER COLUMN "applied" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "messages" ALTER COLUMN "snapshots" DROP DEFAULT;--> statement-breakpoint
ALTER TABLE "messages" ALTER COLUMN "snapshots" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "conversations" ADD COLUMN "suggestions" jsonb DEFAULT '[]'::jsonb;--> statement-breakpoint
ALTER TABLE "messages" ADD COLUMN "checkpoints" jsonb DEFAULT '[]'::jsonb NOT NULL;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD COLUMN "stripe_current_period_start" timestamp with time zone NOT NULL;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD COLUMN "stripe_current_period_end" timestamp with time zone NOT NULL;--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "stripe_customer_id" text;--> statement-breakpoint
ALTER TABLE "rate_limits" ADD CONSTRAINT "rate_limits_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "rate_limits" ADD CONSTRAINT "rate_limits_subscription_id_subscriptions_id_fk" FOREIGN KEY ("subscription_id") REFERENCES "public"."subscriptions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "rate_limits_user_time_idx" ON "rate_limits" USING btree ("user_id","started_at","ended_at");--> statement-breakpoint
CREATE INDEX "usage_records_user_time_idx" ON "usage_records" USING btree ("user_id","timestamp");--> statement-breakpoint
================================================
FILE: apps/backend/supabase/migrations/0017_small_xavin.sql
================================================
--> statement-breakpoint
CREATE TABLE "feedbacks" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid,
"email" text,
"message" text NOT NULL,
"page_url" text,
"user_agent" text,
"attachments" jsonb DEFAULT '[]'::jsonb NOT NULL,
"metadata" jsonb DEFAULT '{}'::jsonb NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "feedbacks" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "project_invitations" DROP CONSTRAINT "project_invitations_invitee_email_project_id_unique";--> statement-breakpoint
ALTER TABLE "custom_domain_verification" DROP CONSTRAINT "custom_domain_verification_project_id_projects_id_fk";
--> statement-breakpoint
ALTER TABLE "preview_domains" DROP CONSTRAINT "preview_domains_project_id_projects_id_fk";
--> statement-breakpoint
ALTER TABLE "deployments" DROP CONSTRAINT "deployments_project_id_projects_id_fk";
--> statement-breakpoint
ALTER TABLE "projects" ADD COLUMN "tags" varchar[] DEFAULT '{}';--> statement-breakpoint
ALTER TABLE "projects" ADD COLUMN "updated_preview_img_at" timestamp with time zone;--> statement-breakpoint
ALTER TABLE "feedbacks" ADD CONSTRAINT "feedbacks_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "custom_domain_verification" ADD CONSTRAINT "custom_domain_verification_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "preview_domains" ADD CONSTRAINT "preview_domains_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "deployments" ADD CONSTRAINT "deployments_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
CREATE INDEX "project_invitations_invitee_email_project_id_idx" ON "project_invitations" USING btree ("invitee_email","project_id");
================================================
FILE: apps/backend/supabase/migrations/0018_lush_thanos.sql
================================================
CREATE TABLE "branches" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"project_id" uuid NOT NULL,
"name" varchar NOT NULL,
"description" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
"is_default" boolean DEFAULT false NOT NULL,
"git_branch" varchar,
"git_commit_sha" varchar,
"git_repo_url" varchar,
"sandbox_id" varchar NOT NULL
);
--> statement-breakpoint
ALTER TABLE "branches" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
ALTER TABLE "frames" ALTER COLUMN "type" SET DATA TYPE text;--> statement-breakpoint
ALTER TABLE "frames" ALTER COLUMN "type" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "projects" ALTER COLUMN "sandbox_id" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "projects" ALTER COLUMN "sandbox_url" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "frames" ADD COLUMN "branch_id" uuid;--> statement-breakpoint
ALTER TABLE "usage_records" ADD COLUMN "trace_id" varchar(255);--> statement-breakpoint
ALTER TABLE "branches" ADD CONSTRAINT "branches_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
CREATE INDEX "branches_project_id_idx" ON "branches" USING btree ("project_id");--> statement-breakpoint
CREATE UNIQUE INDEX "branches_name_per_project_ux" ON "branches" USING btree ("project_id","name");--> statement-breakpoint
CREATE UNIQUE INDEX "branches_default_per_project_ux" ON "branches" USING btree ("project_id") WHERE "branches"."is_default" = true;--> statement-breakpoint
ALTER TABLE "frames" ADD CONSTRAINT "frames_branch_id_branches_id_fk" FOREIGN KEY ("branch_id") REFERENCES "public"."branches"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
ALTER TABLE "usage_records" ADD CONSTRAINT "usage_records_user_trace_idx" UNIQUE("user_id","trace_id");--> statement-breakpoint
DROP TYPE "public"."frame_type";
================================================
FILE: apps/backend/supabase/migrations/0019_abandoned_psylocke.sql
================================================
ALTER TYPE "public"."message_role" ADD VALUE 'system';--> statement-breakpoint
ALTER TABLE "users" ADD COLUMN "github_installation_id" text;
================================================
FILE: apps/backend/supabase/migrations/meta/0000_snapshot.json
================================================
{
"id": "95612ed1-7374-41c8-8f07-1ee3b064226b",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"scale": {
"name": "scale",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"conversations_project_id_projects_id_fk": {
"name": "conversations_project_id_projects_id_fk",
"tableFrom": "conversations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.messages": {
"name": "messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"role": {
"name": "role",
"type": "role",
"primaryKey": false,
"notNull": true
},
"applied": {
"name": "applied",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"snapshots": {
"name": "snapshots",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"context": {
"name": "context",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"parts": {
"name": "parts",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
}
},
"indexes": {},
"foreignKeys": {
"messages_conversation_id_conversations_id_fk": {
"name": "messages_conversation_id_conversations_id_fk",
"tableFrom": "messages",
"tableTo": "conversations",
"columnsFrom": [
"conversation_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_id": {
"name": "sandbox_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_url": {
"name": "sandbox_url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"preview_img": {
"name": "preview_img",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"users_id_users_id_fk": {
"name": "users_id_users_id_fk",
"tableFrom": "users",
"tableTo": "users",
"schemaTo": "auth",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_projects": {
"name": "user_projects",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"user_projects_user_id_users_id_fk": {
"name": "user_projects_user_id_users_id_fk",
"tableFrom": "user_projects",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_projects_project_id_projects_id_fk": {
"name": "user_projects_project_id_projects_id_fk",
"tableFrom": "user_projects",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_projects_user_id_project_id_pk": {
"name": "user_projects_user_id_project_id_pk",
"columns": [
"user_id",
"project_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
}
},
"enums": {
"public.frame_type": {
"name": "frame_type",
"schema": "public",
"values": [
"web"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"user",
"assistant",
"system"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
================================================
FILE: apps/backend/supabase/migrations/meta/0001_snapshot.json
================================================
{
"id": "7fab2c6f-cf80-420e-bad4-3d6065d58b9c",
"prevId": "95612ed1-7374-41c8-8f07-1ee3b064226b",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"scale": {
"name": "scale",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"conversations_project_id_projects_id_fk": {
"name": "conversations_project_id_projects_id_fk",
"tableFrom": "conversations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.messages": {
"name": "messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"role": {
"name": "role",
"type": "role",
"primaryKey": false,
"notNull": true
},
"applied": {
"name": "applied",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"snapshots": {
"name": "snapshots",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"context": {
"name": "context",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"parts": {
"name": "parts",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
}
},
"indexes": {},
"foreignKeys": {
"messages_conversation_id_conversations_id_fk": {
"name": "messages_conversation_id_conversations_id_fk",
"tableFrom": "messages",
"tableTo": "conversations",
"columnsFrom": [
"conversation_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_id": {
"name": "sandbox_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_url": {
"name": "sandbox_url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"preview_img": {
"name": "preview_img",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"users_id_users_id_fk": {
"name": "users_id_users_id_fk",
"tableFrom": "users",
"tableTo": "users",
"schemaTo": "auth",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_projects": {
"name": "user_projects",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"user_projects_user_id_users_id_fk": {
"name": "user_projects_user_id_users_id_fk",
"tableFrom": "user_projects",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_projects_project_id_projects_id_fk": {
"name": "user_projects_project_id_projects_id_fk",
"tableFrom": "user_projects",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_projects_user_id_project_id_pk": {
"name": "user_projects_user_id_project_id_pk",
"columns": [
"user_id",
"project_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
}
},
"enums": {
"public.frame_type": {
"name": "frame_type",
"schema": "public",
"values": [
"web"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"user",
"assistant",
"system"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
================================================
FILE: apps/backend/supabase/migrations/meta/0002_snapshot.json
================================================
{
"id": "cf650e40-2b28-43b0-bfcd-fdd3603f7f88",
"prevId": "7fab2c6f-cf80-420e-bad4-3d6065d58b9c",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"scale": {
"name": "scale",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"conversations_project_id_projects_id_fk": {
"name": "conversations_project_id_projects_id_fk",
"tableFrom": "conversations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.messages": {
"name": "messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"role": {
"name": "role",
"type": "role",
"primaryKey": false,
"notNull": true
},
"applied": {
"name": "applied",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"snapshots": {
"name": "snapshots",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"context": {
"name": "context",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"parts": {
"name": "parts",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
}
},
"indexes": {},
"foreignKeys": {
"messages_conversation_id_conversations_id_fk": {
"name": "messages_conversation_id_conversations_id_fk",
"tableFrom": "messages",
"tableTo": "conversations",
"columnsFrom": [
"conversation_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_id": {
"name": "sandbox_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_url": {
"name": "sandbox_url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"preview_img": {
"name": "preview_img",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_settings": {
"name": "user_settings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"auto_apply_code": {
"name": "auto_apply_code",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"expand_code_blocks": {
"name": "expand_code_blocks",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_suggestions": {
"name": "show_suggestions",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_mini_chat": {
"name": "show_mini_chat",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
}
},
"indexes": {},
"foreignKeys": {
"user_settings_user_id_users_id_fk": {
"name": "user_settings_user_id_users_id_fk",
"tableFrom": "user_settings",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"user_settings_user_id_unique": {
"name": "user_settings_user_id_unique",
"nullsNotDistinct": false,
"columns": [
"user_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"users_id_users_id_fk": {
"name": "users_id_users_id_fk",
"tableFrom": "users",
"tableTo": "users",
"schemaTo": "auth",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_projects": {
"name": "user_projects",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"user_projects_user_id_users_id_fk": {
"name": "user_projects_user_id_users_id_fk",
"tableFrom": "user_projects",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_projects_project_id_projects_id_fk": {
"name": "user_projects_project_id_projects_id_fk",
"tableFrom": "user_projects",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_projects_user_id_project_id_pk": {
"name": "user_projects_user_id_project_id_pk",
"columns": [
"user_id",
"project_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
}
},
"enums": {
"public.frame_type": {
"name": "frame_type",
"schema": "public",
"values": [
"web"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"user",
"assistant",
"system"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
================================================
FILE: apps/backend/supabase/migrations/meta/0003_snapshot.json
================================================
{
"id": "518e58bf-052b-4c2c-8095-3fa357233432",
"prevId": "cf650e40-2b28-43b0-bfcd-fdd3603f7f88",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"conversations_project_id_projects_id_fk": {
"name": "conversations_project_id_projects_id_fk",
"tableFrom": "conversations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.messages": {
"name": "messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"role": {
"name": "role",
"type": "role",
"primaryKey": false,
"notNull": true
},
"applied": {
"name": "applied",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"snapshots": {
"name": "snapshots",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"context": {
"name": "context",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"parts": {
"name": "parts",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
}
},
"indexes": {},
"foreignKeys": {
"messages_conversation_id_conversations_id_fk": {
"name": "messages_conversation_id_conversations_id_fk",
"tableFrom": "messages",
"tableTo": "conversations",
"columnsFrom": [
"conversation_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_id": {
"name": "sandbox_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_url": {
"name": "sandbox_url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"preview_img": {
"name": "preview_img",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_settings": {
"name": "user_settings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"auto_apply_code": {
"name": "auto_apply_code",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"expand_code_blocks": {
"name": "expand_code_blocks",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_suggestions": {
"name": "show_suggestions",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_mini_chat": {
"name": "show_mini_chat",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
}
},
"indexes": {},
"foreignKeys": {
"user_settings_user_id_users_id_fk": {
"name": "user_settings_user_id_users_id_fk",
"tableFrom": "user_settings",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"user_settings_user_id_unique": {
"name": "user_settings_user_id_unique",
"nullsNotDistinct": false,
"columns": [
"user_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"users_id_users_id_fk": {
"name": "users_id_users_id_fk",
"tableFrom": "users",
"tableTo": "users",
"schemaTo": "auth",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_canvases": {
"name": "user_canvases",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"scale": {
"name": "scale",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"user_canvases_user_id_users_id_fk": {
"name": "user_canvases_user_id_users_id_fk",
"tableFrom": "user_canvases",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_canvases_canvas_id_canvas_id_fk": {
"name": "user_canvases_canvas_id_canvas_id_fk",
"tableFrom": "user_canvases",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_canvases_user_id_canvas_id_pk": {
"name": "user_canvases_user_id_canvas_id_pk",
"columns": [
"user_id",
"canvas_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_projects": {
"name": "user_projects",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"user_projects_user_id_users_id_fk": {
"name": "user_projects_user_id_users_id_fk",
"tableFrom": "user_projects",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_projects_project_id_projects_id_fk": {
"name": "user_projects_project_id_projects_id_fk",
"tableFrom": "user_projects",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_projects_user_id_project_id_pk": {
"name": "user_projects_user_id_project_id_pk",
"columns": [
"user_id",
"project_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
}
},
"enums": {
"public.frame_type": {
"name": "frame_type",
"schema": "public",
"values": [
"web"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"user",
"assistant",
"system"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
================================================
FILE: apps/backend/supabase/migrations/meta/0004_snapshot.json
================================================
{
"id": "6187c007-6c6d-4e4f-af6e-a232e3cd5cf6",
"prevId": "518e58bf-052b-4c2c-8095-3fa357233432",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"conversations_project_id_projects_id_fk": {
"name": "conversations_project_id_projects_id_fk",
"tableFrom": "conversations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.messages": {
"name": "messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"role": {
"name": "role",
"type": "role",
"primaryKey": false,
"notNull": true
},
"applied": {
"name": "applied",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"snapshots": {
"name": "snapshots",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"context": {
"name": "context",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"parts": {
"name": "parts",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
}
},
"indexes": {},
"foreignKeys": {
"messages_conversation_id_conversations_id_fk": {
"name": "messages_conversation_id_conversations_id_fk",
"tableFrom": "messages",
"tableTo": "conversations",
"columnsFrom": [
"conversation_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.project_invitations": {
"name": "project_invitations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"inviter_id": {
"name": "inviter_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"invitee_email": {
"name": "invitee_email",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "invitation_status",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"token": {
"name": "token",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "project_role",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"project_invitations_project_id_projects_id_fk": {
"name": "project_invitations_project_id_projects_id_fk",
"tableFrom": "project_invitations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"project_invitations_inviter_id_users_id_fk": {
"name": "project_invitations_inviter_id_users_id_fk",
"tableFrom": "project_invitations",
"tableTo": "users",
"columnsFrom": [
"inviter_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"project_invitations_token_unique": {
"name": "project_invitations_token_unique",
"nullsNotDistinct": false,
"columns": [
"token"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_id": {
"name": "sandbox_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_url": {
"name": "sandbox_url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"preview_img": {
"name": "preview_img",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_settings": {
"name": "user_settings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"auto_apply_code": {
"name": "auto_apply_code",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"expand_code_blocks": {
"name": "expand_code_blocks",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_suggestions": {
"name": "show_suggestions",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_mini_chat": {
"name": "show_mini_chat",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
}
},
"indexes": {},
"foreignKeys": {
"user_settings_user_id_users_id_fk": {
"name": "user_settings_user_id_users_id_fk",
"tableFrom": "user_settings",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"user_settings_user_id_unique": {
"name": "user_settings_user_id_unique",
"nullsNotDistinct": false,
"columns": [
"user_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"users_id_users_id_fk": {
"name": "users_id_users_id_fk",
"tableFrom": "users",
"tableTo": "users",
"schemaTo": "auth",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_canvases": {
"name": "user_canvases",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"scale": {
"name": "scale",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"user_canvases_user_id_users_id_fk": {
"name": "user_canvases_user_id_users_id_fk",
"tableFrom": "user_canvases",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_canvases_canvas_id_canvas_id_fk": {
"name": "user_canvases_canvas_id_canvas_id_fk",
"tableFrom": "user_canvases",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_canvases_user_id_canvas_id_pk": {
"name": "user_canvases_user_id_canvas_id_pk",
"columns": [
"user_id",
"canvas_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_projects": {
"name": "user_projects",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false,
"default": "now()"
},
"role": {
"name": "role",
"type": "project_role",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"user_projects_user_id_users_id_fk": {
"name": "user_projects_user_id_users_id_fk",
"tableFrom": "user_projects",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_projects_project_id_projects_id_fk": {
"name": "user_projects_project_id_projects_id_fk",
"tableFrom": "user_projects",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_projects_user_id_project_id_pk": {
"name": "user_projects_user_id_project_id_pk",
"columns": [
"user_id",
"project_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
}
},
"enums": {
"public.frame_type": {
"name": "frame_type",
"schema": "public",
"values": [
"web"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"user",
"assistant",
"system"
]
},
"public.invitation_status": {
"name": "invitation_status",
"schema": "public",
"values": [
"pending",
"accepted",
"expired"
]
},
"public.project_role": {
"name": "project_role",
"schema": "public",
"values": [
"owner",
"admin"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
================================================
FILE: apps/backend/supabase/migrations/meta/0005_snapshot.json
================================================
{
"id": "3d0069f3-846f-40fb-903d-6e3375df0e77",
"prevId": "6187c007-6c6d-4e4f-af6e-a232e3cd5cf6",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"conversations_project_id_projects_id_fk": {
"name": "conversations_project_id_projects_id_fk",
"tableFrom": "conversations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.messages": {
"name": "messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"role": {
"name": "role",
"type": "role",
"primaryKey": false,
"notNull": true
},
"applied": {
"name": "applied",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"snapshots": {
"name": "snapshots",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"context": {
"name": "context",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"parts": {
"name": "parts",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
}
},
"indexes": {},
"foreignKeys": {
"messages_conversation_id_conversations_id_fk": {
"name": "messages_conversation_id_conversations_id_fk",
"tableFrom": "messages",
"tableTo": "conversations",
"columnsFrom": [
"conversation_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.project_invitations": {
"name": "project_invitations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"inviter_id": {
"name": "inviter_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"invitee_email": {
"name": "invitee_email",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"token": {
"name": "token",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "project_role",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"project_invitations_project_id_projects_id_fk": {
"name": "project_invitations_project_id_projects_id_fk",
"tableFrom": "project_invitations",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"project_invitations_inviter_id_users_id_fk": {
"name": "project_invitations_inviter_id_users_id_fk",
"tableFrom": "project_invitations",
"tableTo": "users",
"columnsFrom": [
"inviter_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"project_invitations_token_unique": {
"name": "project_invitations_token_unique",
"nullsNotDistinct": false,
"columns": [
"token"
]
},
"project_invitations_invitee_email_project_id_unique": {
"name": "project_invitations_invitee_email_project_id_unique",
"nullsNotDistinct": false,
"columns": [
"invitee_email",
"project_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_id": {
"name": "sandbox_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"sandbox_url": {
"name": "sandbox_url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"preview_img": {
"name": "preview_img",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"auth.users": {
"name": "users",
"schema": "auth",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email_confirmed_at": {
"name": "email_confirmed_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"raw_user_meta_data": {
"name": "raw_user_meta_data",
"type": "jsonb",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user_settings": {
"name": "user_settings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"auto_apply_code": {
"name": "auto_apply_code",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"expand_code_blocks": {
"name": "expand_code_blocks",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_suggestions": {
"name": "show_suggestions",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"show_mini_chat": {
"name": "show_mini_chat",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
}
},
"indexes": {},
"foreignKeys": {
"user_settings_user_id_users_id_fk": {
"name": "user_settings_user_id_users_id_fk",
"tableFrom": "user_settings",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"user_settings_user_id_unique": {
"name": "user_settings_user_id_unique",
"nullsNotDistinct": false,
"columns": [
"user_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"users_id_users_id_fk": {
"name": "users_id_users_id_fk",
"tableFrom": "users",
"tableTo": "users",
"schemaTo": "auth",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_canvases": {
"name": "user_canvases",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"scale": {
"name": "scale",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"user_canvases_user_id_users_id_fk": {
"name": "user_canvases_user_id_users_id_fk",
"tableFrom": "user_canvases",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_canvases_canvas_id_canvas_id_fk": {
"name": "user_canvases_canvas_id_canvas_id_fk",
"tableFrom": "user_canvases",
"tableTo": "canvas",
"columnsFrom": [
"canvas_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_canvases_user_id_canvas_id_pk": {
"name": "user_canvases_user_id_canvas_id_pk",
"columns": [
"user_id",
"canvas_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.user_projects": {
"name": "user_projects",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false,
"default": "now()"
},
"role": {
"name": "role",
"type": "project_role",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"user_projects_user_id_users_id_fk": {
"name": "user_projects_user_id_users_id_fk",
"tableFrom": "user_projects",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
},
"user_projects_project_id_projects_id_fk": {
"name": "user_projects_project_id_projects_id_fk",
"tableFrom": "user_projects",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {
"user_projects_user_id_project_id_pk": {
"name": "user_projects_user_id_project_id_pk",
"columns": [
"user_id",
"project_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
}
},
"enums": {
"public.frame_type": {
"name": "frame_type",
"schema": "public",
"values": [
"web"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"user",
"assistant",
"system"
]
},
"public.project_role": {
"name": "project_role",
"schema": "public",
"values": [
"owner",
"admin"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
================================================
FILE: apps/backend/supabase/migrations/meta/0006_snapshot.json
================================================
{
"id": "28cb89f1-cebc-487a-84e2-0341168df378",
"prevId": "3d0069f3-846f-40fb-903d-6e3375df0e77",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.canvas": {
"name": "canvas",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"canvas_project_id_projects_id_fk": {
"name": "canvas_project_id_projects_id_fk",
"tableFrom": "canvas",
"columnsFrom": [
"project_id"
],
"tableTo": "projects",
"columnsTo": [
"id"
],
"onUpdate": "cascade",
"onDelete": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.frames": {
"name": "frames",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"canvas_id": {
"name": "canvas_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "frame_type",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"x": {
"name": "x",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"y": {
"name": "y",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": true
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"frames_canvas_id_canvas_id_fk": {
"name": "frames_canvas_id_canvas_id_fk",
"tableFrom": "frames",
"columnsFrom": [
"canvas_id"
],
"tableTo": "canvas",
"columnsTo": [
"id"
],
"onUpdate": "cascade",
"onDelete": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": true
},
"public.conversations": {
"name": "conversations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated
gitextract_tfg2fxbz/
├── .dockerignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── help_wanted.md
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── chromatic.yml
│ ├── ci.yml
│ └── supabase-push-staging.yml
├── .gitignore
├── .gitmodules
├── .prettierignore
├── .vscode/
│ ├── .debug.script.mjs
│ ├── extensions.json
│ ├── launch.json
│ └── tasks.json
├── AGENTS.md
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.md
├── README.md
├── SECURITY.md
├── apps/
│ ├── backend/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── supabase/
│ │ │ ├── .gitignore
│ │ │ ├── config.toml
│ │ │ └── migrations/
│ │ │ ├── 0000_same_human_robot.sql
│ │ │ ├── 0001_graceful_exodus.sql
│ │ │ ├── 0002_red_crusher_hogan.sql
│ │ │ ├── 0003_loud_ozymandias.sql
│ │ │ ├── 0004_pink_expediter.sql
│ │ │ ├── 0005_short_lila_cheney.sql
│ │ │ ├── 0006_rls.sql
│ │ │ ├── 0007_realtime_rls.sql
│ │ │ ├── 0008_preview-img-storage.sql
│ │ │ ├── 0009_project_img_path.sql
│ │ │ ├── 0010_bent_edwin_jarvis.sql
│ │ │ ├── 0011_typical_clea.sql
│ │ │ ├── 0012_file-transfer-bucket.sql
│ │ │ ├── 0013_aspiring_kabuki.sql
│ │ │ ├── 0014_military_marrow.sql
│ │ │ ├── 0015_same_leo.sql
│ │ │ ├── 0016_pretty_dust.sql
│ │ │ ├── 0017_small_xavin.sql
│ │ │ ├── 0018_lush_thanos.sql
│ │ │ ├── 0019_abandoned_psylocke.sql
│ │ │ └── meta/
│ │ │ ├── 0000_snapshot.json
│ │ │ ├── 0001_snapshot.json
│ │ │ ├── 0002_snapshot.json
│ │ │ ├── 0003_snapshot.json
│ │ │ ├── 0004_snapshot.json
│ │ │ ├── 0005_snapshot.json
│ │ │ ├── 0006_snapshot.json
│ │ │ ├── 0007_snapshot.json
│ │ │ ├── 0008_snapshot.json
│ │ │ ├── 0009_snapshot.json
│ │ │ ├── 0010_snapshot.json
│ │ │ ├── 0011_snapshot.json
│ │ │ ├── 0012_snapshot.json
│ │ │ ├── 0013_snapshot.json
│ │ │ ├── 0014_snapshot.json
│ │ │ ├── 0015_snapshot.json
│ │ │ ├── 0016_snapshot.json
│ │ │ ├── 0017_snapshot.json
│ │ │ ├── 0018_snapshot.json
│ │ │ ├── 0019_snapshot.json
│ │ │ └── _journal.json
│ │ └── tsconfig.json
│ └── web/
│ ├── .gitignore
│ ├── README.md
│ ├── client/
│ │ ├── .gitignore
│ │ ├── .storybook/
│ │ │ ├── main.ts
│ │ │ ├── mocks/
│ │ │ │ ├── supabase-client.ts
│ │ │ │ └── trpc-react.tsx
│ │ │ ├── preview-head.html
│ │ │ ├── preview.tsx
│ │ │ └── vitest.setup.ts
│ │ ├── README.md
│ │ ├── chromatic.config.json
│ │ ├── components.json
│ │ ├── eslint.config.js
│ │ ├── messages/
│ │ │ ├── en.d.json.ts
│ │ │ ├── en.json
│ │ │ ├── es.json
│ │ │ ├── ja.json
│ │ │ ├── ko.json
│ │ │ └── zh.json
│ │ ├── next.config.ts
│ │ ├── package.json
│ │ ├── postcss.config.js
│ │ ├── public/
│ │ │ ├── onlook-preload-script.js
│ │ │ └── scenes/
│ │ │ └── flow-background.json
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── _components/
│ │ │ │ │ ├── auth-modal.tsx
│ │ │ │ │ ├── button-link.tsx
│ │ │ │ │ ├── hero/
│ │ │ │ │ │ ├── ai-features-hero.tsx
│ │ │ │ │ │ ├── ai-frontend-hero.tsx
│ │ │ │ │ │ ├── builder-features-hero.tsx
│ │ │ │ │ │ ├── claude-code-hero.tsx
│ │ │ │ │ │ ├── create-error.tsx
│ │ │ │ │ │ ├── create.tsx
│ │ │ │ │ │ ├── features-hero.tsx
│ │ │ │ │ │ ├── high-demand.tsx
│ │ │ │ │ │ ├── import.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── mobile-email-capture.tsx
│ │ │ │ │ │ ├── start-blank.tsx
│ │ │ │ │ │ └── unicorn-background.tsx
│ │ │ │ │ ├── landing-page/
│ │ │ │ │ │ ├── ai-benefits-section.tsx
│ │ │ │ │ │ ├── ai-features-grid-section.tsx
│ │ │ │ │ │ ├── ai-features-intro-section.tsx
│ │ │ │ │ │ ├── benefits-section.tsx
│ │ │ │ │ │ ├── builder-benefits-section.tsx
│ │ │ │ │ │ ├── builder-features-grid-section.tsx
│ │ │ │ │ │ ├── builder-features-intro-section.tsx
│ │ │ │ │ │ ├── code-one-to-one-section.tsx
│ │ │ │ │ │ ├── color-swatch-group.tsx
│ │ │ │ │ │ ├── contributor-section.tsx
│ │ │ │ │ │ ├── contributor.css
│ │ │ │ │ │ ├── cta-section.tsx
│ │ │ │ │ │ ├── design-mockup/
│ │ │ │ │ │ │ ├── design-mockup-icons.tsx
│ │ │ │ │ │ │ └── design-mockup.tsx
│ │ │ │ │ │ ├── faq-dropdown.tsx
│ │ │ │ │ │ ├── faq-section.tsx
│ │ │ │ │ │ ├── feature-blocks/
│ │ │ │ │ │ │ ├── ai-chat-preview-block.tsx
│ │ │ │ │ │ │ ├── brand-compliance.tsx
│ │ │ │ │ │ │ ├── components.tsx
│ │ │ │ │ │ │ ├── direct-editing.tsx
│ │ │ │ │ │ │ ├── layers.tsx
│ │ │ │ │ │ │ ├── responsive-website.tsx
│ │ │ │ │ │ │ └── revision-history.tsx
│ │ │ │ │ │ ├── features-grid-section.tsx
│ │ │ │ │ │ ├── features-intro-section.tsx
│ │ │ │ │ │ ├── illustrations.tsx
│ │ │ │ │ │ ├── obsess-for-hours-section.tsx
│ │ │ │ │ │ ├── onlook-interface-mockup.tsx
│ │ │ │ │ │ ├── page-footer.tsx
│ │ │ │ │ │ ├── responsive-mockup-section.tsx
│ │ │ │ │ │ ├── social-proof-section.tsx
│ │ │ │ │ │ ├── testimonials-section.tsx
│ │ │ │ │ │ └── what-can-onlook-do-section.tsx
│ │ │ │ │ ├── login-button.tsx
│ │ │ │ │ ├── shared/
│ │ │ │ │ │ └── mockups/
│ │ │ │ │ │ ├── ai-chat-interactive.tsx
│ │ │ │ │ │ ├── components-mockup.tsx
│ │ │ │ │ │ ├── direct-editing-interactive.tsx
│ │ │ │ │ │ └── tailwind-color-editor.tsx
│ │ │ │ │ ├── theme.tsx
│ │ │ │ │ ├── top-bar/
│ │ │ │ │ │ ├── github.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── mega-menu.tsx
│ │ │ │ │ │ ├── mobile-menu.tsx
│ │ │ │ │ │ └── user.tsx
│ │ │ │ │ └── website-layout.tsx
│ │ │ │ ├── about/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── api/
│ │ │ │ │ ├── chat/
│ │ │ │ │ │ ├── helpers/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── stream.ts
│ │ │ │ │ │ │ └── usage.ts
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── email-capture/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── trpc/
│ │ │ │ │ └── [trpc]/
│ │ │ │ │ └── route.ts
│ │ │ │ ├── auth/
│ │ │ │ │ ├── auth-context.tsx
│ │ │ │ │ ├── callback/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── redirect/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── callback/
│ │ │ │ │ ├── github/
│ │ │ │ │ │ └── install/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── stripe/
│ │ │ │ │ ├── cancel/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── message-screen.tsx
│ │ │ │ │ └── success/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── faq/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── features/
│ │ │ │ │ ├── ai/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── ai-for-frontend/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── builder/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── prototype/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── fonts.ts
│ │ │ │ ├── invitation/
│ │ │ │ │ └── [id]/
│ │ │ │ │ ├── _components/
│ │ │ │ │ │ ├── auth.tsx
│ │ │ │ │ │ └── main.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── login/
│ │ │ │ │ ├── actions.tsx
│ │ │ │ │ ├── error.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── not-found.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── pricing/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── privacy-policy/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── project/
│ │ │ │ │ ├── [id]/
│ │ │ │ │ │ ├── _components/
│ │ │ │ │ │ │ ├── bottom-bar/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── restart-sandbox-button.tsx
│ │ │ │ │ │ │ │ ├── terminal-area.tsx
│ │ │ │ │ │ │ │ └── terminal.tsx
│ │ │ │ │ │ │ ├── branch/
│ │ │ │ │ │ │ │ ├── branch-controls.tsx
│ │ │ │ │ │ │ │ └── branch-list.tsx
│ │ │ │ │ │ │ ├── canvas/
│ │ │ │ │ │ │ │ ├── frame/
│ │ │ │ │ │ │ │ │ ├── gesture.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── resize-handles.tsx
│ │ │ │ │ │ │ │ │ ├── top-bar/
│ │ │ │ │ │ │ │ │ │ ├── branch.tsx
│ │ │ │ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── page-selector.tsx
│ │ │ │ │ │ │ │ │ ├── use-frame-reload.ts
│ │ │ │ │ │ │ │ │ ├── use-sandbox-timeout.ts
│ │ │ │ │ │ │ │ │ └── view.tsx
│ │ │ │ │ │ │ │ ├── frames.tsx
│ │ │ │ │ │ │ │ ├── hotkeys/
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── overlay/
│ │ │ │ │ │ │ │ │ ├── drag-select.tsx
│ │ │ │ │ │ │ │ │ ├── elements/
│ │ │ │ │ │ │ │ │ │ ├── buttons/
│ │ │ │ │ │ │ │ │ │ │ ├── chat.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── code.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── measurement.tsx
│ │ │ │ │ │ │ │ │ │ ├── rect/
│ │ │ │ │ │ │ │ │ │ │ ├── base.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── click.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── hover.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── insert.tsx
│ │ │ │ │ │ │ │ │ │ │ └── resize.tsx
│ │ │ │ │ │ │ │ │ │ ├── snap-guidelines.tsx
│ │ │ │ │ │ │ │ │ │ └── text.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ └── pan.tsx
│ │ │ │ │ │ │ │ ├── recenter-canvas-button.tsx
│ │ │ │ │ │ │ │ └── selection-utils.ts
│ │ │ │ │ │ │ ├── clone-project-dialog.tsx
│ │ │ │ │ │ │ ├── editor-bar/
│ │ │ │ │ │ │ │ ├── div-selected.tsx
│ │ │ │ │ │ │ │ ├── dropdowns/
│ │ │ │ │ │ │ │ │ ├── border-color.tsx
│ │ │ │ │ │ │ │ │ ├── border.tsx
│ │ │ │ │ │ │ │ │ ├── color-background.tsx
│ │ │ │ │ │ │ │ │ ├── display/
│ │ │ │ │ │ │ │ │ │ ├── direction.tsx
│ │ │ │ │ │ │ │ │ │ ├── gap.tsx
│ │ │ │ │ │ │ │ │ │ ├── horizontal-align.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── type.tsx
│ │ │ │ │ │ │ │ │ │ └── vertical-align.tsx
│ │ │ │ │ │ │ │ │ ├── height.tsx
│ │ │ │ │ │ │ │ │ ├── img-background.tsx
│ │ │ │ │ │ │ │ │ ├── img-fit.tsx
│ │ │ │ │ │ │ │ │ ├── margin.tsx
│ │ │ │ │ │ │ │ │ ├── opacity.tsx
│ │ │ │ │ │ │ │ │ ├── padding.tsx
│ │ │ │ │ │ │ │ │ ├── radius.tsx
│ │ │ │ │ │ │ │ │ ├── state-dropdown.tsx
│ │ │ │ │ │ │ │ │ └── width.tsx
│ │ │ │ │ │ │ │ ├── frame-selected/
│ │ │ │ │ │ │ │ │ ├── device-selector.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── rotate-group.tsx
│ │ │ │ │ │ │ │ │ ├── theme-group.tsx
│ │ │ │ │ │ │ │ │ └── window-actions-group.tsx
│ │ │ │ │ │ │ │ ├── hooks/
│ │ │ │ │ │ │ │ │ ├── use-background-image-update.ts
│ │ │ │ │ │ │ │ │ ├── use-box-control.ts
│ │ │ │ │ │ │ │ │ ├── use-color-update.ts
│ │ │ │ │ │ │ │ │ ├── use-dimension-control.ts
│ │ │ │ │ │ │ │ │ ├── use-dropdown-manager.tsx
│ │ │ │ │ │ │ │ │ ├── use-gradient-update.ts
│ │ │ │ │ │ │ │ │ ├── use-input-control.ts
│ │ │ │ │ │ │ │ │ ├── use-measure-group.ts
│ │ │ │ │ │ │ │ │ └── use-text-control.ts
│ │ │ │ │ │ │ │ ├── hover-tooltip.tsx
│ │ │ │ │ │ │ │ ├── img-selected.tsx
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── inputs/
│ │ │ │ │ │ │ │ │ ├── color-picker.tsx
│ │ │ │ │ │ │ │ │ ├── input-color.tsx
│ │ │ │ │ │ │ │ │ ├── input-dropdown.tsx
│ │ │ │ │ │ │ │ │ ├── input-icon.tsx
│ │ │ │ │ │ │ │ │ ├── input-image.tsx
│ │ │ │ │ │ │ │ │ ├── input-radio.tsx
│ │ │ │ │ │ │ │ │ ├── input-range.tsx
│ │ │ │ │ │ │ │ │ └── spacing-inputs.tsx
│ │ │ │ │ │ │ │ ├── overflow-menu.tsx
│ │ │ │ │ │ │ │ ├── separator.tsx
│ │ │ │ │ │ │ │ ├── text-inputs/
│ │ │ │ │ │ │ │ │ ├── advanced-typography.tsx
│ │ │ │ │ │ │ │ │ ├── font/
│ │ │ │ │ │ │ │ │ │ ├── font-family-selector.tsx
│ │ │ │ │ │ │ │ │ │ ├── font-family.tsx
│ │ │ │ │ │ │ │ │ │ ├── font-size.tsx
│ │ │ │ │ │ │ │ │ │ └── font-weight.tsx
│ │ │ │ │ │ │ │ │ ├── text-align.tsx
│ │ │ │ │ │ │ │ │ └── text-color.tsx
│ │ │ │ │ │ │ │ ├── text-selected.tsx
│ │ │ │ │ │ │ │ ├── toolbar-button.tsx
│ │ │ │ │ │ │ │ └── utils/
│ │ │ │ │ │ │ │ └── gradient.ts
│ │ │ │ │ │ │ ├── left-panel/
│ │ │ │ │ │ │ │ ├── code-panel/
│ │ │ │ │ │ │ │ │ ├── code-tab/
│ │ │ │ │ │ │ │ │ │ ├── file-content/
│ │ │ │ │ │ │ │ │ │ │ ├── code-editor.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── code-mirror-config.ts
│ │ │ │ │ │ │ │ │ │ │ ├── floating-add-to-chat-button.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ │ └── unsaved-changes-dialog.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tabs/
│ │ │ │ │ │ │ │ │ │ │ ├── file-tab.tsx
│ │ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── header-controls.tsx
│ │ │ │ │ │ │ │ │ │ ├── hooks/
│ │ │ │ │ │ │ │ │ │ │ └── use-code-navigation.ts
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── modals/
│ │ │ │ │ │ │ │ │ │ │ ├── file-modal.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── folder-modal.tsx
│ │ │ │ │ │ │ │ │ │ │ └── upload-modal.tsx
│ │ │ │ │ │ │ │ │ │ ├── shared/
│ │ │ │ │ │ │ │ │ │ │ ├── file-operations.ts
│ │ │ │ │ │ │ │ │ │ │ ├── file-templates.ts
│ │ │ │ │ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ │ │ │ │ └── sidebar/
│ │ │ │ │ │ │ │ │ │ ├── file-icon.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tree-node.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tree-row.tsx
│ │ │ │ │ │ │ │ │ │ ├── file-tree-search.tsx
│ │ │ │ │ │ │ │ │ │ └── file-tree.tsx
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ ├── design-panel/
│ │ │ │ │ │ │ │ │ ├── branches-tab/
│ │ │ │ │ │ │ │ │ │ ├── branch-management.tsx
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── brand-tab/
│ │ │ │ │ │ │ │ │ │ ├── color-panel/
│ │ │ │ │ │ │ │ │ │ │ ├── color-name-input.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── color-pallet-group.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── color-popover.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── color-row.tsx
│ │ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── font-panel/
│ │ │ │ │ │ │ │ │ │ │ ├── font-family.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── font-files.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── system-font.tsx
│ │ │ │ │ │ │ │ │ │ │ └── upload-modal.tsx
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── help-button/
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── image-tab/
│ │ │ │ │ │ │ │ │ │ ├── breadcrumb-navigation.tsx
│ │ │ │ │ │ │ │ │ │ ├── folder-list.tsx
│ │ │ │ │ │ │ │ │ │ ├── hooks/
│ │ │ │ │ │ │ │ │ │ │ ├── use-image-drag-drop.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── use-image-operations.tsx
│ │ │ │ │ │ │ │ │ │ │ └── use-navigation.tsx
│ │ │ │ │ │ │ │ │ │ ├── image-grid.tsx
│ │ │ │ │ │ │ │ │ │ ├── image-item.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── search-upload-bar.tsx
│ │ │ │ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ │ │ │ └── utils/
│ │ │ │ │ │ │ │ │ │ ├── image-references.test.ts
│ │ │ │ │ │ │ │ │ │ └── image-references.ts
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── layers-tab/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── tree/
│ │ │ │ │ │ │ │ │ │ ├── page-tree-node.tsx
│ │ │ │ │ │ │ │ │ │ ├── page-tree-row.tsx
│ │ │ │ │ │ │ │ │ │ ├── tree-node.tsx
│ │ │ │ │ │ │ │ │ │ └── tree-row.tsx
│ │ │ │ │ │ │ │ │ ├── page-tab/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── page-modal.tsx
│ │ │ │ │ │ │ │ │ ├── windows-tab/
│ │ │ │ │ │ │ │ │ │ ├── device-settings.tsx
│ │ │ │ │ │ │ │ │ │ ├── frame-dimensions.tsx
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ └── zoom-controls/
│ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── main.tsx
│ │ │ │ │ │ │ ├── members/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ ├── invitation-row.tsx
│ │ │ │ │ │ │ │ ├── invite-member-input.tsx
│ │ │ │ │ │ │ │ ├── member-row.tsx
│ │ │ │ │ │ │ │ ├── members-content.tsx
│ │ │ │ │ │ │ │ └── suggested-teammates.tsx
│ │ │ │ │ │ │ ├── right-click-menu/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── right-panel/
│ │ │ │ │ │ │ │ ├── chat-tab/
│ │ │ │ │ │ │ │ │ ├── chat-input/
│ │ │ │ │ │ │ │ │ │ ├── action-buttons.tsx
│ │ │ │ │ │ │ │ │ │ ├── chat-context.tsx
│ │ │ │ │ │ │ │ │ │ ├── chat-mode-toggle.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── queue-items/
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ └── queue-item.tsx
│ │ │ │ │ │ │ │ │ ├── chat-messages/
│ │ │ │ │ │ │ │ │ │ ├── assistant-message.tsx
│ │ │ │ │ │ │ │ │ │ ├── error-message.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── message-content/
│ │ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ │ ├── tool-call-display.tsx
│ │ │ │ │ │ │ │ │ │ │ └── tool-call-simple.tsx
│ │ │ │ │ │ │ │ │ │ ├── multi-branch-revert-modal.tsx
│ │ │ │ │ │ │ │ │ │ ├── stream-message.tsx
│ │ │ │ │ │ │ │ │ │ └── user-message.tsx
│ │ │ │ │ │ │ │ │ ├── chat-tab-content/
│ │ │ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ │ │ ├── code-display/
│ │ │ │ │ │ │ │ │ │ ├── bash-code-display.tsx
│ │ │ │ │ │ │ │ │ │ ├── code-block.tsx
│ │ │ │ │ │ │ │ │ │ ├── code-diff.tsx
│ │ │ │ │ │ │ │ │ │ ├── collapsible-code-block.tsx
│ │ │ │ │ │ │ │ │ │ └── search-sources-display.tsx
│ │ │ │ │ │ │ │ │ ├── context-pills/
│ │ │ │ │ │ │ │ │ │ ├── draft-context-pill.tsx
│ │ │ │ │ │ │ │ │ │ ├── helpers.tsx
│ │ │ │ │ │ │ │ │ │ ├── image-pill.tsx
│ │ │ │ │ │ │ │ │ │ ├── input-context-pills.tsx
│ │ │ │ │ │ │ │ │ │ └── sent-context-pill.tsx
│ │ │ │ │ │ │ │ │ ├── controls.tsx
│ │ │ │ │ │ │ │ │ ├── error.tsx
│ │ │ │ │ │ │ │ │ ├── history.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── panel-dropdown.tsx
│ │ │ │ │ │ │ │ │ └── suggestions.tsx
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ └── top-bar/
│ │ │ │ │ │ │ ├── branch.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── mode-toggle.tsx
│ │ │ │ │ │ │ ├── new-project-menu.tsx
│ │ │ │ │ │ │ ├── project-breadcrumb.tsx
│ │ │ │ │ │ │ ├── publish/
│ │ │ │ │ │ │ │ ├── dropdown/
│ │ │ │ │ │ │ │ │ ├── advanced-settings.tsx
│ │ │ │ │ │ │ │ │ ├── custom-domain/
│ │ │ │ │ │ │ │ │ │ ├── action.tsx
│ │ │ │ │ │ │ │ │ │ ├── domain.tsx
│ │ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ │ ├── no-domain.tsx
│ │ │ │ │ │ │ │ │ │ └── provider.tsx
│ │ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ │ ├── loading.tsx
│ │ │ │ │ │ │ │ │ ├── preview-domain-section.tsx
│ │ │ │ │ │ │ │ │ └── url.tsx
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ └── trigger-button.tsx
│ │ │ │ │ │ │ └── recent-projects.tsx
│ │ │ │ │ │ ├── _hooks/
│ │ │ │ │ │ │ ├── use-chat/
│ │ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ │ ├── use-panel-measure.tsx
│ │ │ │ │ │ │ ├── use-start-project.tsx
│ │ │ │ │ │ │ └── use-tab-active.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── providers.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── projects/
│ │ │ │ │ ├── _components/
│ │ │ │ │ │ ├── carousel/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── edit-app.tsx
│ │ │ │ │ │ ├── select/
│ │ │ │ │ │ │ ├── highlight-text.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── masonry-layout.tsx
│ │ │ │ │ │ │ ├── project-card-presentation.tsx
│ │ │ │ │ │ │ ├── project-card.tsx
│ │ │ │ │ │ │ ├── square-project-card-presentation.tsx
│ │ │ │ │ │ │ └── square-project-card.tsx
│ │ │ │ │ │ ├── select-presentation.tsx
│ │ │ │ │ │ ├── settings/
│ │ │ │ │ │ │ ├── clone-project.tsx
│ │ │ │ │ │ │ ├── create-template.tsx
│ │ │ │ │ │ │ ├── delete-project.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── rename-project.tsx
│ │ │ │ │ │ ├── templates/
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── lazy-image.tsx
│ │ │ │ │ │ │ ├── template-card.tsx
│ │ │ │ │ │ │ ├── template-modal-presentation.tsx
│ │ │ │ │ │ │ └── template-modal.tsx
│ │ │ │ │ │ ├── top-bar-presentation.tsx
│ │ │ │ │ │ └── top-bar.tsx
│ │ │ │ │ ├── import/
│ │ │ │ │ │ ├── cancel-button.tsx
│ │ │ │ │ │ ├── github/
│ │ │ │ │ │ │ ├── _components/
│ │ │ │ │ │ │ │ ├── connect.tsx
│ │ │ │ │ │ │ │ ├── finalizing.tsx
│ │ │ │ │ │ │ │ └── setup.tsx
│ │ │ │ │ │ │ ├── _context/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── _hooks/
│ │ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ │ ├── use-data.ts
│ │ │ │ │ │ │ │ ├── use-installation.ts
│ │ │ │ │ │ │ │ ├── use-repo-import.ts
│ │ │ │ │ │ │ │ └── use-repo-validation.ts
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── local/
│ │ │ │ │ │ │ ├── _components/
│ │ │ │ │ │ │ │ ├── finalizing-project.tsx
│ │ │ │ │ │ │ │ ├── import-local-project.tsx
│ │ │ │ │ │ │ │ ├── select-folder.tsx
│ │ │ │ │ │ │ │ └── verify-project.tsx
│ │ │ │ │ │ │ ├── _context/
│ │ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── steps.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── types.ts
│ │ │ │ ├── see-a-demo/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── seo.ts
│ │ │ │ ├── site-map/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── sitemap.ts
│ │ │ │ ├── terms-of-service/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── webhook/
│ │ │ │ │ └── stripe/
│ │ │ │ │ ├── route.ts
│ │ │ │ │ └── subscription/
│ │ │ │ │ ├── create.ts
│ │ │ │ │ ├── delete.ts
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── update.ts
│ │ │ │ └── workflows/
│ │ │ │ ├── claude-code/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── vibe-coding/
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── components/
│ │ │ │ ├── hotkey.ts
│ │ │ │ ├── ide.ts
│ │ │ │ ├── rb2b-loader.tsx
│ │ │ │ ├── store/
│ │ │ │ │ ├── create/
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── manager.ts
│ │ │ │ │ ├── editor/
│ │ │ │ │ │ ├── action/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── api/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── ast/
│ │ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── layers.ts
│ │ │ │ │ │ ├── branch/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── manager.ts
│ │ │ │ │ │ ├── cache/
│ │ │ │ │ │ │ ├── file-cache.ts
│ │ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ │ └── unified-cache.ts
│ │ │ │ │ │ ├── canvas/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── chat/
│ │ │ │ │ │ │ ├── context.ts
│ │ │ │ │ │ │ ├── conversation.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── code/
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── insert.ts
│ │ │ │ │ │ │ ├── requests.ts
│ │ │ │ │ │ │ └── tailwind.ts
│ │ │ │ │ │ ├── copy/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── element/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── engine.ts
│ │ │ │ │ │ ├── error/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── font/
│ │ │ │ │ │ │ ├── font-config.ts
│ │ │ │ │ │ │ ├── font-search-manager.ts
│ │ │ │ │ │ │ ├── font-upload-manager.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── layout-manager.ts
│ │ │ │ │ │ │ └── tailwind-config.ts
│ │ │ │ │ │ ├── frame-events/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ │ ├── frames/
│ │ │ │ │ │ │ ├── dimension.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── manager.ts
│ │ │ │ │ │ │ └── navigation.ts
│ │ │ │ │ │ ├── git/
│ │ │ │ │ │ │ ├── git.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── group/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── history/
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── ide/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── image/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── insert/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── move/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── overlay/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── prosemirror/
│ │ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ │ ├── state.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── pages/
│ │ │ │ │ │ │ ├── helper.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── sandbox/
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── preload-script.ts
│ │ │ │ │ │ │ ├── session.ts
│ │ │ │ │ │ │ └── terminal.ts
│ │ │ │ │ │ ├── screenshot/
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── snap/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ │ ├── state/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── style/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── text/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ └── theme/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── util.ts
│ │ │ │ │ ├── hosting/
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── provider.tsx
│ │ │ │ │ │ └── type.tsx
│ │ │ │ │ └── state/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── manager.ts
│ │ │ │ ├── telemetry-provider.tsx
│ │ │ │ ├── tools/
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── tools.ts
│ │ │ │ └── ui/
│ │ │ │ ├── auth-redirect.tsx
│ │ │ │ ├── avatar-dropdown/
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── plans.tsx
│ │ │ │ ├── pricing-modal/
│ │ │ │ │ ├── enterprise-card.tsx
│ │ │ │ │ ├── free-card.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── legacy-promotion.tsx
│ │ │ │ │ ├── pro-card.tsx
│ │ │ │ │ └── use-subscription.tsx
│ │ │ │ ├── pricing-table/
│ │ │ │ │ └── index.tsx
│ │ │ │ └── settings-modal/
│ │ │ │ ├── domain/
│ │ │ │ │ ├── custom/
│ │ │ │ │ │ ├── headers.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── no-domain-input.tsx
│ │ │ │ │ │ ├── record-field.tsx
│ │ │ │ │ │ ├── use-domain-verification.tsx
│ │ │ │ │ │ ├── verification.tsx
│ │ │ │ │ │ └── verified.tsx
│ │ │ │ │ ├── danger-zone.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── preview.tsx
│ │ │ │ │ └── upgrade-prompt.tsx
│ │ │ │ ├── helpers.tsx
│ │ │ │ ├── non-project.tsx
│ │ │ │ ├── preferences-tab.tsx
│ │ │ │ ├── project/
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── site/
│ │ │ │ │ ├── favicon.tsx
│ │ │ │ │ ├── image.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── metadata-form.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── use-metadata-form.ts
│ │ │ │ ├── subscription-cancel-modal.tsx
│ │ │ │ ├── subscription-tab.tsx
│ │ │ │ ├── user-delete-section.tsx
│ │ │ │ ├── versions/
│ │ │ │ │ ├── empty-state/
│ │ │ │ │ │ └── version.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── version-row.tsx
│ │ │ │ │ └── versions.tsx
│ │ │ │ └── with-project.tsx
│ │ │ ├── env.ts
│ │ │ ├── global.ts
│ │ │ ├── hooks/
│ │ │ │ ├── use-create-blank-project.ts
│ │ │ │ ├── use-debounce-input.tsx
│ │ │ │ ├── use-feature-flags.tsx
│ │ │ │ ├── use-font-loader.tsx
│ │ │ │ ├── use-get-background.tsx
│ │ │ │ └── use-parallax-cursor.ts
│ │ │ ├── i18n/
│ │ │ │ ├── keys.ts
│ │ │ │ └── request.ts
│ │ │ ├── instrumentation.ts
│ │ │ ├── proxy.ts
│ │ │ ├── server/
│ │ │ │ └── api/
│ │ │ │ ├── root.ts
│ │ │ │ ├── routers/
│ │ │ │ │ ├── chat/
│ │ │ │ │ │ ├── conversation.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── message.ts
│ │ │ │ │ │ └── suggestion.ts
│ │ │ │ │ ├── code.ts
│ │ │ │ │ ├── domain/
│ │ │ │ │ │ ├── adapters/
│ │ │ │ │ │ │ └── freestyle.ts
│ │ │ │ │ │ ├── custom.ts
│ │ │ │ │ │ ├── freestyle.ts
│ │ │ │ │ │ ├── hosting-factory.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── preview.ts
│ │ │ │ │ │ └── verify/
│ │ │ │ │ │ ├── helpers/
│ │ │ │ │ │ │ ├── freestyle.ts
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ └── records.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── forward/
│ │ │ │ │ │ ├── editor.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── github.ts
│ │ │ │ │ ├── image.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── project/
│ │ │ │ │ │ ├── branch.ts
│ │ │ │ │ │ ├── createRequest.ts
│ │ │ │ │ │ ├── fork.ts
│ │ │ │ │ │ ├── frame.ts
│ │ │ │ │ │ ├── helper.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── invitation.ts
│ │ │ │ │ │ ├── member.ts
│ │ │ │ │ │ ├── project.ts
│ │ │ │ │ │ ├── sandbox.ts
│ │ │ │ │ │ └── settings.ts
│ │ │ │ │ ├── publish/
│ │ │ │ │ │ ├── deployment.ts
│ │ │ │ │ │ ├── helpers/
│ │ │ │ │ │ │ ├── deploy.ts
│ │ │ │ │ │ │ ├── env.ts
│ │ │ │ │ │ │ ├── fork.ts
│ │ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── publish.ts
│ │ │ │ │ │ │ └── unpublish.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── manager.ts
│ │ │ │ │ ├── subscription/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── subscription.ts
│ │ │ │ │ ├── usage/
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── user/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── user-canvas.ts
│ │ │ │ │ ├── user-settings.ts
│ │ │ │ │ └── user.ts
│ │ │ │ └── trpc.ts
│ │ │ ├── services/
│ │ │ │ └── sync-engine/
│ │ │ │ ├── index.ts
│ │ │ │ └── sync-engine.ts
│ │ │ ├── stories/
│ │ │ │ ├── Button.stories.tsx
│ │ │ │ ├── ProjectCard.stories.tsx
│ │ │ │ ├── ProjectsPage.stories.tsx
│ │ │ │ ├── SelectProject.stories.tsx
│ │ │ │ ├── TopBar.stories.tsx
│ │ │ │ └── assets/
│ │ │ │ └── avif-test-image.avif
│ │ │ ├── styles/
│ │ │ │ └── globals.css
│ │ │ ├── trpc/
│ │ │ │ ├── client.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── query-client.ts
│ │ │ │ ├── react.tsx
│ │ │ │ ├── request-server.ts
│ │ │ │ └── server.ts
│ │ │ └── utils/
│ │ │ ├── analytics/
│ │ │ │ └── server.ts
│ │ │ ├── constants/
│ │ │ │ ├── index.ts
│ │ │ │ └── navigation.ts
│ │ │ ├── git/
│ │ │ │ ├── index.test.ts
│ │ │ │ └── index.ts
│ │ │ ├── n8n/
│ │ │ │ └── webhook.ts
│ │ │ ├── subscription.ts
│ │ │ ├── supabase/
│ │ │ │ ├── admin.ts
│ │ │ │ ├── client/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── middleware.ts
│ │ │ │ ├── request-server.ts
│ │ │ │ └── server.ts
│ │ │ ├── telemetry/
│ │ │ │ └── index.ts
│ │ │ ├── upload/
│ │ │ │ └── image-compression.ts
│ │ │ └── url/
│ │ │ └── index.ts
│ │ ├── test/
│ │ │ ├── cache/
│ │ │ │ ├── file-cache.test.ts
│ │ │ │ └── unified-cache.test.ts
│ │ │ ├── frame/
│ │ │ │ └── navigation.test.ts
│ │ │ ├── messages.test.ts
│ │ │ ├── pages/
│ │ │ │ └── helper.test.ts
│ │ │ ├── sandbox/
│ │ │ │ ├── env.test.ts
│ │ │ │ ├── helpers.test.ts
│ │ │ │ ├── port.test.ts
│ │ │ │ └── subdirectory.test.ts
│ │ │ └── setup.ts
│ │ ├── tsconfig.json
│ │ ├── vercel.json
│ │ ├── vitest.config.ts
│ │ └── vitest.shims.d.ts
│ ├── package.json
│ ├── preload/
│ │ ├── .gitignore
│ │ ├── Dockerfile
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── script/
│ │ │ ├── api/
│ │ │ │ ├── dom.ts
│ │ │ │ ├── elements/
│ │ │ │ │ ├── dom/
│ │ │ │ │ │ ├── group.ts
│ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ ├── image.ts
│ │ │ │ │ │ ├── insert.ts
│ │ │ │ │ │ └── remove.ts
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── move/
│ │ │ │ │ │ ├── drag.ts
│ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── stub.ts
│ │ │ │ │ ├── style.ts
│ │ │ │ │ └── text.ts
│ │ │ │ ├── events/
│ │ │ │ │ ├── dom.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── publish.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── ready.ts
│ │ │ │ ├── screenshot.ts
│ │ │ │ ├── state.ts
│ │ │ │ ├── style/
│ │ │ │ │ ├── css-manager.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── update.ts
│ │ │ │ └── theme/
│ │ │ │ └── index.ts
│ │ │ ├── helpers/
│ │ │ │ ├── assert.ts
│ │ │ │ ├── clone.ts
│ │ │ │ ├── dom.ts
│ │ │ │ ├── ids.ts
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ ├── server/
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ └── server/
│ ├── .gitignore
│ ├── Dockerfile
│ ├── README.md
│ ├── eslint.config.js
│ ├── package.json
│ ├── src/
│ │ ├── index.ts
│ │ ├── router/
│ │ │ ├── context.ts
│ │ │ ├── index.ts
│ │ │ ├── routes/
│ │ │ │ └── sandbox.ts
│ │ │ └── trpc.ts
│ │ ├── sandbox/
│ │ │ └── index.ts
│ │ └── server.ts
│ └── tsconfig.json
├── bunfig.toml
├── docker-compose.yml
├── docs/
│ ├── .gitignore
│ ├── README.md
│ ├── content/
│ │ └── docs/
│ │ ├── developers/
│ │ │ ├── appendix.mdx
│ │ │ ├── architecture.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── running-locally.mdx
│ │ │ └── troubleshooting.mdx
│ │ ├── enterprise.mdx
│ │ ├── faq.mdx
│ │ ├── getting-started/
│ │ │ ├── core-features.mdx
│ │ │ ├── first-project.mdx
│ │ │ ├── meta.json
│ │ │ └── ui-overview.mdx
│ │ ├── index.mdx
│ │ ├── meta.json
│ │ ├── migrations/
│ │ │ └── electron-to-web-migration.mdx
│ │ ├── self-hosting/
│ │ │ ├── admin-dashboard.mdx
│ │ │ ├── cloud-deployment.mdx
│ │ │ ├── docker-compose.mdx
│ │ │ ├── external-services.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── oauth-setup.mdx
│ │ │ └── single-machine.mdx
│ │ └── tutorials/
│ │ ├── figma-to-onlook.mdx
│ │ └── importing-templates.mdx
│ ├── eslint.config.js
│ ├── next-sitemap.config.js
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public/
│ │ ├── sitemap-0.xml
│ │ └── sitemap.xml
│ ├── source.config.ts
│ ├── src/
│ │ ├── app/
│ │ │ ├── [[...slug]]/
│ │ │ │ ├── edit-button.tsx
│ │ │ │ ├── edit-gh.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── api/
│ │ │ │ └── search/
│ │ │ │ └── route.ts
│ │ │ ├── global.css
│ │ │ ├── layout.config.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── not-found.tsx
│ │ │ └── robots.txt/
│ │ │ └── route.ts
│ │ ├── components/
│ │ │ ├── card.tsx
│ │ │ ├── cards.tsx
│ │ │ └── rb2b-loader.tsx
│ │ ├── lib/
│ │ │ └── source.ts
│ │ └── mdx-components.tsx
│ └── tsconfig.json
├── eslint.config.js
├── package.json
├── packages/
│ ├── ai/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agents/
│ │ │ │ ├── index.ts
│ │ │ │ ├── root.ts
│ │ │ │ └── tool-lookup.ts
│ │ │ ├── apply/
│ │ │ │ ├── client.ts
│ │ │ │ └── index.ts
│ │ │ ├── chat/
│ │ │ │ ├── index.ts
│ │ │ │ └── providers.ts
│ │ │ ├── contexts/
│ │ │ │ ├── classes/
│ │ │ │ │ ├── agent-rule.ts
│ │ │ │ │ ├── branch.ts
│ │ │ │ │ ├── error.ts
│ │ │ │ │ ├── file.ts
│ │ │ │ │ ├── highlight.ts
│ │ │ │ │ ├── image.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── models/
│ │ │ │ ├── base.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── prompt/
│ │ │ │ ├── constants/
│ │ │ │ │ ├── ask.ts
│ │ │ │ │ ├── base.ts
│ │ │ │ │ ├── create.ts
│ │ │ │ │ ├── format.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── onlook.ts
│ │ │ │ │ ├── shell.ts
│ │ │ │ │ ├── signatures.ts
│ │ │ │ │ ├── suggest.ts
│ │ │ │ │ ├── summary.ts
│ │ │ │ │ └── system.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── provider.ts
│ │ │ ├── stream/
│ │ │ │ ├── converter.ts
│ │ │ │ └── index.ts
│ │ │ ├── tokens/
│ │ │ │ └── index.ts
│ │ │ └── tools/
│ │ │ ├── classes/
│ │ │ │ ├── bash-edit.ts
│ │ │ │ ├── bash-read.ts
│ │ │ │ ├── check-errors.ts
│ │ │ │ ├── fuzzy-edit-file.ts
│ │ │ │ ├── glob.ts
│ │ │ │ ├── grep.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── list-branches.ts
│ │ │ │ ├── list-files.ts
│ │ │ │ ├── onlook-instructions.ts
│ │ │ │ ├── read-file.ts
│ │ │ │ ├── read-style-guide.ts
│ │ │ │ ├── sandbox.ts
│ │ │ │ ├── scrape-url.ts
│ │ │ │ ├── search-replace-edit.ts
│ │ │ │ ├── search-replace-multi-edit.ts
│ │ │ │ ├── terminal-command.ts
│ │ │ │ ├── typecheck.ts
│ │ │ │ ├── upload-image.ts
│ │ │ │ ├── web-search.ts
│ │ │ │ └── write-file.ts
│ │ │ ├── index.ts
│ │ │ ├── models/
│ │ │ │ ├── base.ts
│ │ │ │ ├── client.ts
│ │ │ │ └── index.ts
│ │ │ ├── shared/
│ │ │ │ ├── helpers/
│ │ │ │ │ ├── cli.ts
│ │ │ │ │ └── files.ts
│ │ │ │ └── type.ts
│ │ │ └── toolset.ts
│ │ ├── test/
│ │ │ ├── apply.test.ts
│ │ │ ├── contexts/
│ │ │ │ ├── agent-rule-context.test.ts
│ │ │ │ ├── branch-context.test.ts
│ │ │ │ ├── error-context.test.ts
│ │ │ │ ├── file-context.test.ts
│ │ │ │ ├── highlight-context.test.ts
│ │ │ │ ├── image-context.test.ts
│ │ │ │ └── index.test.ts
│ │ │ ├── prompt/
│ │ │ │ ├── data/
│ │ │ │ │ ├── create-page-system.txt
│ │ │ │ │ ├── examples.txt
│ │ │ │ │ ├── file.txt
│ │ │ │ │ ├── highlights.txt
│ │ │ │ │ ├── summary.txt
│ │ │ │ │ ├── system.txt
│ │ │ │ │ ├── user-empty.txt
│ │ │ │ │ └── user.txt
│ │ │ │ └── prompt.test.ts
│ │ │ ├── stream/
│ │ │ │ └── convert.test.ts
│ │ │ ├── tokens.test.ts
│ │ │ └── tools/
│ │ │ ├── edit.test.ts
│ │ │ ├── helpers.test.ts
│ │ │ └── read.test.ts
│ │ └── tsconfig.json
│ ├── code-provider/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── providers/
│ │ │ │ ├── codesandbox/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── utils/
│ │ │ │ │ ├── list-files.ts
│ │ │ │ │ ├── read-file.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ ├── utils.ts
│ │ │ │ │ └── write-file.ts
│ │ │ │ └── nodefs/
│ │ │ │ └── index.ts
│ │ │ ├── providers.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── constants/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── colors.ts
│ │ │ ├── contact.ts
│ │ │ ├── csb.ts
│ │ │ ├── dom.ts
│ │ │ ├── editor.ts
│ │ │ ├── files.ts
│ │ │ ├── frame.ts
│ │ │ ├── freestyle.ts
│ │ │ ├── index.ts
│ │ │ ├── language.ts
│ │ │ ├── links.ts
│ │ │ ├── storage.ts
│ │ │ ├── style.ts
│ │ │ └── tags.ts
│ │ └── tsconfig.json
│ ├── db/
│ │ ├── drizzle.config.ts
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── client.ts
│ │ │ ├── defaults/
│ │ │ │ ├── branch.ts
│ │ │ │ ├── canvas.ts
│ │ │ │ ├── conversation.ts
│ │ │ │ ├── frame.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project-settings.ts
│ │ │ │ ├── project.ts
│ │ │ │ ├── user-canvas.ts
│ │ │ │ └── user-settings.ts
│ │ │ ├── index.ts
│ │ │ ├── mappers/
│ │ │ │ ├── chat/
│ │ │ │ │ ├── conversation.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── message.ts
│ │ │ │ ├── domain.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project/
│ │ │ │ │ ├── branch.ts
│ │ │ │ │ ├── canvas.ts
│ │ │ │ │ ├── frame.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── project.ts
│ │ │ │ │ └── settings.ts
│ │ │ │ ├── subscription.ts
│ │ │ │ └── user/
│ │ │ │ ├── index.ts
│ │ │ │ ├── settings.ts
│ │ │ │ └── user.ts
│ │ │ ├── migration-scripts/
│ │ │ │ ├── README.md
│ │ │ │ └── migrate-to-branching.ts
│ │ │ ├── schema/
│ │ │ │ ├── canvas/
│ │ │ │ │ ├── canvas.ts
│ │ │ │ │ ├── frame.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── chat/
│ │ │ │ │ ├── conversation.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── message.ts
│ │ │ │ ├── domain/
│ │ │ │ │ ├── custom/
│ │ │ │ │ │ ├── domain.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── project-custom-domain.ts
│ │ │ │ │ │ └── verification.ts
│ │ │ │ │ ├── deployment.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── preview.ts
│ │ │ │ ├── feedback/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project/
│ │ │ │ │ ├── branch.ts
│ │ │ │ │ ├── create.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── invitation.ts
│ │ │ │ │ ├── project.ts
│ │ │ │ │ └── settings.ts
│ │ │ │ ├── subscription/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── legacy.ts
│ │ │ │ │ ├── price.ts
│ │ │ │ │ ├── product.ts
│ │ │ │ │ ├── rate-limits.ts
│ │ │ │ │ ├── subscription.ts
│ │ │ │ │ └── usage.ts
│ │ │ │ ├── supabase/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── user.ts
│ │ │ │ └── user/
│ │ │ │ ├── index.ts
│ │ │ │ ├── settings.ts
│ │ │ │ ├── user-canvas.ts
│ │ │ │ ├── user-project.ts
│ │ │ │ └── user.ts
│ │ │ └── seed/
│ │ │ ├── constants.ts
│ │ │ ├── db.ts
│ │ │ ├── reset.ts
│ │ │ ├── seed.ts
│ │ │ ├── stripe/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── backfill-subscriptions.ts
│ │ │ │ ├── legacy-subscription.ts
│ │ │ │ └── stripe.ts
│ │ │ └── supabase.ts
│ │ └── tsconfig.json
│ ├── email/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── client.ts
│ │ │ ├── index.ts
│ │ │ ├── invitation.ts
│ │ │ ├── templates/
│ │ │ │ ├── index.ts
│ │ │ │ └── invite-user.tsx
│ │ │ └── types/
│ │ │ └── send-email.ts
│ │ └── tsconfig.json
│ ├── file-system/
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── code-fs.ts
│ │ │ ├── config.ts
│ │ │ ├── fs.ts
│ │ │ ├── hooks/
│ │ │ │ ├── index.ts
│ │ │ │ ├── use-dir.ts
│ │ │ │ ├── use-file.ts
│ │ │ │ └── use-fs.tsx
│ │ │ ├── index-cache.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── fonts/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── default.ts
│ │ │ ├── family.ts
│ │ │ ├── helpers/
│ │ │ │ ├── ast-generators.ts
│ │ │ │ ├── ast-manipulators.ts
│ │ │ │ ├── class-utils.ts
│ │ │ │ ├── font-extractors.ts
│ │ │ │ ├── import-export-manager.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── validators.ts
│ │ │ ├── index.ts
│ │ │ ├── utils.ts
│ │ │ └── variants.ts
│ │ ├── test/
│ │ │ ├── ast-generators.test.ts
│ │ │ ├── ast-manipulators.test.ts
│ │ │ ├── class-utils.test.ts
│ │ │ ├── data/
│ │ │ │ ├── ast-manipulators/
│ │ │ │ │ ├── add-font-to-tailwind-theme/
│ │ │ │ │ │ ├── existing-fontfamily/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── font-already-exists/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── new-fontfamily/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── add-google-font-specifier/
│ │ │ │ │ │ ├── existing-import/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── no-import/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── merge-local-font-sources/
│ │ │ │ │ │ ├── array-to-array/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── empty-array/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── no-src-property/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── single-to-array/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── remove-font-declaration/
│ │ │ │ │ │ ├── google-font/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── last-google-font/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── local-font/
│ │ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── multiple-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── remove-font-from-tailwind-theme/
│ │ │ │ │ ├── multiple-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── non-existent-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── single-font/
│ │ │ │ │ ├── config.json
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── create-font-src-objects/
│ │ │ │ │ ├── basic-sources/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── multiple-formats/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ └── optional-properties/
│ │ │ │ │ ├── config.json
│ │ │ │ │ └── expected.ts
│ │ │ │ ├── create-local-font-config/
│ │ │ │ │ ├── basic-local-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ └── complex-font-name/
│ │ │ │ │ ├── config.json
│ │ │ │ │ └── expected.ts
│ │ │ │ ├── create-template-literal-with-font/
│ │ │ │ │ ├── conditional-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── empty-string/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── function-call-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── identifier-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── member-expression/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── string-literal/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── font-extractors/
│ │ │ │ │ ├── migrate-fonts-from-layout/
│ │ │ │ │ │ ├── complex-layout/
│ │ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── layout-with-classnames/
│ │ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── simple-layout/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── parse-font-declarations/
│ │ │ │ │ ├── google-fonts/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── local-fonts/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── mixed-fonts/
│ │ │ │ │ │ ├── expected.json
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── no-fonts/
│ │ │ │ │ ├── expected.json
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── generate-font-variable-export/
│ │ │ │ │ ├── basic-google-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── local-font-type/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── missing-optional-props/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ ├── multiple-weights-styles/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ └── expected.ts
│ │ │ │ │ └── special-characters/
│ │ │ │ │ ├── config.json
│ │ │ │ │ └── expected.ts
│ │ │ │ ├── remove-fonts-classname/
│ │ │ │ │ ├── font-weight-preservation/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── member-expression-remove-all/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── member-expression-remove-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-empty/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-no-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-remove-all/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── string-literal-specific-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-complex-expressions/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-multiple-fonts/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-remove-all/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── template-literal-specific-font/
│ │ │ │ │ │ ├── config.json
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── template-literal-static-only/
│ │ │ │ │ ├── config.json
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── update-classname-with-font-var/
│ │ │ │ │ ├── jsx-expression-classname/
│ │ │ │ │ │ ├── already-has-font/
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ ├── identifier-expression/
│ │ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ │ └── input.tsx
│ │ │ │ │ │ └── template-literal-existing/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── string-literal-classname/
│ │ │ │ │ ├── empty-string/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── with-existing-classes/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── with-font-classes/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ └── update-template-literal-with-font-class/
│ │ │ │ ├── complex-template/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── empty-template/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── font-weight-preservation/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── multiple-expressions/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── multiple-font-classes/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── replace-existing-font/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── with-existing-classes/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ └── with-leading-space/
│ │ │ │ ├── expected.tsx
│ │ │ │ └── input.tsx
│ │ │ ├── font-extractors.test.ts
│ │ │ ├── import-export-manager.test.ts
│ │ │ ├── test-utils.ts
│ │ │ └── validators.test.ts
│ │ └── tsconfig.json
│ ├── git/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── git.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── github/
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── auth.ts
│ │ │ ├── config.ts
│ │ │ ├── index.ts
│ │ │ ├── installation.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── growth/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── helpers.ts
│ │ │ ├── index.ts
│ │ │ ├── inject.ts
│ │ │ ├── remove.ts
│ │ │ └── script.ts
│ │ ├── tests/
│ │ │ └── inject.test.ts
│ │ └── tsconfig.json
│ ├── image-server/
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── compress.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── test/
│ │ │ └── image.test.ts
│ │ └── tsconfig.json
│ ├── models/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── actions/
│ │ │ │ ├── action.ts
│ │ │ │ ├── code.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── location.ts
│ │ │ │ └── target.ts
│ │ │ ├── assets/
│ │ │ │ └── index.ts
│ │ │ ├── auth/
│ │ │ │ └── index.ts
│ │ │ ├── chat/
│ │ │ │ ├── conversation/
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── message/
│ │ │ │ │ ├── checkpoint.ts
│ │ │ │ │ ├── code.ts
│ │ │ │ │ ├── context.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── message.ts
│ │ │ │ │ └── queue.ts
│ │ │ │ ├── request.ts
│ │ │ │ ├── response.ts
│ │ │ │ ├── suggestion.ts
│ │ │ │ ├── summary.ts
│ │ │ │ └── type.ts
│ │ │ ├── code/
│ │ │ │ └── index.ts
│ │ │ ├── create/
│ │ │ │ └── index.ts
│ │ │ ├── domain/
│ │ │ │ └── index.ts
│ │ │ ├── editor/
│ │ │ │ └── index.ts
│ │ │ ├── element/
│ │ │ │ ├── classes.ts
│ │ │ │ ├── element.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── layers.ts
│ │ │ │ ├── props.ts
│ │ │ │ └── templateNode.ts
│ │ │ ├── font/
│ │ │ │ └── index.ts
│ │ │ ├── hosting/
│ │ │ │ └── index.ts
│ │ │ ├── ide/
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── llm/
│ │ │ │ └── index.ts
│ │ │ ├── next/
│ │ │ │ └── index.ts
│ │ │ ├── pages/
│ │ │ │ ├── index.ts
│ │ │ │ └── opengraph.ts
│ │ │ ├── project/
│ │ │ │ ├── branch.ts
│ │ │ │ ├── canvas.ts
│ │ │ │ ├── command.ts
│ │ │ │ ├── create.ts
│ │ │ │ ├── frame.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── project.ts
│ │ │ │ ├── rect.ts
│ │ │ │ ├── role.ts
│ │ │ │ └── settings.ts
│ │ │ ├── run/
│ │ │ │ └── index.ts
│ │ │ ├── sandbox/
│ │ │ │ ├── files.ts
│ │ │ │ ├── folder.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── template.ts
│ │ │ ├── style/
│ │ │ │ └── index.ts
│ │ │ ├── supabase/
│ │ │ │ └── db.ts
│ │ │ ├── tools/
│ │ │ │ └── index.ts
│ │ │ ├── usage/
│ │ │ │ └── index.ts
│ │ │ └── user/
│ │ │ ├── index.ts
│ │ │ ├── settings.ts
│ │ │ └── user.ts
│ │ └── tsconfig.json
│ ├── parser/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── code-edit/
│ │ │ │ ├── group.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── image.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── insert.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── move.ts
│ │ │ │ ├── next-config.ts
│ │ │ │ ├── remove.ts
│ │ │ │ ├── style.ts
│ │ │ │ ├── text.ts
│ │ │ │ └── transform.ts
│ │ │ ├── helpers.ts
│ │ │ ├── ids.ts
│ │ │ ├── index.ts
│ │ │ ├── packages.ts
│ │ │ ├── parse.ts
│ │ │ ├── prettier/
│ │ │ │ └── index.ts
│ │ │ └── template-node/
│ │ │ ├── helpers.ts
│ │ │ ├── index.ts
│ │ │ └── map.ts
│ │ ├── test/
│ │ │ ├── data/
│ │ │ │ ├── ids/
│ │ │ │ │ ├── adds-ids-to-jsx/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── does-not-add-ids-if-exist/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── layout/
│ │ │ │ │ ├── adds-script-if-missing/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── creates-body/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── does-not-duplicate/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── handles-self-closing-body/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── handles-self-closing-html-head/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── injects-at-bottom/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── injects-in-first-body/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── injects-with-existing-head-script/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── preserves-body-props/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── removes-deprecated-script/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── removes-deprecated-script-multiple/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── wraps-conditional-ternary/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ ├── wraps-fragment-only/
│ │ │ │ │ │ ├── expected.tsx
│ │ │ │ │ │ └── input.tsx
│ │ │ │ │ └── wraps-plain-children/
│ │ │ │ │ ├── expected.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── next-config/
│ │ │ │ │ ├── add-basic-js/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── add-basic-mjs/
│ │ │ │ │ │ ├── expected.mjs
│ │ │ │ │ │ └── input.mjs
│ │ │ │ │ ├── add-basic-ts/
│ │ │ │ │ │ ├── expected.ts
│ │ │ │ │ │ └── input.ts
│ │ │ │ │ ├── alternative-name-config/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── complex-nested-objects/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── direct-return-from-function/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── empty-config/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── exported-as-function/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── iife-wrapped-config/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── merge-typescript-props/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── no-duplicate-props/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── with-mdx/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── with-mdx-alt-name-order/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ ├── with-mdx-alt-order/
│ │ │ │ │ │ ├── expected.js
│ │ │ │ │ │ └── input.js
│ │ │ │ │ └── with-plugin/
│ │ │ │ │ ├── expected.js
│ │ │ │ │ └── input.js
│ │ │ │ └── parse/
│ │ │ │ └── simple/
│ │ │ │ ├── expected.js
│ │ │ │ └── input.js
│ │ │ ├── helpers.test.ts
│ │ │ ├── ids.test.ts
│ │ │ ├── layout.test.ts
│ │ │ ├── next-config.test.ts
│ │ │ ├── parse.test.ts
│ │ │ ├── preload.test.ts
│ │ │ └── template.test.ts
│ │ └── tsconfig.json
│ ├── penpal/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── child.ts
│ │ │ ├── index.ts
│ │ │ └── parent.ts
│ │ └── tsconfig.json
│ ├── rpc/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ └── trpc/
│ │ │ ├── config.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── scripts/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── api-keys.ts
│ │ │ ├── backend.ts
│ │ │ ├── helpers.ts
│ │ │ └── index.ts
│ │ ├── test/
│ │ │ ├── comprehensive.test.ts
│ │ │ ├── integration.test.ts
│ │ │ └── simple.test.ts
│ │ └── tsconfig.json
│ ├── stripe/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── client.ts
│ │ │ ├── constants.ts
│ │ │ ├── functions.ts
│ │ │ ├── index.ts
│ │ │ ├── scripts/
│ │ │ │ ├── dev/
│ │ │ │ │ ├── customer.ts
│ │ │ │ │ ├── product.ts
│ │ │ │ │ ├── reset.ts
│ │ │ │ │ └── setup.ts
│ │ │ │ └── production/
│ │ │ │ ├── coupon.ts
│ │ │ │ └── product-price.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── types/
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── adapters/
│ │ │ │ ├── index.ts
│ │ │ │ └── props.ts
│ │ │ ├── design-tokens/
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── ui/
│ │ ├── README.md
│ │ ├── components.json
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── postcss.config.js
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── accordion.tsx
│ │ │ │ ├── ai-elements/
│ │ │ │ │ ├── code-block.tsx
│ │ │ │ │ ├── context.tsx
│ │ │ │ │ ├── conversation.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── reasoning.tsx
│ │ │ │ │ ├── response.tsx
│ │ │ │ │ ├── tool.tsx
│ │ │ │ │ └── web-preview.tsx
│ │ │ │ ├── alert-dialog.tsx
│ │ │ │ ├── alert.tsx
│ │ │ │ ├── aspect-ratio.tsx
│ │ │ │ ├── avatar.tsx
│ │ │ │ ├── badge.tsx
│ │ │ │ ├── breadcrumb.tsx
│ │ │ │ ├── button.tsx
│ │ │ │ ├── calendar.tsx
│ │ │ │ ├── card.tsx
│ │ │ │ ├── chart.tsx
│ │ │ │ ├── checkbox.tsx
│ │ │ │ ├── collapsible.tsx
│ │ │ │ ├── color-picker/
│ │ │ │ │ ├── ColorPicker.tsx
│ │ │ │ │ ├── ColorSlider.tsx
│ │ │ │ │ ├── EyeDropperButton.tsx
│ │ │ │ │ ├── Gradient.tsx
│ │ │ │ │ ├── SVPicker.tsx
│ │ │ │ │ ├── checkPattern.ts
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── command.tsx
│ │ │ │ ├── context-menu.tsx
│ │ │ │ ├── dialog.tsx
│ │ │ │ ├── draftable-input.tsx
│ │ │ │ ├── drawer.tsx
│ │ │ │ ├── dropdown-menu.tsx
│ │ │ │ ├── form.tsx
│ │ │ │ ├── hotkey-label.tsx
│ │ │ │ ├── hover-card.tsx
│ │ │ │ ├── icons/
│ │ │ │ │ ├── header-level-icons/
│ │ │ │ │ │ ├── h1Icon.tsx
│ │ │ │ │ │ ├── h2Icon.tsx
│ │ │ │ │ │ ├── h3Icon.tsx
│ │ │ │ │ │ ├── h4Icon.tsx
│ │ │ │ │ │ ├── h5Icon.tsx
│ │ │ │ │ │ └── h6Icon.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── input-group.tsx
│ │ │ │ ├── input-otp.tsx
│ │ │ │ ├── input.tsx
│ │ │ │ ├── kbd.tsx
│ │ │ │ ├── label.tsx
│ │ │ │ ├── menubar.tsx
│ │ │ │ ├── motion-card.tsx
│ │ │ │ ├── navigation-menu.tsx
│ │ │ │ ├── node-icon.tsx
│ │ │ │ ├── pagination.tsx
│ │ │ │ ├── popover.tsx
│ │ │ │ ├── progress-with-interval.tsx
│ │ │ │ ├── progress.tsx
│ │ │ │ ├── radio-group.tsx
│ │ │ │ ├── resizable.tsx
│ │ │ │ ├── scroll-area.tsx
│ │ │ │ ├── select.tsx
│ │ │ │ ├── separator.tsx
│ │ │ │ ├── sheet.tsx
│ │ │ │ ├── shine-border.tsx
│ │ │ │ ├── sidebar.tsx
│ │ │ │ ├── skeleton.tsx
│ │ │ │ ├── slider.tsx
│ │ │ │ ├── sonner.tsx
│ │ │ │ ├── switch.tsx
│ │ │ │ ├── table.tsx
│ │ │ │ ├── tabs.tsx
│ │ │ │ ├── textarea.tsx
│ │ │ │ ├── toggle-group.tsx
│ │ │ │ ├── toggle.tsx
│ │ │ │ └── tooltip.tsx
│ │ │ ├── globals.css
│ │ │ ├── hooks/
│ │ │ │ ├── index.ts
│ │ │ │ ├── use-enter-submit.ts
│ │ │ │ ├── use-media-query.ts
│ │ │ │ ├── use-mobile.ts
│ │ │ │ ├── use-pointer-stroke.tsx
│ │ │ │ ├── use-reduced-motion.ts
│ │ │ │ └── use-resize-observer.ts
│ │ │ ├── index.ts
│ │ │ └── utils/
│ │ │ ├── cn.ts
│ │ │ ├── index.ts
│ │ │ └── truncate.ts
│ │ ├── tailwind.config.ts
│ │ ├── test/
│ │ │ └── Gradient.test.ts
│ │ ├── tokens.ts
│ │ └── tsconfig.json
│ └── utility/
│ ├── eslint.config.js
│ ├── package.json
│ ├── src/
│ │ ├── assert.ts
│ │ ├── autolayout.ts
│ │ ├── clone.ts
│ │ ├── color.ts
│ │ ├── domain.test.ts
│ │ ├── domain.ts
│ │ ├── email.ts
│ │ ├── errors.ts
│ │ ├── file.ts
│ │ ├── folder.ts
│ │ ├── font.ts
│ │ ├── frame.ts
│ │ ├── id.ts
│ │ ├── image.ts
│ │ ├── index.ts
│ │ ├── initials.ts
│ │ ├── math.ts
│ │ ├── name.ts
│ │ ├── null.ts
│ │ ├── path.ts
│ │ ├── screenshot.ts
│ │ ├── string.ts
│ │ ├── tailwind.ts
│ │ ├── time.ts
│ │ ├── tw-merge.ts
│ │ ├── unit.ts
│ │ ├── urls.ts
│ │ └── window-metadata.ts
│ ├── test/
│ │ ├── colors.test.ts
│ │ ├── domain.test.ts
│ │ ├── errors.test.ts
│ │ ├── file.test.ts
│ │ ├── frame.ts
│ │ ├── id.test.ts
│ │ ├── image.test.ts
│ │ ├── name.test.ts
│ │ ├── path.test.ts
│ │ ├── tailwind.test.ts
│ │ ├── tw-merge.test.ts
│ │ └── urls.test.ts
│ └── tsconfig.json
└── tooling/
├── eslint/
│ ├── base.js
│ ├── nextjs.js
│ ├── package.json
│ ├── react.js
│ └── tsconfig.json
├── prettier/
│ ├── index.js
│ ├── package.json
│ └── tsconfig.json
└── typescript/
├── base.json
├── next-react.json
├── package.json
├── react-library.json
└── vite-react.json
Showing preview only (387K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3998 symbols across 884 files)
FILE: apps/backend/supabase/migrations/0000_same_human_robot.sql
type "canvas" (line 13) | CREATE TABLE IF NOT EXISTS "canvas" (
type "frames" (line 22) | CREATE TABLE IF NOT EXISTS "frames" (
type "conversations" (line 34) | CREATE TABLE IF NOT EXISTS "conversations" (
type "messages" (line 42) | CREATE TABLE IF NOT EXISTS "messages" (
type "projects" (line 54) | CREATE TABLE IF NOT EXISTS "projects" (
type "users" (line 66) | CREATE TABLE IF NOT EXISTS "users" (
type "user_projects" (line 71) | CREATE TABLE IF NOT EXISTS "user_projects" (
FILE: apps/backend/supabase/migrations/0002_red_crusher_hogan.sql
type "user_settings" (line 1) | CREATE TABLE IF NOT EXISTS "user_settings" (
FILE: apps/backend/supabase/migrations/0003_loud_ozymandias.sql
type "user_canvases" (line 1) | CREATE TABLE IF NOT EXISTS "user_canvases" (
FILE: apps/backend/supabase/migrations/0004_pink_expediter.sql
type "project_invitations" (line 15) | CREATE TABLE IF NOT EXISTS "project_invitations" (
FILE: apps/backend/supabase/migrations/0006_rls.sql
function user_has_project_access (line 2) | CREATE OR REPLACE FUNCTION user_has_project_access(
function user_has_canvas_access (line 17) | CREATE OR REPLACE FUNCTION user_has_canvas_access(
FILE: apps/backend/supabase/migrations/0007_realtime_rls.sql
function public (line 1) | CREATE OR REPLACE FUNCTION public.project_changes()
FILE: apps/backend/supabase/migrations/0010_bent_edwin_jarvis.sql
type "custom_domains" (line 3) | CREATE TABLE "custom_domains" (
type "preview_domains" (line 12) | CREATE TABLE "preview_domains" (
type "published_domains" (line 21) | CREATE TABLE "published_domains" (
type "custom_domain_verification" (line 32) | CREATE TABLE "custom_domain_verification" (
FILE: apps/backend/supabase/migrations/0011_typical_clea.sql
type "project_settings" (line 8) | CREATE TABLE "project_settings" (
type "prices" (line 17) | CREATE TABLE "prices" (
type "products" (line 27) | CREATE TABLE "products" (
type "subscriptions" (line 36) | CREATE TABLE "subscriptions" (
type "usage_records" (line 57) | CREATE TABLE "usage_records" (
FILE: apps/backend/supabase/migrations/0013_aspiring_kabuki.sql
type "project_create_requests" (line 4) | CREATE TABLE "project_create_requests" (
type "deployments" (line 15) | CREATE TABLE "deployments" (
FILE: apps/backend/supabase/migrations/0014_military_marrow.sql
type "project_custom_domains" (line 2) | CREATE TABLE "project_custom_domains" (
FILE: apps/backend/supabase/migrations/0015_same_leo.sql
type "legacy_subscriptions" (line 4) | CREATE TABLE "legacy_subscriptions" (
FILE: apps/backend/supabase/migrations/0016_pretty_dust.sql
type "rate_limits" (line 1) | CREATE TABLE "rate_limits" (
type "rate_limits" (line 27) | CREATE INDEX "rate_limits_user_time_idx" ON "rate_limits" USING btree ("...
type "usage_records" (line 28) | CREATE INDEX "usage_records_user_time_idx" ON "usage_records" USING btre...
FILE: apps/backend/supabase/migrations/0017_small_xavin.sql
type "feedbacks" (line 2) | CREATE TABLE "feedbacks" (
type "project_invitations" (line 28) | CREATE INDEX "project_invitations_invitee_email_project_id_idx" ON "proj...
FILE: apps/backend/supabase/migrations/0018_lush_thanos.sql
type "branches" (line 1) | CREATE TABLE "branches" (
type "branches" (line 23) | CREATE INDEX "branches_project_id_idx" ON "branches" USING btree ("proje...
type "branches" (line 24) | CREATE UNIQUE INDEX "branches_name_per_project_ux" ON "branches" USING b...
type "branches" (line 25) | CREATE UNIQUE INDEX "branches_default_per_project_ux" ON "branches" USIN...
FILE: apps/web/client/.storybook/main.ts
function getAbsolutePath (line 12) | function getAbsolutePath(value: string): any {
function findGitRoot (line 19) | function findGitRoot(startPath: string): string | null {
method viteFinal (line 50) | async viteFinal(config) {
FILE: apps/web/client/.storybook/mocks/trpc-react.tsx
type MockAppRouter (line 18) | type MockAppRouter = Record<string, any>;
type RouterInputs (line 23) | type RouterInputs = Record<string, any>;
type RouterOutputs (line 24) | type RouterOutputs = Record<string, any>;
function TRPCReactProvider (line 42) | function TRPCReactProvider(props: { children: React.ReactNode }) {
FILE: apps/web/client/public/onlook-preload-script.js
function K4 (line 1) | function K4(r){var t=typeof r;return r!=null&&(t=="object"||t=="function")}
function Y4 (line 1) | function Y4(r){var t=r.length;while(t--&&V4.test(r.charAt(t)));return t}
function G4 (line 1) | function G4(r){return r?r.slice(0,F4(r)+1).replace(Q4,""):r}
function H4 (line 1) | function H4(r){var t=y4.call(r,wn),i=r[wn];try{r[wn]=void 0;var o=!0}cat...
function T4 (line 1) | function T4(r){return Z4.call(r)}
function ta (line 1) | function ta(r){if(r==null)return r===void 0?ra:s4;return dh&&dh in Objec...
function na (line 1) | function na(r){return r!=null&&typeof r=="object"}
function la (line 1) | function la(r){return typeof r=="symbol"||oa(r)&&ia(r)==ea}
function ha (line 1) | function ha(r){if(typeof r=="number")return r;if(ua(r))return l$;if(e$(r...
function aa (line 1) | function aa(r,t,i){var o,n,e,l,u,g,c=0,m=!1,v=!1,h=!0;if(typeof r!="func...
function a6 (line 1) | function a6(r){return r<0?(-r<<1)+1:(r<<1)+0}
function z6 (line 1) | function z6(r){var t=(r&1)===1,i=r>>1;return t?-i:i}
function p6 (line 1) | function p6(r,t,i){if(t in r)return r[t];else if(arguments.length===3)re...
function kn (line 1) | function kn(r){var t=r.match(w0);if(!t)return null;return{scheme:t[1],au...
function yt (line 1) | function yt(r){var t="";if(r.scheme)t+=r.scheme+":";if(t+="//",r.auth)t+...
function k6 (line 1) | function k6(r){var t=[];return function(i){for(var o=0;o<t.length;o++)if...
function a0 (line 1) | function a0(r,t){if(r==="")r=".";if(t==="")t=".";var i=kn(t),o=kn(r);if(...
function U6 (line 1) | function U6(r,t){if(r==="")r=".";r=r.replace(/\/$/,"");var i=0;while(t.i...
function _0 (line 1) | function _0(r){return r}
function J6 (line 1) | function J6(r){if(O0(r))return"$"+r;return r}
function P6 (line 1) | function P6(r){if(O0(r))return r.slice(1);return r}
function O0 (line 1) | function O0(r){if(!r)return!1;var t=r.length;if(t<9)return!1;if(r.charCo...
function E6 (line 1) | function E6(r,t,i){var o=tt(r.source,t.source);if(o!==0)return o;if(o=r....
function K6 (line 1) | function K6(r,t,i){var o=r.originalLine-t.originalLine;if(o!==0)return o...
function L6 (line 1) | function L6(r,t,i){var o=r.generatedLine-t.generatedLine;if(o!==0)return...
function X6 (line 1) | function X6(r,t,i){var o=r.generatedColumn-t.generatedColumn;if(o!==0||i...
function tt (line 1) | function tt(r,t){if(r===t)return 0;if(r===null)return 1;if(t===null)retu...
function W6 (line 1) | function W6(r,t){var i=r.generatedLine-t.generatedLine;if(i!==0)return i...
function q6 (line 1) | function q6(r){return JSON.parse(r.replace(/^\)]}'[^\n]*\n/,""))}
function N6 (line 1) | function N6(r,t,i){if(t=t||"",r){if(r[r.length-1]!=="/"&&t[0]!=="/")r+="...
function nt (line 1) | function nt(){this._array=[],this._set=Ut?new Map:Object.create(null)}
function nz (line 1) | function nz(r,t){var i=r.generatedLine,o=t.generatedLine,n=r.generatedCo...
function Ti (line 1) | function Ti(){this._array=[],this._sorted=!0,this._last={generatedLine:-...
method constructor (line 1) | constructor(r,t){super(t);this.name="PenpalError",this.code=r}
method constructor (line 1) | constructor(r,t){this.value=r,this.transferables=t?.transferables}
method constructor (line 1) | constructor(r){this.transferables=r?.transferables,this.timeout=r?.timeout}
method get (line 1) | get(o,n){if(n==="then")return;if(i.length&&Xa.has(n))return Reflect.get(...
method apply (line 1) | apply(o,n,e){return r(i,e)}
method constructor (line 1) | constructor(r){super(`You've hit a bug in Penpal. Please file an issue w...
method constructor (line 1) | constructor({remoteWindow:r,allowedOrigins:t}){if(!r)throw new Or("INVAL...
method constructor (line 1) | constructor({worker:r}){if(!r)throw new Or("INVALID_ARGUMENT","worker mu...
method constructor (line 1) | constructor({port:r}){if(!r)throw new Or("INVALID_ARGUMENT","port must b...
function Q (line 1) | function Q(r){return document.querySelector(`[${"data-odid"}="${r}"]`)}
function Ne (line 1) | function Ne(r,t=!1){let i=`[${"data-odid"}="${r}"]`;if(!t)return i;retur...
function Ca (line 1) | function Ca(r){return CSS.escape(r)}
function pt (line 1) | function pt(r){return r&&r instanceof Node&&r.nodeType===Node.ELEMENT_NO...
function Pr (line 1) | function Pr(r){let t=r.getAttribute("data-odid");if(!t)t=`odid-${k$()}`,...
function Qr (line 1) | function Qr(r){return r.getAttribute("data-oid")}
function Gr (line 1) | function Gr(r){return r.getAttribute("data-oiid")}
function U$ (line 1) | function U$(r,t){if(!ar)return;ar.onDomProcessed({layerMap:Object.fromEn...
function Se (line 1) | function Se(r){window._onlookFrameId=r}
function Vt (line 1) | function Vt(){let r=window._onlookFrameId;if(!r)return console.warn("Fra...
function Ve (line 1) | function Ve(r){window._onlookBranchId=r}
function zn (line 1) | function zn(){let r=window._onlookBranchId;if(!r)return console.warn("Br...
function sa (line 1) | function sa(r=document.body){if(!Vt())return console.warn("frameView id ...
function zr (line 1) | function zr(r){if(!pt(r))return null;let t=new Map,i=document.createTree...
function J$ (line 1) | function J$(r){let t=Pr(r),i=Qr(r),o=Gr(r),n=Array.from(r.childNodes).ma...
function Ye (line 1) | function Ye(r){throw Error(`Expected \`never\`, found: ${JSON.stringify(...
function K$ (line 1) | function K$(r){let t=X$(r),i=t6(r),o=n6(r);return{defined:{width:"auto",...
function L$ (line 1) | function L$(r){let t=Q(r);if(!t)return{};return X$(t)}
function X$ (line 1) | function X$(r){return E$(window.getComputedStyle(r))}
function t6 (line 1) | function t6(r){let t={},i=W$(r.style.cssText);return Object.entries(i).f...
function n6 (line 1) | function n6(r){let t={},i=document.styleSheets;for(let o=0;o<i.length;o+...
function W$ (line 1) | function W$(r){let t={};return r.split(";").forEach((i)=>{if(i=i.trim(),...
function qi (line 1) | function qi(r){try{let t=r.getAttribute("data-onlook-drag-saved-style");...
function N$ (line 1) | function N$(r){let t=r.parentElement;if(!t)return;return{type:"index",ta...
function A$ (line 1) | function A$(r,t,i){let o=Q(r.domId);if(!o)return console.warn("Failed to...
function B$ (line 1) | function B$(r,t){let i=Q(r.domId);if(!i)return console.warn(`Parent elem...
function o6 (line 1) | function o6(r){let t=document.createElement(r.tagName);return Object.ent...
function y$ (line 1) | function y$(r){r.removeAttribute("data-odid"),r.removeAttribute("data-oi...
function Si (line 1) | function Si(r){let t=Q(r);if(!t)return console.warn("Element not found f...
function R$ (line 1) | function R$(r){let t=Array.from(r.attributes).reduce((o,n)=>{return o[n....
function H$ (line 1) | function H$(r){let t=Q(r);if(!t)throw Error("Element not found for domId...
function M$ (line 1) | function M$(r){let t=document.querySelector(`[${"data-odid"}="${r}"]`);i...
function Z$ (line 1) | function Z$(r,t,i){let o=document.querySelector(`[${"data-odid"}="${r}"]...
function T$ (line 1) | function T$(){let t=document.body.querySelector(`[${"data-oid"}]`);if(t)...
function cr (line 1) | function cr(r){return r>=48&&r<=57}
function Ir (line 1) | function Ir(r){return cr(r)||r>=65&&r<=70||r>=97&&r<=102}
function Fi (line 1) | function Fi(r){return r>=65&&r<=90}
function e6 (line 1) | function e6(r){return r>=97&&r<=122}
function l6 (line 1) | function l6(r){return Fi(r)||e6(r)}
function c6 (line 1) | function c6(r){return r>=128}
function Yi (line 1) | function Yi(r){return l6(r)||c6(r)||r===95}
function _n (line 1) | function _n(r){return Yi(r)||cr(r)||r===45}
function u6 (line 1) | function u6(r){return r>=0&&r<=8||r===11||r>=14&&r<=31||r===127}
function On (line 1) | function On(r){return r===10||r===13||r===12}
function Ar (line 1) | function Ar(r){return On(r)||r===32||r===9}
function Dr (line 1) | function Dr(r,t){if(r!==92)return!1;if(On(t)||t===0)return!1;return!0}
function Ft (line 1) | function Ft(r,t,i){if(r===45)return Yi(t)||t===45||Dr(t,i);if(Yi(r))retu...
function Qi (line 1) | function Qi(r,t,i){if(r===43||r===45){if(cr(t))return 2;return t===46&&c...
function Gi (line 1) | function Gi(r){if(r===65279)return 1;if(r===65534)return 1;return 0}
function Bi (line 1) | function Bi(r){return r<128?Fe[r]:Ai}
function Qt (line 1) | function Qt(r,t){return t<r.length?r.charCodeAt(t):0}
function yi (line 1) | function yi(r,t,i){if(i===13&&Qt(r,t+1)===10)return 2;return 1}
function sr (line 1) | function sr(r,t,i){let o=r.charCodeAt(t);if(Fi(o))o=o|32;return o===i}
function rt (line 1) | function rt(r,t,i,o){if(i-t!==o.length)return!1;if(t<0||i>r.length)retur...
function C$ (line 1) | function C$(r,t){for(;t>=0;t--)if(!Ar(r.charCodeAt(t)))break;return t+1}
function pn (line 1) | function pn(r,t){for(;t<r.length;t++)if(!Ar(r.charCodeAt(t)))break;retur...
function Ae (line 1) | function Ae(r,t){for(;t<r.length;t++)if(!cr(r.charCodeAt(t)))break;retur...
function Br (line 1) | function Br(r,t){if(t+=2,Ir(Qt(r,t-1))){for(let o=Math.min(r.length,t+5)...
function In (line 1) | function In(r,t){for(;t<r.length;t++){let i=r.charCodeAt(t);if(_n(i))con...
function It (line 1) | function It(r,t){let i=r.charCodeAt(t);if(i===43||i===45)i=r.charCodeAt(...
function Ri (line 1) | function Ri(r,t){for(;t<r.length;t++){let i=r.charCodeAt(t);if(i===41){t...
function jn (line 1) | function jn(r){if(r.length===1&&!Ir(r.charCodeAt(0)))return r[0];let t=p...
function At (line 1) | function At(r=null,t){if(r===null||r.length<t)return new Uint32Array(Mat...
function r0 (line 1) | function r0(r){let t=r.source,i=t.length,o=t.length>0?Gi(t.charCodeAt(0)...
class Hi (line 1) | class Hi{constructor(r,t,i,o){this.setSource(r,t,i,o),this.lines=null,th...
method constructor (line 1) | constructor(r,t,i,o){this.setSource(r,t,i,o),this.lines=null,this.colu...
method setSource (line 1) | setSource(r="",t=0,i=1,o=1){this.source=r,this.startOffset=t,this.star...
method getLocation (line 1) | getLocation(r,t){if(!this.computed)r0(this);return{source:t,offset:thi...
method getLocationRange (line 1) | getLocationRange(r,t,i){if(!this.computed)r0(this);return{source:i,sta...
function t0 (line 1) | function t0(r){return jt[r]!==0}
class Mi (line 1) | class Mi{constructor(r,t){this.setSource(r,t)}reset(){this.eof=!1,this.t...
method constructor (line 1) | constructor(r,t){this.setSource(r,t)}
method reset (line 1) | reset(){this.eof=!1,this.tokenIndex=-1,this.tokenType=0,this.tokenStar...
method setSource (line 1) | setSource(r="",t=()=>{}){r=String(r||"");let i=r.length,o=At(this.offs...
method lookupType (line 1) | lookupType(r){if(r+=this.tokenIndex,r<this.tokenCount)return this.offs...
method lookupTypeNonSC (line 1) | lookupTypeNonSC(r){for(let t=this.tokenIndex;t<this.tokenCount;t++){le...
method lookupOffset (line 1) | lookupOffset(r){if(r+=this.tokenIndex,r<this.tokenCount)return this.of...
method lookupOffsetNonSC (line 1) | lookupOffsetNonSC(r){for(let t=this.tokenIndex;t<this.tokenCount;t++){...
method lookupValue (line 1) | lookupValue(r,t){if(r+=this.tokenIndex,r<this.tokenCount)return rt(thi...
method getTokenStart (line 1) | getTokenStart(r){if(r===this.tokenIndex)return this.tokenStart;if(r>0)...
method substrToCursor (line 1) | substrToCursor(r){return this.source.substring(r,this.tokenStart)}
method isBalanceEdge (line 1) | isBalanceEdge(r){return this.balance[this.tokenIndex]<r}
method isDelim (line 1) | isDelim(r,t){if(t)return this.lookupType(t)===P&&this.source.charCodeA...
method skip (line 1) | skip(r){let t=this.tokenIndex+r;if(t<this.tokenCount)this.tokenIndex=t...
method next (line 1) | next(){let r=this.tokenIndex+1;if(r<this.tokenCount)this.tokenIndex=r,...
method skipSC (line 1) | skipSC(){while(this.tokenType===N||this.tokenType===y)this.next()}
method skipUntilBalanced (line 1) | skipUntilBalanced(r,t){let i=r,o=0,n=0;r:for(;i<this.tokenCount;i++){i...
method forEachToken (line 1) | forEachToken(r){for(let t=0,i=this.firstCharOffset;t<this.tokenCount;t...
method dump (line 1) | dump(){let r=Array(this.tokenCount);return this.forEachToken((t,i,o,n)...
function vt (line 1) | function vt(r,t){function i(v){return v<u?r.charCodeAt(v):0}function o()...
class or (line 1) | class or{static createItem(r){return{prev:null,next:null,data:r}}constru...
method createItem (line 1) | static createItem(r){return{prev:null,next:null,data:r}}
method constructor (line 1) | constructor(){this.head=null,this.tail=null,this.cursor=null}
method createItem (line 1) | createItem(r){return or.createItem(r)}
method allocateCursor (line 1) | allocateCursor(r,t){let i;if(Bt!==null)i=Bt,Bt=Bt.cursor,i.prev=r,i.ne...
method releaseCursor (line 1) | releaseCursor(){let{cursor:r}=this;this.cursor=r.cursor,r.prev=null,r....
method updateCursors (line 1) | updateCursors(r,t,i,o){let{cursor:n}=this;while(n!==null){if(n.prev===...
method size (line 1) | get size(){let r=0;for(let t=this.head;t!==null;t=t.next)r++;return r}
method isEmpty (line 1) | get isEmpty(){return this.head===null}
method first (line 1) | get first(){return this.head&&this.head.data}
method last (line 1) | get last(){return this.tail&&this.tail.data}
method fromArray (line 1) | fromArray(r){let t=null;this.head=null;for(let i of r){let o=or.create...
method toArray (line 1) | toArray(){return[...this]}
method toJSON (line 1) | toJSON(){return[...this]}
method forEach (line 1) | forEach(r,t=this){let i=this.allocateCursor(null,this.head);while(i.ne...
method forEachRight (line 1) | forEachRight(r,t=this){let i=this.allocateCursor(this.tail,null);while...
method reduce (line 1) | reduce(r,t,i=this){let o=this.allocateCursor(null,this.head),n=t,e;whi...
method reduceRight (line 1) | reduceRight(r,t,i=this){let o=this.allocateCursor(this.tail,null),n=t,...
method some (line 1) | some(r,t=this){for(let i=this.head;i!==null;i=i.next)if(r.call(t,i.dat...
method map (line 1) | map(r,t=this){let i=new or;for(let o=this.head;o!==null;o=o.next)i.app...
method filter (line 1) | filter(r,t=this){let i=new or;for(let o=this.head;o!==null;o=o.next)if...
method nextUntil (line 1) | nextUntil(r,t,i=this){if(r===null)return;let o=this.allocateCursor(nul...
method prevUntil (line 1) | prevUntil(r,t,i=this){if(r===null)return;let o=this.allocateCursor(r,n...
method clear (line 1) | clear(){this.head=null,this.tail=null}
method copy (line 1) | copy(){let r=new or;for(let t of this)r.appendData(t);return r}
method prepend (line 1) | prepend(r){if(this.updateCursors(null,r,this.head,r),this.head!==null)...
method prependData (line 1) | prependData(r){return this.prepend(or.createItem(r))}
method append (line 1) | append(r){return this.insert(r)}
method appendData (line 1) | appendData(r){return this.insert(or.createItem(r))}
method insert (line 1) | insert(r,t=null){if(t!==null)if(this.updateCursors(t.prev,r,t,r),t.pre...
method insertData (line 1) | insertData(r,t){return this.insert(or.createItem(r),t)}
method remove (line 1) | remove(r){if(this.updateCursors(r,r.prev,r,r.next),r.prev!==null)r.pre...
method push (line 1) | push(r){this.insert(or.createItem(r))}
method pop (line 1) | pop(){return this.tail!==null?this.remove(this.tail):null}
method unshift (line 1) | unshift(r){this.prepend(or.createItem(r))}
method shift (line 1) | shift(){return this.head!==null?this.remove(this.head):null}
method prependList (line 1) | prependList(r){return this.insertList(r,this.head)}
method appendList (line 1) | appendList(r){return this.insertList(r)}
method insertList (line 1) | insertList(r,t){if(r.head===null)return this;if(t!==void 0&&t!==null){...
method replace (line 1) | replace(r,t){if("head"in t)this.insertList(t,r);else this.insert(t,r);...
method [Symbol.iterator] (line 1) | *[Symbol.iterator](){for(let r=this.head;r!==null;r=r.next)yield r.data}
function kt (line 1) | function kt(r,t){let i=Object.create(SyntaxError.prototype),o=Error();re...
function o0 (line 2) | function o0({source:r,line:t,column:i,baseLine:o,baseColumn:n},e){functi...
function ye (line 5) | function ye(r,t,i,o,n,e=1,l=1){return Object.assign(kt("SyntaxError",r),...
function e0 (line 6) | function e0(r){let t=this.createList(),i=!1,o={recognizer:r};while(!this...
function h6 (line 6) | function h6(r){return function(){return this[r]()}}
function He (line 6) | function He(r){let t=Object.create(null);for(let i of Object.keys(r)){le...
function $6 (line 6) | function $6(r){let t={context:Object.create(null),features:Object.assign...
function g0 (line 6) | function g0(r){let t="",i="<unknown>",o=!1,n=l0,e=!1,l=new Hi,u=Object.a...
function Wr (line 6) | function Wr(r){if(!r)r={};this._file=ur.getArg(r,"file",null),this._sour...
function k0 (line 6) | function k0(r){let t=new de,i={line:1,column:0},o={line:0,column:0},n={l...
function J0 (line 6) | function J0(r){let t=new Set(r.map(([i,o])=>se(i)<<16|se(o)));return fun...
function bz (line 6) | function bz(r,t){if(typeof t==="function"){let i=null;r.children.forEach...
function vz (line 6) | function vz(r){vt(r,(t,i,o)=>{this.token(t,r.slice(i,o))})}
function P0 (line 6) | function P0(r){let t=new Map;for(let[i,o]of Object.entries(r.node))if(ty...
function E0 (line 7) | function E0(r){return{fromPlainObject(t){return r(t,{enter(i){if(i.child...
function K0 (line 7) | function K0(r){return typeof r==="function"?r:Jn}
function L0 (line 7) | function L0(r,t){return function(i,o,n){if(i.type===t)r.call(this,i,o,n)}}
function hz (line 7) | function hz(r,t){let i=t.structure,o=[];for(let n in i){if(tl.call(i,n)=...
function $z (line 7) | function $z(r){let t={};for(let i in r.node)if(tl.call(r.node,i)){let o=...
function X0 (line 7) | function X0(r,t){let i=r.fields.slice(),o=r.context,n=typeof o==="string...
function W0 (line 7) | function W0({StyleSheet:r,Atrule:t,Rule:i,Block:o,DeclarationList:n}){re...
function q0 (line 7) | function q0(r){let t=$z(r),i={},o={},n=Symbol("break-walk"),e=Symbol("sk...
function fz (line 7) | function fz(r){return r}
function xz (line 7) | function xz(r){let{min:t,max:i,comma:o}=r;if(t===0&&i===0)return o?"#?":...
function wz (line 7) | function wz(r){switch(r.type){case"Range":return" ["+(r.min===null?"-∞":...
function az (line 7) | function az(r,t,i,o){let n=r.combinator===" "||o?r.combinator:" "+r.comb...
function si (line 7) | function si(r,t,i,o){let n;switch(r.type){case"Group":n=az(r,t,i,o)+(r.d...
function Rt (line 7) | function Rt(r,t){let i=fz,o=!1,n=!1;if(typeof t==="function")i=t;else if...
function zz (line 7) | function zz(r,t){let{tokens:i,longestMatch:o}=r,n=o<i.length?i[o].node||...
function ro (line 7) | function ro(r,t){let i=r&&r.loc&&r.loc[t];if(i)return"line"in i?Pn(i):i;...
function Pn (line 7) | function Pn({offset:r,line:t,column:i},o){let n={offset:r,line:t,column:...
function io (line 10) | function io(r,t){return t=t||0,r.length-t>=2&&r.charCodeAt(t)===45&&r.ch...
function V0 (line 10) | function V0(r,t){if(t=t||0,r.length-t>=3){if(r.charCodeAt(t)===45&&r.cha...
function _z (line 10) | function _z(r){if(to.has(r))return to.get(r);let t=r.toLowerCase(),i=to....
function Oz (line 10) | function Oz(r){if(Mt.has(r))return Mt.get(r);let t=r,i=r[0];if(i==="/")i...
function el (line 10) | function el(r,t){return r!==null&&r.type===P&&r.value.charCodeAt(0)===t}
function En (line 10) | function En(r,t,i){while(r!==null&&(r.type===N||r.type===y))r=i(++t);ret...
function ht (line 10) | function ht(r,t,i,o){if(!r)return 0;let n=r.value.charCodeAt(t);if(n===K...
function ol (line 10) | function ol(r,t,i){let o=!1,n=En(r,t,i);if(r=i(n),r===null)return t;if(r...
function ll (line 10) | function ll(r,t){let i=0;if(!r)return 0;if(r.type===U)return ht(r,0,pz,i...
function cl (line 10) | function cl(r,t){return r!==null&&r.type===P&&r.value.charCodeAt(0)===t}
function kz (line 10) | function kz(r,t){return r.value.charCodeAt(0)===t}
function Ln (line 10) | function Ln(r,t,i){let o=0;for(let n=t;n<r.value.length;n++){let e=r.val...
function oo (line 10) | function oo(r,t,i){if(!r)return 0;while(cl(i(t),F0)){if(++r>6)return 0;t...
function ul (line 10) | function ul(r,t){let i=0;if(r===null||r.type!==w||!sr(r.value,0,jz))retu...
function Yr (line 10) | function Yr(r,t){return t<r.length?r.charCodeAt(t):0}
function Q0 (line 10) | function Q0(r,t){return rt(r,0,r.length,t)}
function G0 (line 10) | function G0(r,t){for(let i=0;i<t.length;i++)if(Q0(r,t[i]))return!0;retur...
function A0 (line 10) | function A0(r,t){if(t!==r.length-2)return!1;return Yr(r,t)===92&&cr(Yr(r...
function eo (line 10) | function eo(r,t,i){if(r&&r.type==="Range"){let o=Number(i!==void 0&&i!==...
function Jz (line 10) | function Jz(r,t){let i=0,o=[],n=0;r:do{switch(r.type){case fr:case p:cas...
function qr (line 10) | function qr(r){return function(t,i,o){if(t===null)return 0;if(t.type===k...
function T (line 10) | function T(r){return function(t){if(t===null||t.type!==r)return 0;return...
function Pz (line 10) | function Pz(r){if(r===null||r.type!==w)return 0;let t=r.value.toLowerCas...
function B0 (line 10) | function B0(r){if(r===null||r.type!==w)return 0;if(Yr(r.value,0)!==45||Y...
function Ez (line 10) | function Ez(r){if(!B0(r))return 0;if(r.value==="--")return 0;return 1}
function Kz (line 10) | function Kz(r){if(r===null||r.type!==F)return 0;let t=r.value.length;if(...
function Lz (line 10) | function Lz(r){if(r===null||r.type!==F)return 0;if(!Ft(Yr(r.value,1),Yr(...
function Xz (line 10) | function Xz(r,t){if(!r)return 0;let i=0,o=[],n=0;r:do{switch(r.type){cas...
function Wz (line 10) | function Wz(r,t){if(!r)return 0;let i=0,o=[],n=0;r:do{switch(r.type){cas...
function it (line 10) | function it(r){if(r)r=new Set(r);return function(t,i,o){if(t===null||t.t...
function qz (line 10) | function qz(r,t,i){if(r===null||r.type!==B)return 0;if(eo(i,r.value,r.va...
function y0 (line 10) | function y0(r){if(typeof r!=="function")r=function(){return 0};return fu...
function Nz (line 10) | function Nz(r,t,i){if(r===null)return 0;let o=It(r.value,0);if(o!==r.val...
function Sz (line 10) | function Sz(r,t,i){if(r===null||r.type!==U)return 0;let o=Yr(r.value,0)=...
function Fz (line 10) | function Fz(r){let{angle:t,decibel:i,frequency:o,flex:n,length:e,resolut...
function R0 (line 10) | function R0(r){return{...Vz,...Yz,...Fz(r)}}
function ml (line 10) | function ml(r,t,i){return Object.assign(kt("SyntaxError",r),{input:t,off...
class bl (line 12) | class bl{constructor(r){this.str=r,this.pos=0}charCodeAt(r){return r<thi...
method constructor (line 12) | constructor(r){this.str=r,this.pos=0}
method charCodeAt (line 12) | charCodeAt(r){return r<this.str.length?this.str.charCodeAt(r):0}
method charCode (line 12) | charCode(){return this.charCodeAt(this.pos)}
method isNameCharCode (line 12) | isNameCharCode(r=this.charCode()){return r<128&&H0[r]===1}
method nextCharCode (line 12) | nextCharCode(){return this.charCodeAt(this.pos+1)}
method nextNonWsCode (line 12) | nextNonWsCode(r){return this.charCodeAt(this.findWsEnd(r))}
method skipWs (line 12) | skipWs(){this.pos=this.findWsEnd(this.pos)}
method findWsEnd (line 12) | findWsEnd(r){for(;r<this.str.length;r++){let t=this.str.charCodeAt(r);...
method substringToPos (line 12) | substringToPos(r){return this.str.substring(this.pos,this.pos=r)}
method eat (line 12) | eat(r){if(this.charCode()!==r)this.error("Expect `"+String.fromCharCod...
method peek (line 12) | peek(){return this.pos<this.str.length?this.str.charAt(this.pos++):""}
method error (line 12) | error(r){throw new ml(r,this.str,this.pos)}
method scanSpaces (line 12) | scanSpaces(){return this.substringToPos(this.findWsEnd(this.pos))}
method scanWord (line 12) | scanWord(){let r=this.pos;for(;r<this.str.length;r++){let t=this.str.c...
method scanNumber (line 12) | scanNumber(){let r=this.pos;for(;r<this.str.length;r++){let t=this.str...
method scanString (line 12) | scanString(){let r=this.str.indexOf("'",this.pos+1);if(r===-1)this.pos...
function rf (line 12) | function rf(r){let t=null,i=null;if(r.eat(uo),r.skipWs(),t=r.scanNumber(...
function c1 (line 12) | function c1(r){let t=null,i=!1;switch(r.charCode()){case of:r.pos++,t={m...
function $t (line 12) | function $t(r,t){let i=c1(r);if(i!==null){if(i.term=t,r.charCode()===fl&...
function vl (line 12) | function vl(r){let t=r.peek();if(t==="")return null;return $t(r,{type:"T...
function u1 (line 12) | function u1(r){let t;return r.eat(al),r.eat(co),t=r.scanWord(),r.eat(co)...
function g1 (line 12) | function g1(r){let t=null,i=null,o=1;if(r.eat(Xn),r.charCode()===Z0)r.pe...
function m1 (line 12) | function m1(r){let t,i=null;if(r.eat(al),t=r.scanWord(),t==="boolean-exp...
function b1 (line 12) | function b1(r){let t=r.scanWord();if(r.charCode()===nf)return r.pos++,{t...
function v1 (line 12) | function v1(r,t){function i(n,e){return{type:"Group",terms:n,combinator:...
function zl (line 12) | function zl(r,t){let i=Object.create(null),o=[],n,e=null,l=r.pos;while(r...
function h1 (line 12) | function h1(r,t){let i;if(r.eat(Xn),i=zl(r,t),r.eat(Wn),i.explicit=!0,r....
function $1 (line 12) | function $1(r,t){let i=r.charCode();switch(i){case Wn:break;case Xn:retu...
function qn (line 12) | function qn(r){let t=new bl(r),i=zl(t);if(t.pos!==r.length)t.error("Unex...
function ef (line 12) | function ef(r){return typeof r==="function"?r:Nn}
function _l (line 12) | function _l(r,t,i){function o(l){switch(n.call(i,l),l.type){case"Group":...
method decorator (line 12) | decorator(r){let t=[],i=null;return{...r,node(o){let n=i;i=o,r.node.call...
function w1 (line 12) | function w1(r){let t=[];return vt(r,(i,o,n)=>t.push({type:i,value:r.slic...
function Ol (line 12) | function Ol(r,t){if(typeof r==="string")return w1(r);return t.generate(r...
function _r (line 12) | function _r(r,t,i){if(t===G&&i===R)return r;if(r===G&&t===G&&i===G)retur...
function cf (line 12) | function cf(r){return r.length>2&&r.charCodeAt(r.length-2)===a1&&r.charC...
function lf (line 12) | function lf(r){return r.type==="Keyword"||r.type==="AtKeyword"||r.type==...
function ft (line 12) | function ft(r,t=" ",i=!1){return{type:"Group",terms:r,combinator:t,disal...
function Sn (line 12) | function Sn(r,t,i=new Set){if(!i.has(r))switch(i.add(r),r.type){case"If"...
function Dl (line 12) | function Dl(r,t,i){switch(r){case" ":{let o=G;for(let n=t.length-1;n>=0;...
function _1 (line 12) | function _1(r){let t=G,i=Ct(r.term);if(r.max===0){if(i=_r(i,go,R),t=_r(i...
function Ct (line 12) | function Ct(r){if(typeof r==="function")return{type:"Generic",fn:r};swit...
function Vn (line 12) | function Vn(r,t){if(typeof r==="string")r=qn(r);return{type:"MatchGraph"...
function k1 (line 12) | function k1(r){let t=null,i=null,o=r;while(o!==null)i=o.prev,o.prev=t,t=...
function pl (line 12) | function pl(r,t){if(r.length!==t.length)return!1;for(let i=0;i<r.length;...
function U1 (line 12) | function U1(r){if(r.type!==P)return!1;return r.value!=="?"}
function bf (line 12) | function bf(r){if(r===null)return!0;return r.type===ir||r.type===k||r.ty...
function vf (line 12) | function vf(r){if(r===null)return!0;return r.type===p||r.type===wr||r.ty...
function J1 (line 12) | function J1(r,t,i){function o(){do J++,O=J<r.length?r[J]:null;while(O!==...
function jl (line 12) | function jl(r,t,i){let o=J1(r,t,i||{});if(o.match===null)return o;let n=...
function $f (line 12) | function $f(r){function t(n){if(n===null)return!1;return n.type==="Type"...
function P1 (line 12) | function P1(r,t){return kl(this,r,(i)=>i.type==="Type"&&i.name===t)}
function E1 (line 12) | function E1(r,t){return kl(this,r,(i)=>i.type==="Property"&&i.name===t)}
function K1 (line 12) | function K1(r){return kl(this,r,(t)=>t.type==="Keyword")}
function kl (line 12) | function kl(r,t,i){let o=$f.call(r,t);if(o===null)return!1;return o.some...
function ff (line 12) | function ff(r){if("node"in r)return r.node;return ff(r.match[0])}
function xf (line 12) | function xf(r){if("node"in r)return r.node;return xf(r.match[r.match.len...
function Jl (line 12) | function Jl(r,t,i,o,n){function e(u){if(u.syntax!==null&&u.syntax.type==...
function Pl (line 12) | function Pl(r){return typeof r==="number"&&isFinite(r)&&Math.floor(r)===...
function wf (line 12) | function wf(r){return Boolean(r)&&Pl(r.offset)&&Pl(r.line)&&Pl(r.column)}
function L1 (line 12) | function L1(r,t){return function(o,n){if(!o||o.constructor!==Object)retu...
function af (line 12) | function af(r,t){let i=[];for(let o=0;o<r.length;o++){let n=r[o];if(n===...
function X1 (line 12) | function X1(r,t){let i=t.structure,o={type:String,loc:!0},n={type:'"'+r+...
function zf (line 12) | function zf(r){let t={};if(r.node){for(let i in r.node)if(Yn.call(r.node...
function El (line 12) | function El(r,t,i){let o={};for(let n in r)if(r[n].syntax)o[n]=i?r[n].sy...
function W1 (line 12) | function W1(r,t,i){let o={};for(let[n,e]of Object.entries(r))o[n]={prelu...
function q1 (line 12) | function q1(r){for(let t=0;t<r.length;t++)if(r[t].value.toLowerCase()===...
function N1 (line 12) | function N1(r){let t=r.terms[0];return r.explicit===!1&&r.terms.length==...
function Fr (line 12) | function Fr(r,t,i){return{matched:r,iterations:i,error:t,...Ul}}
function dt (line 12) | function dt(r,t,i,o){let n=Ol(i,r.syntax),e;if(q1(n))return Fr(null,Erro...
class Fn (line 12) | class Fn{constructor(r,t,i){if(this.cssWideKeywords=Zt,this.syntax=t,thi...
method constructor (line 12) | constructor(r,t,i){if(this.cssWideKeywords=Zt,this.syntax=t,this.gener...
method checkStructure (line 12) | checkStructure(r){function t(n,e){o.push({node:n,message:e})}let i=thi...
method createDescriptor (line 12) | createDescriptor(r,t,i,o=null){let n={type:t,name:i},e={type:t,name:i,...
method addAtrule_ (line 12) | addAtrule_(r,t){if(!t)return;this.atrules[r]={type:"Atrule",name:r,pre...
method addProperty_ (line 12) | addProperty_(r,t){if(!t)return;this.properties[r]=this.createDescripto...
method addType_ (line 12) | addType_(r,t){if(!t)return;this.types[r]=this.createDescriptor(t,"Type...
method checkAtruleName (line 12) | checkAtruleName(r){if(!this.getAtrule(r))return new Ht("Unknown at-rul...
method checkAtrulePrelude (line 12) | checkAtrulePrelude(r,t){let i=this.checkAtruleName(r);if(i)return i;le...
method checkAtruleDescriptorName (line 12) | checkAtruleDescriptorName(r,t){let i=this.checkAtruleName(r);if(i)retu...
method checkPropertyName (line 12) | checkPropertyName(r){if(!this.getProperty(r))return new Ht("Unknown pr...
method matchAtrulePrelude (line 12) | matchAtrulePrelude(r,t){let i=this.checkAtrulePrelude(r,t);if(i)return...
method matchAtruleDescriptor (line 12) | matchAtruleDescriptor(r,t,i){let o=this.checkAtruleDescriptorName(r,t)...
method matchDeclaration (line 12) | matchDeclaration(r){if(r.type!=="Declaration")return Fr(null,Error("No...
method matchProperty (line 12) | matchProperty(r,t){if(nl(r).custom)return Fr(null,Error("Lexer matchin...
method matchType (line 12) | matchType(r,t){let i=this.getType(r);if(!i)return Fr(null,new Ht("Unkn...
method match (line 12) | match(r,t){if(typeof r!=="string"&&(!r||!r.type))return Fr(null,new Ht...
method findValueFragments (line 12) | findValueFragments(r,t,i,o){return Jl(this,t,this.matchProperty(r,t),i...
method findDeclarationValueFragments (line 12) | findDeclarationValueFragments(r,t,i){return Jl(this,r.value,this.match...
method findAllFragments (line 12) | findAllFragments(r,t,i){let o=[];return this.syntax.walk(r,{visit:"Dec...
method getAtrule (line 12) | getAtrule(r,t=!0){let i=no(r);return(i.vendor&&t?this.atrules[i.name]|...
method getAtrulePrelude (line 12) | getAtrulePrelude(r,t=!0){let i=this.getAtrule(r,t);return i&&i.prelude...
method getAtruleDescriptor (line 12) | getAtruleDescriptor(r,t){return this.atrules.hasOwnProperty(r)&&this.a...
method getProperty (line 12) | getProperty(r,t=!0){let i=nl(r);return(i.vendor&&t?this.properties[i.n...
method getType (line 12) | getType(r){return hasOwnProperty.call(this.types,r)?this.types[r]:null}
method validate (line 12) | validate(){function r(u,g){return g?`<${u}>`:`<'${u}'>`}function t(u,g...
method dump (line 12) | dump(r,t){return{generic:this.generic,cssWideKeywords:this.cssWideKeyw...
method toString (line 12) | toString(){return JSON.stringify(this.dump())}
function Kl (line 12) | function Kl(r,t){if(typeof t==="string"&&/^\s*\|/.test(t))return typeof ...
function _f (line 12) | function _f(r,t){let i=Object.create(null);for(let[o,n]of Object.entries...
function Qn (line 12) | function Qn(r,t){let i={...r};for(let[o,n]of Object.entries(t))switch(o)...
function Of (line 12) | function Of(r){let t=g0(r),i=q0(r),o=P0(r),{fromPlainObject:n,toPlainObj...
function bo (line 12) | function bo(r,t){let i=this.tokenStart+r,o=this.charCodeAt(i);if(o===Mr|...
function st (line 12) | function st(r){return bo.call(this,0,r)}
function xt (line 12) | function xt(r,t){if(!this.cmpChar(this.tokenStart+r,t)){let i="";switch(...
function Xl (line 12) | function Xl(){let r=0,t=0,i=this.tokenType;while(i===N||i===y)i=this.loo...
function Wl (line 12) | function Wl(){let r=this.tokenStart,t=null,i=null;if(this.tokenType===U)...
function F1 (line 12) | function F1(r){if(r.a){let t=r.a==="+1"&&"n"||r.a==="1"&&"n"||r.a==="-1"...
function pf (line 12) | function pf(){return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicol...
function Q1 (line 12) | function Q1(){for(let r=1,t;t=this.lookupType(r);r++){if(t===fr)return!0...
function Nl (line 12) | function Nl(r=!1){let t=this.tokenStart,i,o,n=null,e=null;if(this.eat(H)...
function y1 (line 12) | function y1(r){if(this.token(H,"@"+r.name),r.prelude!==null)this.node(r....
function Vl (line 12) | function Vl(r){let t=null;if(r!==null)r=r.toLowerCase();if(this.skipSC()...
function Z1 (line 12) | function Z1(r){this.children(r)}
function s1 (line 12) | function s1(){if(this.eof)this.error("Unexpected end of input");let r=th...
function r_ (line 12) | function r_(){let r=this.tokenStart,t=this.charCodeAt(r);if(t!==vo&&t!==...
function Ql (line 12) | function Ql(){let r=this.tokenStart,t,i=null,o=null,n=null;if(this.eat(m...
function i_ (line 12) | function i_(r){if(this.token(P,"["),this.node(r.name),r.matcher!==null)t...
function Uf (line 12) | function Uf(){return this.Raw(null,!0)}
function jf (line 12) | function jf(){return this.parseWithFallback(this.Rule,Uf)}
function kf (line 12) | function kf(){return this.Raw(this.consumeUntilSemicolonIncluded,!0)}
function e_ (line 12) | function e_(){if(this.tokenType===nr)return kf.call(this,this.tokenIndex...
function Al (line 12) | function Al(r){let t=r?e_:jf,i=this.tokenStart,o=this.createList();this....
function g_ (line 12) | function g_(r){this.token(Z,"{"),this.children(r,(t)=>{if(t.type==="Decl...
function yl (line 12) | function yl(r,t){let i=this.tokenStart,o=null;if(this.eat(mr),o=r.call(t...
function v_ (line 12) | function v_(r){this.token(P,"["),this.children(r),this.token(P,"]")}
function Hl (line 12) | function Hl(){let r=this.tokenStart;return this.eat(hr),{type:"CDC",loc:...
function f_ (line 12) | function f_(){this.token(hr,"-->")}
function Zl (line 12) | function Zl(){let r=this.tokenStart;return this.eat(dr),{type:"CDO",loc:...
function a_ (line 12) | function a_(){this.token(dr,"<!--")}
function Cl (line 12) | function Cl(){return this.eatDelim(z_),{type:"ClassSelector",loc:this.ge...
function D_ (line 12) | function D_(r){this.token(P,"."),this.token(w,r.name)}
function sl (line 12) | function sl(){let r=this.tokenStart,t;switch(this.tokenType){case N:t=" ...
function J_ (line 12) | function J_(r){this.tokenize(r.name)}
function tc (line 12) | function tc(){let r=this.tokenStart,t=this.tokenEnd;if(this.eat(y),t-r+2...
function X_ (line 12) | function X_(r){this.token(y,"/*"+r.value+"*/")}
function Pf (line 12) | function Pf(r){if(this.lookupTypeNonSC(1)===w&&W_.has(this.lookupTypeNon...
method supports (line 12) | supports(){return this.SupportsDeclaration()}
function ic (line 12) | function ic(r="media"){let t=this.createList();r:while(!this.eof)switch(...
function V_ (line 12) | function V_(r){r.children.forEach((t)=>{if(t.type==="Condition")this.tok...
function B_ (line 12) | function B_(){return this.Raw(this.consumeUntilExclamationMarkOrSemicolo...
function y_ (line 12) | function y_(){return this.Raw(this.consumeUntilExclamationMarkOrSemicolo...
function R_ (line 12) | function R_(){let r=this.tokenIndex,t=this.Value();if(t.type!=="Raw"&&th...
function ec (line 12) | function ec(){let r=this.tokenStart,t=this.tokenIndex,i=C_.call(this),o=...
function T_ (line 12) | function T_(r){if(this.token(w,r.property),this.token(d,":"),this.node(r...
function C_ (line 12) | function C_(){let r=this.tokenStart;if(this.tokenType===P)switch(this.ch...
function d_ (line 12) | function d_(){this.eat(P),this.skipSC();let r=this.consume(w);return r==...
function cc (line 12) | function cc(){return this.Raw(this.consumeUntilSemicolonIncluded,!0)}
function uc (line 12) | function uc(){let r=this.createList();r:while(!this.eof)switch(this.toke...
function nO (line 12) | function nO(r){this.children(r,(t)=>{if(t.type==="Declaration")this.toke...
function mc (line 12) | function mc(){let r=this.tokenStart,t=this.consumeNumber(K);return{type:...
function eO (line 12) | function eO(r){this.token(K,r.value+r.unit)}
function vc (line 12) | function vc(r){let t=this.tokenStart,i,o=null;if(this.eat(X),this.skipSC...
function gO (line 12) | function gO(r){if(this.token(X,"("),this.token(w,r.name),r.value!==null)...
function vO (line 12) | function vO(r,t){let o=(this.features[r]||{})[t];if(typeof o!=="function...
function $c (line 12) | function $c(r="unknown"){let t=this.tokenStart,i=this.consumeFunctionNam...
function hO (line 12) | function hO(r){this.token(k,r.feature+"("),this.node(r.value),this.token...
function xc (line 12) | function xc(){switch(this.skipSC(),this.tokenType){case U:if(this.isDeli...
function Wf (line 12) | function Wf(r){if(this.skipSC(),this.isDelim($O)||this.isDelim(fO)){let ...
function wc (line 12) | function wc(r="unknown"){let t=this.tokenStart;this.skipSC(),this.eat(X)...
function aO (line 12) | function aO(r){if(this.token(X,"("),this.node(r.left),this.tokenize(r.le...
function zc (line 12) | function zc(r,t){let i=this.tokenStart,o=this.consumeFunctionName(),n=o....
function DO (line 12) | function DO(r){this.token(k,r.name+"("),this.children(r),this.token(p,")")}
function Oc (line 12) | function Oc(r){let t=this.tokenStart,i=null;if(this.tokenType===k)i=this...
function jO (line 12) | function jO(r){if(r.function)this.token(k,r.function+"(");else this.toke...
function pc (line 12) | function pc(){let r=this.tokenStart;return this.eat(F),{type:"Hash",loc:...
function PO (line 12) | function PO(r){this.token(F,"#"+r.value)}
function jc (line 12) | function jc(){return{type:"Identifier",loc:this.getLocation(this.tokenSt...
function LO (line 12) | function LO(r){this.token(w,r.name)}
function Uc (line 12) | function Uc(){let r=this.tokenStart;return this.eat(F),{type:"IdSelector...
function qO (line 12) | function qO(r){this.token(P,"#"+r.name)}
function Pc (line 12) | function Pc(){let r=this.tokenStart,t=this.consume(w);while(this.isDelim...
function YO (line 12) | function YO(r){this.tokenize(r.name)}
function Kc (line 12) | function Kc(){let r=this.createList();this.skipSC();while(!this.eof){if(...
function GO (line 12) | function GO(r){this.children(r,()=>this.token(ir,","))}
function Xc (line 12) | function Xc(){let r=this.tokenStart,t=null,i=null,o=null;if(this.skipSC(...
function yO (line 12) | function yO(r){if(r.mediaType){if(r.modifier)this.token(w,r.modifier);if...
function qc (line 12) | function qc(){let r=this.createList();this.skipSC();while(!this.eof){if(...
function MO (line 12) | function MO(r){this.children(r,()=>this.token(ir,","))}
function Sc (line 12) | function Sc(){let r=this.tokenStart;return this.eatDelim(ZO),{type:"Nest...
function dO (line 12) | function dO(){this.token(P,"&")}
function Yc (line 12) | function Yc(){this.skipSC();let r=this.tokenStart,t=r,i=null,o;if(this.l...
function tD (line 12) | function tD(r){if(this.node(r.nth),r.selector!==null)this.token(w,"of"),...
function Qc (line 12) | function Qc(){return{type:"Number",loc:this.getLocation(this.tokenStart,...
function oD (line 12) | function oD(r){this.token(U,r.value)}
function Ac (line 12) | function Ac(){let r=this.tokenStart;return this.next(),{type:"Operator",...
function cD (line 12) | function cD(r){this.tokenize(r.value)}
function yc (line 12) | function yc(r,t){let i=this.tokenStart,o=null;if(this.eat(X),o=r.call(th...
function mD (line 12) | function mD(r){this.token(X,"("),this.children(r),this.token(p,")")}
function Hc (line 12) | function Hc(){return{type:"Percentage",loc:this.getLocation(this.tokenSt...
function hD (line 12) | function hD(r){this.token(B,r.value+"%")}
function Zc (line 12) | function Zc(){let r=this.tokenStart,t=null,i,o;if(this.eat(d),this.token...
function wD (line 12) | function wD(r){if(this.token(d,":"),r.children===null)this.token(w,r.nam...
function Cc (line 12) | function Cc(){let r=this.tokenStart,t=null,i,o;if(this.eat(d),this.eat(d...
function OD (line 12) | function OD(r){if(this.token(d,":"),this.token(d,":"),r.children===null)...
function Nf (line 12) | function Nf(){switch(this.skipSC(),this.tokenType){case U:return this.Nu...
function sc (line 12) | function sc(){let r=this.tokenStart,t=Nf.call(this),i=null;if(this.skipS...
function ID (line 12) | function ID(r){if(this.node(r.left),this.token(P,"/"),r.right)this.node(...
function jD (line 12) | function jD(){if(this.tokenIndex>0){if(this.lookupType(-1)===N)return th...
function tu (line 12) | function tu(r,t){let i=this.getTokenStart(this.tokenIndex),o;if(this.ski...
function JD (line 12) | function JD(r){this.tokenize(r.value)}
function Sf (line 12) | function Sf(){return this.Raw(this.consumeUntilLeftCurlyBracket,!0)}
function PD (line 12) | function PD(){let r=this.SelectorList();if(r.type!=="Raw"&&this.eof===!1...
function iu (line 12) | function iu(){let r=this.tokenIndex,t=this.tokenStart,i,o;if(this.parseR...
function XD (line 12) | function XD(r){this.node(r.prelude),this.node(r.block)}
function eu (line 12) | function eu(){let r=null,t=null;this.skipSC();let i=this.tokenStart;if(t...
function ND (line 12) | function ND(r){if(r.root)this.token(X,"("),this.node(r.root),this.token(...
function cu (line 12) | function cu(){let r=this.readSequence(this.scope.Selector);if(this.getFi...
function YD (line 12) | function YD(r){this.children(r)}
function gu (line 12) | function gu(){let r=this.createList();while(!this.eof){if(r.push(this.Se...
function AD (line 12) | function AD(r){this.children(r,()=>this.token(ir,","))}
function ho (line 12) | function ho(r){let t=r.length,i=r.charCodeAt(0),o=i===Vf||i===Yf?1:0,n=o...
function Ff (line 12) | function Ff(r,t){let i=t?"'":'"',o=t?Yf:Vf,n="",e=!1;for(let l=0;l<r.len...
function vu (line 12) | function vu(){return{type:"String",loc:this.getLocation(this.tokenStart,...
function RD (line 12) | function RD(r){this.token(gr,Ff(r.value))}
function Gf (line 12) | function Gf(){return this.Raw(null,!1)}
function $u (line 12) | function $u(){let r=this.tokenStart,t=this.createList(),i;r:while(!this....
function CD (line 12) | function CD(r){this.children(r)}
function xu (line 12) | function xu(){let r=this.tokenStart;this.eat(X),this.skipSC();let t=this...
function rp (line 12) | function rp(r){this.token(X,"("),this.node(r.declaration),this.token(p,"...
function au (line 12) | function au(){if(this.tokenType!==w&&this.isDelim(tp)===!1)this.error("I...
function zu (line 12) | function zu(){let r=this.tokenStart;if(this.isDelim(Af))this.next(),au.c...
function op (line 12) | function op(r){this.tokenize(r.name)}
function Gn (line 12) | function Gn(r,t){let i=0;for(let o=this.tokenStart+r;o<this.tokenEnd;o++...
function $o (line 12) | function $o(r){let t=0;while(this.isDelim(Ou)){if(++t>r)this.error("Too ...
function ep (line 12) | function ep(r){if(this.charCodeAt(this.tokenStart)!==r)this.error((r===B...
function lp (line 12) | function lp(){let r=0;switch(this.tokenType){case U:if(r=Gn.call(this,1,...
function Du (line 12) | function Du(){let r=this.tokenStart;return this.eatIdent("u"),lp.call(th...
function gp (line 12) | function gp(r){this.tokenize(r.value)}
function Hf (line 12) | function Hf(r){let t=r.length,i=4,o=r.charCodeAt(t-1)===Rf?t-2:t-1,n="";...
function Mf (line 12) | function Mf(r){let t="",i=!1;for(let o=0;o<r.length;o++){let n=r.charCod...
function ju (line 12) | function ju(){let r=this.tokenStart,t;switch(this.tokenType){case er:t=H...
function xp (line 12) | function xp(r){this.token(er,Mf(r.value))}
function Uu (line 12) | function Uu(){let r=this.tokenStart,t=this.readSequence(this.scope.Value...
function zp (line 12) | function zp(r){this.children(r)}
function Pu (line 12) | function Pu(){return this.eat(N),_p}
function pp (line 12) | function pp(r){this.token(N,r.value)}
function Bn (line 12) | function Bn(r){switch(this.tokenType){case F:return this.Hash();case ir:...
function Sp (line 12) | function Sp(r,t){if(t.last!==null&&t.last.type!=="Combinator"&&r!==null&...
function Vp (line 12) | function Vp(){switch(this.tokenType){case mr:return this.AttributeSelect...
function Ku (line 12) | function Ku(){return this.createSingleNodeList(this.Raw(null,!1))}
function Lu (line 12) | function Lu(){let r=this.createList();if(this.skipSC(),r.push(this.Ident...
function tx (line 12) | function tx(r){return r!==null&&r.type==="Operator"&&(r.value[r.value.le...
method onWhiteSpace (line 12) | onWhiteSpace(r,t){if(tx(r))r.value=" "+r.value;if(tx(t.last))t.last.valu...
method prelude (line 12) | prelude(){let r=this.createList();if(this.tokenType===w){let t=this.subs...
method block (line 12) | block(r=!1){return this.Block(r)}
method block (line 12) | block(){return this.Block(!0)}
function Wu (line 12) | function Wu(r,t){return this.parseWithFallback(()=>{try{return r.call(th...
method layer (line 12) | layer(){this.skipSC();let r=this.createList(),t=Wu.call(this,this.Layer)...
method supports (line 12) | supports(){this.skipSC();let r=this.createList(),t=Wu.call(this,this.Dec...
method prelude (line 12) | prelude(){let r=this.createList();switch(this.tokenType){case gr:r.push(...
method prelude (line 12) | prelude(){return this.createSingleNodeList(this.LayerList())}
method block (line 12) | block(){return this.Block(!1)}
method prelude (line 12) | prelude(){return this.createSingleNodeList(this.MediaQueryList())}
method block (line 12) | block(r=!1){return this.Block(r)}
method prelude (line 12) | prelude(){return this.createSingleNodeList(this.SelectorList())}
method block (line 12) | block(){return this.Block(!0)}
method prelude (line 12) | prelude(){return this.createSingleNodeList(this.SelectorList())}
method block (line 12) | block(){return this.Block(!0)}
method prelude (line 12) | prelude(){return this.createSingleNodeList(this.Scope())}
method block (line 12) | block(r=!1){return this.Block(r)}
method block (line 12) | block(r=!1){return this.Block(r)}
method prelude (line 12) | prelude(){return this.createSingleNodeList(this.Condition("supports"))}
method block (line 12) | block(r=!1){return this.Block(r)}
function fx (line 12) | function fx(){let r=this.createList();this.skipSC();r:while(!this.eof){s...
method parse (line 12) | parse(){return this.createSingleNodeList(this.SelectorList())}
method parse (line 12) | parse(){return this.createSingleNodeList(this.Selector())}
method parse (line 12) | parse(){return this.createSingleNodeList(this.Identifier())}
method parse (line 12) | parse(){return this.createSingleNodeList(this.Nth())}
method atrulePrelude (line 12) | atrulePrelude(r){return this.AtrulePrelude(r.atrule?String(r.atrule):null)}
method condition (line 12) | condition(r){return this.Condition(r.kind)}
method block (line 12) | block(){return this.Block(!0)}
method selector (line 12) | selector(){return this.Selector()}
method style (line 12) | style(){return this.Declaration()}
class rn (line 12) | class rn{static instance;constructor(){}injectDefaultStyles(){try{let r=...
method constructor (line 12) | constructor(){}
method injectDefaultStyles (line 12) | injectDefaultStyles(){try{let r=document.createElement("style");r.id="...
method getInstance (line 19) | static getInstance(){if(!rn.instance)rn.instance=new rn;return rn.inst...
method stylesheet (line 19) | get stylesheet(){let r=document.getElementById("onlook-stylesheet")||t...
method stylesheet (line 19) | set stylesheet(r){let t=document.getElementById("onlook-stylesheet")||...
method createStylesheet (line 19) | createStylesheet(){let r=document.createElement("style");return r.id="...
method find (line 19) | find(r,t){let i=[];return xo(r,{visit:"Rule",enter:(o)=>{if(o.type==="...
method updateStyle (line 19) | updateStyle(r,t){let i=Ne(r,!1),o=this.stylesheet;for(let[n,e]of Objec...
method addRule (line 19) | addRule(r,t,i,o){let n={type:"Rule",prelude:{type:"SelectorList",child...
method updateRule (line 19) | updateRule(r,t,i){let o=!1;if(xo(r.block,{visit:"Declaration",enter:(n...
method getJsStyle (line 19) | getJsStyle(r){let t=this.stylesheet,i=this.find(t,r),o={};if(!i.length...
method jsToCssProperty (line 19) | jsToCssProperty(r){if(!r)return"";return r.replace(/([A-Z])/g,"-$1").t...
method cssToJsProperty (line 19) | cssToJsProperty(r){if(!r)return"";return r.replace(/-([a-z])/g,(t)=>t[...
method removeStyles (line 19) | removeStyles(r,t){let i=Ne(r,!1),o=this.stylesheet;this.find(o,i).forE...
method clear (line 19) | clear(){this.stylesheet=Su("")}
function _x (line 19) | function _x(r,t){return ot.updateStyle(r,t.updated),Ni(r,!0)}
function Ox (line 19) | function Ox(r,t){ot.updateStyle(r,{backgroundImage:{value:`url(${t})`,ty...
function Dx (line 19) | function Dx(r){ot.updateStyle(r,{backgroundImage:{value:"none",type:"val...
function Ap (line 19) | function Ap(r,t){let i=Array.from(r.children);if(i.length===0)return 0;l...
function px (line 19) | function px(r,t){let i=Bp(r,t);if(!i)return null;let o=window.getCompute...
function Bp (line 19) | function Bp(r,t){let i=q$(r,t);if(!i)return null;let o=!0;while(i&&o)if(...
function Ix (line 19) | function Ix(r,t){let i=Q(t.targetDomId);if(!i){console.warn(`Target elem...
function jx (line 19) | function jx(r){let t=document.createElement(r.tagName);t.setAttribute("d...
function kx (line 19) | function kx(r){let t=Q(r.targetDomId);if(!t)return console.warn(`Target ...
function Ux (line 19) | function Ux(r,t){let i=Q(r);if(!i)return console.warn("Element not found...
function Jx (line 19) | function Jx(r,t){let i=Q(r);if(!i)return console.warn(`Move element not ...
function Px (line 19) | function Px(r){let t=Q(r);if(!t)return console.warn(`Element not found: ...
function yp (line 19) | function yp(r,t){let i=r.parentElement;if(!i){console.warn("Parent not f...
function wo (line 19) | function wo(r){if(!r||!r.children||r.children.length<2)return"vertical";...
function Ex (line 19) | function Ex(r,t,i,o){if(r.length===0)return 0;let n=r.map((e)=>{let l=e....
function Kx (line 19) | function Kx(r,t,i,o){let n=r.getBoundingClientRect(),e=window.getCompute...
function Lx (line 19) | function Lx(r){let t=document.createElement("div"),i=window.getComputedS...
function Xx (line 19) | function Xx(r,t,i){let o=document.getElementById("onlook-drag-stub");if(...
function Yu (line 19) | function Yu(){let r=document.getElementById("onlook-drag-stub");if(!r)re...
function Wx (line 19) | function Wx(r,t){let i=document.getElementById("onlook-drag-stub");if(!i...
function qx (line 19) | function qx(r){let t=Q(r);if(!t)return console.warn(`Start drag element ...
function Nx (line 19) | function Nx(r,t,i,o){let n=Q(r);if(!n){console.warn("Dragging element no...
function Sx (line 19) | function Sx(r,t,i,o,n){let e=Q(r);if(!e){console.warn("Dragging element ...
function Vx (line 19) | function Vx(r){let t=Q(r);if(!t)return console.warn("End drag element no...
function Yx (line 19) | function Yx(r){let t=Q(r);if(!t)return console.warn("End drag element no...
function Rp (line 19) | function Rp(r){if(r.getAttribute("data-onlook-drag-saved-style"))return;...
function Fu (line 19) | function Fu(r){qi(r),Fx(r),Pr(r)}
function Fx (line 19) | function Fx(r){r.removeAttribute("data-onlook-drag-saved-style"),r.remov...
function Hp (line 19) | function Hp(r){let t=r.getBoundingClientRect();return{left:t.left+window...
function Qu (line 19) | function Qu(){let r=document.querySelectorAll(`[${"data-onlook-dragging"...
function Qx (line 19) | function Qx(r){let t=Q(r);if(!t)return console.warn("Start editing text ...
function Gx (line 19) | function Gx(r,t){let i=Q(r);if(!i)return console.warn("Edit text failed....
function Ax (line 19) | function Ax(r){let t=Q(r);if(!t)return console.warn("Stop editing text f...
function Bx (line 19) | function Bx(r){r.setAttribute("data-onlook-editing-text","true")}
function Mp (line 19) | function Mp(r){qi(r),Zp(r)}
function Zp (line 19) | function Zp(r){r.removeAttribute("data-onlook-editing-text")}
function Tp (line 19) | function Tp(r,t){let o=t.replace(/\r\n/g,`
function yx (line 22) | function yx(r){let t=r.innerHTML;t=t.replace(/<br\s*\/?>/gi,`
function Rx (line 23) | function Rx(r){return!0}
function Mx (line 23) | function Mx(){let r=document.body,t={childList:!0,subtree:!0};new Mutati...
function Zx (line 23) | function Zx(){function r(){if(ar)ar.onWindowResized().catch((t)=>{consol...
function Hx (line 23) | function Hx(r){if(r.id==="onlook-drag-stub")return!0;if(r.getAttribute("...
function Cp (line 23) | function Cp(r){let t=r.getAttribute("data-oid");if(!t)return;document.qu...
function Tx (line 23) | function Tx(){Mx(),Zx()}
function Gu (line 23) | function Gu(){Tx(),dp(),ot.injectDefaultStyles()}
function dp (line 23) | function dp(){if(tn!==null)clearInterval(tn),tn=null;let r=setInterval((...
function dx (line 23) | async function dx(){try{let{innerWidth:r,innerHeight:t}=window,i=documen...
function Cx (line 23) | async function Cx(r){let o=[0.9,0.8,0.7,0.6,0.5,0.4,0.3],n=[1,0.8,0.6,0....
function rI (line 23) | async function rI(r,t,i){r.fillStyle="#ffffff",r.fillRect(0,0,t,i);let o...
function tI (line 23) | async function tI(r,t,i,o){let{left:n,top:e,width:l,height:u}=i;if(l<1||...
function $ (line 23) | function $(r,t,i){function o(u,g){var c;Object.defineProperty(u,"_zod",{...
class Zr (line 23) | class Zr extends Error{constructor(){super("Encountered Promise during s...
method constructor (line 23) | constructor(){super("Encountered Promise during synchronous parse. Use...
class Et (line 23) | class Et extends Error{constructor(r){super(`Encountered unidirectional ...
method constructor (line 23) | constructor(r){super(`Encountered unidirectional transform during enco...
function br (line 23) | function br(r){if(r)Object.assign(yn,r);return yn}
function nI (line 23) | function nI(r){return r}
function iI (line 23) | function iI(r){return r}
function oI (line 23) | function oI(r){}
function eI (line 23) | function eI(r){throw Error()}
function lI (line 23) | function lI(r){}
function Hn (line 23) | function Hn(r){let t=Object.values(r).filter((o)=>typeof o==="number");r...
function f (line 23) | function f(r,t="|"){return r.map((i)=>a(i)).join(t)}
function nn (line 23) | function nn(r,t){if(typeof t==="bigint")return t.toString();return t}
function on (line 23) | function on(r){return{get value(){{let i=r();return Object.definePropert...
function wt (line 23) | function wt(r){return r===null||r===void 0}
function Mn (line 23) | function Mn(r){let t=r.startsWith("^")?1:0,i=r.endsWith("$")?r.length-1:...
function Ru (line 23) | function Ru(r,t){let i=(r.toString().split(".")[1]||"").length,o=t.toStr...
function Y (line 23) | function Y(r,t,i){let o=void 0;Object.defineProperty(r,t,{get(){if(o===s...
function cI (line 23) | function cI(r){return Object.create(Object.getPrototypeOf(r),Object.getO...
function at (line 23) | function at(r,t,i){Object.defineProperty(r,t,{value:i,writable:!0,enumer...
function zt (line 23) | function zt(...r){let t={};for(let i of r){let o=Object.getOwnPropertyDe...
function uI (line 23) | function uI(r){return zt(r._zod.def)}
function gI (line 23) | function gI(r,t){if(!t)return r;return t.reduce((i,o)=>i?.[o],r)}
function mI (line 23) | function mI(r){let t=Object.keys(r),i=t.map((o)=>r[o]);return Promise.al...
function bI (line 23) | function bI(r=10){let i="";for(let o=0;o<r;o++)i+="abcdefghijklmnopqrstu...
function ao (line 23) | function ao(r){return JSON.stringify(r)}
function Kt (line 23) | function Kt(r){return typeof r==="object"&&r!==null&&!Array.isArray(r)}
function _t (line 23) | function _t(r){if(Kt(r)===!1)return!1;let t=r.constructor;if(t===void 0)...
function Mu (line 23) | function Mu(r){if(_t(r))return{...r};if(Array.isArray(r))return[...r];re...
function vI (line 23) | function vI(r){let t=0;for(let i in r)if(Object.prototype.hasOwnProperty...
function Tr (line 23) | function Tr(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}
function pr (line 23) | function pr(r,t,i){let o=new r._zod.constr(t??r._zod.def);if(!t||i?.pare...
function z (line 23) | function z(r){let t=r;if(!t)return{};if(typeof t==="string")return{error...
function $I (line 23) | function $I(r){let t;return new Proxy({},{get(i,o,n){return t??(t=r()),R...
function a (line 23) | function a(r){if(typeof r==="bigint")return r.toString()+"n";if(typeof r...
function Tu (line 23) | function Tu(r){return Object.keys(r).filter((t)=>{return r[t]._zod.optin...
function fI (line 23) | function fI(r,t){let i=r._zod.def,o=zt(r._zod.def,{get shape(){let n={};...
function xI (line 23) | function xI(r,t){let i=r._zod.def,o=zt(r._zod.def,{get shape(){let n={.....
function wI (line 23) | function wI(r,t){if(!_t(t))throw Error("Invalid input to extend: expecte...
function aI (line 23) | function aI(r,t){if(!_t(t))throw Error("Invalid input to safeExtend: exp...
function zI (line 23) | function zI(r,t){let i=zt(r._zod.def,{get shape(){let o={...r._zod.def.s...
function _I (line 23) | function _I(r,t,i){let o=zt(t._zod.def,{get shape(){let n=t._zod.def.sha...
function OI (line 23) | function OI(r,t,i){let o=zt(t._zod.def,{get shape(){let n=t._zod.def.sha...
function Ot (line 23) | function Ot(r,t=0){if(r.aborted===!0)return!0;for(let i=t;i<r.issues.len...
function Kr (line 23) | function Kr(r,t){return t.map((i)=>{var o;return(o=i).path??(o.path=[]),...
function Rn (line 23) | function Rn(r){return typeof r==="string"?r:r?.message}
function Lr (line 23) | function Lr(r,t,i){let o={...r,path:r.path??[]};if(!r.message){let n=Rn(...
function Tn (line 23) | function Tn(r){if(r instanceof Set)return"set";if(r instanceof Map)retur...
function Cn (line 23) | function Cn(r){if(Array.isArray(r))return"array";if(typeof r==="string")...
function en (line 23) | function en(...r){let[t,i,o]=r;if(typeof t==="string")return{message:t,c...
function DI (line 23) | function DI(r){return Object.entries(r).filter(([t,i])=>{return Number.i...
function rw (line 23) | function rw(r){let t=atob(r),i=new Uint8Array(t.length);for(let o=0;o<t....
function tw (line 23) | function tw(r){let t="";for(let i=0;i<r.length;i++)t+=String.fromCharCod...
function pI (line 23) | function pI(r){let t=r.replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat(...
function II (line 23) | function II(r){return tw(r).replace(/\+/g,"-").replace(/\//g,"_").replac...
function jI (line 23) | function jI(r){let t=r.replace(/^0x/,"");if(t.length%2!==0)throw Error("...
function kI (line 23) | function kI(r){return Array.from(r).map((t)=>t.toString(16).padStart(2,"...
class nw (line 23) | class nw{constructor(...r){}}
method constructor (line 23) | constructor(...r){}
function sn (line 23) | function sn(r,t=(i)=>i.message){let i={},o=[];for(let n of r.issues)if(n...
function ri (line 23) | function ri(r,t=(i)=>i.message){let i={_errors:[]},o=(n)=>{for(let e of ...
function su (line 23) | function su(r,t=(i)=>i.message){let i={errors:[]},o=(n,e=[])=>{var l,u;f...
function ow (line 23) | function ow(r){let t=[],i=r.map((o)=>typeof o==="object"?o.key:o);for(le...
function rg (line 23) | function rg(r){let t=[],i=[...r.issues].sort((o,n)=>(o.path??[]).length-...
function vg (line 24) | function vg(){return new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_...
function cw (line 24) | function cw(r){return typeof r.precision==="number"?r.precision===-1?"(?...
function Og (line 24) | function Og(r){return new RegExp(`^${cw(r)}$`)}
function Dg (line 24) | function Dg(r){let t=cw({precision:r.precision}),i=["Z"];if(r.local)i.pu...
function ti (line 24) | function ti(r,t){return new RegExp(`^[A-Za-z0-9+/]{${r}}${t}$`)}
function ni (line 24) | function ni(r){return new RegExp(`^[A-Za-z0-9_-]{${r}}$`)}
function uw (line 24) | function uw(r,t,i){if(r.issues.length)t.issues.push(...Kr(i,r.issues))}
class Xo (line 24) | class Xo{constructor(r=[]){if(this.content=[],this.indent=0,this)this.ar...
method constructor (line 24) | constructor(r=[]){if(this.content=[],this.indent=0,this)this.args=r}
method indented (line 24) | indented(r){this.indent+=1,r(this),this.indent-=1}
method write (line 24) | write(r){if(typeof r==="function"){r(this,{execution:"sync"}),r(this,{...
method compile (line 25) | compile(){let r=Function,t=this?.args,o=[...(this?.content??[""]).map(...
function wm (line 26) | function wm(r){if(r==="")return!0;if(r.length%4!==0)return!1;try{return ...
function Ow (line 26) | function Ow(r){if(!Eo.test(r))return!1;let t=r.replace(/[-_]/g,(o)=>o===...
function Dw (line 26) | function Dw(r,t=null){try{let i=r.split(".");if(i.length!==3)return!1;le...
function bw (line 26) | function bw(r,t,i){if(r.issues.length)t.issues.push(...Kr(i,r.issues));t...
function Vo (line 26) | function Vo(r,t,i,o){if(r.issues.length)t.issues.push(...Kr(i,r.issues))...
function pw (line 26) | function pw(r){let t=Object.keys(r.shape);for(let o of t)if(!r.shape?.[o...
function Iw (line 26) | function Iw(r,t,i,o,n,e){let l=[],u=n.keySet,g=n.catchall._zod,c=g.def.t...
function vw (line 43) | function vw(r,t,i,o){for(let e of r)if(e.issues.length===0)return t.valu...
function Cg (line 43) | function Cg(r,t){if(r===t)return{valid:!0,data:r};if(r instanceof Date&&...
function hw (line 43) | function hw(r,t,i){if(t.issues.length)r.issues.push(...t.issues);if(i.is...
function Wo (line 43) | function Wo(r,t,i){if(r.issues.length)t.issues.push(...Kr(i,r.issues));t...
function $w (line 43) | function $w(r,t,i,o,n,e,l){if(r.issues.length)if(Zn.has(typeof o))i.issu...
function fw (line 43) | function fw(r,t){if(r.issues.length)t.issues.push(...r.issues);t.value.a...
function xw (line 43) | function xw(r,t){if(r.issues.length&&t===void 0)return{issues:[],value:v...
function ww (line 43) | function ww(r,t){if(r.value===void 0)r.value=t.defaultValue;return r}
function aw (line 43) | function aw(r,t){if(!r.issues.length&&r.value===void 0)r.issues.push({co...
function qo (line 43) | function qo(r,t,i){if(r.issues.length)return r.aborted=!0,r;return t._zo...
function No (line 43) | function No(r,t,i){if(r.issues.length)return r.aborted=!0,r;if((i.direct...
function So (line 43) | function So(r,t,i,o){if(r.issues.length)return r.aborted=!0,r;return i._...
function zw (line 43) | function zw(r){return r.value=Object.freeze(r.value),r}
function _w (line 43) | function _w(r,t,i,o){if(!r){let n={code:"custom",input:i,inst:o,path:[.....
function t (line 43) | function t(n){return r[n]??null}
function eb (line 43) | function eb(){return{localeError:u2()}}
function t (line 43) | function t(n){return r[n]??null}
function lb (line 43) | function lb(){return{localeError:g2()}}
function kw (line 43) | function kw(r,t,i,o){let n=Math.abs(r),e=n%10,l=n%100;if(l>=11&&l<=19)re...
function t (line 43) | function t(n){return r[n]??null}
function cb (line 43) | function cb(){return{localeError:m2()}}
function t (line 43) | function t(o){return r[o]??null}
function ub (line 43) | function ub(){return{localeError:v2()}}
function t (line 43) | function t(n){return r[n]??null}
function gb (line 43) | function gb(){return{localeError:h2()}}
function t (line 43) | function t(n){return r[n]??null}
function mb (line 43) | function mb(){return{localeError:$2()}}
function i (line 43) | function i(l){return r[l]??null}
function o (line 43) | function o(l){return t[l]??l}
function bb (line 43) | function bb(){return{localeError:f2()}}
function t (line 43) | function t(n){return r[n]??null}
function vb (line 43) | function vb(){return{localeError:x2()}}
function t (line 43) | function t(o){return r[o]??null}
function ei (line 43) | function ei(){return{localeError:a2()}}
function t (line 43) | function t(o){return r[o]??null}
function hb (line 43) | function hb(){return{localeError:_2()}}
function i (line 43) | function i(l){return r[l]??null}
function o (line 43) | function o(l){return t[l]??l}
function $b (line 43) | function $b(){return{localeError:O2()}}
function t (line 43) | function t(n){return r[n]??null}
function fb (line 43) | function fb(){return{localeError:D2()}}
function t (line 43) | function t(n){return r[n]??null}
function xb (line 43) | function xb(){return{localeError:p2()}}
function t (line 43) | function t(n){return r[n]??null}
function wb (line 43) | function wb(){return{localeError:I2()}}
function t (line 43) | function t(n){return r[n]??null}
function ab (line 43) | function ab(){return{localeError:j2()}}
function t (line 43) | function t(n){return r[n]??null}
function zb (line 43) | function zb(){return{localeError:k2()}}
function t (line 43) | function t(n){return r[n]??null}
function _b (line 43) | function _b(){return{localeError:U2()}}
function t (line 43) | function t(n){return r[n]??null}
function Ob (line 43) | function Ob(){return{localeError:J2()}}
function t (line 43) | function t(o){return r[o]??null}
function Db (line 43) | function Db(){return{localeError:E2()}}
function t (line 43) | function t(n){return r[n]??null}
function pb (line 43) | function pb(){return{localeError:K2()}}
function t (line 43) | function t(n){return r[n]??null}
function Ib (line 43) | function Ib(){return{localeError:L2()}}
function t (line 43) | function t(o){return r[o]??null}
function jb (line 43) | function jb(){return{localeError:W2()}}
function t (line 43) | function t(n){return r[n]??null}
function li (line 43) | function li(){return{localeError:q2()}}
function kb (line 43) | function kb(){return li()}
function t (line 43) | function t(n){return r[n]??null}
function Ub (line 43) | function Ub(){return{localeError:N2()}}
function Uw (line 43) | function Uw(r){let t=Math.abs(r),i=t%10,o=t%100;if(o>=11&&o<=19||i===0)r...
function t (line 43) | function t(o,n,e,l){let u=r[o]??null;if(u===null)return u;return{unit:u....
function Jb (line 43) | function Jb(){return{localeError:V2()}}
function t (line 43) | function t(n){return r[n]??null}
function Pb (line 43) | function Pb(){return{localeError:Y2()}}
function t (line 43) | function t(n){return r[n]??null}
function Eb (line 43) | function Eb(){return{localeError:F2()}}
function t (line 43) | function t(n){return r[n]??null}
function Kb (line 43) | function Kb(){return{localeError:Q2()}}
function t (line 43) | function t(n){return r[n]??null}
function Lb (line 43) | function Lb(){return{localeError:G2()}}
function t (line 43) | function t(n){return r[n]??null}
function Xb (line 43) | function Xb(){return{localeError:A2()}}
function t (line 43) | function t(n){return r[n]??null}
function Wb (line 43) | function Wb(){return{localeError:B2()}}
function t (line 43) | function t(n){return r[n]??null}
function qb (line 43) | function qb(){return{localeError:y2()}}
function t (line 43) | function t(n){return r[n]??null}
function Nb (line 43) | function Nb(){return{localeError:R2()}}
function Jw (line 43) | function Jw(r,t,i,o){let n=Math.abs(r),e=n%10,l=n%100;if(l>=11&&l<=19)re...
function t (line 43) | function t(n){return r[n]??null}
function Sb (line 43) | function Sb(){return{localeError:H2()}}
function t (line 43) | function t(n){return r[n]??null}
function Vb (line 43) | function Vb(){return{localeError:M2()}}
function t (line 43) | function t(n){return r[n]??null}
function Yb (line 43) | function Yb(){return{localeError:Z2()}}
function t (line 43) | function t(n){return r[n]??null}
function Fb (line 43) | function Fb(){return{localeError:T2()}}
function t (line 43) | function t(n){return r[n]??null}
function Qb (line 43) | function Qb(){return{localeError:C2()}}
function t (line 43) | function t(o){return r[o]??null}
function Gb (line 43) | function Gb(){return{localeError:s2()}}
function t (line 43) | function t(n){return r[n]??null}
function gi (line 43) | function gi(){return{localeError:rj()}}
function Ab (line 43) | function Ab(){return gi()}
function t (line 43) | function t(n){return r[n]??null}
function Bb (line 43) | function Bb(){return{localeError:tj()}}
function t (line 43) | function t(n){return r[n]??null}
function yb (line 43) | function yb(){return{localeError:nj()}}
function t (line 43) | function t(n){return r[n]??null}
function Rb (line 43) | function Rb(){return{localeError:ij()}}
function t (line 43) | function t(n){return r[n]??null}
function Hb (line 43) | function Hb(){return{localeError:oj()}}
function t (line 43) | function t(n){return r[n]??null}
function Mb (line 43) | function Mb(){return{localeError:ej()}}
class bi (line 43) | class bi{constructor(){this._map=new WeakMap,this._idmap=new Map}add(r,....
method constructor (line 43) | constructor(){this._map=new WeakMap,this._idmap=new Map}
method add (line 43) | add(r,...t){let i=t[0];if(this._map.set(r,i),i&&typeof i==="object"&&"...
method clear (line 43) | clear(){return this._map=new WeakMap,this._idmap=new Map,this}
method remove (line 43) | remove(r){let t=this._map.get(r);if(t&&typeof t==="object"&&"id"in t)t...
method get (line 43) | get(r){let t=r._zod.parent;if(t){let i={...this.get(t)??{}};delete i.i...
method has (line 43) | has(r){return this._map.has(r)}
function Ao (line 43) | function Ao(){return new bi}
function Cb (line 43) | function Cb(r,t){return new r({type:"string",...z(t)})}
function db (line 43) | function db(r,t){return new r({type:"string",coerce:!0,...z(t)})}
function Bo (line 43) | function Bo(r,t){return new r({type:"string",format:"email",check:"strin...
function vi (line 43) | function vi(r,t){return new r({type:"string",format:"guid",check:"string...
function yo (line 43) | function yo(r,t){return new r({type:"string",format:"uuid",check:"string...
function Ro (line 43) | function Ro(r,t){return new r({type:"string",format:"uuid",check:"string...
function Ho (line 43) | function Ho(r,t){return new r({type:"string",format:"uuid",check:"string...
function Mo (line 43) | function Mo(r,t){return new r({type:"string",format:"uuid",check:"string...
function hi (line 43) | function hi(r,t){return new r({type:"string",format:"url",check:"string_...
function Zo (line 43) | function Zo(r,t){return new r({type:"string",format:"emoji",check:"strin...
function To (line 43) | function To(r,t){return new r({type:"string",format:"nanoid",check:"stri...
function Co (line 43) | function Co(r,t){return new r({type:"string",format:"cuid",check:"string...
function so (line 43) | function so(r,t){return new r({type:"string",format:"cuid2",check:"strin...
function re (line 43) | function re(r,t){return new r({type:"string",format:"ulid",check:"string...
function te (line 43) | function te(r,t){return new r({type:"string",format:"xid",check:"string_...
function ne (line 43) | function ne(r,t){return new r({type:"string",format:"ksuid",check:"strin...
function ie (line 43) | function ie(r,t){return new r({type:"string",format:"ipv4",check:"string...
function oe (line 43) | function oe(r,t){return new r({type:"string",format:"ipv6",check:"string...
function ee (line 43) | function ee(r,t){return new r({type:"string",format:"cidrv4",check:"stri...
function le (line 43) | function le(r,t){return new r({type:"string",format:"cidrv6",check:"stri...
function ce (line 43) | function ce(r,t){return new r({type:"string",format:"base64",check:"stri...
function ue (line 43) | function ue(r,t){return new r({type:"string",format:"base64url",check:"s...
function ge (line 43) | function ge(r,t){return new r({type:"string",format:"e164",check:"string...
function me (line 43) | function me(r,t){return new r({type:"string",format:"jwt",check:"string_...
function rv (line 43) | function rv(r,t){return new r({type:"string",format:"datetime",check:"st...
function tv (line 43) | function tv(r,t){return new r({type:"string",format:"date",check:"string...
function nv (line 43) | function nv(r,t){return new r({type:"string",format:"time",check:"string...
function iv (line 43) | function iv(r,t){return new r({type:"string",format:"duration",check:"st...
function ov (line 43) | function ov(r,t){return new r({type:"number",checks:[],...z(t)})}
function ev (line 43) | function ev(r,t){return new r({type:"number",coerce:!0,checks:[],...z(t)})}
function lv (line 43) | function lv(r,t){return new r({type:"number",check:"number_format",abort...
function cv (line 43) | function cv(r,t){return new r({type:"number",check:"number_format",abort...
function uv (line 43) | function uv(r,t){return new r({type:"number",check:"number_format",abort...
function gv (line 43) | function gv(r,t){return new r({type:"number",check:"number_format",abort...
function mv (line 43) | function mv(r,t){return new r({type:"number",check:"number_format",abort...
function bv (line 43) | function bv(r,t){return new r({type:"boolean",...z(t)})}
function vv (line 43) | function vv(r,t){return new r({type:"boolean",coerce:!0,...z(t)})}
function hv (line 43) | function hv(r,t){return new r({type:"bigint",...z(t)})}
function $v (line 43) | function $v(r,t){return new r({type:"bigint",coerce:!0,...z(t)})}
function fv (line 43) | function fv(r,t){return new r({type:"bigint",check:"bigint_format",abort...
function xv (line 43) | function xv(r,t){return new r({type:"bigint",check:"bigint_format",abort...
function wv (line 43) | function wv(r,t){return new r({type:"symbol",...z(t)})}
function av (line 43) | function av(r,t){return new r({type:"undefined",...z(t)})}
function zv (line 43) | function zv(r,t){return new r({type:"null",...z(t)})}
function _v (line 43) | function _v(r){return new r({type:"any"})}
function Ov (line 43) | function Ov(r){return new r({type:"unknown"})}
function Dv (line 43) | function Dv(r,t){return new r({type:"never",...z(t)})}
function pv (line 43) | function pv(r,t){return new r({type:"void",...z(t)})}
function Iv (line 43) | function Iv(r,t){return new r({type:"date",...z(t)})}
function jv (line 43) | function jv(r,t){return new r({type:"date",coerce:!0,...z(t)})}
function kv (line 43) | function kv(r,t){return new r({type:"nan",...z(t)})}
function et (line 43) | function et(r,t){return new Ko({check:"less_than",...z(t),value:r,inclus...
function Sr (line 43) | function Sr(r,t){return new Ko({check:"less_than",...z(t),value:r,inclus...
function lt (line 43) | function lt(r,t){return new Lo({check:"greater_than",...z(t),value:r,inc...
function kr (line 43) | function kr(r,t){return new Lo({check:"greater_than",...z(t),value:r,inc...
function Uv (line 43) | function Uv(r){return lt(0,r)}
function Jv (line 43) | function Jv(r){return et(0,r)}
function Pv (line 43) | function Pv(r){return Sr(0,r)}
function Ev (line 43) | function Ev(r){return kr(0,r)}
function Wt (line 43) | function Wt(r,t){return new Lg({check:"multiple_of",...z(t),value:r})}
function bn (line 43) | function bn(r,t){return new qg({check:"max_size",...z(t),maximum:r})}
function qt (line 43) | function qt(r,t){return new Ng({check:"min_size",...z(t),minimum:r})}
function $i (line 43) | function $i(r,t){return new Sg({check:"size_equals",...z(t),size:r})}
function vn (line 43) | function vn(r,t){return new Vg({check:"max_length",...z(t),maximum:r})}
function Dt (line 43) | function Dt(r,t){return new Yg({check:"min_length",...z(t),minimum:r})}
function hn (line 43) | function hn(r,t){return new Fg({check:"length_equals",...z(t),length:r})}
function fi (line 43) | function fi(r,t){return new Qg({check:"string_format",format:"regex",......
function xi (line 43) | function xi(r){return new Gg({check:"string_format",format:"lowercase",....
function wi (line 43) | function wi(r){return new Ag({check:"string_format",format:"uppercase",....
function ai (line 43) | function ai(r,t){return new Bg({check:"string_format",format:"includes",...
function zi (line 43) | function zi(r,t){return new yg({check:"string_format",format:"starts_wit...
function _i (line 43) | function _i(r,t){return new Rg({check:"string_format",format:"ends_with"...
function Kv (line 43) | function Kv(r,t,i){return new Hg({check:"property",property:r,schema:t,....
function Oi (line 43) | function Oi(r,t){return new Mg({check:"mime_type",mime:r,...z(t)})}
function ct (line 43) | function ct(r){return new Zg({check:"overwrite",tx:r})}
function Di (line 43) | function Di(r){return ct((t)=>t.normalize(r))}
function pi (line 43) | function pi(){return ct((r)=>r.trim())}
function Ii (line 43) | function Ii(){return ct((r)=>r.toLowerCase())}
function ji (line 43) | function ji(){return ct((r)=>r.toUpperCase())}
function Lv (line 43) | function Lv(r,t,i){return new r({type:"array",element:t,...z(i)})}
function lj (line 43) | function lj(r,t,i){return new r({type:"union",options:t,...z(i)})}
function cj (line 43) | function cj(r,t,i,o){return new r({type:"union",options:i,discriminator:...
function uj (line 43) | function uj(r,t,i){return new r({type:"intersection",left:t,right:i})}
function gj (line 43) | function gj(r,t,i,o){let n=i instanceof W;return new r({type:"tuple",ite...
function mj (line 43) | function mj(r,t,i,o){return new r({type:"record",keyType:t,valueType:i,....
function bj (line 43) | function bj(r,t,i,o){return new r({type:"map",keyType:t,valueType:i,...z...
function vj (line 43) | function vj(r,t,i){return new r({type:"set",valueType:t,...z(i)})}
function hj (line 43) | function hj(r,t,i){let o=Array.isArray(t)?Object.fromEntries(t.map((n)=>...
function $j (line 43) | function $j(r,t,i){return new r({type:"enum",entries:t,...z(i)})}
function fj (line 43) | function fj(r,t,i){return new r({type:"literal",values:Array.isArray(t)?...
function Xv (line 43) | function Xv(r,t){return new r({type:"file",...z(t)})}
function xj (line 43) | function xj(r,t){return new r({type:"transform",transform:t})}
function wj (line 43) | function wj(r,t){return new r({type:"optional",innerType:t})}
function aj (line 43) | function aj(r,t){return new r({type:"nullable",innerType:t})}
function zj (line 43) | function zj(r,t,i){return new r({type:"default",innerType:t,get defaultV...
function _j (line 43) | function _j(r,t,i){return new r({type:"nonoptional",innerType:t,...z(i)})}
function Oj (line 43) | function Oj(r,t){return new r({type:"success",innerType:t})}
function Dj (line 43) | function Dj(r,t,i){return new r({type:"catch",innerType:t,catchValue:typ...
function pj (line 43) | function pj(r,t,i){return new r({type:"pipe",in:t,out:i})}
function Ij (line 43) | function Ij(r,t){return new r({type:"readonly",innerType:t})}
function jj (line 43) | function jj(r,t,i){return new r({type:"template_literal",parts:t,...z(i)})}
function kj (line 43) | function kj(r,t){return new r({type:"lazy",getter:t})}
function Uj (line 43) | function Uj(r,t){return new r({type:"promise",innerType:t})}
function Wv (line 43) | function Wv(r,t,i){let o=z(i);return o.abort??(o.abort=!0),new r({type:"...
function qv (line 43) | function qv(r,t,i){return new r({type:"custom",check:"custom",fn:t,...z(...
function Nv (line 43) | function Nv(r){let t=Pw((i)=>{return i.addIssue=(o)=>{if(typeof o==="str...
function Pw (line 43) | function Pw(r,t){let i=new s({check:"custom",...z(t)});return i._zod.che...
function Sv (line 43) | function Sv(r,t){let i=z(t),o=i.truthy??["true","1","yes","on","y","enab...
function $n (line 43) | function $n(r,t,i,o={}){let n=z(o),e={...z(o),check:"string_format",type...
class be (line 43) | class be{constructor(r){this.counter=0,this.metadataRegistry=r?.metadata...
method constructor (line 43) | constructor(r){this.counter=0,this.metadataRegistry=r?.metadata??Cr,th...
method process (line 43) | process(r,t={path:[],schemaPath:[]}){var i;let o=r._zod.def,n={guid:"u...
method emit (line 43) | emit(r,t){let i={cycles:t?.cycles??"ref",reused:t?.reused??"inline",ex...
function Vv (line 45) | function Vv(r,t){if(r instanceof bi){let o=new be(t),n={};for(let u of r...
function $r (line 45) | function $r(r,t){let i=t??{seen:new Set};if(i.seen.has(r))return!1;i.see...
function Yv (line 45) | function Yv(r){return rv(ve,r)}
function Fv (line 45) | function Fv(r){return tv(he,r)}
function Qv (line 45) | function Qv(r){return nv($e,r)}
function Gv (line 45) | function Gv(r){return iv(fe,r)}
method get (line 45) | get(){return r.issues.length===0}
method get (line 45) | get(){return Cr.get(r)?.description}
function th (line 45) | function th(r){return Cb(Ui,r)}
function Kj (line 45) | function Kj(r){return Bo(oh,r)}
function Lj (line 45) | function Lj(r){return vi(we,r)}
function Xj (line 45) | function Xj(r){return yo(gt,r)}
function Wj (line 45) | function Wj(r){return Ro(gt,r)}
function qj (line 45) | function qj(r){return Ho(gt,r)}
function Nj (line 45) | function Nj(r){return Mo(gt,r)}
function Sj (line 45) | function Sj(r){return hi(Oe,r)}
function Vj (line 45) | function Vj(r){return hi(Oe,{protocol:/^https?$/,hostname:Nr.domain,..._...
function Yj (line 45) | function Yj(r){return Zo(eh,r)}
function Fj (line 45) | function Fj(r){return To(lh,r)}
function Qj (line 45) | function Qj(r){return Co(ch,r)}
function Gj (line 45) | function Gj(r){return so(uh,r)}
function Aj (line 45) | function Aj(r){return re(gh,r)}
function Bj (line 45) | function Bj(r){return te(mh,r)}
function yj (line 45) | function yj(r){return ne(bh,r)}
function Rj (line 45) | function Rj(r){return ie(vh,r)}
function Hj (line 45) | function Hj(r){return oe(hh,r)}
function Mj (line 45) | function Mj(r){return ee($h,r)}
function Zj (line 45) | function Zj(r){return le(fh,r)}
function Tj (line 45) | function Tj(r){return ce(xh,r)}
function Cj (line 45) | function Cj(r){return ue(wh,r)}
function dj (line 45) | function dj(r){return ge(ah,r)}
function sj (line 45) | function sj(r){return me(zh,r)}
function rk (line 45) | function rk(r,t,i={}){return $n(Ji,r,t,i)}
function tk (line 45) | function tk(r){return $n(Ji,"hostname",Nr.hostname,r)}
function nk (line 45) | function nk(r){return $n(Ji,"hex",Nr.hex,r)}
function ik (line 45) | function ik(r,t){let i=t?.enc??"hex",o=`${r}_${i}`,n=Nr[o];if(!n)throw E...
function Xw (line 45) | function Xw(r){return ov(Pi,r)}
function nh (line 45) | function nh(r){return lv(xn,r)}
function ok (line 45) | function ok(r){return cv(xn,r)}
function ek (line 45) | function ek(r){return uv(xn,r)}
function lk (line 45) | function lk(r){return gv(xn,r)}
function ck (line 45) | function ck(r){return mv(xn,r)}
function Ww (line 45) | function Ww(r){return bv(Ei,r)}
function uk (line 45) | function uk(r){return hv(Ki,r)}
function gk (line 45) | function gk(r){return fv(_h,r)}
function mk (line 45) | function mk(r){return xv(_h,r)}
function bk (line 45) | function bk(r){return wv(qw,r)}
function vk (line 45) | function vk(r){return av(Nw,r)}
function Vw (line 45) | function Vw(r){return zv(Sw,r)}
function hk (line 45) | function hk(){return _v(Yw)}
function fn (line 45) | function fn(){return Ov(Fw)}
function Oh (line 45) | function Oh(r){return Dv(Qw,r)}
function $k (line 45) | function $k(r){return pv(Gw,r)}
function fk (line 45) | function fk(r){return Iv(De,r)}
function pe (line 45) | function pe(r,t){return Lv(Aw,r,t)}
function xk (line 45) | function xk(r){let t=r._zod.def.shape;return jh(Object.keys(t))}
function wk (line 45) | function wk(r,t){let i={type:"object",shape:r??{},..._.normalizeParams(t...
function ak (line 45) | function ak(r,t){return new Ie({type:"object",shape:r,catchall:Oh(),..._...
function zk (line 45) | function zk(r,t){return new Ie({type:"object",shape:r,catchall:fn(),..._...
function ph (line 45) | function ph(r,t){return new Dh({type:"union",options:r,..._.normalizePar...
function _k (line 45) | function _k(r,t,i){return new Bw({type:"union",options:t,discriminator:r...
function Rw (line 45) | function Rw(r,t){return new yw({type:"intersection",left:r,right:t})}
function Mw (line 45) | function Mw(r,t,i){let o=t instanceof W,n=o?i:t;return new Hw({type:"tup...
function Zw (line 45) | function Zw(r,t,i){return new Ih({type:"record",keyType:r,valueType:t,.....
function Ok (line 45) | function Ok(r,t,i){let o=pr(r);return o._zod.values=void 0,new Ih({type:...
function Dk (line 45) | function Dk(r,t,i){return new Tw({type:"map",keyType:r,valueType:t,..._....
function pk (line 45) | function pk(r,t){return new Cw({type:"set",valueType:r,..._.normalizePar...
function jh (line 45) | function jh(r,t){let i=Array.isArray(r)?Object.fromEntries(r.map((o)=>[o...
function Ik (line 45) | function Ik(r,t){return new ki({type:"enum",entries:r,..._.normalizePara...
method get (line 45) | get(){if(t.values.length>1)throw Error("This schema contains multiple va...
function jk (line 45) | function jk(r,t){return new dw({type:"literal",values:Array.isArray(r)?r...
function kk (line 45) | function kk(r){return Xv(sw,r)}
function kh (line 45) | function kh(r){return new r4({type:"transform",transform:r})}
function ae (line 45) | function ae(r){return new Uh({type:"optional",innerType:r})}
function ze (line 45) | function ze(r){return new t4({type:"nullable",innerType:r})}
function Uk (line 45) | function Uk(r){return ae(ze(r))}
function i4 (line 45) | function i4(r,t){return new n4({type:"default",innerType:r,get defaultVa...
function e4 (line 45) | function e4(r,t){return new o4({type:"prefault",innerType:r,get defaultV...
function l4 (line 45) | function l4(r,t){return new Jh({type:"nonoptional",innerType:r,..._.norm...
function Jk (line 45) | function Jk(r){return new c4({type:"success",innerType:r})}
function g4 (line 45) | function g4(r,t){return new u4({type:"catch",innerType:r,catchValue:type...
function Pk (line 45) | function Pk(r){return kv(m4,r)}
function _e (line 45) | function _e(r,t){return new Ph({type:"pipe",in:r,out:t})}
function Ek (line 45) | function Ek(r,t,i){return new Eh({type:"pipe",in:r,out:t,transform:i.dec...
function v4 (line 45) | function v4(r){return new b4({type:"readonly",innerType:r})}
function Kk (line 45) | function Kk(r,t){return new h4({type:"template_literal",parts:r,..._.nor...
function f4 (line 45) | function f4(r){return new $4({type:"lazy",getter:r})}
function Lk (line 45) | function Lk(r){return new x4({type:"promise",innerType:r})}
function Xk (line 45) | function Xk(r){return new w4({type:"function",input:Array.isArray(r?.inp...
function Wk (line 45) | function Wk(r){let t=new s({check:"custom"});return t._zod.check=r,t}
function qk (line 45) | function qk(r,t){return Wv(je,r??(()=>!0),t)}
function a4 (line 45) | function a4(r,t={}){return qv(je,r,t)}
function z4 (line 45) | function z4(r){return Nv(r)}
function Nk (line 45) | function Nk(r,t={error:`Input not instance of ${r.name}`}){let i=new je(...
function Vk (line 45) | function Vk(r){let t=f4(()=>{return ph([th(r),Xw(),Ww(),Vw(),pe(t),Zw(th...
function Yk (line 45) | function Yk(r,t){return _e(kh(r),t)}
function Qk (line 45) | function Qk(r){br({customError:r})}
function Gk (line 45) | function Gk(){return br().customError}
function Ak (line 45) | function Ak(r){return db(Ui,r)}
function Bk (line 45) | function Bk(r){return ev(Pi,r)}
function yk (line 45) | function yk(r){return vv(Ei,r)}
function Rk (line 45) | function Rk(r){return $v(Ki,r)}
function Hk (line 45) | function Hk(r){return jv(De,r)}
function O4 (line 45) | function O4(){try{return window?.localStorage.getItem("theme")||"light"}...
function D4 (line 45) | function D4(r){try{if(r==="dark")document.documentElement.classList.add(...
function Zk (line 45) | function Zk(r){return(...t)=>{try{return r(...t)}catch(i){return console...
FILE: apps/web/client/src/app/_components/auth-modal.tsx
function AuthModal (line 17) | function AuthModal() {
FILE: apps/web/client/src/app/_components/button-link.tsx
function ButtonLink (line 2) | function ButtonLink({ href, children, rightIcon, target, rel }: {
FILE: apps/web/client/src/app/_components/hero/ai-features-hero.tsx
function AiFeaturesHero (line 12) | function AiFeaturesHero() {
FILE: apps/web/client/src/app/_components/hero/ai-frontend-hero.tsx
function AiFrontendHero (line 12) | function AiFrontendHero() {
FILE: apps/web/client/src/app/_components/hero/builder-features-hero.tsx
function BuilderFeaturesHero (line 12) | function BuilderFeaturesHero() {
FILE: apps/web/client/src/app/_components/hero/claude-code-hero.tsx
function ClaudeCodeHero (line 12) | function ClaudeCodeHero() {
FILE: apps/web/client/src/app/_components/hero/create.tsx
constant SAVED_INPUT_KEY (line 24) | const SAVED_INPUT_KEY = 'create-input';
type CreateInputContext (line 25) | interface CreateInputContext {
FILE: apps/web/client/src/app/_components/hero/features-hero.tsx
function FeaturesHero (line 12) | function FeaturesHero() {
FILE: apps/web/client/src/app/_components/hero/high-demand.tsx
function HighDemand (line 3) | function HighDemand() {
FILE: apps/web/client/src/app/_components/hero/import.tsx
function Import (line 10) | function Import() {
FILE: apps/web/client/src/app/_components/hero/index.tsx
function Hero (line 16) | function Hero() {
FILE: apps/web/client/src/app/_components/hero/mobile-email-capture.tsx
type FormData (line 9) | interface FormData {
constant MEASUREMENT_DELAY (line 20) | const MEASUREMENT_DELAY = 100;
constant SUCCESS_TIMEOUT (line 21) | const SUCCESS_TIMEOUT = 7000;
function MobileEmailCapture (line 23) | function MobileEmailCapture() {
FILE: apps/web/client/src/app/_components/hero/start-blank.tsx
function StartBlank (line 7) | function StartBlank() {
FILE: apps/web/client/src/app/_components/hero/unicorn-background.tsx
function UnicornBackground (line 7) | function UnicornBackground() {
FILE: apps/web/client/src/app/_components/landing-page/ai-benefits-section.tsx
function AiBenefitsSection (line 10) | function AiBenefitsSection() {
FILE: apps/web/client/src/app/_components/landing-page/ai-features-grid-section.tsx
function AiFeaturesGridSection (line 3) | function AiFeaturesGridSection() {
FILE: apps/web/client/src/app/_components/landing-page/ai-features-intro-section.tsx
function AiFeaturesIntroSection (line 3) | function AiFeaturesIntroSection() {
FILE: apps/web/client/src/app/_components/landing-page/benefits-section.tsx
function BenefitsSection (line 10) | function BenefitsSection() {
FILE: apps/web/client/src/app/_components/landing-page/builder-benefits-section.tsx
function BuilderBenefitsSection (line 7) | function BuilderBenefitsSection() {
FILE: apps/web/client/src/app/_components/landing-page/builder-features-grid-section.tsx
function BuilderFeaturesGridSection (line 3) | function BuilderFeaturesGridSection() {
FILE: apps/web/client/src/app/_components/landing-page/builder-features-intro-section.tsx
function BuilderFeaturesIntroSection (line 3) | function BuilderFeaturesIntroSection() {
FILE: apps/web/client/src/app/_components/landing-page/code-one-to-one-section.tsx
function escapeHtml (line 32) | function escapeHtml(str: string) {
function highlightCode (line 38) | function highlightCode(line: string) {
function CodeOneToOneSection (line 54) | function CodeOneToOneSection() {
FILE: apps/web/client/src/app/_components/landing-page/color-swatch-group.tsx
type ColorSwatchGroupProps (line 3) | interface ColorSwatchGroupProps {
function ColorSwatchGroup (line 8) | function ColorSwatchGroup({ label, colorClasses }: ColorSwatchGroupProps) {
FILE: apps/web/client/src/app/_components/landing-page/contributor-section.tsx
type Contributor (line 9) | interface Contributor {
type ContributorSectionProps (line 139) | interface ContributorSectionProps {
function ContributorSection (line 145) | function ContributorSection({
FILE: apps/web/client/src/app/_components/landing-page/cta-section.tsx
type CTASectionProps (line 7) | interface CTASectionProps {
function CTASection (line 15) | function CTASection({ href, onClick, ctaText = "Ready to stop rebuilding...
FILE: apps/web/client/src/app/_components/landing-page/design-mockup/design-mockup-icons.tsx
type IconProps (line 2) | interface IconProps {
FILE: apps/web/client/src/app/_components/landing-page/design-mockup/design-mockup.tsx
type ImageCardProps (line 6) | interface ImageCardProps {
function ImageCard (line 14) | function ImageCard({ src, alt, caption, isSelected = false, lightMode = ...
function DesignMockup (line 33) | function DesignMockup() {
function DesignMockupMobile (line 160) | function DesignMockupMobile() {
FILE: apps/web/client/src/app/_components/landing-page/faq-dropdown.tsx
type FAQ (line 4) | interface FAQ {
type FAQDropdownProps (line 9) | interface FAQDropdownProps {
function FAQItem (line 13) | function FAQItem({ faq, isOpen, onToggle }: { faq: FAQ; isOpen: boolean;...
function FAQDropdown (line 58) | function FAQDropdown({ faqs }: FAQDropdownProps) {
FILE: apps/web/client/src/app/_components/landing-page/faq-section.tsx
type FAQ (line 7) | interface FAQ {
type FAQSectionProps (line 12) | interface FAQSectionProps {
function FAQSection (line 55) | function FAQSection({
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/ai-chat-preview-block.tsx
function AiChatPreviewBlock (line 5) | function AiChatPreviewBlock() {
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/brand-compliance.tsx
function ParallaxContainer (line 5) | function ParallaxContainer({ children, speed = 0.1 }: { children: React....
function BrandComplianceBlock (line 58) | function BrandComplianceBlock() {
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/components.tsx
function ComponentsBlock (line 4) | function ComponentsBlock() {
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/direct-editing.tsx
function DirectEditingBlock (line 6) | function DirectEditingBlock() {
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/layers.tsx
function MockLayersTab (line 26) | function MockLayersTab() {
function LayersBlock (line 75) | function LayersBlock() {
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/responsive-website.tsx
function ResponsiveWebsiteBlock (line 4) | function ResponsiveWebsiteBlock() {
FILE: apps/web/client/src/app/_components/landing-page/feature-blocks/revision-history.tsx
function VersionRow (line 4) | function VersionRow({ title, subtitle, children, selected, onClick }: { ...
function RevisionHistory (line 19) | function RevisionHistory() {
FILE: apps/web/client/src/app/_components/landing-page/features-grid-section.tsx
function FeaturesGridSection (line 3) | function FeaturesGridSection() {
FILE: apps/web/client/src/app/_components/landing-page/features-intro-section.tsx
function FeaturesIntroSection (line 3) | function FeaturesIntroSection() {
FILE: apps/web/client/src/app/_components/landing-page/illustrations.tsx
type IllustrationProps (line 3) | interface IllustrationProps {
FILE: apps/web/client/src/app/_components/landing-page/obsess-for-hours-section.tsx
function ObsessForHoursSection (line 4) | function ObsessForHoursSection() {
FILE: apps/web/client/src/app/_components/landing-page/onlook-interface-mockup.tsx
function NotesComponent (line 10) | function NotesComponent() {
constant PRESET_SENTENCE (line 43) | const PRESET_SENTENCE = "Add a villain verification badge system";
function UserMessage (line 44) | function UserMessage({ text }: { text: string }) {
function AiMessage (line 53) | function AiMessage({ text }: { text: string }) {
function ToolCallDisplay (line 62) | function ToolCallDisplay({ toolName }: { toolName: string }) {
function OnlookInterfaceMockup (line 81) | function OnlookInterfaceMockup() {
FILE: apps/web/client/src/app/_components/landing-page/page-footer.tsx
function Footer (line 6) | function Footer() {
FILE: apps/web/client/src/app/_components/landing-page/responsive-mockup-section.tsx
function ResponsiveMockupSection (line 4) | function ResponsiveMockupSection() {
FILE: apps/web/client/src/app/_components/landing-page/social-proof-section.tsx
function SocialProofSection (line 6) | function SocialProofSection() {
FILE: apps/web/client/src/app/_components/landing-page/testimonials-section.tsx
type TestimonialCardProps (line 3) | interface TestimonialCardProps {
function TestimonialCard (line 12) | function TestimonialCard({ text, name, label, profileImage, profileColor...
function TestimonialsSection (line 52) | function TestimonialsSection() {
FILE: apps/web/client/src/app/_components/landing-page/what-can-onlook-do-section.tsx
function useOperatingSystem (line 11) | function useOperatingSystem() {
function VersionRow (line 31) | function VersionRow({ title, subtitle, children, selected, onClick }: { ...
function ParallaxContainer (line 46) | function ParallaxContainer({ children, speed = 0.1 }: { children: React....
function WhatCanOnlookDoSection (line 100) | function WhatCanOnlookDoSection() {
FILE: apps/web/client/src/app/_components/login-button.tsx
type LoginButtonProps (line 10) | interface LoginButtonProps {
FILE: apps/web/client/src/app/_components/shared/mockups/ai-chat-interactive.tsx
constant PRESET_SENTENCE (line 10) | const PRESET_SENTENCE = "Add a section for baristas to upsell new season...
function UserMessage (line 12) | function UserMessage({ text }: { text: string }) {
function AiMessage (line 22) | function AiMessage({ text }: { text: string }) {
function ToolCallDisplay (line 32) | function ToolCallDisplay({ toolName }: { toolName: string }) {
function AiChatInteractive (line 50) | function AiChatInteractive() {
FILE: apps/web/client/src/app/_components/shared/mockups/components-mockup.tsx
function ComponentsMockup (line 4) | function ComponentsMockup() {
FILE: apps/web/client/src/app/_components/shared/mockups/direct-editing-interactive.tsx
function DraggableElement (line 5) | function DraggableElement({
function DirectEditingInteractive (line 226) | function DirectEditingInteractive() {
FILE: apps/web/client/src/app/_components/shared/mockups/tailwind-color-editor.tsx
function TailwindColorEditorMockup (line 12) | function TailwindColorEditorMockup() {
FILE: apps/web/client/src/app/_components/theme.tsx
function ThemeProvider (line 6) | function ThemeProvider({
FILE: apps/web/client/src/app/_components/top-bar/github.tsx
constant DEFAULT_STAR_COUNT (line 6) | const DEFAULT_STAR_COUNT = 22000;
constant DEFAULT_CONTRIBUTORS_COUNT (line 7) | const DEFAULT_CONTRIBUTORS_COUNT = 90;
function useGitHubStats (line 16) | function useGitHubStats() {
function GitHubButton (line 56) | function GitHubButton() {
FILE: apps/web/client/src/app/_components/top-bar/index.tsx
constant LINKS (line 14) | const LINKS = [
FILE: apps/web/client/src/app/_components/top-bar/mega-menu.tsx
type DropdownMenuProps (line 8) | interface DropdownMenuProps {
function DropdownMenu (line 13) | function DropdownMenu({ label, links }: DropdownMenuProps) {
FILE: apps/web/client/src/app/_components/top-bar/mobile-menu.tsx
type MobileMenuProps (line 12) | interface MobileMenuProps {
function MobileMenu (line 17) | function MobileMenu({ isOpen, onOpenChange }: MobileMenuProps) {
FILE: apps/web/client/src/app/_components/website-layout.tsx
type WebsiteLayoutProps (line 6) | interface WebsiteLayoutProps {
function WebsiteLayout (line 11) | function WebsiteLayout({ children, showFooter = true }: WebsiteLayoutPro...
FILE: apps/web/client/src/app/about/layout.tsx
function AboutLayout (line 158) | function AboutLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/about/page.tsx
function AboutPage (line 14) | function AboutPage() {
FILE: apps/web/client/src/app/api/chat/helpers/stream.ts
function errorHandler (line 1) | function errorHandler(error: unknown) {
FILE: apps/web/client/src/app/api/chat/route.ts
function POST (line 10) | async function POST(req: NextRequest) {
FILE: apps/web/client/src/app/api/email-capture/route.ts
function POST (line 3) | async function POST(request: Request) {
FILE: apps/web/client/src/app/auth/auth-context.tsx
constant LAST_SIGN_IN_METHOD_KEY (line 10) | const LAST_SIGN_IN_METHOD_KEY = 'lastSignInMethod';
type AuthContextType (line 12) | interface AuthContextType {
FILE: apps/web/client/src/app/auth/callback/route.ts
function GET (line 7) | async function GET(request: Request) {
FILE: apps/web/client/src/app/auth/redirect/page.tsx
function AuthRedirect (line 10) | function AuthRedirect() {
FILE: apps/web/client/src/app/callback/github/install/page.tsx
type CallbackState (line 12) | type CallbackState = 'loading' | 'success' | 'error';
function GitHubInstallCallbackPage (line 14) | function GitHubInstallCallbackPage() {
FILE: apps/web/client/src/app/callback/stripe/cancel/page.tsx
function Cancel (line 4) | function Cancel() {
FILE: apps/web/client/src/app/callback/stripe/message-screen.tsx
function MessageScreen (line 2) | function MessageScreen({
FILE: apps/web/client/src/app/callback/stripe/success/page.tsx
function Success (line 6) | function Success() {
FILE: apps/web/client/src/app/faq/layout.tsx
function FAQLayout (line 46) | function FAQLayout({
FILE: apps/web/client/src/app/faq/page.tsx
function FAQPage (line 142) | function FAQPage() {
FILE: apps/web/client/src/app/features/ai-for-frontend/layout.tsx
function AiForFrontendLayout (line 187) | function AiForFrontendLayout({
FILE: apps/web/client/src/app/features/ai-for-frontend/page.tsx
function AiForFrontendPage (line 70) | function AiForFrontendPage() {
FILE: apps/web/client/src/app/features/ai/layout.tsx
function AiFeaturesLayout (line 134) | function AiFeaturesLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/features/ai/page.tsx
function AiFeaturesPage (line 43) | function AiFeaturesPage() {
FILE: apps/web/client/src/app/features/builder/layout.tsx
function BuilderFeaturesLayout (line 134) | function BuilderFeaturesLayout({ children }: { children: React.ReactNode...
FILE: apps/web/client/src/app/features/builder/page.tsx
function BuilderFeaturesPage (line 43) | function BuilderFeaturesPage() {
FILE: apps/web/client/src/app/features/layout.tsx
function FeaturesLayout (line 138) | function FeaturesLayout({
FILE: apps/web/client/src/app/features/page.tsx
function FeaturesPage (line 43) | function FeaturesPage() {
FILE: apps/web/client/src/app/features/prototype/layout.tsx
function PrototypeFeaturesLayout (line 141) | function PrototypeFeaturesLayout({ children }: { children: React.ReactNo...
FILE: apps/web/client/src/app/features/prototype/page.tsx
function PrototypeFeaturesHero (line 24) | function PrototypeFeaturesHero() {
function PrototypeBenefitsSection (line 103) | function PrototypeBenefitsSection() {
function PrototypeFeaturesGridSection (line 171) | function PrototypeFeaturesGridSection() {
function PrototypeFAQSection (line 285) | function PrototypeFAQSection() {
function PrototypeFeaturesPage (line 310) | function PrototypeFeaturesPage() {
FILE: apps/web/client/src/app/invitation/[id]/_components/main.tsx
function Main (line 14) | function Main({ invitationId }: { invitationId: string }) {
FILE: apps/web/client/src/app/invitation/[id]/layout.tsx
function Layout (line 10) | async function Layout({ children }: Readonly<{ children: React.ReactNode...
FILE: apps/web/client/src/app/invitation/[id]/page.tsx
function Page (line 3) | async function Page({ params }: { params: Promise<{ id: string }> }) {
FILE: apps/web/client/src/app/layout.tsx
function RootLayout (line 56) | async function RootLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/login/actions.tsx
function login (line 11) | async function login(provider: SignInMethod.GITHUB | SignInMethod.GOOGLE) {
function devLogin (line 40) | async function devLogin() {
FILE: apps/web/client/src/app/login/error.tsx
function ErrorPage (line 2) | function ErrorPage() {
FILE: apps/web/client/src/app/login/page.tsx
function LoginPage (line 14) | function LoginPage() {
FILE: apps/web/client/src/app/not-found.tsx
function NotFound (line 8) | function NotFound() {
FILE: apps/web/client/src/app/page.tsx
function Main (line 17) | function Main() {
FILE: apps/web/client/src/app/pricing/page.tsx
constant HIGHLIGHTED_FEATURES (line 12) | const HIGHLIGHTED_FEATURES = [
constant ENTERPRISE_FEATURES (line 60) | const ENTERPRISE_FEATURES = [
function PricingPage (line 71) | function PricingPage() {
FILE: apps/web/client/src/app/privacy-policy/page.tsx
function PrivacyPage (line 5) | function PrivacyPage() {
FILE: apps/web/client/src/app/project/[id]/_components/bottom-bar/terminal.tsx
type TerminalProps (line 12) | interface TerminalProps {
constant TERMINAL_THEME (line 19) | const TERMINAL_THEME: Record<'LIGHT' | 'DARK', ITheme> = {
FILE: apps/web/client/src/app/project/[id]/_components/branch/branch-controls.tsx
type BranchControlsProps (line 9) | interface BranchControlsProps {
function BranchControls (line 17) | function BranchControls({
FILE: apps/web/client/src/app/project/[id]/_components/branch/branch-list.tsx
type BranchListProps (line 11) | interface BranchListProps {
function BranchList (line 18) | function BranchList({
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/gesture.tsx
function handleDoubleClick (line 132) | async function handleDoubleClick(e: React.MouseEvent<HTMLDivElement>) {
function handleMouseDown (line 139) | async function handleMouseDown(e: React.MouseEvent<HTMLDivElement>) {
function handleMouseUp (line 151) | async function handleMouseUp(e: React.MouseEvent<HTMLDivElement>) {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/index.tsx
constant LOADING_MESSAGES (line 16) | const LOADING_MESSAGES = [
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/resize-handles.tsx
type HandleType (line 8) | enum HandleType {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/top-bar/branch.tsx
type BranchDisplayProps (line 17) | interface BranchDisplayProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/top-bar/helpers.ts
type MouseMoveHandlerOptions (line 4) | interface MouseMoveHandlerOptions {
function createMouseMoveHandler (line 10) | function createMouseMoveHandler(
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/top-bar/page-selector.tsx
type PageSelectorProps (line 19) | interface PageSelectorProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/use-frame-reload.ts
constant RELOAD_BASE_DELAY_MS (line 5) | const RELOAD_BASE_DELAY_MS = 2000;
constant RELOAD_INCREMENT_MS (line 6) | const RELOAD_INCREMENT_MS = 1000;
constant PENPAL_BASE_TIMEOUT_MS (line 7) | const PENPAL_BASE_TIMEOUT_MS = 5000;
constant PENPAL_TIMEOUT_INCREMENT_MS (line 8) | const PENPAL_TIMEOUT_INCREMENT_MS = 2000;
constant PENPAL_MAX_TIMEOUT_MS (line 9) | const PENPAL_MAX_TIMEOUT_MS = 30000;
function useFrameReload (line 11) | function useFrameReload() {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/use-sandbox-timeout.ts
constant SANDBOX_TIMEOUT_MS (line 6) | const SANDBOX_TIMEOUT_MS = 30000;
function useSandboxTimeout (line 8) | function useSandboxTimeout(frame: Frame, onTimeout: () => void) {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/frame/view.tsx
type IFrameView (line 20) | type IFrameView = HTMLIFrameElement & {
method get (line 30) | get(_target, prop: string | symbol) {
type FrameViewProps (line 54) | interface FrameViewProps extends IframeHTMLAttributes<HTMLIFrameElement> {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/index.tsx
constant ZOOM_SENSITIVITY (line 17) | const ZOOM_SENSITIVITY = 0.006;
constant PAN_SENSITIVITY (line 18) | const PAN_SENSITIVITY = 0.52;
constant MIN_ZOOM (line 19) | const MIN_ZOOM = 0.1;
constant MAX_ZOOM (line 20) | const MAX_ZOOM = 3;
constant MAX_X (line 21) | const MAX_X = 10000;
constant MAX_Y (line 22) | const MAX_Y = 10000;
constant MIN_X (line 23) | const MIN_X = -5000;
constant MIN_Y (line 24) | const MIN_Y = -5000;
function clampZoom (line 146) | function clampZoom(scale: number) {
function clampPosition (line 150) | function clampPosition(position: { x: number; y: number }, scale: number) {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/drag-select.tsx
type DragSelectOverlayProps (line 6) | interface DragSelectOverlayProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/buttons/helpers.ts
type InputState (line 1) | interface InputState {
constant DEFAULT_INPUT_STATE (line 8) | const DEFAULT_INPUT_STATE: InputState = {
constant DIMENSIONS (line 15) | const DIMENSIONS = {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/measurement.tsx
type Point (line 8) | interface Point {
type Distance (line 13) | interface Distance {
type RectPoint (line 23) | interface RectPoint extends RectDimensions {
type MeasurementProps (line 28) | interface MeasurementProps {
type DistanceWithoutSupportLine (line 93) | type DistanceWithoutSupportLine = Omit<Distance, 'supportLine'>;
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/rect/base.tsx
type RectProps (line 6) | interface RectProps extends RectDimensions {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/rect/click.tsx
type ClickRectProps (line 91) | interface ClickRectProps extends RectDimensions {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/rect/hover.tsx
type HoverRectProps (line 5) | interface HoverRectProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/rect/insert.tsx
type InsertRectProps (line 5) | interface InsertRectProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/rect/resize.tsx
type ResizeHandlePosition (line 6) | enum ResizeHandlePosition {
type HandleProps (line 17) | interface HandleProps {
type ResizeDimensions (line 62) | interface ResizeDimensions {
type EdgeHandleProps (line 123) | interface EdgeHandleProps extends HandleProps {
constant HANDLE_CONFIG (line 128) | const HANDLE_CONFIG = {
type ResizeHandlesProps (line 284) | interface ResizeHandlesProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/elements/snap-guidelines.tsx
constant SNAP_VISUAL_CONFIG (line 6) | const SNAP_VISUAL_CONFIG = {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/overlay/pan.tsx
type PanOverlayProps (line 6) | interface PanOverlayProps {
FILE: apps/web/client/src/app/project/[id]/_components/canvas/selection-utils.ts
type SelectionRect (line 3) | interface SelectionRect {
type CanvasPosition (line 10) | interface CanvasPosition {
function getFramesInSelection (line 24) | function getFramesInSelection(
function getSelectedFrameData (line 82) | function getSelectedFrameData(
FILE: apps/web/client/src/app/project/[id]/_components/clone-project-dialog.tsx
type CloneProjectDialogProps (line 24) | interface CloneProjectDialogProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/div-selected.tsx
constant DIV_SELECTED_GROUPS (line 27) | const DIV_SELECTED_GROUPS = [
constant MUST_EXTEND_GROUPS (line 62) | const MUST_EXTEND_GROUPS = [
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/border.tsx
type BorderTab (line 15) | enum BorderTab {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/display/index.tsx
type CssValue (line 18) | interface CssValue {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/img-fit.tsx
type ObjectFitValue (line 12) | type ObjectFitValue = 'fill' | 'contain' | 'cover' | 'none' | 'scale-down';
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/margin.tsx
type MarginTab (line 20) | enum MarginTab {
type MarginSide (line 25) | enum MarginSide {
constant SIDE_ORDER (line 33) | const SIDE_ORDER = ['top', 'right', 'bottom', 'left'] as const;
constant MARGIN_ICON_MAP (line 35) | const MARGIN_ICON_MAP: Record<string, typeof Icons.MarginEmpty> = {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/opacity.tsx
constant OPACITY_PRESETS (line 12) | const OPACITY_PRESETS = [100, 80, 75, 50, 25, 10, 0];
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/padding.tsx
type PaddingTab (line 18) | enum PaddingTab {
constant SIDE_ORDER (line 23) | const SIDE_ORDER = ['top', 'right', 'bottom', 'left'] as const;
constant PADDING_ICON_MAP (line 25) | const PADDING_ICON_MAP: Record<string, typeof Icons.PaddingEmpty> = {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/frame-selected/rotate-group.tsx
function RotateGroup (line 7) | function RotateGroup({ frameData }: { frameData: FrameData }) {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/frame-selected/theme-group.tsx
function ThemeGroup (line 9) | function ThemeGroup({ frameData }: { frameData: FrameData }) {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/frame-selected/window-actions-group.tsx
function WindowActionsGroup (line 8) | function WindowActionsGroup({ frameData }: { frameData: FrameData }) {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-background-image-update.ts
type ImageFit (line 5) | enum ImageFit {
constant IMAGE_FIT_OPTIONS (line 14) | const IMAGE_FIT_OPTIONS = [
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-box-control.ts
type BoxType (line 6) | type BoxType = 'margin' | 'padding' | 'border' | 'radius';
type BoxSide (line 7) | type BoxSide = 'Top' | 'Right' | 'Bottom' | 'Left';
type RadiusCorner (line 8) | type RadiusCorner = `${BoxSide}${BoxSide}Radius`;
type BoxProperty (line 9) | type BoxProperty =
type CSSBoxProperty (line 17) | type CSSBoxProperty = keyof Pick<
type BoxState (line 46) | interface BoxState {
type BoxStateMap (line 52) | type BoxStateMap = Record<CSSBoxProperty, BoxState>;
constant CORNERS_RADIUS (line 54) | const CORNERS_RADIUS: RadiusCorner[] = [
constant SIDES (line 61) | const SIDES: BoxSide[] = ['Top', 'Right', 'Bottom', 'Left'];
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-color-update.ts
type ColorUpdateOptions (line 7) | interface ColorUpdateOptions {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-dimension-control.ts
type DimensionType (line 12) | type DimensionType = 'width' | 'height';
type DimensionProperty (line 13) | type DimensionProperty<T extends DimensionType> = T | `min${Capitalize<T...
type DimensionState (line 15) | interface DimensionState {
type DimensionStateMap (line 22) | type DimensionStateMap<T extends DimensionType> = Record<DimensionProper...
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-dropdown-manager.tsx
type DropdownManagerContextType (line 6) | interface DropdownManagerContextType {
type DropdownManagerProviderProps (line 17) | interface DropdownManagerProviderProps {
type UseDropdownControlProps (line 88) | interface UseDropdownControlProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-gradient-update.ts
type GradientUpdateOptions (line 5) | interface GradientUpdateOptions {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-measure-group.ts
constant GROUP_WIDTHS (line 4) | const GROUP_WIDTHS = {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hooks/use-text-control.ts
type TextAlign (line 6) | type TextAlign = 'left' | 'center' | 'right' | 'justify';
type TextState (line 8) | interface TextState {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/hover-tooltip.tsx
type HoverOnlyTooltipProps (line 4) | interface HoverOnlyTooltipProps {
function HoverOnlyTooltip (line 14) | function HoverOnlyTooltip({
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/img-selected.tsx
constant IMG_SELECTED_GROUPS (line 17) | const IMG_SELECTED_GROUPS = [
constant MUST_EXTEND_GROUPS (line 40) | const MUST_EXTEND_GROUPS = [
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/index.tsx
type TAG_CATEGORIES (line 13) | enum TAG_CATEGORIES {
constant TAG_TYPES (line 20) | const TAG_TYPES: Record<TAG_CATEGORIES, string[]> = {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/color-picker.tsx
type TabValue (line 95) | enum TabValue {
type ColorPickerProps (line 101) | interface ColorPickerProps {
type PresetGradient (line 144) | interface PresetGradient {
function renderPalette (line 515) | function renderPalette() {
function renderPresets (line 576) | function renderPresets() {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/input-color.tsx
type InputColorProps (line 9) | interface InputColorProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/input-dropdown.tsx
constant OPTION_OVERRIDES (line 14) | const OPTION_OVERRIDES: Record<string, string | undefined> = {
type InputDropdownProps (line 19) | interface InputDropdownProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/input-icon.tsx
type IconType (line 13) | type IconType =
type InputIconProps (line 23) | interface InputIconProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/input-radio.tsx
type IconOption (line 6) | type IconOption = {
type TextOption (line 11) | type TextOption = {
type InputRadioProps (line 16) | interface InputRadioProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/input-range.tsx
type InputRangeProps (line 12) | interface InputRangeProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/inputs/spacing-inputs.tsx
type IconType (line 5) | type IconType =
type SpacingInputsProps (line 15) | interface SpacingInputsProps {
type IconMap (line 30) | type IconMap = Record<string, IconType>;
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/overflow-menu.tsx
type OverflowMenuProps (line 9) | interface OverflowMenuProps {
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/text-inputs/font/font-size.tsx
constant FONT_SIZES (line 11) | const FONT_SIZES = [12, 14, 16, 18, 20, 24, 30, 36, 48, 60, 72, 96];
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/text-selected.tsx
constant TEXT_SELECTED_GROUPS (line 26) | const TEXT_SELECTED_GROUPS = [
constant MUST_EXTEND_GROUPS (line 60) | const MUST_EXTEND_GROUPS = [
FILE: apps/web/client/src/app/project/[id]/_components/editor-bar/toolbar-button.tsx
type ToolbarButtonProps (line 5) | interface ToolbarButtonProps extends React.ButtonHTMLAttributes<HTMLButt...
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-content/code-editor.tsx
type CodeEditorProps (line 10) | interface CodeEditorProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-content/code-mirror-config.ts
method create (line 196) | create() {
method update (line 199) | update(decorations, tr) {
function createSearchHighlight (line 238) | function createSearchHighlight(term: string) {
function clearSearchHighlight (line 242) | function clearSearchHighlight() {
method create (line 251) | create() {
method update (line 254) | update(decorations, tr) {
function highlightElementRange (line 297) | function highlightElementRange(startLine: number, startCol: number, endL...
function clearElementHighlight (line 302) | function clearElementHighlight() {
function undebounceScrollToLineColumn (line 308) | function undebounceScrollToLineColumn(view: EditorView, line: number, co...
function scrollToFirstMatch (line 327) | function scrollToFirstMatch(view: EditorView, term: string): boolean {
function getLanguageFromFileName (line 379) | function getLanguageFromFileName(fileName: string): string {
function getExtensions (line 404) | function getExtensions(language: string): any[] {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-content/floating-add-to-chat-button.tsx
type FloatingAddToChatButtonProps (line 5) | interface FloatingAddToChatButtonProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-content/index.tsx
type CodeEditorAreaProps (line 10) | interface CodeEditorAreaProps {
function checkDirty (line 50) | async function checkDirty() {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-content/unsaved-changes-dialog.tsx
type UnsavedChangesDialogProps (line 3) | interface UnsavedChangesDialogProps {
function UnsavedChangesDialog (line 10) | function UnsavedChangesDialog({ onSave, onDiscard, onCancel, fileCount =...
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-tabs/file-tab.tsx
type FileTabProps (line 9) | interface FileTabProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/file-tabs/index.tsx
type FileTabsProps (line 15) | interface FileTabsProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/header-controls.tsx
type CodeControlsProps (line 16) | interface CodeControlsProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/hooks/use-code-navigation.ts
function useCodeNavigation (line 20) | function useCodeNavigation() {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/index.tsx
constant SOFT_MAX_OPENED_FILES (line 21) | const SOFT_MAX_OPENED_FILES = 7;
type CodeTabRef (line 23) | interface CodeTabRef {
type CodeTabProps (line 32) | interface CodeTabProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/modals/file-modal.tsx
type FileModalProps (line 17) | interface FileModalProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/modals/folder-modal.tsx
type FolderModalProps (line 16) | interface FolderModalProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/modals/upload-modal.tsx
type UploadModalProps (line 18) | interface UploadModalProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/shared/file-operations.ts
constant RESERVED_NAMES (line 3) | const RESERVED_NAMES: string[] = [
constant INVALID_CHARS_REGEX (line 29) | const INVALID_CHARS_REGEX = /[<>:"|?*\\/]/;
constant FILE_CONSTRAINTS (line 31) | const FILE_CONSTRAINTS = {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/shared/file-templates.ts
function generatePascalCaseName (line 3) | function generatePascalCaseName(fileName: string, extension: string): st...
constant FILE_TEMPLATES (line 13) | const FILE_TEMPLATES = {
function getFileTemplate (line 201) | function getFileTemplate(fileName: string): string {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/shared/types.ts
type EditorFile (line 1) | interface EditorFile {
type TextEditorFile (line 8) | interface TextEditorFile extends EditorFile {
type BinaryEditorFile (line 15) | interface BinaryEditorFile extends EditorFile {
type HighlightRange (line 21) | interface HighlightRange {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/shared/utils.ts
function isDirty (line 5) | async function isDirty(file: EditorFile): Promise<boolean> {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/sidebar/file-tree-node.tsx
type FileTreeNodeProps (line 28) | interface FileTreeNodeProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/sidebar/file-tree-search.tsx
type FileTreeSearchProps (line 5) | interface FileTreeSearchProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/code-panel/code-tab/sidebar/file-tree.tsx
type FileTreeProps (line 12) | interface FileTreeProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/branches-tab/branch-management.tsx
type BranchManagementProps (line 12) | interface BranchManagementProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/color-panel/color-name-input.tsx
type ColorNameInputProps (line 7) | interface ColorNameInputProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/color-panel/color-pallet-group.tsx
type BrandPalletGroupProps (line 18) | interface BrandPalletGroupProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/color-panel/color-row.tsx
type ColorRowProps (line 1) | interface ColorRowProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/font-panel/font-family.tsx
type FontVariantProps (line 13) | interface FontVariantProps {
type FontFamilyProps (line 24) | interface FontFamilyProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/font-panel/font-files.tsx
type FontFile (line 7) | interface FontFile {
type FontFilesProps (line 17) | interface FontFilesProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/font-panel/upload-modal.tsx
type UploadModalProps (line 15) | interface UploadModalProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/brand-tab/index.tsx
type ColorSquareProps (line 10) | interface ColorSquareProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/breadcrumb-navigation.tsx
type BreadcrumbNavigationProps (line 7) | interface BreadcrumbNavigationProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/folder-list.tsx
type FolderListProps (line 7) | interface FolderListProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/image-grid.tsx
type ImageGridProps (line 9) | interface ImageGridProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/image-item.tsx
type ImageItemProps (line 28) | interface ImageItemProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/search-upload-bar.tsx
type SearchUploadBarProps (line 8) | interface SearchUploadBarProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/types.ts
type ImageData (line 1) | interface ImageData {
type FolderData (line 7) | interface FolderData {
type BreadcrumbSegment (line 12) | interface BreadcrumbSegment {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/image-tab/utils/image-references.ts
function updateImageReferences (line 8) | async function updateImageReferences(
function replaceImageInString (line 116) | function replaceImageInString(
function escapeRegExp (line 139) | function escapeRegExp(str: string): string {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/layers-tab/index.tsx
function handleSelectChange (line 27) | function handleSelectChange() {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/layers-tab/tree/page-tree-node.tsx
type PageTreeNodeProps (line 17) | interface PageTreeNodeProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/layers-tab/tree/tree-node.tsx
function sideOffset (line 216) | function sideOffset() {
function toggleVisibility (line 229) | function toggleVisibility(): void {
function getNodeName (line 238) | function getNodeName() {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/layers-tab/tree/tree-row.tsx
type TreeRowProps (line 5) | interface TreeRowProps {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/page-tab/page-modal.tsx
type PageModalProps (line 21) | interface PageModalProps {
function PageModal (line 29) | function PageModal({
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/windows-tab/device-settings.tsx
function changeTheme (line 28) | async function changeTheme(newTheme: SystemTheme) {
FILE: apps/web/client/src/app/project/[id]/_components/left-panel/design-panel/zoom-controls/index.tsx
function clampZoom (line 42) | function clampZoom(scale: number) {
FILE: apps/web/client/src/app/project/[id]/_components/main.tsx
function handleGlobalWheel (line 36) | function handleGlobalWheel(event: WheelEvent) {
FILE: apps/web/client/src/app/project/[id]/_components/members/index.tsx
type MembersProps (line 10) | interface MembersProps {
FILE: apps/web/client/src/app/project/[id]/_components/members/member-row.tsx
type MemberRowProps (line 5) | interface MemberRowProps {
FILE: apps/web/client/src/app/project/[id]/_components/members/suggested-teammates.tsx
type SuggestedTeammateProps (line 7) | interface SuggestedTeammateProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-click-menu/index.tsx
type RightClickMenuProps (line 17) | interface RightClickMenuProps {
type MenuItem (line 21) | interface MenuItem {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-input/chat-mode-toggle.tsx
type ChatModeToggleProps (line 11) | interface ChatModeToggleProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-input/index.tsx
type ChatInputProps (line 32) | interface ChatInputProps {
function handleInput (line 112) | function handleInput(e: React.ChangeEvent<HTMLTextAreaElement>) {
function sendMessage (line 147) | async function sendMessage() {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/error-message.tsx
type ErrorMessageProps (line 7) | interface ErrorMessageProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/index.tsx
type ChatMessagesProps (line 21) | interface ChatMessagesProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/message-content/tool-call-simple.tsx
function getDefaultToolLabel (line 34) | function getDefaultToolLabel(toolName: string): string {
function getToolLabel (line 38) | function getToolLabel(toolClass: typeof BaseTool, input: unknown): string {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/multi-branch-revert-modal.tsx
type MultiBranchRevertModalProps (line 22) | interface MultiBranchRevertModalProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/user-message.tsx
type UserMessageProps (line 29) | interface UserMessageProps {
function handleCopyClick (line 91) | async function handleCopyClick() {
function renderEditingInput (line 141) | function renderEditingInput() {
function renderButtons (line 166) | function renderButtons() {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-tab-content/index.tsx
type ChatTabContentProps (line 7) | interface ChatTabContentProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/code-display/code-diff.tsx
type CodeDiffProps (line 5) | interface CodeDiffProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/code-display/collapsible-code-block.tsx
type CollapsibleCodeBlockProps (line 11) | interface CollapsibleCodeBlockProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/code-display/search-sources-display.tsx
type SearchResult (line 8) | interface SearchResult {
type SearchSourcesDisplayProps (line 13) | interface SearchSourcesDisplayProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/context-pills/helpers.tsx
function getTruncatedName (line 7) | function getTruncatedName(context: MessageContext) {
function getContextIcon (line 19) | function getContextIcon(context: MessageContext) {
function validateImageLimit (line 35) | function validateImageLimit(
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/context-pills/sent-context-pill.tsx
function SentContextPill (line 4) | function SentContextPill({ context }: { context: MessageContext }) {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/error.tsx
type ErrorSectionProps (line 14) | interface ErrorSectionProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/history.tsx
type ChatHistoryProps (line 19) | interface ChatHistoryProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/index.tsx
type ChatTabProps (line 5) | interface ChatTabProps {
FILE: apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/suggestions.tsx
type SuggestionsRef (line 9) | interface SuggestionsRef {
FILE: apps/web/client/src/app/project/[id]/_components/top-bar/mode-toggle.tsx
constant MODE_TOGGLE_ITEMS (line 13) | const MODE_TOGGLE_ITEMS: {
FILE: apps/web/client/src/app/project/[id]/_components/top-bar/new-project-menu.tsx
type NewProjectMenuProps (line 18) | interface NewProjectMenuProps {
FILE: apps/web/client/src/app/project/[id]/_components/top-bar/project-breadcrumb.tsx
function handleNavigateToProjects (line 41) | async function handleNavigateToProjects(_route?: 'create' | 'import') {
function handleDownloadCode (line 56) | async function handleDownloadCode() {
FILE: apps/web/client/src/app/project/[id]/_hooks/use-chat/index.tsx
type SendMessage (line 18) | type SendMessage = (content: string, type: ChatType) => Promise<ChatMess...
type EditMessage (line 19) | type EditMessage = (
type ProcessMessage (line 24) | type ProcessMessage = (
type UseChatProps (line 30) | interface UseChatProps {
function useChat (line 36) | function useChat({ conversationId, projectId, initialMessages }: UseChat...
FILE: apps/web/client/src/app/project/[id]/_hooks/use-chat/utils.ts
function createCheckpointsForAllBranches (line 36) | async function createCheckpointsForAllBranches(
FILE: apps/web/client/src/app/project/[id]/_hooks/use-start-project.tsx
type ProjectReadyState (line 19) | interface ProjectReadyState {
FILE: apps/web/client/src/app/project/[id]/_hooks/use-tab-active.tsx
type TabActivityState (line 3) | type TabActivityState = 'active' | 'inactive' | 'reactivated';
function useTabActive (line 5) | function useTabActive() {
FILE: apps/web/client/src/app/project/[id]/layout.tsx
function Layout (line 7) | async function Layout({ params, children }: Readonly<{ params: Promise<{...
FILE: apps/web/client/src/app/project/[id]/page.tsx
function Page (line 5) | async function Page({ params }: { params: Promise<{ id: string }> }) {
FILE: apps/web/client/src/app/project/layout.tsx
function Layout (line 7) | async function Layout({ children }: Readonly<{ children: React.ReactNode...
FILE: apps/web/client/src/app/project/page.tsx
function Page (line 4) | function Page() {
FILE: apps/web/client/src/app/projects/_components/carousel/index.tsx
type CarouselProps (line 8) | interface CarouselProps {
constant SCROLL_AMOUNT (line 16) | const SCROLL_AMOUNT = 300;
constant SCROLL_TOLERANCE (line 17) | const SCROLL_TOLERANCE = 10;
function Carousel (line 19) | function Carousel({
FILE: apps/web/client/src/app/projects/_components/edit-app.tsx
type EditAppButtonProps (line 17) | interface EditAppButtonProps extends ComponentProps<typeof ButtonMotion> {
FILE: apps/web/client/src/app/projects/_components/select-presentation.tsx
type SelectProjectPresentationProps (line 18) | interface SelectProjectPresentationProps {
function handleClickOutside (line 199) | function handleClickOutside(event: MouseEvent) {
FILE: apps/web/client/src/app/projects/_components/select/highlight-text.tsx
function HighlightText (line 3) | function HighlightText({ text, searchQuery }: { text: string; searchQuer...
FILE: apps/web/client/src/app/projects/_components/select/index.tsx
constant STARRED_TEMPLATES_KEY (line 24) | const STARRED_TEMPLATES_KEY = 'onlook_starred_templates';
function handleClickOutside (line 192) | function handleClickOutside(event: MouseEvent) {
FILE: apps/web/client/src/app/projects/_components/select/masonry-layout.tsx
function MasonryLayout (line 6) | function MasonryLayout<T extends Project>({ items, spacing, renderItem }: {
FILE: apps/web/client/src/app/projects/_components/select/project-card-presentation.tsx
type ProjectCardPresentationProps (line 16) | interface ProjectCardPresentationProps {
function ProjectCardPresentation (line 41) | function ProjectCardPresentation({
FILE: apps/web/client/src/app/projects/_components/select/project-card.tsx
function ProjectCard (line 12) | function ProjectCard({
FILE: apps/web/client/src/app/projects/_components/select/square-project-card-presentation.tsx
type SquareProjectCardPresentationProps (line 7) | interface SquareProjectCardPresentationProps {
function SquareProjectCardPresentation (line 21) | function SquareProjectCardPresentation({
FILE: apps/web/client/src/app/projects/_components/select/square-project-card.tsx
function SquareProjectCard (line 11) | function SquareProjectCard({
FILE: apps/web/client/src/app/projects/_components/settings/clone-project.tsx
function CloneProject (line 23) | function CloneProject({ project, refetch }: { project: Project; refetch:...
FILE: apps/web/client/src/app/projects/_components/settings/create-template.tsx
function CreateTemplate (line 10) | function CreateTemplate({ project, refetch }: { project: Project; refetc...
FILE: apps/web/client/src/app/projects/_components/settings/delete-project.tsx
function DeleteProject (line 20) | function DeleteProject({ project, refetch }: { project: Project; refetch...
FILE: apps/web/client/src/app/projects/_components/settings/index.tsx
function SettingsDropdown (line 14) | function SettingsDropdown({ project, refetch }: { project: Project; refe...
FILE: apps/web/client/src/app/projects/_components/settings/rename-project.tsx
function RenameProject (line 22) | function RenameProject({ project, refetch }: { project: Project; refetch...
FILE: apps/web/client/src/app/projects/_components/templates/index.tsx
type TemplatesProps (line 12) | interface TemplatesProps {
function Templates (line 20) | function Templates({ templateProjects, searchQuery, onTemplateClick, onT...
FILE: apps/web/client/src/app/projects/_components/templates/lazy-image.tsx
type LazyImageProps (line 6) | interface LazyImageProps {
function LazyImage (line 16) | function LazyImage({
FILE: apps/web/client/src/app/projects/_components/templates/template-card.tsx
type TemplateCardProps (line 6) | interface TemplateCardProps {
function TemplateCard (line 16) | function TemplateCard({
FILE: apps/web/client/src/app/projects/_components/templates/template-modal-presentation.tsx
type TemplateModalPresentationProps (line 16) | interface TemplateModalPresentationProps {
function TemplateModalPresentation (line 37) | function TemplateModalPresentation({
FILE: apps/web/client/src/app/projects/_components/templates/template-modal.tsx
type TemplateModalProps (line 25) | interface TemplateModalProps {
function TemplateModal (line 39) | function TemplateModal({
function TemplateStats (line 255) | function TemplateStats() {
FILE: apps/web/client/src/app/projects/_components/top-bar-presentation.tsx
type TopBarPresentationProps (line 22) | interface TopBarPresentationProps {
FILE: apps/web/client/src/app/projects/_components/top-bar.tsx
constant RECENT_SEARCHES_KEY (line 27) | const RECENT_SEARCHES_KEY = 'onlook_recent_searches';
constant RECENT_COLORS_KEY (line 28) | const RECENT_COLORS_KEY = 'onlook_recent_colors';
type TopBarProps (line 30) | interface TopBarProps {
FILE: apps/web/client/src/app/projects/import/github/_context/index.tsx
type ImportGithubProjectProviderProps (line 14) | interface ImportGithubProjectProviderProps {
type ImportGithubContextType (line 19) | interface ImportGithubContextType {
FILE: apps/web/client/src/app/projects/import/github/_hooks/use-installation.ts
type GitHubAppInstallation (line 6) | interface GitHubAppInstallation {
FILE: apps/web/client/src/app/projects/import/github/layout.tsx
function Layout (line 12) | async function Layout({ children }: Readonly<{ children: React.ReactNode...
FILE: apps/web/client/src/app/projects/import/layout.tsx
function Layout (line 11) | async function Layout({ children }: Readonly<{ children: React.ReactNode...
FILE: apps/web/client/src/app/projects/import/local/_components/select-folder.tsx
type InputHTMLAttributes (line 17) | interface InputHTMLAttributes<T> extends HTMLAttributes<T> {
FILE: apps/web/client/src/app/projects/import/local/_context/index.tsx
type Project (line 18) | interface Project {
type ProjectCreationContextValue (line 24) | interface ProjectCreationContextValue {
function detectPortFromPackageJson (line 47) | function detectPortFromPackageJson(packageJsonFile: ProcessedFile | unde...
type ProjectCreationProviderProps (line 85) | interface ProjectCreationProviderProps {
FILE: apps/web/client/src/app/projects/import/local/layout.tsx
function Layout (line 12) | async function Layout({ children }: Readonly<{ children: React.ReactNode...
FILE: apps/web/client/src/app/projects/layout.tsx
function Layout (line 15) | async function Layout({ children }: Readonly<{ children: React.ReactNode...
FILE: apps/web/client/src/app/projects/types.ts
type ProcessedFileType (line 1) | enum ProcessedFileType {
type BaseProcessedFile (line 6) | interface BaseProcessedFile {
type BinaryProcessedFile (line 12) | interface BinaryProcessedFile extends BaseProcessedFile {
type TextProcessedFile (line 17) | interface TextProcessedFile extends BaseProcessedFile {
type ProcessedFile (line 22) | type ProcessedFile = BinaryProcessedFile | TextProcessedFile;
type NextJsProjectValidation (line 24) | interface NextJsProjectValidation {
FILE: apps/web/client/src/app/see-a-demo/page.tsx
function DemoOnlyPage (line 10) | function DemoOnlyPage() {
FILE: apps/web/client/src/app/site-map/layout.tsx
function SitemapLayout (line 74) | function SitemapLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/site-map/page.tsx
type SitemapLink (line 8) | interface SitemapLink {
type SitemapSection (line 15) | interface SitemapSection {
function SitemapLinkItem (line 178) | function SitemapLinkItem({ link }: { link: SitemapLink }) {
function SitemapPage (line 206) | function SitemapPage() {
FILE: apps/web/client/src/app/sitemap.ts
function sitemap (line 3) | function sitemap(): MetadataRoute.Sitemap {
FILE: apps/web/client/src/app/terms-of-service/page.tsx
function TermsPage (line 5) | function TermsPage() {
FILE: apps/web/client/src/app/webhook/stripe/route.ts
function POST (line 6) | async function POST(request: Request) {
FILE: apps/web/client/src/app/webhook/stripe/subscription/helpers.ts
function extractIdsFromEvent (line 3) | function extractIdsFromEvent(
FILE: apps/web/client/src/app/workflows/claude-code/layout.tsx
function ClaudeCodeLayout (line 147) | function ClaudeCodeLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/workflows/claude-code/page.tsx
function ClaudeCodeWorkflowPage (line 58) | function ClaudeCodeWorkflowPage() {
FILE: apps/web/client/src/app/workflows/layout.tsx
function WorkflowsLayout (line 89) | function WorkflowsLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/workflows/page.tsx
function WorkflowsPage (line 54) | function WorkflowsPage() {
FILE: apps/web/client/src/app/workflows/vibe-coding/layout.tsx
function VibeCodingLayout (line 156) | function VibeCodingLayout({ children }: { children: React.ReactNode }) {
FILE: apps/web/client/src/app/workflows/vibe-coding/page.tsx
function VibeCodingHero (line 60) | function VibeCodingHero() {
function VibeCodingWorkflowPage (line 137) | function VibeCodingWorkflowPage() {
FILE: apps/web/client/src/components/hotkey.ts
class Hotkey (line 3) | class Hotkey {
method constructor (line 46) | private constructor(
method toString (line 51) | toString() {
method readableCommand (line 55) | get readableCommand() {
FILE: apps/web/client/src/components/ide.ts
class IDE (line 5) | class IDE {
method constructor (line 12) | private constructor(
method toString (line 19) | toString() {
method fromType (line 23) | static fromType(type: IdeType): IDE {
method getAll (line 40) | static getAll(): IDE[] {
method getCodeFileCommand (line 44) | getCodeFileCommand(filePath: string, line?: number) {
FILE: apps/web/client/src/components/rb2b-loader.tsx
function RB2BLoader (line 7) | function RB2BLoader() {
FILE: apps/web/client/src/components/store/create/manager.ts
class CreateManager (line 9) | class CreateManager {
method constructor (line 12) | constructor() {
method generateProjectName (line 16) | async generateProjectName(prompt: string): Promise<string> {
method startCreate (line 28) | async startCreate(userId: string, prompt: string, images: ImageMessage...
method startGitHubTemplate (line 80) | async startGitHubTemplate(userId: string, repoUrl: string) {
method createSandboxFromGithub (line 121) | async createSandboxFromGithub(repoUrl: string, branch: string) {
FILE: apps/web/client/src/components/store/editor/action/index.ts
class ActionManager (line 21) | class ActionManager {
method constructor (line 22) | constructor(private editorEngine: EditorEngine) { }
method run (line 24) | async run(action: Action) {
method undo (line 29) | async undo() {
method redo (line 39) | async redo() {
method dispatch (line 48) | private async dispatch(action: Action) {
method updateStyle (line 85) | async updateStyle({ targets }: UpdateStyleAction) {
method debouncedRefreshDomElement (line 128) | debouncedRefreshDomElement(domEls: DomElement[]) {
method insertElement (line 134) | private async insertElement({ targets, element, editText, location }: ...
method removeElement (line 156) | private async removeElement({ targets, location }: RemoveElementAction) {
method moveElement (line 177) | private async moveElement({ targets, location }: MoveElementAction) {
method editText (line 193) | private async editText({ targets, newContent }: EditTextAction) {
method groupElements (line 210) | private async groupElements({ parent, container, children }: GroupElem...
method ungroupElements (line 231) | private async ungroupElements({ parent, container }: UngroupElementsAc...
method insertImage (line 248) | private insertImage({ targets, image }: InsertImageAction) {
method removeImage (line 262) | private removeImage({ targets }: RemoveImageAction) {
method refreshAndClickMutatedElement (line 275) | async refreshAndClickMutatedElement(
method clear (line 288) | clear() { }
FILE: apps/web/client/src/components/store/editor/api/index.ts
class ApiManager (line 6) | class ApiManager {
method constructor (line 7) | constructor(private editorEngine: EditorEngine) {
method webSearch (line 11) | async webSearch(input: {
method applyDiff (line 20) | async applyDiff(input: {
method scrapeUrl (line 32) | async scrapeUrl(input: {
method getConversationMessages (line 43) | async getConversationMessages(conversationId: string): Promise<ChatMes...
FILE: apps/web/client/src/components/store/editor/ast/index.ts
class AstManager (line 9) | class AstManager {
method constructor (line 12) | constructor(private editorEngine: EditorEngine) {
method mappings (line 17) | get mappings() {
method setMapRoot (line 21) | setMapRoot(frameId: string, rootNode: LayerNode, layerMap: Map<string,...
method updateMap (line 26) | updateMap(frameId: string, newMap: Map<string, LayerNode>, domId: stri...
method processNode (line 36) | processNode(frameId: string, node: LayerNode) {
method dfs (line 42) | dfs(frameId: string, root: LayerNode, callback: (node: LayerNode) => v...
method processNodeForMap (line 64) | private async processNodeForMap(frameId: string, node: LayerNode) {
method findNodeInstance (line 112) | private async findNodeInstance(
method updateElementInstance (line 191) | updateElementInstance(frameId: string, domId: string, instanceId: stri...
method clear (line 200) | clear() {
FILE: apps/web/client/src/components/store/editor/ast/layers.ts
type LayerMetadata (line 5) | interface LayerMetadata {
class LayersManager (line 11) | class LayersManager {
method constructor (line 14) | constructor(private editorEngine: EditorEngine) {
method layers (line 18) | get layers(): LayerNode[] {
method filteredLayers (line 24) | get filteredLayers(): LayerNode[] {
method getRootLayer (line 34) | getRootLayer(frameId: string): LayerNode | undefined {
method getMetadata (line 38) | getMetadata(frameId: string): LayerMetadata | undefined {
method setMetadata (line 42) | setMetadata(
method addNewMapping (line 53) | addNewMapping(frameId: string, domIdToLayerNode: Map<string, LayerNode...
method getMapping (line 63) | getMapping(frameId: string): Map<string, LayerNode> | undefined {
method getLayerNode (line 67) | getLayerNode(frameId: string, domId: string): LayerNode | undefined {
method remove (line 71) | remove(frameId: string) {
method clear (line 75) | clear() {
FILE: apps/web/client/src/components/store/editor/branch/manager.ts
type BranchData (line 12) | interface BranchData {
class BranchManager (line 20) | class BranchManager {
method constructor (line 26) | constructor(editorEngine: EditorEngine) {
method initBranches (line 31) | async initBranches(branches: Branch[]): Promise<void> {
method init (line 56) | async init(): Promise<void> {
method setupActiveFrameReaction (line 64) | private setupActiveFrameReaction(): void {
method activeBranchData (line 80) | get activeBranchData(): BranchData {
method activeBranch (line 91) | get activeBranch(): Branch {
method activeSandbox (line 95) | get activeSandbox(): SandboxManager {
method activeHistory (line 99) | get activeHistory(): HistoryManager {
method activeError (line 103) | get activeError(): ErrorManager {
method activeCodeEditor (line 107) | get activeCodeEditor(): CodeFileSystem {
method switchToBranch (line 111) | async switchToBranch(branchId: string): Promise<void> {
method getBranchDataById (line 118) | getBranchDataById(branchId: string): BranchData | null {
method getBranchById (line 122) | getBranchById(branchId: string): Branch | null {
method getSandboxById (line 126) | getSandboxById(branchId: string): SandboxManager | null {
method createBranchData (line 130) | private createBranchData(branch: Branch, routerType?: RouterType): Bra...
method allBranches (line 149) | get allBranches(): Branch[] {
method listBranches (line 153) | async listBranches(): Promise<Branch[]> {
method forkBranch (line 157) | async forkBranch(branchId: string): Promise<void> {
method createBlankSandbox (line 193) | async createBlankSandbox(branchName?: string): Promise<void> {
method updateBranch (line 248) | async updateBranch(branchId: string, updates: Partial<Branch>): Promis...
method removeBranch (line 272) | async removeBranch(branchId: string): Promise<void> {
method clear (line 305) | async clear(): Promise<void> {
method getAllErrors (line 319) | getAllErrors(): ParsedError[] {
method getTotalErrorCount (line 332) | getTotalErrorCount(): number {
method getErrorsForBranch (line 339) | getErrorsForBranch(branchId: string): ParsedError[] {
FILE: apps/web/client/src/components/store/editor/cache/file-cache.ts
class FileCacheManager (line 6) | class FileCacheManager {
method constructor (line 10) | constructor(projectId: string, branchId: string) {
method init (line 28) | async init(): Promise<void> {
method hasFile (line 36) | hasFile(filePath: string): boolean {
method getFile (line 40) | getFile(filePath: string): SandboxFile | undefined {
method setFile (line 44) | setFile(file: SandboxFile, contentHash?: string): void {
method deleteFile (line 48) | deleteFile(filePath: string): boolean {
method hasDirectory (line 53) | hasDirectory(dirPath: string): boolean {
method setDirectory (line 57) | setDirectory(directory: SandboxDirectory): void {
method deleteDirectory (line 61) | deleteDirectory(dirPath: string): boolean {
method isFileLoaded (line 65) | isFileLoaded(file: SandboxFile): boolean {
method readOrFetch (line 69) | async readOrFetch(
method write (line 85) | async write(
method rename (line 108) | rename(oldPath: string, newPath: string): void {
method renameDirectory (line 117) | renameDirectory(oldPath: string, newPath: string): void {
method listAllFiles (line 176) | listAllFiles(): string[] {
method listAllDirectories (line 180) | listAllDirectories(): string[] {
method writeEmptyFile (line 184) | writeEmptyFile(filePath: string, type: 'binary'): void {
method clear (line 197) | async clear(): Promise<void> {
method fileCount (line 211) | get fileCount(): number {
method directoryCount (line 215) | get directoryCount(): number {
FILE: apps/web/client/src/components/store/editor/cache/types.ts
type CacheConfig (line 3) | interface CacheConfig {
type Serializable (line 11) | interface Serializable {
type CachedItem (line 15) | interface CachedItem<T> {
type PersistentCacheData (line 22) | interface PersistentCacheData {
type CacheBackend (line 28) | interface CacheBackend<T> {
FILE: apps/web/client/src/components/store/editor/cache/unified-cache.ts
class UnifiedCacheManager (line 8) | class UnifiedCacheManager<T extends Serializable = Serializable> {
method constructor (line 14) | constructor(config: CacheConfig) {
method init (line 33) | async init(): Promise<void> {
method get (line 43) | get(key: string): T | undefined {
method set (line 48) | set(key: string, data: T, contentHash?: string): void {
method has (line 65) | has(key: string): boolean {
method delete (line 69) | delete(key: string): boolean {
method clear (line 73) | clear(): void {
method size (line 77) | get size(): number {
method entries (line 81) | entries(): IterableIterator<[string, T]> {
method keys (line 89) | keys(): IterableIterator<string> {
method getCached (line 94) | getCached(key: string, currentContentHash?: string): T | undefined {
method loadFromPersistent (line 106) | private async loadFromPersistent(): Promise<void> {
method saveToPersistent (line 129) | async saveToPersistent(): Promise<void> {
method clearPersistent (line 161) | async clearPersistent(): Promise<void> {
method shouldPersist (line 166) | private shouldPersist(): boolean {
method estimateSize (line 171) | private estimateSize(data: T): number {
FILE: apps/web/client/src/components/store/editor/canvas/index.ts
class CanvasManager (line 9) | class CanvasManager {
method constructor (line 14) | constructor(private readonly editorEngine: EditorEngine) {
method applyCanvas (line 19) | applyCanvas(canvas: Canvas) {
method getDefaultPanPosition (line 25) | getDefaultPanPosition(): RectPosition {
method id (line 37) | get id() {
method id (line 41) | set id(value: string) {
method scale (line 45) | get scale() {
method scale (line 49) | set scale(value: number) {
method position (line 54) | get position() {
method position (line 58) | set position(value: RectPosition) {
method undebouncedSaveCanvas (line 66) | private async undebouncedSaveCanvas() {
method clear (line 81) | clear() {
FILE: apps/web/client/src/components/store/editor/chat/context.ts
class ChatContext (line 16) | class ChatContext {
method constructor (line 20) | constructor(private editorEngine: EditorEngine) {
method init (line 24) | init() {
method context (line 46) | get context(): MessageContext[] {
method context (line 50) | set context(context: MessageContext[]) {
method addContexts (line 54) | addContexts(contexts: MessageContext[]) {
method addHighlightContext (line 80) | addHighlightContext(path: string, content: string, start: number, end:...
method getContextByChatType (line 93) | async getContextByChatType(type: ChatType): Promise<MessageContext[]> {
method getChatEditContext (line 106) | async getChatEditContext(): Promise<MessageContext[]> {
method generateContextFromReaction (line 113) | private async generateContextFromReaction({ elements, frames }: { elem...
method getRefreshedContext (line 126) | async getRefreshedContext(context: MessageContext[]): Promise<MessageC...
method getFileContext (line 163) | private async getFileContext(highlightedContext: HighlightMessageConte...
method getBranchContext (line 195) | getBranchContext(
method getHighlightedContext (line 223) | private async getHighlightedContext(
method getHighlightContextById (line 249) | private async getHighlightContextById(
method getAgentRuleContext (line 282) | private async getAgentRuleContext(): Promise<AgentRuleMessageContext[]> {
method getErrorContext (line 314) | getErrorContext(): ErrorMessageContext[] {
method getCreateContext (line 335) | async getCreateContext() {
method getDefaultPageContext (line 353) | async getDefaultPageContext(): Promise<FileMessageContext | null> {
method getDefaultStyleGuideContext (line 395) | async getDefaultStyleGuideContext(): Promise<FileMessageContext[] | nu...
method clearImagesFromContext (line 430) | clearImagesFromContext() {
method clear (line 436) | clear() {
FILE: apps/web/client/src/components/store/editor/chat/conversation.ts
type CurrentConversation (line 7) | interface CurrentConversation extends ChatConversation {
class ConversationManager (line 11) | class ConversationManager {
method constructor (line 16) | constructor(private editorEngine: EditorEngine) {
method applyConversations (line 20) | async applyConversations(conversations: ChatConversation[]) {
method getConversations (line 30) | async getConversations(projectId: string): Promise<ChatConversation[]> {
method setConversationLength (line 44) | setConversationLength(length: number) {
method startNewConversation (line 53) | async startNewConversation() {
method selectConversation (line 77) | async selectConversation(id: string) {
method deleteConversation (line 90) | deleteConversation(id: string) {
method generateTitle (line 112) | async generateTitle(content: string): Promise<void> {
method getConversationsFromStorage (line 140) | async getConversationsFromStorage(id: string): Promise<ChatConversatio...
method upsertConversationInStorage (line 144) | async upsertConversationInStorage(conversation: Partial<ChatConversati...
method updateConversationInStorage (line 151) | async updateConversationInStorage(conversation: Partial<ChatConversati...
method deleteConversationInStorage (line 155) | async deleteConversationInStorage(id: string) {
method clear (line 159) | clear() {
FILE: apps/web/client/src/components/store/editor/chat/index.ts
constant FOCUS_CHAT_INPUT_EVENT (line 8) | const FOCUS_CHAT_INPUT_EVENT = 'focus-chat-input';
class ChatManager (line 9) | class ChatManager {
method constructor (line 17) | constructor(private editorEngine: EditorEngine) {
method init (line 23) | init() {
method focusChatInput (line 27) | focusChatInput() {
method getCurrentConversationId (line 31) | getCurrentConversationId() {
method setIsStreaming (line 35) | setIsStreaming(isStreaming: boolean) {
method setChatActions (line 39) | setChatActions(sendMessage: SendMessage) {
method sendMessage (line 43) | async sendMessage(content: string, type: ChatType): Promise<void> {
method clear (line 51) | clear() {
FILE: apps/web/client/src/components/store/editor/code/helpers.ts
function getOrCreateCodeDiffRequest (line 3) | async function getOrCreateCodeDiffRequest(
FILE: apps/web/client/src/components/store/editor/code/index.ts
class CodeManager (line 21) | class CodeManager {
method constructor (line 22) | constructor(private editorEngine: EditorEngine) {
method write (line 26) | async write(action: Action) {
method writeRequest (line 48) | async writeRequest(requests: CodeDiffRequest[]) {
method collectRequests (line 71) | private async collectRequests(action: Action): Promise<CodeDiffRequest...
method groupRequestByFile (line 98) | async groupRequestByFile(requests: CodeDiffRequest[]): Promise<FileToR...
method clear (line 125) | clear() { }
FILE: apps/web/client/src/components/store/editor/code/insert.ts
function getInsertedElement (line 8) | function getInsertedElement(
FILE: apps/web/client/src/components/store/editor/code/requests.ts
function processGroupedRequests (line 27) | async function processGroupedRequests(groupedRequests: FileToRequests): ...
function getStyleRequests (line 46) | async function getStyleRequests({ targets }: UpdateStyleAction): Promise...
function getInsertRequests (line 61) | async function getInsertRequests({
function getRemoveRequests (line 83) | async function getRemoveRequests({
function getEditTextRequests (line 99) | async function getEditTextRequests({
function getMoveRequests (line 116) | async function getMoveRequests({
function getGroupRequests (line 144) | async function getGroupRequests(action: GroupElementsAction): Promise<Co...
function getUngroupRequests (line 162) | async function getUngroupRequests(
function getWriteCodeRequests (line 182) | async function getWriteCodeRequests(action: WriteCodeAction): Promise<Co...
function getInsertImageRequests (line 186) | async function getInsertImageRequests(
function getRemoveImageRequests (line 192) | async function getRemoveImageRequests(
FILE: apps/web/client/src/components/store/editor/code/tailwind.ts
function addTailwindToRequest (line 6) | function addTailwindToRequest(
function getTailwindClasses (line 14) | function getTailwindClasses(oid: string, styles: Record<string, StyleCha...
function createCSSRuleString (line 51) | function createCSSRuleString(oid: string, styles: Record<string, StyleCh...
FILE: apps/web/client/src/components/store/editor/copy/index.ts
class CopyManager (line 13) | class CopyManager {
method constructor (line 19) | constructor(private editorEngine: EditorEngine) {
method copy (line 23) | async copy() {
method clearClipboard (line 69) | async clearClipboard() {
method paste (line 77) | async paste() {
method cut (line 132) | async cut() {
method duplicate (line 137) | async duplicate() {
method getInsertLocation (line 144) | async getInsertLocation(selectedEl: DomElement): Promise<ActionLocatio...
method clear (line 179) | clear() {
FILE: apps/web/client/src/components/store/editor/element/index.ts
class ElementsManager (line 9) | class ElementsManager {
method constructor (line 13) | constructor(private editorEngine: EditorEngine) {
method hovered (line 17) | get hovered() {
method selected (line 21) | get selected() {
method selected (line 25) | set selected(elements: DomElement[]) {
method mouseover (line 29) | mouseover(domEl: DomElement) {
method shiftClick (line 50) | shiftClick(domEl: DomElement) {
method click (line 62) | click(domEls: DomElement[]) {
method setHoveredElement (line 89) | setHoveredElement(element: DomElement) {
method clearHoveredElement (line 93) | clearHoveredElement() {
method emitError (line 97) | emitError(error: string) {
method delete (line 102) | async delete() {
method shouldDelete (line 158) | private async shouldDelete(
method clear (line 210) | clear() {
method clearSelectedElements (line 215) | private clearSelectedElements() {
FILE: apps/web/client/src/components/store/editor/engine.ts
class EditorEngine (line 33) | class EditorEngine {
method activeSandbox (line 38) | get activeSandbox(): SandboxManager {
method history (line 42) | get history() {
method fileSystem (line 46) | get fileSystem(): CodeFileSystem {
method constructor (line 75) | constructor(projectId: string, posthog: PostHog) {
method init (line 81) | async init() {
method initBranches (line 89) | async initBranches(branches: Branch[]) {
method clear (line 94) | clear() {
method clearUI (line 119) | clearUI() {
method refreshLayers (line 126) | async refreshLayers() {
FILE: apps/web/client/src/components/store/editor/error/index.ts
class ErrorManager (line 5) | class ErrorManager {
method constructor (line 9) | constructor(private readonly branch: Branch) {
method errors (line 26) | get errors(): ParsedError[] {
method processMessage (line 30) | processMessage(message: string) {
method addError (line 35) | addError(message: string) {
method addCodeApplicationError (line 49) | addCodeApplicationError(message: string, metadata: Action | Object) {
method handleSuccess (line 68) | handleSuccess(message: string) {
method clear (line 72) | clear() {
FILE: apps/web/client/src/components/store/editor/font/font-search-manager.ts
class FontSearchManager (line 6) | class FontSearchManager {
method constructor (line 16) | constructor() {
method loadInitialFonts (line 42) | async loadInitialFonts(): Promise<void> {
method loadFontBatch (line 55) | private async loadFontBatch(fonts: Font[]): Promise<void> {
method fetchNextFontBatch (line 80) | async fetchNextFontBatch(): Promise<{ fonts: Font[]; hasMore: boolean ...
method searchFonts (line 119) | async searchFonts(query: string): Promise<Font[]> {
method loadFontFromBatch (line 153) | async loadFontFromBatch(fonts: Font[]): Promise<void> {
method resetFontFetching (line 157) | resetFontFetching(): void {
method updateFontsList (line 162) | updateFontsList(fonts: Font[]): void {
method clear (line 166) | clear(): void {
method systemFonts (line 174) | get systemFonts(): Font[] {
method searchResults (line 180) | get searchResults(): Font[] {
method isFetching (line 186) | get isFetching(): boolean {
method currentFontIndex (line 190) | get currentFontIndex(): number {
method hasMoreFonts (line 194) | get hasMoreFonts(): boolean {
FILE: apps/web/client/src/components/store/editor/font/index.ts
class FontManager (line 18) | class FontManager {
method constructor (line 29) | constructor(private editorEngine: EditorEngine) {
method init (line 36) | init() {
method loadInitialFonts (line 42) | private async loadInitialFonts(): Promise<void> {
method scanFonts (line 46) | async scanFonts(): Promise<Font[]> {
method scanExistingFonts (line 79) | private async scanExistingFonts(): Promise<Font[] | undefined> {
method addFont (line 97) | async addFont(font: Font): Promise<boolean> {
method addFonts (line 124) | async addFonts(fonts: Font[]): Promise<void> {
method removeFont (line 130) | async removeFont(font: Font): Promise<CodeDiff | false> {
method setDefaultFont (line 165) | async setDefaultFont(font: Font): Promise<boolean> {
method clearDefaultFont (line 185) | async clearDefaultFont(): Promise<boolean> {
method uploadFonts (line 212) | async uploadFonts(fontFiles: FontUploadFile[]): Promise<boolean> {
method fetchNextFontBatch (line 261) | async fetchNextFontBatch(): Promise<{ fonts: Font[]; hasMore: boolean ...
method searchFonts (line 265) | async searchFonts(query: string): Promise<Font[]> {
method resetFontFetching (line 269) | resetFontFetching(): void {
method fonts (line 274) | get fonts(): Font[] {
method fontFamilies (line 278) | get fontFamilies(): Font[] {
method systemFonts (line 282) | get systemFonts(): Font[] {
method defaultFont (line 286) | get defaultFont(): string | null {
method searchResults (line 290) | get searchResults(): Font[] {
method isFetching (line 294) | get isFetching(): boolean {
method isUploading (line 298) | get isUploading(): boolean {
method isScanning (line 302) | get isScanning(): boolean {
method currentFontIndex (line 306) | get currentFontIndex(): number {
method hasMoreFonts (line 310) | get hasMoreFonts(): boolean {
method getCurrentDefaultFont (line 317) | private async getCurrentDefaultFont(): Promise<string | null> {
method syncFontsWithConfigs (line 333) | private async syncFontsWithConfigs(): Promise<void> {
method ensureConfigFilesExist (line 376) | private async ensureConfigFilesExist(): Promise<void> {
method clear (line 394) | clear() {
FILE: apps/web/client/src/components/store/editor/frame-events/index.ts
class FrameEventManager (line 8) | class FrameEventManager {
method constructor (line 12) | constructor(private editorEngine: EditorEngine) {
method init (line 16) | init() {
method undebouncedHandleWindowMutated (line 30) | private async undebouncedHandleWindowMutated() {
method isFrameInViewport (line 45) | private isFrameInViewport(frame: Frame): boolean {
method handleWindowResized (line 106) | async handleWindowResized(): Promise<void> {
method handleDomProcessed (line 114) | async handleDomProcessed(frameId: string, data: { layerMap: Record<str...
method validateAndCleanSelections (line 131) | private async validateAndCleanSelections(): Promise<void> {
method clear (line 155) | clear() {
FILE: apps/web/client/src/components/store/editor/frame-events/types.ts
type WindowMutatedData (line 3) | interface WindowMutatedData {
type DomProcessedData (line 8) | interface DomProcessedData {
type WindowResizedData (line 13) | interface WindowResizedData {}
type AutonomousEventData (line 15) | type AutonomousEventData =
FILE: apps/web/client/src/components/store/editor/frames/dimension.ts
function roundDimensions (line 3) | function roundDimensions(frame: Frame): Frame {
FILE: apps/web/client/src/components/store/editor/frames/manager.ts
type FrameData (line 13) | interface FrameData {
class FramesManager (line 19) | class FramesManager {
method constructor (line 24) | constructor(private editorEngine: EditorEngine) {
method updateFrameSelection (line 28) | private updateFrameSelection(id: string, selected: boolean): void {
method applyFrames (line 36) | applyFrames(frames: Frame[]) {
method selected (line 47) | get selected(): FrameData[] {
method navigation (line 51) | get navigation(): FrameNavigationManager {
method getAll (line 55) | getAll(): FrameData[] {
method getByBranchId (line 59) | getByBranchId(branchId: string): FrameData[] {
method get (line 63) | get(id: string): FrameData | null {
method registerView (line 67) | registerView(frame: Frame, view: IFrameView) {
method deregister (line 74) | deregister(frame: Frame) {
method deregisterAll (line 78) | deregisterAll() {
method isSelected (line 82) | isSelected(id: string) {
method select (line 86) | select(frames: Frame[], multiselect = false) {
method deselect (line 100) | deselect(frame: Frame) {
method deselectAll (line 105) | deselectAll() {
method notify (line 112) | private notify() {
method clear (line 116) | clear() {
method disposeFrame (line 123) | disposeFrame(frameId: string) {
method reloadAllViews (line 129) | reloadAllViews() {
method reloadView (line 135) | reloadView(id: string) {
method goBack (line 145) | async goBack(frameId: string): Promise<void> {
method goForward (line 152) | async goForward(frameId: string): Promise<void> {
method navigateToPath (line 159) | async navigateToPath(frameId: string, path: string, addToHistory = tru...
method delete (line 192) | async delete(id: string) {
method create (line 210) | async create(frame: Frame) {
method duplicate (line 222) | async duplicate(id: string) {
method updateAndSaveToStorage (line 250) | async updateAndSaveToStorage(frameId: string, frame: Partial<Frame>) {
method undebouncedSaveToStorage (line 265) | async undebouncedSaveToStorage(frameId: string, frame: Partial<Frame>) {
method canDelete (line 281) | canDelete() {
method canDuplicate (line 300) | canDuplicate() {
method calculateNonOverlappingPosition (line 304) | calculateNonOverlappingPosition(proposedFrame: Frame): { x: number; y:...
method duplicateSelected (line 309) | async duplicateSelected() {
method deleteSelected (line 315) | async deleteSelected() {
FILE: apps/web/client/src/components/store/editor/frames/navigation.ts
type NavigationObject (line 3) | interface NavigationObject {
class FrameNavigationManager (line 8) | class FrameNavigationManager {
method constructor (line 12) | constructor() {
method registerFrame (line 16) | registerFrame(frameId: string, framePathname: string): void {
method canGoBack (line 22) | canGoBack(frameId: string): boolean {
method canGoForward (line 30) | canGoForward(frameId: string): boolean {
method getHistoryLength (line 38) | getHistoryLength(frameId: string): number {
method getCurrentHistoryIndex (line 43) | getCurrentHistoryIndex(frameId: string): number {
method getNavigationHistory (line 48) | getNavigationHistory(frameId: string): string[] {
method addToHistory (line 53) | addToHistory(frameId: string, path: string): void {
method goBack (line 81) | goBack(frameId: string): string | null {
method goForward (line 101) | goForward(frameId: string): string | null {
method clearHistory (line 121) | clearHistory(frameId: string): void {
method clearAllHistory (line 125) | clearAllHistory(): void {
method removeFrame (line 129) | removeFrame(frameId: string): void {
FILE: apps/web/client/src/components/store/editor/git/git.ts
constant ONLOOK_DISPLAY_NAME_NOTE_REF (line 10) | const ONLOOK_DISPLAY_NAME_NOTE_REF = 'refs/notes/onlook-display-name';
type GitStatus (line 12) | interface GitStatus {
type GitCommandResult (line 16) | interface GitCommandResult {
class GitManager (line 22) | class GitManager {
method constructor (line 26) | constructor(private sandbox: SandboxManager) {
method init (line 33) | async init(): Promise<void> {
method isRepoInitialized (line 44) | async isRepoInitialized(): Promise<boolean> {
method ensureGitConfig (line 56) | async ensureGitConfig(): Promise<boolean> {
method initRepo (line 103) | async initRepo(): Promise<boolean> {
method getStatus (line 142) | async getStatus(): Promise<GitStatus | null> {
method stageAll (line 162) | async stageAll(): Promise<GitCommandResult> {
method commit (line 169) | async commit(message: string): Promise<GitCommandResult> {
method createCommit (line 184) | async createCommit(message = 'New Onlook backup'): Promise<GitCommandR...
method listCommits (line 203) | async listCommits(maxRetries = 2): Promise<GitCommit[]> {
method restoreToCommit (line 281) | async restoreToCommit(commitOid: string): Promise<GitCommandResult> {
method addCommitNote (line 296) | async addCommitNote(commitOid: string, displayName: string): Promise<G...
method getCommitNote (line 317) | async getCommitNote(commitOid: string): Promise<string | null> {
method runCommand (line 337) | private runCommand(command: string, ignoreError = false): Promise<GitC...
method parseGitLog (line 344) | private parseGitLog(rawOutput: string): GitCommit[] {
method formatGitLogOutput (line 413) | private formatGitLogOutput(input: string): string {
FILE: apps/web/client/src/components/store/editor/git/utils.ts
constant BACKUP_COMMIT_MESSAGE (line 6) | const BACKUP_COMMIT_MESSAGE = 'Save before restoring backup';
type RestoreResult (line 8) | interface RestoreResult {
function restoreCheckpoint (line 20) | async function restoreCheckpoint(
FILE: apps/web/client/src/components/store/editor/group/index.ts
class GroupManager (line 11) | class GroupManager {
method constructor (line 12) | constructor(private editorEngine: EditorEngine) { }
method groupSelectedElements (line 14) | async groupSelectedElements() {
method ungroupSelectedElement (line 32) | async ungroupSelectedElement() {
method getGroupParentId (line 53) | getGroupParentId(
method canGroupElements (line 101) | canGroupElements() {
method canUngroupElement (line 105) | canUngroupElement() {
method getGroupAction (line 109) | async getGroupAction(
method getUngroupAction (line 156) | async getUngroupAction(selectedEl: DomElement): Promise<UngroupElement...
method clear (line 213) | clear() { }
FILE: apps/web/client/src/components/store/editor/history/helpers.ts
function reverse (line 16) | function reverse<T>(change: Change<T>): Change<T> {
function reverseMoveLocation (line 20) | function reverseMoveLocation(location: IndexActionLocation): IndexAction...
function reverseStyleAction (line 28) | function reverseStyleAction(action: UpdateStyleAction): UpdateStyleAction {
function reverseWriteCodeAction (line 38) | function reverseWriteCodeAction(action: WriteCodeAction): WriteCodeAction {
function undoAction (line 49) | function undoAction(action: Action): Action {
function handleUpdateStyleAction (line 155) | function handleUpdateStyleAction(
function updateTransactionActions (line 181) | function updateTransactionActions(actions: Action[], newAction: Action):...
function getCleanedElement (line 194) | function getCleanedElement(
function transformRedoAction (line 227) | function transformRedoAction(action: Action): Action {
FILE: apps/web/client/src/components/store/editor/history/index.ts
type TransactionType (line 7) | enum TransactionType {
type InTransaction (line 12) | interface InTransaction {
type NotInTransaction (line 17) | interface NotInTransaction {
type TransactionState (line 21) | type TransactionState = InTransaction | NotInTransaction;
class HistoryManager (line 23) | class HistoryManager {
method constructor (line 24) | constructor(
method canUndo (line 33) | get canUndo() {
method canRedo (line 37) | get canRedo() {
method isInTransaction (line 41) | get isInTransaction() {
method length (line 45) | get length() {
FILE: apps/web/client/src/components/store/editor/ide/index.ts
class IdeManager (line 5) | class IdeManager {
method constructor (line 8) | constructor(private readonly editorEngine: EditorEngine) {
method codeNavigationOverride (line 12) | get codeNavigationOverride() {
method openCodeBlock (line 16) | async openCodeBlock(oid: string) {
method clearCodeNavigationOverride (line 63) | clearCodeNavigationOverride() {
method hasCodeNavigationOverride (line 67) | hasCodeNavigationOverride(): boolean {
FILE: apps/web/client/src/components/store/editor/image/index.ts
class ImageManager (line 7) | class ImageManager {
method constructor (line 13) | constructor(private editorEngine: EditorEngine) {
method init (line 17) | init() { }
method imagePaths (line 19) | get imagePaths() {
method isSelectingImage (line 23) | get isSelectingImage() {
method selectedImage (line 27) | get selectedImage() {
method previewImage (line 31) | get previewImage() {
method setPreviewImage (line 35) | setPreviewImage(image: ImageContentData | null) {
method setSelectedImage (line 65) | setSelectedImage(image: ImageContentData | null) {
method setIsSelectingImage (line 102) | setIsSelectingImage(isSelectingImage: boolean) {
method upload (line 106) | async upload(file: File, destinationFolder: string): Promise<void> {
method search (line 119) | search(name: string) {
method getTargets (line 124) | getTargets() {
method readImageContent (line 145) | async readImageContent(imagePath: string): Promise<ImageContentData | ...
method readImagesContent (line 187) | async readImagesContent(imagePaths: string[]): Promise<ImageContentDat...
method clear (line 206) | clear() {
FILE: apps/web/client/src/components/store/editor/insert/index.ts
class InsertManager (line 27) | class InsertManager {
method constructor (line 31) | constructor(private editorEngine: EditorEngine) { }
method getDefaultProperties (line 33) | getDefaultProperties(mode: InsertMode): DropElementProperties {
method start (line 60) | start(e: React.MouseEvent<HTMLDivElement>) {
method draw (line 69) | draw(e: React.MouseEvent<HTMLDivElement>) {
method end (line 80) | async end(e: React.MouseEvent<HTMLDivElement>, frameView: IFrameView |...
method updateInsertRect (line 101) | private updateInsertRect(pos: ElementPosition) {
method getDrawRect (line 116) | private getDrawRect(currentPos: ElementPosition): RectDimensions {
method insertElement (line 149) | async insertElement(frameView: IFrameView, newRect: RectDimensions, or...
method createInsertAction (line 158) | async createInsertAction(
method insertDroppedImage (line 228) | async insertDroppedImage(
method updateImageSource (line 272) | private async updateImageSource(
method insertImageElement (line 347) | insertImageElement(frame: FrameData, location: ActionLocation, imageDa...
method updateElementBackgroundAction (line 387) | updateElementBackgroundAction(
method insertDroppedElement (line 451) | async insertDroppedElement(
method clear (line 505) | clear() {
FILE: apps/web/client/src/components/store/editor/move/index.ts
type DragState (line 8) | enum DragState {
type MoveManagerState (line 13) | interface MoveManagerState {
class MoveManager (line 20) | class MoveManager {
method constructor (line 25) | constructor(private editorEngine: EditorEngine) {
method shouldDrag (line 29) | get shouldDrag() {
method isPreparing (line 33) | get isPreparing() {
method isDragInProgress (line 37) | get isDragInProgress() {
method setDragState (line 41) | setDragState(dragState: DragState) {
method startDragPreparation (line 49) | startDragPreparation(el: DomElement, pos: ElementPosition, frameData: ...
method cancelDragPreparation (line 71) | cancelDragPreparation() {
method prepareDrag (line 81) | async prepareDrag(el: DomElement, frameData: FrameData) {
method drag (line 117) | async drag(
method end (line 162) | async end(_e: React.MouseEvent<HTMLDivElement>) {
method endAllDrag (line 224) | async endAllDrag() {
method moveSelected (line 243) | async moveSelected(direction: 'up' | 'down') {
method shiftElement (line 256) | async shiftElement(element: DomElement, direction: 'up' | 'down'): Pro...
method createMoveAction (line 303) | createMoveAction(
method clear (line 330) | clear() {
FILE: apps/web/client/src/components/store/editor/overlay/index.ts
class OverlayManager (line 8) | class OverlayManager {
method constructor (line 12) | constructor(private editorEngine: EditorEngine) {
method init (line 16) | init() {
method showMeasurement (line 84) | showMeasurement() {
FILE: apps/web/client/src/components/store/editor/overlay/prosemirror/index.ts
function applyStylesToEditor (line 42) | function applyStylesToEditor(editorView: EditorView, styles: Record<stri...
FILE: apps/web/client/src/components/store/editor/overlay/state.ts
type MeasurementState (line 5) | interface MeasurementState {
type ClickRectState (line 10) | interface ClickRectState extends RectDimensions {
type TextEditorState (line 16) | interface TextEditorState {
type HoverRectState (line 25) | interface HoverRectState {
type DragElementState (line 30) | interface DragElementState {
class OverlayState (line 36) | class OverlayState {
method constructor (line 43) | constructor() {
FILE: apps/web/client/src/components/store/editor/overlay/utils.ts
function getRelativeOffset (line 9) | function getRelativeOffset(element: HTMLElement, ancestor: HTMLElement) {
function adaptRectToCanvas (line 43) | function adaptRectToCanvas(
function adaptValueToCanvas (line 72) | function adaptValueToCanvas(value: number, inverse = false): number {
function getRelativeMousePositionToFrameView (line 86) | function getRelativeMousePositionToFrameView(
FILE: apps/web/client/src/components/store/editor/pages/helper.ts
constant DEFAULT_LAYOUT_CONTENT (line 10) | const DEFAULT_LAYOUT_CONTENT = `export default function Layout({
constant IGNORED_DIRECTORIES (line 78) | const IGNORED_DIRECTORIES = ['api', 'components', 'lib', 'utils', 'node_...
constant APP_ROUTER_PATHS (line 79) | const APP_ROUTER_PATHS = ['src/app', 'app'];
constant PAGES_ROUTER_PATHS (line 80) | const PAGES_ROUTER_PATHS = ['src/pages', 'pages'];
constant ALLOWED_EXTENSIONS (line 81) | const ALLOWED_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js'];
constant ROOT_PAGE_NAME (line 82) | const ROOT_PAGE_NAME = 'Home';
constant ROOT_PATH_IDENTIFIERS (line 83) | const ROOT_PATH_IDENTIFIERS = ['', '/', '.'];
constant ROOT_PAGE_COPY_NAME (line 84) | const ROOT_PAGE_COPY_NAME = 'landing-page-copy';
constant DEFAULT_PAGE_CONTENT (line 86) | const DEFAULT_PAGE_CONTENT = `export default function Page() {
method ExportNamedDeclaration (line 166) | ExportNamedDeclaration(path) {
function updateMetadataInFile (line 791) | async function updateMetadataInFile(
FILE: apps/web/client/src/components/store/editor/pages/index.ts
class PagesManager (line 17) | class PagesManager {
method constructor (line 24) | constructor(private editorEngine: EditorEngine) {
method init (line 28) | init() { }
method scanPages (line 30) | async scanPages() {
method isScanning (line 48) | get isScanning() {
method tree (line 52) | get tree() {
method activeRoute (line 56) | get activeRoute(): string | undefined {
method getActiveFrame (line 61) | private getActiveFrame(): FrameData | undefined {
method isNodeActive (line 68) | public isNodeActive(node: PageNode): boolean {
method setActivePath (line 110) | public setActivePath(frameId: string, path: string) {
method updateActiveStates (line 118) | private updateActiveStates(nodes: PageNode[], activePath: string) {
method setPages (line 128) | private setPages(pages: PageNode[]) {
method createPage (line 138) | public async createPage(baseRoute: string, pageName: string): Promise<...
method renamePage (line 161) | public async renamePage(oldPath: string, newName: string): Promise<voi...
method duplicatePage (line 182) | public async duplicatePage(sourcePath: string, targetPath: string): Pr...
method deletePage (line 198) | public async deletePage(pageName: string, isDir: boolean): Promise<voi...
method updateMetadataPage (line 215) | public async updateMetadataPage(pagePath: string, metadata: PageMetada...
method navigateTo (line 230) | async navigateTo(path: string, addToHistory = true) {
method setCurrentPath (line 259) | public setCurrentPath(path: string) {
method handleFrameUrlChange (line 263) | public handleFrameUrlChange(frameId: string) {
method clear (line 289) | clear() {
FILE: apps/web/client/src/components/store/editor/sandbox/helpers.ts
constant SANDBOX_ROOT (line 3) | const SANDBOX_ROOT = '/project/sandbox';
function normalizePath (line 5) | function normalizePath(p: string): string {
FILE: apps/web/client/src/components/store/editor/sandbox/index.ts
type PreloadScriptState (line 15) | enum PreloadScriptState {
class SandboxManager (line 20) | class SandboxManager {
method constructor (line 28) | constructor(
method init (line 39) | async init() {
method getRouterConfig (line 65) | async getRouterConfig(): Promise<RouterConfig | null> {
method initializeSyncEngine (line 76) | async initializeSyncEngine(provider: Provider) {
method ensurePreloadScriptExists (line 91) | private async ensurePreloadScriptExists(): Promise<void> {
method getLayoutPath (line 119) | async getLayoutPath(): Promise<string | null> {
method errors (line 127) | get errors() {
method syncEngine (line 131) | get syncEngine() {
method readFile (line 135) | async readFile(path: string): Promise<string | Uint8Array> {
method writeFile (line 140) | async writeFile(path: string, content: string | Uint8Array): Promise<v...
method listAllFiles (line 145) | listAllFiles() {
method readDir (line 150) | async readDir(dir: string): Promise<FileEntry[]> {
method listFilesRecursively (line 155) | async listFilesRecursively(dir: string): Promise<string[]> {
method fileExists (line 160) | async fileExists(path: string): Promise<boolean> {
method copyFile (line 165) | async copyFile(path: string, targetPath: string): Promise<void> {
method copyDirectory (line 170) | async copyDirectory(path: string, targetPath: string): Promise<void> {
method deleteFile (line 175) | async deleteFile(path: string): Promise<void> {
method deleteDirectory (line 180) | async deleteDirectory(path: string): Promise<void> {
method rename (line 185) | async rename(oldPath: string, newPath: string): Promise<void> {
method downloadFiles (line 191) | async downloadFiles(
method clear (line 216) | clear() {
FILE: apps/web/client/src/components/store/editor/sandbox/preload-script.ts
function copyPreloadScriptToPublic (line 8) | async function copyPreloadScriptToPublic(provider: Provider, routerConfi...
function injectPreloadScriptIntoLayout (line 31) | async function injectPreloadScriptIntoLayout(provider: Provider, routerC...
function getLayoutPath (line 70) | async function getLayoutPath(routerConfig: RouterConfig, fileExists: (pa...
FILE: apps/web/client/src/components/store/editor/sandbox/session.ts
class SessionManager (line 8) | class SessionManager {
method constructor (line 14) | constructor(
method start (line 21) | async start(sandboxId: string, userId?: string): Promise<void> {
method restartDevServer (line 73) | async restartDevServer(): Promise<boolean> {
method readDevServerLogs (line 90) | async readDevServerLogs(): Promise<string> {
method getTerminalSession (line 98) | getTerminalSession(id: string) {
method createTerminalSessions (line 102) | async createTerminalSessions(provider: Provider) {
method disposeTerminal (line 131) | async disposeTerminal(id: string) {
method hibernate (line 144) | async hibernate(sandboxId: string) {
method reconnect (line 148) | async reconnect(sandboxId: string, userId?: string) {
method restartProvider (line 175) | async restartProvider(sandboxId: string, userId?: string) {
method ping (line 184) | async ping() {
method runCommand (line 195) | async runCommand(
method clear (line 230) | async clear() {
FILE: apps/web/client/src/components/store/editor/sandbox/terminal.ts
type CLISessionType (line 12) | enum CLISessionType {
type CLISession (line 17) | interface CLISession {
type TaskSession (line 28) | interface TaskSession extends CLISession {
type TerminalSession (line 33) | interface TerminalSession extends CLISession {
class CLISessionImpl (line 38) | class CLISessionImpl implements CLISession {
method constructor (line 45) | constructor(
method ensureXTermLibraries (line 59) | private async ensureXTermLibraries() {
method initTerminal (line 75) | async initTerminal() {
method initTask (line 119) | async initTask() {
method createXTerm (line 146) | createXTerm(): Terminal {
method createDevTaskTerminal (line 194) | async createDevTaskTerminal() {
method dispose (line 207) | dispose() {
FILE: apps/web/client/src/components/store/editor/screenshot/index.tsx
class ScreenshotManager (line 7) | class ScreenshotManager {
method constructor (line 11) | constructor(private editorEngine: EditorEngine) {
method lastScreenshotAt
Condensed preview — 1600 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,736K chars).
[
{
"path": ".dockerignore",
"chars": 288,
"preview": "node_modules\n.git\n.gitignore\nREADME.md\n.env\n.env.local\n.env.*.local\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.next"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 159,
"preview": "---\n\nname: 🐞 Bug report\nabout: Create a report to help us improve\ntitle: \"[bug] the title of bug report\"\nlabels: bug\nass"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 168,
"preview": "---\n\nname: ✨ Feature request\nabout: Create a feature request\ntitle: \"[feat] the title of the request\"\nlabels: enhancemen"
},
{
"path": ".github/ISSUE_TEMPLATE/help_wanted.md",
"chars": 189,
"preview": "---\nname: 🥺 Help wanted\nabout: Confuse about the use of Onlook\ntitle: \"[Help] the title of help wanted report\"\nlabels: h"
},
{
"path": ".github/dependabot.yml",
"chars": 503,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/pull_request_template.md",
"chars": 617,
"preview": "## Description\n\n<!-- Provide a clear and concise description of your changes -->\n\n## Related Issues\n\n<!-- Link any relat"
},
{
"path": ".github/workflows/chromatic.yml",
"chars": 656,
"preview": "name: Chromatic\n\non: push\n\njobs:\n chromatic:\n name: Run Chromatic\n runs-on: ubuntu-latest\n env:\n SKIP_ENV"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1805,
"preview": "name: CI\n\non:\n pull_request:\n push:\n branches: [main]\n\njobs:\n # TODO: Enable lint job after applying lint fixes an"
},
{
"path": ".github/workflows/supabase-push-staging.yml",
"chars": 542,
"preview": "name: Push Supabase Drizzle Schema to Staging Environment\n\non:\n workflow_dispatch:\n\njobs:\n migrate:\n runs-o"
},
{
"path": ".gitignore",
"chars": 563,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndis"
},
{
"path": ".gitmodules",
"chars": 91,
"preview": "[submodule \"apps/admin\"]\n\tpath = apps/admin\n\turl = https://github.com/onlook-dev/admin.git\n"
},
{
"path": ".prettierignore",
"chars": 55,
"preview": "dist-electron\ndist\nnode_modules\nrelease\ndemos\ntest/data"
},
{
"path": ".vscode/.debug.script.mjs",
"chars": 706,
"preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { createRequire } "
},
{
"path": ".vscode/extensions.json",
"chars": 196,
"preview": "{\n // See http://go.microsoft.com/fwlink/?LinkId=827846\n // for the documentation about the extensions.json format"
},
{
"path": ".vscode/launch.json",
"chars": 1430,
"preview": "{\n // Use IntelliSense to learn about possible attributes.\n // Hover to view descriptions of existing attributes.\n //"
},
{
"path": ".vscode/tasks.json",
"chars": 1025,
"preview": "{\n // See https://go.microsoft.com/fwlink/?LinkId=733558 \n // for the documentation about the tasks.json format\n "
},
{
"path": "AGENTS.md",
"chars": 6111,
"preview": "## Onlook Agents Guide\n\nActionable rules for repo agents—keep diffs minimal, safe, token‑efficient.\n\n### Purpose & Scope"
},
{
"path": "CLAUDE.md",
"chars": 6111,
"preview": "## Onlook Agents Guide\n\nActionable rules for repo agents—keep diffs minimal, safe, token‑efficient.\n\n### Purpose & Scope"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3593,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "CONTRIBUTING.md",
"chars": 244,
"preview": "# Contributing\n\nTo keep all docs in one place, we've moved the contributing guide here:\nhttps://docs.onlook.com/develope"
},
{
"path": "Dockerfile",
"chars": 744,
"preview": "# Build Onlook web client\nFROM oven/bun:1\n\nWORKDIR /app\n\n# Set build and production environment\nENV NODE_ENV=production\n"
},
{
"path": "LICENSE.md",
"chars": 11342,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 10539,
"preview": "<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 -->\n\n<"
},
{
"path": "SECURITY.md",
"chars": 113,
"preview": "# Security Policy\n\nPlease contact us at [contact@onlook.com](mailto:contact@onlook.com) with any security issues."
},
{
"path": "apps/backend/.gitignore",
"chars": 412,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndis"
},
{
"path": "apps/backend/README.md",
"chars": 608,
"preview": "## Why a backend stack?\n\nThis is our server stack built in Supabase which you can also run locally or\nself-host.\n\nUsed t"
},
{
"path": "apps/backend/package.json",
"chars": 664,
"preview": "{\n \"name\": \"@onlook/backend\",\n \"private\": true,\n \"scripts\": {\n \"start\": \"supabase start\",\n \"stop\""
},
{
"path": "apps/backend/supabase/.gitignore",
"chars": 32,
"preview": "# Supabase\n.branches\n.temp\n.env\n"
},
{
"path": "apps/backend/supabase/config.toml",
"chars": 870,
"preview": "project_id = \"onlook-web\"\n\n[api]\nenabled = true\nport = 54321\nschemas = [\"public\", \"storage\"]\nextra_search_path = [\"publi"
},
{
"path": "apps/backend/supabase/migrations/0000_same_human_robot.sql",
"chars": 4977,
"preview": "DO $$ \nBEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'frame_type') THEN\n CREATE TYPE \"public\".\"f"
},
{
"path": "apps/backend/supabase/migrations/0001_graceful_exodus.sql",
"chars": 128,
"preview": "ALTER TABLE \"conversations\" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint\nALTER TABLE \"messages\" ENABLE ROW LEVEL S"
},
{
"path": "apps/backend/supabase/migrations/0002_red_crusher_hogan.sql",
"chars": 764,
"preview": "CREATE TABLE IF NOT EXISTS \"user_settings\" (\n\t\"id\" uuid PRIMARY KEY NOT NULL,\n\t\"user_id\" uuid NOT NULL,\n\t\"auto_apply_cod"
},
{
"path": "apps/backend/supabase/migrations/0003_loud_ozymandias.sql",
"chars": 1751,
"preview": "CREATE TABLE IF NOT EXISTS \"user_canvases\" (\n\t\"user_id\" uuid NOT NULL,\n\t\"canvas_id\" uuid NOT NULL,\n\t\"scale\" numeric NOT "
},
{
"path": "apps/backend/supabase/migrations/0004_pink_expediter.sql",
"chars": 2100,
"preview": "-- Create ENUMs only if they don't exist\nDO $$ BEGIN\n CREATE TYPE \"public\".\"invitation_status\" AS ENUM('pending', 'ac"
},
{
"path": "apps/backend/supabase/migrations/0005_short_lila_cheney.sql",
"chars": 419,
"preview": "ALTER TABLE \"project_invitations\" DROP COLUMN IF EXISTS \"status\";--> statement-breakpoint\nALTER TABLE \"project_invitatio"
},
{
"path": "apps/backend/supabase/migrations/0006_rls.sql",
"chars": 10953,
"preview": "-- Helper function to check if user has specific roles for a project\nCREATE OR REPLACE FUNCTION user_has_project_access("
},
{
"path": "apps/backend/supabase/migrations/0007_realtime_rls.sql",
"chars": 2114,
"preview": "CREATE OR REPLACE FUNCTION public.project_changes()\nRETURNS TRIGGER\nSECURITY DEFINER\nLANGUAGE plpgsql\nAS $$\nDECLARE\n to"
},
{
"path": "apps/backend/supabase/migrations/0008_preview-img-storage.sql",
"chars": 747,
"preview": "delete from storage.objects where bucket_id = 'preview_images';\ndelete from storage.buckets where id = 'preview_images';"
},
{
"path": "apps/backend/supabase/migrations/0009_project_img_path.sql",
"chars": 527,
"preview": "ALTER TABLE \"projects\" DROP COLUMN IF EXISTS \"preview_img_url\";--> statement-breakpoint\nALTER TABLE \"projects\" DROP COLU"
},
{
"path": "apps/backend/supabase/migrations/0010_bent_edwin_jarvis.sql",
"chars": 3019,
"preview": "-- Create new type\nCREATE TYPE \"public\".\"verification_request_status\" AS ENUM('active', 'expired', 'used');--> statement"
},
{
"path": "apps/backend/supabase/migrations/0011_typical_clea.sql",
"chars": 5441,
"preview": ";--> statement-breakpoint\nCREATE TYPE \"public\".\"price_keys\" AS ENUM('PRO_MONTHLY_TIER_1', 'PRO_MONTHLY_TIER_2', 'PRO_MON"
},
{
"path": "apps/backend/supabase/migrations/0012_file-transfer-bucket.sql",
"chars": 1144,
"preview": "delete from storage.objects where bucket_id = 'file_transfer';\ndelete from storage.buckets where id = 'file_transfer';\n\n"
},
{
"path": "apps/backend/supabase/migrations/0013_aspiring_kabuki.sql",
"chars": 2655,
"preview": "CREATE TYPE \"public\".\"project_create_status\" AS ENUM('pending', 'completed', 'failed');--> statement-breakpoint\nCREATE T"
},
{
"path": "apps/backend/supabase/migrations/0014_military_marrow.sql",
"chars": 2700,
"preview": "CREATE TYPE \"public\".\"project_custom_domain_status\" AS ENUM('active', 'cancelled');--> statement-breakpoint\nCREATE TABLE"
},
{
"path": "apps/backend/supabase/migrations/0015_same_leo.sql",
"chars": 818,
"preview": "--> statement-breakpoint\nALTER TYPE \"public\".\"deployment_status\" ADD VALUE 'pending' BEFORE 'in_progress';--> statement-"
},
{
"path": "apps/backend/supabase/migrations/0016_pretty_dust.sql",
"chars": 2170,
"preview": "CREATE TABLE \"rate_limits\" (\n\t\"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,\n\t\"user_id\" uuid NOT NULL,\n\t\"subs"
},
{
"path": "apps/backend/supabase/migrations/0017_small_xavin.sql",
"chars": 2139,
"preview": "--> statement-breakpoint\nCREATE TABLE \"feedbacks\" (\n\t\"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,\n\t\"user_id"
},
{
"path": "apps/backend/supabase/migrations/0018_lush_thanos.sql",
"chars": 1985,
"preview": "CREATE TABLE \"branches\" (\n\t\"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,\n\t\"project_id\" uuid NOT NULL,\n\t\"name"
},
{
"path": "apps/backend/supabase/migrations/0019_abandoned_psylocke.sql",
"chars": 140,
"preview": "ALTER TYPE \"public\".\"message_role\" ADD VALUE 'system';--> statement-breakpoint\nALTER TABLE \"users\" ADD COLUMN \"github_in"
},
{
"path": "apps/backend/supabase/migrations/meta/0000_snapshot.json",
"chars": 11819,
"preview": "{\n \"id\": \"95612ed1-7374-41c8-8f07-1ee3b064226b\",\n \"prevId\": \"00000000-0000-0000-0000-000000000000\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0001_snapshot.json",
"chars": 11817,
"preview": "{\n \"id\": \"7fab2c6f-cf80-420e-bad4-3d6065d58b9c\",\n \"prevId\": \"95612ed1-7374-41c8-8f07-1ee3b064226b\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0002_snapshot.json",
"chars": 13739,
"preview": "{\n \"id\": \"cf650e40-2b28-43b0-bfcd-fdd3603f7f88\",\n \"prevId\": \"7fab2c6f-cf80-420e-bad4-3d6065d58b9c\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0003_snapshot.json",
"chars": 15284,
"preview": "{\n \"id\": \"518e58bf-052b-4c2c-8095-3fa357233432\",\n \"prevId\": \"cf650e40-2b28-43b0-bfcd-fdd3603f7f88\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0004_snapshot.json",
"chars": 18773,
"preview": "{\n \"id\": \"6187c007-6c6d-4e4f-af6e-a232e3cd5cf6\",\n \"prevId\": \"518e58bf-052b-4c2c-8095-3fa357233432\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0005_snapshot.json",
"chars": 19579,
"preview": "{\n \"id\": \"3d0069f3-846f-40fb-903d-6e3375df0e77\",\n \"prevId\": \"6187c007-6c6d-4e4f-af6e-a232e3cd5cf6\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0006_snapshot.json",
"chars": 19579,
"preview": "{\n \"id\": \"28cb89f1-cebc-487a-84e2-0341168df378\",\n \"prevId\": \"3d0069f3-846f-40fb-903d-6e3375df0e77\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0007_snapshot.json",
"chars": 19579,
"preview": "{\n \"id\": \"138016e8-55b3-439e-9bc9-f5f2d1b38bb6\",\n \"prevId\": \"28cb89f1-cebc-487a-84e2-0341168df378\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0008_snapshot.json",
"chars": 19579,
"preview": "{\n \"id\": \"190b8f91-9fa5-44da-a7db-e38b9154da04\",\n \"prevId\": \"138016e8-55b3-439e-9bc9-f5f2d1b38bb6\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0009_snapshot.json",
"chars": 19579,
"preview": "{\n \"id\": \"b234e1b4-c30a-471f-b431-233cb4947039\",\n \"prevId\": \"190b8f91-9fa5-44da-a7db-e38b9154da04\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0010_snapshot.json",
"chars": 28489,
"preview": "{\n \"id\": \"866fb593-8f7d-431f-b791-226ede7ab0c4\",\n \"prevId\": \"b234e1b4-c30a-471f-b431-233cb4947039\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0011_snapshot.json",
"chars": 40578,
"preview": "{\n \"id\": \"6913ab93-9cf1-4ab2-96f9-7e1d5c124999\",\n \"prevId\": \"866fb593-8f7d-431f-b791-226ede7ab0c4\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0012_snapshot.json",
"chars": 40578,
"preview": "{\n \"id\": \"7fe865fd-ad69-4633-8197-fce5dda31a09\",\n \"prevId\": \"6913ab93-9cf1-4ab2-96f9-7e1d5c124999\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0013_snapshot.json",
"chars": 47447,
"preview": "{\n \"id\": \"ee92d761-f1e2-4588-a659-34e2f8c57e5a\",\n \"prevId\": \"7fe865fd-ad69-4633-8197-fce5dda31a09\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0014_snapshot.json",
"chars": 47929,
"preview": "{\n \"id\": \"00708cb9-76b7-47b9-ba22-6bf72b1b872d\",\n \"prevId\": \"ee92d761-f1e2-4588-a659-34e2f8c57e5a\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0015_snapshot.json",
"chars": 49972,
"preview": "{\n \"id\": \"65e43a14-1d2e-491f-adf1-c073e34f71c8\",\n \"prevId\": \"00708cb9-76b7-47b9-ba22-6bf72b1b872d\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0016_snapshot.json",
"chars": 55095,
"preview": "{\n \"id\": \"9c200d7a-5f78-47db-a99d-02e6e0a9c11f\",\n \"prevId\": \"65e43a14-1d2e-491f-adf1-c073e34f71c8\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0017_snapshot.json",
"chars": 57959,
"preview": "{\n \"id\": \"c208e744-6364-4488-bf96-d462f35ea5d1\",\n \"prevId\": \"9c200d7a-5f78-47db-a99d-02e6e0a9c11f\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0018_snapshot.json",
"chars": 62675,
"preview": "{\n \"id\": \"c726b804-42fb-40b6-a5d3-6b66e5a50620\",\n \"prevId\": \"c208e744-6364-4488-bf96-d462f35ea5d1\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/0019_snapshot.json",
"chars": 62902,
"preview": "{\n \"id\": \"029a46b4-3db9-433a-b476-b37f7a8338f5\",\n \"prevId\": \"c726b804-42fb-40b6-a5d3-6b66e5a50620\",\n \"version\": \"7\",\n"
},
{
"path": "apps/backend/supabase/migrations/meta/_journal.json",
"chars": 2918,
"preview": "{\n \"version\": \"7\",\n \"dialect\": \"postgresql\",\n \"entries\": [\n {\n \"idx\": 0,\n \"version\": \"7\",\n \"when\": "
},
{
"path": "apps/backend/tsconfig.json",
"chars": 719,
"preview": "{\n \"compilerOptions\": {\n // Enable latest features\n \"lib\": [\"ESNext\", \"DOM\"],\n \"target\": \"ESNext"
},
{
"path": "apps/web/.gitignore",
"chars": 388,
"preview": "# dependencies (bun install)\nnode_modules\n\n# output\nout\ndist\n*.tgz\n\n# code coverage\ncoverage\n*.lcov\n\n# logs\nlogs\n_.log\nr"
},
{
"path": "apps/web/README.md",
"chars": 354,
"preview": "# Web project\n\nStructure\n\n- Client - Next.js client that is served as app front-end\n- Server - The control server that w"
},
{
"path": "apps/web/client/.gitignore",
"chars": 673,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
},
{
"path": "apps/web/client/.storybook/main.ts",
"chars": 3302,
"preview": "import type { StorybookConfig } from \"@storybook/nextjs-vite\";\n\nimport { dirname, join, relative } from \"path\"\n\nimport {"
},
{
"path": "apps/web/client/.storybook/mocks/supabase-client.ts",
"chars": 925,
"preview": "/**\n * Mock Supabase client utilities for Storybook\n *\n * This mock prevents the import chain:\n * getFileUrlFromStorage "
},
{
"path": "apps/web/client/.storybook/mocks/trpc-react.tsx",
"chars": 1970,
"preview": "'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { createTRPCReact, httpB"
},
{
"path": "apps/web/client/.storybook/preview-head.html",
"chars": 91,
"preview": "<script type=\"module\" src=\"/onlook-preload-script.js\" id=\"onlook-preload-script\"></script>\n"
},
{
"path": "apps/web/client/.storybook/preview.tsx",
"chars": 1222,
"preview": "import type { Preview } from '@storybook/nextjs-vite'\nimport '@onlook/ui/globals.css'\nimport { Inter } from 'next/font/g"
},
{
"path": "apps/web/client/.storybook/vitest.setup.ts",
"chars": 454,
"preview": "import * as a11yAddonAnnotations from \"@storybook/addon-a11y/preview\";\nimport { setProjectAnnotations } from '@storybook"
},
{
"path": "apps/web/client/README.md",
"chars": 1364,
"preview": "# Create T3 App\n\nThis is a [T3 Stack](https://create.t3.gg/) project bootstrapped with\n`create-t3-app`.\n\n## What's next?"
},
{
"path": "apps/web/client/chromatic.config.json",
"chars": 114,
"preview": "{\n \"projectToken\": \"chpt_549eddb0e603baf\",\n \"buildScriptName\": \"build-storybook\",\n \"exitZeroOnChanges\": true\n}\n"
},
{
"path": "apps/web/client/components.json",
"chars": 490,
"preview": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n \"style\": \"new-york\",\n \"rsc\": true,\n \"tsx\": true,\n \"ta"
},
{
"path": "apps/web/client/eslint.config.js",
"chars": 537,
"preview": "// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format\nimport sto"
},
{
"path": "apps/web/client/messages/en.d.json.ts",
"chars": 14033,
"preview": "// This file is auto-generated by next-intl, do not edit directly.\n// See: https://next-intl.dev/docs/workflows/typescri"
},
{
"path": "apps/web/client/messages/en.json",
"chars": 13840,
"preview": "{\n \"projects\": {\n \"create\": {\n \"settings\": {\n \"title\": \"Settings\",\n \""
},
{
"path": "apps/web/client/messages/es.json",
"chars": 14691,
"preview": "{\n \"projects\": {\n \"create\": {\n \"settings\": {\n \"title\": \"Configuración\",\n "
},
{
"path": "apps/web/client/messages/ja.json",
"chars": 12118,
"preview": "{\n \"pricing\": {\n \"plans\": {\n \"basic\": {\n \"name\": \"Basic\",\n \"price\": \""
},
{
"path": "apps/web/client/messages/ko.json",
"chars": 12005,
"preview": "{\n \"projects\": {\n \"create\": {\n \"settings\": {\n \"title\": \"설정\",\n \"toolti"
},
{
"path": "apps/web/client/messages/zh.json",
"chars": 11272,
"preview": "{\n \"projects\": {\n \"create\": {\n \"settings\": {\n \"title\": \"设置\",\n \"toolti"
},
{
"path": "apps/web/client/next.config.ts",
"chars": 830,
"preview": "/**\n * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful\n * for Docker b"
},
{
"path": "apps/web/client/package.json",
"chars": 4979,
"preview": "{\n \"productName\": \"Onlook\",\n \"name\": \"@onlook/web-client\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"homepage\": \"htt"
},
{
"path": "apps/web/client/postcss.config.js",
"chars": 78,
"preview": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n};\n"
},
{
"path": "apps/web/client/public/onlook-preload-script.js",
"chars": 463594,
"preview": "var U4=Object.create;var{getPrototypeOf:J4,defineProperty:Je,getOwnPropertyNames:P4}=Object;var E4=Object.prototype.hasO"
},
{
"path": "apps/web/client/public/scenes/flow-background.json",
"chars": 15079,
"preview": "{\"history\":[{\"breakpoints\":[],\"visible\":true,\"aspectRatio\":1,\"userDownsample\":0.5,\"layerType\":\"effect\",\"type\":\"gradient\""
},
{
"path": "apps/web/client/src/app/_components/auth-modal.tsx",
"chars": 2365,
"preview": "import { transKeys } from '@/i18n/keys';\nimport {\n AlertDialog,\n AlertDialogContent,\n AlertDialogDescription,\n "
},
{
"path": "apps/web/client/src/app/_components/button-link.tsx",
"chars": 1084,
"preview": "// Reusable button-link component\nexport function ButtonLink({ href, children, rightIcon, target, rel }: { \n href: st"
},
{
"path": "apps/web/client/src/app/_components/hero/ai-features-hero.tsx",
"chars": 4548,
"preview": "'use client';\n\nimport { useRouter } from 'next/navigation';\nimport { motion } from 'motion/react';\n\nimport { Button } fr"
},
{
"path": "apps/web/client/src/app/_components/hero/ai-frontend-hero.tsx",
"chars": 4489,
"preview": "'use client';\n\nimport { useRouter } from 'next/navigation';\nimport { motion } from 'motion/react';\n\nimport { Button } fr"
},
{
"path": "apps/web/client/src/app/_components/hero/builder-features-hero.tsx",
"chars": 4536,
"preview": "'use client';\n\nimport { useRouter } from 'next/navigation';\nimport { motion } from 'motion/react';\n\nimport { Button } fr"
},
{
"path": "apps/web/client/src/app/_components/hero/claude-code-hero.tsx",
"chars": 4417,
"preview": "'use client';\n\nimport { motion } from 'motion/react';\n\nimport { Button } from '@onlook/ui/button';\nimport { Icons } from"
},
{
"path": "apps/web/client/src/app/_components/hero/create-error.tsx",
"chars": 846,
"preview": "import { useCreateManager } from '@/components/store/create';\nimport { observer } from 'mobx-react-lite';\nimport { motio"
},
{
"path": "apps/web/client/src/app/_components/hero/create.tsx",
"chars": 18709,
"preview": "'use client';\n\nimport { useAuthContext } from '@/app/auth/auth-context';\nimport { ImagePill } from '@/app/project/[id]/_"
},
{
"path": "apps/web/client/src/app/_components/hero/features-hero.tsx",
"chars": 4356,
"preview": "'use client';\n\nimport { useRouter } from 'next/navigation';\nimport { motion } from 'motion/react';\n\nimport { Button } fr"
},
{
"path": "apps/web/client/src/app/_components/hero/high-demand.tsx",
"chars": 749,
"preview": "import { motion } from 'motion/react';\n\nexport function HighDemand() {\n // TODO: Use feature flags\n const isHighDe"
},
{
"path": "apps/web/client/src/app/_components/hero/import.tsx",
"chars": 1160,
"preview": "'use client';\n\nimport { api } from '@/trpc/react';\nimport { LocalForageKeys, Routes } from '@/utils/constants';\nimport {"
},
{
"path": "apps/web/client/src/app/_components/hero/index.tsx",
"chars": 5344,
"preview": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport { motion } from 'motion/react';\n\nimport { Button } fr"
},
{
"path": "apps/web/client/src/app/_components/hero/mobile-email-capture.tsx",
"chars": 20216,
"preview": "'use client';\n\nimport { Button } from '@onlook/ui/button';\nimport { Icons } from '@onlook/ui/icons/index';\nimport { Inpu"
},
{
"path": "apps/web/client/src/app/_components/hero/start-blank.tsx",
"chars": 859,
"preview": "'use client';\n\nimport { Icons } from '@onlook/ui/icons/index';\n\nimport { useCreateBlankProject } from '@/hooks/use-creat"
},
{
"path": "apps/web/client/src/app/_components/hero/unicorn-background.tsx",
"chars": 1861,
"preview": "'use client';\n\nimport { motion } from 'motion/react';\nimport { useEffect, useRef } from 'react';\nimport UnicornScene fro"
},
{
"path": "apps/web/client/src/app/_components/landing-page/ai-benefits-section.tsx",
"chars": 6100,
"preview": "'use client';\n\nimport React from 'react';\nimport { Icons } from '@onlook/ui/icons';\nimport { ButtonLink } from '../butto"
},
{
"path": "apps/web/client/src/app/_components/landing-page/ai-features-grid-section.tsx",
"chars": 3963,
"preview": "import React from 'react';\n\nexport function AiFeaturesGridSection() {\n return (\n <div className=\"w-full max-w-"
},
{
"path": "apps/web/client/src/app/_components/landing-page/ai-features-intro-section.tsx",
"chars": 927,
"preview": "import React from 'react';\n\nexport function AiFeaturesIntroSection() {\n return (\n <div className=\"w-full max-w"
},
{
"path": "apps/web/client/src/app/_components/landing-page/benefits-section.tsx",
"chars": 6191,
"preview": "'use client';\n\nimport React from 'react';\nimport { Icons } from '@onlook/ui/icons';\nimport { ButtonLink } from '../butto"
},
{
"path": "apps/web/client/src/app/_components/landing-page/builder-benefits-section.tsx",
"chars": 5963,
"preview": "import React from 'react';\nimport { Icons } from '@onlook/ui/icons';\nimport { TailwindColorEditorMockup } from '../share"
},
{
"path": "apps/web/client/src/app/_components/landing-page/builder-features-grid-section.tsx",
"chars": 2665,
"preview": "import React from 'react';\n\nexport function BuilderFeaturesGridSection() {\n return (\n <div className=\"w-full m"
},
{
"path": "apps/web/client/src/app/_components/landing-page/builder-features-intro-section.tsx",
"chars": 938,
"preview": "import React from 'react';\n\nexport function BuilderFeaturesIntroSection() {\n return (\n <div className=\"w-full "
},
{
"path": "apps/web/client/src/app/_components/landing-page/code-one-to-one-section.tsx",
"chars": 4799,
"preview": "import React, { useState } from 'react';\n\nconst mockDivs = [\n { id: 1, label: 'Header', codeLines: [2, 3] },\n { id: 2,"
},
{
"path": "apps/web/client/src/app/_components/landing-page/color-swatch-group.tsx",
"chars": 1467,
"preview": "import { Icons } from '@onlook/ui/icons';\n\ninterface ColorSwatchGroupProps {\n label: string;\n colorClasses: string"
},
{
"path": "apps/web/client/src/app/_components/landing-page/contributor-section.tsx",
"chars": 8998,
"preview": "'use client';\n\nimport './contributor.css';\n\nimport { Icons } from '@onlook/ui/icons';\nimport Link from 'next/link';\nimpo"
},
{
"path": "apps/web/client/src/app/_components/landing-page/contributor.css",
"chars": 874,
"preview": "\n/* Contributor Section */\n\n@keyframes spin-normal {\n from {\n transform: translate(-50%, -50%) rotate(0deg);\n }\n "
},
{
"path": "apps/web/client/src/app/_components/landing-page/cta-section.tsx",
"chars": 2623,
"preview": "'use client';\n\nimport { Button } from '@onlook/ui/button';\nimport { useRouter } from 'next/navigation';\nimport Link from"
},
{
"path": "apps/web/client/src/app/_components/landing-page/design-mockup/design-mockup-icons.tsx",
"chars": 5720,
"preview": "\nexport interface IconProps {\n className?: string;\n [key: string]: any;\n}\n\nexport const DesignMockupIcons = {\n "
},
{
"path": "apps/web/client/src/app/_components/landing-page/design-mockup/design-mockup.tsx",
"chars": 14829,
"preview": "import React from 'react';\nimport { DesignMockupIcons } from './design-mockup-icons';\nimport { vujahdayScript } from '.."
},
{
"path": "apps/web/client/src/app/_components/landing-page/faq-dropdown.tsx",
"chars": 2602,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport { useState, useRef, useEffect } from 'react';\n\ninterface FAQ {\n ques"
},
{
"path": "apps/web/client/src/app/_components/landing-page/faq-section.tsx",
"chars": 3604,
"preview": "import { Routes } from '@/utils/constants';\nimport { Icons } from '@onlook/ui/icons';\nimport React from 'react';\nimport "
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/ai-chat-preview-block.tsx",
"chars": 844,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport React from 'react';\nimport { AiChatInteractive } from '../../shared/moc"
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/brand-compliance.tsx",
"chars": 9063,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport { ColorSwatchGroup } from '../color-swatch-group';\nimport React, { useR"
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/components.tsx",
"chars": 21311,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport React from 'react';\n\nexport function ComponentsBlock() {\n return (\n "
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/direct-editing.tsx",
"chars": 931,
"preview": "import React from 'react';\nimport { Icons } from '@onlook/ui/icons';\nimport { DirectEditingInteractive } from '../../sha"
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/layers.tsx",
"chars": 8008,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport { NodeIcon } from '@onlook/ui/node-icon';\nimport { cn } from '@onlook/u"
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/responsive-website.tsx",
"chars": 7801,
"preview": "import { Laptop, Menu } from 'lucide-react';\nimport React, { useEffect, useRef, useState } from 'react';\n\nexport functio"
},
{
"path": "apps/web/client/src/app/_components/landing-page/feature-blocks/revision-history.tsx",
"chars": 6788,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport React, { useState, useEffect } from 'react';\n\nfunction VersionRow({ tit"
},
{
"path": "apps/web/client/src/app/_components/landing-page/features-grid-section.tsx",
"chars": 3811,
"preview": "import React from 'react';\n\nexport function FeaturesGridSection() {\n return (\n <div className=\"w-full max-w-6x"
},
{
"path": "apps/web/client/src/app/_components/landing-page/features-intro-section.tsx",
"chars": 901,
"preview": "import React from 'react';\n\nexport function FeaturesIntroSection() {\n return (\n <div className=\"w-full max-w-6"
},
{
"path": "apps/web/client/src/app/_components/landing-page/illustrations.tsx",
"chars": 1245311,
"preview": "import { cn } from '@onlook/ui/utils';\n\nexport interface IllustrationProps {\n className?: string;\n [key: string]: "
},
{
"path": "apps/web/client/src/app/_components/landing-page/obsess-for-hours-section.tsx",
"chars": 2659,
"preview": "import { Icons } from '@onlook/ui/icons/index';\nimport { vujahdayScript } from '../../fonts';\n\nexport function ObsessFor"
},
{
"path": "apps/web/client/src/app/_components/landing-page/onlook-interface-mockup.tsx",
"chars": 31476,
"preview": "'use client';\n\nimport { Icons } from '@onlook/ui/icons';\nimport { NodeIcon } from '@onlook/ui/node-icon';\nimport { cn } "
},
{
"path": "apps/web/client/src/app/_components/landing-page/page-footer.tsx",
"chars": 7549,
"preview": "import { ExternalRoutes, Routes } from '@/utils/constants';\nimport { Icons } from '@onlook/ui/icons';\nimport { useRouter"
},
{
"path": "apps/web/client/src/app/_components/landing-page/responsive-mockup-section.tsx",
"chars": 2463,
"preview": "import React from 'react';\nimport { OnlookInterfaceMockup } from './onlook-interface-mockup';\n\nexport function Responsiv"
},
{
"path": "apps/web/client/src/app/_components/landing-page/social-proof-section.tsx",
"chars": 1613,
"preview": "'use client';\n\nimport React from 'react';\nimport { useGitHubStats } from '../top-bar/github';\n\nexport function SocialPro"
},
{
"path": "apps/web/client/src/app/_components/landing-page/testimonials-section.tsx",
"chars": 6110,
"preview": "import React from 'react';\n\ninterface TestimonialCardProps {\n text: string;\n name: string;\n label: string;\n profileI"
},
{
"path": "apps/web/client/src/app/_components/landing-page/what-can-onlook-do-section.tsx",
"chars": 14995,
"preview": "import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { vujahdayScript } from '@/app/fonts';\ni"
},
{
"path": "apps/web/client/src/app/_components/login-button.tsx",
"chars": 3210,
"preview": "import { transKeys } from '@/i18n/keys';\nimport { SignInMethod } from '@onlook/models/auth';\nimport { Button } from '@on"
},
{
"path": "apps/web/client/src/app/_components/shared/mockups/ai-chat-interactive.tsx",
"chars": 6600,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport React, { useState } from 'react';\n\nconst chatMessages = [\n { sender: '"
},
{
"path": "apps/web/client/src/app/_components/shared/mockups/components-mockup.tsx",
"chars": 19521,
"preview": "import { Icons } from '@onlook/ui/icons';\nimport React from 'react';\n\nexport function ComponentsMockup() {\n return (\n"
},
{
"path": "apps/web/client/src/app/_components/shared/mockups/direct-editing-interactive.tsx",
"chars": 21834,
"preview": "import React, { useState, useEffect } from 'react';\nimport { Icons } from '@onlook/ui/icons';\nimport { Illustrations } f"
},
{
"path": "apps/web/client/src/app/_components/shared/mockups/tailwind-color-editor.tsx",
"chars": 17212,
"preview": "'use client';\n\nimport React, { useState } from 'react';\nimport { Color } from '@onlook/utility';\nimport { ColorPicker } "
},
{
"path": "apps/web/client/src/app/_components/theme.tsx",
"chars": 305,
"preview": "'use client';\n\nimport { ThemeProvider as NextThemesProvider } from 'next-themes';\nimport * as React from 'react';\n\nexpor"
},
{
"path": "apps/web/client/src/app/_components/top-bar/github.tsx",
"chars": 2636,
"preview": "'use client';\n\nimport { Icons } from '@onlook/ui/icons';\nimport { useEffect, useState } from 'react';\n\nconst DEFAULT_STA"
},
{
"path": "apps/web/client/src/app/_components/top-bar/index.tsx",
"chars": 2515,
"preview": "'use client';\n\nimport { Routes } from '@/utils/constants';\nimport { NAVIGATION_CATEGORIES } from '@/utils/constants/navi"
},
{
"path": "apps/web/client/src/app/_components/top-bar/mega-menu.tsx",
"chars": 3614,
"preview": "'use client';\n\nimport { type NavigationLink } from '@/utils/constants/navigation';\nimport { cn } from '@onlook/ui/utils'"
},
{
"path": "apps/web/client/src/app/_components/top-bar/mobile-menu.tsx",
"chars": 5738,
"preview": "'use client';\n\nimport { useEffect } from 'react';\nimport * as Portal from '@radix-ui/react-portal';\n\nimport { Accordion,"
},
{
"path": "apps/web/client/src/app/_components/top-bar/user.tsx",
"chars": 963,
"preview": "'use client';\n\nimport { CurrentUserAvatar } from '@/components/ui/avatar-dropdown';\nimport { api } from '@/trpc/react';\n"
},
{
"path": "apps/web/client/src/app/_components/website-layout.tsx",
"chars": 785,
"preview": "'use client';\n\nimport { TopBar } from './top-bar';\nimport { Footer } from './landing-page/page-footer';\n\ninterface Websi"
},
{
"path": "apps/web/client/src/app/about/layout.tsx",
"chars": 6093,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'About Onlook | The Team Behind th"
},
{
"path": "apps/web/client/src/app/about/page.tsx",
"chars": 45774,
"preview": "\"use client\";\nimport { WebsiteLayout } from '@/app/_components/website-layout';\nimport { useReducedMotion } from '@onloo"
},
{
"path": "apps/web/client/src/app/api/chat/helpers/index.ts",
"chars": 51,
"preview": "export * from './stream';\nexport * from './usage';\n"
},
{
"path": "apps/web/client/src/app/api/chat/helpers/stream.ts",
"chars": 488,
"preview": "export function errorHandler(error: unknown) {\n try {\n console.error('Error in chat', error);\n if (!err"
},
{
"path": "apps/web/client/src/app/api/chat/helpers/usage.ts",
"chars": 2779,
"preview": "import { createClient as createTRPCClient } from '@/trpc/request-server';\nimport { createClient as createSupabaseClient "
},
{
"path": "apps/web/client/src/app/api/chat/route.ts",
"chars": 4619,
"preview": "import { api } from '@/trpc/server';\nimport { trackEvent } from '@/utils/analytics/server';\nimport { createRootAgentStre"
},
{
"path": "apps/web/client/src/app/api/email-capture/route.ts",
"chars": 3430,
"preview": "import { env } from '@/env';\nimport { z } from 'zod';\nexport async function POST(request: Request) {\n try {\n c"
},
{
"path": "apps/web/client/src/app/api/trpc/[trpc]/route.ts",
"chars": 1043,
"preview": "import { fetchRequestHandler } from '@trpc/server/adapters/fetch';\nimport { type NextRequest } from 'next/server';\nimpor"
},
{
"path": "apps/web/client/src/app/auth/auth-context.tsx",
"chars": 2929,
"preview": "'use client';\n\nimport { LocalForageKeys } from '@/utils/constants';\nimport { SignInMethod } from '@onlook/models/auth';\n"
},
{
"path": "apps/web/client/src/app/auth/callback/route.ts",
"chars": 1726,
"preview": "import { trackEvent } from '@/utils/analytics/server';\nimport { Routes } from '@/utils/constants';\nimport { createClient"
},
{
"path": "apps/web/client/src/app/auth/redirect/page.tsx",
"chars": 1860,
"preview": "'use client';\n\nimport { LocalForageKeys, Routes } from '@/utils/constants';\nimport { sanitizeReturnUrl } from '@/utils/u"
},
{
"path": "apps/web/client/src/app/callback/github/install/page.tsx",
"chars": 9373,
"preview": "'use client';\n\nimport { api } from '@/trpc/react';\nimport { Routes } from '@/utils/constants';\nimport { Button } from '@"
},
{
"path": "apps/web/client/src/app/callback/stripe/cancel/page.tsx",
"chars": 397,
"preview": "import { Icons } from \"@onlook/ui/icons\";\nimport MessageScreen from \"../message-screen\";\n\nexport default function Cancel"
},
{
"path": "apps/web/client/src/app/callback/stripe/message-screen.tsx",
"chars": 429,
"preview": "\nexport default function MessageScreen({\n title,\n message,\n icon,\n}: {\n title: string;\n message: string;\n"
},
{
"path": "apps/web/client/src/app/callback/stripe/success/page.tsx",
"chars": 415,
"preview": "'use client';\n\nimport { Icons } from \"@onlook/ui/icons\";\nimport MessageScreen from \"../message-screen\";\n\nexport default "
},
{
"path": "apps/web/client/src/app/faq/layout.tsx",
"chars": 1656,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'FAQ | Onlook - AI-Powered Visual "
},
{
"path": "apps/web/client/src/app/faq/page.tsx",
"chars": 15160,
"preview": "'use client';\n\nimport { useEffect, useRef, useState } from 'react';\nimport { FAQDropdown } from '../_components/landing-"
},
{
"path": "apps/web/client/src/app/features/ai/layout.tsx",
"chars": 5553,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'AI Visual Editor | Build UIs with"
},
{
"path": "apps/web/client/src/app/features/ai/page.tsx",
"chars": 5161,
"preview": "'use client';\n\nimport { CreateManagerProvider } from '@/components/store/create';\nimport { SubscriptionModal } from '@/c"
},
{
"path": "apps/web/client/src/app/features/ai-for-frontend/layout.tsx",
"chars": 8465,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'AI for Frontend Development | Vis"
},
{
"path": "apps/web/client/src/app/features/ai-for-frontend/page.tsx",
"chars": 17074,
"preview": "'use client';\n\nimport { CreateManagerProvider } from '@/components/store/create';\nimport { SubscriptionModal } from '@/c"
},
{
"path": "apps/web/client/src/app/features/builder/layout.tsx",
"chars": 5305,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'Visual Builder | Design with Your"
},
{
"path": "apps/web/client/src/app/features/builder/page.tsx",
"chars": 5288,
"preview": "'use client';\n\nimport { CreateManagerProvider } from '@/components/store/create';\nimport { SubscriptionModal } from '@/c"
},
{
"path": "apps/web/client/src/app/features/layout.tsx",
"chars": 6136,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'Features | Onlook - AI-Powered Vi"
},
{
"path": "apps/web/client/src/app/features/page.tsx",
"chars": 4865,
"preview": "'use client';\n\nimport { CreateManagerProvider } from '@/components/store/create';\nimport { SubscriptionModal } from '@/c"
},
{
"path": "apps/web/client/src/app/features/prototype/layout.tsx",
"chars": 5905,
"preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'AI Prototype Generator | Create F"
},
{
"path": "apps/web/client/src/app/features/prototype/page.tsx",
"chars": 21062,
"preview": "'use client';\n\nimport { useRouter } from 'next/navigation';\nimport { motion } from 'motion/react';\n\nimport { Button } fr"
},
{
"path": "apps/web/client/src/app/fonts.ts",
"chars": 163,
"preview": "import { Vujahday_Script } from 'next/font/google';\n\nexport const vujahdayScript = Vujahday_Script({\n weight: '400',\n "
},
{
"path": "apps/web/client/src/app/invitation/[id]/_components/auth.tsx",
"chars": 1170,
"preview": "'use client';\n\nimport { Routes } from '@/utils/constants';\nimport { getReturnUrlQueryParam } from '@/utils/url';\nimport "
},
{
"path": "apps/web/client/src/app/invitation/[id]/_components/main.tsx",
"chars": 5981,
"preview": "'use client';\n\nimport { api } from '@/trpc/react';\nimport { Routes } from '@/utils/constants';\nimport { resetTelemetry }"
},
{
"path": "apps/web/client/src/app/invitation/[id]/layout.tsx",
"chars": 667,
"preview": "import { createClient } from '@/utils/supabase/server';\nimport { type Metadata } from 'next';\nimport { HandleAuth } from"
},
{
"path": "apps/web/client/src/app/invitation/[id]/page.tsx",
"chars": 205,
"preview": "import { Main } from './_components/main';\n\nexport default async function Page({ params }: { params: Promise<{ id: strin"
},
{
"path": "apps/web/client/src/app/layout.tsx",
"chars": 4232,
"preview": "import '@/styles/globals.css';\nimport '@onlook/ui/globals.css';\n\nimport RB2BLoader from '@/components/rb2b-loader';\nimpo"
},
{
"path": "apps/web/client/src/app/login/actions.tsx",
"chars": 1754,
"preview": "'use server';\n\nimport { env } from '@/env';\nimport { Routes } from '@/utils/constants';\nimport { createClient } from '@/"
},
{
"path": "apps/web/client/src/app/login/error.tsx",
"chars": 101,
"preview": "'use client';\nexport default function ErrorPage() {\n return <p>Sorry, something went wrong</p>;\n}\n"
},
{
"path": "apps/web/client/src/app/login/page.tsx",
"chars": 4202,
"preview": "'use client';\n\nimport { useGetBackground } from '@/hooks/use-get-background';\nimport { transKeys } from '@/i18n/keys';\ni"
},
{
"path": "apps/web/client/src/app/not-found.tsx",
"chars": 2931,
"preview": "'use client';\n\nimport Link from 'next/link';\nimport { motion } from 'framer-motion';\nimport { WebsiteLayout } from './_c"
},
{
"path": "apps/web/client/src/app/page.tsx",
"chars": 1762,
"preview": "'use client';\n\nimport { CreateManagerProvider } from '@/components/store/create';\nimport { SubscriptionModal } from '@/c"
},
{
"path": "apps/web/client/src/app/pricing/page.tsx",
"chars": 8574,
"preview": "'use client';\n\nimport { Button } from '@onlook/ui/button';\nimport { Icons, type IconProps } from '@onlook/ui/icons';\nimp"
},
{
"path": "apps/web/client/src/app/privacy-policy/page.tsx",
"chars": 18810,
"preview": "'use client';\n\nimport { WebsiteLayout } from '../_components/website-layout';\n\nexport default function PrivacyPage() {\n "
},
{
"path": "apps/web/client/src/app/project/[id]/_components/bottom-bar/index.tsx",
"chars": 5587,
"preview": "'use client';\n\nimport { Hotkey } from '@/components/hotkey';\nimport { useEditorEngine } from '@/components/store/editor'"
},
{
"path": "apps/web/client/src/app/project/[id]/_components/bottom-bar/restart-sandbox-button.tsx",
"chars": 6271,
"preview": "'use client';\n\nimport { useEditorEngine } from '@/components/store/editor';\nimport { Icons } from '@onlook/ui/icons';\nim"
},
{
"path": "apps/web/client/src/app/project/[id]/_components/bottom-bar/terminal-area.tsx",
"chars": 7438,
"preview": "'use client';\n\nimport { useEditorEngine } from '@/components/store/editor';\nimport { Icons } from '@onlook/ui/icons';\nim"
},
{
"path": "apps/web/client/src/app/project/[id]/_components/bottom-bar/terminal.tsx",
"chars": 4263,
"preview": "'use client';\n\nimport '@xterm/xterm/css/xterm.css';\n\nimport { useEditorEngine } from '@/components/store/editor';\nimport"
},
{
"path": "apps/web/client/src/app/project/[id]/_components/branch/branch-controls.tsx",
"chars": 2839,
"preview": "import { useEditorEngine } from \"@/components/store/editor\";\nimport { BranchTabValue, LeftPanelTabValue, type Branch } f"
}
]
// ... and 1400 more files (download for full content)
About this extraction
This page contains the full source code of the onlook-dev/onlook GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1600 files (7.9 MB), approximately 2.2M tokens, and a symbol index with 3998 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.