fix(test): guard discord acp smoke cli args

This commit is contained in:
Vincent Koc
2026-06-20 02:47:36 +02:00
parent 49b0487e5b
commit 41691a82d5
2 changed files with 138 additions and 29 deletions
+94 -29
View File
@@ -136,6 +136,26 @@ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
const DEFAULT_OPENCLAW_CLI_TIMEOUT_MS = 60_000;
const DISCORD_RESPONSE_BODY_MAX_BYTES = 1024 * 1024;
const WEBHOOK_CLEANUP_TIMEOUT_MS = 10_000;
const BOOLEAN_OPTIONS = new Set(["--help", "-h", "--json"]);
const VALUE_OPTIONS = new Set([
"--channel",
"--driver",
"--token",
"--token-prefix",
"--bot-token",
"--bot-token-prefix",
"--agent",
"--mention",
"--instruction",
"--timeout-ms",
"--poll-ms",
"--state-dir",
"--openclaw-bin",
]);
class CliArgumentError extends Error {
override name = "CliArgumentError";
}
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => {
@@ -237,21 +257,48 @@ function resolveStateDir(): string {
return path.join(home, ".openclaw");
}
function resolveArg(flag: string): string | undefined {
const argv = process.argv.slice(2);
function resolveArg(flag: string, argv: string[]): string | undefined {
const eq = argv.find((entry) => entry.startsWith(`${flag}=`));
if (eq) {
return eq.slice(flag.length + 1);
const value = eq.slice(flag.length + 1);
if (!value) {
throw new CliArgumentError(`${flag} requires a value`);
}
return value;
}
const idx = argv.indexOf(flag);
if (idx >= 0 && idx + 1 < argv.length) {
return argv[idx + 1];
if (idx < 0) {
return undefined;
}
return undefined;
const value = argv[idx + 1];
if (!value || value.startsWith("--")) {
throw new CliArgumentError(`${flag} requires a value`);
}
return value;
}
function hasFlag(flag: string): boolean {
return process.argv.slice(2).includes(flag);
function hasFlag(flag: string, argv = process.argv.slice(2)): boolean {
return argv.includes(flag);
}
function validateCliArgs(argv: string[]): void {
for (let index = 0; index < argv.length; index += 1) {
const arg = argv[index] ?? "";
if (BOOLEAN_OPTIONS.has(arg)) {
continue;
}
if (arg.startsWith("--") && arg.includes("=")) {
const [flag] = arg.split("=", 1);
if (VALUE_OPTIONS.has(flag)) {
continue;
}
}
if (VALUE_OPTIONS.has(arg)) {
index += 1;
continue;
}
throw new CliArgumentError(`Unknown argument: ${arg}`);
}
}
function parseDriverMode(raw: string): DriverMode {
@@ -314,43 +361,54 @@ function usage(): string {
);
}
function parseArgs(): Args {
const channelId = resolveArg("--channel") || process.env.OPENCLAW_DISCORD_SMOKE_CHANNEL_ID || "";
function parseArgs(argv = process.argv.slice(2)): Args {
validateCliArgs(argv);
const channelId =
resolveArg("--channel", argv) || process.env.OPENCLAW_DISCORD_SMOKE_CHANNEL_ID || "";
const driverModeRaw =
resolveArg("--driver") || process.env.OPENCLAW_DISCORD_SMOKE_DRIVER || "token";
resolveArg("--driver", argv) || process.env.OPENCLAW_DISCORD_SMOKE_DRIVER || "token";
const driverMode = parseDriverMode(driverModeRaw);
const driverToken =
resolveArg("--token") || process.env.OPENCLAW_DISCORD_SMOKE_DRIVER_TOKEN || "";
resolveArg("--token", argv) || process.env.OPENCLAW_DISCORD_SMOKE_DRIVER_TOKEN || "";
const driverTokenPrefix =
resolveArg("--token-prefix") || process.env.OPENCLAW_DISCORD_SMOKE_DRIVER_TOKEN_PREFIX || "Bot";
resolveArg("--token-prefix", argv) ||
process.env.OPENCLAW_DISCORD_SMOKE_DRIVER_TOKEN_PREFIX ||
"Bot";
const botToken =
resolveArg("--bot-token") ||
resolveArg("--bot-token", argv) ||
process.env.OPENCLAW_DISCORD_SMOKE_BOT_TOKEN ||
process.env.DISCORD_BOT_TOKEN ||
"";
const botTokenPrefix =
resolveArg("--bot-token-prefix") ||
resolveArg("--bot-token-prefix", argv) ||
process.env.OPENCLAW_DISCORD_SMOKE_BOT_TOKEN_PREFIX ||
"Bot";
const targetAgent = resolveArg("--agent") || process.env.OPENCLAW_DISCORD_SMOKE_AGENT || "codex";
const targetAgent =
resolveArg("--agent", argv) || process.env.OPENCLAW_DISCORD_SMOKE_AGENT || "codex";
const mentionUserId =
resolveArg("--mention") || process.env.OPENCLAW_DISCORD_SMOKE_MENTION_USER_ID || undefined;
resolveArg("--mention", argv) ||
process.env.OPENCLAW_DISCORD_SMOKE_MENTION_USER_ID ||
undefined;
const instruction =
resolveArg("--instruction") || process.env.OPENCLAW_DISCORD_SMOKE_INSTRUCTION || undefined;
resolveArg("--instruction", argv) ||
process.env.OPENCLAW_DISCORD_SMOKE_INSTRUCTION ||
undefined;
const timeoutMs = parseNumber(
resolveArg("--timeout-ms") || process.env.OPENCLAW_DISCORD_SMOKE_TIMEOUT_MS,
resolveArg("--timeout-ms", argv) || process.env.OPENCLAW_DISCORD_SMOKE_TIMEOUT_MS,
240_000,
"--timeout-ms",
);
const pollMs = parseNumber(
resolveArg("--poll-ms") || process.env.OPENCLAW_DISCORD_SMOKE_POLL_MS,
resolveArg("--poll-ms", argv) || process.env.OPENCLAW_DISCORD_SMOKE_POLL_MS,
1_500,
"--poll-ms",
);
const stateDir = path.resolve(resolveArg("--state-dir") || resolveStateDir());
const stateDir = path.resolve(resolveArg("--state-dir", argv) || resolveStateDir());
const openclawBin =
resolveArg("--openclaw-bin") || process.env.OPENCLAW_DISCORD_SMOKE_OPENCLAW_BIN || "openclaw";
const json = hasFlag("--json");
resolveArg("--openclaw-bin", argv) ||
process.env.OPENCLAW_DISCORD_SMOKE_OPENCLAW_BIN ||
"openclaw";
const json = hasFlag("--json", argv);
if (!channelId) {
throw new Error(usage());
@@ -736,10 +794,10 @@ function printOutput(params: { json: boolean; payload: SuccessResult | FailureRe
}
}
async function run(): Promise<SuccessResult | FailureResult> {
async function run(argv = process.argv.slice(2)): Promise<SuccessResult | FailureResult> {
let args: Args;
try {
args = parseArgs();
args = parseArgs(argv);
} catch (err) {
return {
ok: false,
@@ -1032,12 +1090,18 @@ async function run(): Promise<SuccessResult | FailureResult> {
}
}
async function main(): Promise<number> {
if (hasFlag("--help") || hasFlag("-h")) {
async function main(argv = process.argv.slice(2)): Promise<number> {
try {
validateCliArgs(argv);
} catch (err) {
writeStderrLine(safeErrorMessage(err));
return 1;
}
if (hasFlag("--help", argv) || hasFlag("-h", argv)) {
writeStdoutLine(usage());
return 0;
}
const result = await run().catch(
const result = await run(argv).catch(
(err: unknown): FailureResult => ({
ok: false,
stage: "unexpected",
@@ -1046,7 +1110,7 @@ async function main(): Promise<number> {
}),
);
printOutput({
json: hasFlag("--json"),
json: hasFlag("--json", argv),
payload: result,
});
return result.ok ? 0 : 1;
@@ -1054,6 +1118,7 @@ async function main(): Promise<number> {
export const testing = {
parseDriverMode,
parseArgs,
parseNumber,
DISCORD_RESPONSE_BODY_MAX_BYTES,
redactDiscordApiPath,