diff --git a/AGENTS.md b/AGENTS.md
index bcc9f4d..5cc25a4 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -9,6 +9,7 @@ This is a **monorepo** with npm workspaces:
Internal packages:
+- **CDN** (`packages/cdn/`) - IIFE builds for script tag usage (npm: `@page-agent/cdn`)
- **LLMs** (`packages/llms/`) - LLM client with reflection-before-action mental model
- **Page Controller** (`packages/page-controller/`) - DOM operations and visual feedback (SimulatorMask), independent of LLM
- **UI** (`packages/ui/`) - Panel and i18n. Decoupled from PageAgent
@@ -31,6 +32,7 @@ Simple monorepo solution: TypeScript references + Vite aliases. Update tsconfig
```
packages/
├── page-agent/ # npm: "page-agent" ⭐ MAIN
+├── cdn/ # npm: "@page-agent/cdn" (IIFE builds)
├── website/ # @page-agent/website (private)
├── llms/ # @page-agent/llms
├── page-controller/ # @page-agent/page-controller
@@ -69,42 +71,43 @@ const pageInfo = await this.pageController.getPageInfo()
3. **LLM Processing**: AI returns action plans (page-agent)
4. **Indexed Operations**: PageAgent calls PageController by element index
-### CDN Auto-Injection
+### CDN Builds (`packages/cdn/`)
-Library auto-initializes via script tag:
+Two IIFE builds for script tag usage:
-```html
-
-```
+| Build | File | Description |
+| ----- | -------------------- | -------------------------------- |
+| Demo | `page-agent.demo.js` | Auto-init with built-in test API |
+| Full | `page-agent.js` | Exposes `PageAgent` class only |
-Query params configure `PageAgentConfig` in `src/umd.ts`.
+Demo build supports query params (e.g., `?model=gpt-4&lang=en-US`).
## Key Files Reference
### Page Agent (`packages/page-agent/`)
-| File | Description |
-|------|-------------|
-| `src/PageAgent.ts` | ⭐ Main AI agent class |
-| `src/umd.ts` | CDN/UMD entry with auto-init |
-| `src/tools/` | Tool definitions calling PageController |
+| File | Description |
+| ------------------ | --------------------------------------- |
+| `src/PageAgent.ts` | ⭐ Main AI agent class |
+| `src/umd.ts` | CDN/UMD entry with auto-init |
+| `src/tools/` | Tool definitions calling PageController |
### LLMs (`packages/llms/`)
-| File | Description |
-|------|-------------|
-| `src/index.ts` | ⭐ LLM class with retry logic |
-| `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig |
-| `src/OpenAILenientClient.ts` | OpenAI-compatible client |
+| File | Description |
+| ---------------------------- | ------------------------------------- |
+| `src/index.ts` | ⭐ LLM class with retry logic |
+| `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig |
+| `src/OpenAILenientClient.ts` | OpenAI-compatible client |
### Page Controller (`packages/page-controller/`)
-| File | Description |
-|------|-------------|
-| `src/PageController.ts` | ⭐ Main controller class with optional mask support |
-| `src/SimulatorMask.ts` | Visual overlay blocking user interaction during automation |
-| `src/actions.ts` | Element interactions (click, input, scroll) |
-| `src/dom/dom_tree/index.js` | Core DOM extraction engine |
+| File | Description |
+| --------------------------- | ---------------------------------------------------------- |
+| `src/PageController.ts` | ⭐ Main controller class with optional mask support |
+| `src/SimulatorMask.ts` | Visual overlay blocking user interaction during automation |
+| `src/actions.ts` | Element interactions (click, input, scroll) |
+| `src/dom/dom_tree/index.js` | Core DOM extraction engine |
## Adding New Features
diff --git a/README-zh.md b/README-zh.md
index f673736..1b7a8b8 100644
--- a/README-zh.md
+++ b/README-zh.md
@@ -81,6 +81,7 @@ packages/
├── llms/ # LLM 客户端 (npm: @page-agent/llms)
├── page-controller/ # DOM 操作 & 蒙层 & 模拟鼠标 (npm: @page-agent/page-controller)
├── ui/ # 面板 & i18n (npm: @page-agent/ui)
+├── cdn/ # CDN IIFE builds (npm: @page-agent/cdn)
└── website/ # 文档站点
```
diff --git a/README.md b/README.md
index 452c068..4a982c6 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ packages/
├── llms/ # LLM client (npm: @page-agent/llms)
├── page-controller/ # DOM operations & Visual Mask (npm: @page-agent/page-controller)
├── ui/ # Panel & i18n (npm: @page-agent/ui)
+├── cdn/ # CDN IIFE builds (npm: @page-agent/cdn)
└── website/ # Demo & Documentation site
```
diff --git a/package-lock.json b/package-lock.json
index 9d0a43b..9fa8f5f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"packages/ui",
"packages/llms",
"packages/page-agent",
+ "packages/cdn",
"packages/website"
],
"devDependencies": {
@@ -1597,6 +1598,10 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/@page-agent/cdn": {
+ "resolved": "packages/cdn",
+ "link": true
+ },
"node_modules/@page-agent/llms": {
"resolved": "packages/llms",
"link": true
@@ -8140,6 +8145,14 @@
"zod": "^3.25.0 || ^4.0.0"
}
},
+ "packages/cdn": {
+ "name": "@page-agent/cdn",
+ "version": "0.0.21",
+ "license": "MIT",
+ "dependencies": {
+ "page-agent": "0.0.21"
+ }
+ },
"packages/llms": {
"name": "@page-agent/llms",
"version": "0.0.21",
@@ -8163,16 +8176,16 @@
"packages/page-controller": {
"name": "@page-agent/page-controller",
"version": "0.0.21",
- "license": "MIT"
- },
- "packages/ui": {
- "name": "@page-agent/ui",
- "version": "0.0.21",
"license": "MIT",
"dependencies": {
"ai-motion": "^0.4.8"
}
},
+ "packages/ui": {
+ "name": "@page-agent/ui",
+ "version": "0.0.21",
+ "license": "MIT"
+ },
"packages/website": {
"name": "@page-agent/website",
"version": "0.0.21",
diff --git a/package.json b/package.json
index c92a739..5947e9d 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"packages/ui",
"packages/llms",
"packages/page-agent",
+ "packages/cdn",
"packages/website"
],
"description": "AI-powered UI agent for web applications",
diff --git a/packages/cdn/package.json b/packages/cdn/package.json
new file mode 100644
index 0000000..9cbdbfe
--- /dev/null
+++ b/packages/cdn/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "@page-agent/cdn",
+ "private": false,
+ "version": "0.0.21",
+ "type": "module",
+ "files": [
+ "dist/"
+ ],
+ "description": "CDN builds for page-agent - IIFE bundles for script tag usage",
+ "author": "Simon",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/alibaba/page-agent.git"
+ },
+ "homepage": "https://alibaba.github.io/page-agent/",
+ "scripts": {
+ "build": "vite build && vite build --mode demo"
+ },
+ "dependencies": {
+ "page-agent": "0.0.21"
+ }
+}
diff --git a/packages/cdn/src/demo.js b/packages/cdn/src/demo.js
new file mode 100644
index 0000000..b46378d
--- /dev/null
+++ b/packages/cdn/src/demo.js
@@ -0,0 +1,59 @@
+// @ts-nocheck
+/**
+ * Demo CDN build for page-agent
+ * Auto-initializes with built-in demo API for testing
+ *
+ * Usage:
+ *
+ */
+import { PageAgent } from 'page-agent'
+
+// Clean up existing instances to prevent multiple injections from bookmarklet
+if (window.pageAgent) {
+ window.pageAgent.dispose()
+}
+
+// Mount to global window object
+window.PageAgent = PageAgent
+
+// Export for IIFE
+export { PageAgent }
+
+console.log('🚀 page-agent.js loaded!')
+
+const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
+const DEMO_BASE_URL = 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
+const DEMO_API_KEY = 'PAGE-AGENT-FREE-TESTING-RANDOM'
+
+// Demo warning
+console.log(
+ '%c⚠️ DEMO MODE %c\n' +
+ 'This build uses a shared testing LLM with rate limits.\n' +
+ 'For production, use page-agent.js with your own API key:\n' +
+ 'https://alibaba.github.io/page-agent/#/docs/features/models',
+ 'background: #f59e0b; color: #000; font-size: 14px; font-weight: bold; padding: 4px 8px; border-radius: 4px;',
+ 'color: #f59e0b; font-size: 12px;'
+)
+
+// in case document.x is not ready yet
+setTimeout(() => {
+ const currentScript = document.currentScript
+
+ if (currentScript) {
+ console.log('🚀 page-agent.js detected current script:', currentScript.src)
+ const url = new URL(currentScript.src)
+ const model = url.searchParams.get('model') || DEMO_MODEL
+ const baseURL = url.searchParams.get('baseURL') || DEMO_BASE_URL
+ const apiKey = url.searchParams.get('apiKey') || DEMO_API_KEY
+ const language = url.searchParams.get('lang') || 'zh-CN'
+ const config = { model, baseURL, apiKey, language }
+ window.pageAgent = new PageAgent(config)
+ } else {
+ console.log('🚀 page-agent.js no current script detected, using default demo config')
+ window.pageAgent = new PageAgent()
+ }
+
+ console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
+
+ window.pageAgent.panel.show()
+})
diff --git a/packages/cdn/src/full.js b/packages/cdn/src/full.js
new file mode 100644
index 0000000..9d0e23e
--- /dev/null
+++ b/packages/cdn/src/full.js
@@ -0,0 +1,15 @@
+// @ts-nocheck
+/**
+ * Full CDN build for page-agent
+ * Exposes PageAgent class for manual instantiation and configuration
+ *
+ * Usage:
+ *
+ *
+ */
+import { PageAgent } from 'page-agent'
+
+export { PageAgent }
diff --git a/packages/cdn/vite.config.js b/packages/cdn/vite.config.js
new file mode 100644
index 0000000..108c81c
--- /dev/null
+++ b/packages/cdn/vite.config.js
@@ -0,0 +1,42 @@
+// @ts-nocheck
+import { dirname, resolve } from 'path'
+import { fileURLToPath } from 'url'
+import { defineConfig } from 'vite'
+import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
+
+const __dirname = dirname(fileURLToPath(import.meta.url))
+
+/**
+ * CDN IIFE builds for page-agent
+ *
+ * Build targets (via --mode):
+ * - demo: page-agent.demo.js with auto-init and built-in API
+ * - full (default): page-agent.js exposes PageAgent class only
+ */
+export default defineConfig(({ mode }) => {
+ const isDemo = mode === 'demo'
+ const entry = isDemo ? resolve(__dirname, 'src/demo.js') : resolve(__dirname, 'src/full.js')
+ const fileName = isDemo ? 'page-agent.demo' : 'page-agent'
+
+ return {
+ plugins: [cssInjectedByJsPlugin({ relativeCSSInjection: true })],
+ publicDir: false,
+ esbuild: {
+ keepNames: true,
+ },
+ build: {
+ lib: {
+ entry,
+ name: 'PageAgent',
+ fileName: () => `${fileName}.js`,
+ formats: ['iife'],
+ },
+ outDir: resolve(__dirname, 'dist'),
+ emptyOutDir: !isDemo, // only empty on first build (full)
+ minify: false,
+ },
+ define: {
+ 'process.env.NODE_ENV': '"production"',
+ },
+ }
+})