e2e-pilot 0.0.69 → 0.0.71

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.
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>E2E Pilot</title>
7
+ <script type="module" crossorigin src="./popup/popup.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./popup/popup.css">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,335 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Welcome to E2E Pilot MCP</title>
7
+ <style>
8
+ :root {
9
+ --color-bg: #ffffff;
10
+ --color-text: #262626;
11
+ --color-heading: #171717;
12
+ --color-border: #d4d4d4;
13
+ --color-code-bg: #f5f5f5;
14
+ --color-link: #0969da;
15
+ --color-link-hover: #0550ae;
16
+ --color-success: #16a34a;
17
+ --color-muted: #737373;
18
+ --max-width: 640px;
19
+ --spacing: 1.5rem;
20
+ }
21
+
22
+ @media (prefers-color-scheme: dark) {
23
+ :root {
24
+ --color-bg: #0a0a0a;
25
+ --color-text: #e5e5e5;
26
+ --color-heading: #fafafa;
27
+ --color-border: #404040;
28
+ --color-code-bg: #171717;
29
+ --color-link: #4493f8;
30
+ --color-link-hover: #539bf5;
31
+ --color-success: #22c55e;
32
+ --color-muted: #a3a3a3;
33
+ }
34
+ }
35
+
36
+ * {
37
+ margin: 0;
38
+ padding: 0;
39
+ box-sizing: border-box;
40
+ }
41
+
42
+ body {
43
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
44
+ Helvetica, Arial, sans-serif;
45
+ font-size: 16px;
46
+ line-height: 1.6;
47
+ color: var(--color-text);
48
+ background-color: var(--color-bg);
49
+ padding: 2rem 1rem;
50
+ }
51
+
52
+ main {
53
+ max-width: var(--max-width);
54
+ margin: 0 auto;
55
+ }
56
+
57
+ h2 {
58
+ font-size: 1.75rem;
59
+ font-weight: 600;
60
+ color: var(--color-heading);
61
+ margin-top: 2rem;
62
+ margin-bottom: 1rem;
63
+ padding-bottom: 0.5rem;
64
+ border-bottom: 1px solid var(--color-border);
65
+ }
66
+
67
+ h3 {
68
+ font-size: 1.25rem;
69
+ font-weight: 600;
70
+ color: var(--color-heading);
71
+ margin-top: 1.5rem;
72
+ margin-bottom: 0.75rem;
73
+ }
74
+
75
+ p {
76
+ margin-bottom: 1rem;
77
+ }
78
+
79
+ a {
80
+ color: var(--color-link);
81
+ text-decoration: none;
82
+ }
83
+
84
+ a:hover {
85
+ color: var(--color-link-hover);
86
+ text-decoration: underline;
87
+ }
88
+
89
+ code {
90
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
91
+ "Liberation Mono", monospace;
92
+ font-size: 0.875em;
93
+ background-color: var(--color-code-bg);
94
+ padding: 0.2em 0.4em;
95
+ border-radius: 6px;
96
+ }
97
+
98
+ pre {
99
+ background-color: var(--color-code-bg);
100
+ padding: 1rem;
101
+ border-radius: 6px;
102
+ overflow-x: auto;
103
+ margin-bottom: 1rem;
104
+ border: 1px solid var(--color-border);
105
+ }
106
+
107
+ pre code {
108
+ background-color: transparent;
109
+ padding: 0;
110
+ font-size: 0.875rem;
111
+ }
112
+
113
+ ol,
114
+ ul {
115
+ margin-bottom: 1rem;
116
+ padding-left: 2rem;
117
+ }
118
+
119
+ li {
120
+ margin-bottom: 0.5rem;
121
+ }
122
+
123
+ strong {
124
+ font-weight: 600;
125
+ color: var(--color-heading);
126
+ }
127
+
128
+
129
+
130
+ .step-number {
131
+ color: var(--color-link);
132
+ font-weight: 700;
133
+ font-size: 1.125rem;
134
+ margin-right: 0.75rem;
135
+ flex-shrink: 0;
136
+ line-height: 1.6;
137
+ }
138
+
139
+ .step {
140
+ display: flex;
141
+ align-items: flex-start;
142
+ margin-bottom: 1.5rem;
143
+ }
144
+
145
+ .step-content {
146
+ flex: 1;
147
+ }
148
+
149
+ .install-button {
150
+ display: inline-flex;
151
+ align-items: center;
152
+ gap: 0.5rem;
153
+ padding: 0.5rem 1rem;
154
+ background-color: #262626;
155
+ color: #fff;
156
+ border-radius: 0.5rem;
157
+ text-decoration: none;
158
+ transition: background-color 0.15s;
159
+ font-size: 0.875rem;
160
+ font-weight: 500;
161
+ margin-top: 0.5rem;
162
+ }
163
+
164
+ .install-button:hover {
165
+ background-color: #404040;
166
+ color: #fff;
167
+ text-decoration: none;
168
+ }
169
+
170
+ .install-button svg {
171
+ width: 1.25rem;
172
+ height: 1.25rem;
173
+ }
174
+
175
+ footer {
176
+ margin-top: 3rem;
177
+ padding-top: 2rem;
178
+ border-top: 1px solid var(--color-border);
179
+ text-align: center;
180
+ color: var(--color-muted);
181
+ font-size: 0.875rem;
182
+ }
183
+ </style>
184
+ </head>
185
+ <body>
186
+ <main>
187
+ <section>
188
+ <h2>Getting Started with E2E Pilot MCP</h2>
189
+
190
+ <p>
191
+ Control your browser via extension instead of spawning a full new
192
+ Chrome window. Uses less context window by running Playwright CDP
193
+ protocol directly. Collaborate with your agent and help get it
194
+ unstuck when needed.
195
+ </p>
196
+
197
+ <h3>Quick Start</h3>
198
+
199
+ <div class="step">
200
+ <span class="step-number">1</span>
201
+ <div class="step-content">
202
+ <strong>Pin this extension on Chrome toolbar</strong>
203
+ <p>
204
+ Click the puzzle icon in your Chrome toolbar and pin the
205
+ E2E Pilot MCP extension for easy access.
206
+ </p>
207
+ </div>
208
+ </div>
209
+
210
+ <div class="step">
211
+ <span class="step-number">2</span>
212
+ <div class="step-content">
213
+ <strong>Click the extension icon</strong>
214
+ <p>
215
+ Click the E2E Pilot MCP extension icon in your browser toolbar
216
+ to attach the debugger to the current tab. The icon will turn
217
+ green when successfully connected.
218
+ </p>
219
+ </div>
220
+ </div>
221
+
222
+ <div class="step">
223
+ <span class="step-number">3</span>
224
+ <div class="step-content">
225
+ <strong>Add the MCP to your agent</strong>
226
+ <p>
227
+ Add the following configuration to your MCP client settings (e.g.,
228
+ Claude Desktop's <code>claude_desktop_config.json</code>):
229
+ </p>
230
+ <pre><code>{
231
+ "mcpServers": {
232
+ "e2e-pilot": {
233
+ "command": "npx",
234
+ "args": [
235
+ "-y",
236
+ "e2e-pilot@latest"
237
+ ]
238
+ }
239
+ }
240
+ }</code></pre>
241
+ <p>
242
+ Or install directly in Cursor:
243
+ </p>
244
+ <a
245
+ href="https://cursor.com/en/install-mcp?name=playwriter&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJwbGF5d3JpdGVyQGxhdGVzdCJdfQ%3D%3D"
246
+ target="_blank"
247
+ rel="noopener noreferrer"
248
+ class="install-button"
249
+ >
250
+ <svg viewBox="0 0 466.73 533.32" xmlns="http://www.w3.org/2000/svg">
251
+ <path d="m233.37 266.66 231.16 133.46c-1.42 2.46-3.48 4.56-6.03 6.03l-216.06 124.74c-5.61 3.24-12.53 3.24-18.14 0l-216.06-124.74c-2.55-1.47-4.61-3.57-6.03-6.03z" fill="#72716d"/>
252
+ <path d="m233.37 0v266.66l-231.16 133.46c-1.42-2.46-2.21-5.3-2.21-8.24v-250.44c0-5.89 3.14-11.32 8.24-14.27l216.05-124.74c2.81-1.62 5.94-2.43 9.07-2.43z" fill="#55544f"/>
253
+ <path d="m464.52 133.2c-1.42-2.46-3.48-4.56-6.03-6.03l-216.06-124.74c-2.8-1.62-5.93-2.43-9.06-2.43v266.66l231.16 133.46c1.42-2.46 2.21-5.3 2.21-8.24v-250.44c0-2.95-.78-5.77-2.21-8.24z" fill="#43413c"/>
254
+ <path d="m448.35 142.54c1.31 2.26 1.49 5.16 0 7.74l-209.83 363.42c-1.41 2.46-5.16 1.45-5.16-1.38v-239.48c0-1.91-.51-3.75-1.44-5.36l216.42-124.95h.01z" fill="#d6d5d2"/>
255
+ <path d="m448.35 142.54-216.42 124.95c-.92-1.6-2.26-2.96-3.92-3.92l-207.39-119.74c-2.46-1.41-1.45-5.16 1.38-5.16h419.65c2.98 0 5.4 1.61 6.7 3.87z" fill="#fff"/>
256
+ </svg>
257
+ Install in Cursor
258
+ </a>
259
+ <p style="margin-top: 1rem;">
260
+ This will enable your AI assistant to control the browser through
261
+ the extension.
262
+ </p>
263
+ </div>
264
+ </div>
265
+ </section>
266
+
267
+ <section>
268
+ <h2>How It Works</h2>
269
+
270
+ <ul>
271
+ <li>
272
+ <strong>No new Chrome instances:</strong> Works with your current
273
+ browser session
274
+ </li>
275
+ <li>
276
+ <strong>No CDP mode required:</strong> No need to restart Chrome
277
+ with special flags
278
+ </li>
279
+ <li>
280
+ <strong>Full CDP access:</strong> Complete Chrome DevTools Protocol
281
+ capabilities
282
+ </li>
283
+ <li>
284
+ <strong>Visual feedback:</strong> Extension icon changes color to
285
+ indicate connection status
286
+ </li>
287
+ </ul>
288
+ </section>
289
+
290
+ <section>
291
+ <h2>Icon States</h2>
292
+
293
+ <ul>
294
+ <li><strong>Gray:</strong> Not connected to any tab</li>
295
+ <li><strong>Green:</strong> Successfully connected and ready</li>
296
+ <li><strong>Orange badge (...):</strong> Connecting to relay server</li>
297
+ <li><strong>Red badge (!):</strong> Error occurred</li>
298
+ </ul>
299
+ </section>
300
+
301
+ <section>
302
+ <h2>Privacy &amp; Security</h2>
303
+
304
+ <p>
305
+ E2E Pilot MCP runs locally in your browser and does not send any
306
+ data to external servers. All browser control happens through the
307
+ standard Chrome DevTools Protocol on your machine.
308
+ </p>
309
+ </section>
310
+
311
+ <section>
312
+ <h2>Need Help?</h2>
313
+
314
+ <p>
315
+ For issues, feature requests, or contributions, visit the
316
+ <a
317
+ href="https://github.com/remorses/playwriter"
318
+ target="_blank"
319
+ rel="noopener noreferrer"
320
+ >
321
+ GitHub repository
322
+ </a>
323
+ .
324
+ </p>
325
+ </section>
326
+
327
+ <footer>
328
+ <p>
329
+ E2E Pilot MCP &copy; Microsoft Corporation &middot; Licensed under
330
+ Apache-2.0
331
+ </p>
332
+ </footer>
333
+ </main>
334
+ </body>
335
+ </html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "e2e-pilot",
3
3
  "description": "",
4
- "version": "0.0.69",
4
+ "version": "0.0.71",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -37,6 +37,7 @@
37
37
  "@types/ws": "^8.18.1",
38
38
  "@vitest/ui": "^4.0.8",
39
39
  "bippy": "^0.5.27",
40
+ "bun": "^1.3.6",
40
41
  "image-size": "^2.0.2",
41
42
  "e2e-pilot-extension": "workspace:*",
42
43
  "vite-node": "^5.0.0",
@@ -49,7 +50,6 @@
49
50
  "@hono/node-server": "^1.19.6",
50
51
  "@hono/node-ws": "^1.2.0",
51
52
  "@modelcontextprotocol/sdk": "^1.21.1",
52
- "bun": "^1.3.6",
53
53
  "cac": "^6.7.14",
54
54
  "chalk": "^5.6.2",
55
55
  "colord": "^2.9.3",
package/src/cli.ts CHANGED
@@ -3,7 +3,9 @@
3
3
  import { cac } from 'cac'
4
4
  import fs from 'node:fs'
5
5
  import path from 'node:path'
6
- import { spawn } from 'node:child_process'
6
+ import { exec, spawn } from 'node:child_process'
7
+ import { promisify } from 'node:util'
8
+ import chalk from 'chalk'
7
9
  import { fileURLToPath } from 'node:url'
8
10
  import { chromium, Page } from 'playwright-core'
9
11
  import { startE2EPilotCDPRelayServer } from './cdp-relay.js'
@@ -244,6 +246,65 @@ async function readStdin(): Promise<string> {
244
246
  })
245
247
  }
246
248
 
249
+ function copyDirRecursive(src: string, dest: string): void {
250
+ fs.mkdirSync(dest, { recursive: true })
251
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
252
+ const srcPath = path.join(src, entry.name)
253
+ const destPath = path.join(dest, entry.name)
254
+ entry.isDirectory()
255
+ ? copyDirRecursive(srcPath, destPath)
256
+ : fs.copyFileSync(srcPath, destPath)
257
+ }
258
+ }
259
+
260
+ cli
261
+ .command('chrome', 'Set up the Chrome extension for E2E Pilot')
262
+ .action(async () => {
263
+ const execAsync = promisify(exec)
264
+ const extensionSrc = path.join(__dirname, '..', 'extension-dist')
265
+ const targetDir = path.join(process.cwd(), '.e2e-pilot', 'extension')
266
+
267
+ // Verify source exists
268
+ if (!fs.existsSync(extensionSrc)) {
269
+ console.error(chalk.red('Error: Extension files not found.'))
270
+ process.exit(1)
271
+ }
272
+
273
+ // Copy extension files
274
+ if (fs.existsSync(targetDir)) {
275
+ fs.rmSync(targetDir, { recursive: true })
276
+ }
277
+ copyDirRecursive(extensionSrc, targetDir)
278
+
279
+ // Show instructions first
280
+ console.log()
281
+ console.log(chalk.green.bold('Extension ready!'))
282
+ console.log()
283
+ console.log('Extension files copied to:')
284
+ console.log(chalk.cyan(` ${targetDir}`))
285
+ console.log()
286
+ console.log(chalk.bold('To load in Chrome:'))
287
+ console.log(' 1. Go to', chalk.cyan('chrome://extensions'))
288
+ console.log(' 2. Enable', chalk.yellow('Developer mode'), '(top-right toggle)')
289
+ console.log(' 3. Drag extension folder to chrome')
290
+ console.log()
291
+
292
+ // Wait for Enter key
293
+ process.stdout.write('Press Enter to open Chrome and extension folder...')
294
+ await new Promise<void>((resolve) => {
295
+ process.stdin.setRawMode?.(false)
296
+ process.stdin.resume()
297
+ process.stdin.once('data', () => resolve())
298
+ })
299
+ console.log()
300
+
301
+ // Open folder and Chrome extensions page (macOS)
302
+ try {
303
+ await execAsync(`open "${targetDir}"`)
304
+ await execAsync('open -a "Google Chrome" "chrome://extensions"')
305
+ } catch { /* continue if opening fails */ }
306
+ })
307
+
247
308
  cli.help()
248
309
  cli.version(VERSION)
249
310