fix(clawsweeper): address review for automerge-openclaw-openclaw-75004 (1)

This commit is contained in:
clawsweeper
2026-05-03 03:58:04 +00:00
parent 8b5d73e47c
commit 8b2eca23ec
2 changed files with 34 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
import { afterEach, describe, expect, it } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { Parser } from "web-tree-sitter";
import { explainShellCommand } from "./extract.js";
import {
@@ -20,6 +20,7 @@ afterEach(() => {
setBashParserLoaderForCommandExplanationForTest();
parserLoaderOverridden = false;
}
vi.restoreAllMocks();
});
describe("command explainer tree-sitter runtime", () => {
@@ -71,6 +72,28 @@ describe("command explainer tree-sitter runtime", () => {
).toThrow("Unable to locate missing-openclaw-parser.wasm in web-tree-sitter");
});
it("reports parser progress cancellation as a timeout", async () => {
const reset = vi.fn();
const parser = {
parse: (
_source: string,
_oldTree: unknown,
options?: { progressCallback?: (state: unknown) => boolean },
) => {
options?.progressCallback?.({ currentOffset: 0, hasError: false });
return null;
},
reset,
} as unknown as Parser;
vi.spyOn(performance, "now").mockReturnValueOnce(0).mockReturnValue(501);
setParserLoaderForTest(async () => parser);
await expect(parseBashForCommandExplanation("echo hi")).rejects.toThrow(
"tree-sitter-bash timed out after 500ms while parsing shell command",
);
expect(reset).toHaveBeenCalledOnce();
});
it("explains a pipeline with python inline eval", async () => {
const explanation = await explainShellCommand('ls | grep "stuff" | python -c \'print("hi")\'');

View File

@@ -87,11 +87,20 @@ export async function parseBashForCommandExplanation(source: string): Promise<Tr
}
const parser = await getBashParserForCommandExplanation();
const deadlineMs = performance.now() + MAX_COMMAND_EXPLANATION_PARSE_MS;
let timedOut = false;
const tree = parser.parse(source, null, {
progressCallback: () => performance.now() > deadlineMs,
progressCallback: () => {
timedOut = performance.now() > deadlineMs;
return timedOut;
},
});
if (!tree) {
parser.reset();
if (timedOut) {
throw new Error(
`tree-sitter-bash timed out after ${MAX_COMMAND_EXPLANATION_PARSE_MS}ms while parsing shell command`,
);
}
throw new Error("tree-sitter-bash returned no parse tree");
}
return tree;