diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md
index a771f79..a90361c 100644
--- a/frontend/CLAUDE.md
+++ b/frontend/CLAUDE.md
@@ -14,13 +14,24 @@ npm run lint # ESLint (no test suite exists yet)
## Architecture
-This is a single-page admin console for managing AI video assistants. It is a Next.js 16 app using the App Router, React 19, Tailwind CSS v4, and shadcn components backed by Radix UI primitives.
+This is an admin console for managing AI video assistants. It is a Next.js 16 app using the App Router, React 19, Tailwind CSS v4, and shadcn components backed by Radix UI primitives.
-**Navigation model** — the app has no Next.js routes beyond `/`. All "pages" are React components in `src/components/pages/` that are conditionally rendered by `AppShell` based on a `NavKey` state value. `AppShell` owns the active page and sidebar-collapsed state and threads them down as props.
+**Navigation model** — each sidebar section is a real App Router route, so refresh/deep-link lands on the same page. Route files in `src/app/` are thin server components that render the page components from `src/components/pages/`. The route map:
+
+| Route | Page |
+| --- | --- |
+| `/` | `HomePage` |
+| `/assistants` | `AssistantPage mode="list"` (助手列表) |
+| `/assistants/new` | `AssistantPage mode="choose"` (引导:取名+选构建方式,确认即 POST 建库并跳转编辑页) |
+| `/assistants/[id]` | `AssistantPage mode="edit"` (按 id 拉取并按类型回填编辑器) |
+| `/components/{models,knowledge,tools}` | 组件库三页 |
+| `/history`, `/dashboard`, `/test`, `/profile` | 其余侧栏页 |
+
+`AssistantPage` is one client component driven by a discriminated-union `mode` prop; all in-page transitions (创建/编辑/返回) navigate via `router.push` instead of local view state. There is no separate create form: the 引导 page creates the assistant immediately (blank fields + chosen name/type) and the editor always works against an existing id. 保存 stays on the editor page — the save button is enabled only when the form differs from the last-saved snapshot (`savedSnapshot` JSON diff), and the header back button returns to the list.
**Component layers:**
-- `src/app/` — Next.js entry: `layout.tsx` (fonts, theme-flash script, metadata) and `page.tsx` (renders ``)
-- `src/components/layout/` — `AppShell` (page-switching shell), `Sidebar` (collapsible nav, 252 → 76px), `Topbar` (theme toggle, notifications), `ThemeToggle`
+- `src/app/` — Next.js entry: `layout.tsx` (fonts, theme-flash script, metadata, wraps everything in `AppShell`) plus one thin `page.tsx` per route
+- `src/components/layout/` — `AppShell` (sidebar+topbar shell around route children, owns sidebar-collapsed state), `Sidebar` (collapsible nav, 252 → 76px; `Link`-based, active state from `usePathname`), `Topbar` (theme toggle, notifications), `ThemeToggle`
- `src/components/pages/` — one component per nav section; `PlaceholderPage` is a shared editorial header for unimplemented pages
- `src/components/ui/` — shadcn primitives (button, card, badge, dialog, etc.)
- `src/hooks/` — `use-mobile.ts`
diff --git a/frontend/src/app/assistants/[id]/page.tsx b/frontend/src/app/assistants/[id]/page.tsx
new file mode 100644
index 0000000..c27312b
--- /dev/null
+++ b/frontend/src/app/assistants/[id]/page.tsx
@@ -0,0 +1,10 @@
+import { AssistantPage } from "@/components/pages/AssistantPage";
+
+export default async function Page({
+ params,
+}: {
+ params: Promise<{ id: string }>;
+}) {
+ const { id } = await params;
+ return ;
+}
diff --git a/frontend/src/app/assistants/new/page.tsx b/frontend/src/app/assistants/new/page.tsx
new file mode 100644
index 0000000..5c03fe3
--- /dev/null
+++ b/frontend/src/app/assistants/new/page.tsx
@@ -0,0 +1,5 @@
+import { AssistantPage } from "@/components/pages/AssistantPage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/assistants/page.tsx b/frontend/src/app/assistants/page.tsx
new file mode 100644
index 0000000..b84c1b5
--- /dev/null
+++ b/frontend/src/app/assistants/page.tsx
@@ -0,0 +1,5 @@
+import { AssistantPage } from "@/components/pages/AssistantPage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/components/knowledge/page.tsx b/frontend/src/app/components/knowledge/page.tsx
new file mode 100644
index 0000000..b277f08
--- /dev/null
+++ b/frontend/src/app/components/knowledge/page.tsx
@@ -0,0 +1,5 @@
+import { ComponentsKnowledgePage } from "@/components/pages/ComponentsKnowledgePage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/components/models/page.tsx b/frontend/src/app/components/models/page.tsx
new file mode 100644
index 0000000..4e15a50
--- /dev/null
+++ b/frontend/src/app/components/models/page.tsx
@@ -0,0 +1,5 @@
+import { ComponentsModelsPage } from "@/components/pages/ComponentsModelsPage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/components/tools/page.tsx b/frontend/src/app/components/tools/page.tsx
new file mode 100644
index 0000000..1af9be8
--- /dev/null
+++ b/frontend/src/app/components/tools/page.tsx
@@ -0,0 +1,5 @@
+import { ComponentsToolsPage } from "@/components/pages/ComponentsToolsPage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx
new file mode 100644
index 0000000..90421bc
--- /dev/null
+++ b/frontend/src/app/dashboard/page.tsx
@@ -0,0 +1,5 @@
+import { DashboardPage } from "@/components/pages/DashboardPage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/history/page.tsx b/frontend/src/app/history/page.tsx
new file mode 100644
index 0000000..c797c18
--- /dev/null
+++ b/frontend/src/app/history/page.tsx
@@ -0,0 +1,5 @@
+import { HistoryPage } from "@/components/pages/HistoryPage";
+
+export default function Page() {
+ return ;
+}
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 4211032..f61bfff 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Geist_Mono, Inter, Cormorant_Garamond } from "next/font/google";
import "./globals.css";
import { cn } from "@/lib/utils";
+import { AppShell } from "@/components/layout/AppShell";
const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });
@@ -48,7 +49,9 @@ export default function RootLayout({
- {children}
+
+ {children}
+