


















@@ -4,6 +4,7 @@ import process from "node:process";
44import { fileURLToPath } from "node:url";
55import { resolveStateDir } from "../config/paths.js";
66import type { OpenClawConfig } from "../config/types.openclaw.js";
7+import { isValueToken } from "../infra/cli-root-options.js";
78import { isTruthyEnvValue, normalizeEnv } from "../infra/env.js";
89import { isMainModule } from "../infra/is-main.js";
910import { ensureOpenClawCliOnPath } from "../infra/path-env.js";
@@ -39,6 +40,40 @@ export {
39404041type Awaitable<T> = T | Promise<T>;
414243+const GATEWAY_RUN_VALUE_FLAGS = new Set([
44+"--port",
45+"--bind",
46+"--token",
47+"--auth",
48+"--password",
49+"--password-file",
50+"--tailscale",
51+"--ws-log",
52+"--raw-stream-path",
53+]);
54+55+const GATEWAY_RUN_BOOLEAN_FLAGS = new Set([
56+"--tailscale-reset-on-exit",
57+"--allow-unconfigured",
58+"--dev",
59+"--reset",
60+"--force",
61+"--verbose",
62+"--cli-backend-logs",
63+"--claude-cli-logs",
64+"--compact",
65+"--raw-stream",
66+]);
67+68+const CLI_PROXY_ENV_KEYS = [
69+"HTTP_PROXY",
70+"HTTPS_PROXY",
71+"ALL_PROXY",
72+"http_proxy",
73+"https_proxy",
74+"all_proxy",
75+] as const;
76+4277function createGatewayCliMainStartupTrace(argv: string[]) {
4378const enabled =
4479isTruthyEnvValue(process.env.OPENCLAW_GATEWAY_STARTUP_TRACE) &&
@@ -73,14 +108,45 @@ function createGatewayCliMainStartupTrace(argv: string[]) {
73108}
7410975110export function isGatewayRunFastPathArgv(argv: string[]): boolean {
76-if (argv[2] !== "gateway") {
111+const invocation = resolveCliArgvInvocation(argv);
112+if (invocation.hasHelpOrVersion) {
77113return false;
78114}
79-const invocation = resolveCliArgvInvocation(argv);
80-if (invocation.hasHelpOrVersion || invocation.commandPath[0] !== "gateway") {
115+const args = argv.slice(2);
116+let sawGateway = false;
117+let sawRun = false;
118+119+for (let index = 0; index < args.length; index += 1) {
120+const arg = args[index];
121+if (!arg || arg === "--") {
122+return false;
123+}
124+if (!sawGateway) {
125+const consumed = consumeGatewayFastPathRootOptionToken(args, index);
126+if (consumed > 0) {
127+index += consumed - 1;
128+continue;
129+}
130+if (arg !== "gateway") {
131+return false;
132+}
133+sawGateway = true;
134+continue;
135+}
136+137+const consumed = consumeGatewayRunOptionToken(args, index);
138+if (consumed > 0) {
139+index += consumed - 1;
140+continue;
141+}
142+if (!sawRun && arg === "run") {
143+sawRun = true;
144+continue;
145+}
81146return false;
82147}
83-return invocation.commandPath.length === 1 || invocation.commandPath[1] === "run";
148+149+return sawGateway;
84150}
8515186152function hasJsonOutputFlag(argv: string[]): boolean {
@@ -121,6 +187,7 @@ async function tryRunGatewayRunFastPath(
121187const program = new Command();
122188program.name("openclaw");
123189program.enablePositionalOptions();
190+program.option("--no-color", "Disable ANSI colors", false);
124191program.exitOverride((err) => {
125192process.exitCode = typeof err.exitCode === "number" ? err.exitCode : 1;
126193throw err;
@@ -201,6 +268,72 @@ async function ensureCliEnvProxyDispatcher(): Promise<void> {
201268}
202269}
203270271+function consumeGatewayRunOptionToken(args: ReadonlyArray<string>, index: number): number {
272+const arg = args[index];
273+if (!arg || arg === "--" || !arg.startsWith("-")) {
274+return 0;
275+}
276+const equalsIndex = arg.indexOf("=");
277+const flag = equalsIndex === -1 ? arg : arg.slice(0, equalsIndex);
278+if (GATEWAY_RUN_BOOLEAN_FLAGS.has(flag)) {
279+return equalsIndex === -1 ? 1 : 0;
280+}
281+if (!GATEWAY_RUN_VALUE_FLAGS.has(flag)) {
282+return 0;
283+}
284+if (equalsIndex !== -1) {
285+return arg.slice(equalsIndex + 1).trim() ? 1 : 0;
286+}
287+return isValueToken(args[index + 1]) ? 2 : 0;
288+}
289+290+function consumeGatewayFastPathRootOptionToken(args: ReadonlyArray<string>, index: number): number {
291+const arg = args[index];
292+if (!arg || arg === "--") {
293+return 0;
294+}
295+if (arg === "--no-color") {
296+return 1;
297+}
298+if (arg.startsWith("--profile=")) {
299+return arg.slice("--profile=".length).trim() ? 1 : 0;
300+}
301+if (arg === "--profile") {
302+return isValueToken(args[index + 1]) ? 2 : 0;
303+}
304+return 0;
305+}
306+307+function shouldBootstrapCliProxyBeforeFastPath(env: NodeJS.ProcessEnv = process.env): boolean {
308+if (
309+isTruthyEnvValue(env.OPENCLAW_DEBUG_PROXY_ENABLED) ||
310+isTruthyEnvValue(env.OPENCLAW_DEBUG_PROXY_REQUIRE)
311+) {
312+return true;
313+}
314+return CLI_PROXY_ENV_KEYS.some((key) => {
315+const value = env[key];
316+return typeof value === "string" && value.trim().length > 0;
317+});
318+}
319+320+async function bootstrapCliProxyCaptureAndDispatcher(
321+startupTrace: ReturnType<typeof createGatewayCliMainStartupTrace>,
322+): Promise<void> {
323+const [
324+{ initializeDebugProxyCapture, finalizeDebugProxyCapture },
325+{ maybeWarnAboutDebugProxyCoverage },
326+] = await startupTrace.measure("proxy-imports", () =>
327+Promise.all([import("../proxy-capture/runtime.js"), import("../proxy-capture/coverage.js")]),
328+);
329+initializeDebugProxyCapture("cli");
330+process.once("exit", () => {
331+finalizeDebugProxyCapture();
332+});
333+await startupTrace.measure("proxy-dispatcher", () => ensureCliEnvProxyDispatcher());
334+maybeWarnAboutDebugProxyCoverage();
335+}
336+204337export async function runCli(argv: string[] = process.argv) {
205338const originalArgv = normalizeWindowsArgv(argv);
206339const startupTrace = createGatewayCliMainStartupTrace(originalArgv);
@@ -312,20 +445,20 @@ export async function runCli(argv: string[] = process.argv) {
312445return;
313446}
314447315-const [
316-{ initializeDebugProxyCapture, finalizeDebugProxyCapture },
317-{ maybeWarnAboutDebugProxyCoverage },
318-] = await startupTrace.measure("proxy-imports", () =>
319-Promise.all([import("../proxy-capture/runtime.js"), import("../proxy-capture/coverage.js")]),
320-);
321-initializeDebugProxyCapture("cli");
322-process.once("exit", () => {
323-finalizeDebugProxyCapture();
324-});
325-await startupTrace.measure("proxy-dispatcher", () => ensureCliEnvProxyDispatcher());
326-maybeWarnAboutDebugProxyCoverage();
448+const bootstrapProxyBeforeFastPath = shouldBootstrapCliProxyBeforeFastPath();
449+if (
450+!bootstrapProxyBeforeFastPath &&
451+(await tryRunGatewayRunFastPath(normalizedArgv, startupTrace))
452+) {
453+return;
454+}
455+456+await bootstrapCliProxyCaptureAndDispatcher(startupTrace);
327457328-if (await tryRunGatewayRunFastPath(normalizedArgv, startupTrace)) {
458+if (
459+bootstrapProxyBeforeFastPath &&
460+(await tryRunGatewayRunFastPath(normalizedArgv, startupTrace))
461+) {
329462return;
330463}
331464此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。