diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000000000000000000000000000000000000..6c6400984ecfa46d366a5308b2264b6fa129be97
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,5 @@
+OAUTH_CLIENT_ID=
+OAUTH_CLIENT_SECRET=
+APP_PORT=5173
+REDIRECT_URI=http://localhost:5173/auth/login
+DEFAULT_HF_TOKEN=
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 5ef6a520780202a1d6addd833d800ccb1ecac0bb..38d4117ba770f7518a4bc651b80446a4f2f218d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,41 +1,26 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.*
-.yarn/*
-!.yarn/patches
-!.yarn/plugins
-!.yarn/releases
-!.yarn/versions
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
+# Logs
+logs
+*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-.pnpm-debug.log*
-
-# env files (can opt-in for committing if needed)
-.env*
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.env
+.aider*
diff --git a/Dockerfile b/Dockerfile
index cbe0188aaee92186937765d2c85d76f7b212c537..8003b5cb2da5b411b794263c7d70bae1f6866ae0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,9 @@
-FROM node:20-alpine
+# Dockerfile
+# Use an official Node.js runtime as the base image
+FROM node:22.1.0
USER root
+RUN apt-get update
USER 1000
WORKDIR /usr/src/app
# Copy package.json and package-lock.json to the container
@@ -13,7 +16,7 @@ RUN npm install
RUN npm run build
# Expose the application port (assuming your app runs on port 3000)
-EXPOSE 3000
+EXPOSE 5173
# Start the application
CMD ["npm", "start"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 5ab2231fc7dc96070548f1d03ab1d0f73a799600..5d5239cffd688fecefc35757a3f74ff155a1b47b 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,13 @@
---
-title: DeepSite v2
+title: DeepSite
emoji: 🐳
colorFrom: blue
colorTo: blue
sdk: docker
pinned: true
-app_port: 3000
+app_port: 5173
license: mit
-short_description: Generate any application with DeepSeek
-models:
- - deepseek-ai/DeepSeek-V3-0324
- - deepseek-ai/DeepSeek-R1-0528
+short_description: Imagine and Share in 1-Click
---
-# DeepSite 🐳
-
-DeepSite is a coding platform powered by DeepSeek AI, designed to make coding smarter and more efficient. Tailored for developers, data scientists, and AI engineers, it integrates generative AI into your coding projects to enhance creativity and productivity.
-
-## How to use it locally
-
-Follow [this discussion](https://huggingface.co/spaces/enzostvs/deepsite/discussions/74)
+Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
diff --git a/app/(public)/layout.tsx b/app/(public)/layout.tsx
deleted file mode 100644
index 4a4ec57d2609c783602beb6c06c8dca6a1e6192d..0000000000000000000000000000000000000000
--- a/app/(public)/layout.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import Navigation from "@/components/public/navigation";
-
-export default async function PublicLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
- );
-}
diff --git a/app/(public)/page.tsx b/app/(public)/page.tsx
deleted file mode 100644
index c0849e72cf29027524ec9ebc3818e80a8aee5ef3..0000000000000000000000000000000000000000
--- a/app/(public)/page.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { AskAi } from "@/components/space/ask-ai";
-import { redirect } from "next/navigation";
-export default function Home() {
- redirect("/projects/new");
- return (
- <>
-
-
-
-
- Deploy your website in seconds
-
-
-
-
- Features that make you smile
-
-
- >
- );
-}
diff --git a/app/(public)/projects/page.tsx b/app/(public)/projects/page.tsx
deleted file mode 100644
index 8bf6fc850473236a51ce3366e1820e00882aa454..0000000000000000000000000000000000000000
--- a/app/(public)/projects/page.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { cookies } from "next/headers";
-import { redirect } from "next/navigation";
-
-import { apiServer } from "@/lib/api";
-import MY_TOKEN_KEY from "@/lib/get-cookie-name";
-import { MyProjects } from "@/components/my-projects";
-
-async function getMyProjects() {
- const cookieStore = await cookies();
- const token = cookieStore.get(MY_TOKEN_KEY())?.value;
- if (!token) return { redirectUrl: true, projects: [] };
- try {
- const { data } = await apiServer.get("/me/projects", {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- });
-
- return {
- projects: data.projects,
- };
- } catch {
- return { projects: [] };
- }
-}
-export default async function ProjectsPage() {
- const { redirectUrl, projects } = await getMyProjects();
- if (redirectUrl) {
- redirect("/");
- }
-
- return ;
-}
diff --git a/app/actions/auth.ts b/app/actions/auth.ts
deleted file mode 100644
index a914cf71e5f41b268a93d7f20b654079bb3bd75e..0000000000000000000000000000000000000000
--- a/app/actions/auth.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-"use server";
-
-import { headers } from "next/headers";
-
-export async function getAuth() {
- const authList = await headers();
- const host = authList.get("host") ?? "localhost:3000";
- const redirect_uri =
- `${host.includes("localhost") ? "http://" : "https://"}` +
- host +
- "/auth/callback";
-
- const loginRedirectUrl = `https://huggingface.co/oauth/authorize?client_id=${process.env.OAUTH_CLIENT_ID}&redirect_uri=${redirect_uri}&response_type=code&scope=openid%20profile%20write-repos%20manage-repos%20inference-api&prompt=consent&state=1234567890`;
- return loginRedirectUrl;
-}
diff --git a/app/api/ask-ai/route.ts b/app/api/ask-ai/route.ts
deleted file mode 100644
index 0cfd357f17e169a95e04a26f3d60bb48cf5a9583..0000000000000000000000000000000000000000
--- a/app/api/ask-ai/route.ts
+++ /dev/null
@@ -1,411 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { NextRequest } from "next/server";
-import { NextResponse } from "next/server";
-import { headers } from "next/headers";
-import { InferenceClient } from "@huggingface/inference";
-
-import { MODELS, PROVIDERS } from "@/lib/providers";
-import {
- DIVIDER,
- FOLLOW_UP_SYSTEM_PROMPT,
- INITIAL_SYSTEM_PROMPT,
- MAX_REQUESTS_PER_IP,
- REPLACE_END,
- SEARCH_START,
-} from "@/lib/prompts";
-import MY_TOKEN_KEY from "@/lib/get-cookie-name";
-
-const ipAddresses = new Map();
-
-export async function POST(request: NextRequest) {
- const authHeaders = await headers();
- const userToken = request.cookies.get(MY_TOKEN_KEY())?.value;
-
- const body = await request.json();
- const { prompt, provider, model, redesignMarkdown, html } = body;
-
- if (!model || (!prompt && !redesignMarkdown)) {
- return NextResponse.json(
- { ok: false, error: "Missing required fields" },
- { status: 400 }
- );
- }
-
- const selectedModel = MODELS.find(
- (m) => m.value === model || m.label === model
- );
- if (!selectedModel) {
- return NextResponse.json(
- { ok: false, error: "Invalid model selected" },
- { status: 400 }
- );
- }
-
- if (!selectedModel.providers.includes(provider) && provider !== "auto") {
- return NextResponse.json(
- {
- ok: false,
- error: `The selected model does not support the ${provider} provider.`,
- openSelectProvider: true,
- },
- { status: 400 }
- );
- }
-
- let token = userToken;
- let billTo: string | null = null;
-
- /**
- * Handle local usage token, this bypass the need for a user token
- * and allows local testing without authentication.
- * This is useful for development and testing purposes.
- */
- if (process.env.HF_TOKEN && process.env.HF_TOKEN.length > 0) {
- token = process.env.HF_TOKEN;
- }
-
- const ip = authHeaders.get("x-forwarded-for")?.includes(",")
- ? authHeaders.get("x-forwarded-for")?.split(",")[1].trim()
- : authHeaders.get("x-forwarded-for");
-
- if (!token) {
- ipAddresses.set(ip, (ipAddresses.get(ip) || 0) + 1);
- if (ipAddresses.get(ip) > MAX_REQUESTS_PER_IP) {
- return NextResponse.json(
- {
- ok: false,
- openLogin: true,
- message: "Log In to continue using the service",
- },
- { status: 429 }
- );
- }
-
- token = process.env.DEFAULT_HF_TOKEN as string;
- billTo = "huggingface";
- }
-
- const DEFAULT_PROVIDER = PROVIDERS.novita;
- const selectedProvider =
- provider === "auto"
- ? PROVIDERS[selectedModel.autoProvider as keyof typeof PROVIDERS]
- : PROVIDERS[provider as keyof typeof PROVIDERS] ?? DEFAULT_PROVIDER;
-
- try {
- // Create a stream response
- const encoder = new TextEncoder();
- const stream = new TransformStream();
- const writer = stream.writable.getWriter();
-
- // Start the response
- const response = new NextResponse(stream.readable, {
- headers: {
- "Content-Type": "text/plain; charset=utf-8",
- "Cache-Control": "no-cache",
- Connection: "keep-alive",
- },
- });
-
- (async () => {
- let completeResponse = "";
- try {
- const client = new InferenceClient(token);
- const chatCompletion = client.chatCompletionStream(
- {
- model: selectedModel.value,
- provider: selectedProvider.id as any,
- messages: [
- {
- role: "system",
- content: INITIAL_SYSTEM_PROMPT,
- },
- {
- role: "user",
- content: redesignMarkdown
- ? `Here is my current design as a markdown:\n\n${redesignMarkdown}\n\nNow, please create a new design based on this markdown.`
- : html
- ? `Here is my current HTML code:\n\n\`\`\`html\n${html}\n\`\`\`\n\nNow, please create a new design based on this HTML.`
- : prompt,
- },
- ],
- max_tokens: selectedProvider.max_tokens,
- },
- billTo ? { billTo } : {}
- );
-
- while (true) {
- const { done, value } = await chatCompletion.next();
- if (done) {
- break;
- }
-
- const chunk = value.choices[0]?.delta?.content;
- if (chunk) {
- let newChunk = chunk;
- if (!selectedModel?.isThinker) {
- if (provider !== "sambanova") {
- await writer.write(encoder.encode(chunk));
- completeResponse += chunk;
-
- if (completeResponse.includes("