Files
zn-ai/electron/gateway/config-sync.ts
DEV_DSW 71bcc3b3c5 feat: implement telemetry system for application usage tracking
- Added telemetry utility to capture application events and metrics.
- Integrated PostHog for event tracking with distinct user identification.
- Implemented telemetry initialization, event capturing, and shutdown procedures.

feat: add UV environment setup for Python management

- Created utilities to manage Python installation and configuration.
- Implemented network optimization checks for Python installation mirrors.
- Added functions to set up managed Python environments with error handling.

feat: enhance host API communication with token management

- Introduced host API token retrieval and management for secure requests.
- Updated host API fetch functions to include token in headers.
- Added support for creating event sources with authentication.

test: add comprehensive tests for gateway protocol and startup helpers

- Implemented unit tests for gateway protocol helpers, event dispatching, and state management.
- Added tests for startup recovery strategies and process policies.
- Ensured coverage for connection monitoring and restart governance logic.
2026-04-23 17:21:57 +08:00

100 lines
2.5 KiB
TypeScript

import { existsSync } from 'node:fs';
import { delimiter, join } from 'node:path';
import { app } from 'electron';
import { syncBrowserConfigToOpenClaw } from '@electron/utils/openclaw-auth';
import {
getOpenClawEntryPath,
getOpenClawResolvedDir,
} from '@electron/utils/paths';
export interface GatewayLaunchContext {
openclawDir: string;
entryScript: string;
binDir: string;
gatewayArgs: string[];
forkEnv: Record<string, string | undefined>;
mode: 'dev' | 'packaged';
binPathExists: boolean;
}
export interface PrepareGatewayLaunchContextOptions {
port: number;
token: string;
skipChannels?: boolean;
}
function prependPathEntry(pathValue: string | undefined, entry: string): string {
if (!pathValue?.trim()) {
return entry;
}
const segments = pathValue.split(delimiter);
if (segments.includes(entry)) {
return pathValue;
}
return `${entry}${delimiter}${pathValue}`;
}
function getBundledBinDir(): string {
if (app.isPackaged) {
return join(process.resourcesPath, 'bin');
}
return join(process.cwd(), 'resources', 'bin', `${process.platform}-${process.arch}`);
}
export async function syncGatewayConfigBeforeLaunch(): Promise<void> {
await syncBrowserConfigToOpenClaw();
}
export async function prepareGatewayLaunchContext(
options: PrepareGatewayLaunchContextOptions,
): Promise<GatewayLaunchContext> {
await syncGatewayConfigBeforeLaunch();
const openclawDir = getOpenClawResolvedDir();
const entryScript = getOpenClawEntryPath();
if (!existsSync(entryScript)) {
throw new Error(`OpenClaw entry script not found at ${entryScript}`);
}
const gatewayArgs = [
'gateway',
'--port',
String(options.port),
'--token',
options.token,
'--allow-unconfigured',
];
const skipChannels = options.skipChannels ?? true;
const binDir = getBundledBinDir();
const binPathExists = existsSync(binDir);
const {
NODE_OPTIONS: _nodeOptions,
ELECTRON_RUN_AS_NODE: _electronRunAsNode,
...baseEnv
} = process.env;
const forkEnv: Record<string, string | undefined> = {
...baseEnv,
PATH: binPathExists ? prependPathEntry(baseEnv.PATH, binDir) : baseEnv.PATH,
OPENCLAW_GATEWAY_TOKEN: options.token,
OPENCLAW_SKIP_CHANNELS: skipChannels ? '1' : '',
CLAWDBOT_SKIP_CHANNELS: skipChannels ? '1' : '',
OPENCLAW_NO_RESPAWN: '1',
};
return {
openclawDir,
entryScript,
binDir,
gatewayArgs,
forkEnv,
mode: app.isPackaged ? 'packaged' : 'dev',
binPathExists,
};
}