{"owner":"alibaba","repo":"page-agent","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Instructions for Coding Assistants\n\n## Project Overview\n\nThis is a **monorepo** with npm workspaces:\n\n- **Page Agent** (`packages/page-agent/`) - Main entry with built-in UI Panel, published as `page-agent` on npm\n- **Extension** (`packages/extension/`) - Browser extension (WXT + React)\n- **Website** (`packages/website/`) - React docs and landing page. **When working on website, follow `packages/website/AGENTS.md`**\n\nInternal packages:\n\n- **Core** (`packages/core/`) - PageAgentCore without UI (npm: `@page-agent/core`)\n- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model\n- **Page Controller** (`packages/page-controller/`) - DOM operations and visual feedback (SimulatorMask), independent of LLM\n- **UI** (`packages/ui/`) - Panel and i18n. Decoupled from PageAgent\n\n## Development Commands\n\n```bash\nnpm start                      # Start website dev server\nnpm run build                  # Build all packages\nnpm run build:libs             # Build all libraries\nnpm run build:ext              # Build and zip the extension package\nnpm run typecheck              # Typecheck all packages\nnpm run test                   # Run unit tests across all workspaces\nnpm run lint                   # ESLint\n```\n\n## Architecture\n\n### Monorepo Structure\n\nSource-first monorepo: library `package.json` exports point to `src/*.ts` during development. At publish time, `scripts/pre-publish.js` promotes `publishConfig` fields to top-level (swapping to `dist/`), and `scripts/post-publish.js` restores the originals.\n\n```\npackages/\n├── core/                    # npm: \"@page-agent/core\" ⭐ Core agent logic (headless)\n├── page-agent/              # npm: \"page-agent\" entry class (with UI + controller + demo builds)\n├── website/                 # @page-agent/website (private)\n├── llms/                    # @page-agent/llms\n├── extension/               # Browser extension\n├── page-controller/         # @page-agent/page-controller\n└── ui/                      # @page-agent/ui\n```\n\n`workspaces` in `package.json` must be in topological order.\n\n### Module Boundaries\n\n- **Page Agent**: Main entry with UI. Extends PageAgentCore and adds Panel. Imports from `@page-agent/core`, `@page-agent/ui`\n- **Core**: PageAgentCore without UI. Imports from `@page-agent/llms`, `@page-agent/page-controller`\n- **LLMs**: LLM client with MacroToolInput contract. No dependency on page-agent\n- **UI**: Panel and i18n. Decoupled from PageAgent via PanelAgentAdapter interface\n- **Page Controller**: DOM operations with optional visual feedback (SimulatorMask). No LLM dependency. Enable mask via `enableMask: true` config\n\n### PageController ↔ PageAgent Communication\n\nAll communication is async and isolated:\n\n```typescript\n// PageAgent delegates DOM operations to PageController\nawait this.pageController.updateTree()\nawait this.pageController.clickElement(index)\nawait this.pageController.inputText(index, text)\nawait this.pageController.scroll({ down: true, numPages: 1 })\n\n// PageController exposes state via async methods\nconst simplifiedHTML = await this.pageController.getSimplifiedHTML()\nconst pageInfo = await this.pageController.getPageInfo()\n```\n\n### DOM Pipeline\n\n1. **DOM Extraction**: Live DOM → `FlatDomTree` via `page-controller/src/dom/dom_tree/`\n2. **Dehydration**: DOM tree → simplified text for LLM\n3. **LLM Processing**: AI returns action plans (page-agent)\n4. **Indexed Operations**: PageAgent calls PageController by element index\n\n## Key Files Reference\n\n### Page Agent (`packages/page-agent/`)\n\n| File               | Description                                  |\n| ------------------ | -------------------------------------------- |\n| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |\n| `src/demo.ts`      | IIFE demo entry (auto-init with demo API)    |\n\n### Core (`packages/core/`)\n\n| File                   | Description                             |\n| ---------------------- | --------------------------------------- |\n| `src/PageAgentCore.ts` | ⭐ Core agent class without UI          |\n| `src/tools/`           | Tool definitions calling PageController |\n| `src/config/`          | Configuration types and constants       |\n| `src/prompts/`         | System prompt templates                 |\n\n### LLMs (`packages/llms/`)\n\n| File                  | Description                           |\n| --------------------- | ------------------------------------- |\n| `src/index.ts`        | ⭐ LLM class with retry logic         |\n| `src/types.ts`        | MacroToolInput, AgentBrain, LLMConfig |\n| `src/OpenAIClient.ts` | OpenAI-compatible client              |\n\n### Page Controller (`packages/page-controller/`)\n\n| File                        | Description                                                |\n| --------------------------- | ---------------------------------------------------------- |\n| `src/PageController.ts`     | ⭐ Main controller class with optional mask support        |\n| `src/SimulatorMask.ts`      | Visual overlay blocking user interaction during automation |\n| `src/actions.ts`            | Element interactions (click, input, scroll)                |\n| `src/dom/dom_tree/index.js` | Core DOM extraction engine                                 |\n\n## Adding New Features\n\n### New Agent Tool\n\n1. Implement in `packages/core/src/tools/index.ts`\n2. If tool needs DOM ops, add method to PageController first\n3. Tool calls `this.pageController.methodName()` for DOM interactions\n\n### New PageController Action\n\n1. Add implementation in `packages/page-controller/src/actions.ts`\n2. Expose via async method in `PageController.ts`\n3. Export from `packages/page-controller/src/index.ts`\n\n## Testing\n\n- **Framework**: Vitest (unit tests only for now; future E2E goes to `packages/e2e/` with Playwright)\n- **Location**: co-located, `src/foo.test.ts` next to `src/foo.ts`\n- **Coverage today**: `packages/llms` only — other packages will follow incrementally\n- **Adding tests to a new package**: create `vitest.config.ts` in the package and add a `\"test\": \"vitest run\"` script. Root `npm test` and `node scripts/ci.js` pick it up through npm workspaces.\n- **Live tests** (hit real external APIs, slow/costly): name them `*.live.test.ts`, exclude them from the package's `test` script, and expose them via a `test:live` script. Root `npm run test:live` runs all of them; they never run in `npm test` or CI. Template: `packages/llms`.\n- **Template**: See @page-agent/llms\n\n```bash\nnpm test                            # all packages with a test script\nnpm test -w @page-agent/llms        # single package\ncd packages/llms && npx vitest      # watch mode in one package\n```\n\n## Code Standards\n\n- Explicit typing for exported/public APIs\n- ESLint relaxes some unsafe rules for rapid iteration\n- Every change you make should not only implement the desired functionality but also improve the quality of the codebase\n- All code and comments must be in English.\n- Do not try to hide errors or risks. They are valuable feedbacks for developers and users. Make them visible and actionable.\n- Traceability and predictability is more important than success rate.\n"},"files":{"AGENTS.md":"# Instructions for Coding Assistants\n\n## Project Overview\n\nThis is a **monorepo** with npm workspaces:\n\n- **Page Agent** (`packages/page-agent/`) - Main entry with built-in UI Panel, published as `page-agent` on npm\n- **Extension** (`packages/extension/`) - Browser extension (WXT + React)\n- **Website** (`packages/website/`) - React docs and landing page. **When working on website, follow `packages/website/AGENTS.md`**\n\nInternal packages:\n\n- **Core** (`packages/core/`) - PageAgentCore without UI (npm: `@page-agent/core`)\n- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model\n- **Page Controller** (`packages/page-controller/`) - DOM operations and visual feedback (SimulatorMask), independent of LLM\n- **UI** (`packages/ui/`) - Panel and i18n. Decoupled from PageAgent\n\n## Development Commands\n\n```bash\nnpm start                      # Start website dev server\nnpm run build                  # Build all packages\nnpm run build:libs             # Build all libraries\nnpm run build:ext              # Build and zip the extension package\nnpm run typecheck              # Typecheck all packages\nnpm run test                   # Run unit tests across all workspaces\nnpm run lint                   # ESLint\n```\n\n## Architecture\n\n### Monorepo Structure\n\nSource-first monorepo: library `package.json` exports point to `src/*.ts` during development. At publish time, `scripts/pre-publish.js` promotes `publishConfig` fields to top-level (swapping to `dist/`), and `scripts/post-publish.js` restores the originals.\n\n```\npackages/\n├── core/                    # npm: \"@page-agent/core\" ⭐ Core agent logic (headless)\n├── page-agent/              # npm: \"page-agent\" entry class (with UI + controller + demo builds)\n├── website/                 # @page-agent/website (private)\n├── llms/                    # @page-agent/llms\n├── extension/               # Browser extension\n├── page-controller/         # @page-agent/page-controller\n└── ui/                      # @page-agent/ui\n```\n\n`workspaces` in `package.json` must be in topological order.\n\n### Module Boundaries\n\n- **Page Agent**: Main entry with UI. Extends PageAgentCore and adds Panel. Imports from `@page-agent/core`, `@page-agent/ui`\n- **Core**: PageAgentCore without UI. Imports from `@page-agent/llms`, `@page-agent/page-controller`\n- **LLMs**: LLM client with MacroToolInput contract. No dependency on page-agent\n- **UI**: Panel and i18n. Decoupled from PageAgent via PanelAgentAdapter interface\n- **Page Controller**: DOM operations with optional visual feedback (SimulatorMask). No LLM dependency. Enable mask via `enableMask: true` config\n\n### PageController ↔ PageAgent Communication\n\nAll communication is async and isolated:\n\n```typescript\n// PageAgent delegates DOM operations to PageController\nawait this.pageController.updateTree()\nawait this.pageController.clickElement(index)\nawait this.pageController.inputText(index, text)\nawait this.pageController.scroll({ down: true, numPages: 1 })\n\n// PageController exposes state via async methods\nconst simplifiedHTML = await this.pageController.getSimplifiedHTML()\nconst pageInfo = await this.pageController.getPageInfo()\n```\n\n### DOM Pipeline\n\n1. **DOM Extraction**: Live DOM → `FlatDomTree` via `page-controller/src/dom/dom_tree/`\n2. **Dehydration**: DOM tree → simplified text for LLM\n3. **LLM Processing**: AI returns action plans (page-agent)\n4. **Indexed Operations**: PageAgent calls PageController by element index\n\n## Key Files Reference\n\n### Page Agent (`packages/page-agent/`)\n\n| File               | Description                                  |\n| ------------------ | -------------------------------------------- |\n| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |\n| `src/demo.ts`      | IIFE demo entry (auto-init with demo API)    |\n\n### Core (`packages/core/`)\n\n| File                   | Description                             |\n| ---------------------- | --------------------------------------- |\n| `src/PageAgentCore.ts` | ⭐ Core agent class without UI          |\n| `src/tools/`           | Tool definitions calling PageController |\n| `src/config/`          | Configuration types and constants       |\n| `src/prompts/`         | System prompt templates                 |\n\n### LLMs (`packages/llms/`)\n\n| File                  | Description                           |\n| --------------------- | ------------------------------------- |\n| `src/index.ts`        | ⭐ LLM class with retry logic         |\n| `src/types.ts`        | MacroToolInput, AgentBrain, LLMConfig |\n| `src/OpenAIClient.ts` | OpenAI-compatible client              |\n\n### Page Controller (`packages/page-controller/`)\n\n| File                        | Description                                                |\n| --------------------------- | ---------------------------------------------------------- |\n| `src/PageController.ts`     | ⭐ Main controller class with optional mask support        |\n| `src/SimulatorMask.ts`      | Visual overlay blocking user interaction during automation |\n| `src/actions.ts`            | Element interactions (click, input, scroll)                |\n| `src/dom/dom_tree/index.js` | Core DOM extraction engine                                 |\n\n## Adding New Features\n\n### New Agent Tool\n\n1. Implement in `packages/core/src/tools/index.ts`\n2. If tool needs DOM ops, add method to PageController first\n3. Tool calls `this.pageController.methodName()` for DOM interactions\n\n### New PageController Action\n\n1. Add implementation in `packages/page-controller/src/actions.ts`\n2. Expose via async method in `PageController.ts`\n3. Export from `packages/page-controller/src/index.ts`\n\n## Testing\n\n- **Framework**: Vitest (unit tests only for now; future E2E goes to `packages/e2e/` with Playwright)\n- **Location**: co-located, `src/foo.test.ts` next to `src/foo.ts`\n- **Coverage today**: `packages/llms` only — other packages will follow incrementally\n- **Adding tests to a new package**: create `vitest.config.ts` in the package and add a `\"test\": \"vitest run\"` script. Root `npm test` and `node scripts/ci.js` pick it up through npm workspaces.\n- **Live tests** (hit real external APIs, slow/costly): name them `*.live.test.ts`, exclude them from the package's `test` script, and expose them via a `test:live` script. Root `npm run test:live` runs all of them; they never run in `npm test` or CI. Template: `packages/llms`.\n- **Template**: See @page-agent/llms\n\n```bash\nnpm test                            # all packages with a test script\nnpm test -w @page-agent/llms        # single package\ncd packages/llms && npx vitest      # watch mode in one package\n```\n\n## Code Standards\n\n- Explicit typing for exported/public APIs\n- ESLint relaxes some unsafe rules for rapid iteration\n- Every change you make should not only implement the desired functionality but also improve the quality of the codebase\n- All code and comments must be in English.\n- Do not try to hide errors or risks. They are valuable feedbacks for developers and users. Make them visible and actionable.\n- Traceability and predictability is more important than success rate.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Instructions for Coding Assistants\n\n## Project Overview\n\nThis is a **monorepo** with npm workspaces:\n\n- **Page Agent** (`packages/page-agent/`) - Main entry with built-in UI Panel, published as `page-agent` on npm\n- **Extension** (`packages/extension/`) - Browser extension (WXT + React)\n- **Website** (`packages/website/`) - React docs and landing page. **When working on website, follow `packages/website/AGENTS.md`**\n\nInternal packages:\n\n- **Core** (`packages/core/`) - PageAgentCore without UI (npm: `@page-agent/core`)\n- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model\n- **Page Controller** (`packages/page-controller/`) - DOM operations and visual feedback (SimulatorMask), independent of LLM\n- **UI** (`packages/ui/`) - Panel and i18n. Decoupled from PageAgent\n\n## Development Commands\n\n```bash\nnpm start                      # Start website dev server\nnpm run build                  # Build all packages\nnpm run build:libs             # Build all libraries\nnpm run build:ext              # Build and zip the extension package\nnpm run typecheck              # Typecheck all packages\nnpm run test                   # Run unit tests across all workspaces\nnpm run lint                   # ESLint\n```\n\n## Architecture\n\n### Monorepo Structure\n\nSource-first monorepo: library `package.json` exports point to `src/*.ts` during development. At publish time, `scripts/pre-publish.js` promotes `publishConfig` fields to top-level (swapping to `dist/`), and `scripts/post-publish.js` restores the originals.\n\n```\npackages/\n├── core/                    # npm: \"@page-agent/core\" ⭐ Core agent logic (headless)\n├── page-agent/              # npm: \"page-agent\" entry class (with UI + controller + demo builds)\n├── website/                 # @page-agent/website (private)\n├── llms/                    # @page-agent/llms\n├── extension/               # Browser extension\n├── page-controller/         # @page-agent/page-controller\n└── ui/                      # @page-agent/ui\n```\n\n`workspaces` in `package.json` must be in topological order.\n\n### Module Boundaries\n\n- **Page Agent**: Main entry with UI. Extends PageAgentCore and adds Panel. Imports from `@page-agent/core`, `@page-agent/ui`\n- **Core**: PageAgentCore without UI. Imports from `@page-agent/llms`, `@page-agent/page-controller`\n- **LLMs**: LLM client with MacroToolInput contract. No dependency on page-agent\n- **UI**: Panel and i18n. Decoupled from PageAgent via PanelAgentAdapter interface\n- **Page Controller**: DOM operations with optional visual feedback (SimulatorMask). No LLM dependency. Enable mask via `enableMask: true` config\n\n### PageController ↔ PageAgent Communication\n\nAll communication is async and isolated:\n\n```typescript\n// PageAgent delegates DOM operations to PageController\nawait this.pageController.updateTree()\nawait this.pageController.clickElement(index)\nawait this.pageController.inputText(index, text)\nawait this.pageController.scroll({ down: true, numPages: 1 })\n\n// PageController exposes state via async methods\nconst simplifiedHTML = await this.pageController.getSimplifiedHTML()\nconst pageInfo = await this.pageController.getPageInfo()\n```\n\n### DOM Pipeline\n\n1. **DOM Extraction**: Live DOM → `FlatDomTree` via `page-controller/src/dom/dom_tree/`\n2. **Dehydration**: DOM tree → simplified text for LLM\n3. **LLM Processing**: AI returns action plans (page-agent)\n4. **Indexed Operations**: PageAgent calls PageController by element index\n\n## Key Files Reference\n\n### Page Agent (`packages/page-agent/`)\n\n| File               | Description                                  |\n| ------------------ | -------------------------------------------- |\n| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |\n| `src/demo.ts`      | IIFE demo entry (auto-init with demo API)    |\n\n### Core (`packages/core/`)\n\n| File                   | Description                             |\n| ---------------------- | --------------------------------------- |\n| `src/PageAgentCore.ts` | ⭐ Core agent class without UI          |\n| `src/tools/`           | Tool definitions calling PageController |\n| `src/config/`          | Configuration types and constants       |\n| `src/prompts/`         | System prompt templates                 |\n\n### LLMs (`packages/llms/`)\n\n| File                  | Description                           |\n| --------------------- | ------------------------------------- |\n| `src/index.ts`        | ⭐ LLM class with retry logic         |\n| `src/types.ts`        | MacroToolInput, AgentBrain, LLMConfig |\n| `src/OpenAIClient.ts` | OpenAI-compatible client              |\n\n### Page Controller (`packages/page-controller/`)\n\n| File                        | Description                                                |\n| --------------------------- | ---------------------------------------------------------- |\n| `src/PageController.ts`     | ⭐ Main controller class with optional mask support        |\n| `src/SimulatorMask.ts`      | Visual overlay blocking user interaction during automation |\n| `src/actions.ts`            | Element interactions (click, input, scroll)                |\n| `src/dom/dom_tree/index.js` | Core DOM extraction engine                                 |\n\n## Adding New Features\n\n### New Agent Tool\n\n1. Implement in `packages/core/src/tools/index.ts`\n2. If tool needs DOM ops, add method to PageController first\n3. Tool calls `this.pageController.methodName()` for DOM interactions\n\n### New PageController Action\n\n1. Add implementation in `packages/page-controller/src/actions.ts`\n2. Expose via async method in `PageController.ts`\n3. Export from `packages/page-controller/src/index.ts`\n\n## Testing\n\n- **Framework**: Vitest (unit tests only for now; future E2E goes to `packages/e2e/` with Playwright)\n- **Location**: co-located, `src/foo.test.ts` next to `src/foo.ts`\n- **Coverage today**: `packages/llms` only — other packages will follow incrementally\n- **Adding tests to a new package**: create `vitest.config.ts` in the package and add a `\"test\": \"vitest run\"` script. Root `npm test` and `node scripts/ci.js` pick it up through npm workspaces.\n- **Live tests** (hit real external APIs, slow/costly): name them `*.live.test.ts`, exclude them from the package's `test` script, and expose them via a `test:live` script. Root `npm run test:live` runs all of them; they never run in `npm test` or CI. Template: `packages/llms`.\n- **Template**: See @page-agent/llms\n\n```bash\nnpm test                            # all packages with a test script\nnpm test -w @page-agent/llms        # single package\ncd packages/llms && npx vitest      # watch mode in one package\n```\n\n## Code Standards\n\n- Explicit typing for exported/public APIs\n- ESLint relaxes some unsafe rules for rapid iteration\n- Every change you make should not only implement the desired functionality but also improve the quality of the codebase\n- All code and comments must be in English.\n- Do not try to hide errors or risks. They are valuable feedbacks for developers and users. Make them visible and actionable.\n- Traceability and predictability is more important than success rate.\n","category":"root","tokens":1778}]}