From 3ba77ce74883f818044cb4c8f7ff574a78f348ff Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Thu, 12 Feb 2026 10:12:59 +0100 Subject: [PATCH 1/3] clearing up ownership (#42735) in hydra blog --- apps/www/_blog/2026-02-04-hydra-joins-supabase.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/www/_blog/2026-02-04-hydra-joins-supabase.mdx b/apps/www/_blog/2026-02-04-hydra-joins-supabase.mdx index 042e06a9a3b4b..346d5f612821e 100644 --- a/apps/www/_blog/2026-02-04-hydra-joins-supabase.mdx +++ b/apps/www/_blog/2026-02-04-hydra-joins-supabase.mdx @@ -40,7 +40,7 @@ This effort includes: ### Next Steps for Hydra -Everything will stay open source. We'll take over maintenance of pg_duckdb and work in the open as we develop the Open Warehouse Architecture and the broader Postgres + Analytics vision. +Everything will stay open source. We'll help [MotherDuck](https://motherduck.com/) with `pg_duckdb` contributions and take over the maintenance of Hydra's existing repos. We will work in the open as we develop the Open Warehouse Architecture and the broader Postgres + Analytics vision. ## Join us to build the Open Warehouse From a5511386ce8bd5c1749e4e21c7e5ff9746fe4939 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Thu, 12 Feb 2026 10:15:14 +0100 Subject: [PATCH 2/3] chore: Clean up unused files from a project creation experiment (#42690) This PR removes the onboarding schema generation and visualization feature from the project creation flow. This was part of an experiment which has been tested and shut down. ## Summary by CodeRabbit * **Revert** * Removed project creation workflow components and related UI surfaces including the initial setup interface, project visual preview, and schema generation assistant. * Removed database schema visualization and diagram components. * Cleaned up associated package dependencies. --- .../ProjectCreation/InitialStep.tsx | 82 ---- .../ProjectCreation/ProjectVisual.tsx | 174 ------- .../interfaces/ProjectCreation/SchemaFlow.tsx | 86 ---- .../ProjectCreation/SchemaGenerator.tsx | 230 --------- .../interfaces/SchemaVisualizer/index.tsx | 141 ------ apps/studio/package.json | 2 - pnpm-lock.yaml | 454 +----------------- 7 files changed, 2 insertions(+), 1167 deletions(-) delete mode 100644 apps/studio/components/interfaces/ProjectCreation/InitialStep.tsx delete mode 100644 apps/studio/components/interfaces/ProjectCreation/ProjectVisual.tsx delete mode 100644 apps/studio/components/interfaces/ProjectCreation/SchemaFlow.tsx delete mode 100644 apps/studio/components/interfaces/ProjectCreation/SchemaGenerator.tsx delete mode 100644 apps/studio/components/interfaces/SchemaVisualizer/index.tsx diff --git a/apps/studio/components/interfaces/ProjectCreation/InitialStep.tsx b/apps/studio/components/interfaces/ProjectCreation/InitialStep.tsx deleted file mode 100644 index 4c13387d69d74..0000000000000 --- a/apps/studio/components/interfaces/ProjectCreation/InitialStep.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Database, Import } from 'lucide-react' - -import { cn } from 'ui' -import { SchemaGenerator } from './SchemaGenerator' - -interface SupabaseService { - name: 'Auth' | 'Storage' | 'Database' | 'Edge Function' | 'Cron' | 'Queues' | 'Vector' - reason: string -} - -export const InitialStep = ({ - onSubmit, - onStartBlank, - onMigrate, - onSqlGenerated, - onServicesUpdated, - onTitleUpdated, -}: { - onSubmit: (value: string) => void - onStartBlank: () => void - onMigrate: () => void - onSqlGenerated: (sql: string) => void - onServicesUpdated: (services: SupabaseService[]) => void - onTitleUpdated: (title: string) => void -}) => { - return ( -
-

What are you building?

-

- We can generate a schema for you to kick start your project. -

- { - onSqlGenerated(sql) - onSubmit(sql) - }} - onServicesUpdated={onServicesUpdated} - onTitleUpdated={onTitleUpdated} - /> -
- or -
-
-
- -
- Start blank - Configure a database and dive right in -
-
-
- -
- Migrate - - Import your database from another provider - -
-
-
-
- ) -} diff --git a/apps/studio/components/interfaces/ProjectCreation/ProjectVisual.tsx b/apps/studio/components/interfaces/ProjectCreation/ProjectVisual.tsx deleted file mode 100644 index ee5504c90e9c9..0000000000000 --- a/apps/studio/components/interfaces/ProjectCreation/ProjectVisual.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { AnimatePresence, motion } from 'framer-motion' -import { Box, Clock, Database, File, ListOrdered, User2, Zap } from 'lucide-react' -import { memo } from 'react' - -import { SchemaVisualizer } from 'components/interfaces/SchemaVisualizer' -import { BASE_PATH } from 'lib/constants' -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from 'ui' - -interface SupabaseService { - name: 'Auth' | 'Storage' | 'Database' | 'Edge Function' | 'Cron' | 'Queues' | 'Vector' - reason: string -} - -interface ProjectVisualProps { - sqlStatements: string[] - showInfo: boolean - services: SupabaseService[] - selectedRegion: { - name: string - location: { latitude: number; longitude: number } - code: string - displayName: string - } | null - projectDetails: { - dbRegion: string - cloudProvider: string - postgresVersion: string - } -} - -const arePropsEqual = (prevProps: ProjectVisualProps, nextProps: ProjectVisualProps) => { - return ( - prevProps.sqlStatements.length === nextProps.sqlStatements.length && - prevProps.showInfo === nextProps.showInfo && - prevProps.services.length === nextProps.services.length && - prevProps.selectedRegion?.name === nextProps.selectedRegion?.name && - prevProps.projectDetails.dbRegion === nextProps.projectDetails.dbRegion && - prevProps.projectDetails.cloudProvider === nextProps.projectDetails.cloudProvider && - prevProps.projectDetails.postgresVersion === nextProps.projectDetails.postgresVersion - ) -} - -export const ProjectVisual = memo( - ({ - sqlStatements, - showInfo = true, - services, - selectedRegion, - projectDetails, - }: ProjectVisualProps) => { - const variants = { - center: { - scale: 1, - opacity: 1, - top: '50%', - right: '50%', - x: '50%', - y: '-70%', - }, - corner: { - scale: 1, - opacity: 1, - top: '3%', - right: '3%', - x: '0%', - y: '0%', - }, - } - - const currentVariant = showInfo ? (sqlStatements.length > 0 ? 'corner' : 'center') : 'hidden' - return ( -
-
- {showInfo && ( - -
-
-
-

Primary Database

-

- - {projectDetails.dbRegion} - -

-

- - {projectDetails.cloudProvider} - - - - {projectDetails.postgresVersion} - -

-
-
- {selectedRegion && ( - region icon - )} -
- - -
- {[ - { name: 'Auth', icon: User2 }, - { name: 'Storage', icon: File }, - { name: 'Database', icon: Database }, - { name: 'Edge Function', icon: Zap }, - { name: 'Cron', icon: Clock }, - { name: 'Queues', icon: ListOrdered }, - { name: 'Vector', icon: Box }, - ].map((service) => { - const enabledService = services.find((s) => s.name === service.name) - const isEnabled = !!enabledService - return ( - - -
- -
-
- - {isEnabled ? `${service.name}: ${enabledService.reason}` : service.name} - -
- ) - })} -
-
-
- )} - - - - - -
-
- ) - }, - arePropsEqual -) - -ProjectVisual.displayName = 'ProjectVisual' diff --git a/apps/studio/components/interfaces/ProjectCreation/SchemaFlow.tsx b/apps/studio/components/interfaces/ProjectCreation/SchemaFlow.tsx deleted file mode 100644 index 31ffdc8d702c5..0000000000000 --- a/apps/studio/components/interfaces/ProjectCreation/SchemaFlow.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { useCallback, useEffect, useMemo } from 'react' -import { - applyNodeChanges, - Background, - BackgroundVariant, - Edge, - Node, - NodeChange, - NodeProps, - ReactFlow, - useEdgesState, - useNodesState, - useReactFlow, -} from 'reactflow' - -import { TableNode, TableNodeData } from '../Database/Schemas/SchemaTableNode' - -export const TABLE_NODE_WIDTH = 640 -export const TABLE_NODE_ROW_HEIGHT = 80 - -interface SchemaFlowProps { - nodes: Node[] - edges: Edge[] -} - -export const SchemaFlow = ({ nodes: initialNodes, edges: initialEdges }: SchemaFlowProps) => { - const [nodes, setNodes] = useNodesState(initialNodes) - const [edges, setEdges] = useEdgesState(initialEdges) - const nodeTypes = useMemo( - () => ({ table: (props: NodeProps) => }), - [] - ) - const reactFlowInstance = useReactFlow() - - useEffect(() => { - setNodes(initialNodes) - setEdges(initialEdges) - }, [initialNodes, initialEdges, setNodes, setEdges]) - - useEffect(() => { - reactFlowInstance.fitView() - }, [reactFlowInstance, nodes, edges]) - - const onNodesChange = useCallback( - (changes: NodeChange[]) => { - setNodes((nds) => applyNodeChanges(changes, nds)) - }, - [setNodes] - ) - - return ( -
- - - -
- ) -} diff --git a/apps/studio/components/interfaces/ProjectCreation/SchemaGenerator.tsx b/apps/studio/components/interfaces/ProjectCreation/SchemaGenerator.tsx deleted file mode 100644 index 2e2678050f44b..0000000000000 --- a/apps/studio/components/interfaces/ProjectCreation/SchemaGenerator.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import { useChat } from '@ai-sdk/react' -import { DefaultChatTransport } from 'ai' -import { useEffect, useState } from 'react' - -import { Markdown } from 'components/interfaces/Markdown' -import { onErrorChat } from 'components/ui/AIAssistantPanel/AIAssistant.utils' -import { BASE_PATH } from 'lib/constants' -import { useTrack } from 'lib/telemetry/track' -import { AiIconAnimation, Button, Label_Shadcn_, Textarea } from 'ui' - -interface SupabaseService { - name: 'Auth' | 'Storage' | 'Database' | 'Edge Function' | 'Cron' | 'Queues' | 'Vector' - reason: string -} - -interface SchemaGeneratorProps { - step: 'initial' | 'second' - onSqlGenerated: (sql: string) => void - onReset?: () => void - onServicesUpdated: (services: SupabaseService[]) => void - onTitleUpdated: (title: string) => void - isOneOff?: boolean -} - -export const SchemaGenerator = ({ - step, - onSqlGenerated, - onServicesUpdated, - onTitleUpdated, - onReset, - isOneOff = false, -}: SchemaGeneratorProps) => { - const [input, setInput] = useState('') - const [hasSql, setHasSql] = useState(false) - - const [promptIntendSent, setPromptIntendSent] = useState(false) - const track = useTrack() - - const { messages, setMessages, sendMessage, status, addToolResult } = useChat({ - id: 'schema-generator', - onError: onErrorChat, - onFinish: () => { - setInput('') - }, - async onToolCall({ toolCall }) { - if (toolCall.toolName === 'executeSql') { - try { - const sql = (toolCall.input as { sql: string }).sql - setHasSql(true) - onSqlGenerated(sql) - addToolResult({ - tool: toolCall.toolName, - toolCallId: toolCall.toolCallId, - output: 'Database successfully updated. Respond with next steps.', - }) - } catch (error) { - console.error('Failed to execute SQL:', error) - addToolResult({ - tool: toolCall.toolName, - toolCallId: toolCall.toolCallId, - output: `SQL execution failed: ${error instanceof Error ? error.message : String(error)}`, - }) - } - } - - if (toolCall.toolName === 'reset') { - try { - setHasSql(false) - onSqlGenerated('') - if (onReset) { - onReset() - } - addToolResult({ - tool: toolCall.toolName, - toolCallId: toolCall.toolCallId, - output: 'Database successfully reset', - }) - } catch (error) { - console.error('Failed to reset the database', error) - addToolResult({ - tool: toolCall.toolName, - toolCallId: toolCall.toolCallId, - output: `Resetting the database failed: ${error instanceof Error ? error.message : String(error)}`, - }) - } - } - - if (toolCall.toolName === 'setServices') { - const newServices = (toolCall.input as { services: SupabaseService[] }).services - onServicesUpdated(newServices) - addToolResult({ - tool: toolCall.toolName, - toolCallId: toolCall.toolCallId, - output: 'Services updated successfully', - }) - } - - if (toolCall.toolName === 'setTitle') { - const newTitle = (toolCall.input as { title: string }).title - onTitleUpdated(newTitle) - addToolResult({ - tool: toolCall.toolName, - toolCallId: toolCall.toolCallId, - output: 'Title updated successfully', - }) - } - }, - transport: new DefaultChatTransport({ - api: `${BASE_PATH}/api/ai/onboarding/design`, - }), - }) - - const isMessagesLoading = status === 'submitted' || status === 'streaming' - - useEffect(() => { - if (isOneOff) { - setMessages([]) - setInput('') - } - }, [isOneOff, setMessages]) - - const sendUserMessage = (content: string) => { - const payload = { - role: 'user' as const, - createdAt: new Date(), - parts: [{ type: 'text' as const, text: content }], - id: `msg-${Date.now()}`, - } - sendMessage(payload) - } - - const getLastAssistantMessage = () => { - const lastAssistantMessage = messages.filter((m) => m.role === 'assistant').slice(-1)[0] - if (!lastAssistantMessage?.parts) return '' - - const textPart = lastAssistantMessage.parts.find((part: any) => part.type === 'text') as - | { text: string } - | undefined - return textPart?.text || '' - } - - return ( -
- {!isOneOff && ( -
- - Generate a starting schema - - {messages?.length > 0 && ( - - )} -
- )} -
- {messages.length > 0 && - messages[messages.length - 1].role === 'assistant' && - getLastAssistantMessage() && - ((isOneOff && !hasSql) || !isOneOff) && ( -
-

- -

-
- )} -
-