feat: update AGENTS.md; add instructions for website
This commit is contained in:
186
AGENTS.md
186
AGENTS.md
@@ -1,98 +1,59 @@
|
|||||||
# Instructions for coding assistants
|
# Instructions for Coding Assistants
|
||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
This is a **monorepo** with npm workspaces containing **two main packages**:
|
This is a **monorepo** with npm workspaces:
|
||||||
|
|
||||||
1. **Core Library** (`packages/page-agent/`) - Pure JavaScript/TypeScript AI agent library for browser DOM automation, published as `page-agent` on npm
|
- **Core Library** (`packages/page-agent/`) - AI agent for browser DOM automation, published as `page-agent` on npm
|
||||||
2. **Website** (`packages/website/`) - React documentation and landing page. Also as demo and test page for the core lib. private package `@page-agent/website`
|
- **Website** (`packages/website/`) - React docs and landing page. **When working on website, follow `packages/website/AGENTS.md`**
|
||||||
|
|
||||||
And other internal packages:
|
Internal packages:
|
||||||
|
|
||||||
- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model.
|
- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model
|
||||||
- **Page Controller** (`packages/page-controller/`) - DOM operations and element interactions. Independent of LLM.
|
- **Page Controller** (`packages/page-controller/`) - DOM operations, independent of LLM
|
||||||
- **UI** (`packages/ui/`) - Panel, SimulatorMask, and i18n. Decoupled from PageAgent.
|
- **UI** (`packages/ui/`) - Panel, SimulatorMask, i18n. Decoupled from PageAgent
|
||||||
|
|
||||||
## Development Commands
|
## Development Commands
|
||||||
|
|
||||||
### Core Commands
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm start # Start website dev server
|
npm start # Start website dev server
|
||||||
npm run build # Build all packages
|
npm run build # Build all packages
|
||||||
npm run build:libs # Build all libraries
|
npm run build:libs # Build all libraries
|
||||||
npm run build:website # Build the website
|
|
||||||
npm run lint # ESLint with TypeScript strict rules
|
npm run lint # ESLint with TypeScript strict rules
|
||||||
```
|
```
|
||||||
|
|
||||||
## Architecture & Critical Patterns
|
## Architecture
|
||||||
|
|
||||||
### Monorepo Structure
|
### Monorepo Structure
|
||||||
|
|
||||||
We adopt a very simple monorepo solution: ts reference + vite alias.
|
Simple monorepo solution: TypeScript references + Vite aliases. Update tsconfig and vite config when adding/removing packages.
|
||||||
|
|
||||||
You must update tsconfig and vite config if you add/remove/rename a package.
|
```
|
||||||
|
|
||||||
```bash
|
|
||||||
packages/
|
packages/
|
||||||
├── page-agent/ # npm: "page-agent" ⭐ MAIN
|
├── page-agent/ # npm: "page-agent" ⭐ MAIN
|
||||||
│ ├── src/
|
├── website/ # @page-agent/website (private)
|
||||||
│ │ ├── PageAgent.ts # Main AI agent class
|
├── llms/ # @page-agent/llms
|
||||||
│ │ └── tools/ # LLM tool definitions
|
├── page-controller/ # @page-agent/page-controller
|
||||||
│ ├── vite.config.js # Library build (ES + UMD)
|
└── ui/ # @page-agent/ui
|
||||||
│ └── package.json
|
|
||||||
├── website/ # npm: "@page-agent/website" (private) ⭐ MAIN
|
|
||||||
│ ├── src/ # Website source
|
|
||||||
│ └── index.html # Entry of vite webpage
|
|
||||||
│
|
|
||||||
│ # ...internal packages below...
|
|
||||||
│
|
|
||||||
├── llms/ # npm: "@page-agent/llms"
|
|
||||||
│ └── src/ # LLM client (reflection-before-action model)
|
|
||||||
│ ├── index.ts
|
|
||||||
│ ├── types.ts # MacroToolInput, AgentBrain, LLMConfig
|
|
||||||
│ └── OpenAI*.ts # OpenAI-compatible clients
|
|
||||||
├── page-controller/ # npm: "@page-agent/page-controller"
|
|
||||||
│ └── src/ # DOM operations
|
|
||||||
│ ├── PageController.ts
|
|
||||||
│ ├── actions.ts
|
|
||||||
│ └── dom/
|
|
||||||
└── ui/ # npm: "@page-agent/ui"
|
|
||||||
└── src/ # Panel and Mask Effects
|
|
||||||
├── Panel.ts
|
|
||||||
├── SimulatorMask.ts
|
|
||||||
└── i18n/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`workspaces` must be written in topological order to guarantee build order.
|
`workspaces` in `package.json` must be in topological order.
|
||||||
|
|
||||||
```json
|
### Module Boundaries
|
||||||
"workspaces": [
|
|
||||||
// internal deps (topological order)
|
|
||||||
"packages/page-controller",
|
|
||||||
"packages/ui",
|
|
||||||
"packages/llms",
|
|
||||||
"packages/page-agent",
|
|
||||||
"packages/website"
|
|
||||||
],
|
|
||||||
```
|
|
||||||
|
|
||||||
### Module Boundaries (Critical)
|
- **Page Agent**: Core lib. Imports from `@page-agent/llms`, `@page-agent/page-controller`, `@page-agent/ui`
|
||||||
|
- **LLMs**: LLM client with MacroToolInput contract. No dependency on page-agent
|
||||||
- **Website** (`packages/website/`): CAN import from `page-agent` for demos. Alias `@/` → `website/src/`
|
- **UI**: Panel, Mask, i18n. No dependency on page-agent
|
||||||
- **Page Agent** (`packages/page-agent/`): The core lib. Imports from `@page-agent/llms`, `@page-agent/page-controller` and `@page-agent/ui`.
|
- **Page Controller**: Pure DOM operations. No LLM or UI dependency
|
||||||
- **LLMs** (`packages/llms/`): LLM client with MacroToolInput contract. No dependency on page-agent.
|
|
||||||
- **UI** (`packages/ui/`): Panel, Mask, i18n. No dependency on page-agent.
|
|
||||||
- **Page Controller** (`packages/page-controller/`): Pure DOM operations. No LLM or UI dependency.
|
|
||||||
|
|
||||||
### PageController ↔ PageAgent Communication
|
### PageController ↔ PageAgent Communication
|
||||||
|
|
||||||
All communication between PageAgent and PageController is async and isolated:
|
All communication is async and isolated:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// PageAgent delegates DOM operations to PageController
|
// PageAgent delegates DOM operations to PageController
|
||||||
await this.pageController.updateTree() // Refresh DOM state
|
await this.pageController.updateTree()
|
||||||
await this.pageController.clickElement(index) // Click by index
|
await this.pageController.clickElement(index)
|
||||||
await this.pageController.inputText(index, text)
|
await this.pageController.inputText(index, text)
|
||||||
await this.pageController.scroll({ down: true, numPages: 1 })
|
await this.pageController.scroll({ down: true, numPages: 1 })
|
||||||
|
|
||||||
@@ -101,32 +62,22 @@ const simplifiedHTML = await this.pageController.getSimplifiedHTML()
|
|||||||
const pageInfo = await this.pageController.getPageInfo()
|
const pageInfo = await this.pageController.getPageInfo()
|
||||||
```
|
```
|
||||||
|
|
||||||
DOM element references and internal state (selectorMap, elementTextMap) are encapsulated in PageController.
|
|
||||||
|
|
||||||
### DOM Pipeline
|
### DOM Pipeline
|
||||||
|
|
||||||
1. **DOM Extraction**: Convert live DOM to `FlatDomTree` via `page-controller/src/dom/dom_tree/`
|
1. **DOM Extraction**: Live DOM → `FlatDomTree` via `page-controller/src/dom/dom_tree/`
|
||||||
2. **Dehydration**: DOM tree → simplified text for LLM processing
|
2. **Dehydration**: DOM tree → simplified text for LLM
|
||||||
3. **LLM Processing**: AI model returns action plans (in page-agent)
|
3. **LLM Processing**: AI returns action plans (page-agent)
|
||||||
4. **Indexed Operations**: PageAgent calls PageController methods by element index
|
4. **Indexed Operations**: PageAgent calls PageController by element index
|
||||||
|
|
||||||
### Hash Routing Requirement
|
### CDN Auto-Injection
|
||||||
|
|
||||||
Uses wouter with `useHashLocation` for static hosting:
|
Library auto-initializes via script tag:
|
||||||
|
|
||||||
```tsx
|
|
||||||
<Router hook={useHashLocation}> // Always hash-based routes
|
|
||||||
```
|
|
||||||
|
|
||||||
### CDN Auto-Injection Pattern
|
|
||||||
|
|
||||||
Library auto-initializes when injected via script tag:
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="page-agent.js?model=gpt-4"></script>
|
<script src="page-agent.js?model=gpt-4"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Query params configure `PageAgentConfig` automatically in `src/entry.ts`.
|
Query params configure `PageAgentConfig` in `src/umd.ts`.
|
||||||
|
|
||||||
## Key Files Reference
|
## Key Files Reference
|
||||||
|
|
||||||
@@ -134,94 +85,41 @@ Query params configure `PageAgentConfig` automatically in `src/entry.ts`.
|
|||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `src/PageAgent.ts` | ⭐ Main AI agent class orchestrating tools and LLM |
|
| `src/PageAgent.ts` | ⭐ Main AI agent class |
|
||||||
| `src/umd.ts` | CDN/UMD entry point with auto-initialization |
|
| `src/umd.ts` | CDN/UMD entry with auto-init |
|
||||||
| `src/tools/` | Tool definitions that call PageController methods |
|
| `src/tools/` | Tool definitions calling PageController |
|
||||||
| `vite.config.js` | Library build configuration (ES + UMD) |
|
|
||||||
|
|
||||||
### LLMs (`packages/llms/`)
|
### LLMs (`packages/llms/`)
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `src/index.ts` | ⭐ LLM class with retry logic |
|
| `src/index.ts` | ⭐ LLM class with retry logic |
|
||||||
| `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig definitions |
|
| `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig |
|
||||||
| `src/OpenAILenientClient.ts` | OpenAI-compatible client with lenient parsing |
|
| `src/OpenAILenientClient.ts` | OpenAI-compatible client |
|
||||||
| `src/utils.ts` | Zod-to-OpenAI conversion, model patches |
|
|
||||||
|
|
||||||
### Page Controller (`packages/page-controller/`)
|
### Page Controller (`packages/page-controller/`)
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `src/PageController.ts` | ⭐ Main controller class managing DOM state and actions |
|
| `src/PageController.ts` | ⭐ Main controller class |
|
||||||
| `src/actions.ts` | Element interaction implementations (click, input, scroll) |
|
| `src/actions.ts` | Element interactions (click, input, scroll) |
|
||||||
| `src/dom/dom_tree/index.js` | Core DOM extraction engine (ported from browser-use) |
|
| `src/dom/dom_tree/index.js` | Core DOM extraction engine |
|
||||||
| `src/dom/getPageInfo.ts` | Page scroll/size information |
|
|
||||||
| `src/patches/` | Framework-specific optimizations (React, Antd) |
|
|
||||||
| `src/types.ts` | TypeScript interfaces for controller |
|
|
||||||
|
|
||||||
### Website (`packages/website/`)
|
|
||||||
|
|
||||||
| File | Description |
|
|
||||||
|------|-------------|
|
|
||||||
| `src/router.tsx` | ⭐ Central routing (manual registration required) |
|
|
||||||
| `src/components/DocsLayout.tsx` | Navigation structure (hardcoded nav items) |
|
|
||||||
| `src/main.tsx` | Site entry with hash routing setup |
|
|
||||||
| `src/docs/[section]/[topic]/page.tsx` | Documentation pages |
|
|
||||||
| `src/test-pages/` | Library integration test pages |
|
|
||||||
| `vite.config.js` | Website build configuration |
|
|
||||||
|
|
||||||
## Adding New Features
|
## Adding New Features
|
||||||
|
|
||||||
### New Documentation Page
|
|
||||||
|
|
||||||
1. Create `packages/website/src/docs/<section>/<slug>/page.tsx`
|
|
||||||
2. Add route to `packages/website/src/router.tsx` with `<Header /> + <DocsLayout>` wrapper
|
|
||||||
3. Add navigation item to `DocsLayout.tsx`
|
|
||||||
|
|
||||||
### New Agent Tool
|
### New Agent Tool
|
||||||
|
|
||||||
1. Implement tool in `packages/page-agent/src/tools/index.ts`
|
1. Implement in `packages/page-agent/src/tools/index.ts`
|
||||||
2. If tool needs DOM operations, add method to PageController first
|
2. If tool needs DOM ops, add method to PageController first
|
||||||
3. Tool calls `this.pageController.methodName()` for DOM interactions
|
3. Tool calls `this.pageController.methodName()` for DOM interactions
|
||||||
|
|
||||||
### New PageController Action
|
### New PageController Action
|
||||||
|
|
||||||
1. Add action implementation in `packages/page-controller/src/actions.ts`
|
1. Add implementation in `packages/page-controller/src/actions.ts`
|
||||||
2. Expose via async method in `PageController.ts`
|
2. Expose via async method in `PageController.ts`
|
||||||
3. Export from `packages/page-controller/src/index.ts`
|
3. Export from `packages/page-controller/src/index.ts`
|
||||||
|
|
||||||
## Code Standards
|
## Code Standards
|
||||||
|
|
||||||
### TypeScript
|
|
||||||
|
|
||||||
- Explicit typing for exported/public APIs
|
- Explicit typing for exported/public APIs
|
||||||
- ESLint relaxes some unsafe rules for rapid iteration
|
- ESLint relaxes some unsafe rules for rapid iteration
|
||||||
|
|
||||||
### CSS & Styling
|
|
||||||
|
|
||||||
- **Prefer Tailwind CSS over custom CSS**
|
|
||||||
- Custom CSS variables for theme gradients in `src/index.css`
|
|
||||||
- Dark mode support via `dark:` classes
|
|
||||||
- CSS modules for component-specific styles
|
|
||||||
|
|
||||||
### Import Organization
|
|
||||||
|
|
||||||
- External libraries first
|
|
||||||
- Internal modules (`@/`, `@pages/`)
|
|
||||||
- Relative imports last
|
|
||||||
- Blank lines between groups
|
|
||||||
|
|
||||||
## Debugging Common Issues
|
|
||||||
|
|
||||||
### Blank Documentation Pages
|
|
||||||
|
|
||||||
1. Verify route exists in `packages/website/src/router.tsx`
|
|
||||||
2. Check component import path
|
|
||||||
3. Verify CSS isn't hiding content (check dark mode classes)
|
|
||||||
4. Test with minimal component first
|
|
||||||
|
|
||||||
### Library Integration Issues
|
|
||||||
|
|
||||||
1. Check `packages/page-agent/dist/lib/page-agent.umd.js` builds correctly
|
|
||||||
2. Test CDN injection with query params
|
|
||||||
4. Use `packages/website/src/test-pages/` for isolated testing
|
|
||||||
|
|||||||
115
packages/website/AGENTS.md
Normal file
115
packages/website/AGENTS.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# Website Package - Instructions for Coding Assistants
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- **React** with TypeScript
|
||||||
|
- **Vite** for dev server and build
|
||||||
|
- **Tailwind CSS** for styling
|
||||||
|
- **shadcn/ui** (new-york style) for UI components
|
||||||
|
- **Magic UI** for animations and effects
|
||||||
|
- **wouter** with hash routing for static hosting
|
||||||
|
- **lucide-react** for icons
|
||||||
|
|
||||||
|
## Component Guidelines
|
||||||
|
|
||||||
|
### Use shadcn/ui Components First
|
||||||
|
|
||||||
|
**ALWAYS prefer shadcn/ui components over custom implementations.**
|
||||||
|
|
||||||
|
Before creating any UI component, check if shadcn already provides it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# IMPORTANT: Run from packages/website/, NOT from repo root
|
||||||
|
cd packages/website
|
||||||
|
|
||||||
|
# Add a new shadcn component
|
||||||
|
npx shadcn@latest add <component-name>
|
||||||
|
|
||||||
|
# Add a Magic UI component
|
||||||
|
npx shadcn@latest add "@magicui/<component-name>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Available shadcn components: https://ui.shadcn.com/docs/components
|
||||||
|
Available Magic UI components: https://magicui.design/docs/components
|
||||||
|
|
||||||
|
### Current UI Components
|
||||||
|
|
||||||
|
Located in `src/components/ui/`:
|
||||||
|
|
||||||
|
**From shadcn/ui:**
|
||||||
|
- `alert`, `badge`, `button`, `separator`, `sonner`, `switch`, `tooltip`
|
||||||
|
|
||||||
|
**From Magic UI:**
|
||||||
|
- `animated-gradient-text`, `animated-shiny-text`, `aurora-text`
|
||||||
|
- `hyper-text`, `magic-card`, `neon-gradient-card`, `particles`
|
||||||
|
- `sparkles-text`, `text-animate`, `typing-animation`
|
||||||
|
|
||||||
|
**Custom:**
|
||||||
|
- `highlighter`, `kbd`, `spinner`
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── components/
|
||||||
|
│ ├── ui/ # shadcn/ui + Magic UI components
|
||||||
|
│ ├── Header.tsx # Site header
|
||||||
|
│ ├── Footer.tsx # Site footer
|
||||||
|
│ └── DocsLayout.tsx # Documentation sidebar
|
||||||
|
├── docs/ # Documentation pages
|
||||||
|
│ └── [section]/[topic]/page.tsx
|
||||||
|
├── test-pages/ # Library integration tests
|
||||||
|
├── i18n/ # Internationalization
|
||||||
|
├── router.tsx # Central routing
|
||||||
|
├── page.tsx # Homepage
|
||||||
|
└── main.tsx # App entry
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding New Pages
|
||||||
|
|
||||||
|
### Documentation Page
|
||||||
|
|
||||||
|
1. Create `src/docs/<section>/<slug>/page.tsx`
|
||||||
|
2. Add route to `src/router.tsx` with `<Header /> + <DocsLayout>` wrapper
|
||||||
|
3. Add navigation item to `DocsLayout.tsx`
|
||||||
|
|
||||||
|
### Test Page
|
||||||
|
|
||||||
|
1. Create `src/test-pages/<name>.tsx`
|
||||||
|
2. Add route to `src/test-pages/router.tsx`
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
|
||||||
|
Uses hash-based routing for static hosting:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Router } from 'wouter'
|
||||||
|
import { useHashLocation } from 'wouter/use-hash-location'
|
||||||
|
|
||||||
|
<Router hook={useHashLocation}>
|
||||||
|
{/* routes */}
|
||||||
|
</Router>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `components.json` | shadcn/ui configuration |
|
||||||
|
| `vite.config.js` | Vite build settings |
|
||||||
|
| `tsconfig.json` | TypeScript config |
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm start # Dev server (from root)
|
||||||
|
npm run build:website # Build website (from root)
|
||||||
|
```
|
||||||
|
|
||||||
Reference in New Issue
Block a user