

























@@ -60,34 +60,48 @@ Options:
6060`.trim();
6161}
626263-function readNumber(value, label) {
64-const parsed = Number(value);
65-if (!Number.isFinite(parsed) || parsed < 0) {
66-throw new Error(`${label} must be a non-negative number`);
63+const NON_NEGATIVE_INTEGER_PATTERN = /^(0|[1-9]\d*)$/u;
64+65+export function readNumber(value, label) {
66+const raw = String(value).trim();
67+if (!NON_NEGATIVE_INTEGER_PATTERN.test(raw)) {
68+throw new Error(`${label} must be a non-negative integer`);
69+}
70+const parsed = Number(raw);
71+if (!Number.isSafeInteger(parsed)) {
72+throw new Error(`${label} must be a safe integer`);
6773}
68-return Math.floor(parsed);
74+return parsed;
6975}
707671-function readPositiveNumber(value, label) {
77+export function readPositiveNumber(value, label) {
7278const parsed = readNumber(value, label);
7379if (parsed <= 0) {
7480throw new Error(`${label} must be greater than 0`);
7581}
7682return parsed;
7783}
788479-function parseArgs(argv) {
85+function readNumberEnv(name, fallback) {
86+const raw = process.env[name];
87+return raw == null || raw.trim() === "" ? fallback : readNumber(raw, name);
88+}
89+90+function readPositiveNumberEnv(name, fallback) {
91+const raw = process.env[name];
92+return raw == null || raw.trim() === "" ? fallback : readPositiveNumber(raw, name);
93+}
94+95+export function parseArgs(argv) {
8096const stamp = new Date().toISOString().replace(/[:.]/g, "-");
8197const options = {
82-fileCount: Number(process.env.OPENCLAW_MEMORY_FD_REPRO_FILES || DEFAULT_FILE_COUNT),
98+fileCount: undefined,
8399mode: process.env.OPENCLAW_MEMORY_FD_REPRO_MODE || "fixed",
84-maxWorkspaceRegFds: Number(
85-process.env.OPENCLAW_MEMORY_FD_REPRO_MAX_WORKSPACE_REG_FDS || DEFAULT_MAX_WORKSPACE_REG_FDS,
86-),
100+maxWorkspaceRegFds: undefined,
87101minLeakedFds: undefined,
88-invokeTimeoutMs: Number(process.env.OPENCLAW_MEMORY_FD_REPRO_TIMEOUT_MS || 30_000),
89-sampleDelayMs: Number(process.env.OPENCLAW_MEMORY_FD_REPRO_SAMPLE_DELAY_MS || 1_000),
90-settleDelayMs: Number(process.env.OPENCLAW_MEMORY_FD_REPRO_SETTLE_DELAY_MS || 5_000),
102+invokeTimeoutMs: undefined,
103+sampleDelayMs: undefined,
104+settleDelayMs: undefined,
91105outputDir: path.resolve(".artifacts", "memory-fd-repro", stamp),
92106keep: process.env.OPENCLAW_MEMORY_FD_REPRO_KEEP === "1",
93107allowNonDarwin: process.env.OPENCLAW_MEMORY_FD_REPRO_ALLOW_NON_DARWIN === "1",
@@ -157,6 +171,14 @@ function parseArgs(argv) {
157171if (!["fixed", "leak", "report"].includes(options.mode)) {
158172throw new Error('--mode must be "fixed", "leak", or "report"');
159173}
174+options.fileCount ??= readPositiveNumberEnv("OPENCLAW_MEMORY_FD_REPRO_FILES", DEFAULT_FILE_COUNT);
175+options.maxWorkspaceRegFds ??= readNumberEnv(
176+"OPENCLAW_MEMORY_FD_REPRO_MAX_WORKSPACE_REG_FDS",
177+DEFAULT_MAX_WORKSPACE_REG_FDS,
178+);
179+options.invokeTimeoutMs ??= readPositiveNumberEnv("OPENCLAW_MEMORY_FD_REPRO_TIMEOUT_MS", 30_000);
180+options.sampleDelayMs ??= readNumberEnv("OPENCLAW_MEMORY_FD_REPRO_SAMPLE_DELAY_MS", 1_000);
181+options.settleDelayMs ??= readNumberEnv("OPENCLAW_MEMORY_FD_REPRO_SETTLE_DELAY_MS", 5_000);
160182if (!Number.isFinite(options.fileCount) || options.fileCount <= 0) {
161183throw new Error("file count must be greater than 0");
162184}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。