feat: implement centralized artifact storage with session isolation
Add comprehensive artifact storage system with session-specific directories:
- Add --artifact-dir CLI option and PLAYWRIGHT_MCP_ARTIFACT_DIR env var
- Create ArtifactManager class for session-specific artifact organization
- Implement ArtifactManagerRegistry for multi-session support
- Add tool call logging with JSON persistence in tool-calls.json
- Update screenshot, video, and PDF tools to use centralized storage
- Add browser_configure_artifacts tool for per-session control
- Support dynamic enable/disable without server restart
- Maintain backward compatibility when artifact storage not configured
Directory structure: {artifactDir}/{sessionId}/[artifacts, videos/, tool-calls.json]
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ecedcc48d6
commit
d8202f6694
12 changed files with 727 additions and 93 deletions
|
|
@ -88,6 +88,12 @@ export class Context {
|
|||
}
|
||||
}
|
||||
|
||||
updateSessionId(customSessionId: string) {
|
||||
testDebug(`updating sessionId from ${this.sessionId} to ${customSessionId}`);
|
||||
// Note: sessionId is readonly, but we can update it for artifact management
|
||||
(this as any).sessionId = customSessionId;
|
||||
}
|
||||
|
||||
tabs(): Tab[] {
|
||||
return this._tabs;
|
||||
}
|
||||
|
|
@ -350,19 +356,19 @@ export class Context {
|
|||
permissions?: string[];
|
||||
}): Promise<void> {
|
||||
const currentConfig = { ...this.config };
|
||||
|
||||
|
||||
// Update the configuration
|
||||
if (changes.headless !== undefined) {
|
||||
if (changes.headless !== undefined)
|
||||
currentConfig.browser.launchOptions.headless = changes.headless;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Handle device emulation - this overrides individual viewport/userAgent settings
|
||||
if (changes.device) {
|
||||
if (!devices[changes.device]) {
|
||||
if (!devices[changes.device])
|
||||
throw new Error(`Unknown device: ${changes.device}`);
|
||||
}
|
||||
|
||||
const deviceConfig = devices[changes.device];
|
||||
|
||||
|
||||
// Apply all device properties to context options
|
||||
currentConfig.browser.contextOptions = {
|
||||
...currentConfig.browser.contextOptions,
|
||||
|
|
@ -370,12 +376,12 @@ export class Context {
|
|||
};
|
||||
} else {
|
||||
// Apply individual settings only if no device is specified
|
||||
if (changes.viewport) {
|
||||
if (changes.viewport)
|
||||
currentConfig.browser.contextOptions.viewport = changes.viewport;
|
||||
}
|
||||
if (changes.userAgent) {
|
||||
|
||||
if (changes.userAgent)
|
||||
currentConfig.browser.contextOptions.userAgent = changes.userAgent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Apply additional context options
|
||||
|
|
@ -386,33 +392,33 @@ export class Context {
|
|||
accuracy: changes.geolocation.accuracy || 100
|
||||
};
|
||||
}
|
||||
|
||||
if (changes.locale) {
|
||||
|
||||
if (changes.locale)
|
||||
currentConfig.browser.contextOptions.locale = changes.locale;
|
||||
}
|
||||
|
||||
if (changes.timezone) {
|
||||
|
||||
|
||||
if (changes.timezone)
|
||||
currentConfig.browser.contextOptions.timezoneId = changes.timezone;
|
||||
}
|
||||
|
||||
if (changes.colorScheme) {
|
||||
|
||||
|
||||
if (changes.colorScheme)
|
||||
currentConfig.browser.contextOptions.colorScheme = changes.colorScheme;
|
||||
}
|
||||
|
||||
if (changes.permissions) {
|
||||
|
||||
|
||||
if (changes.permissions)
|
||||
currentConfig.browser.contextOptions.permissions = changes.permissions;
|
||||
}
|
||||
|
||||
|
||||
// Store the modified config
|
||||
(this as any).config = currentConfig;
|
||||
|
||||
// Close the current browser context to force recreation with new settings
|
||||
await this.closeBrowserContext();
|
||||
|
||||
|
||||
// Clear tabs since they're attached to the old context
|
||||
this._tabs = [];
|
||||
this._currentTab = undefined;
|
||||
|
||||
|
||||
testDebug(`browser config updated for session ${this.sessionId}: headless=${currentConfig.browser.launchOptions.headless}, viewport=${JSON.stringify(currentConfig.browser.contextOptions.viewport)}`);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue