From 8319b950740ed0011a2742f959625ad1d3017918 Mon Sep 17 00:00:00 2001 From: Alexzhu Date: Tue, 2 Jun 2026 08:16:50 +0800 Subject: [PATCH] fix(scripts): normalize agent-batch help exits (#3068) Co-authored-by: Steven Enamakel --- scripts/agent-batch/__tests__/cli.test.mjs | 15 +++++++++++++++ scripts/agent-batch/lib.mjs | 4 +++- scripts/agent-batch/overlap.mjs | 12 ++++++++++-- scripts/agent-batch/status.mjs | 12 +++++++++--- scripts/agent-batch/validate.mjs | 12 ++++++++++-- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/scripts/agent-batch/__tests__/cli.test.mjs b/scripts/agent-batch/__tests__/cli.test.mjs index e8368d014..c04682e7e 100644 --- a/scripts/agent-batch/__tests__/cli.test.mjs +++ b/scripts/agent-batch/__tests__/cli.test.mjs @@ -124,3 +124,18 @@ test("status.mjs renders a markdown table from a fixture (no gh needed)", () => // a03 has no PR in the fixture — must still appear with placeholders. assert.match(r.stdout, /\| a03 \|.*\| — \| — \| no pr \|/i); }); + +test("direct agent-batch subcommands print help with exit 0", () => { + for (const [script, usage] of [ + [VALIDATE, /usage: validate\.mjs /], + [OVERLAP, /usage: overlap\.mjs /], + [STATUS, /usage: status\.mjs \[--post\] \[--fixture \]/], + ]) { + for (const flag of ["--help", "-h", "-?"]) { + const r = run(script, [flag]); + assert.strictEqual(r.status, 0, r.stderr); + assert.match(r.stdout, usage); + assert.strictEqual(r.stderr, ""); + } + } +}); diff --git a/scripts/agent-batch/lib.mjs b/scripts/agent-batch/lib.mjs index a6cf482ff..e8e1c6b18 100644 --- a/scripts/agent-batch/lib.mjs +++ b/scripts/agent-batch/lib.mjs @@ -219,7 +219,7 @@ function comparePaths(p1, p2) { } // CLI helper: parse argv after the script name and return { positional, flags }. -// Recognizes `--flag` and `--flag=value` and `--flag value`. +// Recognizes `--flag`, `--flag=value`, `--flag value`, and short help flags. export function parseArgs(argv) { const positional = []; const flags = {}; @@ -239,6 +239,8 @@ export function parseArgs(argv) { i++; } } + } else if (a === "-h" || a === "-?") { + flags[a.slice(1)] = true; } else { positional.push(a); } diff --git a/scripts/agent-batch/overlap.mjs b/scripts/agent-batch/overlap.mjs index 53490f476..4eef6f056 100755 --- a/scripts/agent-batch/overlap.mjs +++ b/scripts/agent-batch/overlap.mjs @@ -11,11 +11,19 @@ import { parseArgs, } from "./lib.mjs"; +function usage() { + return "usage: overlap.mjs "; +} + function main() { - const { positional } = parseArgs(process.argv.slice(2)); + const { positional, flags } = parseArgs(process.argv.slice(2)); + if (flags.help || flags.h || flags["?"]) { + process.stdout.write(`${usage()}\n`); + process.exit(0); + } const specPath = positional[0]; if (!specPath) { - process.stderr.write("usage: overlap.mjs \n"); + process.stderr.write(`${usage()}\n`); process.exit(2); } let spec; diff --git a/scripts/agent-batch/status.mjs b/scripts/agent-batch/status.mjs index a69239361..9d92ee438 100755 --- a/scripts/agent-batch/status.mjs +++ b/scripts/agent-batch/status.mjs @@ -18,6 +18,10 @@ import { loadSpec, validateSpec, SpecError, parseArgs } from "./lib.mjs"; const COMMENT_MARKER = (id) => ``; +function usage() { + return "usage: status.mjs [--post] [--fixture ]"; +} + function ciCell(rollup) { if (rollup === "SUCCESS") return "green"; if (rollup === "FAILURE") return "failing"; @@ -186,11 +190,13 @@ function postOrUpdateTrackingComment(spec, body) { function main() { const { positional, flags } = parseArgs(process.argv.slice(2)); + if (flags.help || flags.h || flags["?"]) { + process.stdout.write(`${usage()}\n`); + process.exit(0); + } const specPath = positional[0]; if (!specPath) { - process.stderr.write( - "usage: status.mjs [--post] [--fixture ]\n", - ); + process.stderr.write(`${usage()}\n`); process.exit(2); } let spec; diff --git a/scripts/agent-batch/validate.mjs b/scripts/agent-batch/validate.mjs index 7f7fe9bcf..57c8da953 100755 --- a/scripts/agent-batch/validate.mjs +++ b/scripts/agent-batch/validate.mjs @@ -6,11 +6,19 @@ import { loadSpec, validateSpec, SpecError, parseArgs } from "./lib.mjs"; +function usage() { + return "usage: validate.mjs "; +} + function main() { - const { positional } = parseArgs(process.argv.slice(2)); + const { positional, flags } = parseArgs(process.argv.slice(2)); + if (flags.help || flags.h || flags["?"]) { + process.stdout.write(`${usage()}\n`); + process.exit(0); + } const specPath = positional[0]; if (!specPath) { - process.stderr.write("usage: validate.mjs \n"); + process.stderr.write(`${usage()}\n`); process.exit(2); } try {