Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6cbb4e99c4 | |||
| 34ce56b446 | |||
| 23ec4602c2 | |||
| 536e5076da | |||
| 81807e17ca | |||
| 6944bedf85 | |||
| 897b919044 | |||
| 3a3bb0e58c | |||
| bc7ccf47ff | |||
| c781eba986 | |||
| efe131660a | |||
| 22516dec74 | |||
| 1f8953c450 | |||
| d6a57f3e20 | |||
| e0027f99c4 | |||
| b234868bc1 | |||
| 10ae34a677 | |||
| 2fb01b7315 | |||
| 5c80f2b002 | |||
| 28c128645e | |||
| 250cb47e44 | |||
| f83a4174cc | |||
| 334512210d | |||
| 3df71788ff | |||
| 60450ea7be | |||
| 80c93bd668 |
+6
-2
@@ -25,11 +25,15 @@ dist-ssr
|
|||||||
*.sw?
|
*.sw?
|
||||||
.qoder
|
.qoder
|
||||||
|
|
||||||
|
# env files
|
||||||
#
|
|
||||||
.env
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
# Copied files for npm publish (generated by prepublishOnly)
|
# Copied files for npm publish (generated by prepublishOnly)
|
||||||
packages/page-agent/README.md
|
packages/page-agent/README.md
|
||||||
packages/page-agent/README-zh.md
|
packages/page-agent/README-zh.md
|
||||||
packages/page-agent/LICENSE
|
packages/page-agent/LICENSE
|
||||||
|
|
||||||
|
# extension
|
||||||
|
.output
|
||||||
|
.wxt
|
||||||
Vendored
+1
@@ -6,6 +6,7 @@
|
|||||||
"HITL",
|
"HITL",
|
||||||
"innerhtml",
|
"innerhtml",
|
||||||
"llms",
|
"llms",
|
||||||
|
"npmmirror",
|
||||||
"onwarn",
|
"onwarn",
|
||||||
"opensource",
|
"opensource",
|
||||||
"qwen",
|
"qwen",
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ Simple monorepo solution: TypeScript references + Vite aliases. Update tsconfig
|
|||||||
|
|
||||||
```
|
```
|
||||||
packages/
|
packages/
|
||||||
├── page-agent/ # npm: "page-agent" ⭐ MAIN (with Panel UI + IIFE builds)
|
├── core/ # npm: "@page-agent/core" ⭐ Core agent logic (headless)
|
||||||
├── core/ # npm: "@page-agent/core" (headless, no UI)
|
├── page-agent/ # npm: "page-agent" entry class (with UI + controller + demo builds)
|
||||||
├── website/ # @page-agent/website (private)
|
├── website/ # @page-agent/website (private)
|
||||||
├── llms/ # @page-agent/llms
|
├── llms/ # @page-agent/llms
|
||||||
├── page-controller/ # @page-agent/page-controller
|
├── page-controller/ # @page-agent/page-controller
|
||||||
@@ -72,33 +72,19 @@ const pageInfo = await this.pageController.getPageInfo()
|
|||||||
3. **LLM Processing**: AI returns action plans (page-agent)
|
3. **LLM Processing**: AI returns action plans (page-agent)
|
||||||
4. **Indexed Operations**: PageAgent calls PageController by element index
|
4. **Indexed Operations**: PageAgent calls PageController by element index
|
||||||
|
|
||||||
### IIFE Builds (`packages/page-agent/dist/iife/`)
|
|
||||||
|
|
||||||
Two IIFE builds for script tag usage:
|
|
||||||
|
|
||||||
| Build | File | Description |
|
|
||||||
| ----- | -------------------- | -------------------------------- |
|
|
||||||
| Demo | `page-agent.demo.js` | Auto-init with built-in test API |
|
|
||||||
| Full | `page-agent.js` | Exposes `PageAgent` class only |
|
|
||||||
|
|
||||||
Demo build supports query params (e.g., `?model=gpt-4&lang=en-US`).
|
|
||||||
|
|
||||||
Build with `npm run build:iife --workspace=page-agent`.
|
|
||||||
|
|
||||||
## Key Files Reference
|
## Key Files Reference
|
||||||
|
|
||||||
### Page Agent (`packages/page-agent/`)
|
### Page Agent (`packages/page-agent/`)
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
| ----------------------- | -------------------------------------------- |
|
| ------------------ | -------------------------------------------- |
|
||||||
| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |
|
| `src/PageAgent.ts` | ⭐ Main class with UI, extends PageAgentCore |
|
||||||
| `src/entry-iife.ts` | IIFE entry (exposes PageAgent class) |
|
| `src/demo.ts` | IIFE demo entry (auto-init with demo API) |
|
||||||
| `src/entry-iife-demo.ts`| IIFE demo entry (auto-init with demo API) |
|
|
||||||
|
|
||||||
### Core (`packages/core/`)
|
### Core (`packages/core/`)
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
| ----------------------- | ------------------------------------------- |
|
| ---------------------- | --------------------------------------- |
|
||||||
| `src/PageAgentCore.ts` | ⭐ Core agent class without UI |
|
| `src/PageAgentCore.ts` | ⭐ Core agent class without UI |
|
||||||
| `src/tools/` | Tool definitions calling PageController |
|
| `src/tools/` | Tool definitions calling PageController |
|
||||||
| `src/config/` | Configuration types and constants |
|
| `src/config/` | Configuration types and constants |
|
||||||
@@ -107,10 +93,10 @@ Build with `npm run build:iife --workspace=page-agent`.
|
|||||||
### 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 |
|
| `src/types.ts` | MacroToolInput, AgentBrain, LLMConfig |
|
||||||
| `src/OpenAILenientClient.ts` | OpenAI-compatible client |
|
| `src/OpenAIClient.ts` | OpenAI-compatible client |
|
||||||
|
|
||||||
### Page Controller (`packages/page-controller/`)
|
### Page Controller (`packages/page-controller/`)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.0.0] - 2026-01-19
|
||||||
|
|
||||||
|
### 🎉 First Stable Release
|
||||||
|
|
||||||
|
PageAgent is now ready for production use. The API is stable and breaking changes will follow semantic versioning.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- **PageAgent** - Main entry class with built-in UI Panel
|
||||||
|
- **PageAgentCore** - Headless agent class for custom UI or programmatic use
|
||||||
|
- **DOM Analysis** - Text-based DOM extraction with high-intensity dehydration
|
||||||
|
- **LLM Support** - Works with OpenAI, Claude, DeepSeek, Qwen, and other OpenAI-compatible APIs
|
||||||
|
- **Tool System** - Built-in tools for click, input, scroll, select, and more
|
||||||
|
- **Custom Tools** - Extend agent capabilities with your own tools (experimental)
|
||||||
|
- **Lifecycle Hooks** - Hook into agent execution (experimental)
|
||||||
|
- **Instructions System** - System-level and page-level instructions to guide agent behavior
|
||||||
|
- **Data Masking** - Transform page content before sending to LLM
|
||||||
|
|
||||||
|
#### Page Controller
|
||||||
|
|
||||||
|
- **Element Interactions** - Click, input text, select options, scroll
|
||||||
|
- **Visual Mask** - Blocks user interaction during automation
|
||||||
|
- **DOM Tree Extraction** - Efficient page structure extraction for LLM consumption
|
||||||
|
|
||||||
|
#### UI
|
||||||
|
|
||||||
|
- **Interactive Panel** - Real-time task progress and agent thinking display
|
||||||
|
- **Ask User Tool** - Agent can ask users for clarification
|
||||||
|
- **i18n Support** - English and Chinese localization
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface PageAgentConfig {
|
||||||
|
// LLM Configuration (required)
|
||||||
|
baseURL: string
|
||||||
|
apiKey: string
|
||||||
|
model: string
|
||||||
|
temperature?: number
|
||||||
|
maxRetries?: number
|
||||||
|
customFetch?: typeof fetch
|
||||||
|
|
||||||
|
// Agent Configuration
|
||||||
|
language?: 'en-US' | 'zh-CN'
|
||||||
|
maxSteps?: number // default: 20
|
||||||
|
customTools?: Record<string, PageAgentTool> // experimental
|
||||||
|
instructions?: InstructionsConfig
|
||||||
|
transformPageContent?: (content: string) => string | Promise<string>
|
||||||
|
experimentalScriptExecutionTool?: boolean // default: false
|
||||||
|
|
||||||
|
// Lifecycle Hooks (experimental)
|
||||||
|
onBeforeTask?: (agent, result) => void
|
||||||
|
onAfterTask?: (agent, result) => void
|
||||||
|
onBeforeStep?: (agent, stepCount) => void
|
||||||
|
onAfterStep?: (agent, history) => void
|
||||||
|
onDispose?: (agent, reason?) => void
|
||||||
|
|
||||||
|
// Page Controller Configuration
|
||||||
|
enableMask?: boolean // default: true
|
||||||
|
viewportExpansion?: number
|
||||||
|
interactiveBlacklist?: Element[]
|
||||||
|
interactiveWhitelist?: Element[]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Packages
|
||||||
|
|
||||||
|
| Package | Description |
|
||||||
|
| ----------------------------- | ---------------------------------- |
|
||||||
|
| `page-agent` | Main entry with UI Panel |
|
||||||
|
| `@page-agent/core` | Core agent logic without UI |
|
||||||
|
| `@page-agent/llms` | LLM client with retry logic |
|
||||||
|
| `@page-agent/page-controller` | DOM operations and visual feedback |
|
||||||
|
| `@page-agent/ui` | Panel and i18n |
|
||||||
|
|
||||||
|
### Known Limitations
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
### Acknowledgments
|
||||||
|
|
||||||
|
This project builds upon the excellent work of [browser-use](https://github.com/browser-use/browser-use). DOM processing components and prompts are adapted from browser-use (MIT License).
|
||||||
+2
-2
@@ -69,10 +69,10 @@ members of the project's leadership.
|
|||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][https://www.contributor-covenant.org], version 1.4,
|
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
|
||||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
----
|
---
|
||||||
|
|
||||||
> Chinese Version
|
> Chinese Version
|
||||||
> 《阿里巴巴开源行为准则》
|
> 《阿里巴巴开源行为准则》
|
||||||
|
|||||||
+2
-2
@@ -122,13 +122,13 @@ npm start
|
|||||||
- Start and serve a local `iife` script
|
- Start and serve a local `iife` script
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev:iife # Serving IIFE with auto rebuild at http://localhost:5174/page-agent.js
|
npm run dev:demo # Serving IIFE with auto rebuild at http://localhost:5174/page-agent.demo.js
|
||||||
```
|
```
|
||||||
|
|
||||||
- Add a new bookmark
|
- Add a new bookmark
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
javascript:(function(){var s=document.createElement('script');s.src=`http://localhost:5174/page-agent.js?t=${Math.random()}`;s.onload=()=>console.log(%27PageAgent ready!%27);document.head.appendChild(s);})();
|
javascript:(function(){var s=document.createElement('script');s.src=`http://localhost:5174/page-agent.demo.js?t=${Math.random()}`;s.onload=()=>console.log(%27PageAgent ready!%27);document.head.appendChild(s);})();
|
||||||
```
|
```
|
||||||
|
|
||||||
- Click the bookmark on any page to load Page-Agent
|
- Click the bookmark on any page to load Page-Agent
|
||||||
|
|||||||
+6
-6
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script
|
<script
|
||||||
src="https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.demo.js"
|
src="https://registry.npmmirror.com/page-agent/1.0.0-beta.4/files/dist/iife/page-agent.demo.js"
|
||||||
crossorigin="true"
|
crossorigin="true"
|
||||||
></script>
|
></script>
|
||||||
```
|
```
|
||||||
@@ -45,9 +45,9 @@
|
|||||||
> ⚠️ **仅用于技术评估。** Demo 模型有速率限制和使用限制,生产环境请使用 NPM 方式。
|
> ⚠️ **仅用于技术评估。** Demo 模型有速率限制和使用限制,生产环境请使用 NPM 方式。
|
||||||
|
|
||||||
| 镜像 | URL |
|
| 镜像 | URL |
|
||||||
| ------ | ----------------------------------------------------------------------------------- |
|
| ------ | ----------------------------------------------------------------------------------------- |
|
||||||
| Global | https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js |
|
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.4/dist/iife/page-agent.demo.js |
|
||||||
| China | https://registry.npmmirror.com/page-agent/latest/files/dist/iife/page-agent.demo.js |
|
| China | https://registry.npmmirror.com/page-agent/1.0.0-beta.4/files/dist/iife/page-agent.demo.js |
|
||||||
|
|
||||||
### NPM 安装
|
### NPM 安装
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ PageAgent adopts a simplified monorepo structure:
|
|||||||
|
|
||||||
```
|
```
|
||||||
packages/
|
packages/
|
||||||
├── page-agent/ # AI agent and demo(npm: page-agent)
|
├── core/ # ** Core agent logic without UI(npm: @page-agent/core) **
|
||||||
├── core/ # Agent core logic without UI(npm: @page-agent/core)
|
├── page-agent/ # Exported agent and demo(npm: page-agent)
|
||||||
├── llms/ # LLM 客户端 (npm: @page-agent/llms)
|
├── llms/ # LLM 客户端 (npm: @page-agent/llms)
|
||||||
├── page-controller/ # DOM 操作 & 蒙层 & 模拟鼠标 (npm: @page-agent/page-controller)
|
├── page-controller/ # DOM 操作 & 蒙层 & 模拟鼠标 (npm: @page-agent/page-controller)
|
||||||
├── ui/ # 面板 & i18n (npm: @page-agent/ui)
|
├── ui/ # 面板 & i18n (npm: @page-agent/ui)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Fastest way to try PageAgent:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script
|
<script
|
||||||
src="https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js"
|
src="https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.4/dist/iife/page-agent.demo.js"
|
||||||
crossorigin="true"
|
crossorigin="true"
|
||||||
></script>
|
></script>
|
||||||
```
|
```
|
||||||
@@ -45,9 +45,9 @@ Fastest way to try PageAgent:
|
|||||||
> ⚠️ **For technical evaluation only.** Demo model has rate limits and usage restrictions. Use NPM for production.
|
> ⚠️ **For technical evaluation only.** Demo model has rate limits and usage restrictions. Use NPM for production.
|
||||||
|
|
||||||
| Mirrors | URL |
|
| Mirrors | URL |
|
||||||
| ------- | ----------------------------------------------------------------------------------- |
|
| ------- | ----------------------------------------------------------------------------------------- |
|
||||||
| Global | https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js |
|
| Global | https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.4/dist/iife/page-agent.demo.js |
|
||||||
| China | https://registry.npmmirror.com/page-agent/latest/files/dist/iife/page-agent.demo.js |
|
| China | https://registry.npmmirror.com/page-agent/1.0.0-beta.4/files/dist/iife/page-agent.demo.js |
|
||||||
|
|
||||||
### NPM Installation
|
### NPM Installation
|
||||||
|
|
||||||
@@ -74,8 +74,8 @@ PageAgent adopts a simplified monorepo structure:
|
|||||||
|
|
||||||
```
|
```
|
||||||
packages/
|
packages/
|
||||||
├── page-agent/ # AI agent and demo(npm: page-agent)
|
├── core/ # ** Core agent logic without UI(npm: @page-agent/core) **
|
||||||
├── core/ # Agent core logic without UI(npm: @page-agent/core)
|
├── page-agent/ # Exported agent and demo(npm: page-agent)
|
||||||
├── llms/ # LLM client (npm: @page-agent/llms)
|
├── llms/ # LLM client (npm: @page-agent/llms)
|
||||||
├── page-controller/ # DOM operations & Visual Mask (npm: @page-agent/page-controller)
|
├── page-controller/ # DOM operations & Visual Mask (npm: @page-agent/page-controller)
|
||||||
├── ui/ # Panel & i18n (npm: @page-agent/ui)
|
├── ui/ # Panel & i18n (npm: @page-agent/ui)
|
||||||
|
|||||||
Generated
+146
-146
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/page-controller",
|
"packages/page-controller",
|
||||||
@@ -22,21 +22,21 @@
|
|||||||
"@eslint/js": "^9.39.2",
|
"@eslint/js": "^9.39.2",
|
||||||
"@microsoft/api-extractor": "^7.55.2",
|
"@microsoft/api-extractor": "^7.55.2",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
||||||
"@types/node": "^25.0.7",
|
"@types/node": "^25.0.9",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"eslint": "^9.39.2",
|
"eslint": "^9.39.2",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-react-dom": "^2.5.7",
|
"eslint-plugin-react-dom": "^2.7.2",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-react-refresh": "^0.4.26",
|
"eslint-plugin-react-refresh": "^0.4.26",
|
||||||
"eslint-plugin-react-x": "^2.5.7",
|
"eslint-plugin-react-x": "^2.7.2",
|
||||||
"globals": "^17.0.0",
|
"globals": "^17.0.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"lint-staged": "^16.2.4",
|
"lint-staged": "^16.2.4",
|
||||||
"prettier": "^3.7.4",
|
"prettier": "^3.8.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.53.0",
|
"typescript-eslint": "^8.53.1",
|
||||||
"unplugin-dts": "^1.0.0-beta.6",
|
"unplugin-dts": "^1.0.0-beta.6",
|
||||||
"vite": "^7.3.1",
|
"vite": "^7.3.1",
|
||||||
"vite-plugin-css-injected-by-js": "^3.5.2"
|
"vite-plugin-css-injected-by-js": "^3.5.2"
|
||||||
@@ -1058,13 +1058,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-react/ast": {
|
"node_modules/@eslint-react/ast": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-react/ast/-/ast-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-react/ast/-/ast-2.7.2.tgz",
|
||||||
"integrity": "sha512-yQvKvyIzo9DPKFUOtFSEfpX0He763G1jFf/LQcIY9xoSOWP9pQ2X8ADNE6ZnmIc0L5zZLQ9nF/H0+MGh2NF3fA==",
|
"integrity": "sha512-RB8AVNjboN6/md9Da4rUG4WqxLT+DqUR+qXIR6iAD0+xxp6Dtihu541+lKLZ3GCstunbBcDwu7gdhSbz+BHSuQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/eff": "2.5.7",
|
"@eslint-react/eff": "2.7.2",
|
||||||
"@typescript-eslint/types": "^8.53.0",
|
"@typescript-eslint/types": "^8.53.0",
|
||||||
"@typescript-eslint/typescript-estree": "^8.53.0",
|
"@typescript-eslint/typescript-estree": "^8.53.0",
|
||||||
"@typescript-eslint/utils": "^8.53.0",
|
"@typescript-eslint/utils": "^8.53.0",
|
||||||
@@ -1079,16 +1079,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-react/core": {
|
"node_modules/@eslint-react/core": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-react/core/-/core-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-react/core/-/core-2.7.2.tgz",
|
||||||
"integrity": "sha512-LqY4YV4Z/uiymdy2OLXkjsEVnoDjoFsxJZI4GWsZ9aBgGWYAsuoKKUG0bdMLp1U9jwMaY0OY9bYgBB5R1ANkoQ==",
|
"integrity": "sha512-QOYh8OWwUGMYLhuvb8WcmoS2jYXb0SJbpX+Ozk+Ht2G9XGRAahl+8PDy/o2l2lLnFXv5JQGfLrN+m2WPTi104g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/ast": "2.5.7",
|
"@eslint-react/ast": "2.7.2",
|
||||||
"@eslint-react/eff": "2.5.7",
|
"@eslint-react/eff": "2.7.2",
|
||||||
"@eslint-react/shared": "2.5.7",
|
"@eslint-react/shared": "2.7.2",
|
||||||
"@eslint-react/var": "2.5.7",
|
"@eslint-react/var": "2.7.2",
|
||||||
"@typescript-eslint/scope-manager": "^8.53.0",
|
"@typescript-eslint/scope-manager": "^8.53.0",
|
||||||
"@typescript-eslint/types": "^8.53.0",
|
"@typescript-eslint/types": "^8.53.0",
|
||||||
"@typescript-eslint/utils": "^8.53.0",
|
"@typescript-eslint/utils": "^8.53.0",
|
||||||
@@ -1104,9 +1104,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-react/eff": {
|
"node_modules/@eslint-react/eff": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-react/eff/-/eff-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-react/eff/-/eff-2.7.2.tgz",
|
||||||
"integrity": "sha512-oxd8eP+dykyOUmQUEItnOZhitlKyo9yFq8Ne0k9+CJeV0Pk1db1+lNcDWswWYoeb1IFEloqHo6y63fVxQXvJew==",
|
"integrity": "sha512-AzQGbidoI8g8izka/1H9xCKW56NR7xWGGPMccBCUZwbCoJZ4wyRKcE10E7ot7LwBv5kBoUQp3GJ9UXCcg/Er0w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1114,16 +1114,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-react/shared": {
|
"node_modules/@eslint-react/shared": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-react/shared/-/shared-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-react/shared/-/shared-2.7.2.tgz",
|
||||||
"integrity": "sha512-ZjKO3rNDoLN2ZTn3PxmMcgoASPNiL3umK1BHQvYwCXqqnXlLEouu7sxK6htOvDu1NC+Dbwsqpu4JGUY7t0XQTw==",
|
"integrity": "sha512-U1H3dLaTj7kvEbyJyJEgn6xX3BmrCH1f9f+tg9gLWlN7askgWT5NF56wfX1l+jtwiEAZD/78W1TfICKkMnZDxQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/eff": "2.5.7",
|
"@eslint-react/eff": "2.7.2",
|
||||||
"@typescript-eslint/utils": "^8.53.0",
|
"@typescript-eslint/utils": "^8.53.0",
|
||||||
"ts-pattern": "^5.9.0",
|
"ts-pattern": "^5.9.0",
|
||||||
"zod": "^4.3.5"
|
"zod": "^3.25.0 || ^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.19.0"
|
"node": ">=20.19.0"
|
||||||
@@ -1134,14 +1134,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-react/var": {
|
"node_modules/@eslint-react/var": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-react/var/-/var-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-react/var/-/var-2.7.2.tgz",
|
||||||
"integrity": "sha512-VWoyZENbK+OV70s/sE9E6T4HD0WO6lsg2CnYjjpKBKBDOBW67SRdIlM7dUPKzqQKsj6p4yNh59eQ5iKaH82LLg==",
|
"integrity": "sha512-sPnXmikpzmAdIWh6lqqKm4Bu0ypKTCAQ7WxGuR5ejxtrA/HjQQuKMBIyPkBdjHWlF9ADdh9pKuo1j2RQwUWiqA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/ast": "2.5.7",
|
"@eslint-react/ast": "2.7.2",
|
||||||
"@eslint-react/eff": "2.5.7",
|
"@eslint-react/eff": "2.7.2",
|
||||||
"@typescript-eslint/scope-manager": "^8.53.0",
|
"@typescript-eslint/scope-manager": "^8.53.0",
|
||||||
"@typescript-eslint/types": "^8.53.0",
|
"@typescript-eslint/types": "^8.53.0",
|
||||||
"@typescript-eslint/utils": "^8.53.0",
|
"@typescript-eslint/utils": "^8.53.0",
|
||||||
@@ -3547,9 +3547,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "25.0.7",
|
"version": "25.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.9.tgz",
|
||||||
"integrity": "sha512-C/er7DlIZgRJO7WtTdYovjIFzGsz0I95UlMyR9anTb4aCpBSRWe5Jc1/RvLKUfzmOxHPGjSE5+63HgLtndxU4w==",
|
"integrity": "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -3577,17 +3577,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz",
|
||||||
"integrity": "sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==",
|
"integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.12.2",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@typescript-eslint/scope-manager": "8.53.0",
|
"@typescript-eslint/scope-manager": "8.53.1",
|
||||||
"@typescript-eslint/type-utils": "8.53.0",
|
"@typescript-eslint/type-utils": "8.53.1",
|
||||||
"@typescript-eslint/utils": "8.53.0",
|
"@typescript-eslint/utils": "8.53.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.53.0",
|
"@typescript-eslint/visitor-keys": "8.53.1",
|
||||||
"ignore": "^7.0.5",
|
"ignore": "^7.0.5",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^2.4.0"
|
"ts-api-utils": "^2.4.0"
|
||||||
@@ -3600,7 +3600,7 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^8.53.0",
|
"@typescript-eslint/parser": "^8.53.1",
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0",
|
||||||
"typescript": ">=4.8.4 <6.0.0"
|
"typescript": ">=4.8.4 <6.0.0"
|
||||||
}
|
}
|
||||||
@@ -3616,16 +3616,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz",
|
||||||
"integrity": "sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==",
|
"integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.53.0",
|
"@typescript-eslint/scope-manager": "8.53.1",
|
||||||
"@typescript-eslint/types": "8.53.0",
|
"@typescript-eslint/types": "8.53.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.53.0",
|
"@typescript-eslint/typescript-estree": "8.53.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.53.0",
|
"@typescript-eslint/visitor-keys": "8.53.1",
|
||||||
"debug": "^4.4.3"
|
"debug": "^4.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3641,14 +3641,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/project-service": {
|
"node_modules/@typescript-eslint/project-service": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz",
|
||||||
"integrity": "sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==",
|
"integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/tsconfig-utils": "^8.53.0",
|
"@typescript-eslint/tsconfig-utils": "^8.53.1",
|
||||||
"@typescript-eslint/types": "^8.53.0",
|
"@typescript-eslint/types": "^8.53.1",
|
||||||
"debug": "^4.4.3"
|
"debug": "^4.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3663,14 +3663,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz",
|
||||||
"integrity": "sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==",
|
"integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.53.0",
|
"@typescript-eslint/types": "8.53.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.53.0"
|
"@typescript-eslint/visitor-keys": "8.53.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -3681,9 +3681,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz",
|
||||||
"integrity": "sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==",
|
"integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3698,15 +3698,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz",
|
||||||
"integrity": "sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==",
|
"integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.53.0",
|
"@typescript-eslint/types": "8.53.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.53.0",
|
"@typescript-eslint/typescript-estree": "8.53.1",
|
||||||
"@typescript-eslint/utils": "8.53.0",
|
"@typescript-eslint/utils": "8.53.1",
|
||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"ts-api-utils": "^2.4.0"
|
"ts-api-utils": "^2.4.0"
|
||||||
},
|
},
|
||||||
@@ -3723,9 +3723,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz",
|
||||||
"integrity": "sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==",
|
"integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3737,16 +3737,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz",
|
||||||
"integrity": "sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==",
|
"integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/project-service": "8.53.0",
|
"@typescript-eslint/project-service": "8.53.1",
|
||||||
"@typescript-eslint/tsconfig-utils": "8.53.0",
|
"@typescript-eslint/tsconfig-utils": "8.53.1",
|
||||||
"@typescript-eslint/types": "8.53.0",
|
"@typescript-eslint/types": "8.53.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.53.0",
|
"@typescript-eslint/visitor-keys": "8.53.1",
|
||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"minimatch": "^9.0.5",
|
"minimatch": "^9.0.5",
|
||||||
"semver": "^7.7.3",
|
"semver": "^7.7.3",
|
||||||
@@ -3791,16 +3791,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz",
|
||||||
"integrity": "sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==",
|
"integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.9.1",
|
"@eslint-community/eslint-utils": "^4.9.1",
|
||||||
"@typescript-eslint/scope-manager": "8.53.0",
|
"@typescript-eslint/scope-manager": "8.53.1",
|
||||||
"@typescript-eslint/types": "8.53.0",
|
"@typescript-eslint/types": "8.53.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.53.0"
|
"@typescript-eslint/typescript-estree": "8.53.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -3815,13 +3815,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz",
|
||||||
"integrity": "sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==",
|
"integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.53.0",
|
"@typescript-eslint/types": "8.53.1",
|
||||||
"eslint-visitor-keys": "^4.2.1"
|
"eslint-visitor-keys": "^4.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4851,17 +4851,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react-dom": {
|
"node_modules/eslint-plugin-react-dom": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-dom/-/eslint-plugin-react-dom-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react-dom/-/eslint-plugin-react-dom-2.7.2.tgz",
|
||||||
"integrity": "sha512-KHCU7KRXeLYlrrXKtInpCqHzt+nYhIGpYIuMM4Q0FyGBOcswRS2Gv9PhN+yQqDI9PRBhnjCuRf+q2Y3ZrYWjsw==",
|
"integrity": "sha512-Qzd4HAFwsxvOJoAycLIRxziOTJwEZ6EGAA6jEFFBSD1BbFVnDlozMvOLp9/+GrZW3cE0FGmAS6QXnjuMf0QYLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/ast": "2.5.7",
|
"@eslint-react/ast": "2.7.2",
|
||||||
"@eslint-react/core": "2.5.7",
|
"@eslint-react/core": "2.7.2",
|
||||||
"@eslint-react/eff": "2.5.7",
|
"@eslint-react/eff": "2.7.2",
|
||||||
"@eslint-react/shared": "2.5.7",
|
"@eslint-react/shared": "2.7.2",
|
||||||
"@eslint-react/var": "2.5.7",
|
"@eslint-react/var": "2.7.2",
|
||||||
"@typescript-eslint/scope-manager": "^8.53.0",
|
"@typescript-eslint/scope-manager": "^8.53.0",
|
||||||
"@typescript-eslint/types": "^8.53.0",
|
"@typescript-eslint/types": "^8.53.0",
|
||||||
"@typescript-eslint/utils": "^8.53.0",
|
"@typescript-eslint/utils": "^8.53.0",
|
||||||
@@ -4908,17 +4908,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react-x": {
|
"node_modules/eslint-plugin-react-x": {
|
||||||
"version": "2.5.7",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-x/-/eslint-plugin-react-x-2.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react-x/-/eslint-plugin-react-x-2.7.2.tgz",
|
||||||
"integrity": "sha512-EU+h7eUHNg9ikLaGOa0Tjsc/o4FO2KdyT3M97TkQmaKc9tzpcy8nlPQp/czBMbUuxAgbj2495wzOvCZ0fEK4mw==",
|
"integrity": "sha512-0NbYqJhc3tZQVluaFMVCOg6HEFarlNNXe+DHa/JrLAR0PVb9AtJGk8FBEDdxaUZO8ph0sAekUNLB7gymftj4Dw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/ast": "2.5.7",
|
"@eslint-react/ast": "2.7.2",
|
||||||
"@eslint-react/core": "2.5.7",
|
"@eslint-react/core": "2.7.2",
|
||||||
"@eslint-react/eff": "2.5.7",
|
"@eslint-react/eff": "2.7.2",
|
||||||
"@eslint-react/shared": "2.5.7",
|
"@eslint-react/shared": "2.7.2",
|
||||||
"@eslint-react/var": "2.5.7",
|
"@eslint-react/var": "2.7.2",
|
||||||
"@typescript-eslint/scope-manager": "^8.53.0",
|
"@typescript-eslint/scope-manager": "^8.53.0",
|
||||||
"@typescript-eslint/type-utils": "^8.53.0",
|
"@typescript-eslint/type-utils": "^8.53.0",
|
||||||
"@typescript-eslint/types": "^8.53.0",
|
"@typescript-eslint/types": "^8.53.0",
|
||||||
@@ -5301,12 +5301,12 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/framer-motion": {
|
"node_modules/framer-motion": {
|
||||||
"version": "12.26.1",
|
"version": "12.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.27.1.tgz",
|
||||||
"integrity": "sha512-Uzc8wGldU4FpmGotthjjcj0SZhigcODjqvKT7lzVZHsmYkzQMFfMIv0vHQoXCeoe/Ahxqp4by4A6QbzFA/lblw==",
|
"integrity": "sha512-cEAqO69kcZt3gL0TGua8WTgRQfv4J57nqt1zxHtLKwYhAwA0x9kDS/JbMa1hJbwkGY74AGJKvZ9pX/IqWZtZWQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"motion-dom": "^12.24.11",
|
"motion-dom": "^12.27.1",
|
||||||
"motion-utils": "^12.24.10",
|
"motion-utils": "^12.24.10",
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
},
|
},
|
||||||
@@ -6514,12 +6514,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/motion": {
|
"node_modules/motion": {
|
||||||
"version": "12.26.1",
|
"version": "12.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/motion/-/motion-12.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/motion/-/motion-12.27.1.tgz",
|
||||||
"integrity": "sha512-IVhzx9HOQTiJ9ykthMOlZPnLwrkXziN5Q/yebsqBYlFJb2rHP8yhmKc8O/YUT9byPJlxOeqkzfNYCrVKZx8vqg==",
|
"integrity": "sha512-FAZTPDm1LccBdWSL46WLnEdTSHmdVx+fdWK8f61qBQn67MmFefXLXlrwy94rK2DDsd9A50Gj8H+LYCgQ/cQlFg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"framer-motion": "^12.26.1",
|
"framer-motion": "^12.27.1",
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@@ -6540,9 +6540,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/motion-dom": {
|
"node_modules/motion-dom": {
|
||||||
"version": "12.24.11",
|
"version": "12.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.24.11.tgz",
|
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.27.1.tgz",
|
||||||
"integrity": "sha512-DlWOmsXMJrV8lzZyd+LKjG2CXULUs++bkq8GZ2Sr0R0RRhs30K2wtY+LKiTjhmJU3W61HK+rB0GLz6XmPvTA1A==",
|
"integrity": "sha512-V/53DA2nBqKl9O2PMJleSUb/G0dsMMeZplZwgIQf5+X0bxIu7Q1cTv6DrjvTTGYRm3+7Y5wMlRZ1wT61boU/bQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"motion-utils": "^12.24.10"
|
"motion-utils": "^12.24.10"
|
||||||
@@ -6862,9 +6862,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.7.4",
|
"version": "3.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz",
|
||||||
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
|
"integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -6926,9 +6926,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-i18next": {
|
"node_modules/react-i18next": {
|
||||||
"version": "16.5.2",
|
"version": "16.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.5.3.tgz",
|
||||||
"integrity": "sha512-GG/SBVxx9dvrO1uCs8VYdKfOP8NEBUhNP+2VDQLCifRJ8DL1qPq296k2ACNGyZMDe7iyIlz/LMJTQOs8HXSRvw==",
|
"integrity": "sha512-fo+/NNch37zqxOzlBYrWMx0uy/yInPkRfjSuy4lqKdaecR17nvCHnEUt3QyzA8XjQ2B/0iW/5BhaHR3ZmukpGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -7165,9 +7165,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/simple-icons": {
|
"node_modules/simple-icons": {
|
||||||
"version": "16.5.0",
|
"version": "16.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-16.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-16.6.0.tgz",
|
||||||
"integrity": "sha512-72nn0oHADKx6Hknu7q6M0vfL8LiCUMKABOHane2+4xdqaFBSHfNNBjuZioihiqVQMz7IvVle4NKAM0IlXvl/9A==",
|
"integrity": "sha512-lzSVlAhflhwud7EprwSalbCpHKpculOfaAk1P+S3QajO1bHG5nqwI1VeGnn4rwaE4xSSSKDsOFFL0XfIDv5iIQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -7568,16 +7568,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript-eslint": {
|
"node_modules/typescript-eslint": {
|
||||||
"version": "8.53.0",
|
"version": "8.53.1",
|
||||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.0.tgz",
|
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.1.tgz",
|
||||||
"integrity": "sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==",
|
"integrity": "sha512-gB+EVQfP5RDElh9ittfXlhZJdjSU4jUSTyE2+ia8CYyNvet4ElfaLlAIqDvQV9JPknKx0jQH1racTYe/4LaLSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "8.53.0",
|
"@typescript-eslint/eslint-plugin": "8.53.1",
|
||||||
"@typescript-eslint/parser": "8.53.0",
|
"@typescript-eslint/parser": "8.53.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.53.0",
|
"@typescript-eslint/typescript-estree": "8.53.1",
|
||||||
"@typescript-eslint/utils": "8.53.0"
|
"@typescript-eslint/utils": "8.53.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -8142,18 +8142,18 @@
|
|||||||
},
|
},
|
||||||
"packages/core": {
|
"packages/core": {
|
||||||
"name": "@page-agent/core",
|
"name": "@page-agent/core",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@page-agent/llms": "0.3.0",
|
"@page-agent/llms": "1.0.0-beta.4",
|
||||||
"@page-agent/page-controller": "0.3.0",
|
"@page-agent/page-controller": "1.0.0-beta.4",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
"zod": "^4.3.5"
|
"zod": "^4.3.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/llms": {
|
"packages/llms": {
|
||||||
"name": "@page-agent/llms",
|
"name": "@page-agent/llms",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
@@ -8161,20 +8161,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/page-agent": {
|
"packages/page-agent": {
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@page-agent/core": "0.3.0",
|
"@page-agent/core": "1.0.0-beta.4",
|
||||||
"@page-agent/llms": "0.3.0",
|
"@page-agent/llms": "1.0.0-beta.4",
|
||||||
"@page-agent/page-controller": "0.3.0",
|
"@page-agent/page-controller": "1.0.0-beta.4",
|
||||||
"@page-agent/ui": "0.3.0",
|
"@page-agent/ui": "1.0.0-beta.4",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
"zod": "^4.3.5"
|
"zod": "^4.3.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/page-controller": {
|
"packages/page-controller": {
|
||||||
"name": "@page-agent/page-controller",
|
"name": "@page-agent/page-controller",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ai-motion": "^0.4.8"
|
"ai-motion": "^0.4.8"
|
||||||
@@ -8182,12 +8182,12 @@
|
|||||||
},
|
},
|
||||||
"packages/ui": {
|
"packages/ui": {
|
||||||
"name": "@page-agent/ui",
|
"name": "@page-agent/ui",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"packages/website": {
|
"packages/website": {
|
||||||
"name": "@page-agent/website",
|
"name": "@page-agent/website",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@radix-ui/react-separator": "^1.1.8",
|
"@radix-ui/react-separator": "^1.1.8",
|
||||||
@@ -8197,10 +8197,10 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
"motion": "^12.26.1",
|
"motion": "^12.27.1",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"rough-notation": "^0.5.1",
|
"rough-notation": "^0.5.1",
|
||||||
"simple-icons": "^16.5.0",
|
"simple-icons": "^16.6.0",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"tailwind-merge": "^3.4.0"
|
"tailwind-merge": "^3.4.0"
|
||||||
},
|
},
|
||||||
@@ -8213,7 +8213,7 @@
|
|||||||
"i18next-browser-languagedetector": "^8.2.0",
|
"i18next-browser-languagedetector": "^8.2.0",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-i18next": "^16.5.2",
|
"react-i18next": "^16.5.3",
|
||||||
"tailwindcss": "^4.1.14",
|
"tailwindcss": "^4.1.14",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
"wouter": "^3.9.0"
|
"wouter": "^3.9.0"
|
||||||
|
|||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/page-controller",
|
"packages/page-controller",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"build:website": "npm run build:website --workspace=@page-agent/website",
|
"build:website": "npm run build:website --workspace=@page-agent/website",
|
||||||
"build:libs": "npm run build --workspaces --if-present",
|
"build:libs": "npm run build --workspaces --if-present",
|
||||||
"build": "npm run build:libs && npm run build:website",
|
"build": "npm run build:libs && npm run build:website",
|
||||||
"dev:iife": "npm run dev:iife --workspace=page-agent",
|
"dev:demo": "npm run dev:demo --workspace=page-agent",
|
||||||
"version": "node scripts/sync-version.js",
|
"version": "node scripts/sync-version.js",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"prepare": "husky"
|
"prepare": "husky"
|
||||||
@@ -40,21 +40,21 @@
|
|||||||
"@eslint/js": "^9.39.2",
|
"@eslint/js": "^9.39.2",
|
||||||
"@microsoft/api-extractor": "^7.55.2",
|
"@microsoft/api-extractor": "^7.55.2",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
||||||
"@types/node": "^25.0.7",
|
"@types/node": "^25.0.9",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"eslint": "^9.39.2",
|
"eslint": "^9.39.2",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-react-dom": "^2.5.7",
|
"eslint-plugin-react-dom": "^2.7.2",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-react-refresh": "^0.4.26",
|
"eslint-plugin-react-refresh": "^0.4.26",
|
||||||
"eslint-plugin-react-x": "^2.5.7",
|
"eslint-plugin-react-x": "^2.7.2",
|
||||||
"globals": "^17.0.0",
|
"globals": "^17.0.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"lint-staged": "^16.2.4",
|
"lint-staged": "^16.2.4",
|
||||||
"prettier": "^3.7.4",
|
"prettier": "^3.8.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.53.0",
|
"typescript-eslint": "^8.53.1",
|
||||||
"unplugin-dts": "^1.0.0-beta.6",
|
"unplugin-dts": "^1.0.0-beta.6",
|
||||||
"vite": "^7.3.1",
|
"vite": "^7.3.1",
|
||||||
"vite-plugin-css-injected-by-js": "^3.5.2"
|
"vite-plugin-css-injected-by-js": "^3.5.2"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@page-agent/core",
|
"name": "@page-agent/core",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/esm/page-agent-core.js",
|
"main": "./dist/esm/page-agent-core.js",
|
||||||
"module": "./dist/esm/page-agent-core.js",
|
"module": "./dist/esm/page-agent-core.js",
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
"zod": "^4.3.5",
|
"zod": "^4.3.5",
|
||||||
"@page-agent/llms": "0.3.0",
|
"@page-agent/llms": "1.0.0-beta.4",
|
||||||
"@page-agent/page-controller": "0.3.0"
|
"@page-agent/page-controller": "1.0.0-beta.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
* Copyright (C) 2025 Alibaba Group Holding Limited
|
* Copyright (C) 2025 Alibaba Group Holding Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*/
|
*/
|
||||||
import { LLM, type Tool } from '@page-agent/llms'
|
import { InvokeError, LLM, type Tool } from '@page-agent/llms'
|
||||||
import type { PageController } from '@page-agent/page-controller'
|
import type { PageController } from '@page-agent/page-controller'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import zod from 'zod'
|
import zod from 'zod'
|
||||||
|
|
||||||
import { type PageAgentConfig } from './config'
|
import { type PageAgentConfig } from './config'
|
||||||
import { MAX_STEPS } from './config/constants'
|
import { DEFAULT_MAX_STEPS } from './config/constants'
|
||||||
import SYSTEM_PROMPT from './prompts/system_prompt.md?raw'
|
import SYSTEM_PROMPT from './prompts/system_prompt.md?raw'
|
||||||
import { tools } from './tools'
|
import { tools } from './tools'
|
||||||
import {
|
import {
|
||||||
@@ -21,11 +21,12 @@ import {
|
|||||||
MacroToolInput,
|
MacroToolInput,
|
||||||
MacroToolResult,
|
MacroToolResult,
|
||||||
} from './types'
|
} from './types'
|
||||||
import { normalizeResponse, trimLines, uid } from './utils'
|
import { normalizeResponse, trimLines, uid, waitFor } from './utils'
|
||||||
import { assert } from './utils/assert'
|
import { assert } from './utils/assert'
|
||||||
|
|
||||||
export { type PageAgentConfig }
|
export { type PageAgentConfig }
|
||||||
export { tool, type PageAgentTool } from './tools'
|
export { tool, type PageAgentTool } from './tools'
|
||||||
|
export type * from './types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI agent for browser DOM automation.
|
* AI agent for browser DOM automation.
|
||||||
@@ -49,7 +50,7 @@ export { tool, type PageAgentTool } from './tools'
|
|||||||
* - Types: thinking, executing, executed, retrying, error
|
* - Types: thinking, executing, executed, retrying, error
|
||||||
*/
|
*/
|
||||||
export class PageAgentCore extends EventTarget {
|
export class PageAgentCore extends EventTarget {
|
||||||
config: PageAgentConfig
|
config: PageAgentConfig & { maxSteps: number }
|
||||||
id = uid()
|
id = uid()
|
||||||
tools: typeof tools
|
tools: typeof tools
|
||||||
disposed = false
|
disposed = false
|
||||||
@@ -86,7 +87,8 @@ export class PageAgentCore extends EventTarget {
|
|||||||
constructor(config: PageAgentConfig & { pageController: PageController }) {
|
constructor(config: PageAgentConfig & { pageController: PageController }) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
this.config = config
|
this.config = { ...config, maxSteps: config.maxSteps || DEFAULT_MAX_STEPS }
|
||||||
|
|
||||||
this.#llm = new LLM(this.config)
|
this.#llm = new LLM(this.config)
|
||||||
this.tools = new Map(tools)
|
this.tools = new Map(tools)
|
||||||
this.pageController = config.pageController
|
this.pageController = config.pageController
|
||||||
@@ -106,7 +108,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
this.#emitHistoryChange()
|
this.#emitHistoryChange()
|
||||||
})
|
})
|
||||||
this.#llm.addEventListener('error', (e) => {
|
this.#llm.addEventListener('error', (e) => {
|
||||||
const { error } = (e as CustomEvent).detail
|
const error = (e as CustomEvent).detail.error as Error | InvokeError
|
||||||
const message = String(error)
|
const message = String(error)
|
||||||
this.emitActivity({ type: 'error', message })
|
this.emitActivity({ type: 'error', message })
|
||||||
// Also push to history for panel rendering
|
// Also push to history for panel rendering
|
||||||
@@ -114,6 +116,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
type: 'error',
|
type: 'error',
|
||||||
errorType: 'error',
|
errorType: 'error',
|
||||||
message,
|
message,
|
||||||
|
rawResponse: (error as InvokeError).rawResponse,
|
||||||
})
|
})
|
||||||
this.#emitHistoryChange()
|
this.#emitHistoryChange()
|
||||||
})
|
})
|
||||||
@@ -183,12 +186,12 @@ export class PageAgentCore extends EventTarget {
|
|||||||
this.tools.delete('ask_user')
|
this.tools.delete('ask_user')
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBeforeStep = this.config.onBeforeStep || (() => void 0)
|
const onBeforeStep = this.config.onBeforeStep
|
||||||
const onAfterStep = this.config.onAfterStep || (() => void 0)
|
const onAfterStep = this.config.onAfterStep
|
||||||
const onBeforeTask = this.config.onBeforeTask || (() => void 0)
|
const onBeforeTask = this.config.onBeforeTask
|
||||||
const onAfterTask = this.config.onAfterTask || (() => void 0)
|
const onAfterTask = this.config.onAfterTask
|
||||||
|
|
||||||
await onBeforeTask.call(this)
|
await onBeforeTask?.(this)
|
||||||
|
|
||||||
// Show mask
|
// Show mask
|
||||||
await this.pageController.showMask()
|
await this.pageController.showMask()
|
||||||
@@ -214,7 +217,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
while (true) {
|
while (true) {
|
||||||
await this.#generateObservations(step)
|
await this.#generateObservations(step)
|
||||||
|
|
||||||
await onBeforeStep.call(this, step)
|
await onBeforeStep?.(this, step)
|
||||||
|
|
||||||
console.group(`step: ${step}`)
|
console.group(`step: ${step}`)
|
||||||
|
|
||||||
@@ -261,26 +264,28 @@ export class PageAgentCore extends EventTarget {
|
|||||||
|
|
||||||
this.history.push({
|
this.history.push({
|
||||||
type: 'step',
|
type: 'step',
|
||||||
|
stepIndex: step,
|
||||||
reflection,
|
reflection,
|
||||||
action,
|
action,
|
||||||
usage: result.usage,
|
usage: result.usage,
|
||||||
|
rawResponse: result.rawResponse,
|
||||||
} as AgentStep)
|
} as AgentStep)
|
||||||
this.#emitHistoryChange()
|
this.#emitHistoryChange()
|
||||||
|
|
||||||
console.log(chalk.green('Step finished:'), actionName)
|
console.log(chalk.green('Step finished:'), actionName)
|
||||||
console.groupEnd()
|
console.groupEnd()
|
||||||
|
|
||||||
await onAfterStep.call(this, this.history)
|
await onAfterStep?.(this, this.history)
|
||||||
|
|
||||||
step++
|
step++
|
||||||
if (step > MAX_STEPS) {
|
if (step > this.config.maxSteps) {
|
||||||
this.#onDone('Step count exceeded maximum limit', false)
|
this.#onDone('Step count exceeded maximum limit', false)
|
||||||
const result: ExecutionResult = {
|
const result: ExecutionResult = {
|
||||||
success: false,
|
success: false,
|
||||||
data: 'Step count exceeded maximum limit',
|
data: 'Step count exceeded maximum limit',
|
||||||
history: this.history,
|
history: this.history,
|
||||||
}
|
}
|
||||||
await onAfterTask.call(this, result)
|
await onAfterTask?.(this, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
if (actionName === 'done') {
|
if (actionName === 'done') {
|
||||||
@@ -293,7 +298,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
data: text,
|
data: text,
|
||||||
history: this.history,
|
history: this.history,
|
||||||
}
|
}
|
||||||
await onAfterTask.call(this, result)
|
await onAfterTask?.(this, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,7 +312,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
data: errorMessage,
|
data: errorMessage,
|
||||||
history: this.history,
|
history: this.history,
|
||||||
}
|
}
|
||||||
await onAfterTask.call(this, result)
|
await onAfterTask?.(this, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -472,10 +477,11 @@ export class PageAgentCore extends EventTarget {
|
|||||||
if (currentURL !== this.states.lastURL) {
|
if (currentURL !== this.states.lastURL) {
|
||||||
this.pushObservation(`Page navigated to → ${currentURL}`)
|
this.pushObservation(`Page navigated to → ${currentURL}`)
|
||||||
this.states.lastURL = currentURL
|
this.states.lastURL = currentURL
|
||||||
|
await waitFor(0.5) // wait for page to stabilize
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn about remaining steps
|
// Warn about remaining steps
|
||||||
const remaining = MAX_STEPS - stepCount
|
const remaining = this.config.maxSteps - stepCount
|
||||||
if (remaining === 5) {
|
if (remaining === 5) {
|
||||||
this.pushObservation(
|
this.pushObservation(
|
||||||
`⚠️ Only ${remaining} steps remaining. Consider wrapping up or calling done with partial results.`
|
`⚠️ Only ${remaining} steps remaining. Consider wrapping up or calling done with partial results.`
|
||||||
@@ -505,7 +511,7 @@ export class PageAgentCore extends EventTarget {
|
|||||||
${this.task}
|
${this.task}
|
||||||
</user_request>
|
</user_request>
|
||||||
<step_info>
|
<step_info>
|
||||||
Step ${stepCount + 1} of ${MAX_STEPS} max possible steps
|
Step ${stepCount + 1} of ${this.config.maxSteps} max possible steps
|
||||||
Current date and time: ${new Date().toISOString()}
|
Current date and time: ${new Date().toISOString()}
|
||||||
</step_info>
|
</step_info>
|
||||||
</agent_state>
|
</agent_state>
|
||||||
@@ -583,6 +589,6 @@ export class PageAgentCore extends EventTarget {
|
|||||||
// Emit dispose event for UI cleanup
|
// Emit dispose event for UI cleanup
|
||||||
this.dispatchEvent(new Event('dispose'))
|
this.dispatchEvent(new Event('dispose'))
|
||||||
|
|
||||||
this.config.onDispose?.call(this, reason)
|
this.config.onDispose?.(this, reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
// Agent-specific constants (LLM constants moved to @page-agent/llms)
|
export const DEFAULT_MAX_STEPS = 20
|
||||||
export const MAX_STEPS = 20
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { LLMConfig } from '@page-agent/llms'
|
import type { LLMConfig } from '@page-agent/llms'
|
||||||
import type { PageController, PageControllerConfig } from '@page-agent/page-controller'
|
import type { PageControllerConfig } from '@page-agent/page-controller'
|
||||||
|
|
||||||
import type { PageAgentCore } from '../PageAgentCore'
|
import type { PageAgentCore } from '../PageAgentCore'
|
||||||
import type { PageAgentTool } from '../tools'
|
import type { PageAgentTool } from '../tools'
|
||||||
@@ -14,6 +14,12 @@ export interface AgentConfig {
|
|||||||
// theme?: 'light' | 'dark'
|
// theme?: 'light' | 'dark'
|
||||||
language?: SupportedLanguage
|
language?: SupportedLanguage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of steps the agent can take per task.
|
||||||
|
* @default 20
|
||||||
|
*/
|
||||||
|
maxSteps?: number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom tools to extend PageAgent capabilities
|
* Custom tools to extend PageAgent capabilities
|
||||||
* @experimental
|
* @experimental
|
||||||
@@ -63,20 +69,52 @@ export interface AgentConfig {
|
|||||||
getPageInstructions?: (url: string) => string | undefined | null
|
getPageInstructions?: (url: string) => string | undefined | null
|
||||||
}
|
}
|
||||||
|
|
||||||
// lifecycle hooks
|
/**
|
||||||
// @todo: use event instead of hooks
|
* Lifecycle hooks for task execution.
|
||||||
// @todo: remove `this` binding, pass agent as explicit parameter instead
|
* @experimental API may change in future versions.
|
||||||
|
*
|
||||||
onBeforeStep?: (this: PageAgentCore, stepCnt: number) => Promise<void> | void
|
* All hooks receive the agent instance as first parameter.
|
||||||
onAfterStep?: (this: PageAgentCore, history: HistoricalEvent[]) => Promise<void> | void
|
*/
|
||||||
onBeforeTask?: (this: PageAgentCore) => Promise<void> | void
|
|
||||||
onAfterTask?: (this: PageAgentCore, result: ExecutionResult) => Promise<void> | void
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note this hook can block the disposal process
|
* Called before each step execution.
|
||||||
* @todo remove `this` binding, pass agent as explicit parameter instead
|
* @experimental
|
||||||
|
* @param agent - The PageAgentCore instance
|
||||||
|
* @param stepCount - Current step number (0-indexed)
|
||||||
*/
|
*/
|
||||||
onDispose?: (this: PageAgentCore, reason?: string) => void
|
onBeforeStep?: (agent: PageAgentCore, stepCount: number) => Promise<void> | void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after each step execution.
|
||||||
|
* @experimental
|
||||||
|
* @param agent - The PageAgentCore instance
|
||||||
|
* @param history - Current history of events
|
||||||
|
*/
|
||||||
|
onAfterStep?: (agent: PageAgentCore, history: HistoricalEvent[]) => Promise<void> | void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called before task execution starts.
|
||||||
|
* @experimental
|
||||||
|
* @param agent - The PageAgentCore instance
|
||||||
|
*/
|
||||||
|
onBeforeTask?: (agent: PageAgentCore) => Promise<void> | void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after task execution completes (success or failure).
|
||||||
|
* @experimental
|
||||||
|
* @param agent - The PageAgentCore instance
|
||||||
|
* @param result - The execution result
|
||||||
|
*/
|
||||||
|
onAfterTask?: (agent: PageAgentCore, result: ExecutionResult) => Promise<void> | void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the agent is disposed.
|
||||||
|
* @experimental
|
||||||
|
* @note This hook can block the disposal process if it's async.
|
||||||
|
* @param agent - The PageAgentCore instance
|
||||||
|
* @param reason - Optional reason for disposal
|
||||||
|
*/
|
||||||
|
onDispose?: (agent: PageAgentCore, reason?: string) => void
|
||||||
|
|
||||||
// page behavior hooks
|
// page behavior hooks
|
||||||
|
|
||||||
@@ -103,21 +141,6 @@ export interface AgentConfig {
|
|||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
transformPageContent?: (content: string) => Promise<string> | string
|
transformPageContent?: (content: string) => Promise<string> | string
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: @unimplemented
|
|
||||||
* hook when action causes a new page to be opened
|
|
||||||
* @note PageAgent will try to detect new pages and decide if it's caused by an action. But not very reliable.
|
|
||||||
* @todo remove `this` binding, pass agent as explicit parameter instead
|
|
||||||
*/
|
|
||||||
// onNewPageOpen?: (this: PageAgent, url: string) => Promise<void> | void
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: @unimplemented
|
|
||||||
* try to navigate to a new page instead of opening a new tab/window.
|
|
||||||
* @note will unload the current page when a action tries to open a new page. so that things keep in the same tab/window.
|
|
||||||
*/
|
|
||||||
// experimentalPreventNewPage?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PageAgentConfig = LLMConfig & AgentConfig & PageControllerConfig
|
export type PageAgentConfig = LLMConfig & AgentConfig & PageControllerConfig
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export interface MacroToolResult {
|
|||||||
*/
|
*/
|
||||||
export interface AgentStep {
|
export interface AgentStep {
|
||||||
type: 'step'
|
type: 'step'
|
||||||
|
stepIndex: number
|
||||||
reflection: Partial<AgentReflection>
|
reflection: Partial<AgentReflection>
|
||||||
action: {
|
action: {
|
||||||
name: string
|
name: string
|
||||||
@@ -48,6 +49,8 @@ export interface AgentStep {
|
|||||||
cachedTokens?: number
|
cachedTokens?: number
|
||||||
reasoningTokens?: number
|
reasoningTokens?: number
|
||||||
}
|
}
|
||||||
|
/** Raw LLM response for debugging */
|
||||||
|
rawResponse?: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,6 +77,7 @@ export interface ErrorEvent {
|
|||||||
message: string
|
message: string
|
||||||
attempt?: number
|
attempt?: number
|
||||||
maxAttempts?: number
|
maxAttempts?: number
|
||||||
|
rawResponse?: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@page-agent/llms",
|
"name": "@page-agent/llms",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/lib/page-agent-llms.js",
|
"main": "./dist/lib/page-agent-llms.js",
|
||||||
"module": "./dist/lib/page-agent-llms.js",
|
"module": "./dist/lib/page-agent-llms.js",
|
||||||
|
|||||||
@@ -107,14 +107,23 @@ export class OpenAIClient implements LLMClient {
|
|||||||
case 'length':
|
case 'length':
|
||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.CONTEXT_LENGTH,
|
InvokeErrorType.CONTEXT_LENGTH,
|
||||||
'Response truncated: max tokens reached'
|
'Response truncated: max tokens reached',
|
||||||
|
undefined,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
case 'content_filter':
|
case 'content_filter':
|
||||||
throw new InvokeError(InvokeErrorType.CONTENT_FILTER, 'Content filtered by safety system')
|
throw new InvokeError(
|
||||||
|
InvokeErrorType.CONTENT_FILTER,
|
||||||
|
'Content filtered by safety system',
|
||||||
|
undefined,
|
||||||
|
data
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.UNKNOWN,
|
InvokeErrorType.UNKNOWN,
|
||||||
`Unexpected finish_reason: ${choice.finish_reason}`
|
`Unexpected finish_reason: ${choice.finish_reason}`,
|
||||||
|
undefined,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +137,8 @@ export class OpenAIClient implements LLMClient {
|
|||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.NO_TOOL_CALL,
|
InvokeErrorType.NO_TOOL_CALL,
|
||||||
'No tool call found in response',
|
'No tool call found in response',
|
||||||
normalizedData
|
undefined,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +147,8 @@ export class OpenAIClient implements LLMClient {
|
|||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.UNKNOWN,
|
InvokeErrorType.UNKNOWN,
|
||||||
`Tool "${toolCallName}" not found in tools`,
|
`Tool "${toolCallName}" not found in tools`,
|
||||||
normalizedData
|
undefined,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +158,8 @@ export class OpenAIClient implements LLMClient {
|
|||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.INVALID_TOOL_ARGS,
|
InvokeErrorType.INVALID_TOOL_ARGS,
|
||||||
'No tool call arguments found',
|
'No tool call arguments found',
|
||||||
normalizedData
|
undefined,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +170,8 @@ export class OpenAIClient implements LLMClient {
|
|||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.INVALID_TOOL_ARGS,
|
InvokeErrorType.INVALID_TOOL_ARGS,
|
||||||
'Failed to parse tool arguments as JSON',
|
'Failed to parse tool arguments as JSON',
|
||||||
error
|
error,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +182,8 @@ export class OpenAIClient implements LLMClient {
|
|||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.INVALID_TOOL_ARGS,
|
InvokeErrorType.INVALID_TOOL_ARGS,
|
||||||
'Tool arguments validation failed',
|
'Tool arguments validation failed',
|
||||||
validation.error
|
validation.error,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const toolInput = validation.data
|
const toolInput = validation.data
|
||||||
@@ -182,7 +196,8 @@ export class OpenAIClient implements LLMClient {
|
|||||||
throw new InvokeError(
|
throw new InvokeError(
|
||||||
InvokeErrorType.TOOL_EXECUTION_ERROR,
|
InvokeErrorType.TOOL_EXECUTION_ERROR,
|
||||||
`Tool execution failed: ${(e as Error).message}`,
|
`Tool execution failed: ${(e as Error).message}`,
|
||||||
e
|
e,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,18 @@ export class InvokeError extends Error {
|
|||||||
type: InvokeErrorType
|
type: InvokeErrorType
|
||||||
retryable: boolean
|
retryable: boolean
|
||||||
statusCode?: number
|
statusCode?: number
|
||||||
|
/* raw error (provided if this error is caused by another error) */
|
||||||
rawError?: unknown
|
rawError?: unknown
|
||||||
|
/* raw response from the API (provided if this error is caused by an API calling) */
|
||||||
|
rawResponse?: unknown
|
||||||
|
|
||||||
constructor(type: InvokeErrorType, message: string, rawError?: unknown) {
|
constructor(type: InvokeErrorType, message: string, rawError?: unknown, rawResponse?: unknown) {
|
||||||
super(message)
|
super(message)
|
||||||
this.name = 'InvokeError'
|
this.name = 'InvokeError'
|
||||||
this.type = type
|
this.type = type
|
||||||
this.retryable = this.isRetryable(type)
|
this.retryable = this.isRetryable(type)
|
||||||
this.rawError = rawError
|
this.rawError = rawError
|
||||||
|
this.rawResponse = rawResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
private isRetryable(type: InvokeErrorType): boolean {
|
private isRetryable(type: InvokeErrorType): boolean {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { DEFAULT_TEMPERATURE, LLM_MAX_RETRIES } from './constants'
|
|||||||
import { InvokeError } from './errors'
|
import { InvokeError } from './errors'
|
||||||
import type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool } from './types'
|
import type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool } from './types'
|
||||||
|
|
||||||
export type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool }
|
export type { InvokeError, InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool }
|
||||||
|
|
||||||
export function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {
|
export function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {
|
||||||
// Runtime validation as defensive programming (types already guarantee these)
|
// Runtime validation as defensive programming (types already guarantee these)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "page-agent",
|
"name": "page-agent",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/esm/page-agent.js",
|
"main": "./dist/esm/page-agent.js",
|
||||||
"module": "./dist/esm/page-agent.js",
|
"module": "./dist/esm/page-agent.js",
|
||||||
@@ -46,9 +46,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
"zod": "^4.3.5",
|
"zod": "^4.3.5",
|
||||||
"@page-agent/llms": "0.3.0",
|
"@page-agent/llms": "1.0.0-beta.4",
|
||||||
"@page-agent/page-controller": "0.3.0",
|
"@page-agent/page-controller": "1.0.0-beta.4",
|
||||||
"@page-agent/core": "0.3.0",
|
"@page-agent/core": "1.0.0-beta.4",
|
||||||
"@page-agent/ui": "0.3.0"
|
"@page-agent/ui": "1.0.0-beta.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
* Copyright (C) 2025 Alibaba Group Holding Limited
|
* Copyright (C) 2025 Alibaba Group Holding Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*/
|
*/
|
||||||
import { type PageAgentConfig, PageAgentCore } from '@page-agent/core'
|
import { type PageAgentConfig, PageAgentCore, type PageAgentTool, tool } from '@page-agent/core'
|
||||||
import { PageController } from '@page-agent/page-controller'
|
import { PageController } from '@page-agent/page-controller'
|
||||||
import { Panel } from '@page-agent/ui'
|
import { Panel } from '@page-agent/ui'
|
||||||
|
|
||||||
export type { PageAgentConfig }
|
export type { PageAgentConfig, PageAgentTool }
|
||||||
|
export { tool }
|
||||||
|
|
||||||
export class PageAgent extends PageAgentCore {
|
export class PageAgent extends PageAgentCore {
|
||||||
panel: Panel
|
panel: Panel
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ setTimeout(() => {
|
|||||||
|
|
||||||
// Create agent
|
// Create agent
|
||||||
window.pageAgent = new PageAgent(config)
|
window.pageAgent = new PageAgent(config)
|
||||||
|
window.pageAgent.panel.show()
|
||||||
|
|
||||||
console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
|
console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@page-agent/page-controller",
|
"name": "@page-agent/page-controller",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/lib/page-controller.js",
|
"main": "./dist/lib/page-controller.js",
|
||||||
"module": "./dist/lib/page-controller.js",
|
"module": "./dist/lib/page-controller.js",
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ export class PageController extends EventTarget {
|
|||||||
/** last time the tree was updated */
|
/** last time the tree was updated */
|
||||||
private lastTimeUpdate = 0
|
private lastTimeUpdate = 0
|
||||||
|
|
||||||
|
/** Whether the tree has been indexed at least once */
|
||||||
|
private isIndexed = false
|
||||||
|
|
||||||
/** Visual mask overlay for blocking user interaction during automation */
|
/** Visual mask overlay for blocking user interaction during automation */
|
||||||
private mask: InstanceType<typeof import('./mask/SimulatorMask').SimulatorMask> | null = null
|
private mask: InstanceType<typeof import('./mask/SimulatorMask').SimulatorMask> | null = null
|
||||||
private maskReady: Promise<void> | null = null
|
private maskReady: Promise<void> | null = null
|
||||||
@@ -196,6 +199,9 @@ export class PageController extends EventTarget {
|
|||||||
this.elementTextMap.clear()
|
this.elementTextMap.clear()
|
||||||
this.elementTextMap = dom.getElementTextMap(this.simplifiedHTML)
|
this.elementTextMap = dom.getElementTextMap(this.simplifiedHTML)
|
||||||
|
|
||||||
|
// Mark as indexed - now element actions are allowed
|
||||||
|
this.isIndexed = true
|
||||||
|
|
||||||
// Restore mask blocking
|
// Restore mask blocking
|
||||||
if (this.mask) {
|
if (this.mask) {
|
||||||
this.mask.wrapper.style.pointerEvents = 'auto'
|
this.mask.wrapper.style.pointerEvents = 'auto'
|
||||||
@@ -215,11 +221,22 @@ export class PageController extends EventTarget {
|
|||||||
|
|
||||||
// ======= Element Actions =======
|
// ======= Element Actions =======
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure the tree has been indexed before any index-based operation.
|
||||||
|
* Throws if updateTree() hasn't been called yet.
|
||||||
|
*/
|
||||||
|
private assertIndexed(): void {
|
||||||
|
if (!this.isIndexed) {
|
||||||
|
throw new Error('DOM tree not indexed. Can not perform actions on elements.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Click element by index
|
* Click element by index
|
||||||
*/
|
*/
|
||||||
async clickElement(index: number): Promise<ActionResult> {
|
async clickElement(index: number): Promise<ActionResult> {
|
||||||
try {
|
try {
|
||||||
|
this.assertIndexed()
|
||||||
const element = getElementByIndex(this.selectorMap, index)
|
const element = getElementByIndex(this.selectorMap, index)
|
||||||
const elemText = this.elementTextMap.get(index)
|
const elemText = this.elementTextMap.get(index)
|
||||||
await clickElement(element)
|
await clickElement(element)
|
||||||
@@ -249,6 +266,7 @@ export class PageController extends EventTarget {
|
|||||||
*/
|
*/
|
||||||
async inputText(index: number, text: string): Promise<ActionResult> {
|
async inputText(index: number, text: string): Promise<ActionResult> {
|
||||||
try {
|
try {
|
||||||
|
this.assertIndexed()
|
||||||
const element = getElementByIndex(this.selectorMap, index)
|
const element = getElementByIndex(this.selectorMap, index)
|
||||||
const elemText = this.elementTextMap.get(index)
|
const elemText = this.elementTextMap.get(index)
|
||||||
await inputTextElement(element, text)
|
await inputTextElement(element, text)
|
||||||
@@ -270,6 +288,7 @@ export class PageController extends EventTarget {
|
|||||||
*/
|
*/
|
||||||
async selectOption(index: number, optionText: string): Promise<ActionResult> {
|
async selectOption(index: number, optionText: string): Promise<ActionResult> {
|
||||||
try {
|
try {
|
||||||
|
this.assertIndexed()
|
||||||
const element = getElementByIndex(this.selectorMap, index)
|
const element = getElementByIndex(this.selectorMap, index)
|
||||||
const elemText = this.elementTextMap.get(index)
|
const elemText = this.elementTextMap.get(index)
|
||||||
await selectOptionElement(element as HTMLSelectElement, optionText)
|
await selectOptionElement(element as HTMLSelectElement, optionText)
|
||||||
@@ -298,6 +317,8 @@ export class PageController extends EventTarget {
|
|||||||
try {
|
try {
|
||||||
const { down, numPages, pixels, index } = options
|
const { down, numPages, pixels, index } = options
|
||||||
|
|
||||||
|
this.assertIndexed()
|
||||||
|
|
||||||
const scrollAmount = pixels ?? numPages * (down ? 1 : -1) * window.innerHeight
|
const scrollAmount = pixels ?? numPages * (down ? 1 : -1) * window.innerHeight
|
||||||
|
|
||||||
const element = index !== undefined ? getElementByIndex(this.selectorMap, index) : null
|
const element = index !== undefined ? getElementByIndex(this.selectorMap, index) : null
|
||||||
@@ -327,6 +348,8 @@ export class PageController extends EventTarget {
|
|||||||
try {
|
try {
|
||||||
const { right, pixels, index } = options
|
const { right, pixels, index } = options
|
||||||
|
|
||||||
|
this.assertIndexed()
|
||||||
|
|
||||||
const scrollAmount = pixels * (right ? 1 : -1)
|
const scrollAmount = pixels * (right ? 1 : -1)
|
||||||
|
|
||||||
const element = index !== undefined ? getElementByIndex(this.selectorMap, index) : null
|
const element = index !== undefined ? getElementByIndex(this.selectorMap, index) : null
|
||||||
@@ -394,6 +417,7 @@ export class PageController extends EventTarget {
|
|||||||
this.selectorMap.clear()
|
this.selectorMap.clear()
|
||||||
this.elementTextMap.clear()
|
this.elementTextMap.clear()
|
||||||
this.simplifiedHTML = '<EMPTY>'
|
this.simplifiedHTML = '<EMPTY>'
|
||||||
|
this.isIndexed = false
|
||||||
this.mask?.dispose()
|
this.mask?.dispose()
|
||||||
this.mask = null
|
this.mask = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@page-agent/ui",
|
"name": "@page-agent/ui",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/lib/page-agent-ui.js",
|
"main": "./dist/lib/page-agent-ui.js",
|
||||||
"module": "./dist/lib/page-agent-ui.js",
|
"module": "./dist/lib/page-agent-ui.js",
|
||||||
|
|||||||
@@ -563,9 +563,8 @@ export class Panel {
|
|||||||
|
|
||||||
// 2. Render each history event
|
// 2. Render each history event
|
||||||
const history = this.#agent.history
|
const history = this.#agent.history
|
||||||
for (let i = 0; i < history.length; i++) {
|
for (const event of history) {
|
||||||
const event = history[i]
|
items.push(...this.#createHistoryCards(event))
|
||||||
items.push(...this.#createHistoryCards(event, i + 1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#historySection.innerHTML = items.join('')
|
this.#historySection.innerHTML = items.join('')
|
||||||
@@ -577,14 +576,17 @@ export class Panel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Create cards for a history event */
|
/** Create cards for a history event */
|
||||||
#createHistoryCards(event: PanelAgentAdapter['history'][number], stepNumber: number): string[] {
|
#createHistoryCards(event: PanelAgentAdapter['history'][number]): string[] {
|
||||||
const cards: string[] = []
|
const cards: string[] = []
|
||||||
const time = formatTime(this.#config.language ?? 'en-US')
|
const time = formatTime(this.#config.language ?? 'en-US')
|
||||||
const meta = this.#i18n.t('ui.panel.step', {
|
const meta =
|
||||||
number: stepNumber.toString(),
|
event.type === 'step' && event.stepIndex !== undefined
|
||||||
|
? this.#i18n.t('ui.panel.step', {
|
||||||
|
number: (event.stepIndex + 1).toString(),
|
||||||
time,
|
time,
|
||||||
duration: '',
|
duration: '',
|
||||||
})
|
})
|
||||||
|
: time
|
||||||
|
|
||||||
if (event.type === 'step') {
|
if (event.type === 'step') {
|
||||||
// Reflection card
|
// Reflection card
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export interface PanelAgentAdapter extends EventTarget {
|
|||||||
/** History of agent events */
|
/** History of agent events */
|
||||||
readonly history: readonly {
|
readonly history: readonly {
|
||||||
type: 'step' | 'observation' | 'user_takeover' | 'error'
|
type: 'step' | 'observation' | 'user_takeover' | 'error'
|
||||||
|
stepIndex?: number
|
||||||
/** For 'step' type */
|
/** For 'step' type */
|
||||||
reflection?: {
|
reflection?: {
|
||||||
evaluation_previous_goal?: string
|
evaluation_previous_goal?: string
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@page-agent/website",
|
"name": "@page-agent/website",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.3.0",
|
"version": "1.0.0-beta.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host 0.0.0.0",
|
"dev": "vite --host 0.0.0.0",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"i18next-browser-languagedetector": "^8.2.0",
|
"i18next-browser-languagedetector": "^8.2.0",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-i18next": "^16.5.2",
|
"react-i18next": "^16.5.3",
|
||||||
"tailwindcss": "^4.1.14",
|
"tailwindcss": "^4.1.14",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
"wouter": "^3.9.0"
|
"wouter": "^3.9.0"
|
||||||
@@ -32,10 +32,10 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
"motion": "^12.26.1",
|
"motion": "^12.27.1",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"rough-notation": "^0.5.1",
|
"rough-notation": "^0.5.1",
|
||||||
"simple-icons": "^16.5.0",
|
"simple-icons": "^16.6.0",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"tailwind-merge": "^3.4.0"
|
"tailwind-merge": "^3.4.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Demo build (auto-init with demo LLM, for quick testing)
|
// Demo build (auto-init with demo LLM, for quick testing)
|
||||||
export const CDN_DEMO_URL = 'https://cdn.jsdelivr.net/npm/page-agent/dist/iife/page-agent.demo.js'
|
export const CDN_DEMO_URL =
|
||||||
|
'https://cdn.jsdelivr.net/npm/page-agent@1.0.0-beta.4/dist/iife/page-agent.demo.js'
|
||||||
export const CDN_DEMO_CN_URL =
|
export const CDN_DEMO_CN_URL =
|
||||||
'https://registry.npmmirror.com/page-agent/latest/files/dist/iife/page-agent.demo.js'
|
'https://registry.npmmirror.com/page-agent/1.0.0-beta.4/files/dist/iife/page-agent.demo.js'
|
||||||
|
|
||||||
// Demo LLM for website testing
|
// Demo LLM for website testing
|
||||||
export const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
export const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
||||||
|
|||||||
@@ -105,8 +105,8 @@ const result = await agent.execute('Fill in the form with test data')`}
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
description: isZh
|
description: isZh
|
||||||
? '模型名称(如 gpt-4o, claude-3.5-sonnet)'
|
? '模型名称(如 gpt-5.2, anthropic/claude-4.5-haiku)'
|
||||||
: 'Model name (e.g., gpt-4o, claude-3.5-sonnet)',
|
: 'Model name (e.g., gpt-5.2, anthropic/claude-4.5-haiku)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'temperature',
|
name: 'temperature',
|
||||||
@@ -149,6 +149,12 @@ const result = await agent.execute('Fill in the form with test data')`}
|
|||||||
defaultValue: "'en-US'",
|
defaultValue: "'en-US'",
|
||||||
description: isZh ? 'Agent 输出语言' : 'Agent output language',
|
description: isZh ? 'Agent 输出语言' : 'Agent output language',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'maxSteps',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: '20',
|
||||||
|
description: isZh ? '每个任务的最大步骤数' : 'Maximum number of steps per task',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'customTools',
|
name: 'customTools',
|
||||||
type: 'Record<string, PageAgentTool | null>',
|
type: 'Record<string, PageAgentTool | null>',
|
||||||
@@ -207,35 +213,48 @@ const result = await agent.execute('Fill in the form with test data')`}
|
|||||||
{/* Lifecycle Hooks */}
|
{/* Lifecycle Hooks */}
|
||||||
<section className="mb-10">
|
<section className="mb-10">
|
||||||
<h2 className="text-2xl font-semibold mb-4">{isZh ? '生命周期钩子' : 'Lifecycle Hooks'}</h2>
|
<h2 className="text-2xl font-semibold mb-4">{isZh ? '生命周期钩子' : 'Lifecycle Hooks'}</h2>
|
||||||
|
<div className="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg p-4 mb-4">
|
||||||
|
<p className="text-amber-800 dark:text-amber-200 text-sm">
|
||||||
|
<strong>⚠️ {isZh ? '警告' : 'Warning'}:</strong>{' '}
|
||||||
|
{isZh
|
||||||
|
? '这些接口高度实验性,可能在未来版本中发生变化。建议优先使用事件系统(Events)来监听 Agent 状态。'
|
||||||
|
: 'These APIs are highly experimental and may change in future versions. Prefer using the Events system for monitoring agent state.'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p className="text-gray-600 dark:text-gray-400 mb-4">
|
||||||
|
{isZh
|
||||||
|
? '所有生命周期钩子都接收 agent 实例作为第一个参数,便于在回调中访问 Agent 状态和方法。'
|
||||||
|
: 'All lifecycle hooks receive the agent instance as first parameter, making it easy to access agent state and methods in callbacks.'}
|
||||||
|
</p>
|
||||||
<APIReference
|
<APIReference
|
||||||
properties={[
|
properties={[
|
||||||
{
|
{
|
||||||
name: 'onBeforeStep',
|
name: 'onBeforeStep',
|
||||||
type: '(stepCnt: number) => void | Promise<void>',
|
type: '(agent: PageAgentCore, stepCount: number) => void | Promise<void>',
|
||||||
description: isZh ? '每个步骤执行前调用' : 'Called before each step execution',
|
description: isZh ? '每个步骤执行前调用' : 'Called before each step execution',
|
||||||
status: 'experimental',
|
status: 'experimental',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'onAfterStep',
|
name: 'onAfterStep',
|
||||||
type: '(history: HistoricalEvent[]) => void | Promise<void>',
|
type: '(agent: PageAgentCore, history: HistoricalEvent[]) => void | Promise<void>',
|
||||||
description: isZh ? '每个步骤执行后调用' : 'Called after each step execution',
|
description: isZh ? '每个步骤执行后调用' : 'Called after each step execution',
|
||||||
status: 'experimental',
|
status: 'experimental',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'onBeforeTask',
|
name: 'onBeforeTask',
|
||||||
type: '() => void | Promise<void>',
|
type: '(agent: PageAgentCore) => void | Promise<void>',
|
||||||
description: isZh ? '任务开始前调用' : 'Called before task starts',
|
description: isZh ? '任务开始前调用' : 'Called before task starts',
|
||||||
status: 'experimental',
|
status: 'experimental',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'onAfterTask',
|
name: 'onAfterTask',
|
||||||
type: '(result: ExecutionResult) => void | Promise<void>',
|
type: '(agent: PageAgentCore, result: ExecutionResult) => void | Promise<void>',
|
||||||
description: isZh ? '任务结束后调用' : 'Called after task ends',
|
description: isZh ? '任务结束后调用' : 'Called after task ends',
|
||||||
status: 'experimental',
|
status: 'experimental',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'onDispose',
|
name: 'onDispose',
|
||||||
type: '(reason?: string) => void',
|
type: '(agent: PageAgentCore, reason?: string) => void',
|
||||||
description: isZh ? 'Agent 销毁时调用' : 'Called when agent is disposed',
|
description: isZh ? 'Agent 销毁时调用' : 'Called when agent is disposed',
|
||||||
status: 'experimental',
|
status: 'experimental',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const agent = new PageAgent({
|
|||||||
// LLM Configuration (required)
|
// LLM Configuration (required)
|
||||||
baseURL: 'https://api.openai.com/v1',
|
baseURL: 'https://api.openai.com/v1',
|
||||||
apiKey: 'your-api-key',
|
apiKey: 'your-api-key',
|
||||||
model: 'gpt-4o',
|
model: 'gpt-5.2',
|
||||||
|
|
||||||
// Optional settings
|
// Optional settings
|
||||||
language: 'en-US',
|
language: 'en-US',
|
||||||
|
|||||||
+35
-4
@@ -9,6 +9,7 @@
|
|||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs'
|
||||||
import { dirname, join } from 'path'
|
import { dirname, join } from 'path'
|
||||||
|
import { exit } from 'process'
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||||
@@ -17,17 +18,23 @@ const rootDir = join(__dirname, '..')
|
|||||||
// Parse arguments
|
// Parse arguments
|
||||||
const versionArg = process.argv[2]
|
const versionArg = process.argv[2]
|
||||||
|
|
||||||
|
if (!versionArg) {
|
||||||
|
console.log(chalk.yellow('⚠️ No version specified.\n'))
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
// Read root package.json
|
// Read root package.json
|
||||||
const rootPkgPath = join(rootDir, 'package.json')
|
const rootPkgPath = join(rootDir, 'package.json')
|
||||||
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'))
|
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'))
|
||||||
const newVersion = versionArg || rootPkg.version
|
const oldVersion = rootPkg.version
|
||||||
|
const newVersion = versionArg
|
||||||
|
|
||||||
console.log(chalk.cyan.bold('\n📦 Syncing version\n'))
|
console.log(chalk.cyan.bold('\n📦 Syncing version\n'))
|
||||||
|
|
||||||
// Update root package.json if new version specified
|
// Update root package.json if new version specified
|
||||||
if (versionArg) {
|
if (versionArg) {
|
||||||
rootPkg.version = newVersion
|
rootPkg.version = newVersion
|
||||||
writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, '\t') + '\n')
|
writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, ' ') + '\n')
|
||||||
console.log(chalk.green('✓') + ` ${chalk.bold('root')} → ${chalk.yellow(newVersion)}`)
|
console.log(chalk.green('✓') + ` ${chalk.bold('root')} → ${chalk.yellow(newVersion)}`)
|
||||||
} else {
|
} else {
|
||||||
console.log(chalk.dim(' root:') + ` ${chalk.yellow(newVersion)} ${chalk.dim('(source)')}`)
|
console.log(chalk.dim(' root:') + ` ${chalk.yellow(newVersion)} ${chalk.dim('(source)')}`)
|
||||||
@@ -69,7 +76,6 @@ for (const pkg of packages) {
|
|||||||
if (!existsSync(pkgPath)) continue
|
if (!existsSync(pkgPath)) continue
|
||||||
|
|
||||||
const pkgJson = JSON.parse(readFileSync(pkgPath, 'utf-8'))
|
const pkgJson = JSON.parse(readFileSync(pkgPath, 'utf-8'))
|
||||||
const oldVersion = pkgJson.version
|
|
||||||
let pkgChanged = false
|
let pkgChanged = false
|
||||||
|
|
||||||
// Update package version
|
// Update package version
|
||||||
@@ -88,7 +94,7 @@ for (const pkg of packages) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(pkgPath, JSON.stringify(pkgJson, null, '\t') + '\n')
|
writeFileSync(pkgPath, JSON.stringify(pkgJson, null, ' ') + '\n')
|
||||||
console.log(
|
console.log(
|
||||||
chalk.green('✓') +
|
chalk.green('✓') +
|
||||||
` ${chalk.bold(pkgJson.name)}: ${chalk.dim(oldVersion)} → ${chalk.yellow(newVersion)}`
|
` ${chalk.bold(pkgJson.name)}: ${chalk.dim(oldVersion)} → ${chalk.yellow(newVersion)}`
|
||||||
@@ -96,6 +102,31 @@ for (const pkg of packages) {
|
|||||||
hasChanges = true
|
hasChanges = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update CDN URLs in documentation and source files
|
||||||
|
const CDN_DEMO_URL_OLD = `https://cdn.jsdelivr.net/npm/page-agent@${oldVersion}/dist/iife/page-agent.demo.js`
|
||||||
|
const CDN_DEMO_URL_NEW = `https://cdn.jsdelivr.net/npm/page-agent@${newVersion}/dist/iife/page-agent.demo.js`
|
||||||
|
const CDN_DEMO_CN_URL_OLD = `https://registry.npmmirror.com/page-agent/${oldVersion}/files/dist/iife/page-agent.demo.js`
|
||||||
|
const CDN_DEMO_CN_URL_NEW = `https://registry.npmmirror.com/page-agent/${newVersion}/files/dist/iife/page-agent.demo.js`
|
||||||
|
|
||||||
|
const filesToUpdateCdn = ['README.md', 'README-zh.md', 'packages/website/src/constants.ts']
|
||||||
|
|
||||||
|
for (const relPath of filesToUpdateCdn) {
|
||||||
|
const filePath = join(rootDir, relPath)
|
||||||
|
if (!existsSync(filePath)) continue
|
||||||
|
|
||||||
|
let content = readFileSync(filePath, 'utf-8')
|
||||||
|
const original = content
|
||||||
|
|
||||||
|
content = content.replaceAll(CDN_DEMO_URL_OLD, CDN_DEMO_URL_NEW)
|
||||||
|
content = content.replaceAll(CDN_DEMO_CN_URL_OLD, CDN_DEMO_CN_URL_NEW)
|
||||||
|
|
||||||
|
if (content !== original) {
|
||||||
|
writeFileSync(filePath, content)
|
||||||
|
console.log(chalk.green('✓') + ` ${chalk.bold(relPath)}: CDN URLs updated`)
|
||||||
|
hasChanges = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log(chalk.green.bold(`\n✓ Version synced: ${newVersion}\n`))
|
console.log(chalk.green.bold(`\n✓ Version synced: ${newVersion}\n`))
|
||||||
|
|
||||||
// Show git commands hint
|
// Show git commands hint
|
||||||
|
|||||||
Reference in New Issue
Block a user