Add --profile flag for persistent browser profiles

Adds support for persistent browser profiles that preserve cookies,
localStorage, and login sessions across browser restarts.

Changes:
- Add --profile <path> CLI flag (flags.rs)
- Add AGENT_BROWSER_PROFILE environment variable support
- Add profile field to LaunchCommand type (types.ts)
- Use launchPersistentContext when profile is specified (browser.ts)
- Update help text and README with documentation

Usage:
  agent-browser --profile ~/.myapp-profile open myapp.com

This enables AI agents to maintain authenticated sessions across
browser restarts without re-authenticating each time.
This commit is contained in:
elsigh
2026-01-13 12:49:42 -08:00
parent 673e2e266e
commit d86de0e736
6 changed files with 68 additions and 7 deletions
+16
View File
@@ -609,11 +609,16 @@ export class BrowserManager {
async launch(options: LaunchCommand): Promise<void> {
const cdpPort = options.cdpPort;
const hasExtensions = !!options.extensions?.length;
const hasProfile = !!options.profile;
if (hasExtensions && cdpPort) {
throw new Error('Extensions cannot be used with CDP connection');
}
if (hasProfile && cdpPort) {
throw new Error('Profile cannot be used with CDP connection');
}
if (this.isLaunched()) {
const needsRelaunch =
(!cdpPort && this.cdpPort !== null) || (!!cdpPort && this.needsCdpReconnect(cdpPort));
@@ -640,6 +645,7 @@ export class BrowserManager {
let context: BrowserContext;
if (hasExtensions) {
// Extensions require persistent context in a temp directory
const extPaths = options.extensions!.join(',');
const session = process.env.AGENT_BROWSER_SESSION || 'default';
context = await launcher.launchPersistentContext(
@@ -653,7 +659,17 @@ export class BrowserManager {
}
);
this.isPersistentContext = true;
} else if (hasProfile) {
// Profile uses persistent context for durable cookies/storage
context = await launcher.launchPersistentContext(options.profile!, {
headless: options.headless ?? true,
executablePath: options.executablePath,
viewport,
extraHTTPHeaders: options.headers,
});
this.isPersistentContext = true;
} else {
// Regular ephemeral browser
this.browser = await launcher.launch({
headless: options.headless ?? true,
executablePath: options.executablePath,
+1
View File
@@ -16,6 +16,7 @@ export interface LaunchCommand extends BaseCommand {
executablePath?: string;
cdpPort?: number;
extensions?: string[];
profile?: string; // Path to persistent browser profile directory
}
export interface NavigateCommand extends BaseCommand {