Add Firefox cookie import and stealth mode
- Firefox cookie importer: reads cookies.sqlite with WAL-safe copy, profile detection via profiles.ini, cross-platform paths, domain filtering - Stealth mode: opt-in via launch(stealth: true), patches navigator.webdriver, plugins/mimeTypes, permissions API, WebGL renderer, iframe isolation, languages, plus realistic Safari UA and context hardening - Import tool now accepts 'safari' | 'firefox' source - STEALTH.md reference documentation - Upgraded @types/node to v25 for node:sqlite support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+54
-38
@@ -20,6 +20,7 @@ let browserOptions = {
|
||||
fullscreen: false,
|
||||
preview: false,
|
||||
previewDelay: 2000,
|
||||
stealth: false,
|
||||
};
|
||||
let browser = new ClaudeBrowser(browserOptions);
|
||||
let launched = false;
|
||||
@@ -86,43 +87,55 @@ server.tool(
|
||||
previewDelay: z.number().optional().default(2000).describe('Preview highlight duration in ms'),
|
||||
width: z.number().optional().default(1280).describe('Viewport width'),
|
||||
height: z.number().optional().default(800).describe('Viewport height'),
|
||||
stealth: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.default(false)
|
||||
.describe(
|
||||
'Enable stealth mode to reduce bot detection. Patches navigator.webdriver, plugins, WebGL, permissions, and sets a realistic Safari user-agent. See STEALTH.md for details.'
|
||||
),
|
||||
},
|
||||
withLogging('launch', async ({ headed, fullscreen, preview, previewDelay, width, height }) => {
|
||||
// Close existing browser if launched
|
||||
if (launched) {
|
||||
await browser.close();
|
||||
launched = false;
|
||||
withLogging(
|
||||
'launch',
|
||||
async ({ headed, fullscreen, preview, previewDelay, width, height, stealth }) => {
|
||||
// Close existing browser if launched
|
||||
if (launched) {
|
||||
await browser.close();
|
||||
launched = false;
|
||||
}
|
||||
|
||||
// Update options - fullscreen/preview imply headed
|
||||
browserOptions = {
|
||||
headless: fullscreen || preview ? false : !headed,
|
||||
width,
|
||||
height,
|
||||
fullscreen,
|
||||
preview,
|
||||
previewDelay,
|
||||
stealth,
|
||||
};
|
||||
|
||||
// Create new browser with updated options
|
||||
browser = new ClaudeBrowser(browserOptions);
|
||||
await browser.launch();
|
||||
launched = true;
|
||||
|
||||
return textResult(
|
||||
JSON.stringify({
|
||||
ok: true,
|
||||
message: `Browser launched${stealth ? ' (stealth mode)' : ''}`,
|
||||
options: {
|
||||
headed: !browserOptions.headless,
|
||||
fullscreen,
|
||||
preview,
|
||||
previewDelay,
|
||||
stealth,
|
||||
viewport: { width, height },
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Update options - fullscreen/preview imply headed
|
||||
browserOptions = {
|
||||
headless: fullscreen || preview ? false : !headed,
|
||||
width,
|
||||
height,
|
||||
fullscreen,
|
||||
preview,
|
||||
previewDelay,
|
||||
};
|
||||
|
||||
// Create new browser with updated options
|
||||
browser = new ClaudeBrowser(browserOptions);
|
||||
await browser.launch();
|
||||
launched = true;
|
||||
|
||||
return textResult(
|
||||
JSON.stringify({
|
||||
ok: true,
|
||||
message: 'Browser launched',
|
||||
options: {
|
||||
headed: !browserOptions.headless,
|
||||
fullscreen,
|
||||
preview,
|
||||
previewDelay,
|
||||
viewport: { width, height },
|
||||
},
|
||||
})
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
// Navigation
|
||||
@@ -680,14 +693,17 @@ server.tool(
|
||||
// Browser import
|
||||
server.tool(
|
||||
'import',
|
||||
'Import cookies from Safari browser (macOS only). Requires Full Disk Access permission.',
|
||||
'Import cookies from Safari or Firefox browser. Safari requires Full Disk Access permission (macOS only). Firefox works on macOS, Linux, and Windows.',
|
||||
{
|
||||
source: z.enum(['safari']).describe('Browser to import from (currently only Safari supported)'),
|
||||
source: z.enum(['safari', 'firefox']).describe('Browser to import from'),
|
||||
domain: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe('Filter cookies to specific domain (e.g., "github.com")'),
|
||||
profile: z.string().optional().describe('Safari profile/WebKit data store ID (optional)'),
|
||||
profile: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe('Safari profile/WebKit data store ID, or Firefox profile name (optional)'),
|
||||
},
|
||||
withLogging('import', async ({ source, domain, profile }) => {
|
||||
await ensureLaunched();
|
||||
|
||||
Reference in New Issue
Block a user