refactor: move welcome.html to src/, simplify vite build config, cleanup cli.ts formatting
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
"permissions": ["debugger", "tabGroups", "contextMenus", "tabs"],
|
"permissions": ["debugger", "tabGroups", "contextMenus", "tabs"],
|
||||||
"host_permissions": ["<all_urls>"],
|
"host_permissions": ["<all_urls>"],
|
||||||
"background": {
|
"background": {
|
||||||
"service_worker": "lib/background.mjs",
|
"service_worker": "background.js",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
|
|||||||
@@ -1163,7 +1163,7 @@ function updateContextMenuVisibility(): void {
|
|||||||
chrome.runtime.onInstalled.addListener((details) => {
|
chrome.runtime.onInstalled.addListener((details) => {
|
||||||
if (import.meta.env.TESTING) return
|
if (import.meta.env.TESTING) return
|
||||||
if (details.reason === 'install') {
|
if (details.reason === 'install') {
|
||||||
void chrome.tabs.create({ url: 'welcome.html' })
|
void chrome.tabs.create({ url: 'src/welcome.html' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -38,23 +38,23 @@ export default defineConfig({
|
|||||||
return JSON.stringify(manifest, null, 2);
|
return JSON.stringify(manifest, null, 2);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
src: resolve(__dirname, 'welcome.html'),
|
|
||||||
dest: '.'
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
lib: {
|
|
||||||
entry: resolve(__dirname, 'src/background.ts'),
|
|
||||||
fileName: 'lib/background',
|
|
||||||
formats: ['es']
|
|
||||||
},
|
|
||||||
outDir: 'dist',
|
outDir: 'dist',
|
||||||
emptyOutDir: false,
|
emptyOutDir: false,
|
||||||
minify: false
|
minify: false,
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
background: resolve(__dirname, 'src/background.ts'),
|
||||||
|
welcome: resolve(__dirname, 'src/welcome.html'),
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
entryFileNames: '[name].js',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
define: defineEnv
|
define: defineEnv
|
||||||
});
|
});
|
||||||
|
|||||||
+19
-19
@@ -7,10 +7,10 @@ import { ensureRelayServer, RELAY_PORT } from './relay-client.js'
|
|||||||
const cli = cac('playwriter')
|
const cli = cac('playwriter')
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command('', 'Start the MCP server. See https://playwriter.dev/prompt.md for usage')
|
.command('', 'Start the MCP server or controls the browser with -e')
|
||||||
.option('--host <host>', 'Remote relay server host to connect to (or use PLAYWRITER_HOST env var)')
|
.option('--host <host>', 'Remote relay server host to connect to (or use PLAYWRITER_HOST env var)')
|
||||||
.option('--token <token>', 'Authentication token (or use PLAYWRITER_TOKEN env var)')
|
.option('--token <token>', 'Authentication token (or use PLAYWRITER_TOKEN env var)')
|
||||||
.option('-e, --eval <code>', 'Execute JavaScript code and exit')
|
.option('-e, --eval <code>', 'Execute JavaScript code and exit, read https://playwriter.dev/prompt.md for usage')
|
||||||
.option('--timeout <ms>', 'Execution timeout in milliseconds', { default: 5000 })
|
.option('--timeout <ms>', 'Execution timeout in milliseconds', { default: 5000 })
|
||||||
.option('-s, --session <name>', 'Session name (required for -e)')
|
.option('-s, --session <name>', 'Session name (required for -e)')
|
||||||
.action(async (options: { host?: string; token?: string; eval?: string; timeout?: number; session?: string }) => {
|
.action(async (options: { host?: string; token?: string; eval?: string; timeout?: number; session?: string }) => {
|
||||||
@@ -25,7 +25,7 @@ cli
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise start the MCP server
|
// Otherwise start the MCP server
|
||||||
const { startMcp } = await import('./mcp.js')
|
const { startMcp } = await import('./mcp.js')
|
||||||
await startMcp({
|
await startMcp({
|
||||||
@@ -44,16 +44,16 @@ async function executeCode(options: {
|
|||||||
const { code, timeout, host, token } = options
|
const { code, timeout, host, token } = options
|
||||||
const cwd = process.cwd()
|
const cwd = process.cwd()
|
||||||
const sessionId = options.sessionId || process.env.PLAYWRITER_SESSION
|
const sessionId = options.sessionId || process.env.PLAYWRITER_SESSION
|
||||||
|
|
||||||
// Determine server URL
|
// Determine server URL
|
||||||
const serverHost = host || process.env.PLAYWRITER_HOST || '127.0.0.1'
|
const serverHost = host || process.env.PLAYWRITER_HOST || '127.0.0.1'
|
||||||
const serverUrl = `http://${serverHost}:${RELAY_PORT}`
|
const serverUrl = `http://${serverHost}:${RELAY_PORT}`
|
||||||
|
|
||||||
// Ensure relay server is running (only for local)
|
// Ensure relay server is running (only for local)
|
||||||
if (!host && !process.env.PLAYWRITER_HOST) {
|
if (!host && !process.env.PLAYWRITER_HOST) {
|
||||||
await ensureRelayServer({ logger: console })
|
await ensureRelayServer({ logger: console })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Session is required
|
// Session is required
|
||||||
if (!sessionId) {
|
if (!sessionId) {
|
||||||
try {
|
try {
|
||||||
@@ -65,10 +65,10 @@ async function executeCode(options: {
|
|||||||
}
|
}
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build request URL with token if provided
|
// Build request URL with token if provided
|
||||||
const executeUrl = `${serverUrl}/cli/execute`
|
const executeUrl = `${serverUrl}/cli/execute`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(executeUrl, {
|
const response = await fetch(executeUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -78,15 +78,15 @@ async function executeCode(options: {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({ sessionId, code, timeout, cwd }),
|
body: JSON.stringify({ sessionId, code, timeout, cwd }),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const text = await response.text()
|
const text = await response.text()
|
||||||
console.error(`Error: ${response.status} ${text}`)
|
console.error(`Error: ${response.status} ${text}`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json() as { text: string; images: Array<{ data: string; mimeType: string }>; isError: boolean }
|
const result = await response.json() as { text: string; images: Array<{ data: string; mimeType: string }>; isError: boolean }
|
||||||
|
|
||||||
// Print output
|
// Print output
|
||||||
if (result.text) {
|
if (result.text) {
|
||||||
if (result.isError) {
|
if (result.isError) {
|
||||||
@@ -95,12 +95,12 @@ async function executeCode(options: {
|
|||||||
console.log(result.text)
|
console.log(result.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: images are base64 encoded, we could save them to files if needed
|
// Note: images are base64 encoded, we could save them to files if needed
|
||||||
if (result.images && result.images.length > 0) {
|
if (result.images && result.images.length > 0) {
|
||||||
console.log(`\n${result.images.length} screenshot(s) captured`)
|
console.log(`\n${result.images.length} screenshot(s) captured`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.isError) {
|
if (result.isError) {
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
@@ -126,11 +126,11 @@ cli
|
|||||||
const sessionId = options.session || process.env.PLAYWRITER_SESSION
|
const sessionId = options.session || process.env.PLAYWRITER_SESSION
|
||||||
const serverHost = options.host || process.env.PLAYWRITER_HOST || '127.0.0.1'
|
const serverHost = options.host || process.env.PLAYWRITER_HOST || '127.0.0.1'
|
||||||
const serverUrl = `http://${serverHost}:${RELAY_PORT}`
|
const serverUrl = `http://${serverHost}:${RELAY_PORT}`
|
||||||
|
|
||||||
if (!options.host && !process.env.PLAYWRITER_HOST) {
|
if (!options.host && !process.env.PLAYWRITER_HOST) {
|
||||||
await ensureRelayServer({ logger: console })
|
await ensureRelayServer({ logger: console })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sessionId) {
|
if (!sessionId) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${serverUrl}/cli/session/suggest`)
|
const res = await fetch(`${serverUrl}/cli/session/suggest`)
|
||||||
@@ -141,20 +141,20 @@ cli
|
|||||||
}
|
}
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${serverUrl}/cli/reset`, {
|
const response = await fetch(`${serverUrl}/cli/reset`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ sessionId, cwd }),
|
body: JSON.stringify({ sessionId, cwd }),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const text = await response.text()
|
const text = await response.text()
|
||||||
console.error(`Error: ${response.status} ${text}`)
|
console.error(`Error: ${response.status} ${text}`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json() as { success: boolean; pageUrl: string; pagesCount: number }
|
const result = await response.json() as { success: boolean; pageUrl: string; pagesCount: number }
|
||||||
console.log(`Connection reset successfully. ${result.pagesCount} page(s) available. Current page URL: ${result.pageUrl}`)
|
console.log(`Connection reset successfully. ${result.pagesCount} page(s) available. Current page URL: ${result.pageUrl}`)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -212,7 +212,7 @@ cli
|
|||||||
// Lazy-load heavy dependencies only when serve command is used
|
// Lazy-load heavy dependencies only when serve command is used
|
||||||
const { createFileLogger } = await import('./create-logger.js')
|
const { createFileLogger } = await import('./create-logger.js')
|
||||||
const { startPlayWriterCDPRelayServer } = await import('./cdp-relay.js')
|
const { startPlayWriterCDPRelayServer } = await import('./cdp-relay.js')
|
||||||
|
|
||||||
const logger = createFileLogger()
|
const logger = createFileLogger()
|
||||||
|
|
||||||
process.title = 'playwriter-serve'
|
process.title = 'playwriter-serve'
|
||||||
|
|||||||
+2
-1
@@ -3,4 +3,5 @@ node_modules
|
|||||||
/build
|
/build
|
||||||
.env
|
.env
|
||||||
.react-router
|
.react-router
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
public/prompt.md
|
||||||
|
|||||||
Reference in New Issue
Block a user