ultimate-playwright-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/README.md +286 -0
- package/dist/browser/cdp.d.ts +37 -0
- package/dist/browser/cdp.d.ts.map +1 -0
- package/dist/browser/cdp.helpers.d.ts +13 -0
- package/dist/browser/cdp.helpers.d.ts.map +1 -0
- package/dist/browser/cdp.helpers.js +38 -0
- package/dist/browser/cdp.helpers.js.map +1 -0
- package/dist/browser/cdp.js +77 -0
- package/dist/browser/cdp.js.map +1 -0
- package/dist/browser/chrome-tab-groups.d.ts +93 -0
- package/dist/browser/chrome-tab-groups.d.ts.map +1 -0
- package/dist/browser/chrome-tab-groups.js +458 -0
- package/dist/browser/chrome-tab-groups.js.map +1 -0
- package/dist/browser/chrome.d.ts +11 -0
- package/dist/browser/chrome.d.ts.map +1 -0
- package/dist/browser/chrome.js +74 -0
- package/dist/browser/chrome.js.map +1 -0
- package/dist/browser/pw-role-snapshot.d.ts +41 -0
- package/dist/browser/pw-role-snapshot.d.ts.map +1 -0
- package/dist/browser/pw-role-snapshot.js +346 -0
- package/dist/browser/pw-role-snapshot.js.map +1 -0
- package/dist/browser/pw-session.d.ts +145 -0
- package/dist/browser/pw-session.d.ts.map +1 -0
- package/dist/browser/pw-session.js +468 -0
- package/dist/browser/pw-session.js.map +1 -0
- package/dist/browser/pw-tools-activity.d.ts +27 -0
- package/dist/browser/pw-tools-activity.d.ts.map +1 -0
- package/dist/browser/pw-tools-activity.js +52 -0
- package/dist/browser/pw-tools-activity.js.map +1 -0
- package/dist/browser/pw-tools-downloads.d.ts +40 -0
- package/dist/browser/pw-tools-downloads.d.ts.map +1 -0
- package/dist/browser/pw-tools-downloads.js +191 -0
- package/dist/browser/pw-tools-downloads.js.map +1 -0
- package/dist/browser/pw-tools-interactions.d.ts +122 -0
- package/dist/browser/pw-tools-interactions.d.ts.map +1 -0
- package/dist/browser/pw-tools-interactions.js +434 -0
- package/dist/browser/pw-tools-interactions.js.map +1 -0
- package/dist/browser/pw-tools-responses.d.ts +19 -0
- package/dist/browser/pw-tools-responses.d.ts.map +1 -0
- package/dist/browser/pw-tools-responses.js +98 -0
- package/dist/browser/pw-tools-responses.js.map +1 -0
- package/dist/browser/pw-tools-shared.d.ts +12 -0
- package/dist/browser/pw-tools-shared.d.ts.map +1 -0
- package/dist/browser/pw-tools-shared.js +55 -0
- package/dist/browser/pw-tools-shared.js.map +1 -0
- package/dist/browser/pw-tools-snapshot.d.ts +70 -0
- package/dist/browser/pw-tools-snapshot.d.ts.map +1 -0
- package/dist/browser/pw-tools-snapshot.js +151 -0
- package/dist/browser/pw-tools-snapshot.js.map +1 -0
- package/dist/browser/pw-tools-state.d.ts +52 -0
- package/dist/browser/pw-tools-state.d.ts.map +1 -0
- package/dist/browser/pw-tools-state.js +159 -0
- package/dist/browser/pw-tools-state.js.map +1 -0
- package/dist/browser/pw-tools-storage.d.ts +53 -0
- package/dist/browser/pw-tools-storage.d.ts.map +1 -0
- package/dist/browser/pw-tools-storage.js +81 -0
- package/dist/browser/pw-tools-storage.js.map +1 -0
- package/dist/browser/pw-tools-trace.d.ts +18 -0
- package/dist/browser/pw-tools-trace.d.ts.map +1 -0
- package/dist/browser/pw-tools-trace.js +31 -0
- package/dist/browser/pw-tools-trace.js.map +1 -0
- package/dist/browser/tab-groups.d.ts +94 -0
- package/dist/browser/tab-groups.d.ts.map +1 -0
- package/dist/browser/tab-groups.js +303 -0
- package/dist/browser/tab-groups.js.map +1 -0
- package/dist/browser/target-id.d.ts +20 -0
- package/dist/browser/target-id.d.ts.map +1 -0
- package/dist/browser/target-id.js +29 -0
- package/dist/browser/target-id.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/chrome-daemon.d.ts +7 -0
- package/dist/daemon/chrome-daemon.d.ts.map +1 -0
- package/dist/daemon/chrome-daemon.js +264 -0
- package/dist/daemon/chrome-daemon.js.map +1 -0
- package/dist/daemon/cli.d.ts +6 -0
- package/dist/daemon/cli.d.ts.map +1 -0
- package/dist/daemon/cli.js +110 -0
- package/dist/daemon/cli.js.map +1 -0
- package/dist/daemon/manager.d.ts +22 -0
- package/dist/daemon/manager.d.ts.map +1 -0
- package/dist/daemon/manager.js +89 -0
- package/dist/daemon/manager.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +41 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +122 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/actions.d.ts +6 -0
- package/dist/mcp/tools/actions.d.ts.map +1 -0
- package/dist/mcp/tools/actions.js +214 -0
- package/dist/mcp/tools/actions.js.map +1 -0
- package/dist/mcp/tools/navigate.d.ts +6 -0
- package/dist/mcp/tools/navigate.d.ts.map +1 -0
- package/dist/mcp/tools/navigate.js +31 -0
- package/dist/mcp/tools/navigate.js.map +1 -0
- package/dist/mcp/tools/snapshot.d.ts +6 -0
- package/dist/mcp/tools/snapshot.d.ts.map +1 -0
- package/dist/mcp/tools/snapshot.js +26 -0
- package/dist/mcp/tools/snapshot.js.map +1 -0
- package/dist/mcp/tools/tab-group.d.ts +9 -0
- package/dist/mcp/tools/tab-group.d.ts.map +1 -0
- package/dist/mcp/tools/tab-group.js +173 -0
- package/dist/mcp/tools/tab-group.js.map +1 -0
- package/dist/mcp/tools/tabs.d.ts +6 -0
- package/dist/mcp/tools/tabs.d.ts.map +1 -0
- package/dist/mcp/tools/tabs.js +209 -0
- package/dist/mcp/tools/tabs.js.map +1 -0
- package/dist/utils/command-format.d.ts +6 -0
- package/dist/utils/command-format.d.ts.map +1 -0
- package/dist/utils/command-format.js +8 -0
- package/dist/utils/command-format.js.map +1 -0
- package/dist/utils/errors.d.ts +6 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +22 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/extension-installer.d.ts +16 -0
- package/dist/utils/extension-installer.d.ts.map +1 -0
- package/dist/utils/extension-installer.js +134 -0
- package/dist/utils/extension-installer.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Patrick
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This software includes code extracted from OpenClaw (https://github.com/openclaw/openclaw),
|
|
26
|
+
which is also MIT licensed. See individual source files for attribution.
|
package/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Ultimate Playwright MCP
|
|
2
|
+
|
|
3
|
+
Multi-agent Playwright MCP server with tab isolation via `targetId`. Allows multiple Claude instances (or other MCP clients) to share a single Chrome browser while maintaining isolated tab groups.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Tab Isolation** - Each agent gets its own tabs via unique `targetId`
|
|
8
|
+
- ✅ **Shared Cookies** - All agents share the same BrowserContext (cookies, sessions, localStorage)
|
|
9
|
+
- ✅ **Parallel Execution** - Multiple agents can operate simultaneously without interference
|
|
10
|
+
- ✅ **CDP Connection** - Connects to existing Chrome via Chrome DevTools Protocol
|
|
11
|
+
- ✅ **Battle-Tested** - Extracted from [OpenClaw](https://github.com/openclaw/openclaw) (MIT licensed)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g ultimate-playwright-mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or run directly with npx:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx ultimate-playwright-mcp --cdp-endpoint http://localhost:9222
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### 1. Launch Chrome with Remote Debugging
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# macOS
|
|
31
|
+
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
|
|
32
|
+
--remote-debugging-port=9222 \
|
|
33
|
+
--user-data-dir=/tmp/chrome-debug
|
|
34
|
+
|
|
35
|
+
# Linux
|
|
36
|
+
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug
|
|
37
|
+
|
|
38
|
+
# Windows
|
|
39
|
+
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ^
|
|
40
|
+
--remote-debugging-port=9222 ^
|
|
41
|
+
--user-data-dir=C:\\temp\\chrome-debug
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Configure Claude Desktop
|
|
45
|
+
|
|
46
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"ultimate-playwright": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": [
|
|
54
|
+
"ultimate-playwright-mcp",
|
|
55
|
+
"--cdp-endpoint",
|
|
56
|
+
"http://localhost:9222"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 3. Restart Claude Desktop
|
|
64
|
+
|
|
65
|
+
Claude will now have access to browser control tools with tab isolation.
|
|
66
|
+
|
|
67
|
+
## Usage Example
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
User: Open two tabs and navigate them independently
|
|
71
|
+
|
|
72
|
+
Claude: I'll create two tabs with separate targetIds:
|
|
73
|
+
|
|
74
|
+
1. browser_tabs({ action: "new" })
|
|
75
|
+
→ **targetId: ABC123...**
|
|
76
|
+
|
|
77
|
+
2. browser_tabs({ action: "new" })
|
|
78
|
+
→ **targetId: XYZ789...**
|
|
79
|
+
|
|
80
|
+
3. browser_navigate({ targetId: "ABC123...", url: "https://github.com" })
|
|
81
|
+
4. browser_navigate({ targetId: "XYZ789...", url: "https://google.com" })
|
|
82
|
+
|
|
83
|
+
Both tabs are now navigated independently!
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Available Tools
|
|
87
|
+
|
|
88
|
+
| Tool | Description | Key Parameters |
|
|
89
|
+
|------|-------------|----------------|
|
|
90
|
+
| `browser_tab_group` | Create/list/delete tab groups for isolation | `action`, `name`, `color`, `groupId` |
|
|
91
|
+
| `browser_tabs` | List, create, close, or select tabs | `action`, `groupId`, `targetId`, `index` |
|
|
92
|
+
| `browser_navigate` | Navigate to a URL | `url`, `targetId` |
|
|
93
|
+
| `browser_snapshot` | Capture accessibility tree with refs | `targetId` |
|
|
94
|
+
| `browser_click` | Click an element | `ref`, `targetId` |
|
|
95
|
+
| `browser_type` | Type text into an element | `ref`, `text`, `targetId` |
|
|
96
|
+
| `browser_hover` | Hover over an element | `ref`, `targetId` |
|
|
97
|
+
| `browser_press_key` | Press a keyboard key | `key`, `targetId` |
|
|
98
|
+
| `browser_fill_form` | Fill multiple form fields | `fields`, `targetId` |
|
|
99
|
+
| `browser_wait_for` | Wait for conditions | `text`, `selector`, `url`, `loadState`, `targetId` |
|
|
100
|
+
|
|
101
|
+
## Tab Groups (Multi-User Isolation)
|
|
102
|
+
|
|
103
|
+
When multiple users or agents share one browser instance, tab groups keep everyone's
|
|
104
|
+
tabs isolated. Each session creates its own group, and all tab operations are scoped
|
|
105
|
+
to that group.
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
User: Research product pricing
|
|
109
|
+
|
|
110
|
+
Claude: I'll create a tab group first, then open tabs within it.
|
|
111
|
+
|
|
112
|
+
1. browser_tab_group({ action: "create", name: "pricing-research", color: "blue" })
|
|
113
|
+
→ **groupId: g_a1b2c3d4e5f6**
|
|
114
|
+
|
|
115
|
+
2. browser_tabs({ action: "new", groupId: "g_a1b2c3d4e5f6", url: "https://example.com/pricing" })
|
|
116
|
+
→ **targetId: ABC123...**
|
|
117
|
+
|
|
118
|
+
3. browser_tabs({ action: "list", groupId: "g_a1b2c3d4e5f6" })
|
|
119
|
+
→ Only shows tabs in this group (not other users' tabs)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Meanwhile, another user on the same server:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
1. browser_tab_group({ action: "create", name: "docs-review", color: "green" })
|
|
126
|
+
→ **groupId: g_x9y8z7w6v5u4**
|
|
127
|
+
|
|
128
|
+
2. browser_tabs({ action: "new", groupId: "g_x9y8z7w6v5u4", url: "https://docs.example.com" })
|
|
129
|
+
→ **targetId: XYZ789...**
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Both users share the same cookies/sessions but only see their own tabs!
|
|
133
|
+
|
|
134
|
+
### Tab Group Lifecycle
|
|
135
|
+
|
|
136
|
+
1. **Create** a group at the start of your session
|
|
137
|
+
2. **Open tabs** within the group using `groupId`
|
|
138
|
+
3. **Work** with tabs using `targetId` as before
|
|
139
|
+
4. **Delete** the group when done (optionally closes all tabs)
|
|
140
|
+
|
|
141
|
+
Group state is persisted to `~/.ultimate-playwright-mcp/tab-groups.json` so it
|
|
142
|
+
survives MCP server restarts.
|
|
143
|
+
|
|
144
|
+
## Architecture
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
┌─────────────────────────────────────────────┐
|
|
148
|
+
│ Single Chrome Process │
|
|
149
|
+
│ (--remote-debugging-port=9222) │
|
|
150
|
+
│ ┌─────────────────────────────────────┐ │
|
|
151
|
+
│ │ Single BrowserContext │ │
|
|
152
|
+
│ │ (shared cookies, storage) │ │
|
|
153
|
+
│ │ │ │
|
|
154
|
+
│ │ Group: alice (blue) │ │
|
|
155
|
+
│ │ ┌─────┐ ┌─────┐ │ │
|
|
156
|
+
│ │ │ Tab │ │ Tab │ │ │
|
|
157
|
+
│ │ │ A │ │ B │ │ │
|
|
158
|
+
│ │ └─────┘ └─────┘ │ │
|
|
159
|
+
│ │ │ │
|
|
160
|
+
│ │ Group: bob (green) │ │
|
|
161
|
+
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
|
|
162
|
+
│ │ │ Tab │ │ Tab │ │ Tab │ │ │
|
|
163
|
+
│ │ │ C │ │ D │ │ E │ │ │
|
|
164
|
+
│ │ └─────┘ └─────┘ └─────┘ │ │
|
|
165
|
+
│ └─────────────────────────────────────┘ │
|
|
166
|
+
└─────────────────────────────────────────────┘
|
|
167
|
+
↑
|
|
168
|
+
CDP Connection
|
|
169
|
+
↓
|
|
170
|
+
┌─────────────────────────────────────────────┐
|
|
171
|
+
│ ultimate-playwright-mcp (MCP Server) │
|
|
172
|
+
│ - Tab routing via targetId │
|
|
173
|
+
│ - Tab groups via groupId │
|
|
174
|
+
│ - Shared ownership registry (JSON file) │
|
|
175
|
+
│ - Stdio transport │
|
|
176
|
+
└─────────────────────────────────────────────┘
|
|
177
|
+
↓ ↓ ↓
|
|
178
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
179
|
+
│ Alice │ │ Bob │ │ Charlie │
|
|
180
|
+
│ (Claude)│ │ (Claude)│ │ (Cursor)│
|
|
181
|
+
└─────────┘ └─────────┘ └─────────┘
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## CLI Options
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
ultimate-playwright-mcp [options]
|
|
188
|
+
|
|
189
|
+
Options:
|
|
190
|
+
--cdp-endpoint <url> CDP endpoint URL (e.g., http://localhost:9222)
|
|
191
|
+
Can also use CDP_ENDPOINT env var
|
|
192
|
+
--agent-id <id> Optional agent ID for logging/debugging
|
|
193
|
+
Can also use AGENT_ID env var
|
|
194
|
+
-V, --version Output version number
|
|
195
|
+
-h, --help Display help
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Multi-Agent Setup
|
|
199
|
+
|
|
200
|
+
### Running Multiple Claude Code Instances
|
|
201
|
+
|
|
202
|
+
Each instance connects to the same MCP server and gets isolated tabs:
|
|
203
|
+
|
|
204
|
+
**Terminal 1:**
|
|
205
|
+
```bash
|
|
206
|
+
claude-code --mcp-config ./mcp-config.json
|
|
207
|
+
# Agent A creates tabs with targetIds starting from ABC...
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Terminal 2:**
|
|
211
|
+
```bash
|
|
212
|
+
claude-code --mcp-config ./mcp-config.json
|
|
213
|
+
# Agent B creates tabs with targetIds starting from XYZ...
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Both agents share cookies and sessions but operate on different tabs!
|
|
217
|
+
|
|
218
|
+
## Persistent Chrome Setup (macOS)
|
|
219
|
+
|
|
220
|
+
For a Chrome instance that auto-starts with debug port:
|
|
221
|
+
|
|
222
|
+
Create `~/Library/LaunchAgents/com.user.chrome-debug.plist`:
|
|
223
|
+
|
|
224
|
+
```xml
|
|
225
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
226
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
227
|
+
<plist version="1.0">
|
|
228
|
+
<dict>
|
|
229
|
+
<key>Label</key>
|
|
230
|
+
<string>com.user.chrome-debug</string>
|
|
231
|
+
<key>ProgramArguments</key>
|
|
232
|
+
<array>
|
|
233
|
+
<string>/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</string>
|
|
234
|
+
<string>--remote-debugging-port=9222</string>
|
|
235
|
+
<string>--user-data-dir=/Users/YOUR_USERNAME/chrome-debug-profile</string>
|
|
236
|
+
</array>
|
|
237
|
+
<key>RunAtLoad</key>
|
|
238
|
+
<true/>
|
|
239
|
+
<key>KeepAlive</key>
|
|
240
|
+
<true/>
|
|
241
|
+
</dict>
|
|
242
|
+
</plist>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Load with:
|
|
246
|
+
```bash
|
|
247
|
+
launchctl load ~/Library/LaunchAgents/com.user.chrome-debug.plist
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Development
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Install dependencies
|
|
254
|
+
npm install
|
|
255
|
+
|
|
256
|
+
# Build
|
|
257
|
+
npm run build
|
|
258
|
+
|
|
259
|
+
# Type check
|
|
260
|
+
npm run type-check
|
|
261
|
+
|
|
262
|
+
# Lint
|
|
263
|
+
npm run lint
|
|
264
|
+
|
|
265
|
+
# Watch mode
|
|
266
|
+
npm run watch
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
MIT
|
|
272
|
+
|
|
273
|
+
## Attribution
|
|
274
|
+
|
|
275
|
+
This project extracts browser control code from [OpenClaw](https://github.com/openclaw/openclaw) (MIT licensed), which provides battle-tested tab isolation and Playwright integration.
|
|
276
|
+
|
|
277
|
+
Key extracted components:
|
|
278
|
+
- CDP session management (`pw-session.ts`)
|
|
279
|
+
- Browser operations (`pw-tools-*.ts`)
|
|
280
|
+
- Role-based element refs (`pw-role-snapshot.ts`)
|
|
281
|
+
|
|
282
|
+
## Links
|
|
283
|
+
|
|
284
|
+
- [OpenClaw](https://github.com/openclaw/openclaw) - Source of browser control code
|
|
285
|
+
- [MCP Specification](https://spec.modelcontextprotocol.io/) - Model Context Protocol
|
|
286
|
+
- [Playwright](https://playwright.dev/) - Browser automation library
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracted from OpenClaw (https://github.com/openclaw/openclaw)
|
|
3
|
+
* Original: src/browser/cdp.ts
|
|
4
|
+
* License: MIT
|
|
5
|
+
*
|
|
6
|
+
* Modified for ultimate-playwright-mcp:
|
|
7
|
+
* - Extracted only AriaSnapshot types and formatting needed by pw-tools-snapshot.ts
|
|
8
|
+
* - Removed WebSocket-based CDP operations (Playwright handles this)
|
|
9
|
+
*/
|
|
10
|
+
export type AriaSnapshotNode = {
|
|
11
|
+
ref: string;
|
|
12
|
+
role: string;
|
|
13
|
+
name: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
backendDOMNodeId?: number;
|
|
17
|
+
depth: number;
|
|
18
|
+
};
|
|
19
|
+
export type RawAXNode = {
|
|
20
|
+
nodeId?: string;
|
|
21
|
+
role?: {
|
|
22
|
+
value?: string;
|
|
23
|
+
};
|
|
24
|
+
name?: {
|
|
25
|
+
value?: string;
|
|
26
|
+
};
|
|
27
|
+
value?: {
|
|
28
|
+
value?: string;
|
|
29
|
+
};
|
|
30
|
+
description?: {
|
|
31
|
+
value?: string;
|
|
32
|
+
};
|
|
33
|
+
childIds?: string[];
|
|
34
|
+
backendDOMNodeId?: number;
|
|
35
|
+
};
|
|
36
|
+
export declare function formatAriaSnapshot(nodes: RawAXNode[], limit: number): AriaSnapshotNode[];
|
|
37
|
+
//# sourceMappingURL=cdp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.d.ts","sourceRoot":"","sources":["../../src/browser/cdp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,WAAW,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAgBF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAyDxF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracted from OpenClaw (https://github.com/openclaw/openclaw)
|
|
3
|
+
* Original: src/browser/cdp.helpers.ts
|
|
4
|
+
* License: MIT
|
|
5
|
+
*
|
|
6
|
+
* Modified for ultimate-playwright-mcp:
|
|
7
|
+
* - Removed WebSocket-based CDP sender (Playwright handles this)
|
|
8
|
+
* - Removed extension relay dependencies
|
|
9
|
+
* - Kept only URL/auth helpers needed by pw-session.ts
|
|
10
|
+
*/
|
|
11
|
+
export declare function isLoopbackHost(host: string): boolean;
|
|
12
|
+
export declare function getHeadersWithAuth(url: string, headers?: Record<string, string>): Record<string, string>;
|
|
13
|
+
//# sourceMappingURL=cdp.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.helpers.d.ts","sourceRoot":"","sources":["../../src/browser/cdp.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,WAW1C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,0BAiBnF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracted from OpenClaw (https://github.com/openclaw/openclaw)
|
|
3
|
+
* Original: src/browser/cdp.helpers.ts
|
|
4
|
+
* License: MIT
|
|
5
|
+
*
|
|
6
|
+
* Modified for ultimate-playwright-mcp:
|
|
7
|
+
* - Removed WebSocket-based CDP sender (Playwright handles this)
|
|
8
|
+
* - Removed extension relay dependencies
|
|
9
|
+
* - Kept only URL/auth helpers needed by pw-session.ts
|
|
10
|
+
*/
|
|
11
|
+
export function isLoopbackHost(host) {
|
|
12
|
+
const h = host.trim().toLowerCase();
|
|
13
|
+
return (h === "localhost" ||
|
|
14
|
+
h === "127.0.0.1" ||
|
|
15
|
+
h === "0.0.0.0" ||
|
|
16
|
+
h === "[::1]" ||
|
|
17
|
+
h === "::1" ||
|
|
18
|
+
h === "[::]" ||
|
|
19
|
+
h === "::");
|
|
20
|
+
}
|
|
21
|
+
export function getHeadersWithAuth(url, headers = {}) {
|
|
22
|
+
try {
|
|
23
|
+
const parsed = new URL(url);
|
|
24
|
+
const hasAuthHeader = Object.keys(headers).some((key) => key.toLowerCase() === "authorization");
|
|
25
|
+
if (hasAuthHeader) {
|
|
26
|
+
return headers;
|
|
27
|
+
}
|
|
28
|
+
if (parsed.username || parsed.password) {
|
|
29
|
+
const auth = Buffer.from(`${parsed.username}:${parsed.password}`).toString("base64");
|
|
30
|
+
return { ...headers, Authorization: `Basic ${auth}` };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// ignore
|
|
35
|
+
}
|
|
36
|
+
return headers;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=cdp.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.helpers.js","sourceRoot":"","sources":["../../src/browser/cdp.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,CACL,CAAC,KAAK,WAAW;QACjB,CAAC,KAAK,WAAW;QACjB,CAAC,KAAK,SAAS;QACf,CAAC,KAAK,OAAO;QACb,CAAC,KAAK,KAAK;QACX,CAAC,KAAK,MAAM;QACZ,CAAC,KAAK,IAAI,CACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,UAAkC,EAAE;IAClF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAC7C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,eAAe,CAC/C,CAAC;QACF,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACrF,OAAO,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC;QACxD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracted from OpenClaw (https://github.com/openclaw/openclaw)
|
|
3
|
+
* Original: src/browser/cdp.ts
|
|
4
|
+
* License: MIT
|
|
5
|
+
*
|
|
6
|
+
* Modified for ultimate-playwright-mcp:
|
|
7
|
+
* - Extracted only AriaSnapshot types and formatting needed by pw-tools-snapshot.ts
|
|
8
|
+
* - Removed WebSocket-based CDP operations (Playwright handles this)
|
|
9
|
+
*/
|
|
10
|
+
function axValue(v) {
|
|
11
|
+
if (!v || typeof v !== "object") {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
const value = v.value;
|
|
15
|
+
if (typeof value === "string") {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
19
|
+
return String(value);
|
|
20
|
+
}
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
export function formatAriaSnapshot(nodes, limit) {
|
|
24
|
+
const byId = new Map();
|
|
25
|
+
for (const n of nodes) {
|
|
26
|
+
if (n.nodeId) {
|
|
27
|
+
byId.set(n.nodeId, n);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Heuristic: pick a root-ish node (one that is not referenced as a child), else first.
|
|
31
|
+
const referenced = new Set();
|
|
32
|
+
for (const n of nodes) {
|
|
33
|
+
for (const c of n.childIds ?? []) {
|
|
34
|
+
referenced.add(c);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const root = nodes.find((n) => n.nodeId && !referenced.has(n.nodeId)) ?? nodes[0];
|
|
38
|
+
if (!root?.nodeId) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
const out = [];
|
|
42
|
+
const stack = [{ id: root.nodeId, depth: 0 }];
|
|
43
|
+
while (stack.length && out.length < limit) {
|
|
44
|
+
const popped = stack.pop();
|
|
45
|
+
if (!popped) {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
const { id, depth } = popped;
|
|
49
|
+
const n = byId.get(id);
|
|
50
|
+
if (!n) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const role = axValue(n.role);
|
|
54
|
+
const name = axValue(n.name);
|
|
55
|
+
const value = axValue(n.value);
|
|
56
|
+
const description = axValue(n.description);
|
|
57
|
+
const ref = `ax${out.length + 1}`;
|
|
58
|
+
out.push({
|
|
59
|
+
ref,
|
|
60
|
+
role: role || "unknown",
|
|
61
|
+
name: name || "",
|
|
62
|
+
...(value ? { value } : {}),
|
|
63
|
+
...(description ? { description } : {}),
|
|
64
|
+
...(typeof n.backendDOMNodeId === "number" ? { backendDOMNodeId: n.backendDOMNodeId } : {}),
|
|
65
|
+
depth,
|
|
66
|
+
});
|
|
67
|
+
const children = (n.childIds ?? []).filter((c) => byId.has(c));
|
|
68
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
69
|
+
const child = children[i];
|
|
70
|
+
if (child) {
|
|
71
|
+
stack.push({ id: child, depth: depth + 1 });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=cdp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../src/browser/cdp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chrome visual tab groups via the companion extension.
|
|
3
|
+
*
|
|
4
|
+
* Connects to the "UltimatePW Tab Grouper" extension's service worker
|
|
5
|
+
* via CDP and calls its global helpers (groupTabs, ungroupTabs, etc.)
|
|
6
|
+
* to manage native Chrome tab groups with titles and colors.
|
|
7
|
+
*
|
|
8
|
+
* Falls back gracefully — if the extension isn't loaded, visual grouping
|
|
9
|
+
* is simply skipped and a warning is returned.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Compute a Chrome unpacked extension ID from its absolute directory path.
|
|
13
|
+
* Chrome uses SHA-256 of the path, maps each nibble to a-p.
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeExtensionId(extensionPath: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Pre-seed the extension ID from a known path. Call this during server init
|
|
18
|
+
* so the wake mechanism works even before the first probe succeeds.
|
|
19
|
+
*/
|
|
20
|
+
export declare function seedExtensionIdFromPath(extensionPath: string): void;
|
|
21
|
+
export declare class ExtensionNotFoundError extends Error {
|
|
22
|
+
constructor();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check whether the companion extension is available.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Warm up: discover and cache the extension ID while the SW is still alive
|
|
29
|
+
* (should be called soon after Chrome starts). Best-effort, non-blocking.
|
|
30
|
+
*/
|
|
31
|
+
export declare function warmupTabGrouper(cdpUrl: string): Promise<void>;
|
|
32
|
+
export declare function isTabGrouperAvailable(cdpUrl: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Get the Chrome tab ID for a given URL + title combo.
|
|
35
|
+
* We need this to bridge CDP targetId → Chrome tab ID.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getChromeTabId(cdpUrl: string, targetUrl: string, targetTitle?: string): Promise<number | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Map CDP targetIds to Chrome tab IDs by correlating URL/title.
|
|
40
|
+
* Returns a map of targetId → chromeTabId.
|
|
41
|
+
*/
|
|
42
|
+
export declare function mapTargetIdsToChromeTabIds(cdpUrl: string, targets: Array<{
|
|
43
|
+
targetId: string;
|
|
44
|
+
url: string;
|
|
45
|
+
title: string;
|
|
46
|
+
}>): Promise<Map<string, number>>;
|
|
47
|
+
/**
|
|
48
|
+
* Group Chrome tabs visually with a title and color.
|
|
49
|
+
* @param chromeTabIds - Chrome internal tab IDs (not CDP targetIds)
|
|
50
|
+
* @param title - Group title
|
|
51
|
+
* @param color - grey|blue|red|yellow|green|pink|purple|cyan
|
|
52
|
+
* @param existingGroupId - If provided, add to an existing Chrome group
|
|
53
|
+
* @returns Chrome's groupId
|
|
54
|
+
*/
|
|
55
|
+
export declare function groupTabsVisually(cdpUrl: string, chromeTabIds: number[], title: string, color: string, existingGroupId?: number): Promise<{
|
|
56
|
+
groupId: number;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Remove tabs from their Chrome visual group.
|
|
60
|
+
*/
|
|
61
|
+
export declare function ungroupTabsVisually(cdpUrl: string, chromeTabIds: number[]): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Update a Chrome visual group's title/color/collapsed state.
|
|
64
|
+
*/
|
|
65
|
+
export declare function updateVisualGroup(cdpUrl: string, chromeGroupId: number, updates: {
|
|
66
|
+
title?: string;
|
|
67
|
+
color?: string;
|
|
68
|
+
collapsed?: boolean;
|
|
69
|
+
}): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* List all Chrome visual tab groups.
|
|
72
|
+
*/
|
|
73
|
+
export declare function listVisualTabGroups(cdpUrl: string): Promise<Array<{
|
|
74
|
+
id: number;
|
|
75
|
+
title: string;
|
|
76
|
+
color: string;
|
|
77
|
+
collapsed: boolean;
|
|
78
|
+
}>>;
|
|
79
|
+
/**
|
|
80
|
+
* Create a tab via the extension (gives us the Chrome tab ID directly).
|
|
81
|
+
* This avoids the unreliable URL-based mapping from CDP targetIds.
|
|
82
|
+
* Returns both the Chrome tabId and the CDP targetId.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createTabViaExtension(cdpUrl: string, url: string): Promise<{
|
|
85
|
+
chromeTabId: number;
|
|
86
|
+
targetId: string;
|
|
87
|
+
url: string;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Close a tab via the extension using its Chrome tab ID.
|
|
91
|
+
*/
|
|
92
|
+
export declare function closeTabViaExtension(cdpUrl: string, chromeTabId: number): Promise<void>;
|
|
93
|
+
//# sourceMappingURL=chrome-tab-groups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome-tab-groups.d.ts","sourceRoot":"","sources":["../../src/browser/chrome-tab-groups.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0CH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAUhE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAInE;AAsSD,qBAAa,sBAAuB,SAAQ,KAAK;;CAQhD;AAID;;GAEG;AACH;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpE;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG5E;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqBxB;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/D,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkC9B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ9B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAOlF;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CA4CjE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf"}
|