diff --git a/README.md b/README.md index 2a4104e..2b5c51a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The GUI Agent Living in Your Webpage. Control web interfaces with natural langua 🌐 **English** | [中文](./docs/README-zh.md) -👉 🚀 Demo | 📖 Documentation +👉 🚀 Demo | 📖 Documentation @@ -28,14 +28,14 @@ The GUI Agent Living in Your Webpage. Control web interfaces with natural langua - No special permissions required. - **🧠 Bring your own LLMs** - **🎨 Pretty UI with human-in-the-loop** -- **🐙 Optional [chrome extension](https://alibaba.github.io/page-agent/#/docs/features/chrome-extension) for multi-page tasks.** +- **🐙 Optional [chrome extension](https://alibaba.github.io/page-agent/docs/features/chrome-extension) for multi-page tasks.** ## 💡 Use Cases - **SaaS AI Copilot** — Ship an AI copilot in your product in lines of code. No backend rewrite needed. - **Smart Form Filling** — Turn 20-click workflows into one sentence. Perfect for ERP, CRM, and admin systems. - **Accessibility** — Make any web app accessible through natural language. Voice commands, screen readers, zero barrier. -- **Multi-page Agent** — Extend your agent's reach across browser tabs with the optional [chrome extension](https://alibaba.github.io/page-agent/#/docs/features/chrome-extension). +- **Multi-page Agent** — Extend your agent's reach across browser tabs with the optional [chrome extension](https://alibaba.github.io/page-agent/docs/features/chrome-extension). ## 🚀 Quick Start @@ -73,7 +73,7 @@ const agent = new PageAgent({ await agent.execute('Click the login button') ``` -For more programmatic usage, see [📖 Documentations](https://alibaba.github.io/page-agent/#/docs/introduction/overview). +For more programmatic usage, see [📖 Documentations](https://alibaba.github.io/page-agent/docs/introduction/overview). ## 🤝 Contributing diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2223623..e4b16de 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -146,7 +146,7 @@ interface PageAgentConfig { - Single-page application only (cannot navigate across pages) - No visual recognition (relies on DOM structure) - Limited interaction support (no hover, drag-drop, canvas operations) -- See [Limitations](https://alibaba.github.io/page-agent/#/docs/introduction/limitations) for details +- See [Limitations](https://alibaba.github.io/page-agent/docs/introduction/limitations) for details ### Acknowledgments diff --git a/docs/README-zh.md b/docs/README-zh.md index e69d912..c2bef39 100644 --- a/docs/README-zh.md +++ b/docs/README-zh.md @@ -11,7 +11,7 @@ 🌐 [English](../README.md) | **中文** -👉 🚀 Demo | 📖 Documentation +👉 🚀 Demo | 📖 Documentation @@ -28,14 +28,14 @@ - 无需特殊权限。 - **🧠 用你自己的 LLM** - **🎨 精美 UI,支持人机协同** -- **🐙 可选的 [Chrome 扩展](https://alibaba.github.io/page-agent/#/docs/features/chrome-extension),支持跨页面任务。** +- **🐙 可选的 [Chrome 扩展](https://alibaba.github.io/page-agent/docs/features/chrome-extension),支持跨页面任务。** ## 💡 应用场景 - **SaaS AI 副驾驶** — 几行代码为你的产品加上 AI 副驾驶,不需要重写后端。 - **智能表单填写** — 把 20 次点击变成一句话。ERP、CRM、管理后台的最佳拍档。 - **无障碍增强** — 用自然语言让任何网页无障碍。语音指令、屏幕阅读器,零门槛。 -- **跨页面 Agent** — 通过可选的 [Chrome 扩展](https://alibaba.github.io/page-agent/#/docs/features/chrome-extension),让你的 Agent 跨标签页工作。 +- **跨页面 Agent** — 通过可选的 [Chrome 扩展](https://alibaba.github.io/page-agent/docs/features/chrome-extension),让你的 Agent 跨标签页工作。 ## 🚀 快速开始 @@ -73,7 +73,7 @@ const agent = new PageAgent({ await agent.execute('点击登录按钮') ``` -更多编程用法,请参阅 [📖 文档](https://alibaba.github.io/page-agent/#/docs/introduction/overview)。 +更多编程用法,请参阅 [📖 文档](https://alibaba.github.io/page-agent/docs/introduction/overview)。 ## 🤝 贡献 diff --git a/packages/extension/src/entrypoints/sidepanel/components/misc.tsx b/packages/extension/src/entrypoints/sidepanel/components/misc.tsx index 4650cc3..fce2085 100644 --- a/packages/extension/src/entrypoints/sidepanel/components/misc.tsx +++ b/packages/extension/src/entrypoints/sidepanel/components/misc.tsx @@ -125,7 +125,7 @@ export function EmptyState() { { if (!config.baseURL || !config.apiKey || !config.model) { throw new Error( '[PageAgent] LLM configuration required. Please provide: baseURL, apiKey, model. ' + - 'See: https://alibaba.github.io/page-agent/#/docs/features/models' + 'See: https://alibaba.github.io/page-agent/docs/features/models' ) } diff --git a/packages/website/AGENTS.md b/packages/website/AGENTS.md index c05eece..1a2290d 100644 --- a/packages/website/AGENTS.md +++ b/packages/website/AGENTS.md @@ -5,9 +5,9 @@ - **React** with TypeScript - **Vite** for dev server and build - **Tailwind CSS** for styling -- **shadcn/ui** (new-york style) for UI components +- **shadcn/ui** (new-york style) for UI components — **do NOT hand-edit `src/components/ui/` files** - **Magic UI** for animations and effects -- **wouter** with hash routing for static hosting +- **wouter** with browser routing (`base: "/page-agent"`) - **lucide-react** for icons ## Component Guidelines @@ -53,58 +53,74 @@ Located in `src/components/ui/`: ### Styling Rules 1. **Prefer Tailwind classes** over custom CSS -2. Use CSS modules only for complex component-specific styles -3. Support dark mode via `dark:` classes -4. Use CSS variables from `src/index.css` for theme colors +2. Support dark mode via `dark:` classes +3. Use CSS variables from `src/index.css` for theme colors ## Project Structure ``` src/ ├── pages/ -│ ├── Home.tsx # Homepage +│ ├── home/ +│ │ ├── HomeContent.tsx # Homepage sections +│ │ └── ...Section.tsx │ └── docs/ -│ ├── Layout.tsx # Documentation sidebar +│ ├── index.tsx # Docs route switch +│ ├── Layout.tsx # Sidebar navigation │ └── [section]/[topic]/page.tsx ├── components/ -│ ├── ui/ # shadcn/ui + Magic UI components +│ ├── ui/ # shadcn/ui + Magic UI (DO NOT hand-edit) +│ ├── Heading.tsx # Anchor heading for doc pages │ ├── Header.tsx # Site header │ └── Footer.tsx # Site footer ├── i18n/ # Internationalization -├── router.tsx # Central routing +├── router.tsx # Root layout + routing └── main.tsx # App entry ``` +## Routing + +Uses wouter browser routing with base path for GitHub Pages deployment at `https://alibaba.github.io/page-agent/`. + +```tsx +// main.tsx + + + +``` + +**Key rules:** + +- Header and Footer live in `router.tsx` **outside** ``, so they always see the root router context (`base="/page-agent"`) +- Docs pages are nested via ``, which creates a child context (`base="/page-agent/docs"`) +- Inside the docs nest, Link hrefs are relative to `/docs` (e.g. `href="/features/models"`, NOT `href="/docs/features/models"`) +- **Never use `~` prefix** in Link hrefs — it bypasses the base path entirely +- Doc page headings use `` for anchor links + +### SPA on GitHub Pages + +Instead of `404.html` redirects, the build copies `index.html` into every route directory. Add new routes to the `SPA_ROUTES` array in `vite.config.js`. + ## Adding New Pages ### Documentation Page 1. Create `src/pages/docs/
//page.tsx` -2. Add route to `src/router.tsx` with `
+ ` wrapper -3. Add navigation item to `pages/docs/Layout.tsx` - -## Routing - -Uses hash-based routing for static hosting: - -```tsx -import { Router } from 'wouter' -import { useHashLocation } from 'wouter/use-hash-location' - -;{/* routes */} -``` +2. Add route in `src/pages/docs/index.tsx` +3. Add navigation item in `src/pages/docs/Layout.tsx` +4. Add path to `SPA_ROUTES` in `vite.config.js` ## Configuration Files | File | Purpose | | ----------------- | ----------------------- | | `components.json` | shadcn/ui configuration | -| `vite.config.js` | Vite build settings | +| `vite.config.js` | Vite build + SPA routes | | `tsconfig.json` | TypeScript config | ## Commands ```bash -npm start # Dev server (from root) +npm start # Dev server (from root) npm run build:website # Build website (from root) ``` diff --git a/packages/website/src/components/Header.tsx b/packages/website/src/components/Header.tsx index 3d9fe31..f8e8a91 100644 --- a/packages/website/src/components/Header.tsx +++ b/packages/website/src/components/Header.tsx @@ -23,7 +23,7 @@ export default function Header() {
{/* Logo */} setMobileMenuOpen(false)} @@ -56,7 +56,7 @@ export default function Header() { aria-label="Mobile navigation" > @@ -90,7 +90,7 @@ export default function Header() { {import.meta.env.VERSION} @@ -138,7 +138,7 @@ export default function Header() { role="navigation" > setMobileMenuOpen(false)} > diff --git a/packages/website/src/components/Heading.tsx b/packages/website/src/components/Heading.tsx new file mode 100644 index 0000000..29b0e91 --- /dev/null +++ b/packages/website/src/components/Heading.tsx @@ -0,0 +1,45 @@ +import { ComponentPropsWithoutRef, useEffect, useRef } from 'react' + +import { cn } from '@/lib/utils' + +type Level = 2 | 3 + +interface HeadingProps extends Omit, 'children'> { + id: string + level?: Level + children: React.ReactNode +} + +const levelStyles = { + 2: { tag: 'h2', className: 'text-2xl font-semibold mb-4' }, + 3: { tag: 'h3', className: 'text-xl font-semibold mb-3' }, +} as const + +export function Heading({ id, level = 2, className, children, ...props }: HeadingProps) { + const ref = useRef(null) + const { tag: Tag, className: defaultClassName } = levelStyles[level] + + useEffect(() => { + if (window.location.hash === `#${id}`) { + ref.current?.scrollIntoView({ behavior: 'smooth' }) + } + }, [id]) + + return ( + + + # + + {children} + + ) +} diff --git a/packages/website/src/components/ui/magic-card.tsx b/packages/website/src/components/ui/magic-card.tsx index b44dcf8..d040937 100644 --- a/packages/website/src/components/ui/magic-card.tsx +++ b/packages/website/src/components/ui/magic-card.tsx @@ -85,7 +85,7 @@ export function MagicCard({ `, }} /> -
+
1 && hash.includes('/')) { + const path = hash.replace(/^#\/?/, '/') + history.replaceState(null, '', '/page-agent' + path) +} + createRoot(document.getElementById('root')!).render( - + diff --git a/packages/website/src/pages/Home.tsx b/packages/website/src/pages/Home.tsx index b76ad17..c1741f3 100644 --- a/packages/website/src/pages/Home.tsx +++ b/packages/website/src/pages/Home.tsx @@ -1,5 +1,3 @@ -import Footer from '../components/Footer' -import Header from '../components/Header' import FeaturesSection from './home/FeaturesSection' import HeroSection from './home/HeroSection' import OneMoreThingSection from './home/OneMoreThingSection' @@ -7,17 +5,11 @@ import ScenariosSection from './home/ScenariosSection' export default function HomePage() { return ( -
-
- -
- - - - -
- -
-
+ <> + + + + + ) } diff --git a/packages/website/src/pages/docs/advanced/custom-ui/page.tsx b/packages/website/src/pages/docs/advanced/custom-ui/page.tsx index 1624bc3..dc0381a 100644 --- a/packages/website/src/pages/docs/advanced/custom-ui/page.tsx +++ b/packages/website/src/pages/docs/advanced/custom-ui/page.tsx @@ -1,4 +1,5 @@ import CodeEditor from '@/components/CodeEditor' +import { Heading } from '@/components/Heading' import { APIDivider, APIReference } from '@/components/ui/api-reference' import { useLanguage } from '@/i18n/context' @@ -17,7 +18,7 @@ export default function CustomUIDocs() { {/* Architecture */}
-

{isZh ? '架构' : 'Architecture'}

+ {isZh ? '架构' : 'Architecture'}

{isZh ? 'PageAgent 由三个独立模块组成,可自由组合:' @@ -45,7 +46,7 @@ export default function CustomUIDocs() { {/* Two Event Streams */}

-

{isZh ? '两个事件流' : 'Two Event Streams'}

+ {isZh ? '两个事件流' : 'Two Event Streams'}

{isZh ? 'PageAgentCore 提供两种不同性质的事件流,方便 UI 渲染:' @@ -120,7 +121,7 @@ export default function CustomUIDocs() { {/* All Events */}

-

{isZh ? '所有事件' : 'All Events'}

+ {isZh ? '所有事件' : 'All Events'} -

HistoricalEvent

+ HistoricalEvent

{isZh ? 'agent.history 数组中的事件类型:' : 'Event types in agent.history array:'}

@@ -172,7 +173,7 @@ export default function CustomUIDocs() { {/* AgentActivity Types */}
-

AgentActivity

+ AgentActivity

{isZh ? 'activity 事件的 detail 类型:' : 'The detail type of activity events:'}

@@ -191,9 +192,7 @@ export default function CustomUIDocs() { {/* React Hooks Example */}
-

- {isZh ? '使用 React Hooks' : 'Using React Hooks'} -

+ {isZh ? '使用 React Hooks' : 'Using React Hooks'}

{isZh ? '监听事件并更新 React 状态:' : 'Listen to events and update React state:'}

@@ -229,9 +228,9 @@ export default function CustomUIDocs() { {/* Assembly Example */}
-

+ {isZh ? '组装 Core + Controller + 自定义 UI' : 'Assembling Core + Controller + Custom UI'} -

+

{isZh ? '参考内置 PageAgent 的实现方式,用自定义 UI 替换 Panel:' diff --git a/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx b/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx index e9a8961..9476041 100644 --- a/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx +++ b/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx @@ -1,4 +1,5 @@ import CodeEditor from '@/components/CodeEditor' +import { Heading } from '@/components/Heading' import { APIDivider, APIReference, TypeRef } from '@/components/ui/api-reference' import { useLanguage } from '@/i18n/context' @@ -17,9 +18,9 @@ export default function PageAgentCoreDocs() { {/* When to use */}

-

+ {isZh ? '何时使用 PageAgentCore' : 'When to Use PageAgentCore'} -

+