feat(gateway, openclaw-auth): add browser config synchronization (#184)

This commit is contained in:
Haze
2026-02-26 14:47:36 +08:00
committed by GitHub
Unverified
parent 402aeeb98b
commit 4f50630291
5 changed files with 62 additions and 5 deletions

View File

@@ -30,7 +30,7 @@ import {
buildDeviceAuthPayload,
type DeviceIdentity,
} from '../utils/device-identity';
import { syncGatewayTokenToConfig } from '../utils/openclaw-auth';
import { syncGatewayTokenToConfig, syncBrowserConfigToOpenClaw } from '../utils/openclaw-auth';
/**
* Gateway connection status
@@ -637,6 +637,12 @@ export class GatewayManager extends EventEmitter {
} catch (err) {
logger.warn('Failed to sync gateway token to openclaw.json:', err);
}
try {
syncBrowserConfigToOpenClaw();
} catch (err) {
logger.warn('Failed to sync browser config to openclaw.json:', err);
}
let command: string;
let args: string[];

View File

@@ -443,6 +443,54 @@ export function syncGatewayTokenToConfig(token: string): void {
console.log('Synced gateway token to openclaw.json');
}
/**
* Ensure browser automation is enabled in ~/.openclaw/openclaw.json with the
* "openclaw" managed profile as the default.
*
* Only sets values that are not already present so existing user
* customisation (e.g. switching to a remote CDP profile) is preserved.
*/
export function syncBrowserConfigToOpenClaw(): void {
const configPath = join(homedir(), '.openclaw', 'openclaw.json');
let config: Record<string, unknown> = {};
try {
if (existsSync(configPath)) {
config = JSON.parse(readFileSync(configPath, 'utf-8')) as Record<string, unknown>;
}
} catch {
// start from a blank config if the file is corrupt
}
const browser = (
config.browser && typeof config.browser === 'object'
? { ...(config.browser as Record<string, unknown>) }
: {}
) as Record<string, unknown>;
let changed = false;
if (browser.enabled === undefined) {
browser.enabled = true;
changed = true;
}
if (browser.defaultProfile === undefined) {
browser.defaultProfile = 'openclaw';
changed = true;
}
if (!changed) return;
config.browser = browser;
const dir = join(configPath, '..');
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
console.log('Synced browser config to openclaw.json');
}
/**
* Update a provider entry in every discovered agent's models.json.
*

View File

@@ -3,6 +3,6 @@
You are ClawX, a desktop AI assistant application based on OpenClaw.
- **Python**: Always use `uv` to run Python commands. The `uv` binary is bundled and available on PATH. Examples: `uv run python script.py`, `uv pip install package`.
- **Browser**: When asked to open URLs or web pages, use the browser tool to open them in the user's system default browser.
- **Browser**: Full browser automation is available via the `browser` tool. The default "openclaw" profile uses an isolated browser instance. Use it for web scraping, form filling, testing, and any browser automation task. For simply opening a URL for the user to view, use `shell:openExternal` instead.
- **Shell**: You have full shell access on the user's machine. Prefer using tools directly over asking the user to run commands manually.
- Always confirm before running destructive operations.

View File

@@ -9,5 +9,9 @@
### Browser
- Use the `browser` tool to open URLs in the user's default browser.
- When the user asks to "open" a link, default to opening it in the browser.
- The `browser` tool provides full browser automation via OpenClaw's browser control server.
- Default profile is "openclaw" (isolated managed browser using system Chrome/Brave/Edge).
- Use `action="start"` to launch the browser, then `action="snapshot"` to see the page, `action="act"` to interact.
- Use `action="open"` with `targetUrl` to open new tabs.
- Refs from snapshots (e.g. `e12`) are used in `act` actions to click/type on specific elements.
- For simple "open a URL for the user to see", use `shell:openExternal` instead.

View File

@@ -129,7 +129,6 @@ queue.push({ nodeModulesDir: openclawVirtualNM, skipPkg: 'openclaw' });
const SKIP_PACKAGES = new Set([
'typescript',
'playwright-core',
'@playwright/test',
]);
const SKIP_SCOPES = ['@cloudflare/', '@types/'];