diff --git a/web/src/app/_components/conversation-starter.tsx b/web/src/app/chat/components/conversation-starter.tsx
similarity index 100%
rename from web/src/app/_components/conversation-starter.tsx
rename to web/src/app/chat/components/conversation-starter.tsx
diff --git a/web/src/app/_components/input-box.tsx b/web/src/app/chat/components/input-box.tsx
similarity index 97%
rename from web/src/app/_components/input-box.tsx
rename to web/src/app/chat/components/input-box.tsx
index 5f9c1b9..6890d3d 100644
--- a/web/src/app/_components/input-box.tsx
+++ b/web/src/app/chat/components/input-box.tsx
@@ -11,6 +11,8 @@ import {
useState,
} from "react";
+import { Detective } from "~/components/deer-flow/icons/detective";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import { Button } from "~/components/ui/button";
import type { Option } from "~/core/messages";
import {
@@ -19,10 +21,6 @@ import {
} from "~/core/store";
import { cn } from "~/lib/utils";
-import { Detective } from "../_icons/detective";
-
-import { Tooltip } from "./tooltip";
-
export function InputBox({
className,
size,
diff --git a/web/src/app/_components/message-list-view.tsx b/web/src/app/chat/components/message-list-view.tsx
similarity index 96%
rename from web/src/app/_components/message-list-view.tsx
rename to web/src/app/chat/components/message-list-view.tsx
index 0775bb1..29ca98a 100644
--- a/web/src/app/_components/message-list-view.tsx
+++ b/web/src/app/chat/components/message-list-view.tsx
@@ -6,6 +6,12 @@ import { motion } from "framer-motion";
import { Download, Headphones } from "lucide-react";
import { useCallback, useMemo, useState } from "react";
+import { LoadingAnimation } from "~/components/deer-flow/loading-animation";
+import { Markdown } from "~/components/deer-flow/markdown";
+import { RainbowText } from "~/components/deer-flow/rainbow-text";
+import { RollingText } from "~/components/deer-flow/rolling-text";
+import { ScrollContainer } from "~/components/deer-flow/scroll-container";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import { Button } from "~/components/ui/button";
import {
Card,
@@ -25,13 +31,6 @@ import {
import { parseJSON } from "~/core/utils";
import { cn } from "~/lib/utils";
-import { LoadingAnimation } from "./loading-animation";
-import { Markdown } from "./markdown";
-import { RainbowText } from "./rainbow-text";
-import { RollingText } from "./rolling-text";
-import { ScrollContainer } from "./scroll-container";
-import { Tooltip } from "./tooltip";
-
export function MessageListView({
className,
onFeedback,
diff --git a/web/src/app/_components/messages-block.tsx b/web/src/app/chat/components/messages-block.tsx
similarity index 98%
rename from web/src/app/_components/messages-block.tsx
rename to web/src/app/chat/components/messages-block.tsx
index 4217737..09cc226 100644
--- a/web/src/app/_components/messages-block.tsx
+++ b/web/src/app/chat/components/messages-block.tsx
@@ -5,6 +5,7 @@ import { motion } from "framer-motion";
import { FastForward, Play } from "lucide-react";
import { useCallback, useRef, useState } from "react";
+import { RainbowText } from "~/components/deer-flow/rainbow-text";
import { Button } from "~/components/ui/button";
import {
Card,
@@ -21,7 +22,6 @@ import { cn } from "~/lib/utils";
import { ConversationStarter } from "./conversation-starter";
import { InputBox } from "./input-box";
import { MessageListView } from "./message-list-view";
-import { RainbowText } from "./rainbow-text";
import { Welcome } from "./welcome";
export function MessagesBlock({ className }: { className?: string }) {
diff --git a/web/src/app/_components/research-activities-block.tsx b/web/src/app/chat/components/research-activities-block.tsx
similarity index 96%
rename from web/src/app/_components/research-activities-block.tsx
rename to web/src/app/chat/components/research-activities-block.tsx
index f742463..9d8e9e4 100644
--- a/web/src/app/_components/research-activities-block.tsx
+++ b/web/src/app/chat/components/research-activities-block.tsx
@@ -11,6 +11,12 @@ import SyntaxHighlighter from "react-syntax-highlighter";
import { docco } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { dark } from "react-syntax-highlighter/dist/esm/styles/prism";
+import { FavIcon } from "~/components/deer-flow/fav-icon";
+import Image from "~/components/deer-flow/image";
+import { LoadingAnimation } from "~/components/deer-flow/loading-animation";
+import { Markdown } from "~/components/deer-flow/markdown";
+import { RainbowText } from "~/components/deer-flow/rainbow-text";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import {
Accordion,
AccordionContent,
@@ -24,13 +30,6 @@ import { useMessage, useStore } from "~/core/store";
import { parseJSON } from "~/core/utils";
import { cn } from "~/lib/utils";
-import { FavIcon } from "./fav-icon";
-import Image from "./image";
-import { LoadingAnimation } from "./loading-animation";
-import { Markdown } from "./markdown";
-import { RainbowText } from "./rainbow-text";
-import { Tooltip } from "./tooltip";
-
export function ResearchActivitiesBlock({
className,
researchId,
diff --git a/web/src/app/_components/research-block.tsx b/web/src/app/chat/components/research-block.tsx
similarity index 96%
rename from web/src/app/_components/research-block.tsx
rename to web/src/app/chat/components/research-block.tsx
index b1f4e3f..47a0ded 100644
--- a/web/src/app/_components/research-block.tsx
+++ b/web/src/app/chat/components/research-block.tsx
@@ -4,6 +4,8 @@
import { Check, Copy, Headphones, X } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
+import { ScrollContainer } from "~/components/deer-flow/scroll-container";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import { Button } from "~/components/ui/button";
import { Card } from "~/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
@@ -13,8 +15,6 @@ import { cn } from "~/lib/utils";
import { ResearchActivitiesBlock } from "./research-activities-block";
import { ResearchReportBlock } from "./research-report-block";
-import { ScrollContainer } from "./scroll-container";
-import { Tooltip } from "./tooltip";
export function ResearchBlock({
className,
@@ -102,7 +102,9 @@ export function ResearchBlock({
className="text-gray-400"
size="sm"
variant="ghost"
- onClick={() => { closeResearch(); }}
+ onClick={() => {
+ closeResearch();
+ }}
>
diff --git a/web/src/app/_components/research-report-block.tsx b/web/src/app/chat/components/research-report-block.tsx
similarity index 93%
rename from web/src/app/_components/research-report-block.tsx
rename to web/src/app/chat/components/research-report-block.tsx
index bf9c5a6..57365e5 100644
--- a/web/src/app/_components/research-report-block.tsx
+++ b/web/src/app/chat/components/research-report-block.tsx
@@ -3,14 +3,13 @@
import { useCallback, useRef } from "react";
+import { LoadingAnimation } from "~/components/deer-flow/loading-animation";
+import { Markdown } from "~/components/deer-flow/markdown";
import ReportEditor from "~/components/editor";
import { useReplay } from "~/core/replay";
import { useMessage, useStore } from "~/core/store";
import { cn } from "~/lib/utils";
-import { LoadingAnimation } from "./loading-animation";
-import { Markdown } from "./markdown";
-
export function ResearchReportBlock({
className,
messageId,
diff --git a/web/src/app/_components/welcome.tsx b/web/src/app/chat/components/welcome.tsx
similarity index 100%
rename from web/src/app/_components/welcome.tsx
rename to web/src/app/chat/components/welcome.tsx
diff --git a/web/src/app/chat/main.tsx b/web/src/app/chat/main.tsx
index 9da46f4..303b13d 100644
--- a/web/src/app/chat/main.tsx
+++ b/web/src/app/chat/main.tsx
@@ -8,8 +8,8 @@ import { useMemo } from "react";
import { useStore } from "~/core/store";
import { cn } from "~/lib/utils";
-import { MessagesBlock } from "../_components/messages-block";
-import { ResearchBlock } from "../_components/research-block";
+import { MessagesBlock } from "./components/messages-block";
+import { ResearchBlock } from "./components/research-block";
export default function Main() {
const openResearchId = useStore((state) => state.openResearchId);
diff --git a/web/src/app/chat/page.tsx b/web/src/app/chat/page.tsx
index aef4eb8..481acb7 100644
--- a/web/src/app/chat/page.tsx
+++ b/web/src/app/chat/page.tsx
@@ -10,10 +10,10 @@ import { Suspense } from "react";
import { Button } from "~/components/ui/button";
-import { Logo } from "../_components/logo";
-import { ThemeToggle } from "../_components/theme-toggle";
-import { Tooltip } from "../_components/tooltip";
-import { SettingsDialog } from "../_settings/dialogs/settings-dialog";
+import { Logo } from "../../components/deer-flow/logo";
+import { ThemeToggle } from "../../components/deer-flow/theme-toggle";
+import { Tooltip } from "../../components/deer-flow/tooltip";
+import { SettingsDialog } from "../settings/dialogs/settings-dialog";
const Main = dynamic(() => import("./main"), { ssr: false });
diff --git a/web/src/app/landing/_components/case-study-section.tsx b/web/src/app/landing/components/case-study-section.tsx
similarity index 100%
rename from web/src/app/landing/_components/case-study-section.tsx
rename to web/src/app/landing/components/case-study-section.tsx
diff --git a/web/src/app/landing/_components/core-features-section.tsx b/web/src/app/landing/components/core-features-section.tsx
similarity index 100%
rename from web/src/app/landing/_components/core-features-section.tsx
rename to web/src/app/landing/components/core-features-section.tsx
diff --git a/web/src/app/landing/_components/join-community-section.tsx b/web/src/app/landing/components/join-community-section.tsx
similarity index 100%
rename from web/src/app/landing/_components/join-community-section.tsx
rename to web/src/app/landing/components/join-community-section.tsx
diff --git a/web/src/app/landing/_components/jumbotron.tsx b/web/src/app/landing/components/jumbotron.tsx
similarity index 100%
rename from web/src/app/landing/_components/jumbotron.tsx
rename to web/src/app/landing/components/jumbotron.tsx
diff --git a/web/src/app/landing/_components/multi-agent-section.tsx b/web/src/app/landing/components/multi-agent-section.tsx
similarity index 100%
rename from web/src/app/landing/_components/multi-agent-section.tsx
rename to web/src/app/landing/components/multi-agent-section.tsx
diff --git a/web/src/app/landing/_components/multi-agent-visualization.tsx b/web/src/app/landing/components/multi-agent-visualization.tsx
similarity index 99%
rename from web/src/app/landing/_components/multi-agent-visualization.tsx
rename to web/src/app/landing/components/multi-agent-visualization.tsx
index c0bb5d2..fe30ccd 100644
--- a/web/src/app/landing/_components/multi-agent-visualization.tsx
+++ b/web/src/app/landing/components/multi-agent-visualization.tsx
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
"use client";
+
import {
ReactFlow,
Background,
@@ -31,12 +32,11 @@ import {
} from "react";
import "@xyflow/react/dist/style.css";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import { ShineBorder } from "~/components/magicui/shine-border";
import { Button } from "~/components/ui/button";
import { useIntersectionObserver } from "~/hooks/use-intersection-observer";
-import { Tooltip } from "../../_components/tooltip";
-
const ROW_HEIGHT = 85;
const ROW_1 = 0;
const ROW_2 = ROW_HEIGHT;
diff --git a/web/src/app/landing/_components/section-header.tsx b/web/src/app/landing/components/section-header.tsx
similarity index 100%
rename from web/src/app/landing/_components/section-header.tsx
rename to web/src/app/landing/components/section-header.tsx
diff --git a/web/src/app/landing/store/mav-store.ts b/web/src/app/landing/store/mav-store.ts
new file mode 100644
index 0000000..e69de29
diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx
index 7405c4c..e8574d4 100644
--- a/web/src/app/layout.tsx
+++ b/web/src/app/layout.tsx
@@ -6,10 +6,10 @@ import "~/styles/globals.css";
import { type Metadata } from "next";
import { Geist } from "next/font/google";
-import { ThemeProviderWrapper } from "~/app/_components/theme-provider-wrapper";
+import { ThemeProviderWrapper } from "~/components/deer-flow/theme-provider-wrapper";
import { TooltipProvider } from "~/components/ui/tooltip";
-import { Toaster } from "./_components/toaster";
+import { Toaster } from "../components/deer-flow/toaster";
export const metadata: Metadata = {
title: "🦌 DeerFlow",
diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx
index 59697ed..cfaf5f2 100644
--- a/web/src/app/page.tsx
+++ b/web/src/app/page.tsx
@@ -5,14 +5,14 @@ import { GithubOutlined } from "@ant-design/icons";
import Link from "next/link";
import { useMemo } from "react";
+import { Ray } from "~/components/deer-flow/ray";
import { Button } from "~/components/ui/button";
-import { Ray } from "./_components/ray";
-import { CaseStudySection } from "./landing/_components/case-study-section";
-import { CoreFeatureSection } from "./landing/_components/core-features-section";
-import { JoinCommunitySection } from "./landing/_components/join-community-section";
-import { Jumbotron } from "./landing/_components/jumbotron";
-import { MultiAgentSection } from "./landing/_components/multi-agent-section";
+import { CaseStudySection } from "./landing/components/case-study-section";
+import { CoreFeatureSection } from "./landing/components/core-features-section";
+import { JoinCommunitySection } from "./landing/components/join-community-section";
+import { Jumbotron } from "./landing/components/jumbotron";
+import { MultiAgentSection } from "./landing/components/multi-agent-section";
export default function HomePage() {
return (
diff --git a/web/src/app/_settings/dialogs/add-mcp-server-dialog.tsx b/web/src/app/settings/dialogs/add-mcp-server-dialog.tsx
similarity index 100%
rename from web/src/app/_settings/dialogs/add-mcp-server-dialog.tsx
rename to web/src/app/settings/dialogs/add-mcp-server-dialog.tsx
diff --git a/web/src/app/_settings/dialogs/settings-dialog.tsx b/web/src/app/settings/dialogs/settings-dialog.tsx
similarity index 98%
rename from web/src/app/_settings/dialogs/settings-dialog.tsx
rename to web/src/app/settings/dialogs/settings-dialog.tsx
index 1eb116a..d9c690c 100644
--- a/web/src/app/_settings/dialogs/settings-dialog.tsx
+++ b/web/src/app/settings/dialogs/settings-dialog.tsx
@@ -4,6 +4,7 @@
import { Settings } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import {
@@ -25,7 +26,6 @@ import {
} from "~/core/store";
import { cn } from "~/lib/utils";
-import { Tooltip } from "../../_components/tooltip";
import { SETTINGS_TABS } from "../tabs";
export function SettingsDialog() {
diff --git a/web/src/app/_settings/tabs/about-tab.tsx b/web/src/app/settings/tabs/about-tab.tsx
similarity index 83%
rename from web/src/app/_settings/tabs/about-tab.tsx
rename to web/src/app/settings/tabs/about-tab.tsx
index 4be2b9f..738a917 100644
--- a/web/src/app/_settings/tabs/about-tab.tsx
+++ b/web/src/app/settings/tabs/about-tab.tsx
@@ -3,7 +3,7 @@
import { BadgeInfo } from "lucide-react";
-import { Markdown } from "~/app/_components/markdown";
+import { Markdown } from "~/components/deer-flow/markdown";
import about from "./about.md";
import type { Tab } from "./types";
diff --git a/web/src/app/_settings/tabs/about.md b/web/src/app/settings/tabs/about.md
similarity index 100%
rename from web/src/app/_settings/tabs/about.md
rename to web/src/app/settings/tabs/about.md
diff --git a/web/src/app/_settings/tabs/general-tab.tsx b/web/src/app/settings/tabs/general-tab.tsx
similarity index 100%
rename from web/src/app/_settings/tabs/general-tab.tsx
rename to web/src/app/settings/tabs/general-tab.tsx
diff --git a/web/src/app/_settings/tabs/index.tsx b/web/src/app/settings/tabs/index.tsx
similarity index 100%
rename from web/src/app/_settings/tabs/index.tsx
rename to web/src/app/settings/tabs/index.tsx
diff --git a/web/src/app/_settings/tabs/mcp-tab.tsx b/web/src/app/settings/tabs/mcp-tab.tsx
similarity index 99%
rename from web/src/app/_settings/tabs/mcp-tab.tsx
rename to web/src/app/settings/tabs/mcp-tab.tsx
index f197092..8fee3f5 100644
--- a/web/src/app/_settings/tabs/mcp-tab.tsx
+++ b/web/src/app/settings/tabs/mcp-tab.tsx
@@ -5,7 +5,7 @@ import { motion } from "framer-motion";
import { Blocks, PencilRuler, Trash } from "lucide-react";
import { useCallback, useState } from "react";
-import { Tooltip } from "~/app/_components/tooltip";
+import { Tooltip } from "~/components/deer-flow/tooltip";
import { Button } from "~/components/ui/button";
import { Switch } from "~/components/ui/switch";
import type { MCPServerMetadata } from "~/core/mcp";
diff --git a/web/src/app/_settings/tabs/types.ts b/web/src/app/settings/tabs/types.ts
similarity index 100%
rename from web/src/app/_settings/tabs/types.ts
rename to web/src/app/settings/tabs/types.ts
diff --git a/web/src/app/_components/fav-icon.tsx b/web/src/components/deer-flow/fav-icon.tsx
similarity index 100%
rename from web/src/app/_components/fav-icon.tsx
rename to web/src/components/deer-flow/fav-icon.tsx
diff --git a/web/src/app/_icons/detective.tsx b/web/src/components/deer-flow/icons/detective.tsx
similarity index 100%
rename from web/src/app/_icons/detective.tsx
rename to web/src/components/deer-flow/icons/detective.tsx
diff --git a/web/src/app/_components/image.tsx b/web/src/components/deer-flow/image.tsx
similarity index 100%
rename from web/src/app/_components/image.tsx
rename to web/src/components/deer-flow/image.tsx
diff --git a/web/src/app/_components/loading-animation.module.css b/web/src/components/deer-flow/loading-animation.module.css
similarity index 100%
rename from web/src/app/_components/loading-animation.module.css
rename to web/src/components/deer-flow/loading-animation.module.css
diff --git a/web/src/app/_components/loading-animation.tsx b/web/src/components/deer-flow/loading-animation.tsx
similarity index 100%
rename from web/src/app/_components/loading-animation.tsx
rename to web/src/components/deer-flow/loading-animation.tsx
diff --git a/web/src/app/_components/logo.tsx b/web/src/components/deer-flow/logo.tsx
similarity index 100%
rename from web/src/app/_components/logo.tsx
rename to web/src/components/deer-flow/logo.tsx
diff --git a/web/src/app/_components/markdown.tsx b/web/src/components/deer-flow/markdown.tsx
similarity index 100%
rename from web/src/app/_components/markdown.tsx
rename to web/src/components/deer-flow/markdown.tsx
diff --git a/web/src/app/_components/rainbow-text.module.css b/web/src/components/deer-flow/rainbow-text.module.css
similarity index 100%
rename from web/src/app/_components/rainbow-text.module.css
rename to web/src/components/deer-flow/rainbow-text.module.css
diff --git a/web/src/app/_components/rainbow-text.tsx b/web/src/components/deer-flow/rainbow-text.tsx
similarity index 100%
rename from web/src/app/_components/rainbow-text.tsx
rename to web/src/components/deer-flow/rainbow-text.tsx
diff --git a/web/src/app/_components/ray.tsx b/web/src/components/deer-flow/ray.tsx
similarity index 92%
rename from web/src/app/_components/ray.tsx
rename to web/src/components/deer-flow/ray.tsx
index a478d58..26aeb00 100644
--- a/web/src/app/_components/ray.tsx
+++ b/web/src/components/deer-flow/ray.tsx
@@ -1,3 +1,6 @@
+// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+// SPDX-License-Identifier: MIT
+
export function Ray() {
return (