docs: update extension related docs

This commit is contained in:
Simon
2026-02-12 17:19:14 +08:00
parent 11d66f42c4
commit f19b3cc2cc
9 changed files with 312 additions and 438 deletions

View File

@@ -1,11 +1,13 @@
import { siGithub } from 'simple-icons'
import { siChromewebstore, siGithub } from 'simple-icons'
import BetaNotice from '@/components/BetaNotice'
import CodeEditor from '@/components/CodeEditor'
import { useLanguage } from '@/i18n/context'
export default function ChromeExtension() {
const { isZh } = useLanguage()
const chromeWebStoreUrl =
'https://chromewebstore.google.com/detail/page-agent-ext/akldabonmimlicnjlflnapfeklbfemhj'
const githubReleasesUrl = 'https://github.com/alibaba/page-agent/releases'
return (
<div>
@@ -13,70 +15,92 @@ export default function ChromeExtension() {
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8 leading-relaxed">
{isZh
? '可选的 Chrome 扩展,解锁多页任务和第三方 API 集成。'
: 'Optional Chrome extension that unlocks multi-page tasks and third-party API integration.'}
? '可选的 Chrome 扩展。PageAgent.js 继续负责页面内自动化;扩展 API 额外提供多页面任务、浏览器级控制,以及从浏览器外部发起任务的能力。'
: 'An optional Chrome extension. PageAgent.js keeps handling in-page automation, while the extension API adds multi-page tasks, browser-level control, and tasks initiated from outside the browser.'}
</p>
<BetaNotice />
<div className="space-y-8 mt-8">
{/* Hero Section */}
<section className="p-6 bg-linear-to-r from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20 rounded-xl">
<div className="flex items-start gap-4">
<div>
<p className="text-gray-600 dark:text-gray-300">
{isZh
? '解锁多页任务!借助 Chrome 扩展Agent 可以跨标签页和页面导航,突破单页限制。'
: 'Unlock multi-page tasks! With the Chrome extension, your agent can navigate across tabs and pages, breaking the single-page limitation.'}
</p>
</div>
</div>
</section>
{/* Features */}
<section>
<h2 className="text-2xl font-bold mb-4">{isZh ? '核心特性' : 'Key Features'}</h2>
<div className="grid md:grid-cols-2 gap-4">
<div className="grid md:grid-cols-3 gap-4">
<div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
<h3 className="font-semibold mb-2">🔓 {isZh ? '多页任务' : 'Multi-Page Tasks'}</h3>
<p className="text-gray-600 dark:text-gray-300 text-sm">
{isZh
? '跨多个页面和标签页执行任务,不再限于单页操作。'
: 'Execute tasks across multiple pages and tabs. No longer limited to single-page operations.'}
? '跨多个页面和标签页连续执行任务,不再限于单页上下文。'
: 'Run tasks across multiple pages and tabs without being limited to a single page context.'}
</p>
</div>
<div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
<h3 className="font-semibold mb-2">
🔌 {isZh ? '开放第三方接口' : 'Third-Party API'}
🧭 {isZh ? '浏览器级控制' : 'Browser-Level Control'}
</h3>
<p className="text-gray-600 dark:text-gray-300 text-sm">
{isZh
? '用户授权后,你的网页、本地 Agent 或云端 Agent 都能通过扩展操作用户浏览器!'
: 'After user authorization, your webpage, local agent, or cloud agent can control the browser through the extension.'}
? '支持跨标签导航、页面切换和更完整的浏览器自动化能力。'
: 'Enable richer browser automation, including cross-tab navigation and page switching.'}
</p>
</div>
<div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
<h3 className="font-semibold mb-2">
🔌 {isZh ? '开放集成接口' : 'Open Integration API'}
</h3>
<p className="text-gray-600 dark:text-gray-300 text-sm">
{isZh
? '用户主动授权后,页面 JS、本地 Agent 或云端 Agent 可通过扩展发起多页面任务。'
: 'With explicit user authorization, page JS, local agents, or cloud agents can trigger multi-page tasks through the extension.'}
</p>
</div>
</div>
</section>
{/* Download */}
{/* Install */}
<section>
<h2 className="text-2xl font-bold mb-4">{isZh ? '下载测试版' : 'Download Beta'}</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh
? '扩展目前处于 Beta 阶段,请从 GitHub Releases 下载最新版本。'
: 'The extension is currently in beta. Download the latest version from GitHub Releases.'}
</p>
<a
href="https://github.com/alibaba/page-agent/releases"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d={siGithub.path} />
</svg>
{isZh ? '前往 GitHub Releases 下载' : 'Download from GitHub Releases'}
</a>
<h2 className="text-2xl font-bold mb-4">{isZh ? '获取扩展' : 'Get the Extension'}</h2>
<div className="flex flex-wrap gap-3">
<a
href={chromeWebStoreUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d={siChromewebstore.path} />
</svg>
{isZh ? '从 Chrome 应用商店安装' : 'Install from Chrome Web Store'}
</a>
<a
href={githubReleasesUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 px-6 py-3 bg-gray-900 hover:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 text-white font-medium rounded-lg transition-colors"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d={siGithub.path} />
</svg>
{isZh ? 'GitHub Releases更新版本' : 'GitHub Releases (faster updates)'}
</a>
</div>
</section>
{/* Relationship with PageAgent.js */}
<section>
<h2 className="text-2xl font-bold mb-4">
{isZh ? '与 PageAgent.js 的关系' : 'How It Relates to PageAgent.js'}
</h2>
<div className="p-5 bg-gray-50 dark:bg-gray-800 rounded-lg space-y-3 text-gray-600 dark:text-gray-300">
<p>
{isZh
? 'PageAgent.js 本身即可在页面内完成自动化。Chrome 扩展是可选的能力扩展。'
: 'PageAgent.js already works for in-page automation. The Chrome extension is optional, not a dependency.'}
</p>
<p>
{isZh
? '通过扩展,你可以执行多页面任务、控制浏览器,以及从浏览器外部(本地服务或云端服务)发起任务。'
: 'With the extension, you can perform multi-page tasks, browser-level control, and tasks triggered outside the browser (local or cloud services).'}
</p>
</div>
</section>
{/* Third-party Integration */}
@@ -86,32 +110,33 @@ export default function ChromeExtension() {
</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh
? '用户授权后,外部应用可以调用扩展 API 来控制浏览器。'
: 'After user authorization, external applications can call the extension API to control the browser.'}
? '通过页面 JavaScript 调用 `window.PAGE_AGENT_EXT`,你的应用可以发起跨页面任务并控制浏览器行为。'
: 'By calling `window.PAGE_AGENT_EXT` from page JavaScript, your app can trigger multi-page tasks and control browser behavior.'}
</p>
{/* Auth Flow */}
<h3 className="text-xl font-semibold mb-3">{isZh ? '授权流程' : 'Authorization Flow'}</h3>
<h3 className="text-xl font-semibold mb-3">
{isZh ? '授权与安全' : 'Authorization and Security'}
</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh
? '扩展使用基于 Token 的授权机制,扩展端和页面端必须持有匹配的 Token。'
: 'The extension uses a token-based authorization mechanism. Both extension and page must have matching tokens.'}
? '扩展权限范围较广(例如页面访问、导航、多标签控制)。若被滥用,可能危害用户隐私。为此,调用能力由 Token 保护,用户必须主动将 Token 提供给其信任的应用。'
: 'The extension has broad permissions (such as page access, navigation, and multi-tab control). If abused, it can harm user privacy. That is why access is protected by a token, and users must actively share the token only with applications they trust.'}
</p>
<CodeEditor
code={
isZh
? `// 1. 用户安装扩展并在扩展设置中配置 auth token
// 2. 你的页面读取相同的 token 并存入 localStorage
// 3. Token 匹配后,扩展会暴露 window.PAGE_AGENT_EXT 对象
? `// 1) 用户在扩展侧边栏获取 auth token
// 2) 仅在可信应用中设置该 token
// 3) token 匹配后,扩展会暴露 window.PAGE_AGENT_EXT
// ⚠️ 请在扩展弹窗中查看你的 auth token然后填入下方
// ⚠️ 不要把 token 提供给不可信页面或脚本
localStorage.setItem('PageAgentExtUserAuthToken', '<从扩展中获取的-token>')`
: `// 1. User installs extension and sets an auth token in extension settings
// 2. Your page reads the same token and stores it in localStorage
// 3. After token match, extension exposes window.PAGE_AGENT_EXT object
: `// 1) Get auth token from the extension side panel
// 2) Set it only in trusted applications
// 3) After token match, extension exposes window.PAGE_AGENT_EXT
// ⚠️ Check your extension popup for the auth token
// ⚠️ Never provide the token to untrusted pages or scripts
localStorage.setItem('PageAgentExtUserAuthToken', '<your-token-from-extension>')`
}
language="javascript"
@@ -152,13 +177,87 @@ localStorage.setItem('PageAgentExtUserAuthToken', '<your-token-from-extension>')
</div>
</section>
<h3 className="text-xl font-semibold my-3">PAGE_AGENT_EXT.execute(task, config)</h3>
{/* TypeScript Declaration */}
<h2 className="text-2xl font-bold mb-4">
{isZh ? 'TypeScript 类型声明' : 'TypeScript Declaration'}
</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh
? '使用配置执行任务。返回一个 Promise在任务完成时 resolve。config 参数包含 LLM 设置、选项和事件回调。'
: 'Execute a task with configuration. Returns a Promise that resolves when the task completes. Config includes LLM settings, options, and event callbacks.'}
? '推荐把 `execute` 的类型声明加入你的项目,获得完整类型提示。'
: 'Add this `execute` declaration to your project for full type support.'}
</p>
<CodeEditor
code={
isZh
? `import type {
AgentActivity,
AgentStatus,
ExecutionResult,
HistoricalEvent
} from '@page-agent/core'
interface ExecuteConfig {
baseURL: string // LLM API 端点
apiKey: string // API 密钥
model: string // 模型名称
includeInitialTab?: boolean
onStatusChange?: (status: AgentStatus) => void
onActivity?: (activity: AgentActivity) => void
onHistoryUpdate?: (history: HistoricalEvent[]) => void
onDispose?: () => void
}
type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
declare global {
interface Window {
PAGE_AGENT_EXT_VERSION?: string
PAGE_AGENT_EXT?: {
version: string
execute: Execute
dispose: () => void
}
}
}`
: `import type {
AgentActivity,
AgentStatus,
ExecutionResult,
HistoricalEvent
} from '@page-agent/core'
interface ExecuteConfig {
baseURL: string // LLM API endpoint
apiKey: string // API key
model: string // Model name
includeInitialTab?: boolean
onStatusChange?: (status: AgentStatus) => void
onActivity?: (activity: AgentActivity) => void
onHistoryUpdate?: (history: HistoricalEvent[]) => void
onDispose?: () => void
}
type Execute = (task: string, config: ExecuteConfig) => Promise<ExecutionResult>
declare global {
interface Window {
PAGE_AGENT_EXT_VERSION?: string
PAGE_AGENT_EXT?: {
version: string
execute: Execute
dispose: () => void
}
}
}`
}
language="typescript"
/>
<h3 className="text-xl font-semibold mt-6 mb-3">PAGE_AGENT_EXT.execute(task, config)</h3>
<CodeEditor
code={
isZh
@@ -168,7 +267,7 @@ const result = await window.PAGE_AGENT_EXT.execute(
{
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5-2',
model: 'gpt-5.2',
// includeInitialTab: false, // 设为 false 排除初始标签页
onStatusChange: status => console.log('状态变化:', status),
onActivity: activity => console.log('活动:', activity),
@@ -184,7 +283,7 @@ const result = await window.PAGE_AGENT_EXT.execute(
{
baseURL: 'https://api.openai.com/v1',
apiKey: 'your-api-key',
model: 'gpt-5-2',
model: 'gpt-5.2',
// includeInitialTab: false, // Set to false to exclude initial tab
onStatusChange: status => console.log('Status change:', status),
onActivity: activity => console.log('Activity:', activity),
@@ -217,111 +316,29 @@ window.PAGE_AGENT_EXT.dispose()`
/>
</section>
{/* ExecuteConfig */}
<section>
<h2 className="text-2xl font-bold mb-4">{isZh ? '执行配置' : 'Execute Configuration'}</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh
? 'config 参数包含 LLM 设置、选项和事件回调,用于控制任务执行行为。'
: 'The config parameter includes LLM settings, options, and event callbacks to control task execution behavior.'}
</p>
<CodeEditor
code={
isZh
? `interface ExecuteConfig {
baseURL: string // LLM API 端点
apiKey: string // API 密钥
model: string // 模型名称
// 是否将初始标签页包含在任务中,默认 true
includeInitialTab?: boolean
// Agent 状态变化时调用idle, running, error, completed 等)
onStatusChange?: (status: AgentStatus) => void
// Agent 执行活动时调用(如点击、输入、导航等操作)
onActivity?: (activity: AgentActivity) => void
// 历史记录更新时调用(包含完整的事件历史)
onHistoryUpdate?: (history: HistoricalEvent[]) => void
// Agent 被停止时调用
onDispose?: () => void
}`
: `interface ExecuteConfig {
baseURL: string // LLM API endpoint
apiKey: string // API key
model: string // Model name
// Whether to include the initial tab in the task, default true
includeInitialTab?: boolean
// Called when agent status changes (idle, running, error, completed, etc.)
onStatusChange?: (status: AgentStatus) => void
// Called when agent performs an activity (click, input, navigation, etc.)
onActivity?: (activity: AgentActivity) => void
// Called when history is updated (contains full event history)
onHistoryUpdate?: (history: HistoricalEvent[]) => void
// Called when agent is disposed
onDispose?: () => void
}`
}
language="typescript"
/>
</section>
{/* Security Notice */}
<section className="p-4 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
<h3 className="text-lg font-semibold text-yellow-900 dark:text-yellow-300 mb-2">
{isZh ? '安全须知' : 'Security Notes'}
</h3>
<ul className="text-gray-600 dark:text-gray-300 space-y-1 text-sm">
<li>
{' '}
{isZh
? '用户必须在扩展设置中显式授权每个域名'
: 'Users must explicitly authorize each domain in extension settings'}
</li>
<li>
{' '}
{isZh
? '生产环境建议使用后端代理 LLM API Key'
: 'Consider using backend proxy for LLM API keys in production'}
</li>
</ul>
</section>
{/* Integration Guide */}
<section>
<h2 className="text-2xl font-bold mb-4">
{isZh
? '将 MultiPageAgent 融入你自己的插件'
? '将 MultiPageAgent 集成你自己的插件'
: 'Integrate MultiPageAgent into Your Extension'}
</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh
? '你可以将 MultiPageAgent 集成到自己的浏览器扩展中,实现跨页面的 AI 自动化能力。'
: 'You can integrate MultiPageAgent into your own browser extension for cross-page AI automation capabilities.'}
? '建议先阅读扩展 API 文档,再参考 background entry implementation。'
: 'Start with the extension API docs, then use the background entry implementation as a reference.'}
<a
href="https://github.com/alibaba/page-agent/blob/main/packages/extension/src/entrypoints/background.ts"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d={siGithub.path} />
</svg>
packages/extension/src/entrypoints/background.ts
</a>
</p>
<p className="text-gray-600 dark:text-gray-300 mb-4">TODO</p>
<p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh ? '参考源码实现:' : 'Reference implementation:'}
</p>
<a
href="https://github.com/alibaba/page-agent/blob/main/packages/extension/src/entrypoints/background.ts"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d={siGithub.path} />
</svg>
packages/extension/src/entrypoints/background.ts
</a>
</section>
</div>
</div>