Files
LangBot/skills/scripts/e2e/agent-run-ledger-audit.mjs
T
2026-07-19 22:46:01 +08:00

84 lines
2.7 KiB
JavaScript

#!/usr/bin/env node
import { spawn } from "node:child_process";
import { readFile } from "node:fs/promises";
import { join } from "node:path";
import { env } from "node:process";
import {
ensureEvidence,
evidencePaths,
exitCode,
loadEnvFiles,
localIsoWithOffset,
resolveLangBotRepo,
writeResult,
} from "./lib/langbot-e2e.mjs";
await loadEnvFiles();
const caseId = env.LBS_CASE_ID || "agent-run-ledger-audit";
const paths = evidencePaths(caseId);
await ensureEvidence(paths);
const startedAt = new Date();
const auditPath = join(paths.evidenceDir, "ledger-audit.json");
const result = {
source: "automation",
case_id: caseId,
run_id: paths.runId,
started_at: startedAt.toISOString(),
started_at_local: localIsoWithOffset(startedAt),
finished_at: "",
finished_at_local: "",
status: "fail",
reason: "",
audited_run: null,
metrics_summary: null,
failures: [],
warnings: [],
evidence: {
ledger_audit_json: auditPath,
automation_result_json: paths.automationResultJson,
result_json: paths.resultJson,
},
evidence_collected: ["filesystem", "metrics", "api_diagnostic"],
};
function run(command, args, cwd) {
return new Promise((resolvePromise) => {
const child = spawn(command, args, { cwd, env, stdio: ["ignore", "pipe", "pipe"] });
let stderr = "";
child.stderr.on("data", (chunk) => { stderr += chunk; });
child.on("error", (error) => resolvePromise({ status: null, stderr, error }));
child.on("close", (status) => resolvePromise({ status, stderr, error: null }));
});
}
try {
const repo = await resolveLangBotRepo();
const python = join(repo, ".venv", "bin", "python");
const args = ["scripts/e2e/agent-run-ledger-audit.py", "--repo", repo, "--output", auditPath];
if (env.LANGBOT_AGENT_RUN_ID) args.push("--run-id", env.LANGBOT_AGENT_RUN_ID);
const execution = await run(python, args, process.cwd());
const report = JSON.parse(await readFile(auditPath, "utf8"));
result.status = report.status;
result.reason = report.reason;
result.audited_run = report.run || null;
result.metrics_summary = report.metrics || null;
result.failures = report.failures || [];
result.warnings = report.warnings || [];
if (execution.error && result.status === "pass") {
result.status = "env_issue";
result.reason = execution.error.message;
}
} catch (error) {
result.status = /ENOENT|not found|No matching/i.test(error.message) ? "env_issue" : "fail";
result.reason = error.message;
} finally {
const finishedAt = new Date();
result.finished_at = finishedAt.toISOString();
result.finished_at_local = localIsoWithOffset(finishedAt);
await writeResult(paths, result);
console.log(JSON.stringify(result, null, 2));
}
process.exit(exitCode(result.status));