mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-05-01 06:36:23 +08:00
fix(cli): skip respawn for foreground gateway
This commit is contained in:
@@ -26,6 +26,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Agents/subagents: enforce `subagents.allowAgents` for explicit same-agent `sessions_spawn(agentId=...)` calls instead of auto-allowing requester self-targets. Fixes #72827. Thanks @oiGaDio.
|
||||
- ACP/sessions_spawn: let explicit `sessions_spawn(runtime="acp")` bootstrap turns run while `acp.dispatch.enabled=false` still blocks automatic ACP thread dispatch. Fixes #63591. Thanks @moeedahmed.
|
||||
- Gateway: skip CLI startup self-respawn for foreground gateway runs so low-memory Linux/Node 24 hosts start through the same path as direct `dist/index.js` without hanging before logs. Fixes #72720. Thanks @sign-2025.
|
||||
- Google Meet: grant Meet media permissions through browser control and pin local Chrome audio defaults to `BlackHole 2ch`, so joined agents no longer show `Permission needed` or use macOS default audio devices. Thanks @DougButdorf.
|
||||
- Google Meet: route local Chrome joins through OpenClaw browser control instead of raw default Chrome, so agents use the configured OpenClaw browser profile when opening Meet. Thanks @oromeis.
|
||||
- Plugins/discovery: follow symlinked plugin directories in global and workspace plugin roots while keeping broken links ignored and existing package safety checks in place. Fixes #36754; carries forward #72695 and #63206. Thanks @Quackstro, @ming1523, and @xsfX20.
|
||||
|
||||
@@ -21,12 +21,22 @@ describe("shouldSkipRespawnForArgv", () => {
|
||||
it.each([
|
||||
{ argv: ["node", "openclaw", "--help"] },
|
||||
{ argv: ["node", "openclaw", "-V"] },
|
||||
{ argv: ["node", "openclaw", "gateway"] },
|
||||
{ argv: ["node", "openclaw", "gateway", "--port", "14720", "--bind", "loopback"] },
|
||||
{ argv: ["node", "openclaw", "gateway", "run", "--port=14720", "--bind", "loopback"] },
|
||||
{
|
||||
argv: ["node", "openclaw", "--profile", "server", "gateway", "run", "--allow-unconfigured"],
|
||||
},
|
||||
] as const)("skips respawn for argv %j", ({ argv }) => {
|
||||
expect(shouldSkipRespawnForArgv([...argv]), argv.join(" ")).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps respawn path for normal commands", () => {
|
||||
expect(shouldSkipRespawnForArgv(["node", "openclaw", "status"])).toBe(false);
|
||||
it.each([
|
||||
{ argv: ["node", "openclaw", "status"] },
|
||||
{ argv: ["node", "openclaw", "gateway", "status"] },
|
||||
{ argv: ["node", "openclaw", "gateway", "call", "health"] },
|
||||
] as const)("keeps respawn path for argv %j", ({ argv }) => {
|
||||
expect(shouldSkipRespawnForArgv([...argv]), argv.join(" ")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
import { resolveCliArgvInvocation } from "./argv-invocation.js";
|
||||
import { getCommandPositionalsWithRootOptions } from "./argv.js";
|
||||
|
||||
const GATEWAY_RUN_BOOLEAN_FLAGS = [
|
||||
"--allow-unconfigured",
|
||||
"--claude-cli-logs",
|
||||
"--cli-backend-logs",
|
||||
"--compact",
|
||||
"--dev",
|
||||
"--force",
|
||||
"--raw-stream",
|
||||
"--reset",
|
||||
"--tailscale-reset-on-exit",
|
||||
"--verbose",
|
||||
] as const;
|
||||
|
||||
const GATEWAY_RUN_VALUE_FLAGS = [
|
||||
"--auth",
|
||||
"--bind",
|
||||
"--password",
|
||||
"--password-file",
|
||||
"--port",
|
||||
"--raw-stream-path",
|
||||
"--tailscale",
|
||||
"--token",
|
||||
"--ws-log",
|
||||
] as const;
|
||||
|
||||
function isForegroundGatewayRunArgv(argv: string[]): boolean {
|
||||
const positionals = getCommandPositionalsWithRootOptions(argv, {
|
||||
commandPath: ["gateway"],
|
||||
booleanFlags: GATEWAY_RUN_BOOLEAN_FLAGS,
|
||||
valueFlags: GATEWAY_RUN_VALUE_FLAGS,
|
||||
});
|
||||
if (!positionals) {
|
||||
return false;
|
||||
}
|
||||
return positionals.length === 0 || (positionals.length === 1 && positionals[0] === "run");
|
||||
}
|
||||
|
||||
export function shouldSkipRespawnForArgv(argv: string[]): boolean {
|
||||
return resolveCliArgvInvocation(argv).hasHelpOrVersion;
|
||||
const invocation = resolveCliArgvInvocation(argv);
|
||||
return (
|
||||
invocation.hasHelpOrVersion ||
|
||||
(invocation.primary === "gateway" && isForegroundGatewayRunArgv(argv))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("buildCliRespawnPlan", () => {
|
||||
|
||||
it("adds NODE_EXTRA_CA_CERTS and warning suppression in one respawn", () => {
|
||||
const plan = buildCliRespawnPlan({
|
||||
argv: ["node", "openclaw", "gateway", "run"],
|
||||
argv: ["node", "openclaw", "status"],
|
||||
env: {},
|
||||
execArgv: [],
|
||||
autoNodeExtraCaCerts: "/etc/ssl/certs/ca-certificates.crt",
|
||||
@@ -52,7 +52,7 @@ describe("buildCliRespawnPlan", () => {
|
||||
|
||||
it("does not overwrite an existing NODE_EXTRA_CA_CERTS value", () => {
|
||||
const plan = buildCliRespawnPlan({
|
||||
argv: ["node", "openclaw", "gateway", "run"],
|
||||
argv: ["node", "openclaw", "status"],
|
||||
env: { NODE_EXTRA_CA_CERTS: "/custom/ca.pem" },
|
||||
execArgv: [],
|
||||
autoNodeExtraCaCerts: "/etc/ssl/certs/ca-certificates.crt",
|
||||
@@ -64,7 +64,7 @@ describe("buildCliRespawnPlan", () => {
|
||||
it("returns null when both respawn guards are already satisfied", () => {
|
||||
expect(
|
||||
buildCliRespawnPlan({
|
||||
argv: ["node", "openclaw", "gateway", "run"],
|
||||
argv: ["node", "openclaw", "status"],
|
||||
env: {
|
||||
[OPENCLAW_NODE_EXTRA_CA_CERTS_READY]: "1",
|
||||
[OPENCLAW_NODE_OPTIONS_READY]: "1",
|
||||
|
||||
Reference in New Issue
Block a user