chore: pre-release cleanup

- Fix daemon per-command timeout: 30s → 120s (was shorter than CLI-layer timeouts)
- Remove debug command: grok/debug.ts
- Sync extension version to 1.0.0
- Rename PlaywrightMCP → BrowserBridge (keep backward-compat alias)
- Add accept/reply-dm to README command tables
- Clean up consoleMessages() JSDoc in page.ts
- Update runtime.ts comment
This commit is contained in:
jackwener committed 2026-03-19 22:49:54 +08:00
1 parent 13e2345089
commit 2e962b2e7c
9 files changed
+398 -363

No files matched your search

+7 -11
View File
@@ -1,8 +1,5 @@
/**
* Browser session manager — auto-spawns daemon and provides IPage.
*
* Replaces the old PlaywrightMCP class. Still exports as PlaywrightMCP
* for backward compatibility with main.ts and other consumers.
*/
import { spawn, type ChildProcess } from 'node:child_process';
@@ -15,21 +12,17 @@ import { isDaemonRunning, isExtensionConnected } from './daemon-client.js';
const DAEMON_SPAWN_TIMEOUT = 10000; // 10s to wait for daemon + extension
export type PlaywrightMCPState = 'idle' | 'connecting' | 'connected' | 'closing' | 'closed';
export type BrowserBridgeState = 'idle' | 'connecting' | 'connected' | 'closing' | 'closed';
/**
* Browser factory: manages daemon lifecycle and provides IPage instances.
*
* Kept as `PlaywrightMCP` class name for backward compatibility.
*/
export class PlaywrightMCP {
private _state: PlaywrightMCPState = 'idle';
export class BrowserBridge {
private _state: BrowserBridgeState = 'idle';
private _page: Page | null = null;
private _daemonProc: ChildProcess | null = null;
get state(): PlaywrightMCPState {
get state(): BrowserBridgeState {
return this._state;
}
@@ -113,3 +106,6 @@ export class PlaywrightMCP {
);
}
}
/** @deprecated Use BrowserBridge instead */
export const PlaywrightMCP = BrowserBridge;
+6 -6
View File
@@ -183,12 +183,12 @@ export class Page implements IPage {
return sendCommand('exec', { code, ...this._tabOpt() });
}
async consoleMessages(level: string = 'info'): Promise<any> {
// Console messages can't be retrospectively read via CDP Runtime.evaluate.
// Would need Runtime.consoleAPICalled event listener, which is not yet implemented.
if (process.env.OPENCLI_VERBOSE) {
console.error('[page] consoleMessages() not supported in lightweight mode — returning empty');
}
/**
* Console messages are not available in lightweight daemon mode.
* Would require CDP Runtime.consoleAPICalled event listener.
* @returns Always returns empty array.
*/
async consoleMessages(_level: string = 'info'): Promise<any> {
return [];
}
-49
View File
@@ -1,49 +0,0 @@
import { cli, Strategy } from '../../registry.js';
import type { IPage } from '../../types.js';
export const debugCommand = cli({
site: 'grok',
name: 'debug',
description: 'Debug grok page structure',
domain: 'grok.com',
strategy: Strategy.COOKIE,
browser: true,
columns: ['data'],
func: async (page: IPage, _kwargs: Record<string, any>) => {
await page.goto('https://grok.com');
await page.wait(3);
// Get all button-like elements near textarea
const debug = await page.evaluate(`(() => {
const ta = document.querySelector('textarea');
if (!ta) return { error: 'no textarea' };
// Get parent containers
let parent = ta.parentElement;
const parents = [];
for (let i = 0; i < 5 && parent; i++) {
parents.push({
tag: parent.tagName,
class: parent.className?.substring(0, 80),
childCount: parent.children.length,
});
parent = parent.parentElement;
}
// Find buttons in the form/container near textarea
const form = ta.closest('form') || ta.closest('[class*="composer"]') || ta.closest('[class*="input"]') || ta.parentElement?.parentElement;
const buttons = form ? [...form.querySelectorAll('button')].map(b => ({
testid: b.getAttribute('data-testid'),
type: b.type,
disabled: b.disabled,
text: (b.textContent || '').substring(0, 30),
html: b.outerHTML.substring(0, 200),
rect: b.getBoundingClientRect().toJSON(),
})) : [];
return { parents, buttons, formTag: form?.tagName, formClass: form?.className?.substring(0, 80) };
})()`);
return [{ data: JSON.stringify(debug, null, 2) }];
},
});
+2 -2
View File
@@ -114,8 +114,8 @@ async function handleRequest(req: IncomingMessage, res: ServerResponse): Promise
const result = await new Promise<unknown>((resolve, reject) => {
const timer = setTimeout(() => {
pending.delete(body.id);
reject(new Error('Command timeout (30s)'));
}, 30000);
reject(new Error('Command timeout (120s)'));
}, 120000);
pending.set(body.id, { resolve, reject, timer });
extensionWs!.send(JSON.stringify(body));
});
+1 -1
View File
@@ -32,7 +32,7 @@ export function withTimeoutMs<T>(promise: Promise<T>, timeoutMs: number, message
});
}
/** Interface for browser factory (PlaywrightMCP or test mocks) */
/** Interface for browser factory (BrowserBridge or test mocks) */
export interface IBrowserFactory {
connect(opts?: { timeout?: number }): Promise<IPage>;
close(): Promise<void>;